From arigo at codespeak.net Thu Feb 1 00:09:25 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 1 Feb 2007 00:09:25 +0100 (CET) Subject: [pypy-svn] r37705 - in pypy/branch/jit-virtual-world/pypy/jit/timeshifter: . test Message-ID: <20070131230925.63F8510087@code0.codespeak.net> Author: arigo Date: Thu Feb 1 00:09:20 2007 New Revision: 37705 Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/rtimeshift.py pypy/branch/jit-virtual-world/pypy/jit/timeshifter/rvalue.py pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_exception.py pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_portal.py pypy/branch/jit-virtual-world/pypy/jit/timeshifter/vlist.py Log: (arre, pedronis, arigo) Don't merge jit states with exceptions and jit states without. Some related minor fixes done while looking at it. Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/rtimeshift.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/timeshifter/rtimeshift.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/timeshifter/rtimeshift.py Thu Feb 1 00:09:20 2007 @@ -761,6 +761,14 @@ #fz_virtualizables = ... set by freeze() def exactmatch(self, jitstate, outgoingvarboxes, memo): + if not memo.force_merge: + null1 = self.fz_exc_type_box.is_constant_nullptr() + box = jitstate.exc_type_box + null2 = (box.is_constant() and + not rvalue.ll_getvalue(box, llmemory.Address)) + if null1 != null2: + raise rvalue.DontMerge # a jit-with-exc. and a jit-without-exc. + fullmatch = True if not self.fz_frame.exactmatch(jitstate.frame, outgoingvarboxes, Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/rvalue.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/timeshifter/rvalue.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/timeshifter/rvalue.py Thu Feb 1 00:09:20 2007 @@ -309,6 +309,9 @@ def is_constant_equal(self, box): return False + def is_constant_nullptr(self): + return False + class FrozenConst(FrozenValue): @@ -403,6 +406,9 @@ self.gv_const.revealconst(llmemory.Address) == box.genvar.revealconst(llmemory.Address)) + def is_constant_nullptr(self): + return not self.gv_const.revealconst(llmemory.Address) + def exactmatch(self, box, outgoingvarboxes, memo): assert isinstance(box, PtrRedBox) memo.partialdatamatch[box] = None # could do better @@ -410,7 +416,7 @@ if not memo.force_merge and not match: from pypy.jit.timeshifter.rcontainer import VirtualContainer if isinstance(box.content, VirtualContainer): - raise DontMerge + raise DontMerge # XXX recursive data structures? return match def unfreeze(self, incomingvarboxes, memo): @@ -426,7 +432,7 @@ if not memo.force_merge and not match: from pypy.jit.timeshifter.rcontainer import VirtualContainer if isinstance(box.content, VirtualContainer): - raise DontMerge + raise DontMerge # XXX recursive data structures? return match def unfreeze(self, incomingvarboxes, memo): @@ -454,7 +460,7 @@ if not memo.force_merge and not match: from pypy.jit.timeshifter.rcontainer import VirtualContainer if isinstance(box.content, VirtualContainer): - raise DontMerge + raise DontMerge # XXX recursive data structures? return match Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_exception.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_exception.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_exception.py Thu Feb 1 00:09:20 2007 @@ -122,3 +122,19 @@ self.timeshift_raises(ValueError, ll_function, [-3], [0], policy=P_OOPSPEC) + + def test_raise_or_return_virtual(self): + class A: + def __init__(self, n): + self.n = n + def g(x): + if x < 3: + raise ValueError + return A(x) + def ll_function(n): + a = g(n) + return a.n + + res = self.timeshift(ll_function, [5], [], policy=P_NOVIRTUAL) + assert res == 5 + self.check_insns(malloc=0) Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_portal.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_portal.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_portal.py Thu Feb 1 00:09:20 2007 @@ -2,7 +2,7 @@ from pypy.translator.translator import graphof from pypy.jit.timeshifter.test.test_timeshift import hannotate, getargtypes from pypy.jit.timeshifter.hrtyper import HintRTyper -from pypy.jit.timeshifter.test.test_timeshift import P_NOVIRTUAL +from pypy.jit.timeshifter.test.test_timeshift import P_NOVIRTUAL, StopAtXPolicy from pypy.jit.timeshifter.test.test_vlist import P_OOPSPEC from pypy.rpython.llinterp import LLInterpreter from pypy.objspace.flow.model import checkgraph, summary @@ -338,11 +338,13 @@ hint(o.__class__, promote=True) return o.double().get() - res = self.timeshift_from_portal(ll_function, ll_function, [5], policy=P_NOVIRTUAL) + res = self.timeshift_from_portal(ll_function, ll_function, [5], + policy=StopAtXPolicy(ll_make)) assert res == 10 self.check_insns(indirect_call=0, malloc=0) - res = self.timeshift_from_portal(ll_function, ll_function, [0], policy=P_NOVIRTUAL) + res = self.timeshift_from_portal(ll_function, ll_function, [0], + policy=StopAtXPolicy(ll_make)) assert res == ord('2') self.check_insns(indirect_call=0, malloc=0) Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/vlist.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/timeshifter/vlist.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/timeshifter/vlist.py Thu Feb 1 00:09:20 2007 @@ -3,6 +3,9 @@ from pypy.jit.timeshifter.rcontainer import cachedtype from pypy.jit.timeshifter import rvalue, rvirtualizable +from pypy.rpython.lltypesystem import lloperation +debug_print = lloperation.llop.debug_print + class ItemDesc(object): __metaclass__ = cachedtype @@ -160,6 +163,7 @@ boxes = self.item_boxes self.item_boxes = None + debug_print(lltype.Void, "FORCE LIST (%d items)" % (len(boxes),)) args_gv = [builder.rgenop.genconst(len(boxes))] gv_list = builder.genop_call(typedesc.tok_ll_newlist, typedesc.gv_ll_newlist, From cfbolz at codespeak.net Thu Feb 1 00:32:20 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 1 Feb 2007 00:32:20 +0100 (CET) Subject: [pypy-svn] r37706 - pypy/dist/pypy/objspace/std/test Message-ID: <20070131233220.40F1010083@code0.codespeak.net> Author: cfbolz Date: Thu Feb 1 00:32:17 2007 New Revision: 37706 Modified: pypy/dist/pypy/objspace/std/test/test_shadowtracking.py Log: remove debug prints (they are uplevel and can therefore come through the py.test output capturing) Modified: pypy/dist/pypy/objspace/std/test/test_shadowtracking.py ============================================================================== --- pypy/dist/pypy/objspace/std/test/test_shadowtracking.py (original) +++ pypy/dist/pypy/objspace/std/test/test_shadowtracking.py Thu Feb 1 00:32:17 2007 @@ -109,7 +109,6 @@ for i, a in enumerate(l): assert a.f() == 42 + i % 3 cache_counter = pypymagic.method_cache_counter("f") - print cache_counter assert cache_counter[1] >= 3 # should be (27, 3) assert sum(cache_counter) == 30 @@ -133,7 +132,6 @@ for i, a in enumerate(l): assert a.f() == 42 + i % 3 cache_counter = pypymagic.method_cache_counter("f") - print cache_counter assert cache_counter[1] >= 2 # should be (18, 2) assert sum(cache_counter) == 20 @@ -148,7 +146,6 @@ assert a.f() == 42 + i A.f = eval("lambda self: %s" % (42 + i + 1, )) cache_counter = pypymagic.method_cache_counter("f") - print cache_counter assert cache_counter == (0, 10) def test_subclasses(self): @@ -166,7 +163,6 @@ for i, a in enumerate(l): assert a.f() == 42 + (i % 3 == 1) cache_counter = pypymagic.method_cache_counter("f") - print cache_counter assert cache_counter[1] >= 3 # should be (27, 3) assert sum(cache_counter) == 30 From cfbolz at codespeak.net Thu Feb 1 00:53:30 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 1 Feb 2007 00:53:30 +0100 (CET) Subject: [pypy-svn] r37707 - pypy/dist/pypy/objspace/std Message-ID: <20070131235330.12F4E10077@code0.codespeak.net> Author: cfbolz Date: Thu Feb 1 00:53:28 2007 New Revision: 37707 Modified: pypy/dist/pypy/objspace/std/stringobject.py Log: cleanups: make str_join use the rpython join. remove some commented out code Modified: pypy/dist/pypy/objspace/std/stringobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/stringobject.py (original) +++ pypy/dist/pypy/objspace/std/stringobject.py Thu Feb 1 00:53:28 2007 @@ -316,54 +316,28 @@ return W_ListObject(res_w) def str_join__String_ANY(space, w_self, w_list): - list = space.unpackiterable(w_list) + list_w = space.unpackiterable(w_list) str_w = space.str_w - if list: + if list_w: self = w_self._value - firstelem = 1 listlen = 0 reslen = 0 - #compute the length of the resulting string - for i in range(len(list)): - if not space.is_true(space.isinstance(list[i], space.w_str)): - if space.is_true(space.isinstance(list[i], space.w_unicode)): + l = [] + for i in range(len(list_w)): + w_s = list_w[i] + if not space.is_true(space.isinstance(w_s, space.w_str)): + if space.is_true(space.isinstance(w_s, space.w_unicode)): w_u = space.call_function(space.w_unicode, w_self) - return space.call_method(w_u, "join", space.newlist(list)) + return space.call_method(w_u, "join", space.newlist(list_w)) raise OperationError( space.w_TypeError, space.wrap("sequence item %d: expected string, %s " - "found"%(i, space.type(list[i]).name))) - reslen = reslen + len(str_w(list[i])) - listlen = listlen + 1 - - reslen = reslen + (listlen - 1) * len(self) - - #allocate the string buffer - res = [' '] * reslen - - pos = 0 - #fill in the string buffer - for w_item in list: - item = str_w(w_item) - if firstelem: - for i in range(len(item)): - res[i+pos] = item[i] - pos = pos + len(item) - firstelem = 0 - else: - for i in range(len(self)): - res[i+pos] = self[i] - pos = pos + len(self) - - for i in range(len(item)): - res[i+pos] = item[i] - pos = pos + len(item) - - return space.wrap("".join(res)) + "found" % (i, space.type(w_s).name))) + l.append(space.str_w(w_s)) + return space.wrap(self.join(l)) else: return space.wrap("") - def str_rjust__String_ANY_ANY(space, w_self, w_arg, w_fillchar): u_arg = space.int_w(w_arg) @@ -454,7 +428,7 @@ input = w_self._value sub = w_sub._value by = w_by._value - maxsplit = space.int_w(w_maxsplit) #I don't use it now + maxsplit = space.int_w(w_maxsplit) #print "from replace, input: %s, sub: %s, by: %s" % (input, sub, by) @@ -493,54 +467,6 @@ bufpos = bufpos + 1 return space.wrap("".join(buf)) -##def _find(self, sub, start, end, dir): - -## length = len(self) - -## #adjust_indicies -## if (end > length): -## end = length -## elif (end < 0): -## end += length -## if (end < 0): -## end = 0 -## if (start < 0): -## start += length -## if (start < 0): -## start = 0 - -## if dir > 0: -## if len(sub) == 0 and start < end: -## return start - -## end = end - len(sub) + 1 - -## for i in range(start, end): -## match = 1 -## for idx in range(len(sub)): -## if sub[idx] != self[idx+i]: -## match = 0 -## break -## if match: -## return i -## return -1 -## else: -## if len(sub) == 0 and start < end: -## return end - -## end = end - len(sub) - -## for j in range(end, start-1, -1): -## match = 1 -## for idx in range(len(sub)): -## if sub[idx] != self[idx+j]: -## match = 0 -## break -## if match: -## return j -## return -1 - - def _strip(space, w_self, w_chars, left, right): "internal function called by str_xstrip methods" u_self = w_self._value @@ -732,6 +658,7 @@ # cannot return w_self, in case it is a subclass of str return space.wrap(input) + result = [] buf = [' '] * width if len(input) > 0 and (input[0] == '+' or input[0] == '-'): buf[0] = input[0] From arigo at codespeak.net Thu Feb 1 03:36:28 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 1 Feb 2007 03:36:28 +0100 (CET) Subject: [pypy-svn] r37708 - in pypy/branch/jit-virtual-world/pypy/jit/timeshifter: . test Message-ID: <20070201023628.CB29D10069@code0.codespeak.net> Author: arigo Date: Thu Feb 1 03:36:26 2007 New Revision: 37708 Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/rtimeshift.py pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_promotion.py Log: (pedronis, arigo) Test case eventually designed (ha!) after a pypyjit assertion. Fix. Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/rtimeshift.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/timeshifter/rtimeshift.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/timeshifter/rtimeshift.py Thu Feb 1 03:36:26 2007 @@ -226,13 +226,16 @@ states_dic[key][index] = (frozen, newblock) if global_resumer is not None and global_resumer is not return_marker: + assert jitstate.resuming is None jitstate.curbuilder.log('start_new_block %s' % (key,)) greens_gv = jitstate.greens rgenop = jitstate.curbuilder.rgenop node = PromotionPathRoot(greens_gv, rgenop, frozen, newblock, global_resumer) - jitstate.frame.dispatchqueue.mergecounter = 0 + dispatchqueue = jitstate.frame.dispatchqueue + assert dispatchqueue.split_chain is None + dispatchqueue.clearlocalcaches() jitstate.promotion_path = PromotionPathMergesToSee(node, 0) #debug_print(lltype.Void, "PROMOTION ROOT") start_new_block._annspecialcase_ = "specialize:arglltype(2)" @@ -701,6 +704,9 @@ self.split_chain = None self.global_merge_chain = None self.return_chain = None + self.clearlocalcaches() + + def clearlocalcaches(self): self.mergecounter = 0 def clear(self): @@ -711,8 +717,8 @@ return BaseDispatchQueue attrnames = unrolling_iterable(attrnames) class DispatchQueue(BaseDispatchQueue): - def __init__(self): - BaseDispatchQueue.__init__(self) + def clearlocalcaches(self): + BaseDispatchQueue.clearlocalcaches(self) for name in attrnames: setattr(self, name, {}) # the new dicts have various types! return DispatchQueue Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_promotion.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_promotion.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_promotion.py Thu Feb 1 03:36:26 2007 @@ -275,3 +275,27 @@ assert res == 6 self.check_oops(**{'newlist': 1, 'list.len': 1}) + def test_promote_bug_1(self): + def ll_function(x, y, z): + a = 17 + while True: + hint(None, global_merge_point=True) + y += 1 + + if a != 17: + z = -z + + if z > 0: + b = 1 - z + else: + b = 2 + y = -y + if b == 2: + hint(z, promote=True) + return y + z + a + a += z + + assert ll_function(1, 5, 8) == 22 + res = self.timeshift(ll_function, [1, 5, 8], [], + policy=P_NOVIRTUAL) + assert res == 22 From cfbolz at codespeak.net Thu Feb 1 09:54:29 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 1 Feb 2007 09:54:29 +0100 (CET) Subject: [pypy-svn] r37709 - pypy/dist/pypy/objspace/std Message-ID: <20070201085429.CABC310053@code0.codespeak.net> Author: cfbolz Date: Thu Feb 1 09:54:28 2007 New Revision: 37709 Modified: pypy/dist/pypy/objspace/std/stringobject.py Log: make replace use rpython join. string * 0 = "". Modified: pypy/dist/pypy/objspace/std/stringobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/stringobject.py (original) +++ pypy/dist/pypy/objspace/std/stringobject.py Thu Feb 1 09:54:28 2007 @@ -429,43 +429,32 @@ sub = w_sub._value by = w_by._value maxsplit = space.int_w(w_maxsplit) + if maxsplit == 0: + return space.wrap(input) #print "from replace, input: %s, sub: %s, by: %s" % (input, sub, by) - #what do we have to replace? + if not sub: + upper = len(input) + if maxsplit > 0 and maxsplit < upper + 2: + upper = maxsplit - 1 + assert upper >= 0 + substrings = [""] + for i in range(upper): + c = input[i] + substrings.append(c) + substrings.append(input[upper:]) + return space.wrap(by.join(substrings)) startidx = 0 - indices = [] + substrings = [] foundidx = input.find(sub, startidx) while foundidx >= 0 and maxsplit != 0: - indices.append(foundidx) - if len(sub) == 0: - #so that we go forward, even if sub is empty - startidx = foundidx + 1 - else: - startidx = foundidx + len(sub) + substrings.append(input[startidx:foundidx]) + startidx = foundidx + len(sub) foundidx = input.find(sub, startidx) maxsplit = maxsplit - 1 - indiceslen = len(indices) - buf = [' '] * (len(input) - indiceslen * len(sub) + indiceslen * len(by)) - startidx = 0 - - #ok, so do it - bufpos = 0 - for i in range(indiceslen): - for j in range(startidx, indices[i]): - buf[bufpos] = input[j] - bufpos = bufpos + 1 - - for j in range(len(by)): - buf[bufpos] = by[j] - bufpos = bufpos + 1 - - startidx = indices[i] + len(sub) - - for j in range(startidx, len(input)): - buf[bufpos] = input[j] - bufpos = bufpos + 1 - return space.wrap("".join(buf)) + substrings.append(input[startidx:]) + return space.wrap(by.join(substrings)) def _strip(space, w_self, w_chars, left, right): "internal function called by str_xstrip methods" @@ -771,7 +760,7 @@ if e.match(space, space.w_TypeError): raise FailedToImplement raise - if mul < 0: + if mul <= 0: return space.wrap('') input = w_str._value input_len = len(input) From cfbolz at codespeak.net Thu Feb 1 10:37:19 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 1 Feb 2007 10:37:19 +0100 (CET) Subject: [pypy-svn] r37710 - pypy/dist/pypy/objspace/std Message-ID: <20070201093719.1E6E210060@code0.codespeak.net> Author: cfbolz Date: Thu Feb 1 10:37:16 2007 New Revision: 37710 Modified: pypy/dist/pypy/objspace/std/listobject.py Log: yet another small cleanup: use RPython's list.reverse Modified: pypy/dist/pypy/objspace/std/listobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/listobject.py (original) +++ pypy/dist/pypy/objspace/std/listobject.py Thu Feb 1 10:37:16 2007 @@ -442,15 +442,6 @@ # Reverse a slice of a list in place, from lo up to (exclusive) hi. # (used in sort) -def _reverse_slice(lis, lo, hi): - hi -= 1 - while lo < hi: - t = lis[lo] - lis[lo] = lis[hi] - lis[hi] = t - lo += 1 - hi -= 1 - class KeyContainer(baseobjspace.W_Root): def __init__(self, w_key, w_item): self.w_key = w_key @@ -530,14 +521,14 @@ # Reverse sort stability achieved by initially reversing the list, # applying a stable forward sort, then reversing the final result. if has_reverse: - _reverse_slice(sorter.list, 0, sorter.listlength) + sorter.list.reverse() # perform the sort sorter.sort() # reverse again if has_reverse: - _reverse_slice(sorter.list, 0, sorter.listlength) + sorter.list.reverse() finally: # unwrap each item if needed From cfbolz at codespeak.net Thu Feb 1 11:13:27 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 1 Feb 2007 11:13:27 +0100 (CET) Subject: [pypy-svn] r37712 - pypy/dist/pypy/objspace/std Message-ID: <20070201101327.C500410060@code0.codespeak.net> Author: cfbolz Date: Thu Feb 1 11:13:12 2007 New Revision: 37712 Modified: pypy/dist/pypy/objspace/std/floatobject.py pypy/dist/pypy/objspace/std/intobject.py pypy/dist/pypy/objspace/std/longobject.py Log: remove strange and quite old comments and commented out code Modified: pypy/dist/pypy/objspace/std/floatobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/floatobject.py (original) +++ pypy/dist/pypy/objspace/std/floatobject.py Thu Feb 1 11:13:12 2007 @@ -4,12 +4,6 @@ from pypy.objspace.std.longobject import W_LongObject from pypy.rlib.rarithmetic import ovfcheck_float_to_int, intmask, isinf -############################################################## -# for the time being, all calls that are made to some external -# libraries in the floatobject.c, calls are made into the -# python math library -############################################################## - import math from pypy.objspace.std.intobject import W_IntObject @@ -280,11 +274,6 @@ truediv__Float_Float = div__Float_Float -# avoid space.getitem for a basic operation -##def floordiv__Float_Float(space, w_float1, w_float2): -## w_t = divmod__Float_Float(space, w_float1, w_float2) -## return space.getitem(w_t, space.wrap(0)) - def floordiv__Float_Float(space, w_float1, w_float2): w_div, w_mod = _divmod_w(space, w_float1, w_float2) return w_div @@ -397,17 +386,6 @@ def nonzero__Float(space, w_float): return space.newbool(w_float.floatval != 0.0) -######## coercion must be done later -later = """ -def float_coerce(space, w_float): - if w_float.__class__ == W_FloatObject: - return w_float - else: - return W_FloatObject(w_float.floatval) - -StdObjSpace.coerce.register(float_coerce, W_FloatObject) -""" - def getnewargs__Float(space, w_float): return space.newtuple([W_FloatObject(w_float.floatval)]) Modified: pypy/dist/pypy/objspace/std/intobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/intobject.py (original) +++ pypy/dist/pypy/objspace/std/intobject.py Thu Feb 1 11:13:12 2007 @@ -28,14 +28,6 @@ registerimplementation(W_IntObject) -""" -XXX not implemented: -free list -FromString -FromUnicode -print -""" - def int_w__Int(space, w_int1): return int(w_int1.intval) @@ -324,19 +316,6 @@ res = a | b return wrapint(space, res) -# coerce is not wanted -## -##static int -##coerce__Int(PyObject **pv, PyObject **pw) -##{ -## if (PyInt_Check(*pw)) { -## Py_INCREF(*pv); -## Py_INCREF(*pw); -## return 0; -## } -## return 1; /* Can't do it */ -##} - # int__Int is supposed to do nothing, unless it has # a derived integer object, where it should return # an exact one. @@ -346,14 +325,6 @@ a = w_int1.intval return wrapint(space, a) -""" -# Not registered -def long__Int(space, w_int1): - a = w_int1.intval - x = long(a) ## XXX should this really be done so? - return space.newlong(x) -""" - def float__Int(space, w_int1): a = w_int1.intval x = float(a) Modified: pypy/dist/pypy/objspace/std/longobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/longobject.py (original) +++ pypy/dist/pypy/objspace/std/longobject.py Thu Feb 1 11:13:12 2007 @@ -205,7 +205,7 @@ def nonzero__Long(space, w_long): return space.newbool(w_long.num.tobool()) -def invert__Long(space, w_long): #Implement ~x as -(x + 1) +def invert__Long(space, w_long): return W_LongObject(w_long.num.invert()) def lshift__Long_Long(space, w_long1, w_long2): From fijal at codespeak.net Thu Feb 1 11:33:39 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 1 Feb 2007 11:33:39 +0100 (CET) Subject: [pypy-svn] r37713 - pypy/dist/pypy/translator/js Message-ID: <20070201103339.1489A10063@code0.codespeak.net> Author: fijal Date: Thu Feb 1 11:33:36 2007 New Revision: 37713 Modified: pypy/dist/pypy/translator/js/function.py Log: Kill unused imports Modified: pypy/dist/pypy/translator/js/function.py ============================================================================== --- pypy/dist/pypy/translator/js/function.py (original) +++ pypy/dist/pypy/translator/js/function.py Thu Feb 1 11:33:36 2007 @@ -7,12 +7,8 @@ from pypy.rpython.lltypesystem.lltype import Signed, Unsigned, Void, Bool, Float from pypy.rpython.lltypesystem.lltype import SignedLongLong, UnsignedLongLong from pypy.rpython.ootypesystem import ootype -from pypy.translator.cli.option import getoption -from pypy.translator.cli.cts import CTS -from pypy.translator.cli.opcodes import opcodes from pypy.translator.oosupport.metavm import Generator,InstructionList from pypy.translator.cli.node import Node -from pypy.translator.cli.class_ import Class from pypy.translator.js.log import log from types import FunctionType From fijal at codespeak.net Thu Feb 1 11:34:34 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 1 Feb 2007 11:34:34 +0100 (CET) Subject: [pypy-svn] r37714 - pypy/dist/pypy/doc/js Message-ID: <20070201103434.515FA10074@code0.codespeak.net> Author: fijal Date: Thu Feb 1 11:34:32 2007 New Revision: 37714 Modified: pypy/dist/pypy/doc/js/todo.txt Log: Update a bit (means more work :-( Modified: pypy/dist/pypy/doc/js/todo.txt ============================================================================== --- pypy/dist/pypy/doc/js/todo.txt (original) +++ pypy/dist/pypy/doc/js/todo.txt Thu Feb 1 11:34:32 2007 @@ -14,3 +14,28 @@ - unnecessary jumps * Provide some high level widgets-like functionality + +* Adhere to a new external function interface + +* Support bound methods as arguments for callbacks. + + Idea is to provide following: + + - if you pass a bound method to a callback, this method is called + with previously bound self + - if you provide an unbound method for a callback, this is an error, + unless class is proper to the callback object (or high level class + apropriate for that DOM object), in which case a bound method is + called with apropriate self. + + I'm quite sure this can be done using RPython, but I'm totally unsure + how much effort this will require :-) (as usuall) + +* Cleanup of parent namespace (put all builtin functions into it's + own namespace?) + +* Dict support is very limited (only string keys right now) + +* Implement possible raising expressions int\_add\_ovf ie. + +* Make JS backend complete From ericvrp at codespeak.net Thu Feb 1 11:42:30 2007 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Thu, 1 Feb 2007 11:42:30 +0100 (CET) Subject: [pypy-svn] r37715 - in pypy/dist/pypy/translator/llvm: . module test Message-ID: <20070201104230.1ECF71006E@code0.codespeak.net> Author: ericvrp Date: Thu Feb 1 11:42:28 2007 New Revision: 37715 Modified: pypy/dist/pypy/translator/llvm/buildllvm.py pypy/dist/pypy/translator/llvm/externs2ll.py pypy/dist/pypy/translator/llvm/gc.py pypy/dist/pypy/translator/llvm/module/support.py pypy/dist/pypy/translator/llvm/test/runtest.py Log: Complete support for llvm-gcc4 and llvm2 Modified: pypy/dist/pypy/translator/llvm/buildllvm.py ============================================================================== --- pypy/dist/pypy/translator/llvm/buildllvm.py (original) +++ pypy/dist/pypy/translator/llvm/buildllvm.py Thu Feb 1 11:42:28 2007 @@ -15,13 +15,15 @@ return False return True -def exe_version(exe): +def _exe_version(exe): v = os.popen(exe + ' -version 2>&1').read() v = ''.join([c for c in v if c.isdigit()]) v = int(v) / 10.0 return v -def exe_version2(exe): +llvm_version = _exe_version('llvm-as') + +def _exe_version2(exe): v = os.popen(exe + ' --version 2>&1').read() i = v.index(')') v = v[i+2:].split()[0].split('.') @@ -29,6 +31,9 @@ v = float(major) + float(minor) / 10.0 return v +gcc_version = _exe_version2('gcc') +llvm_gcc_version = _exe_version2('llvm-gcc') + def optimizations(simple, use_gcc): if simple: @@ -81,8 +86,7 @@ # run llvm assembler and optimizer simple_optimizations = not optimize opts = optimizations(simple_optimizations, use_gcc) - v = exe_version('llvm-as') - if v < 2.0: + if llvm_version < 2.0: cmds = ["llvm-as < %s.ll | opt %s -f -o %s.bc" % (b, opts, b)] else: #we generate 1.x .ll files, so upgrade these first cmds = ["llvm-upgrade < %s.ll | llvm-as | opt %s -f -o %s.bc" % (b, opts, b)] Modified: pypy/dist/pypy/translator/llvm/externs2ll.py ============================================================================== --- pypy/dist/pypy/translator/llvm/externs2ll.py (original) +++ pypy/dist/pypy/translator/llvm/externs2ll.py Thu Feb 1 11:42:28 2007 @@ -7,7 +7,7 @@ from pypy.rpython.rmodel import inputconst from pypy.rpython.lltypesystem import lltype from pypy.translator.llvm.codewriter import DEFAULT_CCONV -from pypy.translator.llvm.buildllvm import exe_version2 +from pypy.translator.llvm.buildllvm import llvm_gcc_version from pypy.tool.udir import udir @@ -40,13 +40,10 @@ plain = filename[:-2] includes = get_incdirs() - global _llvm_gcc_version - if not _llvm_gcc_version: - _llvm_gcc_version = exe_version2('llvm-gcc') - if _llvm_gcc_version < 4.0: + if llvm_gcc_version < 4.0: emit_llvm = '' else: - emit_llvm = '-emit-llvm' + emit_llvm = '-emit-llvm -O3' cmd = "llvm-gcc %s %s -S %s.c -o %s.ll 2>&1" % ( includes, emit_llvm, plain, plain) Modified: pypy/dist/pypy/translator/llvm/gc.py ============================================================================== --- pypy/dist/pypy/translator/llvm/gc.py (original) +++ pypy/dist/pypy/translator/llvm/gc.py Thu Feb 1 11:42:28 2007 @@ -5,6 +5,12 @@ from pypy.translator.llvm.log import log log = log.gc +from pypy.translator.llvm.buildllvm import llvm_version +if llvm_version >= 2.0: + postfix = '.i32' +else: + postfix = '' + def have_boehm(): import distutils.sysconfig from os.path import exists @@ -151,7 +157,7 @@ # malloc_size is unsigned right now codewriter.malloc(targetvar, "sbyte", size) - codewriter.call(None, 'void', '%llvm.memset', + codewriter.call(None, 'void', '%llvm.memset' + postfix, ['sbyte*', 'ubyte', uword, uword], [targetvar, 0, size, boundary_size], cconv='ccc') @@ -204,7 +210,7 @@ codewriter.call(targetvar, 'sbyte*', fnname, [word], [sizei]) if atomic: - codewriter.call(None, 'void', '%llvm.memset', + codewriter.call(None, 'void', '%llvm.memset' + postfix, ['sbyte*', 'ubyte', uword, uword], [targetvar, 0, size, boundary_size], cconv='ccc') 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 Thu Feb 1 11:42:28 2007 @@ -1,12 +1,18 @@ +from pypy.translator.llvm.buildllvm import llvm_version +if llvm_version >= 2.0: + postfix = '.i32' +else: + postfix = '' extdeclarations = """ %last_exception_type = internal global %RPYTHON_EXCEPTION_VTABLE* null %last_exception_value = internal global %RPYTHON_EXCEPTION* null declare ccc uint %strlen(sbyte*) -declare ccc void %llvm.memset(sbyte*, ubyte, UWORD, UWORD) -declare ccc void %llvm.memcpy(sbyte*, sbyte*, UWORD, UWORD) +declare ccc void %llvm.memsetPOSTFIX(sbyte*, ubyte, UWORD, UWORD) +declare ccc void %llvm.memcpyPOSTFIX(sbyte*, sbyte*, UWORD, UWORD) """ +extdeclarations = extdeclarations.replace('POSTFIX', postfix) extfunctions = """ internal fastcc sbyte* %RPyString_AsString(%RPyString* %structstring) { @@ -36,7 +42,7 @@ %rpystrptr = getelementptr %RPyString* %rpy, int 0, uint 1, uint 1 %rpystr = cast [0 x sbyte]* %rpystrptr to sbyte* - call ccc void %llvm.memcpy(sbyte* %rpystr, sbyte* %s, UWORD %lenuword, UWORD 0) + call ccc void %llvm.memcpyPOSTFIX(sbyte* %rpystr, sbyte* %s, UWORD %lenuword, UWORD 0) ret %RPyString* %rpy } @@ -78,6 +84,7 @@ } """ +extfunctions = extfunctions.replace('POSTFIX', postfix) from sys import maxint if maxint != 2**31-1: Modified: pypy/dist/pypy/translator/llvm/test/runtest.py ============================================================================== --- pypy/dist/pypy/translator/llvm/test/runtest.py (original) +++ pypy/dist/pypy/translator/llvm/test/runtest.py Thu Feb 1 11:42:28 2007 @@ -1,10 +1,9 @@ import py from pypy.tool import isolate from pypy.translator.llvm.genllvm import genllvm_compile -from pypy.translator.llvm.buildllvm import llvm_is_on_path, exe_version, exe_version2 +from pypy.translator.llvm.buildllvm import llvm_is_on_path, llvm_version, gcc_version optimize_tests = False -MINIMUM_LLVM_VERSION = 1.7 -MAXIMUM_LLVM_VERSION = 2.0 +MINIMUM_LLVM_VERSION = 1.9 ext_modules = [] @@ -33,21 +32,15 @@ if not llvm_is_on_path(): py.test.skip("could not find one of llvm-as or llvm-gcc") return False - v = exe_version('llvm-as') - if v < MINIMUM_LLVM_VERSION: + if llvm_version < MINIMUM_LLVM_VERSION: py.test.skip("llvm version not up-to-date (found " - "%.1f, should be >= %.1f)" % (v, MINIMUM_LLVM_VERSION)) - return False - elif v >= MAXIMUM_LLVM_VERSION: - py.test.skip("llvm version %.1f and higher are not yet supported (found %.1f)" % ( - MAXIMUM_LLVM_VERSION, v)) + "%.1f, should be >= %.1f)" % (llvm_version, MINIMUM_LLVM_VERSION)) return False return True def gcc3_test(): - v = exe_version2('gcc') - if int(v) != 3: - py.test.skip("test required gcc version 3 (found version %.1f)" % v) + if int(gcc_version) != 3: + py.test.skip("test required gcc version 3 (found version %.1f)" % gcc_version) return False return True From antocuni at codespeak.net Thu Feb 1 11:44:31 2007 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Thu, 1 Feb 2007 11:44:31 +0100 (CET) Subject: [pypy-svn] r37716 - pypy/dist/pypy/translator/cli Message-ID: <20070201104431.0CB5110070@code0.codespeak.net> Author: antocuni Date: Thu Feb 1 11:44:30 2007 New Revision: 37716 Modified: pypy/dist/pypy/translator/cli/rte.py Log: Check for the presence of 'gmcs' only when really needed, not at import time. Thanks to fijal for the bug report. Modified: pypy/dist/pypy/translator/cli/rte.py ============================================================================== --- pypy/dist/pypy/translator/cli/rte.py (original) +++ pypy/dist/pypy/translator/cli/rte.py Thu Feb 1 11:44:30 2007 @@ -27,7 +27,10 @@ ALIAS = None FLAGS = [] DEPENDENCIES = [] - COMPILER = SDK.csc() + + def get_COMPILER(cls): + return SDK.csc() + get_COMPILER = classmethod(get_COMPILER) def get(cls): for dep in cls.DEPENDENCIES: @@ -53,7 +56,7 @@ log.red("Compiling %s" % (cls.ALIAS or cls.OUTPUT)) oldcwd = os.getcwd() os.chdir(SRC_DIR) - compiler = subprocess.Popen([cls.COMPILER] + cls.FLAGS + ['/out:%s' % out] + sources, + compiler = subprocess.Popen([cls.get_COMPILER()] + cls.FLAGS + ['/out:%s' % out] + sources, stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = compiler.communicate() retval = compiler.wait() @@ -68,8 +71,11 @@ class MainStub(Target): SOURCES = ['stub/main.il'] OUTPUT = 'main.exe' - COMPILER = SDK.ilasm() + def get_COMPILER(cls): + return SDK.ilasm() + get_COMPILER = classmethod(get_COMPILER) + class FrameworkDLL(Target): SOURCES = ['pypylib.cs', 'll_os.cs', 'errno.cs', 'll_math.cs'] OUTPUT = 'pypylib.dll' From fijal at codespeak.net Thu Feb 1 11:59:13 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 1 Feb 2007 11:59:13 +0100 (CET) Subject: [pypy-svn] r37718 - pypy/dist/pypy/lib/distributed Message-ID: <20070201105913.563B510077@code0.codespeak.net> Author: fijal Date: Thu Feb 1 11:59:12 2007 New Revision: 37718 Modified: pypy/dist/pypy/lib/distributed/protocol.py Log: Kill some dead code Modified: pypy/dist/pypy/lib/distributed/protocol.py ============================================================================== --- pypy/dist/pypy/lib/distributed/protocol.py (original) +++ pypy/dist/pypy/lib/distributed/protocol.py Thu Feb 1 11:59:12 2007 @@ -363,13 +363,7 @@ def test_env(exported_names): from stackless import channel, tasklet, run - # XXX: This is a hack, proper support for recursive type is needed inp, out = channel(), channel() remote_protocol = RemoteProtocol(inp.send, out.receive, exported_names) t = tasklet(remote_loop)(remote_protocol) return RemoteProtocol(out.send, inp.receive) - -#def bootstrap(gw): -# import py -# import sys -# return gw.remote_exec(py.code.Source(sys.modules[__name__], "remote_loop(channel.send, channel.receive)")) From fijal at codespeak.net Thu Feb 1 12:13:50 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 1 Feb 2007 12:13:50 +0100 (CET) Subject: [pypy-svn] r37719 - in pypy/dist/pypy/translator: . goal js js/test test tool transformer Message-ID: <20070201111350.31D2A10081@code0.codespeak.net> Author: fijal Date: Thu Feb 1 12:13:47 2007 New Revision: 37719 Removed: pypy/dist/pypy/translator/js/test/test_transformer.py pypy/dist/pypy/translator/transformer/ Modified: pypy/dist/pypy/translator/driver.py pypy/dist/pypy/translator/goal/translate.py pypy/dist/pypy/translator/js/main.py pypy/dist/pypy/translator/js/test/runtest.py pypy/dist/pypy/translator/test/test_driver.py pypy/dist/pypy/translator/tool/pdbplus.py Log: Kill transformer, it seems to be louse attempt to make RPython exceptions. Modified: pypy/dist/pypy/translator/driver.py ============================================================================== --- pypy/dist/pypy/translator/driver.py (original) +++ pypy/dist/pypy/translator/driver.py Thu Feb 1 12:13:47 2007 @@ -29,7 +29,6 @@ 'translation.fork_before': None, 'translation.backendopt.raisingop2direct_call' : False, 'translation.backendopt.merge_if_blocks': True, - 'translation.debug_transform' : False, } @@ -275,11 +274,6 @@ s = annotator.build_types(self.entry_point, self.inputtypes) - if self.config.translation.debug_transform: - from pypy.translator.transformer.debug import DebugTransformer - dt = DebugTransformer(translator) - dt.transform_all() - self.sanity_check_annotation() if self.standalone and s.knowntype != int: raise Exception("stand-alone program entry point must return an " @@ -550,8 +544,7 @@ def task_source_js(self): from pypy.translator.js.js import JS self.gen = JS(self.translator, functions=[self.entry_point], - stackless=self.config.translation.stackless, - use_debug=self.config.translation.debug_transform) + stackless=self.config.translation.stackless) filename = self.gen.write_source() self.log.info("Wrote %s" % (filename,)) task_source_js = taskdef(task_source_js, Modified: pypy/dist/pypy/translator/goal/translate.py ============================================================================== --- pypy/dist/pypy/translator/goal/translate.py (original) +++ pypy/dist/pypy/translator/goal/translate.py Thu Feb 1 12:13:47 2007 @@ -77,8 +77,6 @@ 'translation.cc': None, 'translation.profopt': None, 'translation.output': None, - - 'translation.debug_transform': False, } import py Modified: pypy/dist/pypy/translator/js/main.py ============================================================================== --- pypy/dist/pypy/translator/js/main.py (original) +++ pypy/dist/pypy/translator/js/main.py Thu Feb 1 12:13:47 2007 @@ -20,9 +20,6 @@ default=False, cmdline="--view"), BoolOption("use_pdb", "Use debugger", default=False, cmdline="--pdb"), - BoolOption("debug_transform", - "Use !EXPERIMENTAL! debug transform to produce tracebacks", - default=False, cmdline="-d --debug"), StrOption("output", "File to save results (default output.js)", default="output.js", cmdline="--output")]) @@ -65,7 +62,6 @@ import %(module_name)s from pypy.translator.js.helper import __show_traceback -from pypy.translator.transformer.debug import traceback_handler from pypy.rlib.nonconst import NonConstant as NonConst %(function_defs)s @@ -91,7 +87,7 @@ function_base = "%(module_name)s.%(fun_name)s(%(args)s)" wrapped_function_base = "%(fun_name)s(%(args)s)" -def get_source_ssf(mod, module_name, function_names, use_debug=True): +def get_source_ssf(mod, module_name, function_names): #source_ssf = "\n".join(["import %s" % module_name, "def some_strange_function_which_will_never_be_called():"] + [" "+\ # module_name+"."+fun_name+get_args(mod.__dict__[fun_name]) for fun_name in function_names]) function_list = [] @@ -99,12 +95,7 @@ for fun_name in function_names: args = get_args(mod.__dict__[fun_name]) arg_names = get_arg_names(mod.__dict__[fun_name]) - if not use_debug: - base = function_base - else: - base = wrapped_function_base - function_def_list.append(py.code.Source(wrapped_function_def_base % - locals())) + base = function_base function_list.append(py.code.Source(base % locals())) function_defs = "\n\n".join([str(i) for i in function_def_list]) functions = "\n".join([str(i.indent()) for i in function_list]) @@ -140,16 +131,13 @@ if func_code.func_code.co_argcount > 0 and func_code.func_code. \ co_argcount != lgt: raise BadSignature("Function %s does not have default arguments" % func_name) - source_ssf = get_source_ssf(mod, module_name, function_names, - jsconfig.debug_transform) + source_ssf = get_source_ssf(mod, module_name, function_names) exec(source_ssf) in globals() # now we gonna just cut off not needed function # XXX: Really do that #options = optparse.Values(defaults=DEFAULT_OPTIONS) - #options.debug_transform = opts.debug_transform from pypy.config.pypyoption import get_pypy_config config = get_pypy_config(translating=True) - config.translation.debug_transform = jsconfig.debug_transform driver = TranslationDriver(config=config) try: driver.setup(some_strange_function_which_will_never_be_called, [], policy = JsPolicy()) 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 Thu Feb 1 12:13:47 2007 @@ -11,7 +11,6 @@ from pypy.translator.js.log import log from pypy.conftest import option from pypy.rpython.test.tool import BaseRtypingTest, OORtypeMixin -from pypy.translator.transformer.debug import DebugTransformer from pypy.rlib.nonconst import NonConstant from pypy.rpython.llinterp import LLException @@ -28,7 +27,7 @@ return True class compile_function(object): - def __init__(self, function, annotations, stackless=False, view=False, html=None, is_interactive=False, root = None, run_browser = True, debug_transform = False): + def __init__(self, function, annotations, stackless=False, view=False, html=None, is_interactive=False, root = None, run_browser = True): if not use_browsertest and not _CLI_is_on_path(): py.test.skip('Javascript CLI (js) not found') @@ -37,8 +36,6 @@ t = TranslationContext() ann = t.buildannotator() ann.build_types(function, annotations) - if debug_transform: - DebugTransformer(t).transform_all() if view or option.view: t.view() t.buildrtyper(type_system="ootype").specialize() Modified: pypy/dist/pypy/translator/test/test_driver.py ============================================================================== --- pypy/dist/pypy/translator/test/test_driver.py (original) +++ pypy/dist/pypy/translator/test/test_driver.py Thu Feb 1 12:13:47 2007 @@ -34,8 +34,7 @@ assert td.backend_select_goals(['backendopt_lltype']) == [ 'backendopt_lltype'] - assert cmpl(td.exposed, - ['annotate', 'backendopt_lltype', + assert cmpl(td.exposed, ['annotate', 'backendopt_lltype', 'backendopt_ootype', 'llinterpret_lltype', 'rtype_ootype', 'rtype_lltype', 'source_cl', 'source_js', @@ -55,7 +54,8 @@ assert td.backend_select_goals(['backendopt_lltype']) == [ 'backendopt_lltype'] - assert cmpl(td.exposed, - ['annotate', 'backendopt', 'llinterpret', 'rtype', 'source_c', + expected = ['annotate', 'backendopt', 'llinterpret', 'rtype', 'source_c', 'source_llvm', 'compile_c', 'compile_llvm', 'run_llvm', - 'run_c']) + 'run_c'] + + assert cmpl(td.exposed, expected) Modified: pypy/dist/pypy/translator/tool/pdbplus.py ============================================================================== --- pypy/dist/pypy/translator/tool/pdbplus.py (original) +++ pypy/dist/pypy/translator/tool/pdbplus.py Thu Feb 1 12:13:47 2007 @@ -337,7 +337,7 @@ def do_flowg(self, arg): - """callg obj + """flowg obj show flow graph for function obj, obj can be an expression or a dotted name (in which case prefixing with some packages in pypy is tried (see help pypyprefixes))""" from pypy.translator.tool import graphpage From pedronis at codespeak.net Thu Feb 1 12:57:37 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Thu, 1 Feb 2007 12:57:37 +0100 (CET) Subject: [pypy-svn] r37722 - pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test Message-ID: <20070201115737.BD57F10074@code0.codespeak.net> Author: pedronis Date: Thu Feb 1 12:57:36 2007 New Revision: 37722 Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_promotion.py Log: a test showing how pypyjit explode now, we need to be much more careful about exception and exception code paths. Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_promotion.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_promotion.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_promotion.py Thu Feb 1 12:57:36 2007 @@ -1,10 +1,11 @@ import py from pypy.rpython.lltypesystem import lltype from pypy.jit.timeshifter.test.test_timeshift import TimeshiftingTests +from pypy.jit.timeshifter.test.test_timeshift import StopAtXPolicy from pypy.jit.timeshifter.test.test_timeshift import P_NOVIRTUAL from pypy.jit.timeshifter.test.test_vlist import P_OOPSPEC from pypy.rlib.objectmodel import hint - +from pypy.rpython.module.support import LLSupport class TestPromotion(TimeshiftingTests): @@ -299,3 +300,38 @@ res = self.timeshift(ll_function, [1, 5, 8], [], policy=P_NOVIRTUAL) assert res == 22 + + def test_raise_result_mixup(self): + py.test.skip("WIP") + def w(x): + pass + class E(Exception): + def __init__(self, x): + self.x = x + def o(x): + if x < 0: + e = E(x) + w(e) + raise e + return x + def ll_function(c, x): + i = 0 + while True: + hint(None, global_merge_point=True) + op = c[i] + hint(op, concrete=True) + if op == 'e': + break + elif op == 'o': + x = o(x) + x = hint(x, promote=True) + i = x + r = hint(i, variable=True) + return r + ll_function.convert_arguments = [LLSupport.to_rstr, int] + + assert ll_function("oe", 1) == 1 + + res = self.timeshift(ll_function, ["oe", 1], [], + policy=StopAtXPolicy(w)) + res == 1 From antocuni at codespeak.net Thu Feb 1 14:53:53 2007 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Thu, 1 Feb 2007 14:53:53 +0100 (CET) Subject: [pypy-svn] r37727 - pypy/dist/pypy/translator Message-ID: <20070201135353.23D591006F@code0.codespeak.net> Author: antocuni Date: Thu Feb 1 14:53:52 2007 New Revision: 37727 Modified: pypy/dist/pypy/translator/geninterplevel.py Log: The __file__ attribute of the CLR module from pythonnet is None. Handle this case. Modified: pypy/dist/pypy/translator/geninterplevel.py ============================================================================== --- pypy/dist/pypy/translator/geninterplevel.py (original) +++ pypy/dist/pypy/translator/geninterplevel.py Thu Feb 1 14:53:52 2007 @@ -460,7 +460,7 @@ return name def is_module_builtin(self, mod): - if not hasattr(mod, "__file__"): + if not hasattr(mod, "__file__") or mod.__file__ is None: return True if not (mod.__file__.endswith('.pyc') or mod.__file__.endswith('.py') or From antocuni at codespeak.net Thu Feb 1 14:57:46 2007 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Thu, 1 Feb 2007 14:57:46 +0100 (CET) Subject: [pypy-svn] r37730 - in pypy/dist/pypy/module/clr: . test Message-ID: <20070201135746.49E8610070@code0.codespeak.net> Author: antocuni Date: Thu Feb 1 14:57:45 2007 New Revision: 37730 Modified: pypy/dist/pypy/module/clr/interp_clr.py pypy/dist/pypy/module/clr/test/test_clr.py Log: Always use the same wrapper class for each .NET class. Modified: pypy/dist/pypy/module/clr/interp_clr.py ============================================================================== --- pypy/dist/pypy/module/clr/interp_clr.py (original) +++ pypy/dist/pypy/module/clr/interp_clr.py Thu Feb 1 14:57:45 2007 @@ -135,8 +135,28 @@ w_indexers = wrap_list_of_tuples(space, indexers) return w_properties, w_indexers +class _CliClassCache: + def __init__(self): + self.cache = {} + + def put(self, fullname, cls): + assert fullname not in self.cache + self.cache[fullname] = cls + + def get(self, fullname): + return self.cache.get(fullname, None) +CliClassCache = _CliClassCache() + def load_cli_class(space, namespace, classname): fullname = '%s.%s' % (namespace, classname) + w_cls = CliClassCache.get(fullname) + if w_cls is None: + w_cls = build_cli_class(space, namespace, classname, fullname) + CliClassCache.put(fullname, w_cls) + return w_cls +load_cli_class.unwrap_spec = [ObjSpace, str, str] + +def build_cli_class(space, namespace, classname, fullname): b_type = System.Type.GetType(fullname) w_staticmethods, w_methods = get_methods(space, b_type) w_properties, w_indexers = get_properties(space, b_type) @@ -147,7 +167,6 @@ w_methods, w_properties, w_indexers) -load_cli_class.unwrap_spec = [ObjSpace, str, str] class W_CliObject(Wrappable): Modified: pypy/dist/pypy/module/clr/test/test_clr.py ============================================================================== --- pypy/dist/pypy/module/clr/test/test_clr.py (original) +++ pypy/dist/pypy/module/clr/test/test_clr.py Thu Feb 1 14:57:45 2007 @@ -11,6 +11,12 @@ max_index = obj.call_method('Add', [42]) assert max_index == 0 + def test_cache(self): + import clr + ArrayList = clr.load_cli_class('System.Collections', 'ArrayList') + ArrayList2 = clr.load_cli_class('System.Collections', 'ArrayList') + assert ArrayList is ArrayList2 + def test_ArrayList(self): import clr ArrayList = clr.load_cli_class('System.Collections', 'ArrayList') From antocuni at codespeak.net Thu Feb 1 15:31:26 2007 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Thu, 1 Feb 2007 15:31:26 +0100 (CET) Subject: [pypy-svn] r37734 - pypy/dist/pypy/translator/cli Message-ID: <20070201143126.005221008E@code0.codespeak.net> Author: antocuni Date: Thu Feb 1 15:31:25 2007 New Revision: 37734 Modified: pypy/dist/pypy/translator/cli/dotnet.py Log: Pay attention to unicode objects. Modified: pypy/dist/pypy/translator/cli/dotnet.py ============================================================================== --- pypy/dist/pypy/translator/cli/dotnet.py (original) +++ pypy/dist/pypy/translator/cli/dotnet.py Thu Feb 1 15:31:25 2007 @@ -317,7 +317,7 @@ return CLR.System.Boolean(x) elif t is float: return CLR.System.Double(x) - elif t is str: + elif t is str or t is unicode: if len(x) == 1: return CLR.System.Char(x) else: From antocuni at codespeak.net Thu Feb 1 15:32:39 2007 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Thu, 1 Feb 2007 15:32:39 +0100 (CET) Subject: [pypy-svn] r37735 - in pypy/dist/pypy/module/clr: . test Message-ID: <20070201143239.50D7E10095@code0.codespeak.net> Author: antocuni Date: Thu Feb 1 15:32:38 2007 New Revision: 37735 Modified: pypy/dist/pypy/module/clr/boxing_rules.py pypy/dist/pypy/module/clr/interp_clr.py pypy/dist/pypy/module/clr/test/test_clr.py Log: Add rules for converting strings from and to .NET Modified: pypy/dist/pypy/module/clr/boxing_rules.py ============================================================================== --- pypy/dist/pypy/module/clr/boxing_rules.py (original) +++ pypy/dist/pypy/module/clr/boxing_rules.py Thu Feb 1 15:32:38 2007 @@ -2,6 +2,7 @@ from pypy.objspace.std.intobject import W_IntObject from pypy.objspace.std.floatobject import W_FloatObject from pypy.objspace.std.noneobject import W_NoneObject +from pypy.objspace.std.stringobject import W_StringObject from pypy.translator.cli.dotnet import box def tocli(self): @@ -20,6 +21,10 @@ return None W_NoneObject.tocli = tocli +def tocli(self): + return box(self._value) +W_StringObject.tocli = tocli + from pypy.objspace.fake.objspace import W_Object as W_Object_Fake from pypy.rlib.nonconst import NonConstant Modified: pypy/dist/pypy/module/clr/interp_clr.py ============================================================================== --- pypy/dist/pypy/module/clr/interp_clr.py (original) +++ pypy/dist/pypy/module/clr/interp_clr.py Thu Feb 1 15:32:38 2007 @@ -84,6 +84,9 @@ elif b_type == typeof(System.Double): floatval = unbox(b_obj, ootype.Float) return space.wrap(floatval) + elif b_type == typeof(System.String): + strval = unbox(b_obj, ootype.String) + return space.wrap(strval) else: msg = "Can't convert object %s to Python" % str(b_obj.ToString()) raise OperationError(space.w_TypeError, space.wrap(msg)) Modified: pypy/dist/pypy/module/clr/test/test_clr.py ============================================================================== --- pypy/dist/pypy/module/clr/test/test_clr.py (original) +++ pypy/dist/pypy/module/clr/test/test_clr.py Thu Feb 1 15:32:38 2007 @@ -114,3 +114,11 @@ x.Add(obj) obj2 = x[0] assert obj is obj2 + + def test_string_wrapping(self): + import clr + ArrayList = clr.load_cli_class('System.Collections', 'ArrayList') + x = ArrayList() + x.Add("bar") + s = x[0] + assert s == "bar" From pedronis at codespeak.net Thu Feb 1 16:00:42 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Thu, 1 Feb 2007 16:00:42 +0100 (CET) Subject: [pypy-svn] r37740 - pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test Message-ID: <20070201150042.E27DD1008B@code0.codespeak.net> Author: pedronis Date: Thu Feb 1 16:00:41 2007 New Revision: 37740 Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_exception.py Log: test showing the problem with malloc "exceptions" not generating segregated exception paths. Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_exception.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_exception.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_exception.py Thu Feb 1 16:00:41 2007 @@ -138,3 +138,28 @@ res = self.timeshift(ll_function, [5], [], policy=P_NOVIRTUAL) assert res == 5 self.check_insns(malloc=0) + + def test_not_segregated_malloc_exception_path(self): + py.test.skip("WIP") + class E(Exception): + def __init__(self, msg): + self.msg = msg + + def help(l, x): + if x < 0: + raise E("x negative: %d" %x) + l.append(x) + return l + + def ll_function(x): + l = [] + l = help(l, x) + return len(l)+x + + res = self.timeshift(ll_function, [5], [], policy=P_OOPSPEC) + res == 6 + self.check_oops(newlist=0) + + + + From cfbolz at codespeak.net Thu Feb 1 16:26:57 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 1 Feb 2007 16:26:57 +0100 (CET) Subject: [pypy-svn] r37744 - pypy/dist/pypy/doc/config Message-ID: <20070201152657.B9F7D10090@code0.codespeak.net> Author: cfbolz Date: Thu Feb 1 16:26:57 2007 New Revision: 37744 Modified: pypy/dist/pypy/doc/config/objspace.allworkingmodules.txt pypy/dist/pypy/doc/config/objspace.geninterp.txt pypy/dist/pypy/doc/config/objspace.std.oldstyle.txt pypy/dist/pypy/doc/config/objspace.std.withprebuiltint.txt pypy/dist/pypy/doc/config/objspace.std.withrangelist.txt pypy/dist/pypy/doc/config/objspace.std.withstrjoin.txt pypy/dist/pypy/doc/config/objspace.std.withstrslice.txt pypy/dist/pypy/doc/config/objspace.std.withtypeversion.txt Log: start a rough documentation of some of the options. Modified: pypy/dist/pypy/doc/config/objspace.allworkingmodules.txt ============================================================================== --- pypy/dist/pypy/doc/config/objspace.allworkingmodules.txt (original) +++ pypy/dist/pypy/doc/config/objspace.allworkingmodules.txt Thu Feb 1 16:26:57 2007 @@ -0,0 +1,2 @@ +This option enables the usage of all modules that are known to be working well +and that translate without problem. Modified: pypy/dist/pypy/doc/config/objspace.geninterp.txt ============================================================================== --- pypy/dist/pypy/doc/config/objspace.geninterp.txt (original) +++ pypy/dist/pypy/doc/config/objspace.geninterp.txt Thu Feb 1 16:26:57 2007 @@ -0,0 +1,4 @@ +This option enables `geninterp`_. This will usually make the PyPy interpreter +significantly faster (but also a bit bigger). + +.. _`geninterp`: ../geninterp.html Modified: pypy/dist/pypy/doc/config/objspace.std.oldstyle.txt ============================================================================== --- pypy/dist/pypy/doc/config/objspace.std.oldstyle.txt (original) +++ pypy/dist/pypy/doc/config/objspace.std.oldstyle.txt Thu Feb 1 16:26:57 2007 @@ -0,0 +1,2 @@ +With this option you can enable the use of old-style classes by default. +Normally, all PyPy classes are new-style. Modified: pypy/dist/pypy/doc/config/objspace.std.withprebuiltint.txt ============================================================================== --- pypy/dist/pypy/doc/config/objspace.std.withprebuiltint.txt (original) +++ pypy/dist/pypy/doc/config/objspace.std.withprebuiltint.txt Thu Feb 1 16:26:57 2007 @@ -0,0 +1,6 @@ +This option enables the caching of small integer objects (similar to what +CPython does). The range of which integers are cached can be influenced with the +`objspace.std.prebuiltintfrom`_ and `objspace.std.prebuiltintto`_ options. + +.. _`objspace.std.prebuiltintfrom`: objspace.std.prebuiltintfrom.html +.. _`objspace.std.prebuiltintto`: objspace.std.prebuiltintto.html Modified: pypy/dist/pypy/doc/config/objspace.std.withrangelist.txt ============================================================================== --- pypy/dist/pypy/doc/config/objspace.std.withrangelist.txt (original) +++ pypy/dist/pypy/doc/config/objspace.std.withrangelist.txt Thu Feb 1 16:26:57 2007 @@ -0,0 +1,6 @@ +Enable "range list" objects. They are a different implementation of the Python +``list`` type, indistinguishable for the normal user. Whenever the ``range`` +builtin is called, an range list is returned. As long as this list is not +mutated (and for example only iterated over), it uses only enough memory to +store the start, stop and step of the range. This makes using ``range`` as +efficient as ``xrange``, as long as the result is only used in a ``for``-loop. Modified: pypy/dist/pypy/doc/config/objspace.std.withstrjoin.txt ============================================================================== --- pypy/dist/pypy/doc/config/objspace.std.withstrjoin.txt (original) +++ pypy/dist/pypy/doc/config/objspace.std.withstrjoin.txt Thu Feb 1 16:26:57 2007 @@ -0,0 +1,7 @@ +Enable "string join" objects. They are a different implementation of the Python +``str`` type, indistinguishable for the normal user. They represent the lazy +addition of several strings without actually performing the addition (which +involves copying etc.). When the actual value of the string join object is +needed, the addition is performed. This makes it possible efficiently perform +string additions in a loop without using the ``"".join(list_of_strings)`` +pattern. Modified: pypy/dist/pypy/doc/config/objspace.std.withstrslice.txt ============================================================================== --- pypy/dist/pypy/doc/config/objspace.std.withstrslice.txt (original) +++ pypy/dist/pypy/doc/config/objspace.std.withstrslice.txt Thu Feb 1 16:26:57 2007 @@ -0,0 +1,8 @@ +Enable "string slice" objects. They are a different implementation of the Python +``str`` type, indistinguishable for the normal user. They represent the lazy +slicing of a string without actually performing the slicing (which involves +copying). This is only done for slices of step one. When the actual value of +the string slice object is needed, the slicing is done (although a lot of string +methods don't make this necessary). This makes string slicing a very efficient +operation. It also saves memory in some cases but can also lead to memory leaks, +since the string slice retains a reference to the original string. Modified: pypy/dist/pypy/doc/config/objspace.std.withtypeversion.txt ============================================================================== --- pypy/dist/pypy/doc/config/objspace.std.withtypeversion.txt (original) +++ pypy/dist/pypy/doc/config/objspace.std.withtypeversion.txt Thu Feb 1 16:26:57 2007 @@ -0,0 +1,4 @@ +This (mostly internal) option enables "type versions": Every type object gets an +(only internally visible) version that is updated when the type's dict is +changed. This is e.g. used for invalidating cashes. It does not make sense to +enable this option alone. From antocuni at codespeak.net Thu Feb 1 16:38:36 2007 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Thu, 1 Feb 2007 16:38:36 +0100 (CET) Subject: [pypy-svn] r37747 - pypy/dist/pypy/doc/config Message-ID: <20070201153836.44C89100A7@code0.codespeak.net> Author: antocuni Date: Thu Feb 1 16:38:35 2007 New Revision: 37747 Added: pypy/dist/pypy/doc/config/objspace.usemodules.clr.txt - copied unchanged from r37727, pypy/dist/pypy/doc/config/objspace.usemodules._dotnet.txt Removed: pypy/dist/pypy/doc/config/objspace.usemodules._dotnet.txt Log: rename the module also here. From antocuni at codespeak.net Thu Feb 1 16:41:42 2007 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Thu, 1 Feb 2007 16:41:42 +0100 (CET) Subject: [pypy-svn] r37748 - in pypy/dist/pypy/module/clr: . test Message-ID: <20070201154142.B2BE7100AC@code0.codespeak.net> Author: antocuni Date: Thu Feb 1 16:41:41 2007 New Revision: 37748 Modified: pypy/dist/pypy/module/clr/app_clr.py pypy/dist/pypy/module/clr/interp_clr.py pypy/dist/pypy/module/clr/test/test_clr.py Log: Support for static properties. Modified: pypy/dist/pypy/module/clr/app_clr.py ============================================================================== --- pypy/dist/pypy/module/clr/app_clr.py (original) +++ pypy/dist/pypy/module/clr/app_clr.py Thu Feb 1 16:41:41 2007 @@ -69,6 +69,22 @@ return '' % (self.im_self.__class__.__cliclass__, self.im_name, self.im_self) +class StaticProperty(object): + def __init__(self, fget=None, fset=None): + self.fget = fget + self.fset = fset + + def __get__(self, obj, type_): + return self.fget() + +class MetaCliClassWrapper(type): + def __setattr__(cls, name, value): + obj = cls.__dict__.get(name, None) + if isinstance(obj, StaticProperty): + obj.fset(value) + else: + type.__setattr__(cls, name, value) + class CliClassWrapper(object): __slots__ = ('__cliobj__',) @@ -88,22 +104,27 @@ assert len(indexers) <= 1 if indexers: - name, getter, setter = indexers[0] + name, getter, setter, is_static = indexers[0] + assert not is_static if getter: d['__getitem__'] = d[getter] if setter: d['__setitem__'] = d[setter] - cls = type(classname, (CliClassWrapper,), d) - + cls = MetaCliClassWrapper(classname, (CliClassWrapper,), d) + # we must add properties *after* the class has been created # because we need to store UnboundMethods as getters and setters - for (name, getter, setter) in properties: + for (name, getter, setter, is_static) in properties: fget = None fset = None if getter: fget = getattr(cls, getter) if setter: fset = getattr(cls, setter) - setattr(cls, name, property(fget, fset)) + if is_static: + prop = StaticProperty(fget, fset) + else: + prop = property(fget, fset) + setattr(cls, name, prop) return cls Modified: pypy/dist/pypy/module/clr/interp_clr.py ============================================================================== --- pypy/dist/pypy/module/clr/interp_clr.py (original) +++ pypy/dist/pypy/module/clr/interp_clr.py Thu Feb 1 16:41:41 2007 @@ -93,8 +93,8 @@ def wrap_list_of_tuples(space, lst): list_w = [] - for (a,b,c) in lst: - items_w = [space.wrap(a), space.wrap(b), space.wrap(c)] + for (a,b,c,d) in lst: + items_w = [space.wrap(a), space.wrap(b), space.wrap(c), space.wrap(d)] list_w.append(space.newtuple(items_w)) return space.newlist(list_w) @@ -126,14 +126,18 @@ get_name = None set_name = None if b_prop.get_CanRead(): - get_name = b_prop.GetGetMethod().get_Name() + get_meth = b_prop.GetGetMethod() + get_name = get_meth.get_Name() + is_static = get_meth.get_IsStatic() if b_prop.get_CanWrite(): - set_name = b_prop.GetSetMethod().get_Name() + set_meth = b_prop.GetSetMethod() + set_name = set_meth.get_Name() + is_static = set_meth.get_IsStatic() b_indexparams = b_prop.GetIndexParameters() if len(b_indexparams) == 0: - properties.append((b_prop.get_Name(), get_name, set_name)) + properties.append((b_prop.get_Name(), get_name, set_name, is_static)) else: - indexers.append((b_prop.get_Name(), get_name, set_name)) + indexers.append((b_prop.get_Name(), get_name, set_name, is_static)) w_properties = wrap_list_of_tuples(space, properties) w_indexers = wrap_list_of_tuples(space, indexers) return w_properties, w_indexers Modified: pypy/dist/pypy/module/clr/test/test_clr.py ============================================================================== --- pypy/dist/pypy/module/clr/test/test_clr.py (original) +++ pypy/dist/pypy/module/clr/test/test_clr.py Thu Feb 1 16:41:41 2007 @@ -122,3 +122,11 @@ x.Add("bar") s = x[0] assert s == "bar" + + def test_static_property(self): + import clr + import os + Environment = clr.load_cli_class('System', 'Environment') + assert Environment.CurrentDirectory == os.getcwd() + Environment.CurrentDirectory == '/' + assert Environment.CurrentDirectory == os.getcwd() From cfbolz at codespeak.net Thu Feb 1 16:43:01 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 1 Feb 2007 16:43:01 +0100 (CET) Subject: [pypy-svn] r37749 - in pypy/dist/pypy/objspace/std: . test Message-ID: <20070201154301.DEAA9100B3@code0.codespeak.net> Author: cfbolz Date: Thu Feb 1 16:43:01 2007 New Revision: 37749 Modified: pypy/dist/pypy/objspace/std/strjoinobject.py pypy/dist/pypy/objspace/std/test/test_strjoinobject.py Log: yet another str join bug :-( Modified: pypy/dist/pypy/objspace/std/strjoinobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/strjoinobject.py (original) +++ pypy/dist/pypy/objspace/std/strjoinobject.py Thu Feb 1 16:43:01 2007 @@ -50,7 +50,7 @@ def add__StringJoin_StringJoin(space, w_self, w_other): if len(w_self.joined_strs) > w_self.until: w_self.force(True) - w_self.joined_strs.extend(w_other.joined_strs) + w_self.joined_strs.extend(w_other.joined_strs[:w_other.until]) return W_StringJoinObject(w_self.joined_strs) def add__StringJoin_String(space, w_self, w_other): @@ -60,14 +60,10 @@ w_self.joined_strs.append(other) return W_StringJoinObject(w_self.joined_strs) -#def add__String_StringJoin(space, w_other, w_self): -# other = space.str_w(w_other) -# return W_StringObject([other] + w_self.joined_strs) - def str__StringJoin(space, w_str): - if type(w_str) is W_StringJoinObject: - return w_str - return W_StringJoinObject(w_str.joined_strs) + # you cannot get subclasses of W_StringObject here + assert type(w_str) is W_StringJoinObject + return w_str from pypy.objspace.std import stringtype register_all(vars(), stringtype) Modified: pypy/dist/pypy/objspace/std/test/test_strjoinobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/test/test_strjoinobject.py (original) +++ pypy/dist/pypy/objspace/std/test/test_strjoinobject.py Thu Feb 1 16:43:01 2007 @@ -62,3 +62,11 @@ u = s + 'd' v = s + 'e' assert v == 'abe' # meaning u is abcd + + def test_buh_even_more(self): + a = 'a' + 'b' + b = a + 'c' + c = '0' + '1' + x = c + a + assert x == '01ab' + From cfbolz at codespeak.net Thu Feb 1 19:06:03 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 1 Feb 2007 19:06:03 +0100 (CET) Subject: [pypy-svn] r37757 - pypy/dist/pypy/doc Message-ID: <20070201180603.4BE2610076@code0.codespeak.net> Author: cfbolz Date: Thu Feb 1 19:06:02 2007 New Revision: 37757 Modified: pypy/dist/pypy/doc/project-ideas.txt Log: some optimization ideas from discussions. Modified: pypy/dist/pypy/doc/project-ideas.txt ============================================================================== --- pypy/dist/pypy/doc/project-ideas.txt (original) +++ pypy/dist/pypy/doc/project-ideas.txt Thu Feb 1 19:06:02 2007 @@ -44,21 +44,58 @@ * dictionaries which use a different strategy when very small. -Things we've thought about but not yet implemented include: - -* lists which are specialised for int-only values (for saving memory). - * in-progress: caching the lookups of builtin names (by special forms of dictionaries that can invalidate the caches when they are written to) + + +Things we've thought about but not yet implemented include: + +* try out things like lists of integers and lists of strings to save memory. + This might be based on (boringly) implementing "multilists" in the same + spirit as multidicts. + +* neal norwitz in an old post to pypy-dev: "list slices are + often used for iteration. It would be nice if we didn't need to make + a copy of the list. This becomes difficult since the list could + change during iteration. But we could make a copy in that case at the + time it was modified. I'm not sure if that would be easy or difficult + to implement." This would probably be easy to implement in pypy and could be + based on multilists (see previous item). + * create multiple representations of Unicode string that store the character data in narrower arrays when they can. +* introduce a "call method" bytecode that is used for calls of the form + "a.b(...)". This should allow us to shortcut argument passing, and most + importantly avoid the creation of the bound method object. To be based + on the method shadowing detection optimization already implemented. + +* experiment with optimized global/builtin lookups by e.g. using + callback-on-modify-dictionaries for Module dicts, might be + done using the multidicts. Note however that CALL_LIKELY_BUILTIN already + covers the case of calls to common builtins, so this should probably + focus on global lookups. + Experiments of this kind are really experiments in the sense that we do not know whether they will work well or not and the only way to find out is to try. A project of this nature should provide benchmark results (both timing and memory usage) as much as code. +Some ideas on concrete steps for benchmarking: + +* find a set of real-world applications that can be used as benchmarks + for pypy (ideas: docutils, http://hachoir.org/, moinmoin, ...?) + +* do benchmark runs to see how much speedup the currently written + optimizations give + +* profile pypy-c and it's variants with these benchmarks, identify slow areas + +* try to come up with optimized implementations for these slow areas + + + Start or improve a back-end --------------------------- @@ -87,7 +124,7 @@ PyPy's Just-In-Time compiler relies on two assembler backends for actual code generation, one for PowerPC and the other for i386. Those two backends so far -are mostly working, but nearly no effort has been made to make them produce +are mostly working, but only some effort has been made to make them produce efficient code. This is an area where significant improvements could be made, hopefully without having to understand the full intricacies of the JIT. From cfbolz at codespeak.net Thu Feb 1 19:09:57 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 1 Feb 2007 19:09:57 +0100 (CET) Subject: [pypy-svn] r37759 - pypy/dist/pypy/config Message-ID: <20070201180957.C8E6D10086@code0.codespeak.net> Author: cfbolz Date: Thu Feb 1 19:09:57 2007 New Revision: 37759 Modified: pypy/dist/pypy/config/pypyoption.py Log: fix typo Modified: pypy/dist/pypy/config/pypyoption.py ============================================================================== --- pypy/dist/pypy/config/pypyoption.py (original) +++ pypy/dist/pypy/config/pypyoption.py Thu Feb 1 19:09:57 2007 @@ -110,7 +110,7 @@ requires=[("objspace.std.withsmallint", False)]), IntOption("prebuiltintfrom", "lowest integer which is prebuilt", - default=-5, cmdline="--prebuiltinfrom"), + default=-5, cmdline="--prebuiltintfrom"), IntOption("prebuiltintto", "highest integer which is prebuilt", default=100, cmdline="--prebuiltintto"), From cfbolz at codespeak.net Thu Feb 1 19:11:38 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 1 Feb 2007 19:11:38 +0100 (CET) Subject: [pypy-svn] r37760 - in pypy/dist/pypy/config: . test Message-ID: <20070201181138.D3AA810087@code0.codespeak.net> Author: cfbolz Date: Thu Feb 1 19:11:38 2007 New Revision: 37760 Modified: pypy/dist/pypy/config/config.py pypy/dist/pypy/config/makerestdoc.py pypy/dist/pypy/config/test/test_config.py Log: move the getpaths function to the OptionDescription, to not have to make a Config object only to get the paths. Modified: pypy/dist/pypy/config/config.py ============================================================================== --- pypy/dist/pypy/config/config.py (original) +++ pypy/dist/pypy/config/config.py Thu Feb 1 19:11:38 2007 @@ -151,29 +151,10 @@ result += substr return result - def getpaths(self, include_groups=False, currpath=None): + def getpaths(self, include_groups=False): """returns a list of all paths in self, recursively - - currpath should not be provided (helps with recursion) """ - if currpath is None: - currpath = [] - paths = [] - for option in self._cfgimpl_descr._children: - attr = option._name - if attr.startswith('_cfgimpl'): - continue - value = getattr(self, attr) - if isinstance(value, Config): - if include_groups: - paths.append('.'.join(currpath + [attr])) - currpath.append(attr) - paths += value.getpaths(include_groups=include_groups, - currpath=currpath) - currpath.pop() - else: - paths.append('.'.join(currpath + [attr])) - return paths + return self._cfgimpl_descr.getpaths(include_groups=include_groups) DEFAULT_OPTION_NAME = object() @@ -396,6 +377,30 @@ def add_optparse_option(self, argnames, parser, config): return + def getpaths(self, include_groups=False, currpath=None): + """returns a list of all paths in self, recursively + + currpath should not be provided (helps with recursion) + """ + if currpath is None: + currpath = [] + paths = [] + for option in self._children: + attr = option._name + if attr.startswith('_cfgimpl'): + continue + value = getattr(self, attr) + if isinstance(value, OptionDescription): + if include_groups: + paths.append('.'.join(currpath + [attr])) + currpath.append(attr) + paths += value.getpaths(include_groups=include_groups, + currpath=currpath) + currpath.pop() + else: + paths.append('.'.join(currpath + [attr])) + return paths + class OptHelpFormatter(optparse.IndentedHelpFormatter): Modified: pypy/dist/pypy/config/makerestdoc.py ============================================================================== --- pypy/dist/pypy/config/makerestdoc.py (original) +++ pypy/dist/pypy/config/makerestdoc.py Thu Feb 1 19:11:38 2007 @@ -132,21 +132,20 @@ if path: content.add( Paragraph(Link("back to parent", path + ".html"))) - for elt in [ + content.join( Title("Basic Option Information"), ListItem(Strong("name:"), self._name), ListItem(Strong("description:"), self.doc), - Title("Sub-Options") - ]: - content.add(elt) - conf = Config(self) + Title("Sub-Options")) stack = [] prefix = fullpath curr = content - for subpath in conf.getpaths(include_groups=True): + for subpath in self.getpaths(include_groups=True): subpath = fullpath + "." + subpath - while not subpath.startswith(prefix): + while not (subpath.startswith(prefix) and + subpath[len(prefix)] == "."): curr, prefix = stack.pop() + print subpath, fullpath, curr new = curr.add(ListItem(Link(subpath, subpath + ".html"))) stack.append((curr, prefix)) prefix = subpath Modified: pypy/dist/pypy/config/test/test_config.py ============================================================================== --- pypy/dist/pypy/config/test/test_config.py (original) +++ pypy/dist/pypy/config/test/test_config.py Thu Feb 1 19:11:38 2007 @@ -255,10 +255,13 @@ assert config.getpaths() == ['gc.name', 'gc.dummy', 'gc.float', 'bool', 'objspace', 'wantref', 'str', 'wantframework', 'int'] + assert config.getpaths() == descr.getpaths() assert config.gc.getpaths() == ['name', 'dummy', 'float'] + assert config.gc.getpaths() == descr.gc.getpaths() assert config.getpaths(include_groups=True) == [ 'gc', 'gc.name', 'gc.dummy', 'gc.float', 'bool', 'objspace', 'wantref', 'str', 'wantframework', 'int'] + assert config.getpaths(True) == descr.getpaths(True) def test_underscore_in_option_name(): descr = OptionDescription("opt", "", [ From cfbolz at codespeak.net Thu Feb 1 19:28:07 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 1 Feb 2007 19:28:07 +0100 (CET) Subject: [pypy-svn] r37763 - pypy/extradoc/eu-report Message-ID: <20070201182807.19DB11008D@code0.codespeak.net> Author: cfbolz Date: Thu Feb 1 19:28:04 2007 New Revision: 37763 Added: pypy/extradoc/eu-report/D13.1_Build-_and_Configuration_Tool-interim-2006-02-01.pdf Log: add D13.1 interim report Added: pypy/extradoc/eu-report/D13.1_Build-_and_Configuration_Tool-interim-2006-02-01.pdf ============================================================================== Files (empty file) and pypy/extradoc/eu-report/D13.1_Build-_and_Configuration_Tool-interim-2006-02-01.pdf Thu Feb 1 19:28:04 2007 differ From cfbolz at codespeak.net Thu Feb 1 19:32:28 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 1 Feb 2007 19:32:28 +0100 (CET) Subject: [pypy-svn] r37764 - pypy/dist/pypy/doc Message-ID: <20070201183228.A01031008D@code0.codespeak.net> Author: cfbolz Date: Thu Feb 1 19:32:26 2007 New Revision: 37764 Modified: pypy/dist/pypy/doc/index-report.txt Log: add stub about D13.1 interim report Modified: pypy/dist/pypy/doc/index-report.txt ============================================================================== --- pypy/dist/pypy/doc/index-report.txt (original) +++ pypy/dist/pypy/doc/index-report.txt Thu Feb 1 19:32:26 2007 @@ -12,11 +12,15 @@ Reports of 2007 =============== +`Draft D13.1 Build and Configuration Tool`_ is an interim version of a report +about our build an configuration toolchain as well as the planned Debian +packages. The report is still a draft, all feedback for it is welcome. +*(2007-02-02)* + `Draft D08.2 JIT Compiler Architecture`_ is an interim version of a report about the Architecture and working of our JIT compiler generator. The report is still a draft, all feedback for it is welcome. *(2007-01-28)* - `Draft D02.3 Testing Tool`_ is an interim version of a report about the `py.test`_ testing tool which is part of the `py-lib`_. The report is still a draft, all feedback for it is welcome. *(2007-01-28)* @@ -95,3 +99,4 @@ .. _`Draft D03.1 Extension Compiler`: http://codespeak.net/pypy/extradoc/eu-report/D03.1_Extension_Compiler-interim-2007-01-22.pdf .. _`Draft D02.3 Testing Tool`: http://codespeak.net/pypy/extradoc/eu-report/D02.3_Testing_Framework-interim-2007-01-28.pdf .. _`Draft D08.2 JIT Compiler Architecture`: http://codespeak.net/pypy/extradoc/eu-report/D08.2_JIT_Compiler_Architecture-interim-2007-01-28.pdf +.. _`Draft D13.1 Build and Configuration Tool`: http://codespeak.net/pypy/extradoc/eu-report/D13.1_Build-_and_Configuration_Tool-interim-2006-02-01.pdf From cfbolz at codespeak.net Thu Feb 1 22:48:30 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 1 Feb 2007 22:48:30 +0100 (CET) Subject: [pypy-svn] r37771 - in pypy/dist/pypy/objspace/std: . test Message-ID: <20070201214830.2152D1007F@code0.codespeak.net> Author: cfbolz Date: Thu Feb 1 22:48:28 2007 New Revision: 37771 Modified: pypy/dist/pypy/objspace/std/listobject.py pypy/dist/pypy/objspace/std/test/test_listobject.py Log: add a extend__List_List and inplace_add__List_List implementations to not have to call space.unpackiterable on the other list (which loops over the list, constructs a copy of it, etc, etc). Makes list.extend(list) a lot faster. Modified: pypy/dist/pypy/objspace/std/listobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/listobject.py (original) +++ pypy/dist/pypy/objspace/std/listobject.py Thu Feb 1 22:48:28 2007 @@ -92,6 +92,10 @@ list_extend__List_ANY(space, w_list1, w_iterable2) return w_list1 +def inplace_add__List_List(space, w_list1, w_list2): + list_extend__List_List(space, w_list1, w_list2) + return w_list1 + def mul_list_times(space, w_list, w_times): try: times = space.int_w(w_times) @@ -358,6 +362,10 @@ w_list.wrappeditems.append(w_any) return space.w_None +def list_extend__List_List(space, w_list, w_other): + w_list.wrappeditems += w_other.wrappeditems + return space.w_None + def list_extend__List_ANY(space, w_list, w_any): w_list.wrappeditems += space.unpackiterable(w_any) return space.w_None Modified: pypy/dist/pypy/objspace/std/test/test_listobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/test/test_listobject.py (original) +++ pypy/dist/pypy/objspace/std/test/test_listobject.py Thu Feb 1 22:48:28 2007 @@ -370,6 +370,12 @@ assert l is l0 assert l == [1,2] + def test_extend_iterable(self): + l = l0 = [1] + l.extend(iter([1, 2, 3, 4])) + assert l is l0 + assert l == [1, 1, 2, 3, 4] + def test_sort(self): l = l0 = [1, 5, 3, 0] l.sort() @@ -448,6 +454,12 @@ assert l is l0 assert l == [1,2,3,4,5] + def test_iadd_iterable(self): + l = l0 = [1,2,3] + l += iter([4,5]) + assert l is l0 + assert l == [1,2,3,4,5] + def test_imul(self): l = l0 = [4,3] l *= 2 From cfbolz at codespeak.net Fri Feb 2 00:11:57 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 2 Feb 2007 00:11:57 +0100 (CET) Subject: [pypy-svn] r37775 - pypy/dist/pypy/objspace/std Message-ID: <20070201231157.2B7CE10079@code0.codespeak.net> Author: cfbolz Date: Fri Feb 2 00:11:55 2007 New Revision: 37775 Modified: pypy/dist/pypy/objspace/std/listobject.py Log: at least check for the empty list that we just put there Modified: pypy/dist/pypy/objspace/std/listobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/listobject.py (original) +++ pypy/dist/pypy/objspace/std/listobject.py Fri Feb 2 00:11:55 2007 @@ -32,7 +32,10 @@ w_iterable, = __args__.parse('list', (['sequence'], None, None), # signature [EMPTY_LIST]) # default argument - w_list.wrappeditems = space.unpackiterable(w_iterable) + if w_iterable is EMPTY_LIST: + w_list.wrappeditems = [] + else: + w_list.wrappeditems = space.unpackiterable(w_iterable) def len__List(space, w_list): result = len(w_list.wrappeditems) From cfbolz at codespeak.net Fri Feb 2 00:13:51 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 2 Feb 2007 00:13:51 +0100 (CET) Subject: [pypy-svn] r37777 - pypy/dist/pypy/objspace/std Message-ID: <20070201231351.DF29510089@code0.codespeak.net> Author: cfbolz Date: Fri Feb 2 00:13:51 2007 New Revision: 37777 Modified: pypy/dist/pypy/objspace/std/listobject.py pypy/dist/pypy/objspace/std/listtype.py Log: remove old commented out code Modified: pypy/dist/pypy/objspace/std/listobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/listobject.py (original) +++ pypy/dist/pypy/objspace/std/listobject.py Fri Feb 2 00:13:51 2007 @@ -81,15 +81,6 @@ def add__List_List(space, w_list1, w_list2): return W_ListObject(w_list1.wrappeditems + w_list2.wrappeditems) -#def radd__List_List(space, w_list1, w_list2): -# return W_ListObject(w_list2.wrappeditems + w_list1.wrappeditems) - -##def add__List_ANY(space, w_list, w_any): -## if space.is_true(space.isinstance(w_any, space.w_list)): -## items1_w = w_list.wrappeditems -## items2_w = space.unpackiterable(w_any) -## return W_ListObject(items1_w + items2_w) -## raise FailedToImplement def inplace_add__List_ANY(space, w_list1, w_iterable2): list_extend__List_ANY(space, w_list1, w_iterable2) @@ -139,14 +130,6 @@ return space.w_False i += 1 return space.w_True - #return space.newbool(len(w_list1.wrappeditems) == len(w_list2.wrappeditems)) - -##def eq__List_ANY(space, w_list1, w_any): -## if space.is_true(space.isinstance(w_any, space.w_list)): -## items1_w = w_list1.wrappeditems -## items2_w = space.unpackiterable(w_any) -## return equal_wrappeditems(space, items1_w, items2_w) -## raise FailedToImplement def _min(a, b): if a < b: @@ -183,26 +166,10 @@ return lessthan_unwrappeditems(space, w_list1.wrappeditems, w_list2.wrappeditems) -##def lt__List_ANY(space, w_list1, w_any): -## # XXX: Implement it not unpacking all the elements -## if space.is_true(space.isinstance(w_any, space.w_list)): -## items1_w = w_list1.wrappeditems -## items2_w = space.unpackiterable(w_any) -## return lessthan_unwrappeditems(space, items1_w, items2_w) -## raise FailedToImplement - def gt__List_List(space, w_list1, w_list2): return greaterthan_unwrappeditems(space, w_list1.wrappeditems, w_list2.wrappeditems) -##def gt__List_ANY(space, w_list1, w_any): -## # XXX: Implement it not unpacking all the elements -## if space.is_true(space.isinstance(w_any, space.w_list)): -## items1_w = w_list1.wrappeditems -## items2_w = space.unpackiterable(w_any) -## return greaterthan_unwrappeditems(space, items1_w, items2_w) -## raise FailedToImplement - def delitem__List_ANY(space, w_list, w_idx): idx = space.int_w(w_idx) try: Modified: pypy/dist/pypy/objspace/std/listtype.py ============================================================================== --- pypy/dist/pypy/objspace/std/listtype.py (original) +++ pypy/dist/pypy/objspace/std/listtype.py Fri Feb 2 00:13:51 2007 @@ -30,16 +30,7 @@ list_reversed = SMM('__reversed__', 1, doc='L.__reversed__() -- return a reverse iterator over' ' the list') -## -##list_reversed__ANY = gateway.applevel(''' -## # NOT_RPYTHON -- uses yield -## -## def reversed(lst): -## return iter([x for x in lst[::-1]]) -## # for index in range(len(lst)-1, -1, -1): -## # yield lst[index] -## -##''', filename=__file__).interphook('reversed') + def list_reversed__ANY(space, w_list): from pypy.objspace.std.iterobject import W_ReverseSeqIterObject return W_ReverseSeqIterObject(space, w_list, -1) From mwh at codespeak.net Fri Feb 2 11:10:51 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 2 Feb 2007 11:10:51 +0100 (CET) Subject: [pypy-svn] r37791 - pypy/dist/pypy/jit/codegen/ppc Message-ID: <20070202101051.B16941006E@code0.codespeak.net> Author: mwh Date: Fri Feb 2 11:10:48 2007 New Revision: 37791 Modified: pypy/dist/pypy/jit/codegen/ppc/rgenop.py Log: conditionalize some prints Modified: pypy/dist/pypy/jit/codegen/ppc/rgenop.py ============================================================================== --- pypy/dist/pypy/jit/codegen/ppc/rgenop.py (original) +++ pypy/dist/pypy/jit/codegen/ppc/rgenop.py Fri Feb 2 11:10:48 2007 @@ -423,8 +423,8 @@ allocator = self.allocate(outputargs_gv) if DEBUG_PRINT: before_moves = len(self.insns) - print outputargs_gv - print target.args_gv + print outputargs_gv + print target.args_gv prepare_for_jump( self.insns, outputargs_gv, allocator.var2loc, target, allocator) if DEBUG_PRINT: From mwh at codespeak.net Fri Feb 2 11:14:04 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 2 Feb 2007 11:14:04 +0100 (CET) Subject: [pypy-svn] r37792 - in pypy/dist/pypy/jit/codegen/ppc: . test Message-ID: <20070202101404.D2A1310070@code0.codespeak.net> Author: mwh Date: Fri Feb 2 11:14:02 2007 New Revision: 37792 Modified: pypy/dist/pypy/jit/codegen/ppc/emit_moves.py pypy/dist/pypy/jit/codegen/ppc/rgenop.py pypy/dist/pypy/jit/codegen/ppc/test/test_rgenop.py Log: add an ultra-inefficient ultra-safe version of emit_moves. makes test_from_random_4_direct pass, the matching test of the more efficient emit_moves is still skipped. Modified: pypy/dist/pypy/jit/codegen/ppc/emit_moves.py ============================================================================== --- pypy/dist/pypy/jit/codegen/ppc/emit_moves.py (original) +++ pypy/dist/pypy/jit/codegen/ppc/emit_moves.py Fri Feb 2 11:14:02 2007 @@ -92,3 +92,15 @@ gen.emit_move(tarloc, srcloc) # now safe to do our move data.emitted.append(tarvar) return + +def emit_moves_safe(gen, tarvars, tar2src, tar2loc, src2loc): + second_moves = [] + for tarvar in tarvars: + srcvar = tar2src[tarvar] + srcloc = src2loc[srcvar] + freshloc = gen.create_fresh_location() + gen.emit_move(freshloc, srcloc) + second_moves.append((tar2loc[tarvar], freshloc)) + + for tarloc, freshloc in second_moves: + gen.emit_move(tarloc, freshloc) Modified: pypy/dist/pypy/jit/codegen/ppc/rgenop.py ============================================================================== --- pypy/dist/pypy/jit/codegen/ppc/rgenop.py (original) +++ pypy/dist/pypy/jit/codegen/ppc/rgenop.py Fri Feb 2 11:14:02 2007 @@ -12,7 +12,7 @@ from pypy.jit.codegen.ppc.instruction import rSP, rFP, rSCRATCH, gprs from pypy.jit.codegen.ppc import instruction as insn from pypy.jit.codegen.ppc.regalloc import RegisterAllocation -from pypy.jit.codegen.ppc.emit_moves import emit_moves +from pypy.jit.codegen.ppc.emit_moves import emit_moves, emit_moves_safe from pypy.translator.asm.ppcgen.rassemblermaker import make_rassembler from pypy.translator.asm.ppcgen.ppc_assembler import MyPPCAssembler @@ -182,7 +182,7 @@ tarvars.append(tloc) gen = JumpPatchupGenerator(insns, allocator) - emit_moves(gen, tarvars, tar2src, tar2loc, src2loc) + emit_moves_safe(gen, tarvars, tar2src, tar2loc, src2loc) for i in range(len(targetlocs)): tloc = targetlocs[i] Modified: pypy/dist/pypy/jit/codegen/ppc/test/test_rgenop.py ============================================================================== --- pypy/dist/pypy/jit/codegen/ppc/test/test_rgenop.py (original) +++ pypy/dist/pypy/jit/codegen/ppc/test/test_rgenop.py Fri Feb 2 11:14:02 2007 @@ -25,9 +25,6 @@ def test_read_frame_place_direct(self): py.test.skip("in-progress") def test_read_frame_place_compile(self): py.test.skip("in-progress") - def test_from_random_4_direct(self): - py.test.skip("failing :( -- see test_one_to_many in test_emit_moves") - class TestRPPCGenopNoRegs(TestRPPCGenop): RGenOp = FewRegisters From arigo at codespeak.net Fri Feb 2 11:25:18 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 2 Feb 2007 11:25:18 +0100 (CET) Subject: [pypy-svn] r37793 - pypy/dist/pypy/doc Message-ID: <20070202102518.35CE310078@code0.codespeak.net> Author: arigo Date: Fri Feb 2 11:25:16 2007 New Revision: 37793 Modified: pypy/dist/pypy/doc/index.txt Log: Update links to daily test runs. Modified: pypy/dist/pypy/doc/index.txt ============================================================================== --- pypy/dist/pypy/doc/index.txt (original) +++ pypy/dist/pypy/doc/index.txt Fri Feb 2 11:25:16 2007 @@ -121,11 +121,8 @@ an attempt to keep some focus. So PyPy requires a 32-bit machine or OS for now. -*Some links below are broken because of hardware failure of the -snake server - PyPy kills machines :-)* - PyPy's own tests, daily updated, `on Linux`_ and `on Windows`_ and -on `build pypy-c`_ (various variants). +on build pypy-c (not available at the moment). `Nightly builds and benchmarks`_ of PyPy to C, CLI and LLVM. @@ -158,11 +155,10 @@ .. _`bytecode interpreter`: interpreter.html .. _`EU reports`: index-report.html .. _`garbage collection`: garbage_collection.html -.. _`on Linux`: http://snake.cs.uni-duesseldorf.de/pypytest/summary.html +.. _`on Linux`: http://wyvern.cs.uni-duesseldorf.de/pypytest/summary.html .. _`on Windows`: http://scottdial.com/pypytest/summary.html .. _`ideas for PyPy related projects`: project-ideas.html .. _`Nightly builds and benchmarks`: http://tuatara.cs.uni-duesseldorf.de/benchmark.html -.. _`build pypy-c`: http://snake.cs.uni-duesseldorf.de/pypy-c-tests/ .. _`directory reference`: .. _`rlib`: rlib.html From arigo at codespeak.net Fri Feb 2 11:32:58 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 2 Feb 2007 11:32:58 +0100 (CET) Subject: [pypy-svn] r37794 - pypy/dist/pypy/doc Message-ID: <20070202103258.6BB031007F@code0.codespeak.net> Author: arigo Date: Fri Feb 2 11:32:57 2007 New Revision: 37794 Modified: pypy/dist/pypy/doc/extradoc.txt Log: Update IronPython links. Add a link to Tunes, to give the world a reference to the webarchive-saved list of programming languages :-) Modified: pypy/dist/pypy/doc/extradoc.txt ============================================================================== --- pypy/dist/pypy/doc/extradoc.txt (original) +++ pypy/dist/pypy/doc/extradoc.txt Fri Feb 2 11:32:57 2007 @@ -128,18 +128,20 @@ * Jython_ is a Python implementation in Java. -* `Iron Python`_ a new Python implementation compiling Python into +* IronPython_ a new Python implementation compiling Python into Microsofts Common Language Runtime (CLR) Intermediate Language (IL). * `GNU lightning`_ generates assembly language at runtime. +* Tunes_ is not entierely unrelated. (See also the `review of + programming languages`_.) + .. _`CLR under the hood`: http://download.microsoft.com/download/2/4/d/24dfac0e-fec7-4252-91b9-fb2310603f14/CLRUnderTheHood.BradA.ppt .. _Stackless: http://stackless.com .. _Psyco: http://psyco.sourceforge.net .. _Jython: http://www.jython.org .. _`Squeak`: http://www.squeak.org/ .. _`Croquet`: http://www.opencroquet.org/ -.. _`Iron Python`: http://www.gotdotnet.com/workspaces/workspace.aspx?id=ad7acff7-ab1e-4bcb-99c0-57ac5a3a9742 .. _`transparent dynamic optimization`: http://www.hpl.hp.com/techreports/1999/HPL-1999-77.pdf .. _Dynamo: http://www.hpl.hp.com/techreports/1999/HPL-1999-78.pdf .. _testdesign: http://codespeak.net/pypy/dist/pypy/doc/coding-guide.html#test-design @@ -147,6 +149,8 @@ .. _rock: http://codespeak.net/pipermail/pypy-dev/2004q1/001255.html .. _`GNU lightning`: http://www.gnu.org/software/lightning/lightning.html .. _LLVM: http://llvm.org/ -.. _IronPython: http://www.python.org/pycon/dc2004/papers/9/ +.. _IronPython: http://www.codeplex.com/Wiki/View.aspx?ProjectName=IronPython .. _`Dynamic Native Optimization of Native Interpreters`: http://www.ai.mit.edu/~gregs/dynamorio.html .. _JikesRVM: http://jikesrvm.sf.net +.. _Tunes: http://tunes.org +.. _`review of programming languages`: http://web.archive.org/web/20050205011706/cliki.tunes.org/Programming+Languages From guido at codespeak.net Fri Feb 2 12:40:11 2007 From: guido at codespeak.net (guido at codespeak.net) Date: Fri, 2 Feb 2007 12:40:11 +0100 (CET) Subject: [pypy-svn] r37797 - pypy/dist/pypy/translator/js/demo/jsdemo Message-ID: <20070202114011.3DB841005A@code0.codespeak.net> Author: guido Date: Fri Feb 2 12:40:09 2007 New Revision: 37797 Modified: pypy/dist/pypy/translator/js/demo/jsdemo/pythonconsole.py Log: Replacing some code that writed to .innerHTML with 'nicer' DOM stuff (untested!). Modified: pypy/dist/pypy/translator/js/demo/jsdemo/pythonconsole.py ============================================================================== --- pypy/dist/pypy/translator/js/demo/jsdemo/pythonconsole.py (original) +++ pypy/dist/pypy/translator/js/demo/jsdemo/pythonconsole.py Fri Feb 2 12:40:09 2007 @@ -15,7 +15,6 @@ from pypy.translator.js.modules.dom import setTimeout, document from pypy.rpython.ootypesystem.bltregistry import MethodDesc, BasicExternal from pypy.translator.js import commproxy -from pypy.translator.js.modules.mochikit import escapeHTML from pypy.rpython.extfunc import _callable from pypy.translator.js.demo.jsdemo import support @@ -55,7 +54,7 @@ def add_text(text): data_elem = document.getElementById("data") - data_elem.innerHTML += escapeHTML(text) + data_elem.appendChild(document.createTextNode(text)) class Storage(object): def __init__(self): From arigo at codespeak.net Fri Feb 2 12:41:04 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 2 Feb 2007 12:41:04 +0100 (CET) Subject: [pypy-svn] r37798 - pypy/dist/pypy/translator/js/demo/jsdemo Message-ID: <20070202114104.C493710069@code0.codespeak.net> Author: arigo Date: Fri Feb 2 12:41:04 2007 New Revision: 37798 Modified: pypy/dist/pypy/translator/js/demo/jsdemo/example.py Log: Argh argh argh argh argh IE7. Modified: pypy/dist/pypy/translator/js/demo/jsdemo/example.py ============================================================================== --- pypy/dist/pypy/translator/js/demo/jsdemo/example.py (original) +++ pypy/dist/pypy/translator/js/demo/jsdemo/example.py Fri Feb 2 12:41:04 2007 @@ -22,7 +22,7 @@ Example - This is a test!
From fijal at codespeak.net Fri Feb 2 12:52:55 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 2 Feb 2007 12:52:55 +0100 (CET) Subject: [pypy-svn] r37799 - pypy/dist/pypy/translator/js/demo/jsdemo Message-ID: <20070202115255.F3E9010079@code0.codespeak.net> Author: fijal Date: Fri Feb 2 12:52:53 2007 New Revision: 37799 Modified: pypy/dist/pypy/translator/js/demo/jsdemo/bnb.py pypy/dist/pypy/translator/js/demo/jsdemo/controllers.py pypy/dist/pypy/translator/js/demo/jsdemo/pythonconsole.py Log: Add _callable instead of simple lambdas Modified: pypy/dist/pypy/translator/js/demo/jsdemo/bnb.py ============================================================================== --- pypy/dist/pypy/translator/js/demo/jsdemo/bnb.py (original) +++ pypy/dist/pypy/translator/js/demo/jsdemo/bnb.py Fri Feb 2 12:52:53 2007 @@ -68,8 +68,6 @@ self.seen = set() return to_ret -lambda_None = _callable([]) - # Needed double inheritance for both server job # and semi-transparent communication proxy class BnbRoot(Root, BasicExternal): @@ -90,12 +88,12 @@ _render_xmlhttp = True _methods = { - 'get_message' : MethodDesc( [('player_id', int), ('keys' , str), ('callback', lambda_None)] , {str:[{str:str}]}), - 'add_player' : MethodDesc( [('player_id', int), ('callback', lambda_None)] , {str:[{str:str}]}), - 'remove_player': MethodDesc( [('player_id', int), ('callback', lambda_None)] , {str:[{str:str}]}), - 'player_name' : MethodDesc( [('player_id', int), ('name', str), ('callback', lambda_None)] , {str:[{str:str}]}), + 'get_message' : MethodDesc( [('player_id', int), ('keys' , str), ('callback', _callable([{str:[{str:str}]}]))] , {str:[{str:str}]}), + 'add_player' : MethodDesc( [('player_id', int), ('callback', _callable([{str:[{str:str}]}]))] , {str:[{str:str}]}), + 'remove_player': MethodDesc( [('player_id', int), ('callback', _callable([{str:[{str:str}]}]))] , {str:[{str:str}]}), + 'player_name' : MethodDesc( [('player_id', int), ('name', str), ('callback', _callable([{str:[{str:str}]}]))] , {str:[{str:str}]}), # 'key' : MethodDesc( [('player_id', 0), ('keynum', '0'), ('callback', (lambda : None))] , {'aa':[{'aa':'bb'}]}), - 'initialize_session' : MethodDesc( [('callback', lambda_None)], {str:str}), + 'initialize_session' : MethodDesc( [('callback', _callable([{str:str}]))], {str:str}), } def add_player(self, player_id = 0): Modified: pypy/dist/pypy/translator/js/demo/jsdemo/controllers.py ============================================================================== --- pypy/dist/pypy/translator/js/demo/jsdemo/controllers.py (original) +++ pypy/dist/pypy/translator/js/demo/jsdemo/controllers.py Fri Feb 2 12:52:53 2007 @@ -5,7 +5,7 @@ import autopath from pypy.translator.js.test.runtest import compile_function -from pypy.translator.js.modules import dom,xmlhttp +from pypy.translator.js.modules import dom from pypy.translator.js.modules.dom import document import thread @@ -24,7 +24,7 @@ def esc_html(data): return data.replace("&", "&").replace("<", "<").replace(">", ">") \ .replace("\n", "
").replace(" ", " ") - + class Root(controllers.Root): def __init__(self): self.lock = thread.allocate_lock() Modified: pypy/dist/pypy/translator/js/demo/jsdemo/pythonconsole.py ============================================================================== --- pypy/dist/pypy/translator/js/demo/jsdemo/pythonconsole.py (original) +++ pypy/dist/pypy/translator/js/demo/jsdemo/pythonconsole.py Fri Feb 2 12:52:53 2007 @@ -21,9 +21,8 @@ commproxy.USE_MOCHIKIT = True -from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler -#from SimpleHTTPServer import SimpleHTTPRequestHandler - +from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer +from SocketServer import ThreadingMixIn HTML_PAGE = """ From arigo at codespeak.net Fri Feb 2 13:03:41 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 2 Feb 2007 13:03:41 +0100 (CET) Subject: [pypy-svn] r37800 - pypy/dist/pypy/translator/js Message-ID: <20070202120341.90D411007A@code0.codespeak.net> Author: arigo Date: Fri Feb 2 13:03:40 2007 New Revision: 37800 Modified: pypy/dist/pypy/translator/js/jsbuiltin.py Log: Render string[index] with the charAt() method. Modified: pypy/dist/pypy/translator/js/jsbuiltin.py ============================================================================== --- pypy/dist/pypy/translator/js/jsbuiltin.py (original) +++ pypy/dist/pypy/translator/js/jsbuiltin.py Fri Feb 2 13:03:40 2007 @@ -32,7 +32,7 @@ ootype.String.__class__: { 'll_strconcat' : InstructionList([PushAllArgs, '+']), 'll_strlen' : lambda g,op: GetBuiltinField.run_it(g, op.args[1], 'length'), - 'll_stritem_nonneg' : ListGetitem, + 'll_stritem_nonneg' : lambda g, op: Call._render_builtin_method(g, 'charAt', [op.args[1], op.args[2]]), 'll_streq' : InstructionList([PushAllArgs, '==']), 'll_strcmp' : CallBuiltin('strcmp'), 'll_startswith' : CallBuiltin('startswith'), From fijal at codespeak.net Fri Feb 2 13:14:08 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 2 Feb 2007 13:14:08 +0100 (CET) Subject: [pypy-svn] r37802 - pypy/dist/pypy/translator/js/test Message-ID: <20070202121408.397EF10068@code0.codespeak.net> Author: fijal Date: Fri Feb 2 13:14:04 2007 New Revision: 37802 Removed: pypy/dist/pypy/translator/js/test/test_merge_if_blocks.py Log: This test makes no sense at all From fijal at codespeak.net Fri Feb 2 13:14:56 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 2 Feb 2007 13:14:56 +0100 (CET) Subject: [pypy-svn] r37803 - pypy/dist/pypy/translator/js/test Message-ID: <20070202121456.A2EEB10081@code0.codespeak.net> Author: fijal Date: Fri Feb 2 13:14:48 2007 New Revision: 37803 Added: pypy/dist/pypy/translator/js/test/test_rsnippet.py - copied unchanged from r37798, pypy/dist/pypy/translator/js/test/test_genllvm.py pypy/dist/pypy/translator/js/test/test_rsnippet1.py - copied unchanged from r37798, pypy/dist/pypy/translator/js/test/test_genllvm1.py Removed: pypy/dist/pypy/translator/js/test/test_genllvm.py pypy/dist/pypy/translator/js/test/test_genllvm1.py Log: Move deprecated filenames From fijal at codespeak.net Fri Feb 2 13:16:50 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 2 Feb 2007 13:16:50 +0100 (CET) Subject: [pypy-svn] r37804 - in pypy/dist/pypy/translator/js: examples modules test Message-ID: <20070202121650.F29A810080@code0.codespeak.net> Author: fijal Date: Fri Feb 2 13:16:46 2007 New Revision: 37804 Added: pypy/dist/pypy/translator/js/test/test_extfunc.py Modified: pypy/dist/pypy/translator/js/examples/start_bnb.py pypy/dist/pypy/translator/js/modules/dom.py Log: Move setTimeout to new extfunc interface Modified: pypy/dist/pypy/translator/js/examples/start_bnb.py ============================================================================== --- pypy/dist/pypy/translator/js/examples/start_bnb.py (original) +++ pypy/dist/pypy/translator/js/examples/start_bnb.py Fri Feb 2 13:16:46 2007 @@ -92,7 +92,6 @@ def hide_sprite(self, s): i = self.sprites[s] i.style.visibility = "hidden" - #pass def start_clean_sprites(self): self.all_sprites = {} @@ -141,14 +140,14 @@ km = KeyManager() def appendPlayfield(msg): - bgcolor = '#000000' + bgcolor = '#FFF' document.body.setAttribute('bgcolor', bgcolor) div = document.createElement("div") div.setAttribute("id", "playfield") div.setAttribute('width', msg['width']) div.setAttribute('height', msg['height']) div.setAttribute('style', 'position:absolute; top:0px; left:0px') - document.body.appendChild(div) + document.body.childNodes.insert(0, div) def appendPlayfieldXXX(): bgcolor = '#000000' Modified: pypy/dist/pypy/translator/js/modules/dom.py ============================================================================== --- pypy/dist/pypy/translator/js/modules/dom.py (original) +++ pypy/dist/pypy/translator/js/modules/dom.py Fri Feb 2 13:16:46 2007 @@ -21,7 +21,8 @@ from pypy.rpython.ootypesystem.bltregistry import BasicExternal, MethodDesc from pypy.rlib.nonconst import NonConstant -from pypy.translator.stackless.test.test_transform import one +#from pypy.translator.stackless.test.test_transform import one +from pypy.rpython.extfunc import _callable, register_external from xml.dom import minidom from pypy.annotation.signature import annotation @@ -306,12 +307,10 @@ def some_fun(): pass - + def setTimeout(func, delay): - if one(): - setTimeout(some_fun, delay) - else: - func() + pass +register_external(setTimeout, args=[_callable([]), int], result=None) window = Window() document = window.document @@ -700,6 +699,7 @@ 'shiftKey': bool, }) +# XXX: Right now this is only way to get it rendered setTimeout.suggested_primitive = True # the following code wraps minidom nodes with Node classes, and makes Added: pypy/dist/pypy/translator/js/test/test_extfunc.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/js/test/test_extfunc.py Fri Feb 2 13:16:46 2007 @@ -0,0 +1,18 @@ + +""" Some external functions tests +""" + +from pypy.translator.js.test.runtest import compile_function, check_source_contains +from pypy.rpython.extfunc import _callable + +def test_set_timeout(): + from pypy.translator.js.modules.dom import setTimeout + + def to_timeout(): + pass + + def s_timeout_call(): + setTimeout(to_timeout, 300) + + c = compile_function(s_timeout_call, []) + assert check_source_contains(c, "setTimeout \( 'to_timeout\(\)',300 \)") From fijal at codespeak.net Fri Feb 2 13:17:24 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 2 Feb 2007 13:17:24 +0100 (CET) Subject: [pypy-svn] r37805 - pypy/dist/pypy/translator/js/modules Message-ID: <20070202121724.188BA1008B@code0.codespeak.net> Author: fijal Date: Fri Feb 2 13:17:17 2007 New Revision: 37805 Modified: pypy/dist/pypy/translator/js/modules/dom.py Log: Kill dead code Modified: pypy/dist/pypy/translator/js/modules/dom.py ============================================================================== --- pypy/dist/pypy/translator/js/modules/dom.py (original) +++ pypy/dist/pypy/translator/js/modules/dom.py Fri Feb 2 13:17:17 2007 @@ -21,7 +21,6 @@ from pypy.rpython.ootypesystem.bltregistry import BasicExternal, MethodDesc from pypy.rlib.nonconst import NonConstant -#from pypy.translator.stackless.test.test_transform import one from pypy.rpython.extfunc import _callable, register_external from xml.dom import minidom From ericvrp at codespeak.net Fri Feb 2 14:17:38 2007 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Fri, 2 Feb 2007 14:17:38 +0100 (CET) Subject: [pypy-svn] r37806 - pypy/dist/pypy/jit/codegen/llvm/test Message-ID: <20070202131738.E767210078@code0.codespeak.net> Author: ericvrp Date: Fri Feb 2 14:17:37 2007 New Revision: 37806 Modified: pypy/dist/pypy/jit/codegen/llvm/test/test_genc_ts.py Log: skip these llvm frame var tests until frame vars are supported Modified: pypy/dist/pypy/jit/codegen/llvm/test/test_genc_ts.py ============================================================================== --- pypy/dist/pypy/jit/codegen/llvm/test/test_genc_ts.py (original) +++ pypy/dist/pypy/jit/codegen/llvm/test/test_genc_ts.py Fri Feb 2 14:17:37 2007 @@ -27,3 +27,9 @@ test_two_loops_merging = skip_too_minimal #segfault test_green_char_at_merge = skip #segfault test_residual_red_call_with_exc = skip + + def test_simple_red_meth(self): + py.test.skip('no frame var support yet') + + test_simple_red_meth_vars_around = test_simple_red_meth + From mwh at codespeak.net Fri Feb 2 15:06:17 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 2 Feb 2007 15:06:17 +0100 (CET) Subject: [pypy-svn] r37807 - pypy/dist/pypy/jit/codegen/ppc Message-ID: <20070202140617.0030110084@code0.codespeak.net> Author: mwh Date: Fri Feb 2 15:06:16 2007 New Revision: 37807 Modified: pypy/dist/pypy/jit/codegen/ppc/rgenop.py Log: make sure that when we need a fresh location for before-jump rearrangements, we don't use part of the stack the target block considers important. with this change, the ppc backend passes demo/autorun for several hours and is so probably solid. Modified: pypy/dist/pypy/jit/codegen/ppc/rgenop.py ============================================================================== --- pypy/dist/pypy/jit/codegen/ppc/rgenop.py (original) +++ pypy/dist/pypy/jit/codegen/ppc/rgenop.py Fri Feb 2 15:06:16 2007 @@ -131,13 +131,12 @@ self.allocator = allocator def emit_move(self, tarloc, srcloc): + srcvar = None if DEBUG_PRINT: for v, loc in self.allocator.var2loc.iteritems(): if loc is srcloc: srcvar = v break - else: - srcvar = None emit = self.insns.append if tarloc == srcloc: return @@ -180,6 +179,9 @@ tar2loc[tloc] = tloc tar2src[tloc] = src tarvars.append(tloc) + if not tloc.is_register: + if tloc in allocator.free_stack_slots: + allocator.free_stack_slots.remove(tloc) gen = JumpPatchupGenerator(insns, allocator) emit_moves_safe(gen, tarvars, tar2src, tar2loc, src2loc) @@ -425,6 +427,7 @@ before_moves = len(self.insns) print outputargs_gv print target.args_gv + allocator.spill_offset = min(allocator.spill_offset, target.min_stack_offset) prepare_for_jump( self.insns, outputargs_gv, allocator.var2loc, target, allocator) if DEBUG_PRINT: From cfbolz at codespeak.net Fri Feb 2 15:22:32 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 2 Feb 2007 15:22:32 +0100 (CET) Subject: [pypy-svn] r37808 - in pypy/dist/pypy/objspace/std: . test Message-ID: <20070202142232.542E41008A@code0.codespeak.net> Author: cfbolz Date: Fri Feb 2 15:22:31 2007 New Revision: 37808 Modified: pypy/dist/pypy/objspace/std/listobject.py pypy/dist/pypy/objspace/std/test/test_listobject.py Log: make list.remove safe against list elements with an __eq__ that mutate the list. Before, you could get an interp-level exception :-(. Modified: pypy/dist/pypy/objspace/std/listobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/listobject.py (original) +++ pypy/dist/pypy/objspace/std/listobject.py Fri Feb 2 15:22:31 2007 @@ -376,11 +376,13 @@ def list_remove__List_ANY(space, w_list, w_any): # needs to be safe against eq_w() mutating the w_list behind our back items = w_list.wrappeditems - length = len(items) - for i in range(length): + i = 0 + while i < len(items): if space.eq_w(items[i], w_any): - del items[i] + if i < len(items): # if this is wrong the list was changed + del items[i] return space.w_None + i += 1 raise OperationError(space.w_ValueError, space.wrap("list.remove(x): x not in list")) Modified: pypy/dist/pypy/objspace/std/test/test_listobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/test/test_listobject.py (original) +++ pypy/dist/pypy/objspace/std/test/test_listobject.py Fri Feb 2 15:22:31 2007 @@ -1,4 +1,3 @@ -#from __future__ import nested_scopes import autopath, random from pypy.objspace.std.listobject import W_ListObject from pypy.interpreter.error import OperationError @@ -553,3 +552,28 @@ def test_reversed(self): assert list(list('hello').__reversed__()) == ['o', 'l', 'l', 'e', 'h'] assert list(reversed(list('hello'))) == ['o', 'l', 'l', 'e', 'h'] + + def test_mutate_while_remove(self): + class Mean(object): + def __init__(self, i): + self.i = i + def __eq__(self, other): + if self.i == 9: + del l[i - 1] + return True + else: + return False + l = [Mean(i) for i in range(10)] + # does not crash + l.remove(None) + class Mean2(object): + def __init__(self, i): + self.i = i + def __eq__(self, other): + l.append(self.i) + return False + l = [Mean2(i) for i in range(10)] + # does not crash + l.remove(5) + print l + assert l[10:] == [0, 1, 2, 3, 4, 6, 7, 8, 9] From cfbolz at codespeak.net Fri Feb 2 15:25:14 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 2 Feb 2007 15:25:14 +0100 (CET) Subject: [pypy-svn] r37809 - in pypy/dist/pypy: module/marshal/test objspace/std Message-ID: <20070202142514.D6E2A1008F@code0.codespeak.net> Author: cfbolz Date: Fri Feb 2 15:25:12 2007 New Revision: 37809 Modified: pypy/dist/pypy/module/marshal/test/test_marshal.py pypy/dist/pypy/objspace/std/marshal_impl.py Log: enable marshalling for multidicts 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 Fri Feb 2 15:25:12 2007 @@ -589,3 +589,11 @@ x = marshal.load(f) assert x == case + +class AppTestMultiDict(object): + def setup_class(cls): + from pypy.conftest import gettestobjspace + cls.space = gettestobjspace(**{"objspace.std.withmultidict": True}) + + test__dict__tcid_ = AppTestMarshal.test__dict__tcid_.im_func + test__dict_5_colon__6_comma__7_colon__8_tcid_ = AppTestMarshal.test__dict_5_colon__6_comma__7_colon__8_tcid_.im_func 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 Fri Feb 2 15:25:12 2007 @@ -25,7 +25,8 @@ from pypy.objspace.std.tupleobject import W_TupleObject from pypy.objspace.std.listobject import W_ListObject from pypy.objspace.std.dictobject import W_DictObject -from pypy.objspace.std.dictstrobject import W_DictStrObject +from pypy.objspace.std.dictmultiobject import W_DictMultiObject +from pypy.objspace.std.dictstrobject import W_DictStrObject from pypy.objspace.std.stringobject import W_StringObject from pypy.objspace.std.typeobject import W_TypeObject from pypy.objspace.std.longobject import W_LongObject @@ -328,7 +329,7 @@ def unmarshal_Tuple(space, u, tc): items_w = u.get_list_w() - return W_TupleObject(items_w) + return space.newtuple(items_w) register(TYPE_TUPLE, unmarshal_Tuple) def marshal_w__List(space, w_list, m): @@ -338,10 +339,10 @@ def unmarshal_List(space, u, tc): items_w = u.get_list_w() - return W_ListObject(items_w) + return space.newlist(items_w) def finish_List(space, items_w, typecode): - return W_ListObject(items_w) + return space.newlist(items_w) register(TYPE_LIST, unmarshal_List) def marshal_w__Dict(space, w_dict, m): @@ -351,6 +352,14 @@ m.put_w_obj(w_value) m.atom(TYPE_NULL) +def marshal_w__DictMulti(space, w_dict, m): + m.start(TYPE_DICT) + for w_tuple in w_dict.implementation.items(): + w_key, w_value = space.unpacktuple(w_tuple, 2) + m.put_w_obj(w_key) + m.put_w_obj(w_value) + m.atom(TYPE_NULL) + def marshal_w__DictStr(space, w_dict, m): m.start(TYPE_DICT) if w_dict.content is not None: @@ -526,7 +535,7 @@ w_frozen = space.w_False else: w_frozen = space.w_True - w_lis = W_ListObject(items_w) + w_lis = space.newlist(items_w) return list_to_set(space, w_lis, w_frozen) register(TYPE_SET + TYPE_FROZENSET, unmarshal_set_frozenset) From cfbolz at codespeak.net Fri Feb 2 15:28:54 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 2 Feb 2007 15:28:54 +0100 (CET) Subject: [pypy-svn] r37810 - in pypy/dist/pypy/objspace/std: . test Message-ID: <20070202142854.2C8521007B@code0.codespeak.net> Author: cfbolz Date: Fri Feb 2 15:28:52 2007 New Revision: 37810 Modified: pypy/dist/pypy/objspace/std/rangeobject.py pypy/dist/pypy/objspace/std/test/test_rangeobject.py Log: use FailedToImplement instead of constructing the bound method and calling that, if the rangelist is forced. implement rangelist.pop(0) and rangelist.pop(-1) without forcing the list. Modified: pypy/dist/pypy/objspace/std/rangeobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/rangeobject.py (original) +++ pypy/dist/pypy/objspace/std/rangeobject.py Fri Feb 2 15:28:52 2007 @@ -40,17 +40,16 @@ w_self.w_list = space.newlist([]) return w_self.w_list - arr = [0] * length # this is to avoid using append. + arr = [None] * length # this is to avoid using append. i = start n = 0 while n < length: - arr[n] = i + arr[n] = wrapint(space, i) i += step n += 1 - w_self.w_list = space.newlist([wrapint(space, element) - for element in arr]) + w_self.w_list = space.newlist(arr) return w_self.w_list def getitem(w_self, i): @@ -114,12 +113,33 @@ n += 1 return space.wrap("[" + ", ".join(result) + "]") + +def list_pop__RangeList_ANY(space, w_rangelist, w_idx=-1): + if w_rangelist.w_list is not None: + raise FailedToImplement + length = w_rangelist.length + if length == 0: + raise OperationError(space.w_IndexError, + space.wrap("pop from empty list")) + idx = space.int_w(w_idx) + if idx == 0: + result = w_rangelist.start + w_rangelist.start += w_rangelist.step + w_rangelist.length -= 1 + return wrapint(space, result) + if idx == -1 or idx == length - 1: + w_rangelist.length -= 1 + return wrapint( + space, w_rangelist.start + (length - 1) * w_rangelist.step) + if idx >= w_rangelist.length: + raise OperationError(space.w_IndexError, + space.wrap("pop index out of range")) + raise FailedToImplement + def list_reverse__RangeList(space, w_rangelist): # probably somewhat useless, but well... if w_rangelist.w_list is not None: - w_boundmethod = space.getattr(w_rangelist.w_list, - space.wrap("reverse")) - return space.call_function(w_boundmethod) + raise FailedToImplement w_rangelist.start = w_rangelist.getitem(-1) w_rangelist.step = -w_rangelist.step @@ -128,8 +148,7 @@ # even more useless but fun has_reverse = space.is_true(w_reverse) if w_rangelist.w_list is not None: - w_sort = space.getattr(w_rangelist.w_list, space.wrap("sort")) - return space.call_function(w_sort, w_cmp, w_keyfunc, w_reverse) + raise FailedToImplement if has_reverse: factor = -1 else: Modified: pypy/dist/pypy/objspace/std/test/test_rangeobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/test/test_rangeobject.py (original) +++ pypy/dist/pypy/objspace/std/test/test_rangeobject.py Fri Feb 2 15:28:52 2007 @@ -46,6 +46,11 @@ r.reverse() assert self.not_forced(r) assert r == range(9, -1, -1) + r = range(3) + r[0] = 1 + assert r == [1, 1, 2] + r.reverse() + assert r == [2, 1, 1] def test_sort(self): r = range(10, -1, -1) @@ -61,3 +66,27 @@ assert not self.not_forced(r) r.sort() assert r == range(1, 100) + [999] + + def test_pop(self): + r = range(10) + res = r.pop() + assert res == 9 + assert self.not_forced(r) + assert repr(r) == repr(range(9)) + res = r.pop(0) + assert res == 0 + assert self.not_forced(r) + assert repr(r) == repr(range(1, 9)) + res = r.pop(len(r) - 1) + assert res == 8 + assert self.not_forced(r) + assert repr(r) == repr(range(1, 8)) + res = r.pop(2) + assert res == 3 + assert not self.not_forced(r) + assert r == [1, 2, 4, 5, 6, 7] + res = r.pop(2) + assert res == 4 + assert not self.not_forced(r) + assert r == [1, 2, 5, 6, 7] + From auc at codespeak.net Fri Feb 2 17:20:24 2007 From: auc at codespeak.net (auc at codespeak.net) Date: Fri, 2 Feb 2007 17:20:24 +0100 (CET) Subject: [pypy-svn] r37813 - pypy/dist/pypy/doc Message-ID: <20070202162024.E28A41007D@code0.codespeak.net> Author: auc Date: Fri Feb 2 17:20:23 2007 New Revision: 37813 Modified: pypy/dist/pypy/doc/coding-guide.txt Log: reminder about modules & config options Modified: pypy/dist/pypy/doc/coding-guide.txt ============================================================================== --- pypy/dist/pypy/doc/coding-guide.txt (original) +++ pypy/dist/pypy/doc/coding-guide.txt Fri Feb 2 17:20:23 2007 @@ -828,6 +828,11 @@ The interpreter level expression has a ``space`` binding when it is executed. +Having properly added an entry under pypy/module (e.g. mymodule) +automagically creates a new config option (such as --withmod-mymodule +and --withoutmod-mymodule (the later being the default)) for py.py and +translate.py. + Testing modules in ``pypy/lib`` -------------------------------- From auc at codespeak.net Fri Feb 2 17:21:59 2007 From: auc at codespeak.net (auc at codespeak.net) Date: Fri, 2 Feb 2007 17:21:59 +0100 (CET) Subject: [pypy-svn] r37814 - pypy/dist/pypy/doc Message-ID: <20070202162159.9658E1007D@code0.codespeak.net> Author: auc Date: Fri Feb 2 17:21:57 2007 New Revision: 37814 Modified: pypy/dist/pypy/doc/coding-guide.txt Log: better wording Modified: pypy/dist/pypy/doc/coding-guide.txt ============================================================================== --- pypy/dist/pypy/doc/coding-guide.txt (original) +++ pypy/dist/pypy/doc/coding-guide.txt Fri Feb 2 17:21:57 2007 @@ -828,9 +828,9 @@ The interpreter level expression has a ``space`` binding when it is executed. -Having properly added an entry under pypy/module (e.g. mymodule) -automagically creates a new config option (such as --withmod-mymodule -and --withoutmod-mymodule (the later being the default)) for py.py and +Adding an entry under pypy/module (e.g. mymodule) entails automatic +creation of a new config option (such as --withmod-mymodule and +--withoutmod-mymodule (the later being the default)) for py.py and translate.py. Testing modules in ``pypy/lib`` From arigo at codespeak.net Fri Feb 2 19:38:10 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 2 Feb 2007 19:38:10 +0100 (CET) Subject: [pypy-svn] r37816 - pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test Message-ID: <20070202183810.086CE10061@code0.codespeak.net> Author: arigo Date: Fri Feb 2 19:38:08 2007 New Revision: 37816 Added: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_0tlc.py - copied unchanged from r37804, pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_tlc.py pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_1tl.py - copied unchanged from r37804, pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_tl.py Removed: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_tl.py pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_tlc.py Log: Rename the slower tests so that they are at the beginning of the alphabet, and therefore start running early during distributed testing. From arigo at codespeak.net Fri Feb 2 20:35:32 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 2 Feb 2007 20:35:32 +0100 (CET) Subject: [pypy-svn] r37819 - in pypy/branch/jit-virtual-world/pypy/rpython: . ootypesystem test Message-ID: <20070202193532.9B62410068@code0.codespeak.net> Author: arigo Date: Fri Feb 2 20:35:23 2007 New Revision: 37819 Modified: pypy/branch/jit-virtual-world/pypy/rpython/ootypesystem/rpbc.py pypy/branch/jit-virtual-world/pypy/rpython/rpbc.py pypy/branch/jit-virtual-world/pypy/rpython/test/test_rpbc.py Log: A strange case of method call that showed up in the JIT. Modified: pypy/branch/jit-virtual-world/pypy/rpython/ootypesystem/rpbc.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/rpython/ootypesystem/rpbc.py (original) +++ pypy/branch/jit-virtual-world/pypy/rpython/ootypesystem/rpbc.py Fri Feb 2 20:35:23 2007 @@ -1,4 +1,4 @@ -from pypy.rpython.rmodel import CanBeNull, Repr, inputconst +from pypy.rpython.rmodel import CanBeNull, Repr, inputconst, impossible_repr from pypy.rpython.rpbc import AbstractClassesPBCRepr, AbstractMethodsPBCRepr, \ AbstractMultipleFrozenPBCRepr, MethodOfFrozenPBCRepr, \ AbstractFunctionsPBCRepr, AbstractMultipleUnrelatedFrozenPBCRepr, \ @@ -132,7 +132,10 @@ assert meth is not None, 'Missing method %s in class %s'\ % (derived_mangled, self.r_im_self.lowleveltype) v = hop.genop("oosend", [cname]+vlist, resulttype=rresult) - return hop.llops.convertvar(v, rresult, hop.r_result) + if hop.r_result is impossible_repr: + return None # see test_always_raising_methods + else: + return hop.llops.convertvar(v, rresult, hop.r_result) def _get_shape_index_callfamily(self, opname, s_pbc, args_s): bk = self.rtyper.annotator.bookkeeper Modified: pypy/branch/jit-virtual-world/pypy/rpython/rpbc.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/rpython/rpbc.py (original) +++ pypy/branch/jit-virtual-world/pypy/rpython/rpbc.py Fri Feb 2 20:35:23 2007 @@ -8,7 +8,7 @@ typeOf, Void, Bool, nullptr, frozendict, Ptr, Struct, malloc from pypy.rpython.error import TyperError from pypy.rpython.rmodel import Repr, inputconst, HalfConcreteWrapper, CanBeNull, \ - mangle, inputdesc, warning + mangle, inputdesc, warning, impossible_repr from pypy.rpython import rclass from pypy.rpython import robject @@ -330,7 +330,10 @@ else: vlist.append(hop.inputconst(Void, row_of_graphs.values())) v = hop.genop('indirect_call', vlist, resulttype = rresult) - return hop.llops.convertvar(v, rresult, hop.r_result) + if hop.r_result is impossible_repr: + return None # see test_always_raising_methods + else: + return hop.llops.convertvar(v, rresult, hop.r_result) class __extend__(pairtype(AbstractFunctionsPBCRepr, AbstractFunctionsPBCRepr)): def convert_from_to((r_fpbc1, r_fpbc2), v, llops): Modified: pypy/branch/jit-virtual-world/pypy/rpython/test/test_rpbc.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/rpython/test/test_rpbc.py (original) +++ pypy/branch/jit-virtual-world/pypy/rpython/test/test_rpbc.py Fri Feb 2 20:35:23 2007 @@ -1542,6 +1542,28 @@ assert self.ll_to_string(item0) == "hello" assert item1 == 623 + def test_always_raising_methods(self): + class Base: + def m(self): + raise NotImplementedError + class A(Base): + def m(self): + return 42 + class B(Base): + pass + def f(n): + if n > 3: + o = A() + else: + o = B() + try: + o.m() + except NotImplementedError: + pass + return B().m() + + self.interpret_raises(NotImplementedError, f, [7]) + class TestLLtype(BaseTestRPBC, LLRtypeMixin): pass From arigo at codespeak.net Fri Feb 2 20:55:42 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 2 Feb 2007 20:55:42 +0100 (CET) Subject: [pypy-svn] r37821 - in pypy/branch/jit-virtual-world/pypy/jit/codegen: . dump/test i386 llgraph llvm ppc test Message-ID: <20070202195542.228951006F@code0.codespeak.net> Author: arigo Date: Fri Feb 2 20:55:35 2007 New Revision: 37821 Modified: pypy/branch/jit-virtual-world/pypy/jit/codegen/dump/test/test_rgenop.py pypy/branch/jit-virtual-world/pypy/jit/codegen/i386/rgenop.py pypy/branch/jit-virtual-world/pypy/jit/codegen/llgraph/llimpl.py pypy/branch/jit-virtual-world/pypy/jit/codegen/llgraph/rgenop.py pypy/branch/jit-virtual-world/pypy/jit/codegen/llvm/rgenop.py pypy/branch/jit-virtual-world/pypy/jit/codegen/model.py pypy/branch/jit-virtual-world/pypy/jit/codegen/ppc/rgenop.py pypy/branch/jit-virtual-world/pypy/jit/codegen/test/rgenop_tests.py Log: (arre, pedronis, arigo) Added RGenOp.genzeroconst(kind), convenient for the front-end and allowing the llgraph backend to produce a NULL pointer of precisely the correct type. Easy implementation for the other backends. Modified: pypy/branch/jit-virtual-world/pypy/jit/codegen/dump/test/test_rgenop.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/codegen/dump/test/test_rgenop.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/codegen/dump/test/test_rgenop.py Fri Feb 2 20:55:35 2007 @@ -15,6 +15,9 @@ def compile(self, runner, argtypes): py.test.skip("cannot compile tests for now") + # for the individual tests see + # ====> ../../test/rgenop_tests.py + class Whatever(object): def __eq__(self, other): Modified: pypy/branch/jit-virtual-world/pypy/jit/codegen/i386/rgenop.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/codegen/i386/rgenop.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/codegen/i386/rgenop.py Fri Feb 2 20:55:35 2007 @@ -600,10 +600,14 @@ return AddrConst(lladdr) else: assert 0, "XXX not implemented" - + # attached later constPrebuiltGlobal = global_rgenop.genconst @staticmethod + def genzeroconst(kind): + return zero_const + + @staticmethod @specialize.memo() def fieldToken(T, name): FIELD = getattr(T, name) @@ -694,5 +698,6 @@ global_rgenop = RI386GenOp() RI386GenOp.constPrebuiltGlobal = global_rgenop.genconst +zero_const = AddrConst(llmemory.NULL) MALLOC_SIGTOKEN = RI386GenOp.sigToken(GC_MALLOC.TO) Modified: pypy/branch/jit-virtual-world/pypy/jit/codegen/llgraph/llimpl.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/codegen/llgraph/llimpl.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/codegen/llgraph/llimpl.py Fri Feb 2 20:55:35 2007 @@ -198,6 +198,12 @@ assert not isinstance(llvalue, str) and not isinstance(llvalue, lltype.LowLevelType) return to_opaque_object(v) +def genzeroconst(gv_TYPE): + TYPE = from_opaque_object(gv_TYPE).value + c = flowmodel.Constant(TYPE._defl()) + c.concretetype = TYPE + return to_opaque_object(c) + def _generalcast(T, value): if isinstance(T, lltype.Ptr): return lltype.cast_pointer(T, value) @@ -550,6 +556,7 @@ setannotation(genop, s_ConstOrVar) setannotation(end, None) setannotation(genconst, s_ConstOrVar) +setannotation(genzeroconst, s_ConstOrVar) setannotation(cast, s_ConstOrVar) setannotation(revealconst, lambda s_T, s_gv: annmodel.lltype_to_annotation( s_T.const)) Modified: pypy/branch/jit-virtual-world/pypy/jit/codegen/llgraph/rgenop.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/codegen/llgraph/rgenop.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/codegen/llgraph/rgenop.py Fri Feb 2 20:55:35 2007 @@ -404,6 +404,10 @@ constPrebuiltGlobal = genconst + @staticmethod + def genzeroconst(gv_TYPE): + return LLConst(llimpl.genzeroconst(gv_TYPE.v)) + def replay(self, label, kinds): builder = LLBuilder(self, label.g, llimpl.nullblock) args_gv = builder._newblock(kinds) Modified: pypy/branch/jit-virtual-world/pypy/jit/codegen/llvm/rgenop.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/codegen/llvm/rgenop.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/codegen/llvm/rgenop.py Fri Feb 2 20:55:35 2007 @@ -1,7 +1,7 @@ import py, os from pypy.rlib.objectmodel import specialize from pypy.rpython.lltypesystem import lltype, llmemory -from pypy.rlib.rarithmetic import intmask +from pypy.rlib.rarithmetic import intmask, r_uint from pypy.jit.codegen.model import AbstractRGenOp, GenLabel, GenBuilder from pypy.jit.codegen.model import GenVar, GenConst, CodeGenSwitch from pypy.jit.codegen.llvm import llvmjit @@ -859,6 +859,10 @@ # attached later constPrebuiltGlobal = global_rgenop.genconst @staticmethod + def genzeroconst(kind): + return zero_consts[kind] + + @staticmethod @specialize.memo() def kindToken(T): # turn the type T into the llvm approximation that we'll use here @@ -941,3 +945,11 @@ global_rgenop = RLLVMGenOp() RLLVMGenOp.constPrebuiltGlobal = global_rgenop.genconst +zero_consts = { + pi8: AddrConst(llmemory.NULL), + i1: BoolConst(False), + i8: CharConst('\x00'), + u32: UIntConst(r_uint(0)), + f64: FloatConst(0.0), + i32: IntConst(0), + } Modified: pypy/branch/jit-virtual-world/pypy/jit/codegen/model.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/codegen/model.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/codegen/model.py Fri Feb 2 20:55:35 2007 @@ -261,6 +261,12 @@ # This is for immortal prebuilt data.""" # raise NotImplementedError + #@staticmethod + #def genzeroconst(kind): + # """Get a GenConst containing the value 0 (or NULL) of the + # correct kind.""" + # raise NotImplementedError + def replay(self, label, kinds): '''Return a builder that will "generate" exactly the same code as was already generated, starting from label. kinds is a Modified: pypy/branch/jit-virtual-world/pypy/jit/codegen/ppc/rgenop.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/codegen/ppc/rgenop.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/codegen/ppc/rgenop.py Fri Feb 2 20:55:35 2007 @@ -1060,6 +1060,10 @@ ## @specialize.genconst(0) ## def constPrebuiltGlobal(llvalue): + @staticmethod + def genzeroconst(kind): + return zero_const + def replay(self, label, kinds): return ReplayBuilder(self), [dummy_var] * len(kinds) @@ -1227,3 +1231,4 @@ global_rgenop = RPPCGenOp() RPPCGenOp.constPrebuiltGlobal = global_rgenop.genconst +zero_const = AddrConst(llmemory.NULL) Modified: pypy/branch/jit-virtual-world/pypy/jit/codegen/test/rgenop_tests.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/codegen/test/rgenop_tests.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/codegen/test/rgenop_tests.py Fri Feb 2 20:55:35 2007 @@ -1576,3 +1576,11 @@ res = fnptr(2, 10, 10, 400, 0) assert res == 0 + + def test_genzeroconst(self): + RGenOp = self.RGenOp + gv = RGenOp.genzeroconst(RGenOp.kindToken(lltype.Signed)) + assert gv.revealconst(lltype.Signed) == 0 + P = lltype.Ptr(lltype.Struct('S')) + gv = RGenOp.genzeroconst(RGenOp.kindToken(P)) + assert gv.revealconst(llmemory.Address) == llmemory.NULL From arigo at codespeak.net Fri Feb 2 20:59:07 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 2 Feb 2007 20:59:07 +0100 (CET) Subject: [pypy-svn] r37823 - in pypy/branch/jit-virtual-world/pypy: jit/timeshifter jit/timeshifter/test rpython/lltypesystem Message-ID: <20070202195907.3738510071@code0.codespeak.net> Author: arigo Date: Fri Feb 2 20:59:02 2007 New Revision: 37823 Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/hrtyper.py pypy/branch/jit-virtual-world/pypy/jit/timeshifter/rcontainer.py pypy/branch/jit-virtual-world/pypy/jit/timeshifter/rtimeshift.py pypy/branch/jit-virtual-world/pypy/jit/timeshifter/rvalue.py pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_exception.py pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_promotion.py pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_timeshift.py pypy/branch/jit-virtual-world/pypy/jit/timeshifter/transform.py pypy/branch/jit-virtual-world/pypy/jit/timeshifter/vdict.py pypy/branch/jit-virtual-world/pypy/jit/timeshifter/vlist.py pypy/branch/jit-virtual-world/pypy/rpython/lltypesystem/rclass.py Log: (arre, pedronis, arigo) Add a flag 'known_nonzero' to PtrRedBox. This allows the propagation of the fact that some pointers cannot be NULL, which is essential to get reasonable code out of exception raising. This keeps exception-raising paths separate from regular returns - otherwise the compiler would try to produce code that uses normally the special "-1" value returned in case of error! Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/hrtyper.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/timeshifter/hrtyper.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/timeshifter/hrtyper.py Fri Feb 2 20:59:02 2007 @@ -1049,26 +1049,52 @@ [v_jitstate, var ], self.s_ConstOrVar) - def translate_op_split(self, hop): + def translate_op_split(self, hop, splitfn=rtimeshift.split, + reverse=False): + if splitfn is rtimeshift.split: + nb_fixed_args = 2 + else: + nb_fixed_args = 3 + r_switch = self.getredrepr(lltype.Bool) - GREENS = [v.concretetype for v in hop.args_v[2:]] - greens_r = [self.getgreenrepr(TYPE) for TYPE in GREENS] - vlist = hop.inputargs(r_switch, lltype.Signed, *greens_r) + GREENS = [v.concretetype for v in hop.args_v[nb_fixed_args:]] + extra_r = [self.getgreenrepr(TYPE) for TYPE in GREENS] + if splitfn is not rtimeshift.split: + TYPE = originalconcretetype(hop.args_s[2]) + r_ptrbox = self.getredrepr(TYPE) + extra_r.insert(0, r_ptrbox) + vlist = hop.inputargs(r_switch, lltype.Signed, *extra_r) v_jitstate = hop.llops.getjitstate() v_switch = vlist[0] c_resumepoint = vlist[1] - greens_v = list(self.wrap_green_vars(hop.llops, vlist[2:])) + greens_v = list(self.wrap_green_vars(hop.llops, + vlist[nb_fixed_args:])) s_Int = annmodel.SomeInteger(nonneg=True) args_s = [self.s_JITState, self.s_RedBox, s_Int] - args_s += [self.s_ConstOrVar] * len(greens_v) args_v = [v_jitstate, v_switch, c_resumepoint] + + if splitfn is not rtimeshift.split: + v_ptrbox = vlist[2] + c_reverse = hop.inputconst(lltype.Bool, reverse) + args_s += [self.s_PtrRedBox, annmodel.s_Bool] + args_v += [hop.llops.as_ptrredbox(v_ptrbox), c_reverse ] + + args_s += [self.s_ConstOrVar] * len(greens_v) args_v += greens_v - return hop.llops.genmixlevelhelpercall(rtimeshift.split, + return hop.llops.genmixlevelhelpercall(splitfn, args_s, args_v, annmodel.SomeBool()) + def translate_op_split_ptr_nonzero(self, hop): + return self.translate_op_split(hop, rtimeshift.split_ptr_nonzero, + reverse=False) + + def translate_op_split_ptr_iszero(self, hop): + return self.translate_op_split(hop, rtimeshift.split_ptr_nonzero, + reverse=True) + def translate_op_collect_split(self, hop): GREENS = [v.concretetype for v in hop.args_v[1:]] greens_r = [self.getgreenrepr(TYPE) for TYPE in GREENS] @@ -1590,8 +1616,7 @@ typedesc.redirected_fielddescs]) TYPE = self.original_concretetype kind = self.hrtyper.RGenOp.kindToken(TYPE) - boxcls = rvalue.ll_redboxcls(TYPE) - + def make_arg_redbox(jitstate, inputargs_gv, i): box = typedesc.factory() jitstate.add_virtualizable(box) @@ -1601,9 +1626,12 @@ gv_outside = inputargs_gv[i] i += 1 for name, j in names: - content_boxes[j].genvar = inputargs_gv[i] + content_boxes[j] = rvalue.PtrRedBox(content_boxes[j].kind, + inputargs_gv[i]) i += 1 - content_boxes[-1].genvar = gv_outside + content_boxes[-1] = rvalue.PtrRedBox(content_boxes[-1].kind, + gv_outside, + known_nonzero = True) return box self.make_arg_redbox = make_arg_redbox Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/rcontainer.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/timeshifter/rcontainer.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/timeshifter/rcontainer.py Fri Feb 2 20:59:02 2007 @@ -178,7 +178,7 @@ vstruct = self.VirtualStructCls(self) vstruct.content_boxes = [desc.makedefaultbox() for desc in self.fielddescs] - box = rvalue.PtrRedBox(self.innermostdesc.ptrkind) + box = rvalue.PtrRedBox(self.innermostdesc.ptrkind, known_nonzero=True) box.content = vstruct vstruct.ownbox = box return box @@ -191,7 +191,8 @@ gv_size = sizebox.getgenvar(jitstate) alloctoken = contdesc.varsizealloctoken genvar = jitstate.curbuilder.genop_malloc_varsize(alloctoken, gv_size) - return rvalue.PtrRedBox(contdesc.ptrkind, genvar) + # XXX MemoryError checking + return rvalue.PtrRedBox(contdesc.ptrkind, genvar, known_nonzero=True) class VirtualizableStructTypeDesc(StructTypeDesc): @@ -353,6 +354,7 @@ gv_default = None canbevirtual = False gcref = False + fieldnonnull = False def __init__(self, hrtyper, PTRTYPE, RESTYPE): RGenOp = hrtyper.RGenOp @@ -361,6 +363,7 @@ if isinstance(RESTYPE, lltype.ContainerType): T = RESTYPE RESTYPE = lltype.Ptr(RESTYPE) + self.fieldnonnull = True elif isinstance(RESTYPE, lltype.Ptr): T = RESTYPE.TO if hasattr(T, '_hints'): @@ -373,6 +376,7 @@ self.canbevirtual = True else: T = None + self.fieldnonnull = PTRTYPE.TO._hints.get('shouldntbenull', False) self.RESTYPE = RESTYPE self.ptrkind = RGenOp.kindToken(PTRTYPE) self.kind = RGenOp.kindToken(RESTYPE) @@ -400,7 +404,11 @@ assert isinstance(content, VirtualizableStruct) content.load_from(jitstate, gvar) return structbox - return self.redboxcls(self.kind, gvar) + box = self.redboxcls(self.kind, gvar) + if self.fieldnonnull: + assert isinstance(box, rvalue.PtrRedBox) + box.known_nonzero = True + return box class NamedFieldDesc(FieldDesc): @@ -518,7 +526,7 @@ def setforced(self, gv_forced): self.content_boxes = None - self.ownbox.genvar = gv_forced + self.ownbox.setgenvar_hint(gv_forced, known_nonzero=True) self.ownbox.content = None def force_runtime_container(self, jitstate): @@ -532,7 +540,7 @@ break else: gv = typedesc.materialize(builder.rgenop, boxes) - self.ownbox.genvar = gv + self.ownbox.setgenvar_hint(gv, known_nonzero=True) self.ownbox.content = None return debug_print(lltype.Void, "FORCE CONTAINER: "+ typedesc.TYPE._name) @@ -657,7 +665,10 @@ assert isinstance(typedesc, VirtualizableStructTypeDesc) builder = jitstate.curbuilder gv_outside = builder.genop_malloc_fixedsize(typedesc.alloctoken) - self.content_boxes[-1].genvar = gv_outside + outsidebox = rvalue.PtrRedBox(self.content_boxes[-1].kind, + gv_outside, + known_nonzero = True) + self.content_boxes[-1] = outsidebox jitstate.add_virtualizable(self.ownbox) access_token = typedesc.access_desc.fieldtoken gv_access_null = typedesc.access_desc.gv_default @@ -677,8 +688,11 @@ def load_from(self, jitstate, gv_outside): typedesc = self.typedesc assert isinstance(typedesc, VirtualizableStructTypeDesc) + # XXX missing check for gv_outside being NULL boxes = self.content_boxes - boxes[-1].genvar = gv_outside + boxes[-1] = rvalue.PtrRedBox(boxes[-1].kind, + gv_outside, + known_nonzero=True) builder = jitstate.curbuilder builder.genop_call(typedesc.access_is_null_token, typedesc.gv_access_is_null_ptr, Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/rtimeshift.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/timeshifter/rtimeshift.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/timeshifter/rtimeshift.py Fri Feb 2 20:59:02 2007 @@ -99,7 +99,8 @@ gv_size = sizebox.getgenvar(jitstate) alloctoken = contdesc.varsizealloctoken genvar = jitstate.curbuilder.genop_malloc_varsize(alloctoken, gv_size) - return rvalue.PtrRedBox(contdesc.ptrkind, genvar) + # XXX MemoryError handling + return rvalue.PtrRedBox(contdesc.ptrkind, genvar, known_nonzero=True) def ll_gengetfield(jitstate, deepfrozen, fielddesc, argbox): if (fielddesc.immutable or deepfrozen) and argbox.is_constant(): @@ -167,14 +168,14 @@ addr = rvalue.ll_getvalue(argbox, llmemory.Address) return rvalue.ll_fromvalue(jitstate, bool(addr) ^ reverse) builder = jitstate.curbuilder - if argbox.content is None: + if argbox.known_nonzero: + gv_res = builder.rgenop.genconst(True ^ reverse) + else: gv_addr = argbox.getgenvar(jitstate) if reverse: gv_res = builder.genop_ptr_iszero(argbox.kind, gv_addr) else: gv_res = builder.genop_ptr_nonzero(argbox.kind, gv_addr) - else: - gv_res = builder.rgenop.genconst(True ^ reverse) return rvalue.IntRedBox(builder.rgenop.kindToken(lltype.Bool), gv_res) def ll_genptreq(jitstate, argbox0, argbox1, reverse): @@ -201,6 +202,7 @@ linkargs = [] kinds = [] for redbox in incoming: + assert not redbox.genvar.is_const linkargs.append(redbox.genvar) kinds.append(redbox.kind) newblock = jitstate.curbuilder.enter_next_block(kinds, linkargs) @@ -270,9 +272,10 @@ # redboxes from outgoingvarboxes, by making them variables. # Then we make a new block based on this new state. cleanup_partial_data(memo.partialdatamatch) + forget_nonzeroness = memo.forget_nonzeroness replace_memo = rvalue.copy_memo() for box in outgoingvarboxes: - box.forcevar(jitstate, replace_memo) + box.forcevar(jitstate, replace_memo, box in forget_nonzeroness) if replace_memo.boxes: jitstate.replace(replace_memo) start_new_block(states_dic, jitstate, key, global_resumer, index=i) @@ -323,14 +326,49 @@ if exitgvar.is_const: return exitgvar.revealconst(lltype.Bool) else: + # XXX call another function with list(greens_gv) instead + resuming = jitstate.resuming + if resuming is not None and resuming.mergesleft == 0: + node = resuming.path.pop() + assert isinstance(node, PromotionPathSplit) + return node.answer + false_gv = jitstate.get_locals_gv() # alive gvs on the false path + later_builder = jitstate.curbuilder.jump_if_false(exitgvar, false_gv) + memo = rvalue.copy_memo() + jitstate2 = jitstate.split(later_builder, resumepoint, + list(greens_gv), memo) + if resuming is None: + node = jitstate.promotion_path + jitstate2.promotion_path = PromotionPathNo(node) + jitstate .promotion_path = PromotionPathYes(node) + return True + +def split_ptr_nonzero(jitstate, switchredbox, resumepoint, + ptrbox, reverse, *greens_gv): + exitgvar = switchredbox.getgenvar(jitstate) + if exitgvar.is_const: + return exitgvar.revealconst(lltype.Bool) + else: + # XXX call another function with list(greens_gv) instead resuming = jitstate.resuming if resuming is not None and resuming.mergesleft == 0: node = resuming.path.pop() assert isinstance(node, PromotionPathSplit) + ptrbox.learn_nonzeroness(jitstate, + nonzeroness = node.answer ^ reverse) return node.answer false_gv = jitstate.get_locals_gv() # alive gvs on the false path later_builder = jitstate.curbuilder.jump_if_false(exitgvar, false_gv) - jitstate2 = jitstate.split(later_builder, resumepoint, list(greens_gv)) + memo = rvalue.copy_memo() + jitstate2 = jitstate.split(later_builder, resumepoint, + list(greens_gv), memo) + ptrbox.learn_nonzeroness(jitstate, nonzeroness = True ^ reverse) + try: + copybox = memo.boxes[ptrbox] + except KeyError: + pass + else: + copybox.learn_nonzeroness(jitstate2, nonzeroness = reverse) if resuming is None: node = jitstate.promotion_path jitstate2.promotion_path = PromotionPathNo(node) @@ -541,6 +579,7 @@ kinds = [box.kind for box in incoming] builder, vars_gv = self.rgenop.replay(self.replayableblock, kinds) for i in range(len(incoming)): + assert incoming[i].genvar is None incoming[i].genvar = vars_gv[i] jitstate.curbuilder = builder jitstate.greens = self.greens_gv @@ -682,15 +721,16 @@ if len(resuming.path) == 0: incoming_gv = pm.incoming_gv for i in range(len(incoming)): + assert not incoming[i].genvar.is_const incoming[i].genvar = incoming_gv[i] flexswitch = pm.flexswitch - promotebox.genvar = promotenode.gv_value + promotebox.setgenvar(promotenode.gv_value) jitstate.resuming = None node = PromotionPathMergesToSee(promotenode, 0) jitstate.promotion_path = node else: resuming.merges_to_see() - promotebox.genvar = promotenode.gv_value + promotebox.setgenvar(promotenode.gv_value) newbuilder = flexswitch.add_case(promotenode.gv_value) jitstate.curbuilder = newbuilder @@ -869,8 +909,7 @@ if virtualizable_box not in self.virtualizables: self.virtualizables.append(virtualizable_box) - def split(self, newbuilder, newresumepoint, newgreens): - memo = rvalue.copy_memo() + def split(self, newbuilder, newresumepoint, newgreens, memo): virtualizables = [] for virtualizable_box in self.virtualizables: new_virtualizable_box = virtualizable_box.copy(memo) @@ -1112,6 +1151,8 @@ resuming = jitstate.resuming return_chain = merge_returning_jitstates(jitstate, dispatchqueue, force_merge=is_portal) + if is_portal: + assert return_chain is None or return_chain.next is None if resuming is not None: resuming.leave_call(dispatchqueue) jitstate = return_chain Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/rvalue.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/timeshifter/rvalue.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/timeshifter/rvalue.py Fri Feb 2 20:59:02 2007 @@ -16,6 +16,7 @@ def exactmatch_memo(force_merge=False): memo = Memo() memo.partialdatamatch = {} + memo.forget_nonzeroness = {} memo.force_merge=force_merge return memo @@ -50,22 +51,24 @@ def getgenvar(self, jitstate): return self.genvar + def setgenvar(self, newgenvar): + assert not self.is_constant() + self.genvar = newgenvar + def enter_block(self, incoming, memo): memo = memo.boxes if not self.is_constant() and self not in memo: incoming.append(self) memo[self] = None - def forcevar(self, jitstate, memo): - builder = jitstate.curbuilder + def forcevar(self, jitstate, memo, forget_nonzeroness): if self.is_constant(): # cannot mutate constant boxes in-place + builder = jitstate.curbuilder box = self.copy(memo) box.genvar = builder.genop_same_as(self.kind, self.genvar) return box else: - # force virtual containers - self.getgenvar(jitstate) return self def replace(self, memo): @@ -74,15 +77,8 @@ def ll_redboxcls(TYPE): - if isinstance(TYPE, lltype.Ptr): - return PtrRedBox - elif TYPE is lltype.Float: - return DoubleRedBox - else: - assert isinstance(TYPE, lltype.Primitive) - assert TYPE is not lltype.Void, "cannot make red boxes of voids" - # XXX what about long longs? - return IntRedBox + assert TYPE is not lltype.Void, "cannot make red boxes of voids" + return ll_redboxbuilder(TYPE) def redboxbuilder_void(kind, gv_value):return None def redboxbuilder_int(kind, gv_value): return IntRedBox(kind, gv_value) @@ -181,6 +177,29 @@ class PtrRedBox(RedBox): content = None # or an AbstractContainer + def __init__(self, kind, genvar=None, known_nonzero=False): + self.kind = kind + self.genvar = genvar # None or a genvar + if genvar is not None and genvar.is_const: + known_nonzero = bool(genvar.revealconst(llmemory.Address)) + self.known_nonzero = known_nonzero + + def setgenvar(self, newgenvar): + RedBox.setgenvar(self, newgenvar) + self.known_nonzero = (newgenvar.is_const and + bool(newgenvar.revealconst(llmemory.Address))) + + def setgenvar_hint(self, newgenvar, known_nonzero): + RedBox.setgenvar(self, newgenvar) + self.known_nonzero = known_nonzero + + def learn_nonzeroness(self, jitstate, nonzeroness): + if nonzeroness: + self.known_nonzero = True + else: + gv_null = jitstate.curbuilder.rgenop.genzeroconst(self.kind) + self.setgenvar_hint(gv_null, known_nonzero=False) + def __repr__(self): if not self.genvar and self.content is not None: return '' % (self.content,) @@ -188,6 +207,7 @@ return RedBox.__repr__(self) def op_getfield(self, jitstate, fielddesc): + self.known_nonzero = True if self.content is not None: box = self.content.op_getfield(jitstate, fielddesc) if box is not None: @@ -199,6 +219,7 @@ return box def op_setfield(self, jitstate, fielddesc, valuebox): + self.known_nonzero = True gv_ptr = self.genvar if gv_ptr: fielddesc.generate_set(jitstate, gv_ptr, @@ -208,6 +229,7 @@ self.content.op_setfield(jitstate, fielddesc, valuebox) def op_getsubstruct(self, jitstate, fielddesc): + self.known_nonzero = True gv_ptr = self.genvar if gv_ptr: return fielddesc.generate_getsubstruct(jitstate, gv_ptr) @@ -228,7 +250,7 @@ try: result = boxmemo[self] except KeyError: - result = PtrRedBox(self.kind, self.genvar) + result = PtrRedBox(self.kind, self.genvar, self.known_nonzero) boxmemo[self] = result if self.content: result.content = self.content.copy(memo) @@ -263,12 +285,13 @@ elif self.genvar.is_const: result = FrozenPtrConst(self.kind, self.genvar) elif content is None: - result = FrozenPtrVar(self.kind) + result = FrozenPtrVar(self.kind, self.known_nonzero) else: # if self.content is not None, it's a PartialDataStruct from pypy.jit.timeshifter import rcontainer assert isinstance(content, rcontainer.PartialDataStruct) - result = FrozenPtrVarWithPartialData(self.kind) + result = FrozenPtrVarWithPartialData(self.kind, + known_nonzero=True) boxmemo[self] = result result.fz_partialcontent = content.partialfreeze(memo) return result @@ -286,11 +309,23 @@ assert self.genvar return self.genvar - def forcevar(self, jitstate, memo): + def forcevar(self, jitstate, memo, forget_nonzeroness): from pypy.jit.timeshifter import rcontainer # xxx assert not isinstance(self.content, rcontainer.VirtualizableStruct) - return RedBox.forcevar(self, jitstate, memo) + if self.is_constant(): + # cannot mutate constant boxes in-place + builder = jitstate.curbuilder + box = self.copy(memo) + box.genvar = builder.genop_same_as(self.kind, self.genvar) + else: + # force virtual containers + self.getgenvar(jitstate) + box = self + + if forget_nonzeroness: + box.known_nonzero = False + return box def enter_block(self, incoming, memo): if self.genvar: @@ -412,6 +447,8 @@ def exactmatch(self, box, outgoingvarboxes, memo): assert isinstance(box, PtrRedBox) memo.partialdatamatch[box] = None # could do better + if self.is_constant_nullptr(): + memo.forget_nonzeroness[box] = None match = FrozenConst.exactmatch(self, box, outgoingvarboxes, memo) if not memo.force_merge and not match: from pypy.jit.timeshifter.rcontainer import VirtualContainer @@ -425,10 +462,18 @@ class FrozenPtrVar(FrozenVar): + def __init__(self, kind, known_nonzero): + self.kind = kind + self.known_nonzero = known_nonzero + def exactmatch(self, box, outgoingvarboxes, memo): assert isinstance(box, PtrRedBox) memo.partialdatamatch[box] = None + if not self.known_nonzero: + memo.forget_nonzeroness[box] = None match = FrozenVar.exactmatch(self, box, outgoingvarboxes, memo) + if self.known_nonzero and not box.known_nonzero: + match = False if not memo.force_merge and not match: from pypy.jit.timeshifter.rcontainer import VirtualContainer if isinstance(box.content, VirtualContainer): @@ -438,7 +483,7 @@ def unfreeze(self, incomingvarboxes, memo): memo = memo.boxes if self not in memo: - newbox = PtrRedBox(self.kind, None) + newbox = PtrRedBox(self.kind, None, self.known_nonzero) incomingvarboxes.append(newbox) memo[self] = newbox return newbox Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_exception.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_exception.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_exception.py Fri Feb 2 20:59:02 2007 @@ -140,26 +140,14 @@ self.check_insns(malloc=0) def test_not_segregated_malloc_exception_path(self): - py.test.skip("WIP") - class E(Exception): - def __init__(self, msg): - self.msg = msg - def help(l, x): - if x < 0: - raise E("x negative: %d" %x) - l.append(x) - return l + l.append("x is %s" % chr(x)) def ll_function(x): l = [] - l = help(l, x) + help(l, x) return len(l)+x res = self.timeshift(ll_function, [5], [], policy=P_OOPSPEC) res == 6 self.check_oops(newlist=0) - - - - Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_promotion.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_promotion.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_promotion.py Fri Feb 2 20:59:02 2007 @@ -302,7 +302,6 @@ assert res == 22 def test_raise_result_mixup(self): - py.test.skip("WIP") def w(x): pass class E(Exception): Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_timeshift.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_timeshift.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_timeshift.py Fri Feb 2 20:59:02 2007 @@ -785,14 +785,14 @@ res = self.timeshift(ll_function, [21, -21, 0], [], policy=P_NOVIRTUAL) assert res == 42 - self.check_insns({'malloc_varsize': 1, 'ptr_iszero': 1, + self.check_insns({'malloc_varsize': 1, 'setarrayitem': 2, 'getarrayitem': 1, 'getarraysize': 1, 'int_mul': 1}) res = self.timeshift(ll_function, [21, -21, 1], [], policy=P_NOVIRTUAL) assert res == -42 - self.check_insns({'malloc_varsize': 1, 'ptr_iszero': 1, + self.check_insns({'malloc_varsize': 1, 'setarrayitem': 2, 'getarrayitem': 1, 'getarraysize': 1, 'int_mul': 1}) @@ -808,7 +808,7 @@ res = self.timeshift(ll_function, [21, -21, 0], [], policy=P_NOVIRTUAL) assert res == 42 - self.check_insns({'malloc_varsize': 1, 'ptr_iszero': 1, + self.check_insns({'malloc_varsize': 1, 'getarraysubstruct': 3, 'setfield': 2, 'getfield': 1, 'getarraysize': 1, 'int_mul': 1}) @@ -816,7 +816,7 @@ res = self.timeshift(ll_function, [21, -21, 1], [], policy=P_NOVIRTUAL) assert res == -42 - self.check_insns({'malloc_varsize': 1, 'ptr_iszero': 1, + self.check_insns({'malloc_varsize': 1, 'getarraysubstruct': 3, 'setfield': 2, 'getfield': 1, 'getarraysize': 1, 'int_mul': 1}) @@ -1292,3 +1292,59 @@ res = self.timeshift(f, [3], [], policy=P_NOVIRTUAL) assert res == '2' + + def test_known_nonzero(self): + S = lltype.GcStruct('s', ('x', lltype.Signed)) + global_s = lltype.malloc(S, immortal=True) + global_s.x = 100 + + def h(): + s = lltype.malloc(S) + s.x = 50 + return s + def g(s, y): + if s: + return s.x * 5 + else: + return -12 + y + def f(x, y): + x = hint(x, concrete=True) + if x == 1: + return g(lltype.nullptr(S), y) + elif x == 2: + return g(global_s, y) + elif x == 3: + s = lltype.malloc(S) + s.x = y + return g(s, y) + elif x == 4: + s = h() + return g(s, y) + else: + s = h() + if s: + return g(s, y) + else: + return 0 + + P = StopAtXPolicy(h) + + res = self.timeshift(f, [1, 10], [0], policy=P) + assert res == -2 + self.check_insns(int_mul=0, int_add=1) + + res = self.timeshift(f, [2, 10], [0], policy=P) + assert res == 500 + self.check_insns(int_mul=1, int_add=0) + + res = self.timeshift(f, [3, 10], [0], policy=P) + assert res == 50 + self.check_insns(int_mul=1, int_add=0) + + res = self.timeshift(f, [4, 10], [0], policy=P) + assert res == 250 + self.check_insns(int_mul=1, int_add=1) + + res = self.timeshift(f, [5, 10], [0], policy=P) + assert res == 250 + self.check_insns(int_mul=1, int_add=0) Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/transform.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/timeshifter/transform.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/timeshifter/transform.py Fri Feb 2 20:59:02 2007 @@ -53,6 +53,7 @@ return self.raise_analyzer.analyze(op) def transform(self): + self.simplify_operations() self.compute_merge_points() self.insert_save_return() self.insert_splits() @@ -109,6 +110,23 @@ if startblock in global_merge_blocks: self.mergepoint_set[startblock] = 'global' + def simplify_operations(self): + # ptr_eq(x, 0) => ptr_iszero + # ptr_ne(x, 0) => ptr_nonzero + replace = {'ptr_eq': 'ptr_iszero', + 'ptr_ne': 'ptr_nonzero'} + for block in self.graph.iterblocks(): + for op in block.operations: + if op.opname in replace: + srcargs = op.args + for v1, v2 in [(srcargs[0], srcargs[1]), + (srcargs[1], srcargs[0])]: + if isinstance(v2, Constant): + if not v2.value: + op.opname = replace[op.opname] + op.args = [v1] + break + def graph_calling_color(self, tsgraph): args_hs, hs_res = self.hannotator.bookkeeper.tsgraphsigs[tsgraph] if originalconcretetype(hs_res) is lltype.Void: @@ -244,51 +262,58 @@ if not hs_switch.is_green(): self.insert_split_handling(block) + def trace_back_exitswitch(self, block): + """Return the (opname, arguments) that created the exitswitch of + the block. The opname is None if not found. + """ + v = block.exitswitch + inverted = False + for i in range(len(block.operations)-1, -1, -1): + op = block.operations[i] + if op.result is v: + if op.opname == 'bool_not': + inverted = not inverted + [v] = op.args + elif op.opname == 'same_as': + [v] = op.args + else: + opname = op.opname + opargs = op.args + if inverted: + opname = {'ptr_nonzero': 'ptr_iszero', + 'ptr_iszero' : 'ptr_nonzero'}.get(opname) + return opname, opargs # found + # not found, comes from earlier block - give up + return None, None + def insert_split_handling(self, block): - # lots of clever in-line logic commented out v_redswitch = block.exitswitch + + # try to look where the v_redswitch comes from + split_variant = '' + split_extras = [] + srcopname, srcargs = self.trace_back_exitswitch(block) + if srcopname == 'ptr_nonzero': + split_variant = '_ptr_nonzero' + split_extras = srcargs + elif srcopname == 'ptr_iszero': + split_variant = '_ptr_iszero' + split_extras = srcargs + link_f, link_t = block.exits if link_f.exitcase: link_f, link_t = link_t, link_f assert link_f.exitcase is False assert link_t.exitcase is True -## constant_block = Block([]) -## nonconstant_block = Block([]) - -## v_flag = self.genop(block, 'is_constant', [v_redswitch], -## resulttype = lltype.Bool) -## self.genswitch(block, v_flag, true = constant_block, -## false = nonconstant_block) - -## v_greenswitch = self.genop(constant_block, 'revealconst', -## [v_redswitch], -## resulttype = lltype.Bool) -## constant_block.exitswitch = v_greenswitch -## constant_block.closeblock(link_f, link_t) - reds, greens = self.sort_by_color(link_f.args, link_f.target.inputargs) self.genop(block, 'save_locals', reds) resumepoint = self.get_resume_point(link_f.target) c_resumepoint = inputconst(lltype.Signed, resumepoint) - v_flag = self.genop(block, 'split', - [v_redswitch, c_resumepoint] + greens, - resulttype = lltype.Bool) - + v_flag = self.genop(block, 'split' + split_variant, + [v_redswitch, c_resumepoint] + split_extras + greens, + resulttype = lltype.Bool) block.exitswitch = v_flag -## true_block = Block([]) -## true_link = Link([], true_block) -## true_link.exitcase = True -## true_link.llexitcase = True -## block.recloseblock(link_f, true_link) - -## reds, greens = self.sort_by_color(link_t.args) -## self.genop(true_block, 'save_locals', reds) -## self.genop(true_block, 'enter_block', []) -## true_block.closeblock(Link(link_t.args, link_t.target)) - -## SSA_to_SSI({block : True, # reachable from outside -## true_block: False}, self.hannotator) def get_resume_point_link(self, block): try: Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/vdict.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/timeshifter/vdict.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/timeshifter/vdict.py Fri Feb 2 20:59:02 2007 @@ -133,7 +133,7 @@ def factory(self): vdict = self.VirtualDict(self) - box = rvalue.PtrRedBox(self.ptrkind) + box = rvalue.PtrRedBox(self.ptrkind, known_nonzero=True) box.content = vdict vdict.ownbox = box return box @@ -208,7 +208,7 @@ gv_dict = builder.genop_call(typedesc.tok_ll_newdict, typedesc.gv_ll_newdict, args_gv) - self.ownbox.genvar = gv_dict + self.ownbox.setgenvar_hint(gv_dict, known_nonzero=True) self.ownbox.content = None for gv_key, valuebox, hash in items: gv_hash = builder.rgenop.genconst(hash) Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/vlist.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/timeshifter/vlist.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/timeshifter/vlist.py Fri Feb 2 20:59:02 2007 @@ -75,7 +75,7 @@ def factory(self, length, itembox): vlist = VirtualList(self, length, itembox) - box = rvalue.PtrRedBox(self.ptrkind) + box = rvalue.PtrRedBox(self.ptrkind, known_nonzero=True) box.content = vlist vlist.ownbox = box return box @@ -154,7 +154,7 @@ def setforced(self, gv_forced): self.item_boxes = None - self.ownbox.genvar = gv_forced + self.ownbox.setgenvar_hint(gv_forced, known_nonzero=True) self.ownbox.content = None def force_runtime_container(self, jitstate): Modified: pypy/branch/jit-virtual-world/pypy/rpython/lltypesystem/rclass.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/rpython/lltypesystem/rclass.py (original) +++ pypy/branch/jit-virtual-world/pypy/rpython/lltypesystem/rclass.py Fri Feb 2 20:59:02 2007 @@ -58,7 +58,7 @@ OBJECT_VTABLE = lltype.ForwardReference() CLASSTYPE = Ptr(OBJECT_VTABLE) OBJECT = GcStruct('object', ('typeptr', CLASSTYPE), - hints = {'immutable': True}) + hints = {'immutable': True, 'shouldntbenull': True}) OBJECTPTR = Ptr(OBJECT) OBJECT_VTABLE.become(Struct('object_vtable', #('parenttypeptr', CLASSTYPE), From arigo at codespeak.net Fri Feb 2 21:16:23 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 2 Feb 2007 21:16:23 +0100 (CET) Subject: [pypy-svn] r37825 - pypy/dist/pypy/jit/codegen/ppc/test Message-ID: <20070202201623.52D8210068@code0.codespeak.net> Author: arigo Date: Fri Feb 2 21:16:19 2007 New Revision: 37825 Modified: pypy/dist/pypy/jit/codegen/ppc/test/test_rgenop.py Log: Add a "py.test -k" completion hint. Modified: pypy/dist/pypy/jit/codegen/ppc/test/test_rgenop.py ============================================================================== --- pypy/dist/pypy/jit/codegen/ppc/test/test_rgenop.py (original) +++ pypy/dist/pypy/jit/codegen/ppc/test/test_rgenop.py Fri Feb 2 21:16:19 2007 @@ -5,6 +5,9 @@ from ctypes import cast, c_int, c_void_p, CFUNCTYPE from pypy.jit.codegen.ppc import instruction as insn +# for the individual tests see +# ====> ../../test/rgenop_tests.py + class FewRegisters(RPPCGenOp): freeregs = { insn.GP_REGISTER:insn.gprs[3:6], From fijal at codespeak.net Fri Feb 2 21:17:32 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 2 Feb 2007 21:17:32 +0100 (CET) Subject: [pypy-svn] r37826 - pypy/dist/pypy/translator/js/lib Message-ID: <20070202201732.7159310063@code0.codespeak.net> Author: fijal Date: Fri Feb 2 21:17:22 2007 New Revision: 37826 Added: pypy/dist/pypy/translator/js/lib/ Log: directory for keeping server-only modules (to be different than modules/module directory) From fijal at codespeak.net Fri Feb 2 21:19:13 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 2 Feb 2007 21:19:13 +0100 (CET) Subject: [pypy-svn] r37827 - in pypy/dist/pypy/translator/js: examples examples/test lib lib/test Message-ID: <20070202201913.9AEBF10060@code0.codespeak.net> Author: fijal Date: Fri Feb 2 21:19:03 2007 New Revision: 37827 Added: pypy/dist/pypy/translator/js/lib/server.py - copied unchanged from r37798, pypy/dist/pypy/translator/js/examples/server.py pypy/dist/pypy/translator/js/lib/test/ pypy/dist/pypy/translator/js/lib/test/test_server.py - copied unchanged from r37798, pypy/dist/pypy/translator/js/examples/test/test_server.py Removed: pypy/dist/pypy/translator/js/examples/server.py pypy/dist/pypy/translator/js/examples/test/test_server.py Log: Move server.py to lib directory From fijal at codespeak.net Fri Feb 2 21:31:19 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 2 Feb 2007 21:31:19 +0100 (CET) Subject: [pypy-svn] r37828 - pypy/dist/pypy/translator/js/modules Message-ID: <20070202203119.72C9510063@code0.codespeak.net> Author: fijal Date: Fri Feb 2 21:31:16 2007 New Revision: 37828 Modified: pypy/dist/pypy/translator/js/modules/dom.py Log: Let Document/Window have property to be rendered always the same. Modified: pypy/dist/pypy/translator/js/modules/dom.py ============================================================================== --- pypy/dist/pypy/translator/js/modules/dom.py (original) +++ pypy/dist/pypy/translator/js/modules/dom.py Fri Feb 2 21:31:16 2007 @@ -313,8 +313,8 @@ window = Window() document = window.document -window._render_name = 'window' -document._render_name = 'document' +Window._render_name = 'window' +Document._render_name = 'document' # rtyper stuff From fijal at codespeak.net Fri Feb 2 21:31:57 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 2 Feb 2007 21:31:57 +0100 (CET) Subject: [pypy-svn] r37829 - in pypy/dist/pypy/translator/js: lib/test tutorial Message-ID: <20070202203157.077971006E@code0.codespeak.net> Author: fijal Date: Fri Feb 2 21:31:52 2007 New Revision: 37829 Modified: pypy/dist/pypy/translator/js/lib/test/test_server.py pypy/dist/pypy/translator/js/tutorial/step1.py pypy/dist/pypy/translator/js/tutorial/step2.py pypy/dist/pypy/translator/js/tutorial/step3.py Log: Adapt to server.py move Modified: pypy/dist/pypy/translator/js/lib/test/test_server.py ============================================================================== --- pypy/dist/pypy/translator/js/lib/test/test_server.py (original) +++ pypy/dist/pypy/translator/js/lib/test/test_server.py Fri Feb 2 21:31:52 2007 @@ -2,7 +2,7 @@ """ Server testing """ -from pypy.translator.js.examples import server +from pypy.translator.js.lib import server from urllib import URLopener class Handler(server.TestHandler): Modified: pypy/dist/pypy/translator/js/tutorial/step1.py ============================================================================== --- pypy/dist/pypy/translator/js/tutorial/step1.py (original) +++ pypy/dist/pypy/translator/js/tutorial/step1.py Fri Feb 2 21:31:52 2007 @@ -8,7 +8,7 @@ # here we import server, which is derivative of # BaseHTTPServer from python standard library -from pypy.translator.js.examples import server +from pypy.translator.js.lib import server # We create handler, which will handle all our requests class Handler(server.TestHandler): Modified: pypy/dist/pypy/translator/js/tutorial/step2.py ============================================================================== --- pypy/dist/pypy/translator/js/tutorial/step2.py (original) +++ pypy/dist/pypy/translator/js/tutorial/step2.py Fri Feb 2 21:31:52 2007 @@ -4,7 +4,7 @@ server from previous example """ -from pypy.translator.js.examples import server +from pypy.translator.js.lib import server import sys # here we have virtual script "source.js" which we generate Modified: pypy/dist/pypy/translator/js/tutorial/step3.py ============================================================================== --- pypy/dist/pypy/translator/js/tutorial/step3.py (original) +++ pypy/dist/pypy/translator/js/tutorial/step3.py Fri Feb 2 21:31:52 2007 @@ -10,7 +10,7 @@ which will be way easier to manipulate. """ -from pypy.translator.js.examples import server +from pypy.translator.js.lib import server from pypy.translator.js.main import rpython2javascript from pypy.translator.js.modules.dom import document # dom manipulating module From mwh at codespeak.net Fri Feb 2 22:28:11 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 2 Feb 2007 22:28:11 +0100 (CET) Subject: [pypy-svn] r37832 - in pypy/dist/pypy/jit/codegen/ppc: . test Message-ID: <20070202212811.10ACA10060@code0.codespeak.net> Author: mwh Date: Fri Feb 2 22:28:09 2007 New Revision: 37832 Modified: pypy/dist/pypy/jit/codegen/ppc/emit_moves.py pypy/dist/pypy/jit/codegen/ppc/rgenop.py pypy/dist/pypy/jit/codegen/ppc/test/test_emit_moves.py Log: fix the bug in the smarter version of emit_moves -- if there's a "safe" conflict then there may be more than one target the source needs to be copied to. add a fairly beefy random test. Modified: pypy/dist/pypy/jit/codegen/ppc/emit_moves.py ============================================================================== --- pypy/dist/pypy/jit/codegen/ppc/emit_moves.py (original) +++ pypy/dist/pypy/jit/codegen/ppc/emit_moves.py Fri Feb 2 22:28:09 2007 @@ -44,7 +44,7 @@ data.emitted = [] for tar, src in tar2src.items(): - data.src2tar[src] = tar + data.src2tar.setdefault(src, []).append(tar) for src, loc in src2loc.items(): if src in data.src2tar: @@ -77,7 +77,8 @@ if conflictsrcvar not in data.srcstack: # No cycle on our stack yet data.srcstack.append(srcvar) - _cycle_walk(gen, data.src2tar[conflictsrcvar], data) + for tar in data.src2tar[conflictsrcvar]: + _cycle_walk(gen, tar, data) srcloc = data.src2loc[srcvar] # warning: may have changed, so reload gen.emit_move(tarloc, srcloc) data.emitted.append(tarvar) Modified: pypy/dist/pypy/jit/codegen/ppc/rgenop.py ============================================================================== --- pypy/dist/pypy/jit/codegen/ppc/rgenop.py (original) +++ pypy/dist/pypy/jit/codegen/ppc/rgenop.py Fri Feb 2 22:28:09 2007 @@ -184,7 +184,7 @@ allocator.free_stack_slots.remove(tloc) gen = JumpPatchupGenerator(insns, allocator) - emit_moves_safe(gen, tarvars, tar2src, tar2loc, src2loc) + emit_moves(gen, tarvars, tar2src, tar2loc, src2loc) for i in range(len(targetlocs)): tloc = targetlocs[i] Modified: pypy/dist/pypy/jit/codegen/ppc/test/test_emit_moves.py ============================================================================== --- pypy/dist/pypy/jit/codegen/ppc/test/test_emit_moves.py (original) +++ pypy/dist/pypy/jit/codegen/ppc/test/test_emit_moves.py Fri Feb 2 22:28:09 2007 @@ -1,5 +1,5 @@ import py -from pypy.jit.codegen.ppc.emit_moves import emit_moves +from pypy.jit.codegen.ppc.emit_moves import emit_moves, emit_moves_safe class TheHeap(object): def __init__(self, locs): @@ -53,9 +53,7 @@ assert heap.data[2] == 2 assert heap.numlocs == 3 # only creates 1 extra loc - def test_one_to_many(): - py.test.skip("failing :(") heap = TheHeap(4) tar2src = {'A':'a', 'B':'b', 'C':'a'} tar2loc = {'A':2, 'B':1, 'C':3} @@ -68,3 +66,34 @@ assert heap.data[1] == 0 # B assert heap.data[2] == 1 # A assert heap.data[3] == 1 # C + +def test_random(): + for _ in range(20): + import random + NVAR = random.randrange(1000) + heap = TheHeap(NVAR) + varlist = range(NVAR) + tar2src = {} + src2loc = {} + tar2loc = {} + for i in varlist: + tar2src[i] = random.randrange(NVAR) + srcs = list(dict.fromkeys(tar2src.values())) + srclocs = srcs[:] + random.shuffle(srclocs) + for j, k in zip(srcs, srclocs): + src2loc[j] = k + varlist2 = varlist[:] + random.shuffle(varlist2) + for i, j in zip(varlist, varlist2): + tar2loc[i] = j + for i in range(10): + random.shuffle(varlist) + heap1 = TheHeap(NVAR) + emit_moves(heap1, varlist, + tar2src.copy(), tar2loc.copy(), src2loc.copy()) + heap2 = TheHeap(NVAR) + emit_moves_safe(heap2, varlist, + tar2src.copy(), tar2loc.copy(), src2loc.copy()) + for i in range(NVAR): + assert heap1.data[i] == heap2.data[i] From arigo at codespeak.net Sat Feb 3 00:11:54 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 3 Feb 2007 00:11:54 +0100 (CET) Subject: [pypy-svn] r37836 - pypy/branch/jit-virtual-world/pypy/jit/codegen/i386 Message-ID: <20070202231154.DA87F10061@code0.codespeak.net> Author: arigo Date: Sat Feb 3 00:11:52 2007 New Revision: 37836 Modified: pypy/branch/jit-virtual-world/pypy/jit/codegen/i386/rgenop.py Log: Avoid an issue whereby all variables forced to be in the stack would end up being copied during an enter_next_block(). Modified: pypy/branch/jit-virtual-world/pypy/jit/codegen/i386/rgenop.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/codegen/i386/rgenop.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/codegen/i386/rgenop.py Sat Feb 3 00:11:52 2007 @@ -253,16 +253,24 @@ return mc def enter_next_block(self, kinds, args_gv): -## mc = self.generate_block_code(args_gv) -## assert len(self.inputargs_gv) == len(args_gv) -## args_gv[:len(args_gv)] = self.inputargs_gv -## self.set_coming_from(mc) -## self.rgenop.close_mc(mc) -## self.start_writing() - for i in range(len(args_gv)): - op = OpSameAs(args_gv[i]) - args_gv[i] = op - self.operations.append(op) + if self.force_in_stack is not None: + # force_in_stack would keep the variables alive until the end + # of the whole mc block, i.e. past the OpSameAs that we are + # about to introduce => duplication of the value. + mc = self.generate_block_code(args_gv) + assert len(self.inputargs_gv) == len(args_gv) + args_gv[:len(args_gv)] = self.inputargs_gv + self.set_coming_from(mc) + mc.done() + self.rgenop.close_mc(mc) + self.start_writing() + else: + # otherwise, we get better register allocation if we write a + # single larger mc block + for i in range(len(args_gv)): + op = OpSameAs(args_gv[i]) + args_gv[i] = op + self.operations.append(op) lbl = Label() lblop = OpLabel(lbl, args_gv) self.operations.append(lblop) From cfbolz at codespeak.net Sat Feb 3 00:57:22 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sat, 3 Feb 2007 00:57:22 +0100 (CET) Subject: [pypy-svn] r37840 - pypy/dist/pypy/doc Message-ID: <20070202235722.90E8B10060@code0.codespeak.net> Author: cfbolz Date: Sat Feb 3 00:57:06 2007 New Revision: 37840 Modified: pypy/dist/pypy/doc/objspace.txt Log: make the thunk object space referencable Modified: pypy/dist/pypy/doc/objspace.txt ============================================================================== --- pypy/dist/pypy/doc/objspace.txt (original) +++ pypy/dist/pypy/doc/objspace.txt Sat Feb 3 00:57:06 2007 @@ -313,6 +313,8 @@ .. _`traceconfig.py`: http://codespeak.net/svn/pypy/dist/pypy/tool/traceconfig.py +.. _`thunk object space`: + The Thunk Object Space ====================== From arigo at codespeak.net Sat Feb 3 01:06:32 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 3 Feb 2007 01:06:32 +0100 (CET) Subject: [pypy-svn] r37841 - pypy/branch/jit-virtual-world/pypy/jit/codegen/llgraph Message-ID: <20070203000632.48CAD10060@code0.codespeak.net> Author: arigo Date: Sat Feb 3 01:06:01 2007 New Revision: 37841 Modified: pypy/branch/jit-virtual-world/pypy/jit/codegen/llgraph/llimpl.py Log: (pedronis, arigo) Bug! Squash. Modified: pypy/branch/jit-virtual-world/pypy/jit/codegen/llgraph/llimpl.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/codegen/llgraph/llimpl.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/codegen/llgraph/llimpl.py Sat Feb 3 01:06:01 2007 @@ -200,6 +200,7 @@ def genzeroconst(gv_TYPE): TYPE = from_opaque_object(gv_TYPE).value + TYPE = lltype.erasedType(TYPE) c = flowmodel.Constant(TYPE._defl()) c.concretetype = TYPE return to_opaque_object(c) From arigo at codespeak.net Sat Feb 3 01:07:37 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 3 Feb 2007 01:07:37 +0100 (CET) Subject: [pypy-svn] r37842 - pypy/branch/jit-virtual-world/pypy/jit/codegen/test Message-ID: <20070203000737.56CB510068@code0.codespeak.net> Author: arigo Date: Sat Feb 3 01:07:26 2007 New Revision: 37842 Modified: pypy/branch/jit-virtual-world/pypy/jit/codegen/test/rgenop_tests.py Log: This is the test that shows the problem solved by r37836. Modified: pypy/branch/jit-virtual-world/pypy/jit/codegen/test/rgenop_tests.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/codegen/test/rgenop_tests.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/codegen/test/rgenop_tests.py Sat Feb 3 01:07:26 2007 @@ -642,6 +642,10 @@ info = builder.get_frame_info([gv_y]) gv_reader = rgenop.constPrebuiltGlobal(get_reader(info)) gv_z = builder.genop_call(readertoken, gv_reader, [gv_base]) + + args_gv = [gv_y, gv_z] + builder.enter_next_block([signed_kind]*2, args_gv) + [gv_y, gv_z] = args_gv builder.finish_and_return(sigtoken, gv_z) builder.end() From arigo at codespeak.net Sat Feb 3 01:08:23 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 3 Feb 2007 01:08:23 +0100 (CET) Subject: [pypy-svn] r37843 - pypy/branch/jit-virtual-world/pypy/jit/goal Message-ID: <20070203000823.D9E5010068@code0.codespeak.net> Author: arigo Date: Sat Feb 3 01:08:13 2007 New Revision: 37843 Modified: pypy/branch/jit-virtual-world/pypy/jit/goal/targetjit.py Log: Make targetjit a bit faster, while we develop it. Modified: pypy/branch/jit-virtual-world/pypy/jit/goal/targetjit.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/goal/targetjit.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/goal/targetjit.py Sat Feb 3 01:08:13 2007 @@ -45,6 +45,7 @@ def handle_config(self, config): config.translation.fork_before = 'hintannotate' + config.translation.inline_threshold = 20.1 def handle_translate_config(self, translateconfig): translateconfig.goals = ['timeshift'] From arigo at codespeak.net Sat Feb 3 01:15:58 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 3 Feb 2007 01:15:58 +0100 (CET) Subject: [pypy-svn] r37844 - in pypy/branch/jit-virtual-world/pypy: jit/timeshifter jit/timeshifter/test translator/c Message-ID: <20070203001558.CD3C010060@code0.codespeak.net> Author: arigo Date: Sat Feb 3 01:15:36 2007 New Revision: 37844 Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/hrtyper.py pypy/branch/jit-virtual-world/pypy/jit/timeshifter/rtimeshift.py pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_promotion.py pypy/branch/jit-virtual-world/pypy/jit/timeshifter/transform.py pypy/branch/jit-virtual-world/pypy/translator/c/exceptiontransform.py Log: (pedronis, arigo) When an exception is raised by the original graphs, the timeshifted graphs now assert that the exception cannot be None. See test. Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/hrtyper.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/timeshifter/hrtyper.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/timeshifter/hrtyper.py Sat Feb 3 01:15:36 2007 @@ -1233,6 +1233,19 @@ [v_jitstate , v_box , c_desc], annmodel.SomeBool()) + def translate_op_rpyexc_raise(self, hop): + EXCTYPE = originalconcretetype(hop.args_s[0]) + EXCVALUE = originalconcretetype(hop.args_s[1]) + [v_exctype, v_excvalue] = hop.inputargs(self.getredrepr(EXCTYPE), + self.getredrepr(EXCVALUE)) + v_exctype = hop.llops.as_ptrredbox(v_exctype) + v_excvalue = hop.llops.as_ptrredbox(v_excvalue) + v_jitstate = hop.llops.getjitstate() + return hop.llops.genmixlevelhelpercall(rtimeshift.setexception, + [self.s_JITState, self.s_PtrRedBox, self.s_PtrRedBox], + [v_jitstate , v_exctype , v_excvalue ], + annmodel.s_None) + # handling of the various kinds of calls def translate_op_oopspec_call(self, hop): Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/rtimeshift.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/timeshifter/rtimeshift.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/timeshifter/rtimeshift.py Sat Feb 3 01:15:36 2007 @@ -478,6 +478,12 @@ def setexcvaluebox(jitstate, box): jitstate.exc_value_box = box +def setexception(jitstate, typebox, valuebox): + typebox.known_nonzero = True + valuebox.known_nonzero = True + jitstate.exc_type_box = typebox + jitstate.exc_value_box = valuebox + def save_return(jitstate): # add 'jitstate' to the chain of return-jitstates jitstate.pause() Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_promotion.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_promotion.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_promotion.py Sat Feb 3 01:15:36 2007 @@ -334,3 +334,39 @@ res = self.timeshift(ll_function, ["oe", 1], [], policy=StopAtXPolicy(w)) res == 1 + + def test_raise_result_mixup_some_more(self): + def w(x): + if x > 1000: + return None + else: + return E(x) + class E(Exception): + def __init__(self, x): + self.x = x + def o(x): + if x < 0: + e = w(x) + raise e + return x + def ll_function(c, x): + i = 0 + while True: + hint(None, global_merge_point=True) + op = c[i] + hint(op, concrete=True) + if op == 'e': + break + elif op == 'o': + x = o(x) + x = hint(x, promote=True) + i = x + r = hint(i, variable=True) + return r + ll_function.convert_arguments = [LLSupport.to_rstr, int] + + assert ll_function("oe", 1) == 1 + + res = self.timeshift(ll_function, ["oe", 1], [], + policy=StopAtXPolicy(w)) + res == 1 Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/transform.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/timeshifter/transform.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/timeshifter/transform.py Sat Feb 3 01:15:36 2007 @@ -495,6 +495,8 @@ if spaceop.opname == 'direct_call': c_func = spaceop.args[0] fnobj = c_func.value._obj + if hasattr(fnobj, 'jitcallkind'): + return fnobj.jitcallkind if (hasattr(fnobj._callable, 'oopspec') and self.hannotator.policy.oopspec): if fnobj._callable.oopspec.startswith('vable.'): @@ -663,7 +665,13 @@ args = op.args[1:] args.insert(1, Constant(name, lltype.Void)) block.operations[pos] = SpaceOperation(opname, args, op.result) - + + def handle_rpyexc_raise_call(self, block, pos): + op = block.operations[pos] + assert op.opname == 'direct_call' + op.opname = 'rpyexc_raise' + op.args = op.args[1:] + def handle_green_call(self, block, pos): # green-returning call, for now (XXX) we assume it's an # all-green function that we can just call Modified: pypy/branch/jit-virtual-world/pypy/translator/c/exceptiontransform.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/translator/c/exceptiontransform.py (original) +++ pypy/branch/jit-virtual-world/pypy/translator/c/exceptiontransform.py Sat Feb 3 01:15:36 2007 @@ -138,7 +138,9 @@ self.rpyexc_raise_ptr = Constant(lltype.functionptr( RPYEXC_RAISE, "RPyRaiseException", graph=rpyexc_raise_graph, - exception_policy="exc_helper"), + exception_policy="exc_helper", + jitcallkind='rpyexc_raise', # for the JIT + ), lltype.Ptr(RPYEXC_RAISE)) mixlevelannotator.finish() From cfbolz at codespeak.net Sat Feb 3 01:53:13 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sat, 3 Feb 2007 01:53:13 +0100 (CET) Subject: [pypy-svn] r37845 - pypy/dist/pypy/doc Message-ID: <20070203005313.C3A5B10063@code0.codespeak.net> Author: cfbolz Date: Sat Feb 3 01:53:12 2007 New Revision: 37845 Modified: pypy/dist/pypy/doc/proxy.txt Log: clean this document up a bit Modified: pypy/dist/pypy/doc/proxy.txt ============================================================================== --- pypy/dist/pypy/doc/proxy.txt (original) +++ pypy/dist/pypy/doc/proxy.txt Sat Feb 3 01:53:12 2007 @@ -2,54 +2,66 @@ PyPy - transparent proxy implementation ======================================= -Among the unique features of PyPy, there is as well possibility of +Among the unique features of PyPy, there is as well the possibility of having multiple implementations of builtin types. Multiple performance optimisations using this features are already implemented, some -hints are in `Object space`_ document. +hints are in the `Object Space`_ document. -Transparent proxy is implementation of some (maybe all at some point) -of objects like functions, objects, lists etc. which forwards all -operations performed on object to app-level function with specific -signature. +Transparent proxy are implementations of some (maybe all at some point) +objects like functions, objects, lists etc. which forwards all +operations performed on these object to app-level functions which have specific +signatures. -.. _`Object space`: objspace.html#object-types +.. _`Object Space`: objspace.html#object-types Example: ======== Suppose we want to have list which stores all operations performed on -it for later analysis. So we create a list an apropriate controller:: +it for later analysis. So we create an apropriate controller:: - from pypymagic import transparent_proxy - - class Controller(object): - def __init__(self, l): - self.l = l - self.history = [] - def perform(self, name, *args, **kwargs): - self.history.append(name) - return getattr(self.l, name)(*args, **kwargs) - l = [] - c = Controller(l) - lst = transparent_proxy(list, c.perform) - -Here, we've created original list, some random class and called magic -``transparent_proxy`` function, which eats operation name and additional + from pypymagic import transparent_proxy + + class Controller(object): + def __init__(self, l): + self.l = l + self.history = [] + def perform(self, name, *args, **kwargs): + self.history.append(name) + return getattr(self.l, name)(*args, **kwargs) + l = [] + c = Controller(l) + lst = transparent_proxy(list, c.perform) + +Here, we've created original list, some random class and called a magic +``transparent_proxy`` function, which takes an type and a function which will be +called on every operation on the result of the ``transparent_proxy`` call. +The arguments of such a call are the operation name and additional arguments. -Important bit is that we do not need some existing object to perform + +The important bit is that we do not need some existing object to perform operations on, it can do whatever we like. And of course ``type(lst) is type(l)`` and ``lst is not l`` (well, the latter is not "of course", but actually it's true). -Now we can access all history of operations on ``c.history``, if we -perform something like:: - - lst.append(3) - print lst - lst[:-1] +Now we can access all the history of operations on the list in ``c.history``. +Example:: -it'll be something like ``['__getattribute__', '__repr__', '__getitem__']`` -(not that ``append`` is just an argument to ``__getattribute__``). + >>>> lst + [] + >>>> type(lst) + + >>>> lst.append(3) + >>>> lst + [3] + >>>> lst[-1] + 3 + >>>> c.history + ['__repr__', '__getattribute__', '__repr__', '__getitem__'] + +Note that ``append`` shows up as ``__getattribute__`` and that the ``type(lst)`` +does not show up at all (indeed the type is the only aspect of the instance that +the controller cannot change). Further points of interest: =========================== @@ -57,30 +69,31 @@ A lot of tasks could be performed using transparent proxies. Including, but not limited to: -* Remote version of objects, on which we perform operations +* A Remote version of objects, on which we perform operations (think about transparent distribution) -* Access to some persistent-storages like databases (imagine +* Access to some persistent-storages like databases (imagine an SQL object mapper which looks like real object) * Access to external data structures, like other languages as normal - objects. (Of course some will raise exceptions, but it's purely done - in application level, so it's not real problem) + objects. (Of course some operations on them could raise exceptions, but it's + purely done in application level, so it's not real problem) Random notes: ============= -Transparent proxy is implemented on top of `standart object space`_, in +Transparent proxy is implemented on top of `standard object space`_, in `proxy_helpers.py`_, `proxyobject.py`_ and `transparent.py`_. To run it you need to pass ``--with-transparent-proxy`` option to ``py.py`` or ``translate.py``. It registers implementations like a ``W_TransparentXxx`` which usually corresponds to an apropriate ``W_XxxObject``, including some -interpreter hacks for objects that are too involved into interpreter -tricks to be implemented in a std objspace. Actually working objects are: +interpreter hacks for objects that are too close to the interpreter +to be implemented in a std objspace. The types of objects that can be proxied +like this are: user created classes & functions, lists, dicts, exceptions, tracebacks and frames. -.. _`standart object space`: objspace.html#the-standard-object-space +.. _`standard object space`: objspace.html#the-standard-object-space .. _`proxy_helpers.py`: http://codespeak.net/svn/pypy/dist/pypy/objspace/std/proxy_helpers.py .. _`proxyobject.py`: http://codespeak.net/svn/pypy/dist/pypy/objspace/std/proxyobject.py .. _`transparent.py`: http://codespeak.net/svn/pypy/dist/pypy/objspace/std/transparent.py From cfbolz at codespeak.net Sat Feb 3 01:56:53 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sat, 3 Feb 2007 01:56:53 +0100 (CET) Subject: [pypy-svn] r37846 - pypy/dist/pypy/doc/config Message-ID: <20070203005653.19FC110068@code0.codespeak.net> Author: cfbolz Date: Sat Feb 3 01:56:51 2007 New Revision: 37846 Modified: pypy/dist/pypy/doc/config/objspace.name.txt pypy/dist/pypy/doc/config/objspace.opcodes.CALL_LIKELY_BUILTIN.txt pypy/dist/pypy/doc/config/objspace.std.allopts.txt pypy/dist/pypy/doc/config/objspace.std.withmultidict.txt pypy/dist/pypy/doc/config/objspace.std.withrangelist.txt pypy/dist/pypy/doc/config/objspace.std.withshadowtracking.txt pypy/dist/pypy/doc/config/objspace.std.withsharingdict.txt pypy/dist/pypy/doc/config/objspace.std.withsmallint.txt pypy/dist/pypy/doc/config/objspace.std.withtproxy.txt pypy/dist/pypy/doc/config/objspace.usepycfiles.txt Log: document some more of the options Modified: pypy/dist/pypy/doc/config/objspace.name.txt ============================================================================== --- pypy/dist/pypy/doc/config/objspace.name.txt (original) +++ pypy/dist/pypy/doc/config/objspace.name.txt Sat Feb 3 01:56:51 2007 @@ -0,0 +1,11 @@ +Which `Object Space`_ to use. The `Standard Object Space`_ gives the normal +Python semantics, the others give additional features (except the Flow Object +Space which is not intended for normal useage): + + * The `Thunk Object Space`_ adds lazy evaluation to Python + +XXX add the others + +.. _`Object Space`: ../objspace.html +.. _`Standard Object Space`: ../objspace.html#standard-object-space +.. _`Thunk Object Space`: ../objspace.html#thunk-object-space Modified: pypy/dist/pypy/doc/config/objspace.opcodes.CALL_LIKELY_BUILTIN.txt ============================================================================== --- pypy/dist/pypy/doc/config/objspace.opcodes.CALL_LIKELY_BUILTIN.txt (original) +++ pypy/dist/pypy/doc/config/objspace.opcodes.CALL_LIKELY_BUILTIN.txt Sat Feb 3 01:56:51 2007 @@ -0,0 +1,8 @@ +Introduce a new opcode called ``CALL_LIKELY_BUILTIN``. It is used when something +is called, that looks like a builtin function (but could in reality be shadowed +by something in the module globals). For all module globals dictionaries it is +then tracked, which builtin name is shadowed in this module. If the +``CALL_LIKELY_BUILTIN`` opcode is executed, it is checked whether the builtin is +shadowed. If not, the corresponding builtin is called. Otherwise the object that +is shadowing it is called instead. If no shadowing is happening, this safes two +dictionary lookups on calls to builtins. Modified: pypy/dist/pypy/doc/config/objspace.std.allopts.txt ============================================================================== --- pypy/dist/pypy/doc/config/objspace.std.allopts.txt (original) +++ pypy/dist/pypy/doc/config/objspace.std.allopts.txt Sat Feb 3 01:56:51 2007 @@ -0,0 +1,2 @@ +This tries to enable a set of options that makes the resulting pypy-c as fast as +possible. Modified: pypy/dist/pypy/doc/config/objspace.std.withmultidict.txt ============================================================================== --- pypy/dist/pypy/doc/config/objspace.std.withmultidict.txt (original) +++ pypy/dist/pypy/doc/config/objspace.std.withmultidict.txt Sat Feb 3 01:56:51 2007 @@ -0,0 +1,13 @@ +This enables "multidicts". They are a different implementation of the Python +``dict`` type, indistinguishable for the normal user (when using multidicts, the +normal implementation is not used at all). When the multidict implementation is +used, a dictionary can change its internal representation over its lifetime. It +starts with an "empty" representation (that can represent only empty dicts). If +a few keys are added, it changes its representation to a "small" one (that is +optimized for small dicts). As long as only string keys are added, a +representation optimized for string keys is used. Since this case is extremely +common in Python, this makes multidicts a good deal faster than the regular +dictionary implementation. + +The flexibility of multidicts is used by a couple of other, even more advanced +object implementations. Modified: pypy/dist/pypy/doc/config/objspace.std.withrangelist.txt ============================================================================== --- pypy/dist/pypy/doc/config/objspace.std.withrangelist.txt (original) +++ pypy/dist/pypy/doc/config/objspace.std.withrangelist.txt Sat Feb 3 01:56:51 2007 @@ -1,4 +1,4 @@ -Enable "range list" objects. They are a different implementation of the Python +Enable "range list" objects. They are an additional implementation of the Python ``list`` type, indistinguishable for the normal user. Whenever the ``range`` builtin is called, an range list is returned. As long as this list is not mutated (and for example only iterated over), it uses only enough memory to Modified: pypy/dist/pypy/doc/config/objspace.std.withshadowtracking.txt ============================================================================== --- pypy/dist/pypy/doc/config/objspace.std.withshadowtracking.txt (original) +++ pypy/dist/pypy/doc/config/objspace.std.withshadowtracking.txt Sat Feb 3 01:56:51 2007 @@ -0,0 +1,11 @@ +Enable "shadow tracking". This means a special dict representation is used +together with `multidicts`_. This dict representation is used only for instance +dictionaries. The instance dictionary tracks whether an instance attribute +shadows an attribute of it's class. This makes method calls slightly faster in +the following way: When calling a method the first thing that is checked is the +class dictionary to find descriptors. Usually, when a method is found, the +instance dictionary is then checked for instance attributes shadowing the class +attribute. If we know that there is no shadowing (since our instance dict tells +us that) we can save this lookup on the instance dictionary. + +.. _`multidicts`: objspace.std.withmultidict.html Modified: pypy/dist/pypy/doc/config/objspace.std.withsharingdict.txt ============================================================================== --- pypy/dist/pypy/doc/config/objspace.std.withsharingdict.txt (original) +++ pypy/dist/pypy/doc/config/objspace.std.withsharingdict.txt Sat Feb 3 01:56:51 2007 @@ -0,0 +1,13 @@ +Enable "sharing dictionaries". They are a special dict representation used +together with `multidicts`_. This dict representation is used only for instance +dictionaries and tries to make instance dictionaries use less memory (in fact, +in the ideal case the memory behaviour should be mostly like that of using +__slots__). + +The idea is the following: Most instances of the same class have very similar +attributes. Therefore all the instance dictionaries of these instances all store +the same keys. To save memory, these common keys could be stored in a common +place. This is exactly what "sharing dictionaries" are doing: only the values +themselves are stored on the instance, the rest in a shared structure. + +.. _`multidicts`: objspace.std.withmultidict.html Modified: pypy/dist/pypy/doc/config/objspace.std.withsmallint.txt ============================================================================== --- pypy/dist/pypy/doc/config/objspace.std.withsmallint.txt (original) +++ pypy/dist/pypy/doc/config/objspace.std.withsmallint.txt Sat Feb 3 01:56:51 2007 @@ -0,0 +1,6 @@ +Use "tagged pointers" to represent small enough integer values: Integers that +fit into 31 bits (respective 63 bits on 64 bit machines) are not represented by +boxing them in an instance of ``W_IntObject``. Instead they are represented as a +pointer having the lowest bit set and the rest of the bits used to store the +value of the integer. This gives a small speedup for integer operations as well +as better memory behaviour. Modified: pypy/dist/pypy/doc/config/objspace.std.withtproxy.txt ============================================================================== --- pypy/dist/pypy/doc/config/objspace.std.withtproxy.txt (original) +++ pypy/dist/pypy/doc/config/objspace.std.withtproxy.txt Sat Feb 3 01:56:51 2007 @@ -0,0 +1,3 @@ +Enable `transparent proxies`_. + +.. _`transparent proxies`: ../proxy.html Modified: pypy/dist/pypy/doc/config/objspace.usepycfiles.txt ============================================================================== --- pypy/dist/pypy/doc/config/objspace.usepycfiles.txt (original) +++ pypy/dist/pypy/doc/config/objspace.usepycfiles.txt Sat Feb 3 01:56:51 2007 @@ -0,0 +1,3 @@ +Whether PyPy should import and generate "pyc" files. This is mostly always on, +except when using other options that lead to PyPy-specific bytecodes that should +not be cached on disk because they might confuse CPython. From pedronis at codespeak.net Sat Feb 3 02:32:12 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 3 Feb 2007 02:32:12 +0100 (CET) Subject: [pypy-svn] r37847 - pypy/branch/jit-virtual-world/pypy/jit/goal Message-ID: <20070203013212.F3E1E10063@code0.codespeak.net> Author: pedronis Date: Sat Feb 3 02:32:09 2007 New Revision: 37847 Modified: pypy/branch/jit-virtual-world/pypy/jit/goal/targetjit.py Log: oops Modified: pypy/branch/jit-virtual-world/pypy/jit/goal/targetjit.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/goal/targetjit.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/goal/targetjit.py Sat Feb 3 02:32:09 2007 @@ -45,7 +45,7 @@ def handle_config(self, config): config.translation.fork_before = 'hintannotate' - config.translation.inline_threshold = 20.1 + config.translation.backendopt.inline_threshold = 20.1 def handle_translate_config(self, translateconfig): translateconfig.goals = ['timeshift'] From pedronis at codespeak.net Sat Feb 3 04:22:01 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 3 Feb 2007 04:22:01 +0100 (CET) Subject: [pypy-svn] r37848 - pypy/branch/jit-virtual-world/pypy/translator/backendopt Message-ID: <20070203032201.3C41E10069@code0.codespeak.net> Author: pedronis Date: Sat Feb 3 04:21:59 2007 New Revision: 37848 Modified: pypy/branch/jit-virtual-world/pypy/translator/backendopt/all.py Log: umph Modified: pypy/branch/jit-virtual-world/pypy/translator/backendopt/all.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/translator/backendopt/all.py (original) +++ pypy/branch/jit-virtual-world/pypy/translator/backendopt/all.py Sat Feb 3 04:21:59 2007 @@ -37,7 +37,7 @@ # merge_if_blocks, constfold, heap2stack # clever_malloc_removal, remove_asserts - config = translator.config.translation.backendopt.copy() + config = translator.config.translation.backendopt.copy(as_default=True) config.set(**kwds) if graphs is None: From ericvrp at codespeak.net Sat Feb 3 09:54:21 2007 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Sat, 3 Feb 2007 09:54:21 +0100 (CET) Subject: [pypy-svn] r37849 - pypy/dist/pypy/jit/codegen/llvm/test Message-ID: <20070203085421.AE26410069@code0.codespeak.net> Author: ericvrp Date: Sat Feb 3 09:54:20 2007 New Revision: 37849 Modified: pypy/dist/pypy/jit/codegen/llvm/test/test_rgenop.py Log: Skip three more tests that segfault with llvm 1.9 but work with llvm 2.0 Modified: pypy/dist/pypy/jit/codegen/llvm/test/test_rgenop.py ============================================================================== --- pypy/dist/pypy/jit/codegen/llvm/test/test_rgenop.py (original) +++ pypy/dist/pypy/jit/codegen/llvm/test/test_rgenop.py Sat Feb 3 09:54:20 2007 @@ -25,6 +25,9 @@ test_fact_direct = skip_too_minimal #segfault test_fact_compile= skip_too_minimal #segfault test_tight_loop = skip_too_minimal #llvm 1.9 assertion failure + test_from_random_2_direct = skip_too_minimal #segfault + test_from_random_3_direct = skip_too_minimal #segfault + test_from_random_4_direct = skip_too_minimal #segfault test_read_frame_var_direct = skip test_read_frame_var_compile = skip From fijal at codespeak.net Sat Feb 3 11:52:56 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 3 Feb 2007 11:52:56 +0100 (CET) Subject: [pypy-svn] r37852 - in pypy/dist/pypy/translator/js: demo/jsdemo demo/jsdemo/test examples Message-ID: <20070203105256.187611006E@code0.codespeak.net> Author: fijal Date: Sat Feb 3 11:52:54 2007 New Revision: 37852 Added: pypy/dist/pypy/translator/js/examples/pythonconsole.py - copied unchanged from r37799, pypy/dist/pypy/translator/js/demo/jsdemo/pythonconsole.py Removed: pypy/dist/pypy/translator/js/demo/jsdemo/pythonconsole.py Modified: pypy/dist/pypy/translator/js/demo/jsdemo/test/test_demo.py Log: Move pythonconsole to examples, hopefully it'll kill demo directory at some point (or at least most of it's inhabitants) Modified: pypy/dist/pypy/translator/js/demo/jsdemo/test/test_demo.py ============================================================================== --- pypy/dist/pypy/translator/js/demo/jsdemo/test/test_demo.py (original) +++ pypy/dist/pypy/translator/js/demo/jsdemo/test/test_demo.py Sat Feb 3 11:52:54 2007 @@ -1,4 +1,5 @@ -from pypy.translator.js.demo.jsdemo import example, pythonconsole +from pypy.translator.js.demo.jsdemo import example +from pypy.translator.js.examples import pythonconsole from pypy.translator.js.demo.jsdemo.support import js_source def test_example(): From fijal at codespeak.net Sat Feb 3 11:55:18 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 3 Feb 2007 11:55:18 +0100 (CET) Subject: [pypy-svn] r37853 - in pypy/dist/pypy/translator/js/lib: . test Message-ID: <20070203105518.656941006E@code0.codespeak.net> Author: fijal Date: Sat Feb 3 11:55:17 2007 New Revision: 37853 Added: pypy/dist/pypy/translator/js/lib/__init__.py (contents, props changed) Modified: pypy/dist/pypy/translator/js/lib/ (props changed) pypy/dist/pypy/translator/js/lib/test/ (props changed) Log: Oops, add missing files Added: pypy/dist/pypy/translator/js/lib/__init__.py ============================================================================== From fijal at codespeak.net Sat Feb 3 11:56:41 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 3 Feb 2007 11:56:41 +0100 (CET) Subject: [pypy-svn] r37854 - pypy/dist/pypy/translator/js/lib/test Message-ID: <20070203105641.298DD10071@code0.codespeak.net> Author: fijal Date: Sat Feb 3 11:56:40 2007 New Revision: 37854 Added: pypy/dist/pypy/translator/js/lib/test/__init__.py Log: This one would be cool as well Added: pypy/dist/pypy/translator/js/lib/test/__init__.py ============================================================================== From hpk at codespeak.net Sat Feb 3 12:24:00 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sat, 3 Feb 2007 12:24:00 +0100 (CET) Subject: [pypy-svn] r37856 - pypy/branch/pytrunkmerge Message-ID: <20070203112400.A92B110061@code0.codespeak.net> Author: hpk Date: Sat Feb 3 12:23:59 2007 New Revision: 37856 Added: pypy/branch/pytrunkmerge/ - copied from r37855, pypy/dist/ Log: opening a branch for integrating py-trunk changes (probably not many) From fijal at codespeak.net Sat Feb 3 12:24:09 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 3 Feb 2007 12:24:09 +0100 (CET) Subject: [pypy-svn] r37857 - in pypy/dist/pypy/translator/js/lib: . test Message-ID: <20070203112409.9779110070@code0.codespeak.net> Author: fijal Date: Sat Feb 3 12:24:07 2007 New Revision: 37857 Modified: pypy/dist/pypy/translator/js/lib/server.py pypy/dist/pypy/translator/js/lib/test/test_server.py Log: Add a static handler for server.py Modified: pypy/dist/pypy/translator/js/lib/server.py ============================================================================== --- pypy/dist/pypy/translator/js/lib/server.py (original) +++ pypy/dist/pypy/translator/js/lib/server.py Sat Feb 3 12:24:07 2007 @@ -98,6 +98,15 @@ self.end_headers() self.wfile.write(data) +class Static(object): + exposed = True + + def __init__(self, path): + self.path = path + + def __call__(self): + return open(self.path).read() + def start_server(server_address = ('', 8000), handler=TestHandler, fork=False): httpd = HTTPServer(server_address, handler) Modified: pypy/dist/pypy/translator/js/lib/test/test_server.py ============================================================================== --- pypy/dist/pypy/translator/js/lib/test/test_server.py (original) +++ pypy/dist/pypy/translator/js/lib/test/test_server.py Sat Feb 3 12:24:07 2007 @@ -2,8 +2,10 @@ """ Server testing """ +import py from pypy.translator.js.lib import server from urllib import URLopener +import os class Handler(server.TestHandler): def index(self): @@ -21,3 +23,17 @@ server.start_server(server_address=('127.0.0.1', 21211), handler=Handler, fork=True) assert URLopener().open("http://127.0.0.1:21210/index").read() == "xxx" + +def test_static_page(): + import thread + tmpdir = py.test.ensuretemp("server_static_page") + tmpdir.ensure("test.html").write("") + + class StaticHandler(server.TestHandler): + static_dir = str(tmpdir) + index = server.Static(os.path.join(static_dir, "test.html")) + + httpd = server.HTTPServer(('127.0.0.1', 21212), StaticHandler) + thread.start_new_thread(httpd.serve_forever, ()) + assert URLopener().open("http://127.0.0.1:21212/index").read() == \ + "" From hpk at codespeak.net Sat Feb 3 12:28:32 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sat, 3 Feb 2007 12:28:32 +0100 (CET) Subject: [pypy-svn] r37858 - pypy/branch/pytrunkmerge Message-ID: <20070203112832.6F71410072@code0.codespeak.net> Author: hpk Date: Sat Feb 3 12:28:31 2007 New Revision: 37858 Modified: pypy/branch/pytrunkmerge/ (props changed) Log: using py-trunk as external From cfbolz at codespeak.net Sat Feb 3 13:02:40 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sat, 3 Feb 2007 13:02:40 +0100 (CET) Subject: [pypy-svn] r37860 - pypy/dist/lib-python Message-ID: <20070203120240.0C7731006E@code0.codespeak.net> Author: cfbolz Date: Sat Feb 3 13:02:39 2007 New Revision: 37860 Modified: pypy/dist/lib-python/conftest.py Log: check for truth value using the space ("how did that ever work?") Modified: pypy/dist/lib-python/conftest.py ============================================================================== --- pypy/dist/lib-python/conftest.py (original) +++ pypy/dist/lib-python/conftest.py Sat Feb 3 13:02:39 2007 @@ -273,8 +273,8 @@ filename = str(self.fspath) callex(space, set_argv, space, space.wrap(filename)) #space.call_function(self.w_method) - res = callex(space, run_testcase_method, space, self.w_method) - if res: + w_res = callex(space, run_testcase_method, space, self.w_method) + if space.is_true(w_res): raise AssertionError( "testcase instance invociation raised errors, see stdoudt") From fijal at codespeak.net Sat Feb 3 13:35:52 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 3 Feb 2007 13:35:52 +0100 (CET) Subject: [pypy-svn] r37867 - in pypy/branch/pytrunkmerge: lib-python pypy/tool/pytest pypy/tool/test Message-ID: <20070203123552.40D9B1006E@code0.codespeak.net> Author: fijal Date: Sat Feb 3 13:35:48 2007 New Revision: 37867 Modified: pypy/branch/pytrunkmerge/lib-python/conftest.py pypy/branch/pytrunkmerge/pypy/tool/pytest/appsupport.py pypy/branch/pytrunkmerge/pypy/tool/test/test_conftest1.py Log: Adapt to outcome.py Modified: pypy/branch/pytrunkmerge/lib-python/conftest.py ============================================================================== --- pypy/branch/pytrunkmerge/lib-python/conftest.py (original) +++ pypy/branch/pytrunkmerge/lib-python/conftest.py Sat Feb 3 13:35:48 2007 @@ -12,6 +12,7 @@ from pypy.interpreter.module import Module as PyPyModule from pypy.interpreter.main import run_string, run_file from py.__.misc.simplecapture import callcapture +from py.__.test.outcome import Failed, Skipped # the following adds command line options as a side effect! from pypy.conftest import gettestobjspace, option as pypy_option @@ -68,8 +69,8 @@ if appexcinfo.traceback: print "appexcinfo.traceback:" py.std.pprint.pprint(appexcinfo.traceback) - raise py.test.Item.Failed(excinfo=appexcinfo) - raise py.test.Item.Failed(excinfo=ilevelinfo) + raise Failed(excinfo=appexcinfo) + raise Failed(excinfo=ilevelinfo) # # compliance modules where we invoke test_main() usually call into Modified: pypy/branch/pytrunkmerge/pypy/tool/pytest/appsupport.py ============================================================================== --- pypy/branch/pytrunkmerge/pypy/tool/pytest/appsupport.py (original) +++ pypy/branch/pytrunkmerge/pypy/tool/pytest/appsupport.py Sat Feb 3 13:35:48 2007 @@ -4,6 +4,7 @@ from py.__.magic import exprinfo from pypy.interpreter import gateway from pypy.interpreter.error import OperationError +from py.__.test.outcome import ExceptionFailure # ____________________________________________________________ @@ -212,7 +213,7 @@ if not value.match(space, w_ExpectedException): raise type, value, tb return excinfo - except py.test.Item.ExceptionFailure, e: + except ExceptionFailure, e: e.tbindex = getattr(e, 'tbindex', -1) - 1 raise Modified: pypy/branch/pytrunkmerge/pypy/tool/test/test_conftest1.py ============================================================================== --- pypy/branch/pytrunkmerge/pypy/tool/test/test_conftest1.py (original) +++ pypy/branch/pytrunkmerge/pypy/tool/test/test_conftest1.py Sat Feb 3 13:35:48 2007 @@ -3,19 +3,20 @@ innertest = py.magic.autopath().dirpath('conftest1_innertest.py') from py.__.test.terminal.terminal import TerminalSession +from py.__.test.outcome import Passed, Failed, Skipped class TestPyPyTests: def test_select_interplevel(self): config = py.test.config._reparse([innertest, '-k', 'interplevel']) session = TerminalSession(config, py.std.sys.stdout) session.main() - l = session.getitemoutcomepairs(py.test.Item.Passed) + l = session.getitemoutcomepairs(Passed) assert len(l) == 2 for item in l: assert item[0].name in ('test_something', 'test_method') #item = l[0][0] #assert item.name == 'test_one' - l = session.getitemoutcomepairs(py.test.Item.Skipped) + l = session.getitemoutcomepairs(Skipped) assert len(l) == 2 for item in l: assert item[0].name in ('app_test_something', 'test_method_app') @@ -24,13 +25,13 @@ config = py.test.config._reparse([innertest, '-k', 'applevel']) session = TerminalSession(config, py.std.sys.stdout) session.main() - l = session.getitemoutcomepairs(py.test.Item.Passed) + l = session.getitemoutcomepairs(Passed) assert len(l) == 2 for item in l: assert item[0].name in ('app_test_something', 'test_method_app') #item = l[0][0] #assert item.name == 'test_one' - l = session.getitemoutcomepairs(py.test.Item.Skipped) + l = session.getitemoutcomepairs(Skipped) assert len(l) == 2 for item in l: assert item[0].name in ('test_something', 'test_method') @@ -40,13 +41,13 @@ '-k', 'applevel', '--appdirect']) session = TerminalSession(config, py.std.sys.stdout) session.main() - l = session.getitemoutcomepairs(py.test.Item.Passed) + l = session.getitemoutcomepairs(Passed) assert len(l) == 2 for item in l: assert item[0].name in ('app_test_something', 'test_method_app') #item = l[0][0] #assert item.name == 'test_one' - l = session.getitemoutcomepairs(py.test.Item.Skipped) + l = session.getitemoutcomepairs(Skipped) assert len(l) == 2 for item in l: assert item[0].name in ('test_something', 'test_method') From santagada at codespeak.net Sat Feb 3 14:05:14 2007 From: santagada at codespeak.net (santagada at codespeak.net) Date: Sat, 3 Feb 2007 14:05:14 +0100 (CET) Subject: [pypy-svn] r37868 - in pypy/dist/pypy/lang/js: . test Message-ID: <20070203130514.1BA3410069@code0.codespeak.net> Author: santagada Date: Sat Feb 3 14:05:13 2007 New Revision: 37868 Added: pypy/dist/pypy/lang/js/driver.py (contents, props changed) Modified: pypy/dist/pypy/lang/js/interpreter.py pypy/dist/pypy/lang/js/jsobj.py pypy/dist/pypy/lang/js/test/test_interp.py Log: driver and some simple opcodes Added: pypy/dist/pypy/lang/js/driver.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/lang/js/driver.py Sat Feb 3 14:05:13 2007 @@ -0,0 +1,32 @@ +#!/usr/bin/env python + +import autopath +from py import path +import os + +shell = path.local(__file__).dirpath('test', 'ecma', 'shell.js') + +exclusionlist = ['shell.js', 'browser.js'] +def filter(filename): + if filename.basename in exclusionlist or not filename.basename.endswith('.js'): + return False + else: + return True +results = open('results.txt', 'w') +for f in path.local(__file__).dirpath('test', 'ecma').visit(filter): + print f.basename + stdout = os.popen('./js_interactive.py -n -f %s -f %s'%(shell.strpath,f.strpath), 'r') + passed = 0 + total = 0 + for line in stdout.readlines(): + if "PASSED!" in line: + passed += 1 + total += 1 + elif "FAILED!" in line: + total += 1 + + results.write('%s passed %s of %s tests\n'%(f.basename, passed, total)) + results.flush() + + + Modified: pypy/dist/pypy/lang/js/interpreter.py ============================================================================== --- pypy/dist/pypy/lang/js/interpreter.py (original) +++ pypy/dist/pypy/lang/js/interpreter.py Sat Feb 3 14:05:13 2007 @@ -69,7 +69,6 @@ self.right = get_obj(t, '1') class BinaryComparisonOp(BinaryOp): - """super class for binary operators""" def eval(self, ctx): s2 = self.left.eval(ctx).GetValue() s4 = self.right.eval(ctx).GetValue() @@ -81,7 +80,6 @@ raise NotImplementedError class BinaryLogicOp(BinaryOp): - """super class for binary operators""" pass def writer(x): @@ -611,6 +609,15 @@ fright = nright.ToNumber() return W_Number(fleft * fright) +class Mod(BinaryNumberOp): + opcode = 'MOD' + + def mathop(self, ctx, nleft, nright): + fleft = nleft.ToNumber() + fright = nright.ToNumber() + return W_Number(fleft % fright) + + class Div(BinaryNumberOp): opcode = 'DIV' @@ -843,11 +850,18 @@ return W_Boolean(not self.expr.eval(ctx).GetValue().ToBoolean()) class UMinus(UnaryOp): - opcode = "UNARY_MINUS" + opcode = 'UNARY_MINUS' def eval(self, ctx): return W_Number(-self.expr.eval(ctx).GetValue().ToNumber()) +class UPlus(UnaryOp): + opcode = 'UNARY_PLUS' + + def eval(self, ctx): + return W_Number(+self.expr.eval(ctx).GetValue().ToNumber()) + + astundef = Undefined() def get_obj(t, objname): item = get_tree_item(t, objname) Modified: pypy/dist/pypy/lang/js/jsobj.py ============================================================================== --- pypy/dist/pypy/lang/js/jsobj.py (original) +++ pypy/dist/pypy/lang/js/jsobj.py Sat Feb 3 14:05:13 2007 @@ -1,6 +1,6 @@ # encoding: utf-8 -DEBUG = True +DEBUG = False class SeePage(NotImplementedError): pass @@ -318,7 +318,7 @@ return W_PrimitiveObject.Get(self, P) def str_builtin(self, ctx, args, this): - return W_String(ToString()) + return W_String(self.ToString()) def ToString(self): return ','.join(self.array) Modified: pypy/dist/pypy/lang/js/test/test_interp.py ============================================================================== --- pypy/dist/pypy/lang/js/test/test_interp.py (original) +++ pypy/dist/pypy/lang/js/test/test_interp.py Sat Feb 3 14:05:13 2007 @@ -447,4 +447,10 @@ var testcases = new Array(); var tc = testcases.length; print('tc'+tc) - """, ['tc0']) \ No newline at end of file + """, ['tc0']) + + def test_mod_op(self): + self.assert_prints("print(2%2)", ['0']) + + def test_unary_plus(self): + self.assert_prints("print(+1)", ['1']) From santagada at codespeak.net Sat Feb 3 14:35:16 2007 From: santagada at codespeak.net (santagada at codespeak.net) Date: Sat, 3 Feb 2007 14:35:16 +0100 (CET) Subject: [pypy-svn] r37869 - pypy/dist/pypy/lang/js Message-ID: <20070203133516.6937D10071@code0.codespeak.net> Author: santagada Date: Sat Feb 3 14:35:13 2007 New Revision: 37869 Modified: pypy/dist/pypy/lang/js/jsparser.py Log: fixed the temp file problem Modified: pypy/dist/pypy/lang/js/jsparser.py ============================================================================== --- pypy/dist/pypy/lang/js/jsparser.py (original) +++ pypy/dist/pypy/lang/js/jsparser.py Sat Feb 3 14:35:13 2007 @@ -28,12 +28,9 @@ jsdir = py.path.local(__file__).dirpath().join("js") jsdefs = jsdir.join("jsdefs.js").read() jsparse = jsdir.join("jsparse.js").read() - f = open('/tmp/jstobeparsed.js','w') - f.write(jsdefs) - f.write(jsparse) - f.write("print(parse('%s'));\n" % stripped_code) - f.close() - pipe = os.popen("js -f /tmp/jstobeparsed.js", 'r') + f = py.test.ensuretemp("jsinterp").join("tobeparsed.js") + f.write(jsdefs+jsparse+"print(parse('%s'));\n" % stripped_code) + pipe = os.popen("js -f "+str(f), 'r') retval = pipe.read() if not retval.startswith("{"): raise JsSyntaxError(retval) From cfbolz at codespeak.net Sat Feb 3 16:39:06 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sat, 3 Feb 2007 16:39:06 +0100 (CET) Subject: [pypy-svn] r37873 - pypy/dist/pypy/objspace/std Message-ID: <20070203153906.A2ED310071@code0.codespeak.net> Author: cfbolz Date: Sat Feb 3 16:39:04 2007 New Revision: 37873 Modified: pypy/dist/pypy/objspace/std/stringobject.py Log: don't be implementation-specific for no good reason Modified: pypy/dist/pypy/objspace/std/stringobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/stringobject.py (original) +++ pypy/dist/pypy/objspace/std/stringobject.py Sat Feb 3 16:39:04 2007 @@ -233,7 +233,7 @@ # continue to look from the character following the space after the word i = j + 1 - return W_ListObject(res_w) + return space.newlist(res_w) def str_split__String_String_ANY(space, w_self, w_by, w_maxsplit=-1): @@ -256,7 +256,7 @@ res_w.append(sliced(space, value, start, len(value))) - return W_ListObject(res_w) + return space.newlist(res_w) def str_rsplit__String_None_ANY(space, w_self, w_none, w_maxsplit=-1): maxsplit = space.int_w(w_maxsplit) @@ -291,7 +291,7 @@ i = j - 1 res_w.reverse() - return W_ListObject(res_w) + return space.newlist(res_w) def str_rsplit__String_String_ANY(space, w_self, w_by, w_maxsplit=-1): maxsplit = space.int_w(w_maxsplit) @@ -313,7 +313,7 @@ res_w.append(sliced(space, value, 0, end)) res_w.reverse() - return W_ListObject(res_w) + return space.newlist(res_w) def str_join__String_ANY(space, w_self, w_list): list_w = space.unpackiterable(w_list) From fijal at codespeak.net Sat Feb 3 19:58:50 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 3 Feb 2007 19:58:50 +0100 (CET) Subject: [pypy-svn] r37882 - pypy/branch/pytrunkmerge/pypy Message-ID: <20070203185850.0AA3710071@code0.codespeak.net> Author: fijal Date: Sat Feb 3 19:58:49 2007 New Revision: 37882 Modified: pypy/branch/pytrunkmerge/pypy/conftest.py Log: Adapt to new interface Modified: pypy/branch/pytrunkmerge/pypy/conftest.py ============================================================================== --- pypy/branch/pytrunkmerge/pypy/conftest.py (original) +++ pypy/branch/pytrunkmerge/pypy/conftest.py Sat Feb 3 19:58:49 2007 @@ -218,10 +218,10 @@ _pygame_imported = False class IntTestFunction(PyPyTestFunction): - def haskeyword(self, keyword): + def _haskeyword(self, keyword): if keyword == 'interplevel': return True - return super(IntTestFunction, self).haskeyword(keyword) + return super(IntTestFunction, self)._haskeyword(keyword) def execute(self, target, *args): co = target.func_code @@ -251,8 +251,8 @@ "if conftest.option.view is False") class AppTestFunction(PyPyTestFunction): - def haskeyword(self, keyword): - return keyword == 'applevel' or super(AppTestFunction, self).haskeyword(keyword) + def _haskeyword(self, keyword): + return keyword == 'applevel' or super(AppTestFunction, self)._haskeyword(keyword) def execute(self, target, *args): assert not args @@ -299,9 +299,9 @@ class IntClassCollector(PyPyClassCollector): Function = IntTestFunction - def haskeyword(self, keyword): + def _haskeyword(self, keyword): return keyword == 'interplevel' or \ - super(IntClassCollector, self).haskeyword(keyword) + super(IntClassCollector, self)._haskeyword(keyword) class AppClassInstance(py.test.collect.Instance): Function = AppTestMethod @@ -319,12 +319,12 @@ class AppClassCollector(PyPyClassCollector): Instance = AppClassInstance - def haskeyword(self, keyword): + def _haskeyword(self, keyword): return keyword == 'applevel' or \ - super(AppClassCollector, self).haskeyword(keyword) + super(AppClassCollector, self)._haskeyword(keyword) def setup(self): - super(AppClassCollector, self).setup() + super(AppClassCollector, self).setup() cls = self.obj space = cls.space clsname = cls.__name__ From hpk at codespeak.net Sat Feb 3 20:28:30 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sat, 3 Feb 2007 20:28:30 +0100 (CET) Subject: [pypy-svn] r37883 - pypy/branch/pytrunkmerge/lib-python Message-ID: <20070203192830.1E6B510069@code0.codespeak.net> Author: hpk Date: Sat Feb 3 20:28:29 2007 New Revision: 37883 Modified: pypy/branch/pytrunkmerge/lib-python/conftest.py Log: fixing capturing towards the new unified interface Modified: pypy/branch/pytrunkmerge/lib-python/conftest.py ============================================================================== --- pypy/branch/pytrunkmerge/lib-python/conftest.py (original) +++ pypy/branch/pytrunkmerge/lib-python/conftest.py Sat Feb 3 20:28:29 2007 @@ -11,7 +11,6 @@ from pypy.interpreter.error import OperationError from pypy.interpreter.module import Module as PyPyModule from pypy.interpreter.main import run_string, run_file -from py.__.misc.simplecapture import callcapture from py.__.test.outcome import Failed, Skipped # the following adds command line options as a side effect! @@ -170,18 +169,17 @@ """ def call_capture(self, space, func, *args): regrtest = self.parent.regrtest - oldsysout = sys.stdout - sys.stdout = capturesysout = py.std.cStringIO.StringIO() - try: + cap = py.io.StdCapture(out=True, err=False, in_=False) + try: try: res = regrtest.run_file(space) - except: - print capturesysout.getvalue() - raise - else: - return res, capturesysout.getvalue() - finally: - sys.stdout = oldsysout + finally: + out, err = cap.reset() + except: + print out + raise + else: + return res, out def run(self): # XXX integrate this into InterceptedRunModule @@ -992,7 +990,8 @@ test_stdout = "%s\n%s" % (self.fspath.purebasename, test_stdout) if test_stdout != expected: exit_status = 2 - res, out, err = callcapture(reportdiff, expected, test_stdout) + res, out, err = py.io.StdCapture.call( + reportdiff, expected, test_stdout) outcome = 'ERROUT' result.addnamedtext('reportdiff', out) else: From xoraxax at codespeak.net Sun Feb 4 01:29:38 2007 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sun, 4 Feb 2007 01:29:38 +0100 (CET) Subject: [pypy-svn] r37887 - pypy/dist/pypy/doc/config Message-ID: <20070204002938.D8CC710070@code0.codespeak.net> Author: xoraxax Date: Sun Feb 4 01:29:34 2007 New Revision: 37887 Modified: pypy/dist/pypy/doc/config/objspace.opcodes.CALL_LIKELY_BUILTIN.txt Log: Small typo. Modified: pypy/dist/pypy/doc/config/objspace.opcodes.CALL_LIKELY_BUILTIN.txt ============================================================================== --- pypy/dist/pypy/doc/config/objspace.opcodes.CALL_LIKELY_BUILTIN.txt (original) +++ pypy/dist/pypy/doc/config/objspace.opcodes.CALL_LIKELY_BUILTIN.txt Sun Feb 4 01:29:34 2007 @@ -4,5 +4,5 @@ then tracked, which builtin name is shadowed in this module. If the ``CALL_LIKELY_BUILTIN`` opcode is executed, it is checked whether the builtin is shadowed. If not, the corresponding builtin is called. Otherwise the object that -is shadowing it is called instead. If no shadowing is happening, this safes two +is shadowing it is called instead. If no shadowing is happening, this saves two dictionary lookups on calls to builtins. From tismer at codespeak.net Sun Feb 4 06:57:49 2007 From: tismer at codespeak.net (tismer at codespeak.net) Date: Sun, 4 Feb 2007 06:57:49 +0100 (CET) Subject: [pypy-svn] r37890 - in pypy/dist/pypy/translator/c/winproj: extension standalone Message-ID: <20070204055749.1F43510069@code0.codespeak.net> Author: tismer Date: Sun Feb 4 06:57:46 2007 New Revision: 37890 Modified: pypy/dist/pypy/translator/c/winproj/extension/extension.vcproj pypy/dist/pypy/translator/c/winproj/standalone/standalone.vcproj Log: just cleaning up after a loong time Modified: pypy/dist/pypy/translator/c/winproj/extension/extension.vcproj ============================================================================== --- pypy/dist/pypy/translator/c/winproj/extension/extension.vcproj (original) +++ pypy/dist/pypy/translator/c/winproj/extension/extension.vcproj Sun Feb 4 06:57:46 2007 @@ -208,7 +208,7 @@ + RelativePath="F:\tmp\usession-886\testing_1\testing_1.c"> Modified: pypy/dist/pypy/translator/c/winproj/standalone/standalone.vcproj ============================================================================== --- pypy/dist/pypy/translator/c/winproj/standalone/standalone.vcproj (original) +++ pypy/dist/pypy/translator/c/winproj/standalone/standalone.vcproj Sun Feb 4 06:57:46 2007 @@ -126,6 +126,9 @@ RelativePath="..\..\src\char.h"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - From arigo at codespeak.net Sun Feb 4 10:36:01 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 4 Feb 2007 10:36:01 +0100 (CET) Subject: [pypy-svn] r37891 - in pypy/branch/jit-virtual-world/pypy/jit/codegen/i386: . test Message-ID: <20070204093601.32CDE10071@code0.codespeak.net> Author: arigo Date: Sun Feb 4 10:35:58 2007 New Revision: 37891 Modified: pypy/branch/jit-virtual-world/pypy/jit/codegen/i386/ri386.py pypy/branch/jit-virtual-world/pypy/jit/codegen/i386/test/test_ri386.py Log: Cannot use << in RPython if the count can be 32 - it is misinterpreted as a shift by 0 in C code. Modified: pypy/branch/jit-virtual-world/pypy/jit/codegen/i386/ri386.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/codegen/i386/ri386.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/codegen/i386/ri386.py Sun Feb 4 10:35:58 2007 @@ -1,3 +1,4 @@ +from pypy.rlib.rarithmetic import intmask class OPERAND(object): @@ -276,15 +277,19 @@ def unpack(s): assert len(s) in (1, 2, 4) - result = 0 - shift = 0 - char = '\x00' # flow space workaround - for char in s: - result |= ord(char) << shift - shift += 8 - if ord(char) >= 0x80: - result -= 1 << shift - return result + if len(s) == 1: + a = ord(s[0]) + if a > 0x7f: + a -= 0x100 + else: + a = ord(s[0]) | (ord(s[1]) << 8) + if len(s) == 2: + if a > 0x7fff: + a -= 0x10000 + else: + a |= (ord(s[2]) << 16) | (ord(s[3]) << 24) + a = intmask(a) + return a missing = MISSING() Modified: pypy/branch/jit-virtual-world/pypy/jit/codegen/i386/test/test_ri386.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/codegen/i386/test/test_ri386.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/codegen/i386/test/test_ri386.py Sun Feb 4 10:35:58 2007 @@ -99,3 +99,15 @@ res = interpret(f, []) assert ''.join(res.chars) == '\x29\xCE\x89\x4D\x13' + + +def test_unpack_compiled(): + from pypy.translator.c.test.test_genc import compile + + def f(n): + return mem(ebp, n).ofs_relative_to_ebp() + + fn = compile(f, [int]) + for i in [0, 4, 44, 124, 128, 132, 252, 256, 10000000, + -4, -44, -124, -128, -132, -252, -256, -10000000]: + assert fn(i) == i From arigo at codespeak.net Sun Feb 4 10:40:01 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 4 Feb 2007 10:40:01 +0100 (CET) Subject: [pypy-svn] r37892 - in pypy/branch/jit-virtual-world/pypy/jit/timeshifter: . test Message-ID: <20070204094001.13C5810072@code0.codespeak.net> Author: arigo Date: Sun Feb 4 10:39:59 2007 New Revision: 37892 Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/hrtyper.py pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_virtualizable.py Log: (from pedronis) Test and fix: don't use PtrRedBox() to build boxes that are not necessarily pointers. Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/hrtyper.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/timeshifter/hrtyper.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/timeshifter/hrtyper.py Sun Feb 4 10:39:59 2007 @@ -1624,9 +1624,8 @@ def build_portal_arg_helpers(self): typedesc = self.gettypedesc() - names = unrolling_iterable([(fielddesc.fieldname, j) - for (fielddesc, j) in - typedesc.redirected_fielddescs]) + redirected_fielddescs = unrolling_iterable( + typedesc.redirected_fielddescs) TYPE = self.original_concretetype kind = self.hrtyper.RGenOp.kindToken(TYPE) @@ -1634,13 +1633,12 @@ box = typedesc.factory() jitstate.add_virtualizable(box) content = box.content - assert isinstance(content, rcontainer.VirtualStruct) + assert isinstance(content, rcontainer.VirtualizableStruct) content_boxes = content.content_boxes gv_outside = inputargs_gv[i] i += 1 - for name, j in names: - content_boxes[j] = rvalue.PtrRedBox(content_boxes[j].kind, - inputargs_gv[i]) + for fieldesc, j in redirected_fielddescs: + content_boxes[j] = fieldesc.makebox(None, inputargs_gv[i]) i += 1 content_boxes[-1] = rvalue.PtrRedBox(content_boxes[-1].kind, gv_outside, Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_virtualizable.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_virtualizable.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_virtualizable.py Sun Feb 4 10:39:59 2007 @@ -1283,3 +1283,47 @@ res = self.timeshift_from_portal(main, f, [20, 3], policy=StopAtXPolicy(g)) assert res == 222 + + def test_type_bug(self): + class V(object): + _virtualizable_ = True + + def __init__(self, v): + self.v = v + + def f(x, v): + if x: + v.v = 0 + else: + pass + return x*2, v + + def main(x,y): + v = V(y) + r, _ = f(x, v) + return r + + res = self.timeshift_from_portal(main, f, [20, 3], policy=P_OOPSPEC) + assert res == 40 + + def test_indirect_call(self): + py.test.skip("test in progress") + def h1(n): + return n * 6 # force some virtualizable stuff here + def h2(n): + return n * 8 + + l = [h2, h1] + + def f(n): + h = l[n & 1] + n += 10 + return h(n) # the result of the call is not in save_locals!! + + P = StopAtXPolicy() + + assert f(-3) == 42 + res = self.timeshift(f, [-3], [], policy=P) + assert res == 42 + res = self.timeshift(f, [4], [], policy=P) + assert res == 112 From pedronis at codespeak.net Sun Feb 4 12:33:19 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sun, 4 Feb 2007 12:33:19 +0100 (CET) Subject: [pypy-svn] r37893 - pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test Message-ID: <20070204113319.6090610070@code0.codespeak.net> Author: pedronis Date: Sun Feb 4 12:33:15 2007 New Revision: 37893 Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_virtualizable.py Log: have a real merge, not splitting on green vars Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_virtualizable.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_virtualizable.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_virtualizable.py Sun Feb 4 12:33:15 2007 @@ -425,30 +425,30 @@ y = xy_get_y(xy) e.w = y - def f(e): + def f(e, z): hint(None, global_merge_point=True) xy = e.xy y = xy_get_y(xy) newy = 2*y xy_set_y(xy, newy) if y: - dummy = 0 + dummy = z*2 else: - dummy = 1 + dummy = z*3 g(e) return dummy - def main(x, y): + def main(x, y, z): xy = lltype.malloc(XY) xy.vable_access = lltype.nullptr(XY_ACCESS) xy.x = x xy.y = y e = lltype.malloc(E) e.xy = xy - f(e) + f(e, z) return e.w - res = self.timeshift_from_portal(main, f, [0, 21], + res = self.timeshift_from_portal(main, f, [0, 21, 11], policy=StopAtXPolicy(g)) assert res == 42 From pedronis at codespeak.net Sun Feb 4 12:49:09 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sun, 4 Feb 2007 12:49:09 +0100 (CET) Subject: [pypy-svn] r37894 - pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test Message-ID: <20070204114909.CDB7F10077@code0.codespeak.net> Author: pedronis Date: Sun Feb 4 12:48:47 2007 New Revision: 37894 Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_timeshift.py Log: some basic tests about indirect calls Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_timeshift.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_timeshift.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_timeshift.py Sun Feb 4 12:48:47 2007 @@ -1348,3 +1348,49 @@ res = self.timeshift(f, [5, 10], [0], policy=P) assert res == 250 self.check_insns(int_mul=1, int_add=0) + + def test_indirect_red_call(self): + def h1(n): + return n*2 + def h2(n): + return n*4 + l = [h1, h2] + def f(n, x): + h = l[n&1] + return h(n) + x + + P = StopAtXPolicy() + res = self.timeshift(f, [7, 3], policy=P) + assert res == f(7,3) + self.check_insns(indirect_call=1) + + def test_indirect_gray_call(self): + def h1(w, n): + w[0] = n*2 + def h2(w, n): + w[0] = n*4 + l = [h1, h2] + def f(n, x): + w = [0] + h = l[n&1] + h(w, n) + return w[0] + x + + P = StopAtXPolicy() + res = self.timeshift(f, [7, 3], policy=P) + assert res == f(7,3) + + def test_indirect_residual_red_call(self): + def h1(n): + return n*2 + def h2(n): + return n*4 + l = [h1, h2] + def f(n, x): + h = l[n&1] + return h(n) + x + + P = StopAtXPolicy(h1, h2) + res = self.timeshift(f, [7, 3], policy=P) + assert res == f(7,3) + self.check_insns(indirect_call=1) From arigo at codespeak.net Sun Feb 4 12:49:14 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 4 Feb 2007 12:49:14 +0100 (CET) Subject: [pypy-svn] r37895 - in pypy/branch/jit-virtual-world/pypy/jit/timeshifter: . test Message-ID: <20070204114914.55F7210078@code0.codespeak.net> Author: arigo Date: Sun Feb 4 12:48:55 2007 New Revision: 37895 Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_virtualizable.py pypy/branch/jit-virtual-world/pypy/jit/timeshifter/transform.py Log: (pedronis, arigo) Test and fix for a save_locals() that didn't include most of the variables it should. Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_virtualizable.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_virtualizable.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_virtualizable.py Sun Feb 4 12:48:55 2007 @@ -1306,24 +1306,35 @@ res = self.timeshift_from_portal(main, f, [20, 3], policy=P_OOPSPEC) assert res == 40 - def test_indirect_call(self): - py.test.skip("test in progress") - def h1(n): - return n * 6 # force some virtualizable stuff here - def h2(n): + def test_indirect_residual_call(self): + class V(object): + _virtualizable_ = True + + def __init__(self, v): + self.v = v + + def g(v, n): + v.v.append(n) # force the virtualizable arg here + def h1(v, n): + g(v, n) + return n * 6 + def h2(v, n): return n * 8 l = [h2, h1] def f(n): + hint(None, global_merge_point=True) + v = V([100]) h = l[n & 1] n += 10 - return h(n) # the result of the call is not in save_locals!! + res = h(v, n) + return res - v.v.pop() - P = StopAtXPolicy() + P = StopAtXPolicy(g) - assert f(-3) == 42 - res = self.timeshift(f, [-3], [], policy=P) - assert res == 42 - res = self.timeshift(f, [4], [], policy=P) - assert res == 112 + assert f(-3) == 35 + res = self.timeshift_from_portal(f, f, [-3], policy=P) + assert res == 35 + res = self.timeshift_from_portal(f, f, [4], policy=P) + assert res == 12 Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/transform.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/timeshifter/transform.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/timeshifter/transform.py Sun Feb 4 12:48:55 2007 @@ -8,7 +8,6 @@ from pypy.translator.unsimplify import varoftype, copyvar from pypy.translator.unsimplify import split_block, split_block_at_start from pypy.translator.backendopt.ssa import SSA_to_SSI -from pypy.translator.unsimplify import split_block class MergePointFamily(object): @@ -628,15 +627,17 @@ postconstantblock.recloseblock(Link([], resumeblock)) if nonconstantblock is not None: + nonconstantblock.recloseblock(Link(linkargs, nextblock)) v_res, nonconstantblock2 = self.handle_residual_call_details( nonconstantblock, 0, op, - color, preserve_res = False) + color, preserve_res = + (color == 'red')) - if color == 'red': - linkargs[0] = v_res + #if color == 'red': + # linkargs[0] = v_res blockset[nonconstantblock2] = False - nonconstantblock2.recloseblock(Link(linkargs, nextblock)) + blockset[block] = True # reachable from outside blockset[nextblock] = True # reachable from outside From arigo at codespeak.net Sun Feb 4 13:45:48 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 4 Feb 2007 13:45:48 +0100 (CET) Subject: [pypy-svn] r37900 - in pypy/branch/jit-virtual-world/pypy/jit/timeshifter: . test Message-ID: <20070204124548.D6FE110072@code0.codespeak.net> Author: arigo Date: Sun Feb 4 13:45:47 2007 New Revision: 37900 Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/rtimeshift.py pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_promotion.py Log: (pedronis, arigo) A crash in leave_graph_yellow(). Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/rtimeshift.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/timeshifter/rtimeshift.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/timeshifter/rtimeshift.py Sun Feb 4 13:45:47 2007 @@ -1205,11 +1205,12 @@ if resuming is not None: resuming.leave_call(mydispatchqueue) return_chain = mydispatchqueue.return_chain - jitstate = return_chain - while jitstate is not None: - leave_frame(jitstate) - jitstate = jitstate.next - # return the jitstate which is the head of the chain, - # ready for further writing - return_chain.curbuilder.start_writing() + if return_chain is not None: + jitstate = return_chain + while jitstate is not None: + leave_frame(jitstate) + jitstate = jitstate.next + # return the jitstate which is the head of the chain, + # ready for further writing + return_chain.curbuilder.start_writing() return return_chain Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_promotion.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_promotion.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_promotion.py Sun Feb 4 13:45:47 2007 @@ -370,3 +370,17 @@ res = self.timeshift(ll_function, ["oe", 1], [], policy=StopAtXPolicy(w)) res == 1 + + def test_promote_in_yellow_call(self): + def ll_two(n): + n = hint(n, promote=True) + return n + 2 + + def ll_function(n): + hint(None, global_merge_point=True) + c = ll_two(n) + return hint(c, variable=True) + + res = self.timeshift(ll_function, [4], [], policy=P_NOVIRTUAL) + assert res == 6 + self.check_insns(int_add=0) From arigo at codespeak.net Sun Feb 4 14:11:52 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 4 Feb 2007 14:11:52 +0100 (CET) Subject: [pypy-svn] r37902 - pypy/branch/jit-virtual-world/pypy/jit/timeshifter Message-ID: <20070204131152.03FE210070@code0.codespeak.net> Author: arigo Date: Sun Feb 4 14:11:49 2007 New Revision: 37902 Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/hrtyper.py pypy/branch/jit-virtual-world/pypy/jit/timeshifter/transform.py Log: (pedronis, arigo) Add an explicit AssertionError when using promotion but forgetting the global merge point. Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/hrtyper.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/timeshifter/hrtyper.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/timeshifter/hrtyper.py Sun Feb 4 14:11:49 2007 @@ -183,6 +183,8 @@ # returns leaveportalgraph = entrygraph + self.contains_promotion = False + self.portal_contains_global_mp = False pending = [entrygraph] seen = {entrygraph: True} while pending: @@ -192,6 +194,10 @@ if nextgraph not in seen: pending.append(nextgraph) seen[nextgraph] = True + if self.contains_promotion: + assert self.portal_contains_global_mp, ( + "No global merge point found. " + "Forgot 'hint(None, global_merge_point=True)'?") # only keep the hint-annotated graphs that are really useful self.annotator.translator.graphs = [graph for graph in self.annotator.translator.graphs @@ -443,6 +449,10 @@ is_portal=is_portal) transformer.transform() flowmodel.checkgraph(graph) # for now + self.contains_promotion |= transformer.contains_promotion + if is_portal: + self.portal_contains_global_mp = ( + transformer.mergepointfamily.has_global_mergepoints()) return transformer.tsgraphs_seen def timeshift_graph(self, graph): Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/transform.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/timeshifter/transform.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/timeshifter/transform.py Sun Feb 4 14:11:49 2007 @@ -35,6 +35,8 @@ class HintGraphTransformer(object): c_dummy = inputconst(lltype.Void, None) + contains_promotion = False + def __init__(self, hannotator, graph, is_portal=False): self.hannotator = hannotator self.graph = graph @@ -819,6 +821,7 @@ block.operations[i] = newop def handle_promote_hint(self, block, i): + self.contains_promotion = True op = block.operations[i] v_promote = op.args[0] newop = SpaceOperation('revealconst', [v_promote], op.result) From santagada at codespeak.net Sun Feb 4 16:56:21 2007 From: santagada at codespeak.net (santagada at codespeak.net) Date: Sun, 4 Feb 2007 16:56:21 +0100 (CET) Subject: [pypy-svn] r37923 - pypy/dist/pypy/lang/js Message-ID: <20070204155621.5C35E10070@code0.codespeak.net> Author: santagada Date: Sun Feb 4 16:56:11 2007 New Revision: 37923 Modified: pypy/dist/pypy/lang/js/driver.py pypy/dist/pypy/lang/js/interpreter.py Log: checks for the js interpreter, and a quick hack to add String Modified: pypy/dist/pypy/lang/js/driver.py ============================================================================== --- pypy/dist/pypy/lang/js/driver.py (original) +++ pypy/dist/pypy/lang/js/driver.py Sun Feb 4 16:56:11 2007 @@ -2,18 +2,25 @@ import autopath from py import path +import py import os +import sys -shell = path.local(__file__).dirpath('test', 'ecma', 'shell.js') - +pwd = path.local(__file__) +shell = pwd.dirpath('test', 'ecma', 'shell.js') exclusionlist = ['shell.js', 'browser.js'] def filter(filename): if filename.basename in exclusionlist or not filename.basename.endswith('.js'): return False else: return True + +if py.path.local.sysfind("js") is None: + print "js interpreter not found in path" + sys.exit() + results = open('results.txt', 'w') -for f in path.local(__file__).dirpath('test', 'ecma').visit(filter): +for f in pwd.dirpath('test', 'ecma').visit(filter): print f.basename stdout = os.popen('./js_interactive.py -n -f %s -f %s'%(shell.strpath,f.strpath), 'r') passed = 0 Modified: pypy/dist/pypy/lang/js/interpreter.py ============================================================================== --- pypy/dist/pypy/lang/js/interpreter.py (original) +++ pypy/dist/pypy/lang/js/interpreter.py Sun Feb 4 16:56:11 2007 @@ -128,6 +128,11 @@ return W_Boolean(args[0].ToBoolean()) return W_Boolean(False) +def stringjs(ctx, args, this): + if len(args) > 0: + return W_String(args[0].ToString()) + return W_String('') + def numberjs(ctx, args, this): if len(args) > 0: return W_Number(args[0].ToNumber()) @@ -170,6 +175,7 @@ w_math.Put('abs', W_Builtin(absjs, Class='function')) w_math.Put('floor', W_Builtin(floorjs, Class='function')) + w_Global.Put('String', W_Builtin(stringjs, Class='String')) #Global Properties w_Global.Put('Object', w_Object) @@ -177,6 +183,7 @@ w_Global.Put('Array', W_Array()) w_Global.Put('version', W_Builtin(versionjs)) + #Number w_Number = W_Builtin(numberjs, Class="Number") w_Number.Put('NaN', W_Number(NaN)) w_Number.Put('POSITIVE_INFINITY', W_Number(Infinity)) @@ -873,7 +880,7 @@ def get_string(t, string): simb = get_tree_item(t, string) if isinstance(simb, Symbol): - return simb.additional_info + return str(simb.additional_info) else: return '' @@ -891,7 +898,7 @@ if x.children[0].additional_info == name: return x.children[1] return None - + opcodedict = {} for i in locals().values(): if isinstance(i, type(Node)) and issubclass(i, Node): From pedronis at codespeak.net Sun Feb 4 22:05:29 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sun, 4 Feb 2007 22:05:29 +0100 (CET) Subject: [pypy-svn] r37925 - in pypy/branch/jit-virtual-world/pypy/jit: goal timeshifter timeshifter/test Message-ID: <20070204210529.DE72610072@code0.codespeak.net> Author: pedronis Date: Sun Feb 4 22:05:26 2007 New Revision: 37925 Modified: pypy/branch/jit-virtual-world/pypy/jit/goal/jitstep.py pypy/branch/jit-virtual-world/pypy/jit/timeshifter/hrtyper.py pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_portal.py pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_timeshift.py Log: copy the graphs from the hint annotator translator to the base one in timeshifting specialize Modified: pypy/branch/jit-virtual-world/pypy/jit/goal/jitstep.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/goal/jitstep.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/goal/jitstep.py Sun Feb 4 22:05:26 2007 @@ -62,9 +62,6 @@ hrtyper = HintRTyper(ha, t.rtyper, RGenOp) origportalgraph = graphof(t, PORTAL) hrtyper.specialize(origportalgraph=origportalgraph, view=False) - for graph in ha.translator.graphs: - checkgraph(graph) - t.graphs.append(graph) # XXX temp drv.source() Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/hrtyper.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/timeshifter/hrtyper.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/timeshifter/hrtyper.py Sun Feb 4 22:05:26 2007 @@ -213,6 +213,12 @@ self.log.event("portal has now %d blocks" % n) self.rewire_portal() + # move the timeshifted graphs into the original translator + base_translator = self.annotator.base_translator + for graph in self.annotator.translator.graphs: + flowmodel.checkgraph(graph) + base_translator.graphs.append(graph) + # remember a shared pointer for the portal graph, # so that it can be later patched by rewire_portal. # this pointer is going to be used by the resuming logic Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_portal.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_portal.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_portal.py Sun Feb 4 22:05:26 2007 @@ -5,7 +5,7 @@ from pypy.jit.timeshifter.test.test_timeshift import P_NOVIRTUAL, StopAtXPolicy from pypy.jit.timeshifter.test.test_vlist import P_OOPSPEC from pypy.rpython.llinterp import LLInterpreter -from pypy.objspace.flow.model import checkgraph, summary +from pypy.objspace.flow.model import summary from pypy.rlib.objectmodel import hint from pypy.jit.codegen.llgraph.rgenop import RGenOp as LLRGenOp @@ -64,10 +64,6 @@ self.hrtyper.specialize(origportalgraph=origportalgraph, view = conftest.option.view and self.small) - for graph in ha.translator.graphs: - checkgraph(graph) - t.graphs.append(graph) - if conftest.option.view and self.small: t.view() self.postprocess_timeshifting() Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_timeshift.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_timeshift.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_timeshift.py Sun Feb 4 22:05:26 2007 @@ -13,7 +13,6 @@ from pypy.rpython.module.support import LLSupport from pypy.annotation import model as annmodel from pypy.rpython.llinterp import LLInterpreter, LLException -from pypy.objspace.flow.model import checkgraph from pypy.translator.backendopt.inline import auto_inlining from pypy import conftest from pypy.jit.conftest import Benchmark @@ -105,13 +104,9 @@ # make the timeshifted graphs hrtyper = HintRTyper(ha, rtyper, self.RGenOp) hrtyper.specialize(view = conftest.option.view and self.small) - fresh_jitstate = hrtyper.ll_fresh_jitstate finish_jitstate = hrtyper.ll_finish_jitstate t = rtyper.annotator.translator - for graph in ha.translator.graphs: - checkgraph(graph) - t.graphs.append(graph) # make an interface to the timeshifted graphs: # From arigo at codespeak.net Sun Feb 4 23:12:05 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 4 Feb 2007 23:12:05 +0100 (CET) Subject: [pypy-svn] r37932 - in pypy/branch/jit-virtual-world/pypy/jit: hintannotator hintannotator/test timeshifter timeshifter/test Message-ID: <20070204221205.CE88410076@code0.codespeak.net> Author: arigo Date: Sun Feb 4 23:12:02 2007 New Revision: 37932 Modified: pypy/branch/jit-virtual-world/pypy/jit/hintannotator/bookkeeper.py pypy/branch/jit-virtual-world/pypy/jit/hintannotator/model.py pypy/branch/jit-virtual-world/pypy/jit/hintannotator/test/test_annotator.py pypy/branch/jit-virtual-world/pypy/jit/timeshifter/hrtyper.py pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_portal.py pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_timeshift.py pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_vdict.py pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_vlist.py pypy/branch/jit-virtual-world/pypy/jit/timeshifter/transform.py pypy/branch/jit-virtual-world/pypy/jit/timeshifter/vlist.py Log: (pedronis, arigo) * hint-annotation fixes for indirect yellow calls. * refactor and try to unify a bit more red and yellow calls in the transformer. The result is rather powerful (and completely obscure in the transformer). * deepfrozen lists in the oopspec timeshifting. Modified: pypy/branch/jit-virtual-world/pypy/jit/hintannotator/bookkeeper.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/hintannotator/bookkeeper.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/hintannotator/bookkeeper.py Sun Feb 4 23:12:02 2007 @@ -317,7 +317,8 @@ graph = desc.specialize(args_hs, key=key, alt_name=alt_name) return graph - def graph_call(self, graph, fixed, args_hs, tsgraph_accum=None): + def graph_call(self, graph, fixed, args_hs, + tsgraph_accum=None, hs_callable=None): input_args_hs = list(args_hs) graph = self.get_graph_for_call(graph, fixed, input_args_hs) if tsgraph_accum is not None: @@ -337,27 +338,34 @@ input_args_hs) # look on which input args the hs_res result depends on if isinstance(hs_res, hintmodel.SomeLLAbstractConstant): - deps_hs = [] - for hs_inputarg, hs_arg in zip(input_args_hs, args_hs): - if isinstance(hs_inputarg, hintmodel.SomeLLAbstractConstant): - assert len(hs_inputarg.origins) == 1 - [o] = hs_inputarg.origins.keys() - if o in hs_res.origins: - deps_hs.append(hs_arg) - if fixed: - deps_hs.append(hs_res) - hs_res = hintmodel.reorigin(hs_res, *deps_hs) + if (hs_callable is not None and + not isinstance(hs_callable, hintmodel.SomeLLAbstractConstant)): + hs_res = hintmodel.variableoftype(hs_res.concretetype, + hs_res.deepfrozen) + else: + deps_hs = [] + for hs_inputarg, hs_arg in zip(input_args_hs, args_hs): + if isinstance(hs_inputarg, + hintmodel.SomeLLAbstractConstant): + assert len(hs_inputarg.origins) == 1 + [o] = hs_inputarg.origins.keys() + if o in hs_res.origins: + deps_hs.append(hs_arg) + if fixed: + deps_hs.append(hs_res) + hs_res = hintmodel.reorigin(hs_res, hs_callable, *deps_hs) return hs_res def graph_family_call(self, graph_list, fixed, args_hs, - tsgraphs_accum=None): + tsgraphs_accum=None, hs_callable=None): if tsgraphs_accum is None: tsgraphs = [] else: tsgraphs = tsgraphs_accum results_hs = [] for graph in graph_list: - results_hs.append(self.graph_call(graph, fixed, args_hs, tsgraphs)) + results_hs.append(self.graph_call(graph, fixed, args_hs, + tsgraphs, hs_callable)) # put the tsgraphs in the same call family call_families = self.tsgraph_maximal_call_families _, rep, callfamily = call_families.find(tsgraphs[0]) Modified: pypy/branch/jit-virtual-world/pypy/jit/hintannotator/model.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/hintannotator/model.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/hintannotator/model.py Sun Feb 4 23:12:02 2007 @@ -83,6 +83,11 @@ args = self.spaceop.args[1:] elif self.spaceop.opname == 'indirect_call': args = self.spaceop.args[1:-1] + # indirect_call with a red callable must return a red + # (see test_indirect_yellow_call) + v_callable = self.spaceop.args[0] + retdeps = greenorigindependencies.setdefault(self, []) + retdeps.append(v_callable) else: raise AssertionError(self.spaceop.opname) @@ -182,11 +187,11 @@ for o in self.origins: if not o.fixed: return False - return True + return self.concretetype is not lltype.Void def is_green(self): - return (self.is_fixed() or self.eager_concrete or - self.concretetype is lltype.Void or + return (self.concretetype is lltype.Void or + self.is_fixed() or self.eager_concrete or (self.myorigin is not None and self.myorigin.greenargs)) def annotationcolor(self): @@ -349,7 +354,7 @@ fixed = myorigin.read_fixed() tsgraphs_accum = [] hs_res = bookkeeper.graph_family_call(graph_list, fixed, args_hs, - tsgraphs_accum) + tsgraphs_accum, hs_v1) myorigin.any_called_graph = tsgraphs_accum[0] if isinstance(hs_res, SomeLLAbstractConstant): Modified: pypy/branch/jit-virtual-world/pypy/jit/hintannotator/test/test_annotator.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/hintannotator/test/test_annotator.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/hintannotator/test/test_annotator.py Sun Feb 4 23:12:02 2007 @@ -728,3 +728,41 @@ hs = hannotate(ll_function, [int], policy=P_NOVIRTUAL) assert hs.deepfrozen + + +def test_concrete_fnptr_for_green_call(): + + def h1(n): + return n * 10 + + def h2(n): + return n + 20 + + lst = [h1, h2] + + def ll_function(n, m): + h = hint(lst, deepfreeze=True)[m] + res = h(n) + hint(res, concrete=True) # so 'h' gets green, so 'm' gets green + return m + + hs = hannotate(ll_function, [int, int], policy=P_NOVIRTUAL) + assert hs.is_green() + + +def test_indirect_yellow_call(): + + def h1(n): + return 123 + + def h2(n): + return 456 + + lst = [h1, h2] + + def ll_function(n, m): + h = hint(lst, deepfreeze=True)[m] + return h(n) + + hs = hannotate(ll_function, [int, int], policy=P_NOVIRTUAL) + assert not hs.is_green() Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/hrtyper.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/timeshifter/hrtyper.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/timeshifter/hrtyper.py Sun Feb 4 23:12:02 2007 @@ -198,6 +198,7 @@ assert self.portal_contains_global_mp, ( "No global merge point found. " "Forgot 'hint(None, global_merge_point=True)'?") + #import pdb; pdb.set_trace() # only keep the hint-annotated graphs that are really useful self.annotator.translator.graphs = [graph for graph in self.annotator.translator.graphs @@ -1415,6 +1416,10 @@ def translate_op_residual_gray_noexc_call(self, hop): self.translate_op_residual_red_call(hop, color='gray', exc=False) + translate_op_residual_yellow_call = translate_op_residual_red_call + translate_op_residual_yellow_noexc_call = ( + translate_op_residual_red_noexc_call) + def translate_op_after_residual_call(self, hop): v_jitstate = hop.llops.getjitstate() return hop.llops.genmixlevelhelpercall(rtimeshift.after_residual_call, Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_portal.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_portal.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_portal.py Sun Feb 4 23:12:02 2007 @@ -441,3 +441,31 @@ res = self.timeshift_from_portal(ll_main, ll_function, [5], policy=P_NOVIRTUAL) assert not res + def test_greenmethod_call_nonpromote(self): + class Base(object): + pass + class Int(Base): + def __init__(self, n): + self.n = n + def tag(self): + return 123 + class Str(Base): + def __init__(self, s): + self.s = s + def tag(self): + return 456 + + def ll_main(n): + if n > 0: + o = Int(n) + else: + o = Str('123') + return ll_function(o) + + def ll_function(o): + hint(None, global_merge_point=True) + return o.tag() + + res = self.timeshift_from_portal(ll_main, ll_function, [5], policy=P_NOVIRTUAL) + assert res == 123 + self.check_insns(indirect_call=1) Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_timeshift.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_timeshift.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_timeshift.py Sun Feb 4 23:12:02 2007 @@ -1135,6 +1135,10 @@ assert res == 42 self.check_insns({}) + res = self.timeshift(f, [0], [], policy=P_NOVIRTUAL) + assert res == 42 + self.check_insns(indirect_call=0) + def test_simple_red_meth(self): class Base(object): def m(self, n): Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_vdict.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_vdict.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_vdict.py Sun Feb 4 23:12:02 2007 @@ -1,5 +1,6 @@ from pypy.jit.hintannotator.annotator import HintAnnotatorPolicy from pypy.jit.timeshifter.test.test_timeshift import TimeshiftingTests +from pypy.rlib.objectmodel import hint P_OOPSPEC = HintAnnotatorPolicy(novirtualcontainer = True, oopspec = True) @@ -40,3 +41,22 @@ res = self.timeshift(ll_function, [], [], policy=P_OOPSPEC) assert res == 39 self.check_insns({}) + + def test_dicts_deepfreeze(self): + d1 = {1: 123, 2: 54, 3:84} + d2 = {1: 831, 2: 32, 3:81} + def getdict(n): + if n: + return d1 + else: + return d2 + def ll_function(n, i): + d = getdict(n) + d = hint(d, deepfreeze=True) + res = d[i] + res = hint(res, variable=True) + return res + + res = self.timeshift(ll_function, [3, 2], [0, 1], policy=P_OOPSPEC) + assert res == 54 + self.check_insns({}) Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_vlist.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_vlist.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_vlist.py Sun Feb 4 23:12:02 2007 @@ -1,5 +1,6 @@ from pypy.jit.hintannotator.annotator import HintAnnotatorPolicy from pypy.jit.timeshifter.test.test_timeshift import TimeshiftingTests +from pypy.rlib.objectmodel import hint P_OOPSPEC = HintAnnotatorPolicy(novirtualcontainer=True, oopspec=True) @@ -110,3 +111,21 @@ assert res == 9 self.check_insns({}) + def test_lists_deepfreeze(self): + l1 = [1,2,3,4,5] + l2 = [6,7,8,9,10] + def getlist(n): + if n: + return l1 + else: + return l2 + def ll_function(n, i): + l = getlist(n) + l = hint(l, deepfreeze=True) + res = l[i] + res = hint(res, variable=True) + return res + + res = self.timeshift(ll_function, [3, 4], [0, 1], policy=P_OOPSPEC) + assert res == 5 + self.check_insns({}) Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/transform.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/timeshifter/transform.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/timeshifter/transform.py Sun Feb 4 23:12:02 2007 @@ -553,7 +553,8 @@ args_v = op.args[:1] + args_v + [c_targets] hs_func = self.hannotator.binding(args_v[0]) if not hs_func.is_green(): - # XXX for now, assume that it will be a constant red box + # handle_red_call() has checked with is_constant that + # the hs_func is actually a constant red box v_greenfunc = self.genop(block, 'revealconst', [args_v[0]], resulttype = originalconcretetype(hs_func)) args_v[0] = v_greenfunc @@ -574,8 +575,7 @@ linkargs = link.args varsalive = list(linkargs) - if color == 'red': - assert not self.hannotator.binding(op.result).is_green() + if color != 'gray': # the result will be either passed as an extra local 0 # by the caller, or restored by a restore_local try: @@ -622,10 +622,28 @@ blockset[postconstantblock] = False self.make_call(constantblock, op, reds, color) - resumepoint = self.get_resume_point(nextblock) + conversionblock = nextblock + if color == 'red': + assert not self.hannotator.binding(op.result).is_green() + elif color == 'yellow': + conversionblock = Block([copyvar(self.hannotator, v) + for v in nextblock.inputargs]) + v0 = conversionblock.inputargs[0] + already_green = self.hannotator.binding(op.result).is_green() + assert already_green == self.hannotator.binding(v0).is_green() + if not already_green: + RESULT = self.hannotator.binding(v0).concretetype + hs = hintmodel.SomeLLAbstractConstant(RESULT, {}) + self.hannotator.bindings[v0] = hs + conversionblock.closeblock(Link(conversionblock.inputargs, + nextblock)) + # to merge some of the possibly many return jitstates + self.mergepoint_set[nextblock] = 'local' + + resumepoint = self.get_resume_point(conversionblock) c_resumepoint = inputconst(lltype.Signed, resumepoint) self.genop(postconstantblock, 'collect_split', [c_resumepoint] + greens) - resumeblock = self.get_resume_point_link(nextblock).target + resumeblock = self.get_resume_point_link(conversionblock).target postconstantblock.recloseblock(Link([], resumeblock)) if nonconstantblock is not None: @@ -633,7 +651,7 @@ v_res, nonconstantblock2 = self.handle_residual_call_details( nonconstantblock, 0, op, color, preserve_res = - (color == 'red')) + (color != 'gray')) #if color == 'red': # linkargs[0] = v_res @@ -683,55 +701,7 @@ op.opname = 'green_call' def handle_yellow_call(self, block, pos): - op = block.operations[pos] - #if op.opname == 'direct_call': - # f = open('LOG', 'a') - # print >> f, 'handle_yellow_call', op.args[0].value - # f.close() - hs_result = self.hannotator.binding(op.result) - if not hs_result.is_green(): - # yellow calls are supposed to return greens, - # add an indirection if it's not the case - # XXX a bit strange - RESULT = originalconcretetype(hs_result) - v_tmp = varoftype(RESULT) - hs = hintmodel.SomeLLAbstractConstant(RESULT, {}) - self.hannotator.setbinding(v_tmp, hs) - v_real_result = op.result - op.result = v_tmp - newop = SpaceOperation('same_as', [v_tmp], v_real_result) - block.operations.insert(pos+1, newop) - - link = split_block(self.hannotator, block, pos+1) - op1 = block.operations.pop(pos) - assert op1 is op - assert len(block.operations) == pos - nextblock = link.target - varsalive = link.args - try: - index = varsalive.index(op.result) - except ValueError: - XXX-later - - del varsalive[index] - v_result = nextblock.inputargs.pop(index) - nextblock.inputargs.insert(0, v_result) - - reds, greens = self.sort_by_color(varsalive) - postblock = self.naive_split_block(block, len(block.operations)) - self.make_call(block, op, reds, 'yellow') - - resumepoint = self.get_resume_point(nextblock) - c_resumepoint = inputconst(lltype.Signed, resumepoint) - self.genop(postblock, 'collect_split', [c_resumepoint] + greens) - link.args = [] - link.target = self.get_resume_point_link(nextblock).target - - # to merge some of the possibly many return jitstates - self.mergepoint_set[nextblock] = 'local' - - SSA_to_SSI({block: True, - postblock: False}, self.hannotator) + self.handle_red_call(block, pos, color='yellow') def handle_residual_call(self, block, pos, qualifiers=[]): op = block.operations[pos] Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/vlist.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/timeshifter/vlist.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/timeshifter/vlist.py Sun Feb 4 23:12:02 2007 @@ -288,19 +288,23 @@ else: return oopspecdesc.residual_call(jitstate, [selfbox]) -def oop_list_len(jitstate, oopspecdesc, selfbox): +def oop_list_len(jitstate, oopspecdesc, deepfrozen, selfbox): content = selfbox.content if isinstance(content, VirtualList): return rvalue.ll_fromvalue(jitstate, len(content.item_boxes)) else: - return oopspecdesc.residual_call(jitstate, [selfbox]) + return oopspecdesc.residual_call(jitstate, [selfbox], + deepfrozen=deepfrozen) +oop_list_len.couldfold = True -def oop_list_nonzero(jitstate, oopspecdesc, selfbox): +def oop_list_nonzero(jitstate, oopspecdesc, deepfrozen, selfbox): content = selfbox.content if isinstance(content, VirtualList): return rvalue.ll_fromvalue(jitstate, bool(content.item_boxes)) else: - return oopspecdesc.residual_call(jitstate, [selfbox]) + return oopspecdesc.residual_call(jitstate, [selfbox], + deepfrozen=deepfrozen) +oop_list_nonzero.couldfold = True def oop_list_append(jitstate, oopspecdesc, selfbox, itembox): content = selfbox.content @@ -360,7 +364,7 @@ else: oopspecdesc.residual_call(jitstate, [selfbox]) -def oop_list_getitem(jitstate, oopspecdesc, selfbox, indexbox): +def oop_list_getitem(jitstate, oopspecdesc, deepfrozen, selfbox, indexbox): content = selfbox.content if isinstance(content, VirtualList) and indexbox.is_constant(): index = rvalue.ll_getvalue(indexbox, lltype.Signed) @@ -369,7 +373,9 @@ except IndexError: return oopspecdesc.residual_exception(jitstate, IndexError) else: - return oopspecdesc.residual_call(jitstate, [selfbox, indexbox]) + return oopspecdesc.residual_call(jitstate, [selfbox, indexbox], + deepfrozen=deepfrozen) +oop_list_getitem.couldfold = True def oop_list_setitem(jitstate, oopspecdesc, selfbox, indexbox, itembox): content = selfbox.content From arigo at codespeak.net Sun Feb 4 23:14:52 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 4 Feb 2007 23:14:52 +0100 (CET) Subject: [pypy-svn] r37933 - in pypy/branch/jit-virtual-world/pypy: interpreter module/pypyjit module/pypyjit/test Message-ID: <20070204221452.6818D10076@code0.codespeak.net> Author: arigo Date: Sun Feb 4 23:14:50 2007 New Revision: 37933 Modified: pypy/branch/jit-virtual-world/pypy/interpreter/pyopcode.py pypy/branch/jit-virtual-world/pypy/module/pypyjit/interp_jit.py pypy/branch/jit-virtual-world/pypy/module/pypyjit/test/test_jit_setup.py Log: (pedronis, arigo) Fixes in the colors in the bytecode dispatch loop. This now threads next_instr as a green all around. Freeze the table used by COMPARE_OP. Grab the fastlocals_w and make it virtual. Add an assert in STORE_FAST to ensure that LOAD_FAST knows in the common case that it won't fail with UnboundLocalError. Modified: pypy/branch/jit-virtual-world/pypy/interpreter/pyopcode.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/interpreter/pyopcode.py (original) +++ pypy/branch/jit-virtual-world/pypy/interpreter/pyopcode.py Sun Feb 4 23:14:50 2007 @@ -10,7 +10,7 @@ from pypy.interpreter import gateway, function, eval from pypy.interpreter import pyframe, pytraceback from pypy.interpreter.argument import Arguments -from pypy.interpreter.pycode import PyCode +from pypy.interpreter.pycode import PyCode, CO_VARARGS, CO_VARKEYWORDS from pypy.tool.sourcetools import func_with_new_name from pypy.rlib.objectmodel import we_are_translated, hint from pypy.rlib.rarithmetic import r_uint, intmask @@ -53,21 +53,51 @@ def dispatch(self, pycode, next_instr, ec): if JITTING: hint(None, global_merge_point=True) - + pycode = hint(pycode, deepfreeze=True) # *loads* of nonsense for now - stuff = self.valuestackdepth - if len(self.blockstack): - stuff |= (-sys.maxint-1) - - stuff = hint(stuff, promote=True) - if stuff >= 0: - # blockdepth == 0, common case + + fastlocals_w = [None] * pycode.co_nlocals + + if next_instr == 0: + # first time we enter this function + depth = 0 self.blockstack = [] - depth = stuff & sys.maxint - pycode = hint(pycode, deepfreeze=True) + numargs = pycode.co_argcount + if pycode.co_flags & CO_VARARGS: numargs += 1 + if pycode.co_flags & CO_VARKEYWORDS: numargs += 1 + while True: + numargs -= 1 + if numargs < 0: + break + hint(numargs, concrete=True) + w_obj = self.fastlocals_w[numargs] + assert w_obj is not None + fastlocals_w[numargs] = w_obj + + else: + stuff = self.valuestackdepth + if len(self.blockstack): + stuff |= (-sys.maxint-1) + + stuff = hint(stuff, promote=True) + if stuff >= 0: + # blockdepth == 0, common case + self.blockstack = [] + depth = stuff & sys.maxint + + i = pycode.co_nlocals + while True: + i -= 1 + if i < 0: + break + hint(i, concrete=True) + w_obj = self.fastlocals_w[i] + fastlocals_w[i] = w_obj + self.pycode = pycode self.valuestackdepth = depth + self.fastlocals_w = fastlocals_w virtualstack_w = [None] * pycode.co_stacksize while depth > 0: @@ -93,6 +123,12 @@ # returns=w_result) except Return: w_result = self.popvalue() + if JITTING: + self.blockstack = None + self.valuestack_w = None + return w_result + except Yield: + w_result = self.popvalue() return w_result except OperationError, operr: next_instr = self.handle_operation_error(ec, operr) @@ -116,7 +152,6 @@ next_instr = self.handle_asynchronous_error(ec, self.space.w_RuntimeError, self.space.wrap(msg)) - next_instr = hint(next_instr, promote=True) def handle_asynchronous_error(self, ec, w_type, w_value=None): # catch asynchronous exceptions and turn them @@ -185,12 +220,11 @@ else: unroller = SReturnValue(w_returnvalue) next_instr = block.handle(self, unroller) - #next_instr = hint(next_instr, promote=True) return next_instr # now inside a 'finally' block if opcode == opcodedesc.YIELD_VALUE.index: #self.last_instr = intmask(next_instr - 1) XXX clean up! - raise Return + raise Yield if opcode == opcodedesc.END_FINALLY.index: unroller = self.end_finally() @@ -203,7 +237,6 @@ raise Return else: next_instr = block.handle(self, unroller) - #next_instr = hint(next_instr, promote=True) return next_instr if we_are_translated(): @@ -225,7 +258,6 @@ # Instead, it's constant-folded to either True or False if res is not None: next_instr = res - #next_instr = hint(next_instr, promote=True) break else: self.MISSING_OPCODE(oparg, next_instr) @@ -296,6 +328,7 @@ def STORE_FAST(f, varindex, *ignored): w_newvalue = f.popvalue() + assert w_newvalue is not None f.fastlocals_w[varindex] = w_newvalue #except: # print "exception: got index error" @@ -719,8 +752,9 @@ def COMPARE_OP(f, testnum, *ignored): w_2 = f.popvalue() w_1 = f.popvalue() + table = hint(f.compare_dispatch_table, deepfreeze=True) try: - testfn = f.compare_dispatch_table[testnum] + testfn = table[testnum] except IndexError: raise BytecodeCorruption, "bad COMPARE_OP oparg" w_result = testfn(f, w_1, w_2) @@ -949,6 +983,8 @@ class Return(Exception): """Obscure.""" +class Yield(Exception): + """Obscure.""" class BytecodeCorruption(Exception): """Detected bytecode corruption. Never caught; it's an error.""" @@ -1068,13 +1104,17 @@ return space.newtuple([w(self._opname), w(self.handlerposition), w(self.valuestackdepth)]) + def handle(self, frame, unroller): + next_instr = self.really_handle(frame, unroller) # JIT hack + return hint(next_instr, promote=True) + class LoopBlock(FrameBlock): """A loop block. Stores the end-of-loop pointer in case of 'break'.""" _opname = 'SETUP_LOOP' handling_mask = SBreakLoop.kind | SContinueLoop.kind - def handle(self, frame, unroller): + def really_handle(self, frame, unroller): if isinstance(unroller, SContinueLoop): # re-push the loop block without cleaning up the value stack, # and jump to the beginning of the loop, stored in the @@ -1093,7 +1133,7 @@ _opname = 'SETUP_EXCEPT' handling_mask = SApplicationException.kind - def handle(self, frame, unroller): + def really_handle(self, frame, unroller): # push the exception to the value stack for inspection by the # exception handler (the code after the except:) self.cleanupstack(frame) @@ -1127,7 +1167,7 @@ frame.pushvalue(frame.space.w_None) frame.pushvalue(frame.space.w_None) - def handle(self, frame, unroller): + def really_handle(self, frame, unroller): # any abnormal reason for unrolling a finally: triggers the end of # the block unrolling and the entering the finally: handler. # see comments in cleanup(). Modified: pypy/branch/jit-virtual-world/pypy/module/pypyjit/interp_jit.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/module/pypyjit/interp_jit.py (original) +++ pypy/branch/jit-virtual-world/pypy/module/pypyjit/interp_jit.py Sun Feb 4 23:14:50 2007 @@ -43,6 +43,10 @@ else: return super_dispatch(self, pycode, next_instr, ec) + def CALL_FUNCTION(f, oparg, *ignored): + # XXX disable the call_valuestack hacks which are bad for the JIT + return f.call_function(oparg) + setup() PORTAL = PyFrame.dispatch_jit Modified: pypy/branch/jit-virtual-world/pypy/module/pypyjit/test/test_jit_setup.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/module/pypyjit/test/test_jit_setup.py (original) +++ pypy/branch/jit-virtual-world/pypy/module/pypyjit/test/test_jit_setup.py Sun Feb 4 23:14:50 2007 @@ -16,3 +16,13 @@ assert f(6, 7) == 43 pypyjit.enable(f.func_code) assert f(6, 7) == 43 + + def gen(x): + i = 0 + while i < x: + yield i*i + i += 1 + + assert list(gen(3)) == [0, 1, 4] + pypyjit.enable(gen.func_code) + assert list(gen(3)) == [0, 1, 4] From pedronis at codespeak.net Mon Feb 5 01:12:29 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Mon, 5 Feb 2007 01:12:29 +0100 (CET) Subject: [pypy-svn] r37944 - in pypy/branch/jit-virtual-world/pypy/jit/timeshifter: . test Message-ID: <20070205001229.675951007A@code0.codespeak.net> Author: pedronis Date: Mon Feb 5 01:12:26 2007 New Revision: 37944 Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/hrtyper.py pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_timeshift.py pypy/branch/jit-virtual-world/pypy/jit/timeshifter/transform.py Log: always use the information whether a call can raise. refactor a bit the after-residual-call code. the direction is to be able to not generate exception path if they are not needed. Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/hrtyper.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/timeshifter/hrtyper.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/timeshifter/hrtyper.py Mon Feb 5 01:12:26 2007 @@ -1384,7 +1384,7 @@ translate_op_yellow_call = translate_op_red_call translate_op_indirect_yellow_call = translate_op_indirect_red_call - def translate_op_residual_red_call(self, hop, color='red', exc=True): + def translate_op_residual_red_call(self, hop, color='red'): FUNC = originalconcretetype(hop.args_s[0]) [v_funcbox] = hop.inputargs(self.getredrepr(FUNC)) calldesc = rtimeshift.CallDesc(self.RGenOp, FUNC.TO) @@ -1400,33 +1400,25 @@ [self.s_JITState, s_calldesc, self.s_RedBox], [v_jitstate, c_calldesc, v_funcbox ], s_result) - - if exc: - hop.llops.genmixlevelhelpercall(self.fetch_global_excdata, - [self.s_JITState], [v_jitstate], - annmodel.s_None) return v_res def translate_op_residual_gray_call(self, hop): self.translate_op_residual_red_call(hop, color='gray') - def translate_op_residual_red_noexc_call(self, hop): - return self.translate_op_residual_red_call(hop, exc=False) - - def translate_op_residual_gray_noexc_call(self, hop): - self.translate_op_residual_red_call(hop, color='gray', exc=False) - translate_op_residual_yellow_call = translate_op_residual_red_call - translate_op_residual_yellow_noexc_call = ( - translate_op_residual_red_noexc_call) def translate_op_after_residual_call(self, hop): - v_jitstate = hop.llops.getjitstate() + dopts = hop.args_v[0].value + withexc = dopts['withexc'] + v_jitstate = hop.llops.getjitstate() + if withexc: + hop.llops.genmixlevelhelpercall(self.fetch_global_excdata, + [self.s_JITState], [v_jitstate], + annmodel.s_None) return hop.llops.genmixlevelhelpercall(rtimeshift.after_residual_call, [self.s_JITState], [v_jitstate], self.s_RedBox) - def translate_op_reshape(self, hop): v_jitstate = hop.llops.getjitstate() v_shape, = hop.inputargs(self.getredrepr(lltype.Signed)) Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_timeshift.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_timeshift.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_timeshift.py Mon Feb 5 01:12:26 2007 @@ -1361,6 +1361,35 @@ P = StopAtXPolicy() res = self.timeshift(f, [7, 3], policy=P) assert res == f(7,3) + self.check_insns(indirect_call=1, direct_call=1) + + def test_indirect_red_call_with_exc(self): + def h1(n): + if n < 0: + raise ValueError + return n*2 + def h2(n): + if n < 0: + raise ValueError + return n*4 + l = [h1, h2] + def g(n, x): + h = l[n&1] + return h(n) + x + + def f(n, x): + try: + return g(n, x) + except ValueError: + return -1 + + P = StopAtXPolicy() + res = self.timeshift(f, [7, 3], policy=P) + assert res == f(7,3) + self.check_insns(indirect_call=1) + + res = self.timeshift(f, [-7, 3], policy=P) + assert res == -1 self.check_insns(indirect_call=1) def test_indirect_gray_call(self): Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/transform.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/timeshifter/transform.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/timeshifter/transform.py Mon Feb 5 01:12:26 2007 @@ -497,33 +497,35 @@ c_func = spaceop.args[0] fnobj = c_func.value._obj if hasattr(fnobj, 'jitcallkind'): - return fnobj.jitcallkind + return fnobj.jitcallkind, None if (hasattr(fnobj._callable, 'oopspec') and self.hannotator.policy.oopspec): if fnobj._callable.oopspec.startswith('vable.'): - return 'vable' - return 'oopspec' + return 'vable', None + return 'oopspec', None if self.hannotator.bookkeeper.is_green_call(spaceop): - return 'green' + return 'green', None + withexc = self.can_raise(spaceop) colors = {} for graph, tsgraph in self.graphs_from(spaceop): color = self.graph_calling_color(tsgraph) colors[color] = tsgraph if not colors: # cannot follow this call - if not self.can_raise(spaceop): - return 'residual_noexc' - return 'residual' + return 'residual', withexc assert len(colors) == 1, colors # buggy normalization? - return color + return color, withexc def split_after_calls(self): for block in list(self.graph.iterblocks()): for i in range(len(block.operations)-1, -1, -1): op = block.operations[i] if op.opname in ('direct_call', 'indirect_call'): - call_kind = self.guess_call_kind(op) + call_kind, withexc = self.guess_call_kind(op) handler = getattr(self, 'handle_%s_call' % (call_kind,)) - handler(block, i) + if withexc is None: + handler(block, i) + else: + handler(block, i, withexc) def make_call(self, block, op, save_locals_vars, color='red'): # the 'save_locals' pseudo-operation is used to save all @@ -563,7 +565,7 @@ resulttype = lltype.Bool) self.go_to_dispatcher_if(block, v_finished) - def handle_red_call(self, block, pos, color='red'): + def handle_red_call(self, block, pos, withexc, color='red'): link = split_block(self.hannotator, block, pos+1) op = block.operations.pop(pos) #if op.opname == 'direct_call': @@ -651,7 +653,8 @@ v_res, nonconstantblock2 = self.handle_residual_call_details( nonconstantblock, 0, op, color, preserve_res = - (color != 'gray')) + (color != 'gray'), + withexc=withexc) #if color == 'red': # linkargs[0] = v_res @@ -663,8 +666,8 @@ blockset[nextblock] = True # reachable from outside SSA_to_SSI(blockset, self.hannotator) - def handle_gray_call(self, block, pos): - self.handle_red_call(block, pos, color='gray') + def handle_gray_call(self, block, pos, withexc): + self.handle_red_call(block, pos, color='gray', withexc=withexc) def handle_oopspec_call(self, block, pos): op = block.operations[pos] @@ -700,24 +703,21 @@ assert op.opname == 'direct_call' op.opname = 'green_call' - def handle_yellow_call(self, block, pos): - self.handle_red_call(block, pos, color='yellow') + def handle_yellow_call(self, block, pos, withexc): + self.handle_red_call(block, pos, color='yellow', withexc=withexc) - def handle_residual_call(self, block, pos, qualifiers=[]): + def handle_residual_call(self, block, pos, withexc): op = block.operations[pos] if op.result.concretetype is lltype.Void: color = 'gray' else: color = 'red' v_res, _ = self.handle_residual_call_details(block, pos, op, color, - qualifiers=qualifiers) + withexc) return v_res - - def handle_residual_noexc_call(self, block, pos): - return self.handle_residual_call(block, pos, qualifiers=['noexc']) - def handle_residual_call_details(self, block, pos, op, color, - preserve_res=True, qualifiers=[]): + def handle_residual_call_details(self, block, pos, op, color, withexc, + preserve_res=True): if op.opname == 'direct_call': args_v = op.args[1:] elif op.opname == 'indirect_call': @@ -729,10 +729,13 @@ args_v = [v for v in args_v if v.concretetype is not lltype.Void] self.genop(newops, 'save_locals', args_v) call_index = len(newops) - qualifiers = '_'.join([color] + qualifiers) - v_res = self.genop(newops, 'residual_%s_call' % (qualifiers,), + v_res = self.genop(newops, 'residual_%s_call' % (color,), [op.args[0]], result_like = op.result) - v_shape = self.genop(newops, 'after_residual_call', [], resulttype=lltype.Signed, red=True) + + dopts = {'withexc': withexc} + copts = Constant(dopts, lltype.Void) + v_shape = self.genop(newops, 'after_residual_call', [copts], + resulttype=lltype.Signed, red=True) reshape_index = len(newops) self.genop(newops, 'reshape', [v_shape]) reshape_pos = pos+reshape_index From pedronis at codespeak.net Mon Feb 5 02:59:41 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Mon, 5 Feb 2007 02:59:41 +0100 (CET) Subject: [pypy-svn] r37951 - pypy/branch/jit-virtual-world/pypy/jit/timeshifter Message-ID: <20070205015941.C629310072@code0.codespeak.net> Author: pedronis Date: Mon Feb 5 02:59:39 2007 New Revision: 37951 Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/hrtyper.py pypy/branch/jit-virtual-world/pypy/jit/timeshifter/rtimeshift.py pypy/branch/jit-virtual-world/pypy/jit/timeshifter/transform.py Log: start reorganizing such that there's always possibly a promote after oopspec calls that can raise. For now oopspec_was_residual == False so that the promote path is not used/reached. Next step is to have after residual call code that promote whether there was an exception or not from runtime. Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/hrtyper.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/timeshifter/hrtyper.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/timeshifter/hrtyper.py Mon Feb 5 02:59:39 2007 @@ -1265,6 +1265,9 @@ # handling of the various kinds of calls + def translate_op_oopspec_was_residual(self, hop): + return hop.inputconst(lltype.Bool, False) + def translate_op_oopspec_call(self, hop): # special-cased call, for things like list methods from pypy.jit.timeshifter.oop import OopSpecDesc, Index @@ -1410,15 +1413,23 @@ def translate_op_after_residual_call(self, hop): dopts = hop.args_v[0].value withexc = dopts['withexc'] + oop = dopts['oop'] v_jitstate = hop.llops.getjitstate() if withexc: hop.llops.genmixlevelhelpercall(self.fetch_global_excdata, [self.s_JITState], [v_jitstate], annmodel.s_None) - return hop.llops.genmixlevelhelpercall(rtimeshift.after_residual_call, - [self.s_JITState], - [v_jitstate], - self.s_RedBox) + if not oop: + v_after = hop.llops.genmixlevelhelpercall( + rtimeshift.after_residual_call, + [self.s_JITState], + [v_jitstate], + self.s_RedBox) + else: # xxx + v_after = hop.inputconst(self.getredrepr(lltype.Signed), 0) + + return v_after + def translate_op_reshape(self, hop): v_jitstate = hop.llops.getjitstate() v_shape, = hop.inputargs(self.getredrepr(lltype.Signed)) Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/rtimeshift.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/timeshifter/rtimeshift.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/timeshifter/rtimeshift.py Mon Feb 5 02:59:39 2007 @@ -889,6 +889,17 @@ class JITState(object): + _attrs_ = """curbuilder frame + exc_type_box exc_value_box + greens + returnbox + promotion_path + resumepoint resuming + next + virtualizables + shape_place + """.split() + returnbox = None next = None # for linked lists promotion_path = None Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/transform.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/timeshifter/transform.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/timeshifter/transform.py Mon Feb 5 02:59:39 2007 @@ -502,7 +502,7 @@ self.hannotator.policy.oopspec): if fnobj._callable.oopspec.startswith('vable.'): return 'vable', None - return 'oopspec', None + return 'oopspec', self.can_raise(spaceop) if self.hannotator.bookkeeper.is_green_call(spaceop): return 'green', None withexc = self.can_raise(spaceop) @@ -669,11 +669,32 @@ def handle_gray_call(self, block, pos, withexc): self.handle_red_call(block, pos, color='gray', withexc=withexc) - def handle_oopspec_call(self, block, pos): + def handle_oopspec_call(self, block, pos, withexc): op = block.operations[pos] assert op.opname == 'direct_call' op.opname = 'oopspec_call' - + if withexc: + link = split_block(self.hannotator, block, pos+1) + nextblock = link.target + linkargs = link.args + v_residual =self.genop(block, 'oopspec_was_residual', [], + resulttype = lltype.Bool) + residualblock = Block([]) + self.genswitch(block, v_residual, true = residualblock, + false = None) + link_f = block.exits[0] + link_f.args = linkargs + link_f.target = nextblock + residualblock.closeblock(Link(linkargs, nextblock)) + residualblock2 = self.handle_after_residual_call_details( + residualblock, 0, [], oop=True, + withexc=True) + + blockset = { block: True, nextblock: False, + residualblock: False, + residualblock2: False } + SSA_to_SSI(blockset, self.hannotator) + def handle_vable_call(self, block, pos): op = block.operations[pos] assert op.opname == 'direct_call' @@ -731,8 +752,18 @@ call_index = len(newops) v_res = self.genop(newops, 'residual_%s_call' % (color,), [op.args[0]], result_like = op.result) + if preserve_res: + v_res = newops[call_index].result = op.result + + nextblock = self.handle_after_residual_call_details(block, pos, + newops, withexc) + + return v_res, nextblock - dopts = {'withexc': withexc} + + def handle_after_residual_call_details(self, block, pos, newops, withexc, + oop = False): + dopts = {'withexc': withexc, 'oop': oop } copts = Constant(dopts, lltype.Void) v_shape = self.genop(newops, 'after_residual_call', [copts], resulttype=lltype.Signed, red=True) @@ -740,8 +771,6 @@ self.genop(newops, 'reshape', [v_shape]) reshape_pos = pos+reshape_index block.operations[pos:pos+1] = newops - if preserve_res: - v_res = newops[call_index].result = op.result link = split_block(self.hannotator, block, reshape_pos) nextblock = link.target @@ -752,8 +781,7 @@ resulttype = lltype.Bool) self.go_to_dispatcher_if(block, v_finished_flag) - - return v_res, nextblock + return nextblock # __________ hints __________ From pedronis at codespeak.net Mon Feb 5 03:28:10 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Mon, 5 Feb 2007 03:28:10 +0100 (CET) Subject: [pypy-svn] r37952 - pypy/branch/jit-virtual-world/pypy/jit/timeshifter Message-ID: <20070205022810.AA0AA10074@code0.codespeak.net> Author: pedronis Date: Mon Feb 5 03:28:09 2007 New Revision: 37952 Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/hrtyper.py Log: details: transform_graph -> timeshift_cflow timeshift_graph -> timeshift_ops progress logging during timeshifting of operations (hrtyping) Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/hrtyper.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/timeshifter/hrtyper.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/timeshifter/hrtyper.py Mon Feb 5 03:28:09 2007 @@ -189,7 +189,7 @@ seen = {entrygraph: True} while pending: graph = pending.pop() - for nextgraph in self.transform_graph(graph, + for nextgraph in self.timeshift_cflow(graph, is_portal=graph is leaveportalgraph): if nextgraph not in seen: pending.append(nextgraph) @@ -198,6 +198,8 @@ assert self.portal_contains_global_mp, ( "No global merge point found. " "Forgot 'hint(None, global_merge_point=True)'?") + self.log.event("Timeshifted control flow of %d graphs." % (len(seen),)) + #import pdb; pdb.set_trace() # only keep the hint-annotated graphs that are really useful self.annotator.translator.graphs = [graph @@ -205,10 +207,13 @@ if graph in seen] if view: self.annotator.translator.view() # in the middle + self.blockcount = 0 + self.graphcount = 0 + self.ngraphs = len(seen) for graph in seen: - self.timeshift_graph(graph) - self.log.event("Timeshifted %d graphs." % (len(seen),)) + self.timeshift_ops(graph) + self.log.event("Completed timeshifting of %d graphs." % (len(seen),)) if origportalgraph: n = len(list(self.portalgraph.iterblocks())) self.log.event("portal has now %d blocks" % n) @@ -448,7 +453,7 @@ tsportalgraph.name += '_portal_reentry' - def transform_graph(self, graph, is_portal=False): + def timeshift_cflow(self, graph, is_portal=False): # prepare the graphs by inserting all bookkeeping/dispatching logic # as special operations assert graph.startblock in self.annotator.annotated @@ -462,11 +467,17 @@ transformer.mergepointfamily.has_global_mergepoints()) return transformer.tsgraphs_seen - def timeshift_graph(self, graph): + def timeshift_ops(self, graph): # specialize all blocks of this graph for block in list(graph.iterblocks()): self.annotator.annotated[block] = graph self.specialize_block(block) + self.blockcount += 1 + if self.blockcount % 100 == 0: + self.log.event("Timeshifted ops in %d blocks, %d/%d graphs" % + (self.blockcount, self.graphcount, + self.ngraphs)) + self.graphcount += 1 # "normalize" the graphs by putting an explicit v_jitstate variable # everywhere self.insert_v_jitstate_everywhere(graph) From sanxiyn at codespeak.net Mon Feb 5 06:14:41 2007 From: sanxiyn at codespeak.net (sanxiyn at codespeak.net) Date: Mon, 5 Feb 2007 06:14:41 +0100 (CET) Subject: [pypy-svn] r37953 - pypy/dist/pypy/doc/config Message-ID: <20070205051441.4AE1D10074@code0.codespeak.net> Author: sanxiyn Date: Mon Feb 5 06:14:28 2007 New Revision: 37953 Modified: pypy/dist/pypy/doc/config/objspace.std.withtypeversion.txt Log: typo Modified: pypy/dist/pypy/doc/config/objspace.std.withtypeversion.txt ============================================================================== --- pypy/dist/pypy/doc/config/objspace.std.withtypeversion.txt (original) +++ pypy/dist/pypy/doc/config/objspace.std.withtypeversion.txt Mon Feb 5 06:14:28 2007 @@ -1,4 +1,4 @@ This (mostly internal) option enables "type versions": Every type object gets an (only internally visible) version that is updated when the type's dict is -changed. This is e.g. used for invalidating cashes. It does not make sense to +changed. This is e.g. used for invalidating caches. It does not make sense to enable this option alone. From arigo at codespeak.net Mon Feb 5 11:48:37 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 5 Feb 2007 11:48:37 +0100 (CET) Subject: [pypy-svn] r37956 - pypy/branch/jit-virtual-world/pypy/jit/codegen/i386 Message-ID: <20070205104837.1543D10078@code0.codespeak.net> Author: arigo Date: Mon Feb 5 11:48:35 2007 New Revision: 37956 Modified: pypy/branch/jit-virtual-world/pypy/jit/codegen/i386/operation.py pypy/branch/jit-virtual-world/pypy/jit/codegen/i386/rgenop.py Log: Make pause_writing()/start_writing() lazy instead of flushing block code generation every time. Better reg allocation and avoids chains of "LEA" (added at the start of every generated block so far). Modified: pypy/branch/jit-virtual-world/pypy/jit/codegen/i386/operation.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/codegen/i386/operation.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/codegen/i386/operation.py Mon Feb 5 11:48:35 2007 @@ -511,6 +511,7 @@ lbl.targetaddr = allocator.mc.tell() lbl.targetstackdepth = allocator.required_frame_depth lbl.inputoperands = [allocator.get_operand(v) for v in self.args_gv] + lbl.targetbuilder = None # done generating class OpCall(Operation): def __init__(self, sigtoken, gv_fnptr, args_gv): Modified: pypy/branch/jit-virtual-world/pypy/jit/codegen/i386/rgenop.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/codegen/i386/rgenop.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/codegen/i386/rgenop.py Mon Feb 5 11:48:35 2007 @@ -205,23 +205,27 @@ class Builder(GenBuilder): coming_from = 0 - operations = None update_defaultcaseaddr_of = None force_in_stack = None + paused_alive_gv = None + order_dependency = None def __init__(self, rgenop, inputargs_gv, inputoperands): self.rgenop = rgenop self.inputargs_gv = inputargs_gv self.inputoperands = inputoperands + self.operations = [] def start_writing(self): - assert self.operations is None - self.operations = [] + self.paused_alive_gv = None def generate_block_code(self, final_vars_gv, force_vars=[], force_operands=[], renaming=True, minimal_stack_depth=0): + if self.order_dependency is not None: + self.order_dependency.force_generate_code() + self.order_dependency = None allocator = RegAllocator() if self.force_in_stack is not None: allocator.force_stack_storage(self.force_in_stack) @@ -243,7 +247,7 @@ if self.force_in_stack is not None: allocator.save_storage_places(self.force_in_stack) self.force_in_stack = None - self.operations = None + del self.operations[:] if renaming: self.inputargs_gv = [GenVar() for v in final_vars_gv] else: @@ -271,7 +275,7 @@ op = OpSameAs(args_gv[i]) args_gv[i] = op self.operations.append(op) - lbl = Label() + lbl = Label(self) lblop = OpLabel(lbl, args_gv) self.operations.append(lblop) return lbl @@ -311,6 +315,7 @@ def _jump_if(self, gv_condition, args_for_jump_gv, negate): newbuilder = Builder(self.rgenop, list(args_for_jump_gv), None) + newbuilder.order_dependency = self # if the condition does not come from an obvious comparison operation, # e.g. a getfield of a Bool or an input argument to the current block, # then insert an OpIntIsTrue @@ -329,9 +334,11 @@ def finish_and_goto(self, outputargs_gv, targetlbl): operands = targetlbl.inputoperands if operands is None: - # this occurs when jumping back to the same currently-open block; - # close the block and re-open it + # jumping to a label in a builder whose code has not been + # generated yet - this builder could be 'self', in the case + # of a tight loop self.pause_writing(outputargs_gv) + targetlbl.targetbuilder.force_generate_code() self.start_writing() operands = targetlbl.inputoperands assert operands is not None @@ -355,12 +362,18 @@ self.rgenop.close_mc(mc) def pause_writing(self, alive_gv): - mc = self.generate_block_code(alive_gv, renaming=False) - self.set_coming_from(mc) - mc.done() - self.rgenop.close_mc(mc) + self.paused_alive_gv = alive_gv return self + def force_generate_code(self): + alive_gv = self.paused_alive_gv + if alive_gv is not None: + self.paused_alive_gv = None + mc = self.generate_block_code(alive_gv, renaming=False) + self.set_coming_from(mc) + mc.done() + self.rgenop.close_mc(mc) + def end(self): pass @@ -526,6 +539,9 @@ targetstackdepth = 0 inputoperands = None + def __init__(self, targetbuilder): + self.targetbuilder = targetbuilder + # ____________________________________________________________ From hpk at codespeak.net Mon Feb 5 12:20:06 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Mon, 5 Feb 2007 12:20:06 +0100 (CET) Subject: [pypy-svn] r37957 - pypy/branch/pytrunkmerge/pypy Message-ID: <20070205112006.28CED1007B@code0.codespeak.net> Author: hpk Date: Mon Feb 5 12:19:56 2007 New Revision: 37957 Modified: pypy/branch/pytrunkmerge/pypy/conftest.py Log: variants of dist_* options for pypy Modified: pypy/branch/pytrunkmerge/pypy/conftest.py ============================================================================== --- pypy/branch/pytrunkmerge/pypy/conftest.py (original) +++ pypy/branch/pytrunkmerge/pypy/conftest.py Mon Feb 5 12:19:56 2007 @@ -7,6 +7,11 @@ rootdir = py.magic.autopath().dirpath() +dist_rsync_roots = ['../pypy', '../py'] +#dist_rsync_roots = ['.', '../lib-python', '../py'] +#dist_rsync_roots = ['.', '../lib-python'] +dist_rsync_ignore = ['_cache'] + # # PyPy's command line extra options (these are added # to py.test's standard options) From hpk at codespeak.net Mon Feb 5 12:25:23 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Mon, 5 Feb 2007 12:25:23 +0100 (CET) Subject: [pypy-svn] r37958 - pypy/branch/pytrunkmerge/pypy Message-ID: <20070205112523.A1EDE1007C@code0.codespeak.net> Author: hpk Date: Mon Feb 5 12:25:10 2007 New Revision: 37958 Modified: pypy/branch/pytrunkmerge/pypy/conftest.py Log: the real dist_rsync_roots alternatives (i think we need lib-python for running some appspace tests while it may not be needed always for translation) Modified: pypy/branch/pytrunkmerge/pypy/conftest.py ============================================================================== --- pypy/branch/pytrunkmerge/pypy/conftest.py (original) +++ pypy/branch/pytrunkmerge/pypy/conftest.py Mon Feb 5 12:25:10 2007 @@ -7,9 +7,8 @@ rootdir = py.magic.autopath().dirpath() -dist_rsync_roots = ['../pypy', '../py'] +dist_rsync_roots = ['.', '../py'] #dist_rsync_roots = ['.', '../lib-python', '../py'] -#dist_rsync_roots = ['.', '../lib-python'] dist_rsync_ignore = ['_cache'] # From hpk at codespeak.net Mon Feb 5 12:29:15 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Mon, 5 Feb 2007 12:29:15 +0100 (CET) Subject: [pypy-svn] r37959 - pypy/branch/pytrunkmerge/pypy Message-ID: <20070205112915.2FF2110083@code0.codespeak.net> Author: hpk Date: Mon Feb 5 12:29:13 2007 New Revision: 37959 Modified: pypy/branch/pytrunkmerge/pypy/conftest.py Log: ok, default should be to include lib-python Modified: pypy/branch/pytrunkmerge/pypy/conftest.py ============================================================================== --- pypy/branch/pytrunkmerge/pypy/conftest.py (original) +++ pypy/branch/pytrunkmerge/pypy/conftest.py Mon Feb 5 12:29:13 2007 @@ -7,8 +7,7 @@ rootdir = py.magic.autopath().dirpath() -dist_rsync_roots = ['.', '../py'] -#dist_rsync_roots = ['.', '../lib-python', '../py'] +dist_rsync_roots = ['.', '../lib-python', '../py'] dist_rsync_ignore = ['_cache'] # From cfbolz at codespeak.net Mon Feb 5 14:11:42 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 5 Feb 2007 14:11:42 +0100 (CET) Subject: [pypy-svn] r37961 - pypy/dist/pypy/module/__builtin__ Message-ID: <20070205131142.370971007E@code0.codespeak.net> Author: cfbolz Date: Mon Feb 5 14:11:41 2007 New Revision: 37961 Modified: pypy/dist/pypy/module/__builtin__/app_help.py Log: fwiw, update the years in the copyright Modified: pypy/dist/pypy/module/__builtin__/app_help.py ============================================================================== --- pypy/dist/pypy/module/__builtin__/app_help.py (original) +++ pypy/dist/pypy/module/__builtin__/app_help.py Mon Feb 5 14:11:41 2007 @@ -10,12 +10,12 @@ exit = "Use Ctrl-D (i.e. EOF) to exit." def copyright(): - print 'Copyright 2003-2004 Pypy development team.\nAll rights reserved.\nFor further information see http://www.codespeak.net/pypy.\nSome materials may have a different copyright.\nIn these cases, this is explicitly noted in the source code file.' + print 'Copyright 2003-2007 PyPy development team.\nAll rights reserved.\nFor further information see http://www.codespeak.net/pypy.\nSome materials may have a different copyright.\nIn these cases, this is explicitly noted in the source code file.' def license(): print \ """ -Copyright (c) <2003-2005> +Copyright (c) <2003-2007> Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: From cfbolz at codespeak.net Mon Feb 5 14:35:00 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 5 Feb 2007 14:35:00 +0100 (CET) Subject: [pypy-svn] r37963 - pypy/extradoc/minute Message-ID: <20070205133500.9C6651007C@code0.codespeak.net> Author: cfbolz Date: Mon Feb 5 14:34:58 2007 New Revision: 37963 Added: pypy/extradoc/minute/pypy-sync-2007-02-02.txt Log: somewhat uninspired minutes of the pypy-sync meeting. additions welcome. Added: pypy/extradoc/minute/pypy-sync-2007-02-02.txt ============================================================================== --- (empty file) +++ pypy/extradoc/minute/pypy-sync-2007-02-02.txt Mon Feb 5 14:34:58 2007 @@ -0,0 +1,426 @@ +================================================ +pypy-sync release plan meeting 2th February 2007 +================================================ + + +Attendees: Holger, Armin, Samuele, Christian, Maciej, Arre, Michael, Antonio, + Guido, Carl Friedrich (moderation, minutes) + + +Regular Topics +============== + +* activity reports (LAST/NEXT/BLOCKERS, everybody posts + prepared comma-separated lists of things) + +* no resolvable blockers (short of stealing the time machine) + + +Release Goals +============= + +Michael and Carl Friedrich prepared the following list in advance: + +* object optimizations +* pypy.net +* more working modules +* some performance +* maturity +* good documentation +* build tool +* JIT preview +* security prototype +* js backend? +* debian packaging? + +Maciek notes that it is unclear how well he will be able to clean up the JS +backend. Antonio proposes to add more high-level options. Samuele wants to make +sure that the security prototype is not misunderstood to be some sort of +sandboxing. According to Armin it is a major effort to clean up all these areas and +get a good level of documentation. + +At this point the meeting side-tracked into discussing the state of the JIT and +the next steps in this area and the general question how to approach development +during the rest of the EU funding. According to Armin it is expected that the +JIT starts producing non-horrible code "any day or week now". Since the +unpredictability of the JIT-work has a good chance to disturb the release works, +Holger proposed to rest the workings on the JIT, completely focus on making 1.0 +as good as possible and get all the other EU-related results in it. In March it +would be possible to concentrate on the JIT again. Samuele is sceptical that we +will be able to do much development in March due to the necessary wrap-up works +and report writing. Carl Friedrich and Holger think that it is a bad idea to +cram too much of that into March and propose to wrap up as much as possible in +February. + +Also discussed was the possibility of not calling the release 1.0 (e.g. 0.99 +1.0rc1 etc.) and the question what expectations the community will have towards +a 1.0 release. Holger and Carl Friedrich noted that there are a lot of +interesting features in PyPy even without the JIT working. Then the discussion +moved to the expectations of the EU reviewers. The reviewers we had at the last +review meeting were not too interested in the JIT but more in things like +aspects, constraint and logic programming. The state of PyPy in these areas is +unclear. + +After a lengthy discussion about what is needed to pass the EU review, we got +back to time planning. Armin proposed to check the state of the JIT again on +Monday to see how far it improved over the weekend. It was also decided that we +would meet again on Wednesday, February 7th at 11.00 to discuss the release work +distribution in detail. + +Task Planning +============= + +This topic did not happen and is moved to a task planning meeting on Wednesday. + +The preliminary task list is: + +* work out a timeframe for jit usefulness +* fix llvm(?) +* test pypy-cs, run benchmarks. + * windows testing! +* documentation!!! + * pypy.net + * object optimizations (WP6) + * release announcement + * improve getting-started + * transparent proxies + * security prototype + * document options +* make build-tool useable +* polish js backend? + + +Py-lib trunk -> dist merge +========================== + +Holger noted somewhere in between that there could be small disruptions with the +merge of py-trunk to py-dist, which should happen after the weekend. + + +Full IRC log:: + + [14:11] arigo (n=arigo at c-098b70d5.022-54-67626719.cust.bredbandsbolaget.se) joined #pypy-sync. + [14:11] hi + [14:11] hi! + [14:11] hi + [14:11] mornings and moins + [14:11] Hi! + [14:11] mahlzeit + [14:11] hehehe + [14:11] hi + [14:12] who is actually moderating/writing minutes? + [14:12] cfbolz: you? + [14:12] hm, ok + [14:12] activity reports, then + [14:13] LAST: leysin sprint, py lib release and refactorings, EU co-ordination activities + [14:13] NEXT: py lib release, lots of EU/PyPY issues, preparing trillke-sprint, OLPC Workshop + [14:13] BLOCKERS: py lib release :) + [14:13] LAST: .NET integration, WP12 report + [14:13] NEXT: WP12 report, maybe some more .NET integration + [14:13] BLOCKERS: none + [14:13] LAST: debugging ppc codegeneration + [14:13] NEXT: not sure, some family stuff + [14:13] BLOCKERS: family + [14:13] stuff + [14:13] nbecker (n=nbecker at pool-68-236-253-70.hag.east.verizon.net) left irc: Read error: 101 (Network is unreachable) + [14:13] hehehe + [14:13] LAST: jit NEXT:jit BLOCKERS:time + [14:13] LAST: py-lib, small cleanups + [14:13] NEXT: py-lib/pypy release + [14:13] BLOCKERS: 2 exams and 3 concerts + [14:13] LAST: sprint, build tool, py lib release preps + [14:13] NEXT: more build tool, more py lib, reports + [14:13] BLOCKERS: none afaik + [14:14] LAST: JIT + [14:14] NEXT: JIT + [14:14] BLOCKERS: Need more time + [14:14] LAST: pylib release/bugfixing + [14:14] NEXT: pylib, js backend polishing, play1.codespeak.net + [14:14] BLOCKERS: pylib release + [14:14] cfbolz: 3 concerts and we only have two releases! + [14:14] cfbolz: pff... you always let your hobbies interfere with your work ;) + [14:14] LAST: jit, small report work, inlining strategy options + [14:14] NEXT: jit, release work + [14:14] BLOCKERS: time + [14:14] hpk: :-) + [14:14] stakkars: want to post something? + [14:15] ups, None but installation hell. I migrated to the Mac, was hard for me + [14:15] ok, then first topic + [14:15] Release Goals + [14:15] ============= + [14:16] michael and me made a preliminary list: + [14:16] * object optimizations + [14:16] * pypy.net + [14:16] * more working modules + [14:16] * some performance + [14:16] * maturity + [14:16] * good documentation + [14:16] * build tool + [14:16] * JIT preview + [14:16] * security prototype + [14:16] * js backend? + [14:16] * debian packaging? + [14:16] any comments / additions / removals? + [14:16] what's the scheduled release time? + [14:17] feb 15th + [14:17] currently February 15th + [14:17] hum, i'm unsure how much of js backend polishing I can do till that + [14:17] probably we should also add more "high level" options + [14:17] ok, so the question mark is rightfully there + [14:17] antocuni: good point + [14:17] cfbolz: yes + [14:18] antocuni: yip + [14:18] so we agree on these goals? any other comments? + [14:19] i think the list is fine + [14:19] what's the exact meaning of having pypy.net as a goal? + [14:19] this is mostly meant to be an extremely condensed set of hints for the release announcement btw + [14:19] antocuni: having it somewhat useable and documented + [14:19] ok + [14:19] what we need to do between now and the release is the next topic :-) + [14:19] is documentation sufficient from your points of views? + [14:19] for .net? + [14:20] for .net not at all + [14:20] hpk: or in general? + [14:20] particularly for the release items + [14:20] well, there's a bit of expectation management about the sec proto, not to give the idea that we have sandboxing or some such + [14:20] pedronis: also a good point + [14:20] sure + [14:20] maybe we should call it differently? + [14:21] maybe, but let's not discuss here, i'd say + [14:21] ok + [14:21] so, next topic? + [14:21] the documentation is nowhere near complete + [14:21] btw + [14:22] arigo: agreed. that's why it is a goal :-) + [14:22] but I don't see how we can reach a good level of documentation everywhere without investing a few weeks of effort + [14:22] ok, but i think that one release focus should be to have good and interesting points into PyPy (including its development) + [14:22] arigo: so what's your suggestion? + [14:23] I don't have any + [14:23] (points = entry points) + [14:23] i think the most pressing question relates to JIT status and plans, and to "how to manage the release" + [14:23] exarkun (n=exarkun at intarweb.us) joined #pypy-sync. + [14:23] exarkun: hi + [14:23] hi + [14:24] arigo, pedronis, arre: do you have a kind of summary of status and "next steps"? + [14:24] to give here? + [14:24] I mean, do you want a summary now? + [14:24] if you can provide it, yes + [14:24] a high-level one :) + [14:25] it may suddenly start producing non-completely-incredible code + [14:25] any day or any week now + [14:25] cool + [14:25] right now is broken on the branch tough + [14:25] well, technically, yes :-) + [14:25] but we cannot predict when this happens? + [14:25] doesn't much about the release planning + [14:25] not really + [14:25] I see + [14:26] so what's the scenario when it seems to not happen + [14:26] ? + [14:26] hum, i think i'd like to discuss it differently + [14:26] hpk: ? + [14:27] i think the JIT is technically one of the most interesting and challenging areas, and it's already quite successful + [14:27] but i also think that for 1.0 we should have a totally different focus now + [14:28] so that we can be sure that we have a good release covering all (EU-related) results other than producing the full performance that we would like to see with the JIT + [14:28] and afterwards (particulary in March) we all shift to performance issues (there is also another Work package regarding that, dumdidum) + [14:29] Action: hpk takes the freedom to relate to EU issues, because we are almost completely from the EU bunch of people here + [14:29] what do you think about this view? + [14:29] i guess i have a few somewhat related points + [14:29] it would be fantastic propaganda to have even one program that pypyjit runs faster than cpython for the release + [14:30] otoh, we're going to need arigo and arre and pedronis to do more than just jit between now and then + [14:30] mwh: I agree completely, I'd say it should be called 0.99 as long as we don't do that + [14:30] i don't fully see how to square this circle + [14:30] the problem with such propaganda is that if people start using it premature, they would say "yes, but it's usually slower" + [14:31] but march we should wrap up so lots of development doesn't seem possible there + [14:31] reports reports reports + [14:31] pedronis: unless we basically wrap up much in february + [14:31] fijal: yes, we have to manage expectations etc, but still + [14:31] so you want to cram all reports into march? + [14:31] arigo, pedronis: I don't think that that is a good plan + [14:32] arigo: why 0.99? + [14:32] so the jit can be in 1.0, I guess + [14:32] arigo: why is 1.1 in march or april with a fully tuned JIT bad? + [14:32] because is hard to write a jit report before we have results + [14:33] :-) + [14:33] well, we kept a relatively high JIT focus from July last year up till now, and we have 58 days of EU project remaining + [14:34] is it needed to call the next release 1.0? + [14:34] we may get the same reviewers than last time, and they did not ask a single JIT question + [14:34] what about 1.0rc1, or something like that + [14:35] I mean, before having 1.0 people can't have much expectations + [14:36] pedronis: well, what are the alternatives, really? + [14:37] anybody still there? + [14:37] yes, but all thinking/considering things, i guess :) + [14:37] Action: hpk as well + [14:37] arigo, pedronis: do you think that a 1.0 release that does have a fully tuned JIT is not worthwhile? + [14:37] yes, still here + [14:38] still + [14:38] hm + [14:38] hpk: I guess it is more that it is hard to do while working on the jit + [14:38] sorry to introduce the release-number issue again + [14:38] let's move on to other questions + [14:39] arigo: the question how to approach the release (keep working on the jit or not) remains + [14:39] well, i think the fact is that if arigo, pedronis, arre keep a strong JIT focus, then the release will be hard to do, consdiering all circumstances + [14:40] the problem is that 1.0 is a bit a let down community wise and doesn't match the EU milestone targets either + [14:40] pedronis: let down community-wise? could you detail that? + [14:40] I think people will expect a lot from a PyPy 1.0 + [14:40] and moving the 1.0 release to after the EU period is not possible? + [14:41] well we kind of nailed our colours to the mast a bit calling our last release 0.9 + [14:41] stakkars: no, it is promised to the eu + [14:41] but anyway, i agree that the version number is something of a distraction + [14:41] i really don't see this 1.0 magic and it only relies on the JIT + [14:41] and i'd like to understand where this comes from + [14:42] it is the speed question, I guess + [14:42] I think they could englist('verschmerzen') it in favor of finishing other stuff + [14:42] a PyPy that has C/llvm/.NET backends, stackless, Prolog/JS/Python frontends, security prototypes, and a preview JIT-compiler generator (world's first for a VHLL) is not 1.0? + [14:43] for me it's not only a speed question; the general question is: "why I (as a user) should use pypy instead of cpython"? + [14:43] I expect at least one answer to that question for pypy 1.0 + [14:43] (along with generating AJAX applications from python) + [14:43] there is a lot of answers for this, but we may emphasis that 1.0 is not speed release + [14:44] or do not advertise jit for 1.0 or such + [14:44] I see a lot of pluses of using pypy, but speed is not among them + [14:44] well, it comes quite close to CPython, but we keep the tension :) + [14:44] :-) + [14:44] just to keep faassen busy :) + [14:45] hehe + [14:45] (it's not at all relevant to the release, but it's the extending/embedding situation that most holds pypy's adoption back imho) + [14:46] we don't have any goals in this direction for the release, do we? + [14:46] no + [14:46] mwh: seems a good guess + [14:46] in any case, i'd rather get our EU reports and tasks sorted as much as possible in february and then have March (+ X a bit maybe) for speed + [14:47] doing the reverse appears to me as dangerous and potentially extremely stressful + [14:47] antocuni: there are interesting reasons for pypy: transparent proxies, thunks, stackless, security prototype + [14:48] btw., Richard told me that he is writing algorithms using RPython, without the hosting Python. Just as a note, something gers used + [14:48] stakkars: ah, nice + [14:48] gets. eek + [14:49] cfbolz: yes, I know :-). My point is that we should list the plus of pypy over cpython, not that there are none + [14:49] arigo, pedronis, arre: would you rather like to discuss a bit more out-of-pypy-sync and we continue early next week? (and maybe you get the breakthrough on the weekend, who knows :) + [14:50] (i am not stating my opinion to put pressure on you, but from seriously consdiering things and overall issues) + [14:50] the problem is + [14:51] there are three categories of features (A, B, C) + [14:51] A = all these cool features we have + [14:51] B = jit + [14:51] C = what the reviewers care about + [14:51] pypy-sync is no longer set to 30 mins, right? + [14:51] stakkars: nope, currently :) + [14:51] they are mostly distinct + [14:51] A and C are not + [14:52] C contains aspects and embedded devices + [14:52] and least not "mostly distinct", rather "somewhat distinct" + [14:52] which are not in A at all + [14:52] and nobody really knows the state of the logic space + [14:53] and semantic web stuff + [14:53] right + [14:53] not quite right, maybe + [14:53] arigo: i am aware of that + [14:53] I don't think the reviewers will be too interested in stackless or the jit, TBH + [14:53] so we are doomed anyway? :-) + [14:53] so, it means that we have to have very good stackless and jit + [14:54] likely a strong review focus will be on validation, dissemination and community + [14:54] good enough to show that we reached something generally useful + [14:54] hpk: I don't think we can focus on the jit for much more time, 1/1.5 weeks otherwise we are in trouble anyway. Otoh even the amendment five has something called Milestone 3 + [14:54] and this 1.0 would not covert that + [14:54] s/covert/cover + [14:54] arigo: i don't follow your reasoning, sorry + [14:55] arigo: reviewer don't have a strong focus on stackless and jit, thus we need to have very good ones? + [14:55] well, I mean that we cannot write reports that show how toy languages can be jitted + [14:55] because the reviewers are not too interested in the techniques + [14:56] instead, we need to jit the whole of pypy and benchmark some real-world applications + [14:56] this kind of thing + [14:56] that's a very quick conclusion + [14:56] true, the truth is that I have no clue at all + [14:57] arigo: this is to cover the fact that we don't have the things they care about? + [14:57] heh + [14:57] from the WP08 Expected result: "... Verify the expectation of reaching half the speed of C for purely algorithmic code." + [14:57] cfbolz: it's more like, to have some obviously good result at least in some area + [14:57] I see + [14:58] can't follow, too + [14:58] hpk: ah, but that was meant for python code running on pypy-c-jit + [14:58] it's all guessing the reviewers, but having some measurably good results in some area looks like a plan + [14:59] (ah, pedronis just tells me that one of the reviewer actually was interested in the jit and discussed it over lunch) + [15:00] arigo: but a strong (even non-jit) release would look like a measurably good result community-wise + [15:00] well, we are in time shortage, not the community + [15:00] (so I've no clue, really, but it still seems to me that a completely new result like "we can take a real interpreter and turn it into a JIT" implies quite some success) + [15:00] arigo: yes, and maybe also: if we invested now much of our work force on JIT and th reviewers don't care much but dislike the fact that we ignored their focus and recommendations, that might be a more dififcult situation thatn having to admit that the JIT is not fully where we wanted it to be + [15:00] and it's not even clear that the JIT will not be there for the EU review + [15:03] arigo: are you of the opinion that our other thirteen WPs results are not sufficiently presenting a sucess in EU-context? + [15:04] in the worst case yes + [15:05] anyway this is all very meta, what we need is time planning + [15:05] pedronis: indeed + [15:07] the questions are how much more time to spend on the jit and when, how many releases we need to cover what we should package for the EU, when to do report writing and wrap up etc + [15:07] my suggestion stands to finalize as much EU-related things (including a good 1.0 with a JIT-preview) in february + [15:07] I agree that spending feb completely on the jit looks like a very bad idea + [15:08] pedronis: so how much time would you think is reasonable? + [15:09] let's see what happens until monday + [15:10] maybe we'll have a better idea then + [15:10] hm + [15:10] I even mean more than "maybe" + [15:10] we should either start getting somewhere, or not + [15:10] ok + [15:10] so should we plan with you being working on the release from monday on? + [15:11] arigo: ok, but note that there may be a bit of pylib release related disruptions (although i don't think it's going to be bad) + [15:12] maybe we can talk about some other things than the jit now? :-) + [15:12] i suggest to meet tuesday morning and set concrete plans and tasks up until 1.0 + [15:12] arigo,pedronis,arre: would that suit you? + [15:12] i am totally not available on tuesday + [15:13] hpk: monday is pylib release? + [15:13] yes, if my weekend work time will be enough for it + [15:13] hpk: you have to go now? + [15:13] hpk: nicely symmetrical situation + [15:13] heh + [15:13] arigo: :) + [15:13] arigo: let's see who is there first :) + [15:13] yes :-) + [15:14] arigo: but i also have tons of EU stuff until monday, you have an advantage + [15:14] anyway tuesday afternoon looks like a better idea for us + [15:14] arigo: i need to borrow you to explain enough about how genc does direct_fieldptr & c so i can do it for llvm + [15:14] but that can be last next week + [15:14] last -> late + [15:14] mwh: ok + [15:15] I won't be here on tuesday afternoon (I'll be in the airport) + [15:16] stakkars: do you have a windows machine at all? + [15:16] wednesday morning? + [15:17] for me it's fine + [15:17] ok for me + [15:17] probably fine + [15:17] Works. + [15:17] feel free to assign me things if i don't make it :-) + [15:17] I'm away from Wed. and showing up on the Trillke sprint, again. + [15:17] mwh: such as "write all the reports"? + [15:17] works for me + [15:18] antocuni: preferably not that one, no + [15:18] stakkars: ok, put yourself in people.txt, will you? (and please don't forget to co-ordinate with lene about EU things further for monday) + [15:18] cfbolz_ (n=cfbolz at 134.99.112.244) joined #pypy-sync. + [15:18] hm + [15:18] yessir :) + [15:18] sorry + [15:18] cfbolz (n=cfbolz at 134.99.112.244) left irc: Read error: 104 (Connection reset by peer) + [15:18] stakkars: :) + [15:19] stakkars: i know i might be getting on your nerves, but it really helps to sort this out for our pending EU communication + [15:19] so what's the plan now? meeting on tuesday? + [15:19] I will see Stephan after this meeting and will see if he can do some WP6 work before I'm back, maybe + [15:19] cfbolz_: weds it seems + [15:20] cfbolz_: latest suggestion was wednesday morning, where arigo, mwh, antocuni, me could make it + [15:20] and pedronis + [15:20] when exactly? + [15:20] 11? + [15:20] if i gather correctly + [15:20] hpk: i can't promise that i can make it + [15:20] but i'll try + [15:21] so is 11 fine? that's the only slot I can on wed + [15:21] +1 + [15:21] Fine by me. + [15:21] +1 + [15:21] +1 + [15:21] as good as any other + [15:22] ok + [15:22] meeting closed then? + [15:22] i presume so, and we continue/finalise on wednesday 11am gmt+2 + [15:22] ok. see you all + [15:22] I will try to write some minutes + [15:22] bye for now + [15:22] bye for now! + [15:22] bye + [15:22] see you + [15:22] bye + [15:23] bye + [15:23] bye From arigo at codespeak.net Mon Feb 5 15:22:27 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 5 Feb 2007 15:22:27 +0100 (CET) Subject: [pypy-svn] r37965 - pypy/branch/jit-virtual-world/pypy/jit/codegen/i386 Message-ID: <20070205142227.D6AA61007D@code0.codespeak.net> Author: arigo Date: Mon Feb 5 15:22:24 2007 New Revision: 37965 Modified: pypy/branch/jit-virtual-world/pypy/jit/codegen/i386/viewcode.py Log: Add the --text option to only dump the assembler as text to stdout. Modified: pypy/branch/jit-virtual-world/pypy/jit/codegen/i386/viewcode.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/codegen/i386/viewcode.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/codegen/i386/viewcode.py Mon Feb 5 15:22:24 2007 @@ -232,24 +232,29 @@ break # hack hack hacked - def show(self): - g1 = Graph('codedump') + def show(self, showtext=True, showgraph=True): + if showgraph: + g1 = Graph('codedump') self.ranges.sort() for r in self.ranges: disassembled = r.disassemble() - print disassembled - text, width = tab2columns(disassembled) - text = '0x%x\n\n%s' % (r.addr, text) - g1.emit_node('N_%x' % r.addr, shape="box", label=text, - width=str(width*0.1125)) - for lineno, targetaddr, final in r.findjumps(): - if final: - color = "black" - else: - color = "red" - g1.emit_edge('N_%x' % r.addr, 'N_%x' % targetaddr, color=color) + if showtext: + print disassembled + if showgraph: + text, width = tab2columns(disassembled) + text = '0x%x\n\n%s' % (r.addr, text) + g1.emit_node('N_%x' % r.addr, shape="box", label=text, + width=str(width*0.1125)) + for lineno, targetaddr, final in r.findjumps(): + if final: + color = "black" + else: + color = "red" + g1.emit_edge('N_%x' % r.addr, 'N_%x' % targetaddr, + color=color) sys.stdout.flush() - g1.display() + if showgraph: + g1.display() def tab2columns(text): @@ -341,10 +346,15 @@ # ____________________________________________________________ if __name__ == '__main__': + if '--text' in sys.argv: + sys.argv.remove('--text') + showgraph = False + else: + showgraph = True if len(sys.argv) == 1: f = sys.stdin else: f = open(sys.argv[1], 'r') world = World() world.parse(f) - world.show() + world.show(showtext=True, showgraph=showgraph) From arigo at codespeak.net Mon Feb 5 15:24:03 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 5 Feb 2007 15:24:03 +0100 (CET) Subject: [pypy-svn] r37966 - in pypy/branch/jit-virtual-world/pypy: jit/timeshifter jit/timeshifter/test rpython translator/c Message-ID: <20070205142403.3B6641007D@code0.codespeak.net> Author: arigo Date: Mon Feb 5 15:23:58 2007 New Revision: 37966 Added: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/exception.py (contents, props changed) Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/hrtyper.py pypy/branch/jit-virtual-world/pypy/jit/timeshifter/oop.py pypy/branch/jit-virtual-world/pypy/jit/timeshifter/rcontainer.py pypy/branch/jit-virtual-world/pypy/jit/timeshifter/rtimeshift.py pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_portal.py pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_timeshift.py pypy/branch/jit-virtual-world/pypy/jit/timeshifter/transform.py pypy/branch/jit-virtual-world/pypy/rpython/llinterp.py pypy/branch/jit-virtual-world/pypy/translator/c/exceptiontransform.py Log: (pedronis, arre, arigo) * simplify exceptiontransform to use a Struct instead of an RPyhton instance to store the current exception. * after residual calls, if possible, we check for exceptions using promotion. This allows the JIT compiler to only produce code for the branch that is actually taken (i.e. the non-exceptional branch, usually). Added: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/exception.py ============================================================================== --- (empty file) +++ pypy/branch/jit-virtual-world/pypy/jit/timeshifter/exception.py Mon Feb 5 15:23:58 2007 @@ -0,0 +1,76 @@ +from pypy.rpython.lltypesystem import lltype, llmemory +from pypy.jit.timeshifter import rvalue, rtimeshift + + +class ExceptionDesc: + + def __init__(self, hrtyper, lazy_exception_path): + RGenOp = hrtyper.RGenOp + self.etrafo = hrtyper.annotator.exceptiontransformer + self.cexcdata = self.etrafo.cexcdata + self.exc_data_ptr = self.cexcdata.value + self.gv_excdata = RGenOp.constPrebuiltGlobal(self.exc_data_ptr) + + EXCDATA = self.etrafo.EXCDATA + self.exc_type_token = RGenOp.fieldToken(EXCDATA, 'exc_type') + self.exc_value_token = RGenOp.fieldToken(EXCDATA, 'exc_value') + self.exc_type_kind = RGenOp.kindToken(EXCDATA.exc_type) + self.exc_value_kind = RGenOp.kindToken(EXCDATA.exc_value) + + LL_EXC_TYPE = EXCDATA.exc_type + LL_EXC_VALUE = EXCDATA.exc_value + + self.gv_null_exc_type = RGenOp.constPrebuiltGlobal( + lltype.nullptr(LL_EXC_TYPE.TO)) + self.gv_null_exc_value = RGenOp.constPrebuiltGlobal( + lltype.nullptr(LL_EXC_VALUE.TO)) + self.null_exc_type_box = rvalue.PtrRedBox(self.exc_type_kind, + self.gv_null_exc_type) + self.null_exc_value_box = rvalue.PtrRedBox(self.exc_value_kind, + self.gv_null_exc_value) + self.lazy_exception_path = lazy_exception_path + + def _freeze_(self): + return True + + def genop_get_exc_type(self, builder): + return builder.genop_getfield(self.exc_type_token, self.gv_excdata) + + def genop_get_exc_value(self, builder): + return builder.genop_getfield(self.exc_value_token, self.gv_excdata) + + def genop_set_exc_type(self, builder, gv_value): + builder.genop_setfield(self.exc_type_token, self.gv_excdata, gv_value) + + def genop_set_exc_value(self, builder, gv_value): + builder.genop_setfield(self.exc_value_token, self.gv_excdata, gv_value) + + def fetch_global_excdata(self, jitstate, known_occurred=False): + builder = jitstate.curbuilder + gv_etype = self.genop_get_exc_type (builder) + gv_evalue = self.genop_get_exc_value(builder) + self.genop_set_exc_type (builder, self.gv_null_exc_type ) + self.genop_set_exc_value(builder, self.gv_null_exc_value) + etypebox = rvalue.PtrRedBox(self.exc_type_kind, gv_etype ) + evaluebox = rvalue.PtrRedBox(self.exc_value_kind, gv_evalue) + etypebox .known_nonzero = known_occurred + evaluebox.known_nonzero = known_occurred + rtimeshift.setexctypebox (jitstate, etypebox) + rtimeshift.setexcvaluebox(jitstate, evaluebox) + + def store_global_excdata(self, jitstate): + builder = jitstate.curbuilder + etypebox = jitstate.exc_type_box + if etypebox.is_constant(): + ll_etype = rvalue.ll_getvalue(etypebox, llmemory.Address) + if not ll_etype: + return # we know there is no exception set + evaluebox = jitstate.exc_value_box + gv_etype = etypebox .getgenvar(jitstate) + gv_evalue = evaluebox.getgenvar(jitstate) + self.genop_set_exc_type (builder, gv_etype ) + self.genop_set_exc_value(builder, gv_evalue) + + def gen_exc_occurred(self, builder): + gv_etype = self.genop_get_exc_type(builder) + return builder.genop_ptr_nonzero(self.exc_type_kind, gv_etype) Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/hrtyper.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/timeshifter/hrtyper.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/timeshifter/hrtyper.py Mon Feb 5 15:23:58 2007 @@ -22,6 +22,7 @@ from pypy.jit.hintannotator.model import originalconcretetype from pypy.jit.timeshifter import rtimeshift, rvalue, rcontainer, oop from pypy.jit.timeshifter.transform import HintGraphTransformer +from pypy.jit.timeshifter.exception import ExceptionDesc from pypy.jit.codegen import model as cgmodel class HintTypeSystem(LowLevelTypeSystem): @@ -77,69 +78,13 @@ (self.s_Queue, self.r_Queue) = self.s_r_instanceof(rtimeshift.BaseDispatchQueue) - self.etrafo = hannotator.exceptiontransformer - self.cexcdata = self.etrafo.cexcdata - self.exc_data_ptr = self.cexcdata.value - gv_excdata = RGenOp.constPrebuiltGlobal(self.exc_data_ptr) - LL_EXC_TYPE = rtyper.exceptiondata.lltype_of_exception_type - LL_EXC_VALUE = rtyper.exceptiondata.lltype_of_exception_value - null_exc_type_box = rvalue.redbox_from_prebuilt_value(RGenOp, - lltype.nullptr(LL_EXC_TYPE.TO)) - null_exc_value_box = rvalue.redbox_from_prebuilt_value(RGenOp, - lltype.nullptr(LL_EXC_VALUE.TO)) - - p = self.etrafo.rpyexc_fetch_type_ptr.value - gv_rpyexc_fetch_type = RGenOp.constPrebuiltGlobal(p) - tok_fetch_type = RGenOp.sigToken(lltype.typeOf(p).TO) - kind_etype = RGenOp.kindToken(LL_EXC_TYPE) - - p = self.etrafo.rpyexc_fetch_value_ptr.value - gv_rpyexc_fetch_value = RGenOp.constPrebuiltGlobal(p) - tok_fetch_value = RGenOp.sigToken(lltype.typeOf(p).TO) - kind_evalue = RGenOp.kindToken(LL_EXC_VALUE) - - p = self.etrafo.rpyexc_clear_ptr.value - gv_rpyexc_clear = RGenOp.constPrebuiltGlobal(p) - tok_clear = RGenOp.sigToken(lltype.typeOf(p).TO) - - p = self.etrafo.rpyexc_raise_ptr.value - gv_rpyexc_raise = RGenOp.constPrebuiltGlobal(p) - tok_raise = RGenOp.sigToken(lltype.typeOf(p).TO) - - def fetch_global_excdata(jitstate): - builder = jitstate.curbuilder - gv_etype = builder.genop_call(tok_fetch_type, - gv_rpyexc_fetch_type, []) - gv_evalue = builder.genop_call(tok_fetch_value, - gv_rpyexc_fetch_value, []) - builder.genop_call(tok_clear, gv_rpyexc_clear, []) - etypebox = rvalue.PtrRedBox(kind_etype, gv_etype) - evaluebox = rvalue.PtrRedBox(kind_evalue, gv_evalue) - rtimeshift.setexctypebox (jitstate, etypebox) - rtimeshift.setexcvaluebox(jitstate, evaluebox) - self.fetch_global_excdata = fetch_global_excdata - - def store_global_excdata(jitstate): - builder = jitstate.curbuilder - etypebox = jitstate.exc_type_box - if etypebox.is_constant(): - ll_etype = rvalue.ll_getvalue(etypebox, llmemory.Address) - if not ll_etype: - return # we known there is no exception set - evaluebox = jitstate.exc_value_box - gv_etype = etypebox .getgenvar(jitstate) - gv_evalue = evaluebox.getgenvar(jitstate) - builder.genop_call(tok_raise, - gv_rpyexc_raise, [gv_etype, gv_evalue]) - self.store_global_excdata = store_global_excdata - - def ll_fresh_jitstate(builder): + def ll_fresh_jitstate(builder, exceptiondesc): return rtimeshift.JITState(builder, None, - null_exc_type_box, - null_exc_value_box) + exceptiondesc.null_exc_type_box, + exceptiondesc.null_exc_value_box) self.ll_fresh_jitstate = ll_fresh_jitstate - def ll_finish_jitstate(jitstate, graphsigtoken): + def ll_finish_jitstate(jitstate, exceptiondesc, graphsigtoken): assert jitstate.resuming is None returnbox = rtimeshift.getreturnbox(jitstate) gv_ret = returnbox.getgenvar(jitstate) @@ -149,7 +94,7 @@ content = virtualizable_box.content assert isinstance(content, rcontainer.VirtualizableStruct) content.store_back(jitstate) - store_global_excdata(jitstate) + exceptiondesc.store_global_excdata(jitstate) jitstate.curbuilder.finish_and_return(graphsigtoken, gv_ret) self.ll_finish_jitstate = ll_finish_jitstate @@ -200,6 +145,9 @@ "Forgot 'hint(None, global_merge_point=True)'?") self.log.event("Timeshifted control flow of %d graphs." % (len(seen),)) + self.exceptiondesc = ExceptionDesc(self, + self.portal_contains_global_mp) + #import pdb; pdb.set_trace() # only keep the hint-annotated graphs that are really useful self.annotator.translator.graphs = [graph @@ -277,6 +225,7 @@ args_specification = unrolling_iterable(args_specification) fresh_jitstate = self.ll_fresh_jitstate finish_jitstate = self.ll_finish_jitstate + exceptiondesc = self.exceptiondesc sigtoken = rgenop.sigToken(FUNC) # debug helper @@ -323,7 +272,7 @@ builder, gv_generated, inputargs_gv = rgenop.newgraph(sigtoken, "generated") cache[key] = gv_generated - top_jitstate = fresh_jitstate(builder) + top_jitstate = fresh_jitstate(builder, exceptiondesc) i = 0 for color, _, make_arg_redbox in args_specification: if color == "green": @@ -350,7 +299,7 @@ builder.start_writing() top_jitstate = portal_fn(top_jitstate, *portal_ts_args) if top_jitstate is not None: - finish_jitstate(top_jitstate, sigtoken) + finish_jitstate(top_jitstate, exceptiondesc, sigtoken) builder.end() builder.show_incremental_progress() @@ -379,7 +328,7 @@ TYPES = [v.concretetype for v in origportalgraph.getargs()] argspecandtypes = unrolling_iterable(zip(args_specification, TYPES)) - fetch_global_excdata = self.fetch_global_excdata + fetch_global_excdata = self.exceptiondesc.fetch_global_excdata def portalreentry(jitstate, *args): # xxx virtualizables? i = 0 @@ -419,7 +368,7 @@ i += 1 portal_ts_args += (box,) - top_jitstate = fresh_jitstate(builder) + top_jitstate = fresh_jitstate(builder, exceptiondesc) state.graph_compilation_queue.append((top_jitstate, portal_ts_args)) gv_res = curbuilder.genop_call(sigtoken, gv_generated, args_gv) @@ -713,12 +662,12 @@ if isinstance(hop.args_r[0], BlueRepr): return hop.args_r[0].timeshift_getfield(hop) ts = self - if hop.args_v[0] == ts.cexcdata: + if hop.args_v[0] == ts.exceptiondesc.cexcdata: # reading one of the exception boxes (exc_type or exc_value) fieldname = hop.args_v[1].value - if fieldname.endswith('exc_type'): + if fieldname == 'exc_type': reader = rtimeshift.getexctypebox - elif fieldname.endswith('exc_value'): + elif fieldname == 'exc_value': reader = rtimeshift.getexcvaluebox else: raise Exception("getfield(exc_data, %r)" % (fieldname,)) @@ -793,12 +742,12 @@ VALUETYPE = originalconcretetype(hop.args_s[2]) if VALUETYPE is lltype.Void: return - if hop.args_v[0] == ts.cexcdata: + if hop.args_v[0] == ts.exceptiondesc.cexcdata: # reading one of the exception boxes (exc_type or exc_value) fieldname = hop.args_v[1].value - if fieldname.endswith('exc_type'): + if fieldname == 'exc_type': writer = rtimeshift.setexctypebox - elif fieldname.endswith('exc_value'): + elif fieldname == 'exc_value': writer = rtimeshift.setexcvaluebox else: raise Exception("setfield(exc_data, %r)" % (fieldname,)) @@ -1207,6 +1156,7 @@ RESIDUAL_FUNCTYPE = self.get_residual_functype(tsgraph) residualSigToken = self.RGenOp.sigToken(RESIDUAL_FUNCTYPE) ll_finish_jitstate = self.ll_finish_jitstate + exceptiondesc = self.exceptiondesc args_s = [self.s_JITState] + [annmodel.lltype_to_annotation(ARG) for ARG in TS_FUNC.TO.ARGS[1:]] @@ -1220,7 +1170,8 @@ jitstate.resumepoint = N finaljitstate = tsfn(jitstate, *dummy_args) if finaljitstate is not None: - ll_finish_jitstate(finaljitstate, residualSigToken) + ll_finish_jitstate(finaljitstate, exceptiondesc, + residualSigToken) return self.translate_op_merge_point(hop, global_resumer = call_for_global_resuming) @@ -1277,15 +1228,19 @@ # handling of the various kinds of calls def translate_op_oopspec_was_residual(self, hop): - return hop.inputconst(lltype.Bool, False) + v_jitstate = hop.llops.getjitstate() + return hop.llops.genmixlevelhelpercall(rtimeshift.oopspec_was_residual, + [self.s_JITState], + [v_jitstate ], + annmodel.s_Bool) - def translate_op_oopspec_call(self, hop): + def translate_op_oopspec_call(self, hop, can_raise=True): # special-cased call, for things like list methods from pypy.jit.timeshifter.oop import OopSpecDesc, Index c_func = hop.args_v[0] fnobj = c_func.value._obj - oopspecdesc = OopSpecDesc(self, fnobj) + oopspecdesc = OopSpecDesc(self, fnobj, can_raise) hop.r_s_popfirstarg() args_v = [] @@ -1343,6 +1298,9 @@ [v_jitstate, c_oopspecdesc] + args_v, s_result) + def translate_op_oopspec_call_noexc(self, hop): + return self.translate_op_oopspec_call(hop, False) + def translate_op_green_call(self, hop): for r_arg in hop.args_r: assert isinstance(r_arg, GreenRepr) @@ -1427,27 +1385,32 @@ oop = dopts['oop'] v_jitstate = hop.llops.getjitstate() if withexc: - hop.llops.genmixlevelhelpercall(self.fetch_global_excdata, - [self.s_JITState], [v_jitstate], - annmodel.s_None) - if not oop: - v_after = hop.llops.genmixlevelhelpercall( - rtimeshift.after_residual_call, - [self.s_JITState], - [v_jitstate], - self.s_RedBox) - else: # xxx - v_after = hop.inputconst(self.getredrepr(lltype.Signed), 0) - + c_exception_desc = hop.inputconst(lltype.Void, self.exceptiondesc) + else: + c_exception_desc = hop.inputconst(lltype.Void, None) + bk = self.rtyper.annotator.bookkeeper + s_exception_desc = bk.immutablevalue(c_exception_desc.value) + c_check_forced = hop.inputconst(lltype.Bool, not oop) + v_after = hop.llops.genmixlevelhelpercall( + rtimeshift.ll_after_residual_call, + [self.s_JITState, s_exception_desc, annmodel.s_Bool], + [v_jitstate , c_exception_desc, c_check_forced ], + self.s_RedBox) return v_after - - def translate_op_reshape(self, hop): - v_jitstate = hop.llops.getjitstate() - v_shape, = hop.inputargs(self.getredrepr(lltype.Signed)) - return hop.llops.genmixlevelhelpercall(rtimeshift.reshape, - [self.s_JITState, self.s_RedBox], - [v_jitstate , v_shape ], - annmodel.s_None) + + def translate_op_residual_fetch(self, hop): + dopts = hop.args_v[1].value + oop = dopts['oop'] + v_jitstate = hop.llops.getjitstate() + v_flags = hop.inputarg(self.getredrepr(lltype.Signed), arg=0) + bk = self.rtyper.annotator.bookkeeper + c_exception_desc = hop.inputconst(lltype.Void, self.exceptiondesc) + s_exception_desc = bk.immutablevalue(c_exception_desc.value) + c_check_forced = hop.inputconst(lltype.Bool, not oop) + return hop.llops.genmixlevelhelpercall(rtimeshift.residual_fetch, + [self.s_JITState, s_exception_desc, annmodel.s_Bool, self.s_RedBox], + [v_jitstate , c_exception_desc, c_check_forced , v_flags ], + annmodel.s_None) def translate_op_reverse_split_queue(self, hop): hop.llops.genmixlevelhelpercall(rtimeshift.reverse_split_queue, Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/oop.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/timeshifter/oop.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/timeshifter/oop.py Mon Feb 5 15:23:58 2007 @@ -16,11 +16,13 @@ do_call = None - def __init__(self, hrtyper, fnobj): + def __init__(self, hrtyper, fnobj, can_raise): ll_func = fnobj._callable FUNCTYPE = lltype.typeOf(fnobj) nb_args = len(FUNCTYPE.ARGS) + self.can_raise = can_raise + # parse the oopspec and fill in the arguments operation_name, args = ll_func.oopspec.split('(', 1) assert args.endswith(')') @@ -79,12 +81,6 @@ self.ll_handler = getattr(vmodule, method) self.couldfold = getattr(self.ll_handler, 'couldfold', False) - # exception handling - graph = fnobj.graph - etrafo = hrtyper.etrafo - self.can_raise = etrafo.raise_analyzer.analyze_direct_call(graph) - self.fetch_global_excdata = hrtyper.fetch_global_excdata - if self.couldfold: ARGS = FUNCTYPE.ARGS residualargsources = self.residualargsources @@ -129,7 +125,7 @@ return self.errorbox gv_result = builder.genop_call(self.sigtoken, self.gv_fnptr, args_gv) if self.can_raise: - self.fetch_global_excdata(jitstate) + jitstate.generated_oop_residual_can_raise = True return self.redboxbuilder(self.result_kind, gv_result) def residual_exception(self, jitstate, ExcCls): Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/rcontainer.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/timeshifter/rcontainer.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/timeshifter/rcontainer.py Mon Feb 5 15:23:58 2007 @@ -759,7 +759,7 @@ access_token = typedesc.access_desc.fieldtoken builder.genop_setfield(access_token, gv_outside, typedesc.gv_access) - def after_residual_call(self, jitstate): + def check_forced_after_residual_call(self, jitstate): typedesc = self.typedesc builder = jitstate.curbuilder gv_outside = self.content_boxes[-1].genvar Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/rtimeshift.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/timeshifter/rtimeshift.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/timeshifter/rtimeshift.py Mon Feb 5 15:23:58 2007 @@ -518,12 +518,38 @@ gv_result = builder.genop_call(calldesc.sigtoken, gv_funcbox, args_gv) return calldesc.redboxbuilder(calldesc.result_kind, gv_result) -def after_residual_call(jitstate): - return jitstate.after_residual_call() - -def reshape(jitstate, shapebox): - shapemask = rvalue.ll_getvalue(shapebox, lltype.Signed) - jitstate.reshape(shapemask) +def ll_after_residual_call(jitstate, exceptiondesc, check_forced): + builder = jitstate.curbuilder + if check_forced: + gv_flags = jitstate.check_forced_after_residual_call() + else: + gv_flags = None + if exceptiondesc: + if exceptiondesc.lazy_exception_path: + gv_occurred = exceptiondesc.gen_exc_occurred(builder) + gv_flag = builder.genop1("cast_bool_to_int", gv_occurred) + if gv_flags is None: + gv_flags = gv_flag + else: + gv_flags = builder.genop2("int_or", gv_flags, gv_flag) + else: + exceptiondesc.fetch_global_excdata(jitstate) + if gv_flags is None: + gv_flags = builder.rgenop.constPrebuiltGlobal(0) + return rvalue.IntRedBox(builder.rgenop.kindToken(lltype.Signed), gv_flags) + +def residual_fetch(jitstate, exceptiondesc, check_forced, flagsbox): + flags = rvalue.ll_getvalue(flagsbox, lltype.Signed) + if flags & 1: # an exception occurred + exceptiondesc.fetch_global_excdata(jitstate, known_occurred=True) + if check_forced: + shapemask = flags & ~ 1 + jitstate.reshape(shapemask) + +def oopspec_was_residual(jitstate): + res = jitstate.generated_oop_residual_can_raise + jitstate.generated_oop_residual_can_raise = False + return res class ResumingInfo(object): @@ -898,11 +924,13 @@ next virtualizables shape_place + generated_oop_residual_can_raise """.split() returnbox = None next = None # for linked lists promotion_path = None + generated_oop_residual_can_raise = False def __init__(self, builder, frame, exc_type_box, exc_value_box, resumepoint=-1, newgreens=[], resuming=None, @@ -972,7 +1000,7 @@ if virtualizables: builder = self.curbuilder memo = rvalue.make_vrti_memo() - memo.bitcount = 0 + memo.bitcount = 1 memo.frameindex = 0 memo.framevars_gv = [] shape_kind = builder.rgenop.kindToken(lltype.Signed) @@ -998,29 +1026,28 @@ assert isinstance(content, rcontainer.VirtualizableStruct) content.prepare_for_residual_call(self, gv_base, vable_rti) - def after_residual_call(self): + def check_forced_after_residual_call(self): virtualizables = self.virtualizables builder = self.curbuilder if virtualizables: for virtualizable_box in virtualizables: content = virtualizable_box.content assert isinstance(content, rcontainer.VirtualizableStruct) - content.after_residual_call(self) + content.check_forced_after_residual_call(self) shape_kind = builder.rgenop.kindToken(lltype.Signed) gv_shape = builder.genop_absorb_place(shape_kind, self.shape_place) self.shape_place = None + return gv_shape else: - gv_shape = builder.rgenop.genconst(0) - return rvalue.IntRedBox(builder.rgenop.kindToken(lltype.Signed), - gv_shape) + return None def reshape(self, shapemask): virtualizables = self.virtualizables builder = self.curbuilder if virtualizables: memo = rvalue.make_vrti_memo() - memo.bitcount = 0 + memo.bitcount = 1 if shapemask: memo.forced = [] else: Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_portal.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_portal.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_portal.py Mon Feb 5 15:23:58 2007 @@ -64,8 +64,8 @@ self.hrtyper.specialize(origportalgraph=origportalgraph, view = conftest.option.view and self.small) - if conftest.option.view and self.small: - t.view() + #if conftest.option.view and self.small: + # t.view() self.postprocess_timeshifting() self.readportalgraph = self.hrtyper.readportalgraph @@ -86,12 +86,14 @@ backendoptimize=backendoptimize) self.main_args = main_args self.main_is_portal = main is portal - llinterp = LLInterpreter(self.rtyper) + exc_data_ptr = self.hrtyper.exceptiondesc.exc_data_ptr + llinterp = LLInterpreter(self.rtyper, exc_data_ptr=exc_data_ptr) res = llinterp.eval_graph(self.maingraph, main_args) return res def get_residual_graph(self): - llinterp = LLInterpreter(self.rtyper) + exc_data_ptr = self.hrtyper.exceptiondesc.exc_data_ptr + llinterp = LLInterpreter(self.rtyper, exc_data_ptr=exc_data_ptr) if self.main_is_portal: residual_graph = llinterp.eval_graph(self.readportalgraph, self.main_args)._obj.graph @@ -469,3 +471,49 @@ res = self.timeshift_from_portal(ll_main, ll_function, [5], policy=P_NOVIRTUAL) assert res == 123 self.check_insns(indirect_call=1) + + def test_residual_red_call_with_promoted_exc(self): + def h(x): + if x > 0: + return x+1 + else: + raise ValueError + + def g(x): + return 2*h(x) + + def f(x): + hint(None, global_merge_point=True) + try: + return g(x) + except ValueError: + return 7 + + stop_at_h = StopAtXPolicy(h) + res = self.timeshift_from_portal(f, f, [20], policy=stop_at_h) + assert res == 42 + self.check_insns(int_add=0) + + res = self.timeshift_from_portal(f, f, [-20], policy=stop_at_h) + assert res == 7 + self.check_insns(int_add=0) + + def test_residual_oop_raising(self): + def g(x): + lst = [] + if x > 10: + lst.append(x) + return lst + def f(x): + hint(None, global_merge_point=True) + lst = g(x) + try: + return lst[0] + except IndexError: + return -42 + + res = self.timeshift_from_portal(f, f, [5], policy=P_OOPSPEC) + assert res == -42 + + res = self.timeshift_from_portal(f, f, [15], policy=P_OOPSPEC) + assert res == 15 Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_timeshift.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_timeshift.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_timeshift.py Mon Feb 5 15:23:58 2007 @@ -106,6 +106,7 @@ hrtyper.specialize(view = conftest.option.view and self.small) fresh_jitstate = hrtyper.ll_fresh_jitstate finish_jitstate = hrtyper.ll_finish_jitstate + exceptiondesc = hrtyper.exceptiondesc t = rtyper.annotator.translator # make an interface to the timeshifted graphs: @@ -180,11 +181,11 @@ i += 1 timeshifted_entrypoint_args += (box,) - top_jitstate = fresh_jitstate(builder) + top_jitstate = fresh_jitstate(builder, exceptiondesc) top_jitstate = timeshifted_entrypoint(top_jitstate, *timeshifted_entrypoint_args) if top_jitstate is not None: - finish_jitstate(top_jitstate, sigtoken) + finish_jitstate(top_jitstate, exceptiondesc, sigtoken) builder.end() generated = gv_generated.revealconst(lltype.Ptr(FUNC)) @@ -220,9 +221,9 @@ self.rtyper = rtyper self.hrtyper = hrtyper self.annotate_interface_functions() - if conftest.option.view and self.small: - from pypy.translator.tool.graphpage import FlowGraphPage - FlowGraphPage(t, ha.translator.graphs).display() + #if conftest.option.view and self.small: + # from pypy.translator.tool.graphpage import FlowGraphPage + # FlowGraphPage(t, ha.translator.graphs).display() cache = self.__dict__.copy() self._cache[key] = cache, getargtypes(rtyper.annotator, values) @@ -267,12 +268,12 @@ residualargs.append(llvalue) # run the graph generator - llinterp = LLInterpreter(self.rtyper) + exc_data_ptr = self.hrtyper.exceptiondesc.exc_data_ptr + llinterp = LLInterpreter(self.rtyper, exc_data_ptr=exc_data_ptr) ll_generated = llinterp.eval_graph(self.maingraph, mainargs) # now try to run the residual graph generated by the builder residual_graph = ll_generated._obj.graph - residual_graph.exceptiontransformed = self.hrtyper.exc_data_ptr self.ll_generated = ll_generated self.residual_graph = residual_graph if conftest.option.view: Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/transform.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/timeshifter/transform.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/timeshifter/transform.py Mon Feb 5 15:23:58 2007 @@ -672,7 +672,10 @@ def handle_oopspec_call(self, block, pos, withexc): op = block.operations[pos] assert op.opname == 'direct_call' - op.opname = 'oopspec_call' + if withexc: + op.opname = 'oopspec_call' + else: + op.opname = 'oopspec_call_noexc' if withexc: link = split_block(self.hannotator, block, pos+1) nextblock = link.target @@ -765,19 +768,19 @@ oop = False): dopts = {'withexc': withexc, 'oop': oop } copts = Constant(dopts, lltype.Void) - v_shape = self.genop(newops, 'after_residual_call', [copts], + v_flags = self.genop(newops, 'after_residual_call', [copts], resulttype=lltype.Signed, red=True) - reshape_index = len(newops) - self.genop(newops, 'reshape', [v_shape]) - reshape_pos = pos+reshape_index + residual_fetch_index = len(newops) + self.genop(newops, 'residual_fetch', [v_flags, copts]) + residual_fetch_pos = pos+residual_fetch_index block.operations[pos:pos+1] = newops - link = split_block(self.hannotator, block, reshape_pos) + link = split_block(self.hannotator, block, residual_fetch_pos) nextblock = link.target reds, greens = self.sort_by_color(link.args) self.genop(block, 'save_locals', reds) - v_finished_flag = self.genop(block, 'promote', [v_shape], + v_finished_flag = self.genop(block, 'promote', [v_flags], resulttype = lltype.Bool) self.go_to_dispatcher_if(block, v_finished_flag) Modified: pypy/branch/jit-virtual-world/pypy/rpython/llinterp.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/rpython/llinterp.py (original) +++ pypy/branch/jit-virtual-world/pypy/rpython/llinterp.py Mon Feb 5 15:23:58 2007 @@ -42,10 +42,11 @@ class LLInterpreter(object): """ low level interpreter working with concrete values. """ - def __init__(self, typer, heap=llheap, tracing=True): + def __init__(self, typer, heap=llheap, tracing=True, exc_data_ptr=None): self.bindings = {} self.typer = typer self.heap = heap #module that provides malloc, etc for lltypes + self.exc_data_ptr = exc_data_ptr self.active_frame = None # XXX hack: set gc to None because # prepare_graphs_and_create_gc might already use the llinterpreter! @@ -150,6 +151,13 @@ self.active_frame = old_active_frame raise ValueError, "couldn't match exception" + def get_transformed_exc_data(self, graph): + if hasattr(graph, 'exceptiontransformed'): + return graph.exceptiontransformed + if getattr(graph, 'rgenop', False): + return self.exc_data_ptr + return None + def checkptr(ptr): assert isinstance(lltype.typeOf(ptr), lltype.Ptr) @@ -284,18 +292,16 @@ raise LLException(etype, evalue) resultvar, = block.getvariables() result = self.getval(resultvar) - if hasattr(self.graph, 'exceptiontransformed'): + exc_data = self.llinterpreter.get_transformed_exc_data(self.graph) + if exc_data: # re-raise the exception set by this graph, if any - exc_data = self.graph.exceptiontransformed - etype = rclass.fishllattr(exc_data, 'exc_type') + etype = exc_data.exc_type if etype: - evalue = rclass.fishllattr(exc_data, 'exc_value') + evalue = exc_data.exc_value if tracer: tracer.dump('raise') - rclass.feedllattr(exc_data, 'exc_type', - lltype.typeOf(etype)._defl()) - rclass.feedllattr(exc_data, 'exc_value', - lltype.typeOf(evalue)._defl()) + exc_data.exc_type = lltype.typeOf(etype )._defl() + exc_data.exc_value = lltype.typeOf(evalue)._defl() from pypy.translator.c import exceptiontransform T = resultvar.concretetype errvalue = exceptiontransform.error_value(T) @@ -554,13 +560,13 @@ try: return self.perform_call(f, FTYPE.ARGS, args) except LLException, e: - if hasattr(self.graph, 'exceptiontransformed'): + exc_data = self.llinterpreter.get_transformed_exc_data(self.graph) + if exc_data: # store the LLException into the exc_data used by this graph - exc_data = self.graph.exceptiontransformed etype = e.args[0] evalue = e.args[1] - rclass.feedllattr(exc_data, 'exc_type', etype) - rclass.feedllattr(exc_data, 'exc_value', evalue) + exc_data.exc_type = etype + exc_data.exc_value = evalue from pypy.translator.c import exceptiontransform return exceptiontransform.error_value(FTYPE.RESULT) raise Modified: pypy/branch/jit-virtual-world/pypy/translator/c/exceptiontransform.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/translator/c/exceptiontransform.py (original) +++ pypy/branch/jit-virtual-world/pypy/translator/c/exceptiontransform.py Mon Feb 5 15:23:58 2007 @@ -9,6 +9,7 @@ from pypy.rpython.memory.lladdress import NULL from pypy.rpython import rtyper from pypy.rpython import rclass +from pypy.rpython.rmodel import inputconst from pypy.rlib.rarithmetic import r_uint, r_longlong, r_ulonglong from pypy.annotation import model as annmodel from pypy.rpython.annlowlevel import MixLevelHelperAnnotator @@ -45,25 +46,25 @@ mixlevelannotator = MixLevelHelperAnnotator(translator.rtyper) l2a = annmodel.lltype_to_annotation - class ExcData(object): - pass - #exc_type = lltype.nullptr(self.exc_data.lltype_of_exception_type.TO) - #exc_value = lltype.nullptr(self.exc_data.lltype_of_exception_value.TO) + EXCDATA = lltype.Struct('ExcData', + ('exc_type', self.lltype_of_exception_type), + ('exc_value', self.lltype_of_exception_value)) + self.EXCDATA = EXCDATA - exc_data = ExcData() + exc_data = lltype.malloc(EXCDATA, immortal=True) null_type = lltype.nullptr(self.lltype_of_exception_type.TO) null_value = lltype.nullptr(self.lltype_of_exception_value.TO) def rpyexc_occured(): exc_type = exc_data.exc_type - return exc_type is not null_type + return bool(exc_type) # XXX tmp HACK for genllvm # llvm is strongly typed between bools and ints, which means we have no way of # calling rpyexc_occured() from c code with lltype.Bool def _rpyexc_occured(): exc_type = exc_data.exc_type - return exc_type is not null_type + return bool(exc_type) def rpyexc_fetch_type(): return exc_data.exc_type @@ -145,11 +146,8 @@ mixlevelannotator.finish() - ExcDataDef = translator.annotator.bookkeeper.getuniqueclassdef(ExcData) - self.ExcData_repr = rclass.getinstancerepr(translator.rtyper, ExcDataDef) - self.exc_data_ptr = self.ExcData_repr.convert_const(exc_data) - self.cexcdata = Constant(self.exc_data_ptr, - self.ExcData_repr.lowleveltype) + self.exc_data_ptr = exc_data + self.cexcdata = Constant(exc_data, lltype.Ptr(EXCDATA)) self.lltype_to_classdef = translator.rtyper.lltype_to_classdef_mapping() p = lltype.nullptr(self.lltype_of_exception_type.TO) @@ -157,6 +155,15 @@ p = lltype.nullptr(self.lltype_of_exception_value.TO) self.c_null_evalue = Constant(p, self.lltype_of_exception_value) + def gen_getfield(self, name, llops): + c_name = inputconst(lltype.Void, name) + return llops.genop('getfield', [self.cexcdata, c_name], + resulttype = getattr(self.EXCDATA, name)) + + def gen_setfield(self, name, v_value, llops): + c_name = inputconst(lltype.Void, name) + llops.genop('setfield', [self.cexcdata, c_name, v_value]) + def transform_completely(self): for graph in self.translator.graphs: self.create_exception_handling(graph) @@ -290,11 +297,10 @@ excblock = Block([]) llops = rtyper.LowLevelOpList(None) - r = self.ExcData_repr - var_value = r.getfield(self.cexcdata, 'exc_value', llops) - var_type = r.getfield(self.cexcdata, 'exc_type', llops) - r.setfield(self.cexcdata, 'exc_value', self.c_null_evalue, llops) - r.setfield(self.cexcdata, 'exc_type', self.c_null_etype, llops) + var_value = self.gen_getfield('exc_value', llops) + var_type = self.gen_getfield('exc_type' , llops) + self.gen_setfield('exc_value', self.c_null_evalue, llops) + self.gen_setfield('exc_type', self.c_null_etype, llops) excblock.operations[:] = llops newgraph.exceptblock.inputargs[0].concretetype = self.lltype_of_exception_type newgraph.exceptblock.inputargs[1].concretetype = self.lltype_of_exception_value @@ -329,7 +335,7 @@ var_exc_occured = llops.genop('ptr_iszero', [spaceop.result], lltype.Bool) else: - v_exc_type = self.ExcData_repr.getfield(self.cexcdata, 'exc_type', llops) + v_exc_type = self.gen_getfield('exc_type', llops) var_exc_occured = llops.genop('ptr_nonzero', [v_exc_type], lltype.Bool) @@ -376,7 +382,6 @@ if normalafterblock is None: normalafterblock = insert_empty_block(None, l0) llops = rtyper.LowLevelOpList(None) - r = self.ExcData_repr - r.setfield(self.cexcdata, 'exc_value', self.c_null_evalue, llops) - r.setfield(self.cexcdata, 'exc_type', self.c_null_etype, llops) + self.gen_setfield('exc_value', self.c_null_evalue, llops) + self.gen_setfield('exc_type', self.c_null_etype, llops) normalafterblock.operations[:0] = llops From santagada at codespeak.net Mon Feb 5 15:51:58 2007 From: santagada at codespeak.net (santagada at codespeak.net) Date: Mon, 5 Feb 2007 15:51:58 +0100 (CET) Subject: [pypy-svn] r37970 - pypy/dist/pypy/lang/js Message-ID: <20070205145158.3B9EB1007F@code0.codespeak.net> Author: santagada Date: Mon Feb 5 15:51:51 2007 New Revision: 37970 Modified: pypy/dist/pypy/lang/js/interpreter.py pypy/dist/pypy/lang/js/jsobj.py pypy/dist/pypy/lang/js/jsparser.py Log: removed some problems with using re's when they were not needed Modified: pypy/dist/pypy/lang/js/interpreter.py ============================================================================== --- pypy/dist/pypy/lang/js/interpreter.py (original) +++ pypy/dist/pypy/lang/js/interpreter.py Mon Feb 5 15:51:51 2007 @@ -671,6 +671,8 @@ ctx.variable.Put(var.name, w_Undefined) for fun in self.func_decl: ctx.variable.Put(fun.name, fun.eval(ctx)) + + node = self try: last = w_Undefined Modified: pypy/dist/pypy/lang/js/jsobj.py ============================================================================== --- pypy/dist/pypy/lang/js/jsobj.py (original) +++ pypy/dist/pypy/lang/js/jsobj.py Mon Feb 5 15:51:51 2007 @@ -129,7 +129,7 @@ if callfunc is not None: self.Scope = ctx.scope[:] else: - self.Scope = [] + self.Scope = None self.Value = Value def Call(self, ctx, args=[], this=None): Modified: pypy/dist/pypy/lang/js/jsparser.py ============================================================================== --- pypy/dist/pypy/lang/js/jsparser.py (original) +++ pypy/dist/pypy/lang/js/jsparser.py Mon Feb 5 15:51:51 2007 @@ -39,8 +39,7 @@ def unquote(t): if isinstance(t, Symbol): if t.symbol == "QUOTED_STRING": - t.additional_info = t.additional_info.strip("'") - t.additional_info = re.sub(r"\\'", r"'", t.additional_info) + t.additional_info = t.additional_info.strip("'").replace("\\'", "'") else: for i in t.children: unquote(i) From santagada at codespeak.net Mon Feb 5 16:40:33 2007 From: santagada at codespeak.net (santagada at codespeak.net) Date: Mon, 5 Feb 2007 16:40:33 +0100 (CET) Subject: [pypy-svn] r37972 - pypy/dist/pypy/lang/js Message-ID: <20070205154033.CBFE91007E@code0.codespeak.net> Author: santagada Date: Mon Feb 5 16:40:13 2007 New Revision: 37972 Modified: pypy/dist/pypy/lang/js/interpreter.py pypy/dist/pypy/lang/js/jsobj.py Log: some changes to make it rpython Modified: pypy/dist/pypy/lang/js/interpreter.py ============================================================================== --- pypy/dist/pypy/lang/js/interpreter.py (original) +++ pypy/dist/pypy/lang/js/interpreter.py Mon Feb 5 16:40:13 2007 @@ -222,7 +222,7 @@ #d = dict(enumerate(self.items)) array = W_Array() for i in range(len(self.list)): - array.Put(str(i), self.list[i]) + array.Put(str(i), self.list[i].eval(ctx).GetValue()) return array Modified: pypy/dist/pypy/lang/js/jsobj.py ============================================================================== --- pypy/dist/pypy/lang/js/jsobj.py (original) +++ pypy/dist/pypy/lang/js/jsobj.py Mon Feb 5 16:40:13 2007 @@ -229,15 +229,15 @@ else: return 'object' - def str_builtin(self, ctx, args, this): - return W_String(self.ToString()) +def str_builtin(ctx, args, this): + return W_String(this.ToString()) class W_Object(W_PrimitiveObject): def __init__(self, ctx=None, Prototype=None, Class='Object', Value=w_Undefined, callfunc=None): W_PrimitiveObject.__init__(self, ctx, Prototype, Class, Value, callfunc) - self.propdict['toString'] = Property('toString', W_Builtin(self.str_builtin)) + self.propdict['toString'] = Property('toString', W_Builtin(str_builtin)) class W_Builtin(W_PrimitiveObject): @@ -280,8 +280,7 @@ def __init__(self, ctx=None, Prototype=None, Class='Array', Value=w_Undefined, callfunc=None): W_PrimitiveObject.__init__(self, ctx, Prototype, Class, Value, callfunc) - toString = W_Builtin() - toString.set_builtin_call(self.str_builtin) + toString = W_Builtin(array_str_builtin) self.Put('toString', toString) self.Put('length', W_Number(0)) self.array = [] @@ -317,12 +316,13 @@ except ValueError: return W_PrimitiveObject.Get(self, P) - def str_builtin(self, ctx, args, this): - return W_String(self.ToString()) - def ToString(self): return ','.join(self.array) +def array_str_builtin(ctx, args, this): + return W_String(this.ToString()) + + class W_Boolean(W_Primitive): def __init__(self, boolval): From cfbolz at codespeak.net Mon Feb 5 17:32:57 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 5 Feb 2007 17:32:57 +0100 (CET) Subject: [pypy-svn] r37975 - in pypy/dist/pypy/tool/build: . test Message-ID: <20070205163257.EA1E81007B@code0.codespeak.net> Author: cfbolz Date: Mon Feb 5 17:32:57 2007 New Revision: 37975 Modified: pypy/dist/pypy/tool/build/buildserver.py pypy/dist/pypy/tool/build/metaserver.py pypy/dist/pypy/tool/build/test/fake.py pypy/dist/pypy/tool/build/test/test_buildserver.py pypy/dist/pypy/tool/build/test/test_metaserver.py Log: tell the requesting client on which server his request is being built Modified: pypy/dist/pypy/tool/build/buildserver.py ============================================================================== --- pypy/dist/pypy/tool/build/buildserver.py (original) +++ pypy/dist/pypy/tool/build/buildserver.py Mon Feb 5 17:32:57 2007 @@ -5,7 +5,8 @@ from pypy.tool.build import build class BuildServer(object): - def __init__(self, channel, sysinfo, testing_sleeptime=False): + def __init__(self, channel, sysinfo, hostname, testing_sleeptime=False): + self.hostname = hostname self.channel = channel self.sysinfo = sysinfo self.busy_on = None @@ -72,7 +73,7 @@ try: try: - bs = BuildServer(channel, %r, %r) + bs = BuildServer(channel, %r, %r, %r) bs.sit_and_wait() except: try: @@ -97,6 +98,7 @@ sysinfo = make_dict(sysconfig) conference = execnetconference.conference(gw, port, False) channel = conference.remote_exec(initcode % (path, sysinfo, + py.std.socket.gethostname(), testing_sleeptime)) return channel Modified: pypy/dist/pypy/tool/build/metaserver.py ============================================================================== --- pypy/dist/pypy/tool/build/metaserver.py (original) +++ pypy/dist/pypy/tool/build/metaserver.py Mon Feb 5 17:32:57 2007 @@ -26,7 +26,7 @@ return True class MetaServer(object): - """ the build server + """ the build meta-server this delegates or queues build requests, and stores results and sends out emails when they're done @@ -88,13 +88,17 @@ return (True, path) for builder in self._builders: if builder.busy_on and request.has_satisfying_data(builder.busy_on): - self._channel.send('build for %s currently in progress' % - (request,)) + self._channel.send( + "build for %s currently in progress on '%s'" % ( + request, builder.hostname)) self._waiting.append(request) - return (False, 'this build is already in progress') + return (False, "this build is already in progress on '%s'" % ( + builder.hostname, )) # we don't have a build for this yet, find a builder to compile it - if self.run(request): - return (False, 'found a suitable build server, going to build') + hostname = self.run(request) + if hostname is not None: + return (False, "found a suitable server, going to build on '%s'" % + (hostname, )) self._queuelock.acquire() try: self._queued.append(request) @@ -117,13 +121,13 @@ else: self._channel.send( 'going to send compile job for request %s to %s' % ( - request, builder + request, builder.hostname ) ) accepted = builder.compile(request) if accepted: self._channel.send('compile job accepted') - return True + return builder.hostname else: self._channel.send('compile job denied') self._channel.send( Modified: pypy/dist/pypy/tool/build/test/fake.py ============================================================================== --- pypy/dist/pypy/tool/build/test/fake.py (original) +++ pypy/dist/pypy/tool/build/test/fake.py Mon Feb 5 17:32:57 2007 @@ -22,6 +22,7 @@ self.sysinfo = info self.busy_on = None self.refused = [] + self.hostname = "fake" def compile(self, request): self.channel.send(request.serialize()) Modified: pypy/dist/pypy/tool/build/test/test_buildserver.py ============================================================================== --- pypy/dist/pypy/tool/build/test/test_buildserver.py (original) +++ pypy/dist/pypy/tool/build/test/test_buildserver.py Mon Feb 5 17:32:57 2007 @@ -24,11 +24,11 @@ pypy.tool.build.metaserver_instance = svr mod.c1c = c1c = FakeChannel() - mod.c1 = c1 = BuildServerForTests(c1c, {'foo': 1, 'bar': [1,2]}) + mod.c1 = c1 = BuildServerForTests(c1c, {'foo': 1, 'bar': [1,2]}, "noname") svr.register(c1) mod.c2c = c2c = FakeChannel() - mod.c2 = c2 = BuildServerForTests(c2c, {'foo': 2, 'bar': [2,3]}) + mod.c2 = c2 = BuildServerForTests(c2c, {'foo': 2, 'bar': [2,3]}, "noname") svr.register(c2) def test_compile(): Modified: pypy/dist/pypy/tool/build/test/test_metaserver.py ============================================================================== --- pypy/dist/pypy/tool/build/test/test_metaserver.py (original) +++ pypy/dist/pypy/tool/build/test/test_metaserver.py Mon Feb 5 17:32:57 2007 @@ -52,7 +52,8 @@ str(repodir), 'HEAD', 0) ret = svr.compile(br) assert not ret[0] - assert ret[1].find('found a suitable build server') > -1 + assert ret[1].find('found a suitable server') > -1 + assert "fake" in ret[1] # hostname ret = svr._channel.receive() assert ret.find('going to send compile job') > -1 acceptedmsg = svr._channel.receive() From cfbolz at codespeak.net Mon Feb 5 20:27:27 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 5 Feb 2007 20:27:27 +0100 (CET) Subject: [pypy-svn] r37977 - pypy/dist/pypy/tool/build Message-ID: <20070205192727.3482A1007C@code0.codespeak.net> Author: cfbolz Date: Mon Feb 5 20:27:25 2007 New Revision: 37977 Modified: pypy/dist/pypy/tool/build/buildserver.py Log: put the whole result into a directory, I hate it when unzipping pollutes your current dir. Modified: pypy/dist/pypy/tool/build/buildserver.py ============================================================================== --- pypy/dist/pypy/tool/build/buildserver.py (original) +++ pypy/dist/pypy/tool/build/buildserver.py Mon Feb 5 20:27:25 2007 @@ -131,7 +131,7 @@ if fpath.ext in ['.o']: continue try: - zip.writestr(fpath.relto(res_dir), fpath.read()) + zip.writestr("pypy-compiled/" + fpath.relto(res_dir), fpath.read()) except (py.error.ENOENT, py.error.EISDIR), exc: print exc continue From cfbolz at codespeak.net Mon Feb 5 20:34:31 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 5 Feb 2007 20:34:31 +0100 (CET) Subject: [pypy-svn] r37978 - pypy/dist/pypy/tool/build/test Message-ID: <20070205193431.2A6DD1007D@code0.codespeak.net> Author: cfbolz Date: Mon Feb 5 20:34:29 2007 New Revision: 37978 Modified: pypy/dist/pypy/tool/build/test/test_buildserver.py Log: oops, change the test too Modified: pypy/dist/pypy/tool/build/test/test_buildserver.py ============================================================================== --- pypy/dist/pypy/tool/build/test/test_buildserver.py (original) +++ pypy/dist/pypy/tool/build/test/test_buildserver.py Mon Feb 5 20:34:29 2007 @@ -93,10 +93,10 @@ zip.seek(0) zf = ZipFile(zip) - data = zf.read('foo/bar.txt') + data = zf.read('pypy-compiled/foo/bar.txt') assert data == 'bar' - py.test.raises(KeyError, 'zf.read("foo/bar.o")') + py.test.raises(KeyError, 'zf.read("pypy-compiled/foo/bar.o")') def test_tempdir(): parent = py.test.ensuretemp('tempdir') From cfbolz at codespeak.net Mon Feb 5 20:42:20 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 5 Feb 2007 20:42:20 +0100 (CET) Subject: [pypy-svn] r37979 - pypy/dist/pypy/tool/build Message-ID: <20070205194220.7F7FB1007D@code0.codespeak.net> Author: cfbolz Date: Mon Feb 5 20:42:19 2007 New Revision: 37979 Modified: pypy/dist/pypy/tool/build/buildserver.py Log: brilliant idea: actually tell the zip-file to _compress_! Modified: pypy/dist/pypy/tool/build/buildserver.py ============================================================================== --- pypy/dist/pypy/tool/build/buildserver.py (original) +++ pypy/dist/pypy/tool/build/buildserver.py Mon Feb 5 20:42:19 2007 @@ -1,6 +1,6 @@ import py import thread -from zipfile import ZipFile +from zipfile import ZipFile, ZIP_DEFLATED from cStringIO import StringIO from pypy.tool.build import build @@ -126,7 +126,7 @@ pass def zip_dir(res_dir, tofile): - zip = ZipFile(tofile, 'w') + zip = ZipFile(tofile, 'w', ZIP_DEFLATED) for fpath in res_dir.visit(): if fpath.ext in ['.o']: continue From cfbolz at codespeak.net Mon Feb 5 21:25:28 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 5 Feb 2007 21:25:28 +0100 (CET) Subject: [pypy-svn] r37980 - in pypy/dist/pypy/tool/build: . test Message-ID: <20070205202528.9E17710078@code0.codespeak.net> Author: cfbolz Date: Mon Feb 5 21:25:24 2007 New Revision: 37980 Added: pypy/dist/pypy/tool/build/test/__init__.py Modified: pypy/dist/pypy/tool/build/build.py pypy/dist/pypy/tool/build/test/fake.py pypy/dist/pypy/tool/build/test/test_build.py pypy/dist/pypy/tool/build/test/test_buildserver.py pypy/dist/pypy/tool/build/test/test_metaserver.py pypy/dist/pypy/tool/build/test/test_pypybuilder.py Log: rename FakeClient to FakeBuildserver to be consistent with the rest of the terminology. clean up imports a bit, pypy tries to not use relative imports. Modified: pypy/dist/pypy/tool/build/build.py ============================================================================== --- pypy/dist/pypy/tool/build/build.py (original) +++ pypy/dist/pypy/tool/build/build.py Mon Feb 5 21:25:24 2007 @@ -122,7 +122,7 @@ self.svnrev, self.revrange) def serialize(self): - data = {'normalized_rev': self.normalized_rev} + data = {'normalized_rev': self.normalized_rev} # it's a property data.update(self.__dict__) return """\ email: %(email)s Added: pypy/dist/pypy/tool/build/test/__init__.py ============================================================================== Modified: pypy/dist/pypy/tool/build/test/fake.py ============================================================================== --- pypy/dist/pypy/tool/build/test/fake.py (original) +++ pypy/dist/pypy/tool/build/test/fake.py Mon Feb 5 21:25:24 2007 @@ -16,7 +16,7 @@ def waitclose(self): pass -class FakeClient(object): +class FakeBuildserver(object): def __init__(self, info): self.channel = FakeChannel() self.sysinfo = info Modified: pypy/dist/pypy/tool/build/test/test_build.py ============================================================================== --- pypy/dist/pypy/tool/build/test/test_build.py (original) +++ pypy/dist/pypy/tool/build/test/test_build.py Mon Feb 5 21:25:24 2007 @@ -1,8 +1,8 @@ import py -from pypy.tool.build import build from py.__.misc.cache import AgingCache from py.__.path.svn import urlcommand -from repo import create_temp_repo +from pypy.tool.build import build +from pypy.tool.build.test.repo import create_temp_repo def setup_module(mod): # remove nasty cache from py.path.svnurl to allow this to work... Modified: pypy/dist/pypy/tool/build/test/test_buildserver.py ============================================================================== --- pypy/dist/pypy/tool/build/test/test_buildserver.py (original) +++ pypy/dist/pypy/tool/build/test/test_buildserver.py Mon Feb 5 21:25:24 2007 @@ -1,12 +1,13 @@ -import path -from pypy.tool.build import buildserver -from pypy.tool.build import build import py -import time +import path import sys -from zipfile import ZipFile from StringIO import StringIO -from fake import FakeChannel, FakeMetaServer +import time +from zipfile import ZipFile + +from pypy.tool.build import buildserver +from pypy.tool.build import build +from pypy.tool.build.test.fake import FakeChannel, FakeMetaServer class BuildServerForTests(buildserver.BuildServer): def __init__(self, *args, **kwargs): Modified: pypy/dist/pypy/tool/build/test/test_metaserver.py ============================================================================== --- pypy/dist/pypy/tool/build/test/test_metaserver.py (original) +++ pypy/dist/pypy/tool/build/test/test_metaserver.py Mon Feb 5 21:25:24 2007 @@ -1,10 +1,11 @@ +import py import path +import time + from pypy.tool.build import metaserver -import py -from fake import FakeChannel, FakeClient, Container +from pypy.tool.build.test.fake import FakeChannel, FakeBuildserver, Container from pypy.tool.build import build -import time -from repo import create_temp_repo +from pypy.tool.build.test.repo import create_temp_repo def setup_module(mod): mod.temppath = temppath = py.test.ensuretemp('pypybuilder-server') @@ -12,10 +13,10 @@ mailhost=None) mod.svr = metaserver.MetaServer(config, FakeChannel()) - mod.c1 = FakeClient({'foo': 1, 'bar': [1,2]}) + mod.c1 = FakeBuildserver({'foo': 1, 'bar': [1,2]}) mod.svr.register(mod.c1) - mod.c2 = FakeClient({'foo': 2, 'bar': [2,3]}) + mod.c2 = FakeBuildserver({'foo': 2, 'bar': [2,3]}) mod.svr.register(mod.c2) def test_server_issubdict(): Modified: pypy/dist/pypy/tool/build/test/test_pypybuilder.py ============================================================================== --- pypy/dist/pypy/tool/build/test/test_pypybuilder.py (original) +++ pypy/dist/pypy/tool/build/test/test_pypybuilder.py Mon Feb 5 21:25:24 2007 @@ -11,8 +11,8 @@ from pypy.tool.build.conftest import option from pypy.config import config as pypyconfig -from repo import create_temp_repo -from fake import Container +from pypy.tool.build.test.repo import create_temp_repo +from pypy.tool.build.test.fake import Container # XXX this one is a bit messy, it's a quick functional test for the whole # system, but for instance contains time.sleep()s to make sure all threads From cfbolz at codespeak.net Mon Feb 5 21:50:02 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 5 Feb 2007 21:50:02 +0100 (CET) Subject: [pypy-svn] r37981 - in pypy/dist/pypy: config module/__builtin__ objspace/std objspace/std/test Message-ID: <20070205205002.8FD7F10078@code0.codespeak.net> Author: cfbolz Date: Mon Feb 5 21:49:56 2007 New Revision: 37981 Added: pypy/dist/pypy/objspace/std/listmultiobject.py pypy/dist/pypy/objspace/std/test/test_listmultiobject.py Modified: pypy/dist/pypy/config/pypyoption.py pypy/dist/pypy/module/__builtin__/functional.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/test/test_listobject.py Log: weekend project: implement multilists similar to multidicts. re-implement rangelist using them and add a string-list implementation that saves the unwrapped strings. Also have a special slice implementation, that makes list slicing a cheap operation as long as the list and the slice are not mutated. Modified: pypy/dist/pypy/config/pypyoption.py ============================================================================== --- pypy/dist/pypy/config/pypyoption.py (original) +++ pypy/dist/pypy/config/pypyoption.py Mon Feb 5 21:49:56 2007 @@ -170,6 +170,16 @@ IntOption("methodcachesize", "size of the method cache (should be a power of 2)", default=2048), + BoolOption("withmultilist", + "use lists optimized for flexibility", + default=False, + requires=[("objspace.std.withrangelist", False), + ("objspace.name", "std"), + ("objspace.std.withtproxy", False)]), + BoolOption("withfastslice", + "make list slicing lazy", + default=False, + requires=[("objspace.std.withmultilist", True)]), BoolOption("optimized_int_add", "special case the addition of two integers in BINARY_ADD", default=False), Modified: pypy/dist/pypy/module/__builtin__/functional.py ============================================================================== --- pypy/dist/pypy/module/__builtin__/functional.py (original) +++ pypy/dist/pypy/module/__builtin__/functional.py Mon Feb 5 21:49:56 2007 @@ -69,8 +69,9 @@ get a list in decending order.""" if (space.config.objspace.name == "std" and - space.config.objspace.std.withrangelist): - return range_withrangelist(space, w_x, w_y, w_step) + (space.config.objspace.std.withmultilist or + space.config.objspace.std.withrangelist)): + return range_withspecialized_implementation(space, w_x, w_y, w_step) try: # save duplication by redirecting every error to applevel x = space.int_w(w_x) @@ -96,11 +97,9 @@ range_fallback = applevel(getsource(app_range), getfile(app_range) ).interphook('range') -def range_withrangelist(space, w_x, w_y, w_step): +def range_withspecialized_implementation(space, w_x, w_y, w_step): # XXX object space dependant - from pypy.objspace.std.rangeobject import W_RangeListObject try: - # save duplication by redirecting every error to applevel x = space.int_w(w_x) if space.is_w(w_y, space.w_None): start, stop = 0, x @@ -110,5 +109,12 @@ howmany = get_len_of_range(start, stop, step) except (OperationError, ValueError, OverflowError): return range_fallback(space, w_x, w_y, w_step) - return W_RangeListObject(start, step, howmany) + if space.config.objspace.std.withrangelist: + from pypy.objspace.std.rangeobject import W_RangeListObject + return W_RangeListObject(start, step, howmany) + if space.config.objspace.std.withmultilist: + from pypy.objspace.std.listmultiobject import W_ListMultiObject + from pypy.objspace.std.listmultiobject import RangeImplementation + impl = RangeImplementation(space, start, step, howmany) + return W_ListMultiObject(space, impl) Added: pypy/dist/pypy/objspace/std/listmultiobject.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/objspace/std/listmultiobject.py Mon Feb 5 21:49:56 2007 @@ -0,0 +1,1192 @@ +from pypy.objspace.std.objspace import * +from pypy.objspace.std.inttype import wrapint +from pypy.objspace.std.sliceobject import W_SliceObject +from pypy.objspace.std.tupleobject import W_TupleObject +from pypy.objspace.std.stringobject import W_StringObject + +from pypy.objspace.std import slicetype +from pypy.interpreter import gateway, baseobjspace +from pypy.rlib.listsort import TimSort + + +class ListImplementation(object): + + def __init__(self, space): + self.space = space + +# A list implementation should implement the following methods: + +## def length(self): +## pass + +## def getitem(self, i): +## pass + +## def getitem_slice(self, start, stop): +## pass + + +# the following operations return the list implementation that should +# be used after the call +# If it turns out that the list implementation cannot really perform +# the operation it can return None for the following ones: + + def setitem(self, i, w_item): + pass + + def insert(self, i, w_item): + pass + + def delitem(self, index): + pass + + def delitem_slice(self, start, stop): + pass + + def append(self, w_item): + pass + + def extend(self, other): + pass + + +# special cases: + + def add(self, other): + pass + +## def get_list_w(self): +## pass + +# default implementations, can (but don't have to be) overridden: + + def reverse(self): + l = self.length() + for i in range(l // 2): + x = self.getitem(i) + y = self.getitem(l - i - 1) + self = self.i_setitem(i, y) + self = self.i_setitem(l - i - 1, x) + return self + + + def getitem_slice_step(self, start, stop, step, slicelength): + res_w = [None] * slicelength + for i in range(slicelength): + res_w[i] = self.getitem(start) + start += step + return RListImplementation(self.space, res_w) + + def delitem_slice_step(self, start, stop, step, slicelength): + n = self.length() + + recycle = [None] * slicelength + i = start + + # keep a reference to the objects to be removed, + # preventing side effects during destruction + recycle[0] = self.getitem(i) + + for discard in range(1, slicelength): + j = i+1 + i += step + while j < i: + self = self.i_setitem(j - discard, self.getitem(j)) + j += 1 + recycle[discard] = self.getitem(i) + + j = i+1 + while j < n: + self = self.i_setitem(j-slicelength, self.getitem(j)) + j += 1 + start = n - slicelength + assert start >= 0 # annotator hint + self = self.i_delitem_slice(start, n) + return self + + def mul(self, times): + return make_implementation(self.space, self.get_list_w() * times) + + def copy(self): + return self.getitem_slice(0, self.length()) + + def to_rlist(self): + list_w = self.get_list_w() + return RListImplementation(self.space, list_w) + + # interface used by W_ListMultiObject: + + def i_setitem(self, i, w_item): + impl = self.setitem(i, w_item) + if impl is None: # failed to implement + list_w = self.get_list_w() + assert i >= 0 and i < len(list_w) + list_w[i] = w_item + return self.make_implementation(list_w) + return impl + + def i_insert(self, i, w_item): + impl = self.insert(i, w_item) + if impl is None: # failed to implement + list_w = self.get_list_w() + assert i >= 0 and i <= len(list_w) + list_w.insert(i, w_item) + return self.make_implementation(list_w) + return impl + + def i_append(self, w_item): + impl = self.append(w_item) + if impl is None: # failed to implement + list_w = self.get_list_w() + list_w.append(w_item) + return self.make_implementation(list_w) + return impl + + def i_add(self, other): + impl = self.add(other) + if impl is None: + list_w1 = self.get_list_w() + list_w2 = other.get_list_w() + return self.make_implementation(list_w1 + list_w2) + return impl + + def i_extend(self, other): + impl = self.extend(other) + if impl is None: + list_w1 = self.get_list_w() + list_w2 = other.get_list_w() + return self.make_implementation(list_w1 + list_w2) + return impl + + def i_delitem(self, i): + impl = self.delitem(i) + if impl is None: + list_w = self.get_list_w() + del list_w[i] + return self.make_implementation(list_w) + return impl + + def i_delitem_slice(self, start, stop): + impl = self.delitem_slice(start, stop) + if impl is None: + list_w = self.get_list_w() + assert 0 <= start < len(list_w) + assert 0 <= stop <= len(list_w) + del list_w[start:stop] + return self.make_implementation(list_w) + return impl + + def make_implementation(self, list_w): + space = self.space + if space.config.objspace.std.withfastslice: + return SliceTrackingListImplementation(space, list_w) + else: + return RListImplementation(space, list_w) + + +class RListImplementation(ListImplementation): + def __init__(self, space, list_w): + ListImplementation.__init__(self, space) + self.list_w = list_w + + def length(self): + return len(self.list_w) + + def getitem(self, i): + return self.list_w[i] + + def getitem_slice(self, start, stop): + assert start >= 0 + assert stop >= 0 and stop <= len(self.list_w) + return RListImplementation(self.space, self.list_w[start:stop]) + + def delitem(self, i): + assert i >= 0 and i < len(self.list_w) + if len(self.list_w) == 1: + return self.space.fromcache(State).empty_impl + del self.list_w[i] + return self + + def delitem_slice(self, start, stop): + assert start >= 0 + assert stop >= 0 and stop <= len(self.list_w) + if len(self.list_w) == stop and start == 0: + return self.space.fromcache(State).empty_impl + del self.list_w[start:stop] + return self + + def setitem(self, i, w_item): + assert i >= 0 and i < len(self.list_w) + self.list_w[i] = w_item + return self + + def insert(self, i, w_item): + assert i >= 0 and i <= len(self.list_w) + self.list_w.insert(i, w_item) + return self + + def add(self, other): + return RListImplementation( + self.space, self.list_w + other.get_list_w()) + + def append(self, w_item): + self.list_w.append(w_item) + return self + + def extend(self, other): + self.list_w.extend(other.get_list_w()) + return self + + def reverse(self): + self.list_w.reverse() + return self + + def get_list_w(self): + return self.list_w + + def to_rlist(self): + return self + + def __repr__(self): + return "RListImplementation(%s)" % (self.list_w, ) + +class EmptyListImplementation(ListImplementation): + def make_impl(self, w_item): + space = self.space + if space.config.objspace.std.withfastslice: + return SliceTrackingListImplementation(space, [w_item]) + w_type = space.type(w_item) + if space.is_w(w_type, space.w_str): + strlist = [space.str_w(w_item)] + return StrListImplementation(space, strlist) + return RListImplementation(space, [w_item]) + + def length(self): + return 0 + + def getitem(self, i): + raise IndexError + + def getitem_slice(self, start, stop): + if start == 0 and stop == 0: + return self + raise IndexError + + def delitem(self, index): + raise IndexError + + def delitem_slice(self, start, stop): + if start == 0 and stop == 0: + return self + raise IndexError + + def setitem(self, i, w_item): + raise IndexError + + def insert(self, i, w_item): + return self.make_impl(w_item) + + def add(self, other): + return other.copy() + + def append(self, w_item): + return self.make_impl(w_item) + + def extend(self, other): + return other.copy() + + def reverse(self): + return self + + def get_list_w(self): + return [] + + def copy(self): + return self + + def mul(self, times): + return self + + def __repr__(self): + return "EmptyListImplementation()" + +class StrListImplementation(ListImplementation): + def __init__(self, space, strlist): + self.strlist = strlist + ListImplementation.__init__(self, space) + + def length(self): + return len(self.strlist) + + def getitem(self, i): + assert 0 <= i < len(self.strlist) + return self.space.wrap(self.strlist[i]) + + def getitem_slice(self, start, stop): + assert 0 <= start < len(self.strlist) + assert 0 <= stop <= len(self.strlist) + return StrListImplementation(self.space, self.strlist[start:stop]) + + def getitem_slice_step(self, start, stop, step, slicelength): + assert 0 <= start < len(self.strlist) + assert 0 <= stop < len(self.strlist) + assert slicelength > 0 + res = [0] * slicelength + for i in range(slicelength): + res[i] = self.strlist[start] + start += step + return StrListImplementation(self.space, res) + + def delitem(self, index): + assert 0 <= i < len(self.strlist) + if len(self.strlist) == 1: + return self.space.fromcache(State).empty_impl + del self.strlist[index] + return self + + def delitem_slice(self, start, stop): + assert 0 <= start < len(self.strlist) + assert 0 <= stop < len(self.strlist) + if len(self.strlist) == stop and start == 0: + return self.space.fromcache(State).empty_impl + del self.strlist[start:stop] + return self + + def setitem(self, i, w_item): + assert 0 <= i < len(self.strlist) + if self.space.is_w(self.space.type(w_item), self.space.w_str): + self.strlist[i] = self.space.str_w(w_item) + return self + return None + + def insert(self, i, w_item): + assert 0 <= i <= len(self.strlist) + if self.space.is_w(self.space.type(w_item), self.space.w_str): + self.strlist.insert(i, self.space.str_w(w_item)) + return self + return None + + def add(self, other): + if isinstance(other, StrListImplementation): + return StrListImplementation( + self.space, self.strlist + other.strlist) + + def append(self, w_item): + if self.space.is_w(self.space.type(w_item), self.space.w_str): + self.strlist.append(self.space.str_w(w_item)) + return self + return None + + def extend(self, other): + if isinstance(other, StrListImplementation): + self.strlist.extend(other.strlist) + return self + + def reverse(self): + self.strlist.reverse() + return self + + def get_list_w(self): + return [self.space.wrap(i) for i in self.strlist] + + def __repr__(self): + return "StrListImplementation(%s)" % (self.strlist, ) + + +class RangeImplementation(ListImplementation): + def __init__(self, space, start, step, length): + ListImplementation.__init__(self, space) + self.start = start + self.step = step + self.len = length + + def length(self): + return self.len + + def getitem_w(self, i): + assert 0 <= i < self.len + return self.start + i * self.step + + def getitem(self, i): + return wrapint(self.space, self.getitem_w(i)) + + def getitem_slice(self, start, stop): + rangestart = self.getitem_w(start) + return RangeImplementation( + self.space, rangestart, self.step, stop - start) + + def getitem_slice_step(self, start, stop, step, slicelength): + rangestart = self.getitem_w(start) + rangestep = self.step * step + return RangeImplementation( + self.space, rangestart, rangestep, slicelength) + + def delitem(self, index): + if index == 0: + self.start = self.getitem_w(1) + self.len -= 1 + return self + if index == self.len - 1: + self.len -= 1 + return self + return None + + def delitem_slice(self, start, stop): + if start == 0: + if stop == self.len: + return self.space.fromcache(State).empty_impl + self.start = self.getitem_w(stop) + self.len -= stop + return self + if stop == self.len: + self.len = start + return self + return None + + def reverse(self): + self.start = self.getitem_w(self.len - 1) + self.step = -self.step + return self + + def get_list_w(self): + start = self.start + step = self.step + length = self.len + if not length: + return [] + + list_w = [None] * length + + i = start + n = 0 + while n < length: + list_w[n] = wrapint(self.space, i) + i += step + n += 1 + + return list_w + + def __repr__(self): + return "RangeImplementation(%s, %s, %s)" % ( + self.start, self.len, self.step) + + +class SliceTrackingListImplementation(RListImplementation): + def __init__(self, space, list_w): + RListImplementation.__init__(self, space, list_w) + self.slices = [] + + def getitem_slice(self, start, stop): + assert start >= 0 + assert stop >= 0 and stop <= len(self.list_w) + # just do this for slices of a certain length + if stop - start > 5: + index = len(self.slices) + sliceimpl = SliceListImplementation( + self.space, self, index, start, stop) + self.slices.append(sliceimpl) + return sliceimpl + else: + return self.getitem_true_slice(start, stop) + + def getitem_true_slice(self, start, stop): + assert start >= 0 + assert stop >= 0 and stop <= len(self.list_w) + return SliceTrackingListImplementation( + self.space, self.list_w[start:stop]) + + def getitem_slice_step(self, start, stop, step, slicelength): + res_w = [None] * slicelength + for i in range(slicelength): + res_w[i] = self.getitem(start) + start += step + return SliceTrackingListImplementation(self.space, res_w) + + def delitem(self, index): + assert 0 <= index < len(self.list_w) + if len(self.list_w) == 1: + return self.space.fromcache(State).empty_impl + self.changed() + del self.list_w[index] + return self + + def delitem_slice(self, start, stop): + assert start >= 0 + assert stop >= 0 and stop <= len(self.list_w) + if start == 0 and len(self.list_w) == stop: + return self.space.fromcache(State).empty_impl + self.changed() + del self.list_w[start:stop] + return self + + def setitem(self, i, w_item): + self.changed() + assert 0 <= i < len(self.list_w) + self.list_w[i] = w_item + return self + + def insert(self, i, w_item): + assert 0 <= i <= len(self.list_w) + if i == len(self.list_w): + return self.append(w_item) + self.changed() + self.list_w.insert(i, w_item) + return self + + def add(self, other): + if isinstance(other, SliceTrackingListImplementation): + return SliceTrackingListImplementation( + self.space, self.list_w + other.list_w) + return SliceTrackingListImplementation( + self.space, self.list_w + other.get_list_w()) + + # append and extend need not be overridden from RListImplementation.__init__ + # they change the list but cannot affect slices taken so far + + def reverse(self): + # could be optimised: the slices grow steps and their + # step is reversed :-) + self.changed() + self.list_w.reverse() + return self + + def to_rlist(self): + return RListImplementation(self.space, self.list_w) + + def changed(self): + if not self.slices: + return + self.notify_slices() + + def notify_slices(self): + for slice in self.slices: + if slice is not None: + slice.detach() + self.slices = [] + + def unregister_slice(self, index): + self.slices[index] = None + + def __repr__(self): + return "SliceTrackingListImplementation(%s, <%s slice(s)>)" % ( + self.list_w, len(self.slices)) + +class SliceListImplementation(ListImplementation): + def __init__(self, space, listimpl, index, start, stop): + assert 0 <= start < listimpl.length() + assert 0 <= stop <= listimpl.length() + ListImplementation.__init__(self, space) + self.listimpl = listimpl + self.index = index + self.start = start + self.stop = stop + self.len = stop - start + self.detached_impl = None + + def detach(self): + if self.detached_impl is None: + self.detached_impl = self.listimpl.getitem_true_slice( + self.start, self.stop) + self.listimpl = None # loose the reference + + def detach_and_unregister(self): + if self.detached_impl is None: + self.listimpl.unregister_slice(self.index) + self.detach() + + def length(self): + if self.detached_impl is not None: + return self.detached_impl.length() + return self.len + + def getitem(self, i): + if self.detached_impl is not None: + return self.detached_impl.getitem(i) + return self.listimpl.getitem(self.start + i) + + def getitem_slice(self, start, stop): + assert start >= 0 + assert stop >= 0 + if self.detached_impl is not None: + return self.detached_impl.getitem_slice(start, stop) + return self.listimpl.getitem_slice( + self.start + start, self.start + stop) + + def delitem(self, index): + self.detach_and_unregister() + return self.detached_impl.delitem(index) + + def delitem_slice(self, start, stop): + self.detach_and_unregister() + if start == 0 and self.len == stop: + return self.space.fromcache(State).empty_impl + return self.detached_impl.delitem_slice(start, stop) + + def setitem(self, i, w_item): + self.detach_and_unregister() + return self.detached_impl.setitem(i, w_item) + + def insert(self, i, w_item): + self.detach_and_unregister() + return self.detached_impl.insert(i, w_item) + + def add(self, other): + self.detach_and_unregister() + return self.detached_impl.add(other) + + def append(self, w_item): + self.detach_and_unregister() + return self.detached_impl.append(w_item) + + def extend(self, other): + self.detach_and_unregister() + return self.detached_impl.extend(other) + + def reverse(self): + self.detach_and_unregister() + return self.detached_impl.reverse() + + def get_list_w(self): + self.detach_and_unregister() + return self.detached_impl.get_list_w() + + def __repr__(self): + if self.detached_impl is not None: + return "SliceListImplementation(%s)" % (self.detached_impl, ) + return "SliceListImplementation(%s, %s, %s)" % ( + self.listimpl, self.start, self.stop) + + +def is_homogeneous(space, list_w, w_type): + for i in range(len(list_w)): + if not space.is_w(w_type, space.type(list_w[i])): + return False + return True + +def make_implementation(space, list_w): + if list_w: + if space.config.objspace.std.withfastslice: + impl = SliceTrackingListImplementation(space, list_w) + else: + w_type = space.type(list_w[0]) + if (space.is_w(w_type, space.w_str) and + is_homogeneous(space, list_w, w_type)): + strlist = [space.str_w(w_i) for w_i in list_w] + impl = StrListImplementation(space, strlist) + else: + impl = RListImplementation(space, list_w) + else: + impl = space.fromcache(State).empty_impl + return impl + +def convert_list_w(space, list_w): + impl = make_implementation(space, list_w) + return W_ListMultiObject(space, impl) + + +class W_ListMultiObject(W_Object): + from pypy.objspace.std.listtype import list_typedef as typedef + + def __init__(w_self, space, implementation=None): + if implementation is None: + implementation = space.fromcache(State).empty_impl + w_self.implementation = implementation + + def __repr__(w_self): + """ representation for debugging purposes """ + return "%s(%s)" % (w_self.__class__.__name__, w_self.implementation) + + def unwrap(w_list, space): + items = [space.unwrap(w_item) + for w_item in w_list.implementation.get_list_w()] + return items + +registerimplementation(W_ListMultiObject) + +class State(object): + def __init__(self, space): + self.empty_impl = EmptyListImplementation(space) + self.empty_list = W_ListMultiObject(space, self.empty_impl) + + +def _adjust_index(space, index, length, indexerrormsg): + if index < 0: + index += length + if index < 0 or index >= length: + raise OperationError(space.w_IndexError, + space.wrap(indexerrormsg)) + return index + + +def init__ListMulti(space, w_list, __args__): + EMPTY_LIST = space.fromcache(State).empty_list + w_iterable, = __args__.parse('list', + (['sequence'], None, None), # signature + [EMPTY_LIST]) # default argument + if w_iterable is not EMPTY_LIST: + list_w = space.unpackiterable(w_iterable) + if list_w: + w_list.implementation = RListImplementation(space, list_w) + return + w_list.implementation = space.fromcache(State).empty_impl + +def len__ListMulti(space, w_list): + result = w_list.implementation.length() + return wrapint(space, result) + +def getitem__ListMulti_ANY(space, w_list, w_index): + idx = space.int_w(w_index) + idx = _adjust_index(space, idx, w_list.implementation.length(), + "list index out of range") + return w_list.implementation.getitem(idx) + +def getitem__ListMulti_Slice(space, w_list, w_slice): + length = w_list.implementation.length() + start, stop, step, slicelength = w_slice.indices4(space, length) + assert slicelength >= 0 + if step == 1 and 0 <= start <= stop: + return W_ListMultiObject( + space, + w_list.implementation.getitem_slice(start, stop)) + return W_ListMultiObject( + space, + w_list.implementation.getitem_slice_step( + start, stop, step, slicelength)) + +def contains__ListMulti_ANY(space, w_list, w_obj): + # needs to be safe against eq_w() mutating the w_list behind our back + i = 0 + impl = w_list.implementation + while i < impl.length(): # intentionally always calling len! + if space.eq_w(impl.getitem(i), w_obj): + return space.w_True + i += 1 + return space.w_False + +def iter__ListMulti(space, w_list): + from pypy.objspace.std import iterobject + return iterobject.W_SeqIterObject(w_list) + +def add__ListMulti_ListMulti(space, w_list1, w_list2): + impl = w_list1.implementation.i_add(w_list2.implementation) + return W_ListMultiObject(space, impl) + +def inplace_add__ListMulti_ANY(space, w_list1, w_iterable2): + list_extend__ListMulti_ANY(space, w_list1, w_iterable2) + return w_list1 + +def inplace_add__ListMulti_ListMulti(space, w_list1, w_list2): + list_extend__ListMulti_ListMulti(space, w_list1, w_list2) + return w_list1 + +def mul_list_times(space, w_list, w_times): + try: + times = space.int_w(w_times) + except OperationError, e: + if e.match(space, space.w_TypeError): + raise FailedToImplement + raise + return W_ListMultiObject(space, w_list.implementation.mul(times)) + +def mul__ListMulti_ANY(space, w_list, w_times): + return mul_list_times(space, w_list, w_times) + +def mul__ANY_ListMulti(space, w_times, w_list): + return mul_list_times(space, w_list, w_times) + +def inplace_mul__ListMulti_ANY(space, w_list, w_times): + try: + times = space.int_w(w_times) + except OperationError, e: + if e.match(space, space.w_TypeError): + raise FailedToImplement + raise + # XXX could be more efficient? + w_list.implementation = w_list.implementation.mul(times) + return w_list + +def eq__ListMulti_ListMulti(space, w_list1, w_list2): + # needs to be safe against eq_w() mutating the w_lists behind our back + impl1 = w_list1.implementation + impl2 = w_list2.implementation + return equal_impls(space, impl1, impl2) + +def equal_impls(space, impl1, impl2): + if impl1.length() != impl2.length(): + return space.w_False + i = 0 + while i < impl1.length() and i < impl2.length(): + if not space.eq_w(impl1.getitem(i), impl2.getitem(i)): + return space.w_False + i += 1 + return space.w_True + +def _min(a, b): + if a < b: + return a + return b + +def lessthan_impls(space, impl1, impl2): + # needs to be safe against eq_w() mutating the w_lists behind our back + # Search for the first index where items are different + i = 0 + while i < impl1.length() and i < impl2.length(): + w_item1 = impl1.getitem(i) + w_item2 = impl2.getitem(i) + if not space.eq_w(w_item1, w_item2): + return space.lt(w_item1, w_item2) + i += 1 + # No more items to compare -- compare sizes + return space.newbool(impl1.length() < impl2.length()) + +def greaterthan_impls(space, impl1, impl2): + # needs to be safe against eq_w() mutating the w_lists behind our back + # Search for the first index where items are different + i = 0 + while i < impl1.length() and i < impl2.length(): + w_item1 = impl1.getitem(i) + w_item2 = impl2.getitem(i) + if not space.eq_w(w_item1, w_item2): + return space.gt(w_item1, w_item2) + i += 1 + # No more items to compare -- compare sizes + return space.newbool(impl1.length() > impl2.length()) + +def lt__ListMulti_ListMulti(space, w_list1, w_list2): + return lessthan_impls(space, w_list1.implementation, + w_list2.implementation) + +def gt__ListMulti_ListMulti(space, w_list1, w_list2): + return greaterthan_impls(space, w_list1.implementation, + w_list2.implementation) + +def delitem__ListMulti_ANY(space, w_list, w_idx): + idx = space.int_w(w_idx) + length = w_list.implementation.length() + idx = _adjust_index(space, idx, length, "list deletion index out of range") + w_list.implementation = w_list.implementation.i_delitem(idx) + return space.w_None + +def delitem__ListMulti_Slice(space, w_list, w_slice): + start, stop, step, slicelength = w_slice.indices4( + space, w_list.implementation.length()) + + if slicelength==0: + return + + if step < 0: + start = start + step * (slicelength-1) + step = -step + # stop is invalid + + if step == 1: + _del_slice(w_list, start, start+slicelength) + else: + w_list.implementation = w_list.implementation.delitem_slice_step( + start, start + slicelength, step, slicelength) + + return space.w_None + +def setitem__ListMulti_ANY_ANY(space, w_list, w_index, w_any): + idx = space.int_w(w_index) + idx = _adjust_index(space, idx, w_list.implementation.length(), + "list index out of range") + w_list.implementation = w_list.implementation.i_setitem(idx, w_any) + return space.w_None + +def setitem__ListMulti_Slice_ListMulti(space, w_list, w_slice, w_list2): + impl = w_list2.implementation + return _setitem_slice_helper(space, w_list, w_slice, impl) + +def setitem__ListMulti_Slice_ANY(space, w_list, w_slice, w_iterable): + l = RListImplementation(space, space.unpackiterable(w_iterable)) + return _setitem_slice_helper(space, w_list, w_slice, l) + +def _setitem_slice_helper(space, w_list, w_slice, impl2): + impl = w_list.implementation + oldsize = impl.length() + len2 = impl2.length() + start, stop, step, slicelength = w_slice.indices4(space, oldsize) + assert slicelength >= 0 + + if step == 1: # Support list resizing for non-extended slices + delta = len2 - slicelength + if delta >= 0: + newsize = oldsize + delta + impl = impl.i_extend( + RListImplementation(space, [space.w_None] * delta)) + lim = start + len2 + i = newsize - 1 + while i >= lim: + impl = impl.i_setitem(i, impl.getitem(i-delta)) + i -= 1 + else: + # shrinking requires the careful memory management of _del_slice() + _del_slice(w_list, start, start-delta) + elif len2 != slicelength: # No resize for extended slices + raise OperationError(space.w_ValueError, space.wrap("attempt to " + "assign sequence of size %d to extended slice of size %d" % + (len2,slicelength))) + + if impl2 is impl: + if step > 0: + # Always copy starting from the right to avoid + # having to make a shallow copy in the case where + # the source and destination lists are the same list. + i = len2 - 1 + start += i*step + while i >= 0: + impl = impl.i_setitem(start, impl2.getitem(i)) + start -= step + i -= 1 + return space.w_None + else: + # Make a shallow copy to more easily handle the reversal case + impl2 = impl2.getitem_slice(0, impl2.length()) + for i in range(len2): + impl = impl.i_setitem(start, impl2.getitem(i)) + start += step + w_list.implementation = impl + return space.w_None + +app = gateway.applevel(""" + def listrepr(currently_in_repr, l): + 'The app-level part of repr().' + list_id = id(l) + if list_id in currently_in_repr: + return '[...]' + currently_in_repr[list_id] = 1 + try: + return "[" + ", ".join([repr(x) for x in l]) + ']' + finally: + try: + del currently_in_repr[list_id] + except: + pass +""", filename=__file__) + +listrepr = app.interphook("listrepr") + +def repr__ListMulti(space, w_list): + if w_list.implementation.length() == 0: + return space.wrap('[]') + w_currently_in_repr = space.getexecutioncontext()._py_repr + return listrepr(space, w_currently_in_repr, w_list) + +def list_insert__ListMulti_ANY_ANY(space, w_list, w_where, w_any): + where = space.int_w(w_where) + length = w_list.implementation.length() + if where < 0: + where += length + if where < 0: + where = 0 + elif where > length: + where = length + w_list.implementation = w_list.implementation.i_insert(where, w_any) + return space.w_None + +def list_append__ListMulti_ANY(space, w_list, w_any): + w_list.implementation = w_list.implementation.i_append(w_any) + return space.w_None + +def list_extend__ListMulti_ListMulti(space, w_list, w_list2): + impl2 = w_list2.implementation + w_list.implementation = w_list.implementation.i_extend(impl2) + return space.w_None + +def list_extend__ListMulti_ANY(space, w_list, w_any): + list_w2 = space.unpackiterable(w_any) + impl2 = RListImplementation(space, list_w2) + w_list.implementation = w_list.implementation.i_extend(impl2) + return space.w_None + +def _del_slice(w_list, ilow, ihigh): + """ similar to the deletion part of list_ass_slice in CPython """ + impl = w_list.implementation + n = impl.length() + if ilow < 0: + ilow = 0 + elif ilow > n: + ilow = n + if ihigh < ilow: + ihigh = ilow + elif ihigh > n: + ihigh = n + # keep a reference to the objects to be removed, + # preventing side effects during destruction + recycle = impl.getitem_slice(ilow, ihigh) + w_list.implementation = impl.i_delitem_slice(ilow, ihigh) + + +def list_pop__ListMulti_ANY(space, w_list, w_idx=-1): + impl = w_list.implementation + length = impl.length() + if length == 0: + raise OperationError(space.w_IndexError, + space.wrap("pop from empty list")) + idx = space.int_w(w_idx) + idx = _adjust_index(space, idx, length, "pop index out of range") + w_result = impl.getitem(idx) + w_list.implementation = impl.i_delitem(idx) + return w_result + +def list_remove__ListMulti_ANY(space, w_list, w_any): + # needs to be safe against eq_w() mutating the w_list behind our back + i = 0 + while i < w_list.implementation.length(): + if space.eq_w(w_list.implementation.getitem(i), w_any): + if i < w_list.implementation.length(): + w_list.implementation = w_list.implementation.i_delitem(i) + return space.w_None + i += 1 + raise OperationError(space.w_ValueError, + space.wrap("list.remove(x): x not in list")) + +def list_index__ListMulti_ANY_ANY_ANY(space, w_list, w_any, w_start, w_stop): + # needs to be safe against eq_w() mutating the w_list behind our back + length = w_list.implementation.length() + w_start = slicetype.adapt_bound(space, w_start, space.wrap(length)) + w_stop = slicetype.adapt_bound(space, w_stop, space.wrap(length)) + i = space.int_w(w_start) + stop = space.int_w(w_stop) + while i < stop and i < w_list.implementation.length(): + if space.eq_w(w_list.implementation.getitem(i), w_any): + return space.wrap(i) + i += 1 + raise OperationError(space.w_ValueError, + space.wrap("list.index(x): x not in list")) + +def list_count__ListMulti_ANY(space, w_list, w_any): + # needs to be safe against eq_w() mutating the w_list behind our back + count = 0 + i = 0 + while i < w_list.implementation.length(): + if space.eq_w(w_list.implementation.getitem(i), w_any): + count += 1 + i += 1 + return space.wrap(count) + +def list_reverse__ListMulti(space, w_list): + w_list.implementation = w_list.implementation.reverse() + return space.w_None + +# ____________________________________________________________ +# Sorting + +# Reverse a slice of a list in place, from lo up to (exclusive) hi. +# (used in sort) + +class KeyContainer(baseobjspace.W_Root): + def __init__(self, w_key, w_item): + self.w_key = w_key + self.w_item = w_item + +# NOTE: all the subclasses of TimSort should inherit from a common subclass, +# so make sure that only SimpleSort inherits directly from TimSort. +# This is necessary to hide the parent method TimSort.lt() from the +# annotator. +class SimpleSort(TimSort): + def lt(self, a, b): + space = self.space + return space.is_true(space.lt(a, b)) + +class CustomCompareSort(SimpleSort): + def lt(self, a, b): + space = self.space + w_cmp = self.w_cmp + w_result = space.call_function(w_cmp, a, b) + try: + result = space.int_w(w_result) + except OperationError, e: + if e.match(space, space.w_TypeError): + raise OperationError(space.w_TypeError, + space.wrap("comparison function must return int")) + raise + return result < 0 + +class CustomKeySort(SimpleSort): + def lt(self, a, b): + assert isinstance(a, KeyContainer) + assert isinstance(b, KeyContainer) + space = self.space + return space.is_true(space.lt(a.w_key, b.w_key)) + +class CustomKeyCompareSort(CustomCompareSort): + def lt(self, a, b): + assert isinstance(a, KeyContainer) + assert isinstance(b, KeyContainer) + return CustomCompareSort.lt(self, a.w_key, b.w_key) + +def list_sort__ListMulti_ANY_ANY_ANY(space, w_list, w_cmp, w_keyfunc, w_reverse): + has_cmp = not space.is_w(w_cmp, space.w_None) + has_key = not space.is_w(w_keyfunc, space.w_None) + has_reverse = space.is_true(w_reverse) + + # create and setup a TimSort instance + if has_cmp: + if has_key: + sorterclass = CustomKeyCompareSort + else: + sorterclass = CustomCompareSort + else: + if has_key: + sorterclass = CustomKeySort + else: + sorterclass = SimpleSort + impl = w_list.implementation.to_rlist() + w_list.implementation = impl + items = impl.list_w + sorter = sorterclass(items, impl.length()) + sorter.space = space + sorter.w_cmp = w_cmp + + try: + # The list is temporarily made empty, so that mutations performed + # by comparison functions can't affect the slice of memory we're + # sorting (allowing mutations during sorting is an IndexError or + # core-dump factory). + w_list.implementation = EmptyListImplementation(space) + + # wrap each item in a KeyContainer if needed + if has_key: + for i in range(sorter.listlength): + w_item = sorter.list[i] + w_key = space.call_function(w_keyfunc, w_item) + sorter.list[i] = KeyContainer(w_key, w_item) + + # Reverse sort stability achieved by initially reversing the list, + # applying a stable forward sort, then reversing the final result. + if has_reverse: + sorter.list.reverse() + + # perform the sort + sorter.sort() + + # reverse again + if has_reverse: + sorter.list.reverse() + + finally: + # unwrap each item if needed + if has_key: + for i in range(sorter.listlength): + w_obj = sorter.list[i] + if isinstance(w_obj, KeyContainer): + sorter.list[i] = w_obj.w_item + + # check if the user mucked with the list during the sort + mucked = w_list.implementation.length() > 0 + + # put the items back into the list + impl.list_w = sorter.list + w_list.implementation = impl + + if mucked: + raise OperationError(space.w_ValueError, + space.wrap("list modified during sort")) + + return space.w_None + + +from pypy.objspace.std import listtype +register_all(vars(), listtype) Modified: pypy/dist/pypy/objspace/std/listtype.py ============================================================================== --- pypy/dist/pypy/objspace/std/listtype.py (original) +++ pypy/dist/pypy/objspace/std/listtype.py Mon Feb 5 21:49:56 2007 @@ -40,9 +40,14 @@ # ____________________________________________________________ def descr__new__(space, w_listtype, __args__): - from pypy.objspace.std.listobject import W_ListObject - w_obj = space.allocate_instance(W_ListObject, w_listtype) - W_ListObject.__init__(w_obj, []) + if space.config.objspace.std.withmultilist: + from pypy.objspace.std.listmultiobject import W_ListMultiObject + w_obj = space.allocate_instance(W_ListMultiObject, w_listtype) + W_ListMultiObject.__init__(w_obj, space) + else: + from pypy.objspace.std.listobject import W_ListObject + w_obj = space.allocate_instance(W_ListObject, w_listtype) + W_ListObject.__init__(w_obj, []) return w_obj # ____________________________________________________________ Modified: pypy/dist/pypy/objspace/std/model.py ============================================================================== --- pypy/dist/pypy/objspace/std/model.py (original) +++ pypy/dist/pypy/objspace/std/model.py Mon Feb 5 21:49:56 2007 @@ -16,6 +16,7 @@ "dictstrobject.W_DictStrIterObject"], "withmultidict" : ["dictmultiobject.W_DictMultiObject", "dictmultiobject.W_DictMultiIterObject"], + "withmultilist" : ["listmultiobject.W_ListMultiObject"], "withrangelist" : ["rangeobject.W_RangeListObject", "rangeobject.W_RangeIterObject"], "withtproxy" : ["proxyobject.W_TransparentList", @@ -65,6 +66,7 @@ from pypy.objspace.std import dictobject from pypy.objspace.std import dictstrobject from pypy.objspace.std import dictmultiobject + from pypy.objspace.std import listmultiobject from pypy.objspace.std import stringobject from pypy.objspace.std import strsliceobject from pypy.objspace.std import strjoinobject @@ -112,6 +114,7 @@ imported_but_not_registered = { dictobject.W_DictObject: True, dictobject.W_DictIterObject: True, + listobject.W_ListObject: True, } for option, value in config.objspace.std: if option.startswith("with") and option in option_to_typename: @@ -127,6 +130,9 @@ del self.typeorder[dictobject.W_DictObject] del self.typeorder[dictobject.W_DictIterObject] + if config.objspace.std.withmultilist: + del self.typeorder[listobject.W_ListObject] + #check if we missed implementations from pypy.objspace.std.objspace import _registered_implementations for implcls in _registered_implementations: Modified: pypy/dist/pypy/objspace/std/objspace.py ============================================================================== --- pypy/dist/pypy/objspace/std/objspace.py (original) +++ pypy/dist/pypy/objspace/std/objspace.py Mon Feb 5 21:49:56 2007 @@ -348,7 +348,7 @@ return W_TupleObject(wrappeditems) if isinstance(x, list): wrappeditems = [self.wrap(item) for item in x] - return W_ListObject(wrappeditems) + return self.newlist(wrappeditems) # The following cases are even stranger. # Really really only for tests. @@ -432,7 +432,12 @@ return W_TupleObject(list_w) def newlist(self, list_w): - return W_ListObject(list_w) + if self.config.objspace.std.withmultilist: + from pypy.objspace.std.listmultiobject import convert_list_w + return convert_list_w(self, list_w) + else: + from pypy.objspace.std.listobject import W_ListObject + return W_ListObject(list_w) def newdict(self, track_builtin_shadowing=False): if self.config.objspace.opcodes.CALL_LIKELY_BUILTIN and track_builtin_shadowing: Added: pypy/dist/pypy/objspace/std/test/test_listmultiobject.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/objspace/std/test/test_listmultiobject.py Mon Feb 5 21:49:56 2007 @@ -0,0 +1,119 @@ +import autopath +from pypy.interpreter.error import OperationError +from pypy.objspace.std.listmultiobject import W_ListMultiObject, \ + SliceTrackingListImplementation +from pypy.conftest import gettestobjspace +from pypy.objspace.std.test import test_listobject +from pypy.objspace.std.test.test_dictmultiobject import FakeSpace +from pypy.objspace.std.test.test_rangeobject import AppTestRangeListObject + +class AppTest_ListMultiObject(test_listobject.AppTestW_ListObject): + def setup_class(cls): + cls.space = gettestobjspace(**{"objspace.std.withmultilist": True}) + + def test_slice_with_step(self): + l = range(20) + l[0] = 14 + l2 = l[1:-1:2] + assert l2 == range(1, 19, 2) + + def test_strlist_literal(self): + import pypymagic + l = ["1", "2", "3", "4", "5"] + assert "StrListImplementation" in pypymagic.pypy_repr(l) + + def test_strlist_append(self): + import pypymagic + l = [] + l.append("a") + assert "StrListImplementation" in pypymagic.pypy_repr(l) + l.extend(["b", "c", "d"]) + l += ["e", "f"] + assert l == ["a", "b", "c", "d", "e", "f"] + assert "StrListImplementation" in pypymagic.pypy_repr(l) + + +class AppTestRangeImplementation(AppTestRangeListObject): + + def setup_class(cls): + cls.space = gettestobjspace(**{"objspace.std.withmultilist": True}) + cls.w_not_forced = cls.space.appexec([], """(): + import pypymagic + def f(r): + return (isinstance(r, list) and + "RangeImplementation" in pypymagic.pypy_repr(r)) + return f + """) + + def test_sort(self): + pass # won't work with multilists + + +class AppTest_FastSlice(test_listobject.AppTestW_ListObject): + def setup_class(cls): + cls.space = gettestobjspace(**{"objspace.std.withfastslice": True}) + + def test_lazy_slice(self): + import pypymagic + l = [i for i in range(100)] # force it to not be a range impl + l2 = l[1:-1] + assert "SliceTrackingListImplementation" in pypymagic.pypy_repr(l) + assert "SliceListImplementation" in pypymagic.pypy_repr(l2) + result = 0 + for i in l2: + result += i + # didn't force l2 + assert "SliceListImplementation" in pypymagic.pypy_repr(l2) + # force l2: + l2.append(10) + assert l2 == range(1, 99) + [10] + + def test_append_extend_dont_force(self): + import pypymagic + l = [i for i in range(100)] # force it to not be a range impl + l2 = l[1:-1] + assert "SliceTrackingListImplementation" in pypymagic.pypy_repr(l) + assert "SliceListImplementation" in pypymagic.pypy_repr(l2) + l.append(100) + l.extend(range(101, 110)) + assert l == range(110) + assert "SliceTrackingListImplementation" in pypymagic.pypy_repr(l) + assert "SliceListImplementation" in pypymagic.pypy_repr(l2) + + def test_slice_of_slice(self): + import pypymagic + l = [i for i in range(100)] # force it to not be a range impl + l2 = l[1:-1] + l3 = l2[1:-1] + l4 = l3[1:-1] + assert l2 == range(1, 99) + assert l3 == range(2, 98) + assert l4 == range(3, 97) + assert "SliceListImplementation" in pypymagic.pypy_repr(l4) + l2[3] = 4 + assert "SliceListImplementation" not in pypymagic.pypy_repr(l2) + assert "SliceListImplementation" in pypymagic.pypy_repr(l4) + + def test_delitem_to_empty(self): + import pypymagic + l = [i for i in range(100)] # force it to not be a range impl + l1 = l[1:-1] + del l1[:] + assert "EmptyListImplementation" in pypymagic.pypy_repr(l1) + + +class TestSliceListImplementation(object): + def setup_method(self,method): + self.space = FakeSpace() + + def test_simple(self): + impl = SliceTrackingListImplementation(self.space, range(20)) + impl2 = impl.getitem_slice(2, 14) + assert impl2.getitem(2) == 4 + impl = impl.setitem(4, 10) + assert impl.getitem(4) == 10 + # check that impl2 works after detaching + assert impl2.getitem(2) == 4 + impl2 = impl2.setitem(2, 5) + assert impl2.getitem(2) == 5 + Modified: pypy/dist/pypy/objspace/std/test/test_listobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/test/test_listobject.py (original) +++ pypy/dist/pypy/objspace/std/test/test_listobject.py Mon Feb 5 21:49:56 2007 @@ -429,7 +429,26 @@ l = ['a', 'C', 'b'] l.sort(reverse = True, key = lower) assert l == ['C', 'b', 'a'] - + + def test_getitem(self): + l = [1, 2, 3, 4, 5, 6, 9] + assert l[0] == 1 + assert l[-1] == 9 + assert l[-2] == 6 + raises(IndexError, "l[len(l)]") + raises(IndexError, "l[-len(l)-1]") + + def test_delitem(self): + l = [1, 2, 3, 4, 5, 6, 9] + del l[0] + assert l == [2, 3, 4, 5, 6, 9] + del l[-1] + assert l == [2, 3, 4, 5, 6] + del l[-2] + assert l == [2, 3, 4, 6] + raises(IndexError, "del l[len(l)]") + raises(IndexError, "del l[-len(l)-1]") + def test_extended_slice(self): l = range(10) del l[::2] From hpk at codespeak.net Mon Feb 5 22:16:35 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Mon, 5 Feb 2007 22:16:35 +0100 (CET) Subject: [pypy-svn] r37983 - pypy/extradoc/minute Message-ID: <20070205211635.76CF910083@code0.codespeak.net> Author: hpk Date: Mon Feb 5 22:16:33 2007 New Revision: 37983 Modified: pypy/extradoc/minute/pypy-sync-2007-02-02.txt Log: some clarifications/reformulations from my side Modified: pypy/extradoc/minute/pypy-sync-2007-02-02.txt ============================================================================== --- pypy/extradoc/minute/pypy-sync-2007-02-02.txt (original) +++ pypy/extradoc/minute/pypy-sync-2007-02-02.txt Mon Feb 5 22:16:33 2007 @@ -39,7 +39,7 @@ sandboxing. According to Armin it is a major effort to clean up all these areas and get a good level of documentation. -At this point the meeting side-tracked into discussing the state of the JIT and +At this point the meeting we started discussing the state of the JIT and the next steps in this area and the general question how to approach development during the rest of the EU funding. According to Armin it is expected that the JIT starts producing non-horrible code "any day or week now". Since the @@ -58,14 +58,15 @@ interesting features in PyPy even without the JIT working. Then the discussion moved to the expectations of the EU reviewers. The reviewers we had at the last review meeting were not too interested in the JIT but more in things like -aspects, constraint and logic programming. The state of PyPy in these areas is -unclear. - -After a lengthy discussion about what is needed to pass the EU review, we got -back to time planning. Armin proposed to check the state of the JIT again on -Monday to see how far it improved over the weekend. It was also decided that we -would meet again on Wednesday, February 7th at 11.00 to discuss the release work -distribution in detail. +aspects, constraint and logic programming. However, the current state +of PyPy in these areas is not completely obvious to the people +attending the meeting. + +It then was agreed to check the state of the JIT again on +Monday to see how far it improved over the weekend. It was +also decided that we would meet again on Wednesday, February +7th at 11.00 to discuss the release work distribution in +detail. Task Planning ============= From fijal at codespeak.net Tue Feb 6 11:50:23 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 6 Feb 2007 11:50:23 +0100 (CET) Subject: [pypy-svn] r37995 - in pypy/branch/pytrunkmerge/pypy: config doc/config lang/js lang/js/test module/__builtin__ objspace/std objspace/std/test tool/build tool/build/test translator/c/winproj/extension translator/c/winproj/standalone Message-ID: <20070206105023.CD40B10070@code0.codespeak.net> Author: fijal Date: Tue Feb 6 11:50:16 2007 New Revision: 37995 Added: pypy/branch/pytrunkmerge/pypy/lang/js/driver.py - copied unchanged from r37994, pypy/dist/pypy/lang/js/driver.py pypy/branch/pytrunkmerge/pypy/objspace/std/listmultiobject.py - copied unchanged from r37994, pypy/dist/pypy/objspace/std/listmultiobject.py pypy/branch/pytrunkmerge/pypy/objspace/std/test/test_listmultiobject.py - copied unchanged from r37994, pypy/dist/pypy/objspace/std/test/test_listmultiobject.py pypy/branch/pytrunkmerge/pypy/tool/build/test/__init__.py - copied unchanged from r37994, pypy/dist/pypy/tool/build/test/__init__.py Modified: pypy/branch/pytrunkmerge/pypy/config/pypyoption.py pypy/branch/pytrunkmerge/pypy/doc/config/objspace.opcodes.CALL_LIKELY_BUILTIN.txt pypy/branch/pytrunkmerge/pypy/doc/config/objspace.std.withtypeversion.txt pypy/branch/pytrunkmerge/pypy/lang/js/interpreter.py pypy/branch/pytrunkmerge/pypy/lang/js/jsobj.py pypy/branch/pytrunkmerge/pypy/lang/js/jsparser.py pypy/branch/pytrunkmerge/pypy/lang/js/test/test_interp.py pypy/branch/pytrunkmerge/pypy/module/__builtin__/app_help.py pypy/branch/pytrunkmerge/pypy/module/__builtin__/functional.py pypy/branch/pytrunkmerge/pypy/objspace/std/listtype.py pypy/branch/pytrunkmerge/pypy/objspace/std/model.py pypy/branch/pytrunkmerge/pypy/objspace/std/objspace.py pypy/branch/pytrunkmerge/pypy/objspace/std/stringobject.py pypy/branch/pytrunkmerge/pypy/objspace/std/test/test_listobject.py pypy/branch/pytrunkmerge/pypy/tool/build/build.py pypy/branch/pytrunkmerge/pypy/tool/build/buildserver.py pypy/branch/pytrunkmerge/pypy/tool/build/metaserver.py pypy/branch/pytrunkmerge/pypy/tool/build/test/fake.py pypy/branch/pytrunkmerge/pypy/tool/build/test/test_build.py pypy/branch/pytrunkmerge/pypy/tool/build/test/test_buildserver.py pypy/branch/pytrunkmerge/pypy/tool/build/test/test_metaserver.py pypy/branch/pytrunkmerge/pypy/tool/build/test/test_pypybuilder.py pypy/branch/pytrunkmerge/pypy/translator/c/winproj/extension/extension.vcproj pypy/branch/pytrunkmerge/pypy/translator/c/winproj/standalone/standalone.vcproj Log: svn merge -r 37858:HEAD http://codespeak.net/svn/pypy/dist/pypy . Modified: pypy/branch/pytrunkmerge/pypy/config/pypyoption.py ============================================================================== --- pypy/branch/pytrunkmerge/pypy/config/pypyoption.py (original) +++ pypy/branch/pytrunkmerge/pypy/config/pypyoption.py Tue Feb 6 11:50:16 2007 @@ -170,6 +170,16 @@ IntOption("methodcachesize", "size of the method cache (should be a power of 2)", default=2048), + BoolOption("withmultilist", + "use lists optimized for flexibility", + default=False, + requires=[("objspace.std.withrangelist", False), + ("objspace.name", "std"), + ("objspace.std.withtproxy", False)]), + BoolOption("withfastslice", + "make list slicing lazy", + default=False, + requires=[("objspace.std.withmultilist", True)]), BoolOption("optimized_int_add", "special case the addition of two integers in BINARY_ADD", default=False), Modified: pypy/branch/pytrunkmerge/pypy/doc/config/objspace.opcodes.CALL_LIKELY_BUILTIN.txt ============================================================================== --- pypy/branch/pytrunkmerge/pypy/doc/config/objspace.opcodes.CALL_LIKELY_BUILTIN.txt (original) +++ pypy/branch/pytrunkmerge/pypy/doc/config/objspace.opcodes.CALL_LIKELY_BUILTIN.txt Tue Feb 6 11:50:16 2007 @@ -4,5 +4,5 @@ then tracked, which builtin name is shadowed in this module. If the ``CALL_LIKELY_BUILTIN`` opcode is executed, it is checked whether the builtin is shadowed. If not, the corresponding builtin is called. Otherwise the object that -is shadowing it is called instead. If no shadowing is happening, this safes two +is shadowing it is called instead. If no shadowing is happening, this saves two dictionary lookups on calls to builtins. Modified: pypy/branch/pytrunkmerge/pypy/doc/config/objspace.std.withtypeversion.txt ============================================================================== --- pypy/branch/pytrunkmerge/pypy/doc/config/objspace.std.withtypeversion.txt (original) +++ pypy/branch/pytrunkmerge/pypy/doc/config/objspace.std.withtypeversion.txt Tue Feb 6 11:50:16 2007 @@ -1,4 +1,4 @@ This (mostly internal) option enables "type versions": Every type object gets an (only internally visible) version that is updated when the type's dict is -changed. This is e.g. used for invalidating cashes. It does not make sense to +changed. This is e.g. used for invalidating caches. It does not make sense to enable this option alone. Modified: pypy/branch/pytrunkmerge/pypy/lang/js/interpreter.py ============================================================================== --- pypy/branch/pytrunkmerge/pypy/lang/js/interpreter.py (original) +++ pypy/branch/pytrunkmerge/pypy/lang/js/interpreter.py Tue Feb 6 11:50:16 2007 @@ -69,7 +69,6 @@ self.right = get_obj(t, '1') class BinaryComparisonOp(BinaryOp): - """super class for binary operators""" def eval(self, ctx): s2 = self.left.eval(ctx).GetValue() s4 = self.right.eval(ctx).GetValue() @@ -81,7 +80,6 @@ raise NotImplementedError class BinaryLogicOp(BinaryOp): - """super class for binary operators""" pass def writer(x): @@ -130,6 +128,11 @@ return W_Boolean(args[0].ToBoolean()) return W_Boolean(False) +def stringjs(ctx, args, this): + if len(args) > 0: + return W_String(args[0].ToString()) + return W_String('') + def numberjs(ctx, args, this): if len(args) > 0: return W_Number(args[0].ToNumber()) @@ -172,6 +175,7 @@ w_math.Put('abs', W_Builtin(absjs, Class='function')) w_math.Put('floor', W_Builtin(floorjs, Class='function')) + w_Global.Put('String', W_Builtin(stringjs, Class='String')) #Global Properties w_Global.Put('Object', w_Object) @@ -179,6 +183,7 @@ w_Global.Put('Array', W_Array()) w_Global.Put('version', W_Builtin(versionjs)) + #Number w_Number = W_Builtin(numberjs, Class="Number") w_Number.Put('NaN', W_Number(NaN)) w_Number.Put('POSITIVE_INFINITY', W_Number(Infinity)) @@ -217,7 +222,7 @@ #d = dict(enumerate(self.items)) array = W_Array() for i in range(len(self.list)): - array.Put(str(i), self.list[i]) + array.Put(str(i), self.list[i].eval(ctx).GetValue()) return array @@ -611,6 +616,15 @@ fright = nright.ToNumber() return W_Number(fleft * fright) +class Mod(BinaryNumberOp): + opcode = 'MOD' + + def mathop(self, ctx, nleft, nright): + fleft = nleft.ToNumber() + fright = nright.ToNumber() + return W_Number(fleft % fright) + + class Div(BinaryNumberOp): opcode = 'DIV' @@ -657,6 +671,8 @@ ctx.variable.Put(var.name, w_Undefined) for fun in self.func_decl: ctx.variable.Put(fun.name, fun.eval(ctx)) + + node = self try: last = w_Undefined @@ -843,11 +859,18 @@ return W_Boolean(not self.expr.eval(ctx).GetValue().ToBoolean()) class UMinus(UnaryOp): - opcode = "UNARY_MINUS" + opcode = 'UNARY_MINUS' def eval(self, ctx): return W_Number(-self.expr.eval(ctx).GetValue().ToNumber()) +class UPlus(UnaryOp): + opcode = 'UNARY_PLUS' + + def eval(self, ctx): + return W_Number(+self.expr.eval(ctx).GetValue().ToNumber()) + + astundef = Undefined() def get_obj(t, objname): item = get_tree_item(t, objname) @@ -859,7 +882,7 @@ def get_string(t, string): simb = get_tree_item(t, string) if isinstance(simb, Symbol): - return simb.additional_info + return str(simb.additional_info) else: return '' @@ -877,7 +900,7 @@ if x.children[0].additional_info == name: return x.children[1] return None - + opcodedict = {} for i in locals().values(): if isinstance(i, type(Node)) and issubclass(i, Node): Modified: pypy/branch/pytrunkmerge/pypy/lang/js/jsobj.py ============================================================================== --- pypy/branch/pytrunkmerge/pypy/lang/js/jsobj.py (original) +++ pypy/branch/pytrunkmerge/pypy/lang/js/jsobj.py Tue Feb 6 11:50:16 2007 @@ -1,6 +1,6 @@ # encoding: utf-8 -DEBUG = True +DEBUG = False class SeePage(NotImplementedError): pass @@ -129,7 +129,7 @@ if callfunc is not None: self.Scope = ctx.scope[:] else: - self.Scope = [] + self.Scope = None self.Value = Value def Call(self, ctx, args=[], this=None): @@ -229,15 +229,15 @@ else: return 'object' - def str_builtin(self, ctx, args, this): - return W_String(self.ToString()) +def str_builtin(ctx, args, this): + return W_String(this.ToString()) class W_Object(W_PrimitiveObject): def __init__(self, ctx=None, Prototype=None, Class='Object', Value=w_Undefined, callfunc=None): W_PrimitiveObject.__init__(self, ctx, Prototype, Class, Value, callfunc) - self.propdict['toString'] = Property('toString', W_Builtin(self.str_builtin)) + self.propdict['toString'] = Property('toString', W_Builtin(str_builtin)) class W_Builtin(W_PrimitiveObject): @@ -280,8 +280,7 @@ def __init__(self, ctx=None, Prototype=None, Class='Array', Value=w_Undefined, callfunc=None): W_PrimitiveObject.__init__(self, ctx, Prototype, Class, Value, callfunc) - toString = W_Builtin() - toString.set_builtin_call(self.str_builtin) + toString = W_Builtin(array_str_builtin) self.Put('toString', toString) self.Put('length', W_Number(0)) self.array = [] @@ -317,12 +316,13 @@ except ValueError: return W_PrimitiveObject.Get(self, P) - def str_builtin(self, ctx, args, this): - return W_String(ToString()) - def ToString(self): return ','.join(self.array) +def array_str_builtin(ctx, args, this): + return W_String(this.ToString()) + + class W_Boolean(W_Primitive): def __init__(self, boolval): Modified: pypy/branch/pytrunkmerge/pypy/lang/js/jsparser.py ============================================================================== --- pypy/branch/pytrunkmerge/pypy/lang/js/jsparser.py (original) +++ pypy/branch/pytrunkmerge/pypy/lang/js/jsparser.py Tue Feb 6 11:50:16 2007 @@ -28,12 +28,9 @@ jsdir = py.path.local(__file__).dirpath().join("js") jsdefs = jsdir.join("jsdefs.js").read() jsparse = jsdir.join("jsparse.js").read() - f = open('/tmp/jstobeparsed.js','w') - f.write(jsdefs) - f.write(jsparse) - f.write("print(parse('%s'));\n" % stripped_code) - f.close() - pipe = os.popen("js -f /tmp/jstobeparsed.js", 'r') + f = py.test.ensuretemp("jsinterp").join("tobeparsed.js") + f.write(jsdefs+jsparse+"print(parse('%s'));\n" % stripped_code) + pipe = os.popen("js -f "+str(f), 'r') retval = pipe.read() if not retval.startswith("{"): raise JsSyntaxError(retval) @@ -42,8 +39,7 @@ def unquote(t): if isinstance(t, Symbol): if t.symbol == "QUOTED_STRING": - t.additional_info = t.additional_info.strip("'") - t.additional_info = re.sub(r"\\'", r"'", t.additional_info) + t.additional_info = t.additional_info.strip("'").replace("\\'", "'") else: for i in t.children: unquote(i) Modified: pypy/branch/pytrunkmerge/pypy/lang/js/test/test_interp.py ============================================================================== --- pypy/branch/pytrunkmerge/pypy/lang/js/test/test_interp.py (original) +++ pypy/branch/pytrunkmerge/pypy/lang/js/test/test_interp.py Tue Feb 6 11:50:16 2007 @@ -447,4 +447,10 @@ var testcases = new Array(); var tc = testcases.length; print('tc'+tc) - """, ['tc0']) \ No newline at end of file + """, ['tc0']) + + def test_mod_op(self): + self.assert_prints("print(2%2)", ['0']) + + def test_unary_plus(self): + self.assert_prints("print(+1)", ['1']) Modified: pypy/branch/pytrunkmerge/pypy/module/__builtin__/app_help.py ============================================================================== --- pypy/branch/pytrunkmerge/pypy/module/__builtin__/app_help.py (original) +++ pypy/branch/pytrunkmerge/pypy/module/__builtin__/app_help.py Tue Feb 6 11:50:16 2007 @@ -10,12 +10,12 @@ exit = "Use Ctrl-D (i.e. EOF) to exit." def copyright(): - print 'Copyright 2003-2004 Pypy development team.\nAll rights reserved.\nFor further information see http://www.codespeak.net/pypy.\nSome materials may have a different copyright.\nIn these cases, this is explicitly noted in the source code file.' + print 'Copyright 2003-2007 PyPy development team.\nAll rights reserved.\nFor further information see http://www.codespeak.net/pypy.\nSome materials may have a different copyright.\nIn these cases, this is explicitly noted in the source code file.' def license(): print \ """ -Copyright (c) <2003-2005> +Copyright (c) <2003-2007> Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: Modified: pypy/branch/pytrunkmerge/pypy/module/__builtin__/functional.py ============================================================================== --- pypy/branch/pytrunkmerge/pypy/module/__builtin__/functional.py (original) +++ pypy/branch/pytrunkmerge/pypy/module/__builtin__/functional.py Tue Feb 6 11:50:16 2007 @@ -69,8 +69,9 @@ get a list in decending order.""" if (space.config.objspace.name == "std" and - space.config.objspace.std.withrangelist): - return range_withrangelist(space, w_x, w_y, w_step) + (space.config.objspace.std.withmultilist or + space.config.objspace.std.withrangelist)): + return range_withspecialized_implementation(space, w_x, w_y, w_step) try: # save duplication by redirecting every error to applevel x = space.int_w(w_x) @@ -96,11 +97,9 @@ range_fallback = applevel(getsource(app_range), getfile(app_range) ).interphook('range') -def range_withrangelist(space, w_x, w_y, w_step): +def range_withspecialized_implementation(space, w_x, w_y, w_step): # XXX object space dependant - from pypy.objspace.std.rangeobject import W_RangeListObject try: - # save duplication by redirecting every error to applevel x = space.int_w(w_x) if space.is_w(w_y, space.w_None): start, stop = 0, x @@ -110,5 +109,12 @@ howmany = get_len_of_range(start, stop, step) except (OperationError, ValueError, OverflowError): return range_fallback(space, w_x, w_y, w_step) - return W_RangeListObject(start, step, howmany) + if space.config.objspace.std.withrangelist: + from pypy.objspace.std.rangeobject import W_RangeListObject + return W_RangeListObject(start, step, howmany) + if space.config.objspace.std.withmultilist: + from pypy.objspace.std.listmultiobject import W_ListMultiObject + from pypy.objspace.std.listmultiobject import RangeImplementation + impl = RangeImplementation(space, start, step, howmany) + return W_ListMultiObject(space, impl) Modified: pypy/branch/pytrunkmerge/pypy/objspace/std/listtype.py ============================================================================== --- pypy/branch/pytrunkmerge/pypy/objspace/std/listtype.py (original) +++ pypy/branch/pytrunkmerge/pypy/objspace/std/listtype.py Tue Feb 6 11:50:16 2007 @@ -40,9 +40,14 @@ # ____________________________________________________________ def descr__new__(space, w_listtype, __args__): - from pypy.objspace.std.listobject import W_ListObject - w_obj = space.allocate_instance(W_ListObject, w_listtype) - W_ListObject.__init__(w_obj, []) + if space.config.objspace.std.withmultilist: + from pypy.objspace.std.listmultiobject import W_ListMultiObject + w_obj = space.allocate_instance(W_ListMultiObject, w_listtype) + W_ListMultiObject.__init__(w_obj, space) + else: + from pypy.objspace.std.listobject import W_ListObject + w_obj = space.allocate_instance(W_ListObject, w_listtype) + W_ListObject.__init__(w_obj, []) return w_obj # ____________________________________________________________ Modified: pypy/branch/pytrunkmerge/pypy/objspace/std/model.py ============================================================================== --- pypy/branch/pytrunkmerge/pypy/objspace/std/model.py (original) +++ pypy/branch/pytrunkmerge/pypy/objspace/std/model.py Tue Feb 6 11:50:16 2007 @@ -16,6 +16,7 @@ "dictstrobject.W_DictStrIterObject"], "withmultidict" : ["dictmultiobject.W_DictMultiObject", "dictmultiobject.W_DictMultiIterObject"], + "withmultilist" : ["listmultiobject.W_ListMultiObject"], "withrangelist" : ["rangeobject.W_RangeListObject", "rangeobject.W_RangeIterObject"], "withtproxy" : ["proxyobject.W_TransparentList", @@ -65,6 +66,7 @@ from pypy.objspace.std import dictobject from pypy.objspace.std import dictstrobject from pypy.objspace.std import dictmultiobject + from pypy.objspace.std import listmultiobject from pypy.objspace.std import stringobject from pypy.objspace.std import strsliceobject from pypy.objspace.std import strjoinobject @@ -112,6 +114,7 @@ imported_but_not_registered = { dictobject.W_DictObject: True, dictobject.W_DictIterObject: True, + listobject.W_ListObject: True, } for option, value in config.objspace.std: if option.startswith("with") and option in option_to_typename: @@ -127,6 +130,9 @@ del self.typeorder[dictobject.W_DictObject] del self.typeorder[dictobject.W_DictIterObject] + if config.objspace.std.withmultilist: + del self.typeorder[listobject.W_ListObject] + #check if we missed implementations from pypy.objspace.std.objspace import _registered_implementations for implcls in _registered_implementations: Modified: pypy/branch/pytrunkmerge/pypy/objspace/std/objspace.py ============================================================================== --- pypy/branch/pytrunkmerge/pypy/objspace/std/objspace.py (original) +++ pypy/branch/pytrunkmerge/pypy/objspace/std/objspace.py Tue Feb 6 11:50:16 2007 @@ -348,7 +348,7 @@ return W_TupleObject(wrappeditems) if isinstance(x, list): wrappeditems = [self.wrap(item) for item in x] - return W_ListObject(wrappeditems) + return self.newlist(wrappeditems) # The following cases are even stranger. # Really really only for tests. @@ -432,7 +432,12 @@ return W_TupleObject(list_w) def newlist(self, list_w): - return W_ListObject(list_w) + if self.config.objspace.std.withmultilist: + from pypy.objspace.std.listmultiobject import convert_list_w + return convert_list_w(self, list_w) + else: + from pypy.objspace.std.listobject import W_ListObject + return W_ListObject(list_w) def newdict(self, track_builtin_shadowing=False): if self.config.objspace.opcodes.CALL_LIKELY_BUILTIN and track_builtin_shadowing: Modified: pypy/branch/pytrunkmerge/pypy/objspace/std/stringobject.py ============================================================================== --- pypy/branch/pytrunkmerge/pypy/objspace/std/stringobject.py (original) +++ pypy/branch/pytrunkmerge/pypy/objspace/std/stringobject.py Tue Feb 6 11:50:16 2007 @@ -233,7 +233,7 @@ # continue to look from the character following the space after the word i = j + 1 - return W_ListObject(res_w) + return space.newlist(res_w) def str_split__String_String_ANY(space, w_self, w_by, w_maxsplit=-1): @@ -256,7 +256,7 @@ res_w.append(sliced(space, value, start, len(value))) - return W_ListObject(res_w) + return space.newlist(res_w) def str_rsplit__String_None_ANY(space, w_self, w_none, w_maxsplit=-1): maxsplit = space.int_w(w_maxsplit) @@ -291,7 +291,7 @@ i = j - 1 res_w.reverse() - return W_ListObject(res_w) + return space.newlist(res_w) def str_rsplit__String_String_ANY(space, w_self, w_by, w_maxsplit=-1): maxsplit = space.int_w(w_maxsplit) @@ -313,7 +313,7 @@ res_w.append(sliced(space, value, 0, end)) res_w.reverse() - return W_ListObject(res_w) + return space.newlist(res_w) def str_join__String_ANY(space, w_self, w_list): list_w = space.unpackiterable(w_list) Modified: pypy/branch/pytrunkmerge/pypy/objspace/std/test/test_listobject.py ============================================================================== --- pypy/branch/pytrunkmerge/pypy/objspace/std/test/test_listobject.py (original) +++ pypy/branch/pytrunkmerge/pypy/objspace/std/test/test_listobject.py Tue Feb 6 11:50:16 2007 @@ -429,7 +429,26 @@ l = ['a', 'C', 'b'] l.sort(reverse = True, key = lower) assert l == ['C', 'b', 'a'] - + + def test_getitem(self): + l = [1, 2, 3, 4, 5, 6, 9] + assert l[0] == 1 + assert l[-1] == 9 + assert l[-2] == 6 + raises(IndexError, "l[len(l)]") + raises(IndexError, "l[-len(l)-1]") + + def test_delitem(self): + l = [1, 2, 3, 4, 5, 6, 9] + del l[0] + assert l == [2, 3, 4, 5, 6, 9] + del l[-1] + assert l == [2, 3, 4, 5, 6] + del l[-2] + assert l == [2, 3, 4, 6] + raises(IndexError, "del l[len(l)]") + raises(IndexError, "del l[-len(l)-1]") + def test_extended_slice(self): l = range(10) del l[::2] Modified: pypy/branch/pytrunkmerge/pypy/tool/build/build.py ============================================================================== --- pypy/branch/pytrunkmerge/pypy/tool/build/build.py (original) +++ pypy/branch/pytrunkmerge/pypy/tool/build/build.py Tue Feb 6 11:50:16 2007 @@ -122,7 +122,7 @@ self.svnrev, self.revrange) def serialize(self): - data = {'normalized_rev': self.normalized_rev} + data = {'normalized_rev': self.normalized_rev} # it's a property data.update(self.__dict__) return """\ email: %(email)s Modified: pypy/branch/pytrunkmerge/pypy/tool/build/buildserver.py ============================================================================== --- pypy/branch/pytrunkmerge/pypy/tool/build/buildserver.py (original) +++ pypy/branch/pytrunkmerge/pypy/tool/build/buildserver.py Tue Feb 6 11:50:16 2007 @@ -1,11 +1,12 @@ import py import thread -from zipfile import ZipFile +from zipfile import ZipFile, ZIP_DEFLATED from cStringIO import StringIO from pypy.tool.build import build class BuildServer(object): - def __init__(self, channel, sysinfo, testing_sleeptime=False): + def __init__(self, channel, sysinfo, hostname, testing_sleeptime=False): + self.hostname = hostname self.channel = channel self.sysinfo = sysinfo self.busy_on = None @@ -72,7 +73,7 @@ try: try: - bs = BuildServer(channel, %r, %r) + bs = BuildServer(channel, %r, %r, %r) bs.sit_and_wait() except: try: @@ -97,6 +98,7 @@ sysinfo = make_dict(sysconfig) conference = execnetconference.conference(gw, port, False) channel = conference.remote_exec(initcode % (path, sysinfo, + py.std.socket.gethostname(), testing_sleeptime)) return channel @@ -124,12 +126,12 @@ pass def zip_dir(res_dir, tofile): - zip = ZipFile(tofile, 'w') + zip = ZipFile(tofile, 'w', ZIP_DEFLATED) for fpath in res_dir.visit(): if fpath.ext in ['.o']: continue try: - zip.writestr(fpath.relto(res_dir), fpath.read()) + zip.writestr("pypy-compiled/" + fpath.relto(res_dir), fpath.read()) except (py.error.ENOENT, py.error.EISDIR), exc: print exc continue Modified: pypy/branch/pytrunkmerge/pypy/tool/build/metaserver.py ============================================================================== --- pypy/branch/pytrunkmerge/pypy/tool/build/metaserver.py (original) +++ pypy/branch/pytrunkmerge/pypy/tool/build/metaserver.py Tue Feb 6 11:50:16 2007 @@ -26,7 +26,7 @@ return True class MetaServer(object): - """ the build server + """ the build meta-server this delegates or queues build requests, and stores results and sends out emails when they're done @@ -88,13 +88,17 @@ return (True, path) for builder in self._builders: if builder.busy_on and request.has_satisfying_data(builder.busy_on): - self._channel.send('build for %s currently in progress' % - (request,)) + self._channel.send( + "build for %s currently in progress on '%s'" % ( + request, builder.hostname)) self._waiting.append(request) - return (False, 'this build is already in progress') + return (False, "this build is already in progress on '%s'" % ( + builder.hostname, )) # we don't have a build for this yet, find a builder to compile it - if self.run(request): - return (False, 'found a suitable build server, going to build') + hostname = self.run(request) + if hostname is not None: + return (False, "found a suitable server, going to build on '%s'" % + (hostname, )) self._queuelock.acquire() try: self._queued.append(request) @@ -117,13 +121,13 @@ else: self._channel.send( 'going to send compile job for request %s to %s' % ( - request, builder + request, builder.hostname ) ) accepted = builder.compile(request) if accepted: self._channel.send('compile job accepted') - return True + return builder.hostname else: self._channel.send('compile job denied') self._channel.send( Modified: pypy/branch/pytrunkmerge/pypy/tool/build/test/fake.py ============================================================================== --- pypy/branch/pytrunkmerge/pypy/tool/build/test/fake.py (original) +++ pypy/branch/pytrunkmerge/pypy/tool/build/test/fake.py Tue Feb 6 11:50:16 2007 @@ -16,12 +16,13 @@ def waitclose(self): pass -class FakeClient(object): +class FakeBuildserver(object): def __init__(self, info): self.channel = FakeChannel() self.sysinfo = info self.busy_on = None self.refused = [] + self.hostname = "fake" def compile(self, request): self.channel.send(request.serialize()) Modified: pypy/branch/pytrunkmerge/pypy/tool/build/test/test_build.py ============================================================================== --- pypy/branch/pytrunkmerge/pypy/tool/build/test/test_build.py (original) +++ pypy/branch/pytrunkmerge/pypy/tool/build/test/test_build.py Tue Feb 6 11:50:16 2007 @@ -1,8 +1,8 @@ import py -from pypy.tool.build import build from py.__.misc.cache import AgingCache from py.__.path.svn import urlcommand -from repo import create_temp_repo +from pypy.tool.build import build +from pypy.tool.build.test.repo import create_temp_repo def setup_module(mod): # remove nasty cache from py.path.svnurl to allow this to work... Modified: pypy/branch/pytrunkmerge/pypy/tool/build/test/test_buildserver.py ============================================================================== --- pypy/branch/pytrunkmerge/pypy/tool/build/test/test_buildserver.py (original) +++ pypy/branch/pytrunkmerge/pypy/tool/build/test/test_buildserver.py Tue Feb 6 11:50:16 2007 @@ -1,12 +1,13 @@ -import path -from pypy.tool.build import buildserver -from pypy.tool.build import build import py -import time +import path import sys -from zipfile import ZipFile from StringIO import StringIO -from fake import FakeChannel, FakeMetaServer +import time +from zipfile import ZipFile + +from pypy.tool.build import buildserver +from pypy.tool.build import build +from pypy.tool.build.test.fake import FakeChannel, FakeMetaServer class BuildServerForTests(buildserver.BuildServer): def __init__(self, *args, **kwargs): @@ -24,11 +25,11 @@ pypy.tool.build.metaserver_instance = svr mod.c1c = c1c = FakeChannel() - mod.c1 = c1 = BuildServerForTests(c1c, {'foo': 1, 'bar': [1,2]}) + mod.c1 = c1 = BuildServerForTests(c1c, {'foo': 1, 'bar': [1,2]}, "noname") svr.register(c1) mod.c2c = c2c = FakeChannel() - mod.c2 = c2 = BuildServerForTests(c2c, {'foo': 2, 'bar': [2,3]}) + mod.c2 = c2 = BuildServerForTests(c2c, {'foo': 2, 'bar': [2,3]}, "noname") svr.register(c2) def test_compile(): @@ -93,10 +94,10 @@ zip.seek(0) zf = ZipFile(zip) - data = zf.read('foo/bar.txt') + data = zf.read('pypy-compiled/foo/bar.txt') assert data == 'bar' - py.test.raises(KeyError, 'zf.read("foo/bar.o")') + py.test.raises(KeyError, 'zf.read("pypy-compiled/foo/bar.o")') def test_tempdir(): parent = py.test.ensuretemp('tempdir') Modified: pypy/branch/pytrunkmerge/pypy/tool/build/test/test_metaserver.py ============================================================================== --- pypy/branch/pytrunkmerge/pypy/tool/build/test/test_metaserver.py (original) +++ pypy/branch/pytrunkmerge/pypy/tool/build/test/test_metaserver.py Tue Feb 6 11:50:16 2007 @@ -1,10 +1,11 @@ +import py import path +import time + from pypy.tool.build import metaserver -import py -from fake import FakeChannel, FakeClient, Container +from pypy.tool.build.test.fake import FakeChannel, FakeBuildserver, Container from pypy.tool.build import build -import time -from repo import create_temp_repo +from pypy.tool.build.test.repo import create_temp_repo def setup_module(mod): mod.temppath = temppath = py.test.ensuretemp('pypybuilder-server') @@ -12,10 +13,10 @@ mailhost=None) mod.svr = metaserver.MetaServer(config, FakeChannel()) - mod.c1 = FakeClient({'foo': 1, 'bar': [1,2]}) + mod.c1 = FakeBuildserver({'foo': 1, 'bar': [1,2]}) mod.svr.register(mod.c1) - mod.c2 = FakeClient({'foo': 2, 'bar': [2,3]}) + mod.c2 = FakeBuildserver({'foo': 2, 'bar': [2,3]}) mod.svr.register(mod.c2) def test_server_issubdict(): @@ -52,7 +53,8 @@ str(repodir), 'HEAD', 0) ret = svr.compile(br) assert not ret[0] - assert ret[1].find('found a suitable build server') > -1 + assert ret[1].find('found a suitable server') > -1 + assert "fake" in ret[1] # hostname ret = svr._channel.receive() assert ret.find('going to send compile job') > -1 acceptedmsg = svr._channel.receive() Modified: pypy/branch/pytrunkmerge/pypy/tool/build/test/test_pypybuilder.py ============================================================================== --- pypy/branch/pytrunkmerge/pypy/tool/build/test/test_pypybuilder.py (original) +++ pypy/branch/pytrunkmerge/pypy/tool/build/test/test_pypybuilder.py Tue Feb 6 11:50:16 2007 @@ -11,8 +11,8 @@ from pypy.tool.build.conftest import option from pypy.config import config as pypyconfig -from repo import create_temp_repo -from fake import Container +from pypy.tool.build.test.repo import create_temp_repo +from pypy.tool.build.test.fake import Container # XXX this one is a bit messy, it's a quick functional test for the whole # system, but for instance contains time.sleep()s to make sure all threads Modified: pypy/branch/pytrunkmerge/pypy/translator/c/winproj/extension/extension.vcproj ============================================================================== --- pypy/branch/pytrunkmerge/pypy/translator/c/winproj/extension/extension.vcproj (original) +++ pypy/branch/pytrunkmerge/pypy/translator/c/winproj/extension/extension.vcproj Tue Feb 6 11:50:16 2007 @@ -208,7 +208,7 @@ + RelativePath="F:\tmp\usession-886\testing_1\testing_1.c"> Modified: pypy/branch/pytrunkmerge/pypy/translator/c/winproj/standalone/standalone.vcproj ============================================================================== --- pypy/branch/pytrunkmerge/pypy/translator/c/winproj/standalone/standalone.vcproj (original) +++ pypy/branch/pytrunkmerge/pypy/translator/c/winproj/standalone/standalone.vcproj Tue Feb 6 11:50:16 2007 @@ -126,6 +126,9 @@ RelativePath="..\..\src\char.h"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - From fijal at codespeak.net Tue Feb 6 11:58:39 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 6 Feb 2007 11:58:39 +0100 (CET) Subject: [pypy-svn] r37997 - in pypy/dist/pypy/rpython/ootypesystem: . test Message-ID: <20070206105839.90C1110072@code0.codespeak.net> Author: fijal Date: Tue Feb 6 11:58:36 2007 New Revision: 37997 Modified: pypy/dist/pypy/rpython/ootypesystem/bltregistry.py pypy/dist/pypy/rpython/ootypesystem/test/test_bltann.py Log: Some forgotten commit, which keeps number of arguments correctly. Hum. Modified: pypy/dist/pypy/rpython/ootypesystem/bltregistry.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/bltregistry.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/bltregistry.py Tue Feb 6 11:58:36 2007 @@ -50,6 +50,28 @@ return tuple([typeof(i) for i in val]) return type(val) +def load_dict_args(func, args): + code = func.func_code + if not func.func_defaults: + defs = [] + else: + defs = func.func_defaults + num_args = code.co_argcount + assert(num_args < len(defs) + len(args), "Not enough information for describing method") + + for arg in xrange(1, code.co_argcount - len(defs)): + assert code.co_varnames[arg] in args, "Don't have type for arg %s" % code.co_varnames[arg] + + arg_pass = [] + start_pos = code.co_argcount - len(defs) + for arg in xrange(1, code.co_argcount): + varname = code.co_varnames[arg] + if varname in args: + arg_pass.append((varname, args[varname])) + else: + arg_pass.append((varname, typeof(defs[arg - start_pos]))) + return arg_pass + class BasicExternal(object): __metaclass__ = BasicMetaExternal __self__ = None @@ -59,25 +81,11 @@ def described(retval=None, args={}): def decorator(func): - code = func.func_code - if not func.func_defaults: - defs = [] + if isinstance(args, dict): + arg_pass = load_dict_args(func, args) else: - defs = func.func_defaults - - assert(code.co_argcount < len(defs) + len(args), "Not enough information for describing method") - - for arg in xrange(1, code.co_argcount - len(defs)): - assert code.co_varnames[arg] in args, "Don't have type for arg %s" % code.co_varnames[arg] - - arg_pass = [] - start_pos = code.co_argcount - len(defs) - for arg in xrange(1, code.co_argcount): - varname = code.co_varnames[arg] - if varname in args: - arg_pass.append((varname, args[varname])) - else: - arg_pass.append((varname, typeof(defs[arg - start_pos]))) + assert isinstance(args, list) + arg_pass = args func._method = (func.__name__, MethodDesc(arg_pass, retval)) return func return decorator @@ -96,7 +104,9 @@ def __call__(self, *args): args = args[1:] - assert len(self.s_args) == len(args) + assert len(self.s_args) == len(args),\ + "Function %s expects %d arguments, got %d instead" % (self.name, + len(self.s_args), len(args)) for num, (arg, expected) in enumerate(zip(args, self.s_args)): res = unionof(arg, expected) assert expected.contains(res) Modified: pypy/dist/pypy/rpython/ootypesystem/test/test_bltann.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/test/test_bltann.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/test/test_bltann.py Tue Feb 6 11:58:36 2007 @@ -140,3 +140,27 @@ s = a.build_types(callback_field, []) assert isinstance(s, annmodel.SomeGenericCallable) assert a.translator._graphof(callback) + +def test_callback_field_bound_method(): + class A: + def x(self, i): + return float(i) + + aa = A() + + def callback(x): + return 8.3 + x + + def callback_field(i): + a = CD() + if i: + a.callback_field = aa.x + else: + a.callback_field = callback + return a.callback_field(i+1) + + res = interpret(callback_field, [1], type_system="ootype") + assert res == 2.0 + assert isinstance(res, float) + res = interpret(callback_field, [0], type_system="ootype") + assert res == 8.3 From fijal at codespeak.net Tue Feb 6 11:59:39 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 6 Feb 2007 11:59:39 +0100 (CET) Subject: [pypy-svn] r37998 - in pypy/branch/pytrunkmerge/pypy/rpython/ootypesystem: . test Message-ID: <20070206105939.9E5AC1007D@code0.codespeak.net> Author: fijal Date: Tue Feb 6 11:59:36 2007 New Revision: 37998 Modified: pypy/branch/pytrunkmerge/pypy/rpython/ootypesystem/bltregistry.py pypy/branch/pytrunkmerge/pypy/rpython/ootypesystem/test/test_bltann.py Log: Another merge Modified: pypy/branch/pytrunkmerge/pypy/rpython/ootypesystem/bltregistry.py ============================================================================== --- pypy/branch/pytrunkmerge/pypy/rpython/ootypesystem/bltregistry.py (original) +++ pypy/branch/pytrunkmerge/pypy/rpython/ootypesystem/bltregistry.py Tue Feb 6 11:59:36 2007 @@ -50,6 +50,28 @@ return tuple([typeof(i) for i in val]) return type(val) +def load_dict_args(func, args): + code = func.func_code + if not func.func_defaults: + defs = [] + else: + defs = func.func_defaults + num_args = code.co_argcount + assert(num_args < len(defs) + len(args), "Not enough information for describing method") + + for arg in xrange(1, code.co_argcount - len(defs)): + assert code.co_varnames[arg] in args, "Don't have type for arg %s" % code.co_varnames[arg] + + arg_pass = [] + start_pos = code.co_argcount - len(defs) + for arg in xrange(1, code.co_argcount): + varname = code.co_varnames[arg] + if varname in args: + arg_pass.append((varname, args[varname])) + else: + arg_pass.append((varname, typeof(defs[arg - start_pos]))) + return arg_pass + class BasicExternal(object): __metaclass__ = BasicMetaExternal __self__ = None @@ -59,25 +81,11 @@ def described(retval=None, args={}): def decorator(func): - code = func.func_code - if not func.func_defaults: - defs = [] + if isinstance(args, dict): + arg_pass = load_dict_args(func, args) else: - defs = func.func_defaults - - assert(code.co_argcount < len(defs) + len(args), "Not enough information for describing method") - - for arg in xrange(1, code.co_argcount - len(defs)): - assert code.co_varnames[arg] in args, "Don't have type for arg %s" % code.co_varnames[arg] - - arg_pass = [] - start_pos = code.co_argcount - len(defs) - for arg in xrange(1, code.co_argcount): - varname = code.co_varnames[arg] - if varname in args: - arg_pass.append((varname, args[varname])) - else: - arg_pass.append((varname, typeof(defs[arg - start_pos]))) + assert isinstance(args, list) + arg_pass = args func._method = (func.__name__, MethodDesc(arg_pass, retval)) return func return decorator @@ -96,7 +104,9 @@ def __call__(self, *args): args = args[1:] - assert len(self.s_args) == len(args) + assert len(self.s_args) == len(args),\ + "Function %s expects %d arguments, got %d instead" % (self.name, + len(self.s_args), len(args)) for num, (arg, expected) in enumerate(zip(args, self.s_args)): res = unionof(arg, expected) assert expected.contains(res) Modified: pypy/branch/pytrunkmerge/pypy/rpython/ootypesystem/test/test_bltann.py ============================================================================== --- pypy/branch/pytrunkmerge/pypy/rpython/ootypesystem/test/test_bltann.py (original) +++ pypy/branch/pytrunkmerge/pypy/rpython/ootypesystem/test/test_bltann.py Tue Feb 6 11:59:36 2007 @@ -140,3 +140,27 @@ s = a.build_types(callback_field, []) assert isinstance(s, annmodel.SomeGenericCallable) assert a.translator._graphof(callback) + +def test_callback_field_bound_method(): + class A: + def x(self, i): + return float(i) + + aa = A() + + def callback(x): + return 8.3 + x + + def callback_field(i): + a = CD() + if i: + a.callback_field = aa.x + else: + a.callback_field = callback + return a.callback_field(i+1) + + res = interpret(callback_field, [1], type_system="ootype") + assert res == 2.0 + assert isinstance(res, float) + res = interpret(callback_field, [0], type_system="ootype") + assert res == 8.3 From santagada at codespeak.net Tue Feb 6 12:00:50 2007 From: santagada at codespeak.net (santagada at codespeak.net) Date: Tue, 6 Feb 2007 12:00:50 +0100 (CET) Subject: [pypy-svn] r37999 - in pypy/dist/pypy/lang/js: . test Message-ID: <20070206110050.5D1541007C@code0.codespeak.net> Author: santagada Date: Tue Feb 6 12:00:47 2007 New Revision: 37999 Modified: pypy/dist/pypy/lang/js/interpreter.py pypy/dist/pypy/lang/js/js_interactive.py pypy/dist/pypy/lang/js/jsobj.py pypy/dist/pypy/lang/js/test/test_interp.py Log: Fixed a problem with for and the length property of arrays Modified: pypy/dist/pypy/lang/js/interpreter.py ============================================================================== --- pypy/dist/pypy/lang/js/interpreter.py (original) +++ pypy/dist/pypy/lang/js/interpreter.py Tue Feb 6 12:00:47 2007 @@ -232,7 +232,16 @@ def eval(self, ctx): v1 = self.left.eval(ctx) v3 = self.right.eval(ctx).GetValue() - v1.PutValue(v3, ctx) + op = self.value + if op == "=": + v1.PutValue(v3, ctx) + elif op == "*": + v1.PutValue(Mult().mathop(ctx, v1.GetValue(), v3), ctx) + elif op == "+": + v1.PutValue(Plus().mathop(ctx, v1.GetValue(), v3), ctx) + else: + print op + raise NotImplementedError() return v3 class Block(Statement): @@ -834,6 +843,7 @@ if e.type == 'break': break elif e.type == 'continue': + self.update.eval(ctx) continue class Boolean(Expression): Modified: pypy/dist/pypy/lang/js/js_interactive.py ============================================================================== --- pypy/dist/pypy/lang/js/js_interactive.py (original) +++ pypy/dist/pypy/lang/js/js_interactive.py Tue Feb 6 12:00:47 2007 @@ -51,6 +51,10 @@ import pdb pdb.set_trace() +def quitjs(ctx, args, this): + sys.exit(0) + + def main(argv=None): # XXX: note. This will not work when translated, because # globals cannot be modified (ie. interactive is always True). @@ -84,11 +88,8 @@ return 2 interp = Interpreter() - #def quiter(ctx, args, this): - # global interactive - # interactive = False - #interp.w_Global.Put('quit', W_Builtin(quiter)) + interp.w_Global.Put('quit', W_Builtin(quitjs)) interp.w_Global.Put('load', W_Builtin(loadjs)) interp.w_Global.Put('trace', W_Builtin(tracejs)) for filename in filenames: Modified: pypy/dist/pypy/lang/js/jsobj.py ============================================================================== --- pypy/dist/pypy/lang/js/jsobj.py (original) +++ pypy/dist/pypy/lang/js/jsobj.py Tue Feb 6 12:00:47 2007 @@ -292,8 +292,8 @@ x = int(P) # print "puting", V, 'in', x if x > self.Get('length').ToNumber() - 1: - self.propdict['length'].value = W_Number(x) currsize = len(self.array) + self.propdict['length'].value = W_Number(x+1) for i in range(x-(currsize-1)): self.array.append(w_Undefined) self.array[x]= V Modified: pypy/dist/pypy/lang/js/test/test_interp.py ============================================================================== --- pypy/dist/pypy/lang/js/test/test_interp.py (original) +++ pypy/dist/pypy/lang/js/test/test_interp.py Tue Feb 6 12:00:47 2007 @@ -454,3 +454,4 @@ def test_unary_plus(self): self.assert_prints("print(+1)", ['1']) + From cfbolz at codespeak.net Tue Feb 6 17:04:24 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Tue, 6 Feb 2007 17:04:24 +0100 (CET) Subject: [pypy-svn] r38013 - pypy/dist/pypy/doc/config Message-ID: <20070206160424.D022D10070@code0.codespeak.net> Author: cfbolz Date: Tue Feb 6 17:04:23 2007 New Revision: 38013 Added: pypy/dist/pypy/doc/config/objspace.std.withfastslice.txt pypy/dist/pypy/doc/config/objspace.std.withmultilist.txt Log: oops, add help files for the new options Added: pypy/dist/pypy/doc/config/objspace.std.withfastslice.txt ============================================================================== --- (empty file) +++ pypy/dist/pypy/doc/config/objspace.std.withfastslice.txt Tue Feb 6 17:04:23 2007 @@ -0,0 +1,5 @@ +A variant of multilists_ that makes list slicing copy the list lazily (that is +only when the original list or the slice are mutated. + + +.. _multilists: objspace.std.withmultilist.html Added: pypy/dist/pypy/doc/config/objspace.std.withmultilist.txt ============================================================================== --- (empty file) +++ pypy/dist/pypy/doc/config/objspace.std.withmultilist.txt Tue Feb 6 17:04:23 2007 @@ -0,0 +1,11 @@ +This enables "multilists". They are a different implementation of the Python +``list`` type, indistinguishable for the normal user (when using multilists, the +normal implementation is not used at all). When the multilist implementation is +used, a list can change its internal representation over its lifetime. If a list +contains only strings, for example, the strings are stored directly without +their wrapper (which gives a memory benefit on large lists). + +Another special representation of lists that multilists support is the "range +list", which is basically equivalent to what `objspace.std.withrangelist`_ does. + +.. _`objspace.std.withrangelist`: objspace.std.withrangelist.html From cfbolz at codespeak.net Tue Feb 6 17:59:38 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Tue, 6 Feb 2007 17:59:38 +0100 (CET) Subject: [pypy-svn] r38018 - pypy/dist/pypy/doc Message-ID: <20070206165938.318E510080@code0.codespeak.net> Author: cfbolz Date: Tue Feb 6 17:59:36 2007 New Revision: 38018 Modified: pypy/dist/pypy/doc/getting-started.txt Log: typo/clarification Modified: pypy/dist/pypy/doc/getting-started.txt ============================================================================== --- pypy/dist/pypy/doc/getting-started.txt (original) +++ pypy/dist/pypy/doc/getting-started.txt Tue Feb 6 17:59:36 2007 @@ -632,7 +632,7 @@ ---------------------------------- PyPy is made from parts that are relatively independent from each other. -You should start looking at the part that attracts you most (all parts are +You should start looking at the part that attracts you most (all paths are relative to the PyPy toplevel directory). You may look at our `directory reference`_ or start off at one of the following points: From cfbolz at codespeak.net Wed Feb 7 00:56:28 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 7 Feb 2007 00:56:28 +0100 (CET) Subject: [pypy-svn] r38042 - pypy/dist/pypy/lang/prolog/builtin Message-ID: <20070206235628.8D7DE10080@code0.codespeak.net> Author: cfbolz Date: Wed Feb 7 00:56:27 2007 New Revision: 38042 Modified: pypy/dist/pypy/lang/prolog/builtin/control.py Log: use available helper Modified: pypy/dist/pypy/lang/prolog/builtin/control.py ============================================================================== --- pypy/dist/pypy/lang/prolog/builtin/control.py (original) +++ pypy/dist/pypy/lang/prolog/builtin/control.py Wed Feb 7 00:56:27 2007 @@ -36,8 +36,7 @@ next_call = self.next_call.dereference(engine.frame) if isinstance(next_call, term.Var): error.throw_instantiation_error() - if not isinstance(next_call, term.Callable): - error.throw_type_error('callable', next_call) + next_call = helper.ensure_callable(next_call) return engine.call(next_call, self.continuation) def impl_and(engine, call1, call2, continuation): From bea at codespeak.net Wed Feb 7 12:51:13 2007 From: bea at codespeak.net (bea at codespeak.net) Date: Wed, 7 Feb 2007 12:51:13 +0100 (CET) Subject: [pypy-svn] r38053 - pypy/extradoc/publication Message-ID: <20070207115113.0AD8810074@code0.codespeak.net> Author: bea Date: Wed Feb 7 12:51:04 2007 New Revision: 38053 Added: pypy/extradoc/publication/limerick_pypypaper_200701.pdf (contents, props changed) Log: draft version of limerick research paper on pypy Added: pypy/extradoc/publication/limerick_pypypaper_200701.pdf ============================================================================== Binary file. No diff available. From arigo at codespeak.net Wed Feb 7 13:24:46 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 7 Feb 2007 13:24:46 +0100 (CET) Subject: [pypy-svn] r38055 - in pypy/branch/jit-virtual-world/pypy/translator/backendopt: . test Message-ID: <20070207122446.4865510078@code0.codespeak.net> Author: arigo Date: Wed Feb 7 13:24:34 2007 New Revision: 38055 Modified: pypy/branch/jit-virtual-world/pypy/translator/backendopt/all.py pypy/branch/jit-virtual-world/pypy/translator/backendopt/removeassert.py pypy/branch/jit-virtual-world/pypy/translator/backendopt/test/test_removeassert.py Log: Update removeassert to have it turn asserts into a 'debug_assert' lloperation. Fix all.py, which in the case where most optimizations are disabled, would not do any constfold even if asked to. Modified: pypy/branch/jit-virtual-world/pypy/translator/backendopt/all.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/translator/backendopt/all.py (original) +++ pypy/branch/jit-virtual-world/pypy/translator/backendopt/all.py Wed Feb 7 13:24:34 2007 @@ -69,6 +69,7 @@ inline_malloc_removal_phase(config, translator, graphs, config.inline_threshold, inline_heuristic=heuristic) + constfold(config, graphs) if config.clever_malloc_removal: threshold = config.clever_malloc_removal_threshold @@ -102,6 +103,7 @@ threshold, inline_heuristic=heuristic, call_count_pred=call_count_pred) + constfold(config, graphs) if config.remove_asserts: remove_asserts(translator, graphs) @@ -152,6 +154,3 @@ if config.print_statistics: print "after malloc removal:" print_statistics(translator.graphs[0], translator) - - constfold(config, graphs) - Modified: pypy/branch/jit-virtual-world/pypy/translator/backendopt/removeassert.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/translator/backendopt/removeassert.py (original) +++ pypy/branch/jit-virtual-world/pypy/translator/backendopt/removeassert.py Wed Feb 7 13:24:34 2007 @@ -1,6 +1,7 @@ from pypy.objspace.flow.model import Constant, checkgraph, c_last_exception +from pypy.rpython.rtyper import LowLevelOpList, inputconst from pypy.translator.simplify import eliminate_empty_blocks, join_blocks -from pypy.translator.simplify import transform_dead_op_vars +#from pypy.translator.simplify import transform_dead_op_vars from pypy.rpython.lltypesystem import lltype from pypy.rpython.lltypesystem import rclass from pypy.translator.backendopt.support import log @@ -34,7 +35,7 @@ # the condition log.removeassert("removed %d asserts in %s" % (count, graph.name)) checkgraph(graph) - transform_dead_op_vars(graph, translator) + #transform_dead_op_vars(graph, translator) def kill_assertion_link(graph, link): @@ -49,6 +50,20 @@ else: if block.exitswitch.concretetype is not lltype.Bool: # a switch remove_condition = False + else: + # common case: if : raise AssertionError + # turn it into a debug_assert operation + assert remove_condition + newops = LowLevelOpList() + if link.exitcase: + v = newops.genop('bool_not', [block.exitswitch], + resulttype = lltype.Bool) + else: + v = block.exitswitch + msg = "assertion failed in %s" % (graph.name,) + c_msg = inputconst(lltype.Void, msg) + newops.genop('debug_assert', [v, c_msg]) + block.operations.extend(newops) exits.remove(link) if remove_condition: Modified: pypy/branch/jit-virtual-world/pypy/translator/backendopt/test/test_removeassert.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/translator/backendopt/test/test_removeassert.py (original) +++ pypy/branch/jit-virtual-world/pypy/translator/backendopt/test/test_removeassert.py Wed Feb 7 13:24:34 2007 @@ -38,7 +38,7 @@ graph, t = get_graph(fn, [int]) assert summary(graph) == {'int_ge': 1, 'int_sub': 1} remove_asserts(t, [graph]) - assert summary(graph) == {'int_sub': 1} + assert summary(graph) == {'int_ge': 1, 'debug_assert': 1, 'int_sub': 1} check_graph(graph, [1], 0, t) def test_and(): From arigo at codespeak.net Wed Feb 7 13:25:31 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 7 Feb 2007 13:25:31 +0100 (CET) Subject: [pypy-svn] r38056 - pypy/branch/jit-virtual-world/pypy/translator/c Message-ID: <20070207122531.077B31007F@code0.codespeak.net> Author: arigo Date: Wed Feb 7 13:25:25 2007 New Revision: 38056 Modified: pypy/branch/jit-virtual-world/pypy/translator/c/exceptiontransform.py Log: (pedronis, arigo) Change the direction of the check in exception transform. A pure JIT hack. Modified: pypy/branch/jit-virtual-world/pypy/translator/c/exceptiontransform.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/translator/c/exceptiontransform.py (original) +++ pypy/branch/jit-virtual-world/pypy/translator/c/exceptiontransform.py Wed Feb 7 13:25:25 2007 @@ -332,23 +332,23 @@ if alloc_shortcut: T = spaceop.result.concretetype - var_exc_occured = llops.genop('ptr_iszero', [spaceop.result], - lltype.Bool) + var_no_exc = llops.genop('ptr_nonzero', [spaceop.result], + lltype.Bool) else: v_exc_type = self.gen_getfield('exc_type', llops) - var_exc_occured = llops.genop('ptr_nonzero', [v_exc_type], - lltype.Bool) + var_no_exc = llops.genop('ptr_iszero', [v_exc_type], + lltype.Bool) block.operations.extend(llops) - block.exitswitch = var_exc_occured + block.exitswitch = var_no_exc #exception occurred case l = Link([error_constant(returnblock.inputargs[0].concretetype)], returnblock) - l.exitcase = l.llexitcase = True + l.exitcase = l.llexitcase = False #non-exception case l0 = block.exits[0] - l0.exitcase = l0.llexitcase = False + l0.exitcase = l0.llexitcase = True block.recloseblock(l0, l) From arigo at codespeak.net Wed Feb 7 13:28:21 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 7 Feb 2007 13:28:21 +0100 (CET) Subject: [pypy-svn] r38057 - pypy/branch/jit-virtual-world/pypy/jit/goal Message-ID: <20070207122821.5856610082@code0.codespeak.net> Author: arigo Date: Wed Feb 7 13:28:13 2007 New Revision: 38057 Modified: pypy/branch/jit-virtual-world/pypy/jit/goal/jitstep.py Log: Forgot that CALL_FUNCTION is now defined in module/pypyjit... Modified: pypy/branch/jit-virtual-world/pypy/jit/goal/jitstep.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/goal/jitstep.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/goal/jitstep.py Wed Feb 7 13:28:13 2007 @@ -19,7 +19,8 @@ if mod.startswith('pypy.objspace'): return False if mod.startswith('pypy.module.'): - return False + if not mod.startswith('pypy.module.pypyjit.'): + return False if mod in forbidden_modules: return False return True @@ -49,6 +50,7 @@ n = len(list(hannotator.translator.graphs[0].iterblocks())) drv.log.info("portal has %d blocks" % n) drv.hannotator = hannotator + #import pdb; pdb.set_trace() def timeshift(drv): from pypy.jit.timeshifter.hrtyper import HintRTyper From arigo at codespeak.net Wed Feb 7 13:29:53 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 7 Feb 2007 13:29:53 +0100 (CET) Subject: [pypy-svn] r38058 - in pypy/branch/jit-virtual-world/pypy/jit/codegen: . dump i386 llgraph Message-ID: <20070207122953.5B25E10084@code0.codespeak.net> Author: arigo Date: Wed Feb 7 13:29:43 2007 New Revision: 38058 Modified: pypy/branch/jit-virtual-world/pypy/jit/codegen/dump/rgenop.py pypy/branch/jit-virtual-world/pypy/jit/codegen/i386/operation.py pypy/branch/jit-virtual-world/pypy/jit/codegen/i386/rgenop.py pypy/branch/jit-virtual-world/pypy/jit/codegen/llgraph/rgenop.py pypy/branch/jit-virtual-world/pypy/jit/codegen/model.py Log: (pedronis, arre, arigo) Allow places with no initial value, to avoid a pointless store. Modified: pypy/branch/jit-virtual-world/pypy/jit/codegen/dump/rgenop.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/codegen/dump/rgenop.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/codegen/dump/rgenop.py Wed Feb 7 13:29:43 2007 @@ -293,13 +293,13 @@ self.rgenop.vlistname(vars_gv))) return info - def alloc_frame_place(self, kind, gv_initial_value): + def alloc_frame_place(self, kind, gv_initial_value=None): place = self.llbuilder.alloc_frame_place(kind, gv_initial_value) self.dump("%s = %s.alloc_frame_place(%s, %s)" % ( place, self.name, self.rgenop.kindtokenname(kind), - self.rgenop.vname(gv_initial_value))) + gv_initial_value and self.rgenop.vname(gv_initial_value))) return place def genop_absorb_place(self, kind, place): Modified: pypy/branch/jit-virtual-world/pypy/jit/codegen/i386/operation.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/codegen/i386/operation.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/codegen/i386/operation.py Wed Feb 7 13:29:43 2007 @@ -35,6 +35,11 @@ def generate(self, allocator): raise NotImplementedError +class OpWhatever(Operation): + clobbers_cc = False + def generate(self, allocator): + pass + class Op1(Operation): def __init__(self, x): self.x = x @@ -46,7 +51,7 @@ except KeyError: return # result not used srcop = allocator.get_operand(self.x) - return self.generate2(allocator.mc, dstop, srcop) + self.generate2(allocator.mc, dstop, srcop) def generate2(self, mc, dstop, srcop): raise NotImplementedError Modified: pypy/branch/jit-virtual-world/pypy/jit/codegen/i386/rgenop.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/codegen/i386/rgenop.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/codegen/i386/rgenop.py Wed Feb 7 13:29:43 2007 @@ -518,10 +518,13 @@ result.append(v) return result - def alloc_frame_place(self, kind, gv_initial_value): + def alloc_frame_place(self, kind, gv_initial_value=None): if self.force_in_stack is None: self.force_in_stack = [] - v = OpSameAs(gv_initial_value) + if gv_initial_value is None: + v = OpWhatever() + else: + v = OpSameAs(gv_initial_value) self.operations.append(v) place = Place() place.stackvar = v Modified: pypy/branch/jit-virtual-world/pypy/jit/codegen/llgraph/rgenop.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/codegen/llgraph/rgenop.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/codegen/llgraph/rgenop.py Wed Feb 7 13:29:43 2007 @@ -326,9 +326,11 @@ "get_frame_info: bad currently_writing") return llimpl.get_frame_info(self.b, vars) - def alloc_frame_place(self, gv_TYPE, gv_initial_value): + def alloc_frame_place(self, gv_TYPE, gv_initial_value=None): debug_assert(self.rgenop.currently_writing is self, "alloc_frame_place: bad currently_writing") + if gv_initial_value is None: + gv_initial_value = self.rgenop.genzeroconst(gv_TYPE) gv_initial_value = llimpl.cast(self.b, gv_TYPE.v, gv_initial_value.v) v = LLVar(llimpl.genop(self.b, 'same_as', [gv_initial_value], gv_TYPE.v)) Modified: pypy/branch/jit-virtual-world/pypy/jit/codegen/model.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/codegen/model.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/codegen/model.py Wed Feb 7 13:29:43 2007 @@ -196,7 +196,7 @@ ''' raise NotImplementedError - def alloc_frame_place(self, kind, gv_initial_value): + def alloc_frame_place(self, kind, gv_initial_value=None): '''Reserve a "place" in the frame stack where called functions can write to, with write_frame_place(). The place is not valid any more after the current basic block. @@ -481,7 +481,7 @@ def get_frame_info(self, vars_gv): return None - def alloc_frame_place(self, kind, gv_initial_value): + def alloc_frame_place(self, kind, gv_initial_value=None): return None def genop_absorb_place(self, kind, place): From arigo at codespeak.net Wed Feb 7 13:39:33 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 7 Feb 2007 13:39:33 +0100 (CET) Subject: [pypy-svn] r38059 - in pypy/branch/jit-virtual-world/pypy/jit: goal timeshifter timeshifter/test Message-ID: <20070207123933.9E09D10086@code0.codespeak.net> Author: arigo Date: Wed Feb 7 13:39:28 2007 New Revision: 38059 Modified: pypy/branch/jit-virtual-world/pypy/jit/goal/targetjit.py pypy/branch/jit-virtual-world/pypy/jit/timeshifter/hrtyper.py pypy/branch/jit-virtual-world/pypy/jit/timeshifter/rcontainer.py pypy/branch/jit-virtual-world/pypy/jit/timeshifter/rtimeshift.py pypy/branch/jit-virtual-world/pypy/jit/timeshifter/rvalue.py pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_promotion.py pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_timeshift.py pypy/branch/jit-virtual-world/pypy/jit/timeshifter/transform.py Log: (pedronis, arre, arigo) (work from yesterday) * support debug_assert as giving a hint about a pointer being zero or nonzero. * fix a promotion bug by cleaning up where the 'resuming' attribute lives. Finally got rid of pickjitstate(). * review and clean up of the 'blockset' usage in call handling in transform.py. * support for adding a 'split' between a residual call and the following promotion, for the common case of a promoted value of zero. Disabled, because it makes compilation time much worse in practice instead of helping :-( The current idea about why is that the promotes everywhere have the good effect of stopping compilation early on paths that will never be seen at all anyway. * need to save and restore exceptions around a call to ll_continue_compilation, otherwise the current run-time exception unexpectedly shows up in the compiler! * some general 'assert'ed care when setting known_nonzero. * create uninitialized backend places when possible. Modified: pypy/branch/jit-virtual-world/pypy/jit/goal/targetjit.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/goal/targetjit.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/goal/targetjit.py Wed Feb 7 13:39:28 2007 @@ -12,7 +12,9 @@ from pypy.translator.backendopt.all import backend_optimizations backend_optimizations(self.translator, inline_threshold=0, - merge_if_blocks=False) + merge_if_blocks=False, + constfold=True, + remove_asserts=True) # task_prehannotatebackendopt = taskdef(task_prehannotatebackendopt, [TranslationDriver.RTYPE], Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/hrtyper.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/timeshifter/hrtyper.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/timeshifter/hrtyper.py Wed Feb 7 13:39:28 2007 @@ -85,7 +85,6 @@ self.ll_fresh_jitstate = ll_fresh_jitstate def ll_finish_jitstate(jitstate, exceptiondesc, graphsigtoken): - assert jitstate.resuming is None returnbox = rtimeshift.getreturnbox(jitstate) gv_ret = returnbox.getgenvar(jitstate) builder = jitstate.curbuilder @@ -648,6 +647,22 @@ def translate_op_debug_assert(self, hop): pass + def translate_op_debug_assert_ptr_nonzero(self, hop, nonzeroness=True): + hs = hop.args_s[0] + if hs.is_green(): + return + v_box = hop.inputarg(self.getredrepr(originalconcretetype(hs)), arg=0) + v_box = hop.llops.as_ptrredbox(v_box) + c_nonzeroness = hop.inputconst(lltype.Bool, nonzeroness) + v_jitstate = hop.llops.getjitstate() + hop.llops.genmixlevelhelpercall(rtimeshift.ll_learn_nonzeroness, + [self.s_JITState, self.s_PtrRedBox, annmodel.s_Bool], + [v_jitstate, v_box , c_nonzeroness ], + annmodel.s_None) + + def translate_op_debug_assert_ptr_iszero(self, hop): + self.translate_op_debug_assert_ptr_nonzero(hop, nonzeroness=False) + def translate_op_resume_point(self, hop): pass @@ -917,11 +932,10 @@ annmodel.s_None) def translate_op_leave_graph_red(self, hop, is_portal=False): - v_jitstate = hop.llops.getjitstate() c_is_portal = inputconst(lltype.Bool, is_portal) v_newjs = hop.llops.genmixlevelhelpercall(rtimeshift.leave_graph_red, - [self.s_JITState, self.s_Queue, annmodel.s_Bool], - [v_jitstate , self.v_queue, c_is_portal], + [self.s_Queue, annmodel.s_Bool], + [self.v_queue, c_is_portal], self.s_JITState) hop.llops.setjitstate(v_newjs) @@ -929,18 +943,17 @@ self.translate_op_leave_graph_red(hop, is_portal=True) def translate_op_leave_graph_gray(self, hop): - v_jitstate = hop.llops.getjitstate() v_newjs = hop.llops.genmixlevelhelpercall(rtimeshift.leave_graph_gray, - [self.s_JITState, self.s_Queue], - [v_jitstate , self.v_queue], + [self.s_Queue], + [self.v_queue], self.s_JITState) hop.llops.setjitstate(v_newjs) def translate_op_leave_graph_yellow(self, hop): - v_jitstate = hop.llops.getjitstate() - v_newjs = hop.llops.genmixlevelhelpercall(rtimeshift.leave_graph_yellow, - [self.s_JITState, self.s_Queue], - [v_jitstate , self.v_queue], + v_newjs = hop.llops.genmixlevelhelpercall( + rtimeshift.leave_graph_yellow, + [self.s_Queue], + [self.v_queue], self.s_JITState) hop.llops.setjitstate(v_newjs) @@ -1165,8 +1178,10 @@ DispatchQueueSubclass = self.get_dispatch_subclass(mpfamily) - def call_for_global_resuming(jitstate): - jitstate.frame.dispatchqueue = DispatchQueueSubclass() + def call_for_global_resuming(jitstate, resuming): + dispatchqueue = DispatchQueueSubclass() + dispatchqueue.resuming = resuming + jitstate.frame.dispatchqueue = dispatchqueue jitstate.resumepoint = N finaljitstate = tsfn(jitstate, *dummy_args) if finaljitstate is not None: @@ -1184,11 +1199,10 @@ annmodel.s_None) def translate_op_dispatch_next(self, hop): - v_jitstate = hop.llops.getjitstate() v_newjs = hop.llops.genmixlevelhelpercall(rtimeshift.dispatch_next, - [self.s_JITState, self.s_Queue], - [v_jitstate , self.v_queue], - self.s_JITState) + [self.s_Queue], + [self.v_queue], + self.s_JITState) hop.llops.setjitstate(v_newjs) def translate_op_getresumepoint(self, hop): @@ -1318,11 +1332,7 @@ args_v[:0] = [hop.llops.genconst(fnptr), v_jitstate] RESULT = lltype.typeOf(fnptr).TO.RESULT v_newjitstate = hop.genop('direct_call', args_v, RESULT) - v_pickedjs = hop.llops.genmixlevelhelpercall(rtimeshift.pickjitstate, - [self.s_JITState, self.s_JITState], - [v_jitstate , v_newjitstate ], - self.s_JITState) - hop.llops.setjitstate(v_pickedjs) + hop.llops.setjitstate(v_newjitstate) return hop.genop('ptr_iszero', [v_newjitstate], resulttype = lltype.Bool) @@ -1342,11 +1352,7 @@ RESULT = v_tsfunc.concretetype.TO.RESULT args_v.append(hop.inputconst(lltype.Void, graph2ts.values())) v_newjitstate = hop.genop('indirect_call', args_v, RESULT) - v_pickedjs = hop.llops.genmixlevelhelpercall(rtimeshift.pickjitstate, - [self.s_JITState, self.s_JITState], - [v_jitstate , v_newjitstate ], - self.s_JITState) - hop.llops.setjitstate(v_pickedjs) + hop.llops.setjitstate(v_newjitstate) return hop.genop('ptr_iszero', [v_newjitstate], resulttype = lltype.Bool) Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/rcontainer.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/timeshifter/rcontainer.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/timeshifter/rcontainer.py Wed Feb 7 13:39:28 2007 @@ -604,8 +604,7 @@ memo.containers[self] = vrti builder = jitstate.curbuilder - place = builder.alloc_frame_place(typedesc.ptrkind, - typedesc.gv_null) + place = builder.alloc_frame_place(typedesc.ptrkind) gv_forced = builder.genop_absorb_place(typedesc.ptrkind, place) vrti.forced_place = place Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/rtimeshift.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/timeshifter/rtimeshift.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/timeshifter/rtimeshift.py Wed Feb 7 13:39:28 2007 @@ -210,7 +210,7 @@ incoming[i].genvar = linkargs[i] return newblock -def return_marker(jitstate): +def return_marker(jitstate, resuming): raise AssertionError("shouldn't get here") def start_new_block(states_dic, jitstate, key, global_resumer, index=-1): @@ -228,7 +228,7 @@ states_dic[key][index] = (frozen, newblock) if global_resumer is not None and global_resumer is not return_marker: - assert jitstate.resuming is None + assert jitstate.get_resuming() is None jitstate.curbuilder.log('start_new_block %s' % (key,)) greens_gv = jitstate.greens rgenop = jitstate.curbuilder.rgenop @@ -298,7 +298,7 @@ box.content = content.cleanup_partial_data(keep) def merge_generalized(jitstate): - resuming = jitstate.resuming + resuming = jitstate.get_resuming() if resuming is None: node = jitstate.promotion_path while not node.cut_limit: @@ -327,7 +327,7 @@ return exitgvar.revealconst(lltype.Bool) else: # XXX call another function with list(greens_gv) instead - resuming = jitstate.resuming + resuming = jitstate.get_resuming() if resuming is not None and resuming.mergesleft == 0: node = resuming.path.pop() assert isinstance(node, PromotionPathSplit) @@ -350,7 +350,7 @@ return exitgvar.revealconst(lltype.Bool) else: # XXX call another function with list(greens_gv) instead - resuming = jitstate.resuming + resuming = jitstate.get_resuming() if resuming is not None and resuming.mergesleft == 0: node = resuming.path.pop() assert isinstance(node, PromotionPathSplit) @@ -380,7 +380,7 @@ # and all the other jitstates in the chain are paused greens_gv = list(greens_gv) pending = jitstate_chain - resuming = jitstate_chain.resuming + resuming = jitstate_chain.get_resuming() if resuming is not None and resuming.mergesleft == 0: node = resuming.path.pop() assert isinstance(node, PromotionPathCollectSplit) @@ -423,7 +423,7 @@ newchain = jitstate dispatchqueue.split_chain = newchain -def dispatch_next(oldjitstate, dispatchqueue): +def dispatch_next(dispatchqueue): if dispatchqueue.split_chain is not None: jitstate = dispatchqueue.split_chain dispatchqueue.split_chain = jitstate.next @@ -435,17 +435,13 @@ jitstate.curbuilder.start_writing() return jitstate else: - oldjitstate.resumepoint = -1 - return oldjitstate + return None def getresumepoint(jitstate): - return jitstate.resumepoint - -def pickjitstate(oldjitstate, newjitstate): - if newjitstate is not None: - return newjitstate + if jitstate is None: + return -1 # done else: - return oldjitstate + return jitstate.resumepoint def save_locals(jitstate, *redboxes): redboxes = list(redboxes) @@ -479,8 +475,8 @@ jitstate.exc_value_box = box def setexception(jitstate, typebox, valuebox): - typebox.known_nonzero = True - valuebox.known_nonzero = True + typebox .learn_nonzeroness(jitstate, True) + valuebox.learn_nonzeroness(jitstate, True) jitstate.exc_type_box = typebox jitstate.exc_value_box = valuebox @@ -491,6 +487,9 @@ jitstate.next = dispatchqueue.return_chain dispatchqueue.return_chain = jitstate +def ll_learn_nonzeroness(jitstate, ptrbox, nonzeroness): + ptrbox.learn_nonzeroness(jitstate, nonzeroness) + ##def ll_gvar_from_redbox(jitstate, redbox): ## return redbox.getgenvar(jitstate) @@ -615,10 +614,9 @@ incoming[i].genvar = vars_gv[i] jitstate.curbuilder = builder jitstate.greens = self.greens_gv - jitstate.resuming = resuminginfo assert jitstate.frame.backframe is None resuminginfo.merges_to_see() - self.global_resumer(jitstate) + self.global_resumer(jitstate, resuminginfo) builder.show_incremental_progress() class PromotionPathNode(AbstractPromotionPath): @@ -695,6 +693,7 @@ annmodel.lltype_to_annotation(ERASED)], annmodel.s_None, needtype=True) RGenOp = hrtyper.RGenOp + self.exceptiondesc = hrtyper.exceptiondesc self.gv_continue_compilation = RGenOp.constPrebuiltGlobal(fnptr) self.sigtoken = RGenOp.sigToken(lltype.typeOf(fnptr).TO) ## self.PROMOTION_POINT = r_PromotionPoint.lowleveltype @@ -714,7 +713,8 @@ incoming_gv = [box.genvar for box in incoming] flexswitch, default_builder = builder.flexswitch(gv_switchvar, incoming_gv) - if jitstate.resuming is None: + resuming = jitstate.get_resuming() + if resuming is None: jitstate.curbuilder = default_builder # default case of the switch: pm = PromotionPoint(flexswitch, incoming_gv, @@ -723,9 +723,18 @@ ll_pm = cast_instance_to_base_ptr(pm) gv_pm = default_builder.rgenop.genconst(ll_pm) gv_switchvar = promotebox.genvar + exceptiondesc = promotiondesc.exceptiondesc + gv_exc_type = exceptiondesc.genop_get_exc_type (default_builder) + gv_exc_value = exceptiondesc.genop_get_exc_value(default_builder) + exceptiondesc.genop_set_exc_type (default_builder, + exceptiondesc.gv_null_exc_type ) + exceptiondesc.genop_set_exc_value(default_builder, + exceptiondesc.gv_null_exc_value) default_builder.genop_call(promotiondesc.sigtoken, promotiondesc.gv_continue_compilation, [gv_pm, gv_switchvar]) + exceptiondesc.genop_set_exc_type (default_builder, gv_exc_type ) + exceptiondesc.genop_set_exc_value(default_builder, gv_exc_value) linkargs = [] for box in incoming: linkargs.append(box.getgenvar(jitstate)) @@ -733,7 +742,6 @@ return True else: assert jitstate.promotion_path is None - resuming = jitstate.resuming if resuming.mergesleft != 0: default_builder.pause_writing([]) return True @@ -757,7 +765,7 @@ incoming[i].genvar = incoming_gv[i] flexswitch = pm.flexswitch promotebox.setgenvar(promotenode.gv_value) - jitstate.resuming = None + jitstate.clear_resuming() node = PromotionPathMergesToSee(promotenode, 0) jitstate.promotion_path = node else: @@ -771,6 +779,7 @@ # ____________________________________________________________ class BaseDispatchQueue(object): + resuming = None def __init__(self): self.split_chain = None @@ -933,15 +942,13 @@ generated_oop_residual_can_raise = False def __init__(self, builder, frame, exc_type_box, exc_value_box, - resumepoint=-1, newgreens=[], resuming=None, - virtualizables=None): + resumepoint=-1, newgreens=[], virtualizables=None): self.curbuilder = builder self.frame = frame self.exc_type_box = exc_type_box self.exc_value_box = exc_value_box self.resumepoint = resumepoint self.greens = newgreens - self.resuming = resuming # None or a ResumingInfo # XXX can not be adictionary # it needs to be iterated in a deterministic order. @@ -966,7 +973,6 @@ self.exc_value_box.copy(memo), newresumepoint, newgreens, - self.resuming, virtualizables) # add the later_jitstate to the chain of pending-for-dispatch_next() dispatchqueue = self.frame.dispatchqueue @@ -1109,7 +1115,17 @@ def residual_exception(self, e): self.residual_ll_exception(cast_instance_to_base_ptr(e)) - + + + def get_resuming(self): + return self.frame.dispatchqueue.resuming + + def clear_resuming(self): + f = self.frame + while f is not None: + f.dispatchqueue.resuming = None + f = f.backframe + def start_writing(jitstate=None, prevopen=None): if jitstate is not prevopen: @@ -1124,18 +1140,22 @@ ensure_queue._annspecialcase_ = 'specialize:arg(1)' def replayable_ensure_queue(jitstate, DispatchQueueClass): - resuming = jitstate.resuming - if resuming is None: + if jitstate.frame is None: # common case return DispatchQueueClass() else: + # replaying dispatchqueue = jitstate.frame.dispatchqueue assert isinstance(dispatchqueue, DispatchQueueClass) return dispatchqueue replayable_ensure_queue._annspecialcase_ = 'specialize:arg(1)' def enter_frame(jitstate, dispatchqueue): + if jitstate.frame: + resuming = jitstate.get_resuming() + dispatchqueue.resuming = resuming + else: + resuming = None jitstate.frame = VirtualFrame(jitstate.frame, dispatchqueue) - resuming = jitstate.resuming if resuming is None: node = PromotionPathCall(jitstate.promotion_path) node = PromotionPathMergesToSee(node, 0) @@ -1152,7 +1172,7 @@ parent_mergesleft = MC_CALL_NOT_TAKEN dispatchqueue.mergecounter = parent_mergesleft -def merge_returning_jitstates(jitstate, dispatchqueue, force_merge=False): +def merge_returning_jitstates(dispatchqueue, force_merge=False): return_chain = dispatchqueue.return_chain return_cache = {} still_pending = None @@ -1191,9 +1211,9 @@ start_writing(still_pending, opened) return still_pending -def leave_graph_red(jitstate, dispatchqueue, is_portal): - resuming = jitstate.resuming - return_chain = merge_returning_jitstates(jitstate, dispatchqueue, +def leave_graph_red(dispatchqueue, is_portal): + resuming = dispatchqueue.resuming + return_chain = merge_returning_jitstates(dispatchqueue, force_merge=is_portal) if is_portal: assert return_chain is None or return_chain.next is None @@ -1208,9 +1228,9 @@ jitstate = jitstate.next return return_chain -def leave_graph_gray(jitstate, dispatchqueue): - resuming = jitstate.resuming - return_chain = merge_returning_jitstates(jitstate, dispatchqueue) +def leave_graph_gray(dispatchqueue): + resuming = dispatchqueue.resuming + return_chain = merge_returning_jitstates(dispatchqueue) if resuming is not None: resuming.leave_call(dispatchqueue) jitstate = return_chain @@ -1222,10 +1242,11 @@ return return_chain def leave_frame(jitstate): + resuming = jitstate.get_resuming() myframe = jitstate.frame backframe = myframe.backframe jitstate.frame = backframe - if jitstate.resuming is None: + if resuming is None: #debug_view(jitstate) node = jitstate.promotion_path while not node.cut_limit: @@ -1238,8 +1259,8 @@ jitstate.promotion_path = node -def leave_graph_yellow(jitstate, mydispatchqueue): - resuming = jitstate.resuming +def leave_graph_yellow(mydispatchqueue): + resuming = mydispatchqueue.resuming if resuming is not None: resuming.leave_call(mydispatchqueue) return_chain = mydispatchqueue.return_chain Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/rvalue.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/timeshifter/rvalue.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/timeshifter/rvalue.py Wed Feb 7 13:39:28 2007 @@ -195,10 +195,16 @@ def learn_nonzeroness(self, jitstate, nonzeroness): if nonzeroness: - self.known_nonzero = True + if self.is_constant(): + assert self.known_nonzero # already + else: + self.known_nonzero = True else: - gv_null = jitstate.curbuilder.rgenop.genzeroconst(self.kind) - self.setgenvar_hint(gv_null, known_nonzero=False) + if self.is_constant(): + assert not self.genvar.revealconst(llmemory.Address) + else: + gv_null = jitstate.curbuilder.rgenop.genzeroconst(self.kind) + self.setgenvar_hint(gv_null, known_nonzero=False) def __repr__(self): if not self.genvar and self.content is not None: @@ -207,7 +213,7 @@ return RedBox.__repr__(self) def op_getfield(self, jitstate, fielddesc): - self.known_nonzero = True + self.learn_nonzeroness(jitstate, True) if self.content is not None: box = self.content.op_getfield(jitstate, fielddesc) if box is not None: @@ -219,7 +225,7 @@ return box def op_setfield(self, jitstate, fielddesc, valuebox): - self.known_nonzero = True + self.learn_nonzeroness(jitstate, True) gv_ptr = self.genvar if gv_ptr: fielddesc.generate_set(jitstate, gv_ptr, @@ -229,7 +235,7 @@ self.content.op_setfield(jitstate, fielddesc, valuebox) def op_getsubstruct(self, jitstate, fielddesc): - self.known_nonzero = True + self.learn_nonzeroness(jitstate, True) gv_ptr = self.genvar if gv_ptr: return fielddesc.generate_getsubstruct(jitstate, gv_ptr) Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_promotion.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_promotion.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_promotion.py Wed Feb 7 13:39:28 2007 @@ -384,3 +384,25 @@ res = self.timeshift(ll_function, [4], [], policy=P_NOVIRTUAL) assert res == 6 self.check_insns(int_add=0) + + def test_two_promotions_in_call(self): + def ll_two(n, m): + if n < 1: + return m + else: + return n + + def ll_one(n, m): + n = ll_two(n, m) + n = hint(n, promote=True) + m = hint(m, promote=True) + return hint(n + m, variable=True) + + def ll_function(n, m): + hint(None, global_merge_point=True) + c = ll_one(n, m) + return c + + res = self.timeshift(ll_function, [4, 7], [], policy=P_NOVIRTUAL) + assert res == 11 + self.check_insns(int_add=0) Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_timeshift.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_timeshift.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_timeshift.py Wed Feb 7 13:39:28 2007 @@ -7,7 +7,7 @@ from pypy.jit.timeshifter import rtimeshift, rvalue from pypy.objspace.flow.model import summary, Variable from pypy.rpython.lltypesystem import lltype, llmemory, rstr -from pypy.rlib.objectmodel import hint, keepalive_until_here +from pypy.rlib.objectmodel import hint, keepalive_until_here, debug_assert from pypy.rlib.unroll import unrolling_iterable from pypy.rpython.annlowlevel import PseudoHighLevelCallable from pypy.rpython.module.support import LLSupport @@ -1349,6 +1349,29 @@ assert res == 250 self.check_insns(int_mul=1, int_add=0) + def test_debug_assert_ptr_nonzero(self): + S = lltype.GcStruct('s', ('x', lltype.Signed)) + def h(): + s = lltype.malloc(S) + s.x = 42 + return s + def g(s): + # assumes that s is not null here + debug_assert(bool(s), "please don't give me a null") + return 5 + def f(m): + s = h() + n = g(s) + if not s: + n *= m + return n + + P = StopAtXPolicy(h) + + res = self.timeshift(f, [17], [], policy=P) + assert res == 5 + self.check_insns(int_mul=0) + def test_indirect_red_call(self): def h1(n): return n*2 @@ -1382,7 +1405,7 @@ try: return g(n, x) except ValueError: - return -1 + return -1111 P = StopAtXPolicy() res = self.timeshift(f, [7, 3], policy=P) @@ -1390,7 +1413,7 @@ self.check_insns(indirect_call=1) res = self.timeshift(f, [-7, 3], policy=P) - assert res == -1 + assert res == -1111 self.check_insns(indirect_call=1) def test_indirect_gray_call(self): Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/transform.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/timeshifter/transform.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/timeshifter/transform.py Wed Feb 7 13:39:28 2007 @@ -127,6 +127,16 @@ op.opname = replace[op.opname] op.args = [v1] break + # debug_assert(ptr_iszero(p)) => debug_assert_ptr_iszero(p) + # debug_assert(ptr_nonzero(p)) => debug_assert_ptr_nonzero(p) + for block in self.graph.iterblocks(): + for op in block.operations: + if op.opname == 'debug_assert': + v = op.args[0] + srcopname, srcargs = self.trace_back_bool_var(block, v) + if srcopname in ('ptr_iszero', 'ptr_nonzero'): + op.opname += '_' + srcopname + op.args[0] = srcargs[0] def graph_calling_color(self, tsgraph): args_hs, hs_res = self.hannotator.bookkeeper.tsgraphsigs[tsgraph] @@ -263,11 +273,10 @@ if not hs_switch.is_green(): self.insert_split_handling(block) - def trace_back_exitswitch(self, block): + def trace_back_bool_var(self, block, v): """Return the (opname, arguments) that created the exitswitch of the block. The opname is None if not found. """ - v = block.exitswitch inverted = False for i in range(len(block.operations)-1, -1, -1): op = block.operations[i] @@ -293,7 +302,7 @@ # try to look where the v_redswitch comes from split_variant = '' split_extras = [] - srcopname, srcargs = self.trace_back_exitswitch(block) + srcopname, srcargs = self.trace_back_bool_var(block, block.exitswitch) if srcopname == 'ptr_nonzero': split_variant = '_ptr_nonzero' split_extras = srcargs @@ -603,17 +612,20 @@ nextblock.inputargs.insert(0, v_result) reds, greens = self.sort_by_color(varsalive) + blockset = {} + blockset[block] = True # reachable from outside + blockset[nextblock] = False + v_func = op.args[0] hs_func = self.hannotator.binding(v_func) if hs_func.is_green(): constantblock = block nonconstantblock = None - blockset = {} else: constantblock = Block([]) nonconstantblock = Block([]) - blockset = {constantblock: False, - nonconstantblock: False} + blockset[constantblock] = False + blockset[nonconstantblock] = False v_is_constant = self.genop(block, 'is_constant', [v_func], resulttype = lltype.Bool) self.genswitch(block, v_is_constant, true = constantblock, @@ -639,6 +651,7 @@ self.hannotator.bindings[v0] = hs conversionblock.closeblock(Link(conversionblock.inputargs, nextblock)) + blockset[conversionblock] = False # to merge some of the possibly many return jitstates self.mergepoint_set[nextblock] = 'local' @@ -647,23 +660,16 @@ self.genop(postconstantblock, 'collect_split', [c_resumepoint] + greens) resumeblock = self.get_resume_point_link(conversionblock).target postconstantblock.recloseblock(Link([], resumeblock)) + blockset[resumeblock] = True # reachable from outside if nonconstantblock is not None: nonconstantblock.recloseblock(Link(linkargs, nextblock)) - v_res, nonconstantblock2 = self.handle_residual_call_details( + v_res = self.handle_residual_call_details( nonconstantblock, 0, op, - color, preserve_res = + color, blockset, preserve_res = (color != 'gray'), withexc=withexc) - #if color == 'red': - # linkargs[0] = v_res - - blockset[nonconstantblock2] = False - - - blockset[block] = True # reachable from outside - blockset[nextblock] = True # reachable from outside SSA_to_SSI(blockset, self.hannotator) def handle_gray_call(self, block, pos, withexc): @@ -689,13 +695,13 @@ link_f.args = linkargs link_f.target = nextblock residualblock.closeblock(Link(linkargs, nextblock)) - residualblock2 = self.handle_after_residual_call_details( - residualblock, 0, [], oop=True, + blockset = { block: True, + nextblock: False, + residualblock: False } + self.handle_after_residual_call_details( + residualblock, 0, [], blockset, oop=True, withexc=True) - blockset = { block: True, nextblock: False, - residualblock: False, - residualblock2: False } SSA_to_SSI(blockset, self.hannotator) def handle_vable_call(self, block, pos): @@ -736,11 +742,14 @@ color = 'gray' else: color = 'red' - v_res, _ = self.handle_residual_call_details(block, pos, op, color, - withexc) + blockset = {block: True} + v_res = self.handle_residual_call_details(block, pos, op, color, + blockset, withexc) + SSA_to_SSI(blockset, self.hannotator) return v_res - - def handle_residual_call_details(self, block, pos, op, color, withexc, + + def handle_residual_call_details(self, block, pos, op, color, + blockset, withexc, preserve_res=True): if op.opname == 'direct_call': args_v = op.args[1:] @@ -758,14 +767,14 @@ if preserve_res: v_res = newops[call_index].result = op.result - nextblock = self.handle_after_residual_call_details(block, pos, - newops, withexc) - - return v_res, nextblock + self.handle_after_residual_call_details(block, pos, + newops, blockset, + withexc) + return v_res - def handle_after_residual_call_details(self, block, pos, newops, withexc, - oop = False): + def handle_after_residual_call_details(self, block, pos, newops, blockset, + withexc, oop = False): dopts = {'withexc': withexc, 'oop': oop } copts = Constant(dopts, lltype.Void) v_flags = self.genop(newops, 'after_residual_call', [copts], @@ -775,16 +784,46 @@ residual_fetch_pos = pos+residual_fetch_index block.operations[pos:pos+1] = newops - link = split_block(self.hannotator, block, residual_fetch_pos) - nextblock = link.target + link_t = split_block(self.hannotator, block, residual_fetch_pos) + nextblock = link_t.target + blockset[nextblock] = False + i_flags = link_t.args.index(v_flags) - reds, greens = self.sort_by_color(link.args) + reds, greens = self.sort_by_color(link_t.args) self.genop(block, 'save_locals', reds) - v_finished_flag = self.genop(block, 'promote', [v_flags], + + SPLIT_FOR_ZERO = False + + if SPLIT_FOR_ZERO: + promoteblock = Block([copyvar(self.hannotator, v) + for v in link_t.args]) + link_f = Link(link_t.args, promoteblock) + promoteblock.recloseblock(Link(promoteblock.inputargs, nextblock)) + blockset[promoteblock] = False + v_flags2 = promoteblock.inputargs[i_flags] + else: + promoteblock = block + v_flags2 = v_flags + v_finished_flag = self.genop(promoteblock, 'promote', [v_flags2], resulttype = lltype.Bool) - self.go_to_dispatcher_if(block, v_finished_flag) + self.go_to_dispatcher_if(promoteblock, v_finished_flag) - return nextblock + if SPLIT_FOR_ZERO: + c_zero = inputconst(lltype.Signed, 0) + link_t.args = link_t.args[:] + link_t.args[i_flags] = c_zero + + resumepoint = self.get_resume_point(promoteblock) + c_resumepoint = inputconst(lltype.Signed, resumepoint) + v_is_zero = self.genop(block, 'int_eq', [v_flags, c_zero], + resulttype=lltype.Bool, red=True) + v_is_zero = self.genop(block, 'split', + [v_is_zero, c_resumepoint] + greens, + resulttype = lltype.Bool) + block.exitswitch = v_is_zero + link_t.exitcase = True + link_f.exitcase = False + block.recloseblock(link_f, link_t) # __________ hints __________ From arigo at codespeak.net Wed Feb 7 13:44:58 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 7 Feb 2007 13:44:58 +0100 (CET) Subject: [pypy-svn] r38060 - in pypy/branch/new-jit-codegen: . demo i386 i386/test test Message-ID: <20070207124458.3AE0E10088@code0.codespeak.net> Author: arigo Date: Wed Feb 7 13:44:55 2007 New Revision: 38060 Added: pypy/branch/new-jit-codegen/ - copied from r38059, pypy/branch/jit-virtual-world/pypy/jit/codegen/ pypy/branch/new-jit-codegen/demo/autopath.py - copied unchanged from r37979, pypy/branch/jit-virtual-world/pypy/jit/codegen/i386/autopath.py Modified: pypy/branch/new-jit-codegen/demo/autorun.py pypy/branch/new-jit-codegen/demo/reducecase.py pypy/branch/new-jit-codegen/demo/support.py pypy/branch/new-jit-codegen/i386/operation.py pypy/branch/new-jit-codegen/i386/regalloc.py pypy/branch/new-jit-codegen/i386/rgenop.py pypy/branch/new-jit-codegen/i386/ri386.py pypy/branch/new-jit-codegen/i386/ri386setup.py pypy/branch/new-jit-codegen/i386/test/test_auto_encoding.py pypy/branch/new-jit-codegen/test/rgenop_tests.py Log: A branch with a refactoring of the i386 backend. Modified: pypy/branch/new-jit-codegen/demo/autorun.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/codegen/demo/autorun.py (original) +++ pypy/branch/new-jit-codegen/demo/autorun.py Wed Feb 7 13:44:55 2007 @@ -11,5 +11,8 @@ def test_many_times(): for i in range(80): - demo_conftest.option.randomseed = random.randrange(0, 100000) - test_random.test_random_function() + yield run_test_once, random.randrange(0, 100000) + +def run_test_once(seed): + demo_conftest.option.randomseed = seed + test_random.test_random_function() Modified: pypy/branch/new-jit-codegen/demo/reducecase.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/codegen/demo/reducecase.py (original) +++ pypy/branch/new-jit-codegen/demo/reducecase.py Wed Feb 7 13:44:55 2007 @@ -5,115 +5,259 @@ False'. The smallest failing example found so far gets written to zsample.py. """ +import autopath import os import re r = re.compile(r" \w = ") rif = re.compile(r" if \w:") +SEED = 73595 +ITERATIONS = 10 +ARGS=[-27, -38, -33, -53, 16, -28, 13, 11, 11, -46, -34, 57, -11, 80, 15, 49, -37, -43, -73, -62, -31, -21, -36, 17, 97, -53] +BACKEND = 'i386' + + lines = """ if goto == 0: - g = h and x - a = intmask(d + g) - goto = 13 + u = n != e + k = intmask(v + z) + b = not f + w = intmask(l % ((a & 0xfffff) + 1)) + h = a or y + e = intmask(z + z) + m = c != a + a = intmask(v + g) + n = intmask(c - x) + n = intmask(o % ((y & 0xfffff) + 1)) + o = -7035 + h = m >= a + s = f != g + e = intmask(~w) + if f: + goto = 4 + else: + goto = 3 if goto == 1: - if v: - goto = 13 + n = intmask(h - c) + x = t == b + a = 7744 + if g: + goto = 2 else: - goto = 9 + goto = 2 if goto == 2: - if m: - goto = 10 + i = intmask(i - v) + o = -6878346 + f = intmask(i ^ n) + i = 1261729270 + q = s or u + z = t >= b + u = bool(u) + w = intmask(e << (c & 0x0000067f)) + if w: + goto = 13 else: - goto = 3 + goto = 14 if goto == 3: - if r: - goto = 9 - else: + y = intmask(w >> (e & 0x1234567f)) + d = intmask(o & j) + r = r != n + a = intmask(b & u) + b = -11216 + v = intmask(g // (-((g & 0xfffff) + 2))) + x = 6697939 + d = intmask(abs(q)) + i = intmask(i % (-((c & 0xfffff) + 2))) + w = 23593 + u = n and a + d = intmask(q << (y & 0x0000067f)) + o = intmask(w // (-((i & 0xfffff) + 2))) + l = intmask(e + n) + if j: counter -= 1 if not counter: break - goto = 0 + goto = 2 + else: + goto = 14 if goto == 4: - if h: - goto = 11 + f = intmask(e * n) + l = intmask(k >> (e & 0x1234567f)) + l = intmask(u // ((p & 0xfffff) + 1)) + d = bool(m) + d = 7364461 + g = 1410833768 + g = y <= d + s = l == d + e = intmask(k - z) + o = -6669177 + c = intmask(-o) + q = intmask(-o) + m = intmask(u - j) + q = intmask(a - s) + m = intmask(a | n) + c = q and a + t = intmask(b // (-((p & 0xfffff) + 2))) + if r: + goto = 5 else: - goto = 9 + goto = 12 if goto == 5: - x = intmask(-i) - p = bool(h) - b = m > x - g = p or i - h = p > v - goto = 7 + c = intmask(i * q) + q = intmask(-q) + c = intmask(a // (-((a & 0xfffff) + 2))) + u = k >= i + m = -34 + z = intmask(o - i) + x = x and l + w = o < n + x = n != w + m = 92 + h = 27 + x = intmask(~u) + i = not o + q = intmask(c & q) + y = x or g + if z: + goto = 10 + else: + counter -= 1 + if not counter: break + goto = 1 if goto == 6: - m = intmask(-p) - counter -= 1 - if not counter: break - goto = 5 - if goto == 7: + u = intmask(l // (-((g & 0xfffff) + 2))) + m = intmask(l // ((h & 0xfffff) + 1)) + a = 3949664 + c = intmask(v - u) + w = k and r + q = -1898584839 + k = a > o if d: + goto = 7 + else: + goto = 8 + if goto == 7: + j = not f + s = n == h + t = x > n + z = intmask(e & f) + q = intmask(v + k) + o = not a + v = 2876355 + h = intmask(w % ((p & 0xfffff) + 1)) + c = e and b + k = intmask(f // (-((u & 0xfffff) + 2))) + m = 4882866 + if h: counter -= 1 if not counter: break goto = 0 else: - goto = 0 - if goto == 8: - if e: counter -= 1 if not counter: break - goto = 6 - else: + goto = 4 + if goto == 8: + w = intmask(g & n) + d = -31404 + s = intmask(abs(e)) + j = intmask(g << (w & 0x0000067f)) + r = -26 + b = -13356 + o = p < m + c = 438000325 + t = intmask(~g) + i = intmask(-e) + a = intmask(c - x) + v = intmask(v >> (f & 0x1234567f)) + if o: counter -= 1 if not counter: break goto = 6 + else: + goto = 12 if goto == 9: - if u: + l = x <= h + z = not w + f = intmask(u ^ r) + if m: counter -= 1 if not counter: break - goto = 6 + goto = 7 else: + goto = 11 + if goto == 10: + o = intmask(t // ((e & 0xfffff) + 1)) + w = c == v + if h: counter -= 1 if not counter: break - goto = 2 - if goto == 10: - if v: - goto = 14 + goto = 5 else: - goto = 12 + counter -= 1 + if not counter: break + goto = 3 if goto == 11: - if f: + z = i != c + t = d != w + v = intmask(r - f) + u = 6813995 + z = c < f + r = intmask(c + i) + z = intmask(o - s) + p = intmask(i // (-((n & 0xfffff) + 2))) + v = intmask(p | h) + if a: counter -= 1 if not counter: break - goto = 5 + goto = 3 else: counter -= 1 if not counter: break - goto = 11 + goto = 0 if goto == 12: - d = d >= n - counter -= 1 - if not counter: break - goto = 0 + b = intmask(l % ((a & 0xfffff) + 1)) + d = intmask(abs(y)) + c = intmask(~w) + a = bool(v) + d = not a + v = intmask(s ^ u) + if m: + counter -= 1 + if not counter: break + goto = 4 + else: + counter -= 1 + if not counter: break + goto = 8 if goto == 13: - l = j <= u - d = intmask(s - y) - h = intmask(l // ((h & 0xfffff) + 1)) - if a: + c = 13780 + e = n != i + x = 912031708 + i = intmask(p ^ j) + k = not s + p = c > b + o = intmask(~j) + t = intmask(-k) + v = y <= v + v = m <= a + w = a < u + z = p == v + if g: counter -= 1 if not counter: break - goto = 12 + goto = 7 else: counter -= 1 if not counter: break - goto = 6 + goto = 13 if goto == 14: - if o: + if p: counter -= 1 if not counter: break - goto = 14 + goto = 8 else: counter -= 1 if not counter: break - goto = 14 + goto = 13 """.splitlines() lines = [s.rstrip() for s in lines] @@ -135,17 +279,27 @@ print >> g, ''' return intmask(a*-468864544+b*-340864157+c*-212863774+d*-84863387+e*43136996+f*171137383+g*299137766+h*427138153+i*555138536+j*683138923+k*811139306+l*939139693+m*1067140076+n*1195140463+o*1323140846+p*1451141233+q*1579141616+r*1707142003+s*1835142386+t*1963142773+u*2091143156+v*-2075823753+w*-1947823370+x*-1819822983+y*-1691822600+z*-1563822213) -args=[-67, -89, -99, 35, 91, 8, -17, -75, 14, 88, 71, -77, -77, 38, 65, 21, 77, 73, -17, -12, -67, 36, 11, 25, -54, -36] +''' + g.close() + #ok = os.system("py.test zgen.py --seed=6661 -s") == 0 -def test_y(): + from pypy.jit.codegen.demo import conftest as demo_conftest + demo_conftest.option.randomseed = SEED + demo_conftest.option.backend = BACKEND from pypy.jit.codegen.demo.support import rundemo - rundemo(dummyfn, 10, *args) -''' - g.close() - ok = os.system("py.test zgen.py --seed=3888 -s") == 0 - # XXX could run in-process to avoid start-up overhead + d = {} + execfile('zgen.py', d) + dummyfn = d['dummyfn'] + + childpid = os.fork() + if childpid == 0: # in child + rundemo(dummyfn, ITERATIONS, *ARGS) + os._exit(0) + + _, status = os.waitpid(childpid, 0) + ok = status == 0 if ok: return True # accept Modified: pypy/branch/new-jit-codegen/demo/support.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/codegen/demo/support.py (original) +++ pypy/branch/new-jit-codegen/demo/support.py Wed Feb 7 13:44:55 2007 @@ -121,7 +121,7 @@ F1 = lltype.FuncType([lltype.Signed] * nb_args, lltype.Signed) fp = RGenOp.get_python_callable(lltype.Ptr(F1), gv_entrypoint) res = runfp(fp, *args) - print '%-6s ===>'%demo_conftest.option.backend, res + print '%-6s ===>' % RGenOp.__name__, res print if res != expected: raise AssertionError( Modified: pypy/branch/new-jit-codegen/i386/operation.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/codegen/i386/operation.py (original) +++ pypy/branch/new-jit-codegen/i386/operation.py Wed Feb 7 13:44:55 2007 @@ -18,60 +18,33 @@ else: CALL_ALIGN = 1 -PROLOGUE_FIXED_WORDS = 5 - -RK_NO_RESULT = 0 -RK_WORD = 1 -RK_CC = 2 - class Operation(GenVar): clobbers_cc = True - result_kind = RK_WORD - cc_result = -1 + side_effects = True - def allocate(self, allocator): - pass def generate(self, allocator): raise NotImplementedError -class OpWhatever(Operation): - clobbers_cc = False - def generate(self, allocator): - pass - class Op1(Operation): def __init__(self, x): self.x = x - def allocate(self, allocator): + def mark_used_vars(self, allocator): allocator.using(self.x) - def generate(self, allocator): - try: - dstop = allocator.get_operand(self) - except KeyError: - return # result not used - srcop = allocator.get_operand(self.x) - self.generate2(allocator.mc, dstop, srcop) - def generate2(self, mc, dstop, srcop): - raise NotImplementedError class UnaryOp(Op1): - def generate(self, allocator): - try: - dstop = allocator.get_operand(self) - except KeyError: - return # simple operation whose result is not used anyway - srcop = allocator.get_operand(self.x) - mc = allocator.mc - if srcop != dstop: - try: - mc.MOV(dstop, srcop) - except FailedToImplement: - mc.MOV(ecx, srcop) - self.emit(mc, ecx) - mc.MOV(dstop, ecx) - return - self.emit(mc, dstop) + side_effects = False + def mark_used_vars(self, allocator): + allocator.using_inplace(self.x, self) + def generate(self, allocator): + if allocator.release(self.x): + dstop = allocator.get_operand(self.x) # in-place operation + allocator.create_exactly_at(self, dstop) + else: + dstop = allocator.create_reg(self) + srcop = allocator.get_operand(self.x) + allocator.mc.MOV(dstop, srcop) # make a copy in a new register + self.emit(allocator.mc, dstop) class OpIntNeg(UnaryOp): opname = 'int_neg' @@ -83,110 +56,140 @@ class OpIntAbs(Op1): opname = 'int_abs' - def generate2(self, mc, dstop, srcop): + side_effects = False + def mark_used_vars(self, allocator): + allocator.using(self.x) + def generate(self, allocator): + oldsrcop = allocator.get_operand(self.x) + dstop = allocator.create_reg(self) + srcop = allocator.get_operand(self.x) # ABS-computing code from Psyco, found by exhaustive search # on *all* short sequences of operations :-) - inplace = (dstop == srcop) - if inplace or not (isinstance(srcop, REG) or isinstance(dstop, REG)): - mc.MOV(ecx, srcop) - srcop = ecx - if not inplace: + mc = allocator.mc + if dstop != oldsrcop: mc.MOV(dstop, srcop) mc.SHL(dstop, imm8(1)) mc.SBB(dstop, srcop) - mc.SBB(ecx, ecx) - mc.XOR(dstop, ecx) + allocator.release(self.x) + tmpop = allocator.create_scratch_reg() + dstop = allocator.get_operand(self) + mc.SBB(tmpop, tmpop) + mc.XOR(dstop, tmpop) + allocator.end_clobber(tmpop) class OpSameAs(Op1): + clobbers_cc = False # special handling of the cc + side_effects = False + def mark_used_vars(self, allocator): + allocator.using_inplace(self.x, self) + def generate(self, allocator): + srcop = allocator.get_operand(self.x) + if allocator.lastuse(self.x): + allocator.release(self.x) + if isinstance(srcop, CCFLAG): + allocator.create_in_cc(self, srcop) + else: + allocator.create_exactly_at(self, srcop) + else: + if isinstance(srcop, CCFLAG): + allocator.clobber_cc() # which doesn't itself clobber cc, + # so we can reuse it for us + allocator.create_in_cc(self, srcop) + else: + dstop = allocator.create_reg(self) + srcop = allocator.get_operand(self.x) + if srcop != dstop: + allocator.mc.MOV(dstop, srcop) + allocator.release(self.x) + +class OpWhatever(Operation): clobbers_cc = False - def generate2(self, mc, dstop, srcop): - if srcop != dstop: - try: - mc.MOV(dstop, srcop) - except FailedToImplement: - mc.MOV(ecx, srcop) - mc.MOV(dstop, ecx) + side_effects = False + def generate(self, allocator): + allocator.create(self) class OpCompare1(Op1): - result_kind = RK_CC + clobbers_cc = False # special handling of the cc + side_effects = False + def generate(self, allocator): - srcop = allocator.get_operand(self.x) mc = allocator.mc - self.emit(mc, srcop) - def copy(self): - return self.__class__(self.x) + srcop = allocator.get_operand(self.x) + if isinstance(srcop, CCFLAG): + ccop = srcop + allocator.release(self.x) + allocator.clobber_cc() + # the flags are still valid through a clobber_cc + if self.inverted: + ccop = ccflags[cond_negate(ccop.cc)] + else: + allocator.clobber_cc() + srcop = allocator.get_operand(self.x) + mc.CMP(srcop, imm8(0)) + allocator.release(self.x) + ccop = ccflags[self.suggested_cc] + allocator.create_in_cc(self, ccop) class OpIntIsTrue(OpCompare1): opname = 'int_is_true', 'ptr_nonzero', 'uint_is_true' - cc_result = Conditions['NE'] - @staticmethod - def emit(mc, x): - mc.CMP(x, imm8(0)) + suggested_cc = Conditions['NE'] + inverted = False class OpIntIsZero(OpIntIsTrue): opname = 'ptr_iszero', 'bool_not' - cc_result = Conditions['E'] + suggested_cc = Conditions['E'] + inverted = True class Op2(Operation): def __init__(self, x, y): self.x = x self.y = y - def allocate(self, allocator): + def mark_used_vars(self, allocator): allocator.using(self.x) allocator.using(self.y) - def generate(self, allocator): - try: - dstop = allocator.get_operand(self) - except KeyError: - return # simple operation whose result is not used anyway - op1 = allocator.get_operand(self.x) - op2 = allocator.get_operand(self.y) - self.generate3(allocator.mc, dstop, op1, op2) - def generate3(self, mc, dstop, op1, op2): - raise NotImplementedError class BinaryOp(Op2): + side_effects = False commutative = False - def generate3(self, mc, dstop, op1, op2): - # now all of dstop, op1 and op2 may alias each other and be in - # a register, in the stack or an immediate... finding a correct - # and encodable combination of instructions is loads of fun - if dstop == op1: - case = 1 # optimize for this common case - elif self.commutative and dstop == op2: + + def mark_used_vars(self, allocator): + inplace_ok = allocator.using_inplace(self.x, self) + if not inplace_ok and self.commutative: + allocator.using_inplace(self.y, self) + else: + allocator.using(self.y) + + def generate(self, allocator): + x, y = self.x, self.y + op1 = allocator.get_operand(x) + op2 = allocator.get_operand(y) + xlast = allocator.lastuse(x) + if self.commutative and not xlast and allocator.lastuse(y): + # reverse arguments, then it's an in-place operation + x, y = y, x op1, op2 = op2, op1 - case = 1 - elif isinstance(dstop, REG): - if dstop != op2: - # REG = OPERATION(op1, op2) with op2 != REG - case = 2 - else: - # REG = OPERATION(op1, REG) - case = 3 - elif isinstance(op1, REG) and isinstance(op2, REG): - # STACK = OPERATION(REG, REG) - case = 2 - else: - case = 3 - # generate instructions according to the 'case' determined above - if case == 1: - # dstop == op1 - try: - self.emit(mc, op1, op2) - except FailedToImplement: # emit(STACK, STACK) combination - mc.MOV(ecx, op2) - self.emit(mc, op1, ecx) - elif case == 2: - # this case works for: - # * REG = OPERATION(op1, op2) with op2 != REG - # * STACK = OPERATION(REG, REG) - mc.MOV(dstop, op1) - self.emit(mc, dstop, op2) - else: - # most general case - mc.MOV(ecx, op1) - self.emit(mc, ecx, op2) - mc.MOV(dstop, ecx) + xlast = True + + if xlast: + dstop = op1 # in-place operation + # op1 and op2 must not be both in a stack location + if isinstance(op1, MODRM) and isinstance(op2, MODRM): + tmpop = allocator.create_scratch_reg(op2) + # neither op1 nor op2 can have been spilled here, as + # they are already in the stack + op2 = tmpop + allocator.end_clobber(tmpop) + allocator.release(x) + allocator.release(y) + allocator.create_exactly_at(self, op1) + else: + dstop = allocator.create_reg(self) + if dstop != op1: # else op1 was spilled just now, so its value + # is still in place in its old register + allocator.mc.MOV(dstop, op1) # make a copy in the new register + op2 = allocator.get_operand(y) + allocator.release(y) + self.emit(allocator.mc, dstop, op2) class OpIntAdd(BinaryOp): opname = 'int_add', 'uint_add' @@ -211,64 +214,75 @@ class OpIntMul(Op2): opname = 'int_mul' - def generate3(self, mc, dstop, op1, op2): - if isinstance(dstop, REG): - tmpop = dstop - else: - tmpop = ecx - if tmpop == op1: - mc.IMUL(tmpop, op2) - elif isinstance(op2, IMM32): - mc.IMUL(tmpop, op1, op2) + side_effects = False + + def generate(self, allocator): + op1 = allocator.get_operand(self.x) + op2 = allocator.get_operand(self.y) + + if isinstance(op1, REG) and allocator.lastuse(self.x): + allocator.release(self.x) + allocator.release(self.y) + allocator.create_exactly_at(self, op1) + dstop = op1 + elif isinstance(op2, REG) and allocator.lastuse(self.y): + allocator.release(self.x) + allocator.release(self.y) + allocator.create_exactly_at(self, op2) + dstop = op2 + else: + dstop = allocator.create_reg(self) + allocator.release(self.x) + allocator.release(self.y) + mc = allocator.mc + if isinstance(op2, IMM32): + mc.IMUL(dstop, op1, op2) elif isinstance(op1, IMM32): - mc.IMUL(tmpop, op2, op1) + mc.IMUL(dstop, op2, op1) + elif dstop == op1: + mc.IMUL(dstop, op2) + elif dstop == op2: + mc.IMUL(dstop, op1) else: - if tmpop != op2: - mc.MOV(tmpop, op2) - mc.IMUL(tmpop, op1) - if dstop != tmpop: - mc.MOV(dstop, tmpop) + mc.MOV(dstop, op1) + mc.IMUL(dstop, op2) class MulOrDivOp(Op2): + side_effects = False - def generate3(self, mc, dstop, op1, op2): + def generate(self, allocator): # XXX not very efficient but not very common operations either - mc.PUSH(eax) - mc.PUSH(edx) - if op1 != eax: - if op2 == eax: - op2 = mem(esp, 4) + oldop1 = allocator.get_operand(self.x) + #oldop2 = allocator.get_operand(self.y) + allocator.clobber2(eax, edx) + op1 = allocator.get_operand(self.x) + + mc = allocator.mc + + if oldop1 != eax: mc.MOV(eax, op1) if self.input_is_64bits: - if op2 == edx: - op2 = mem(esp) if self.unsigned: mc.XOR(edx, edx) else: mc.CDQ() - try: - self.emit(mc, op2) - except FailedToImplement: - mc.MOV(ecx, op2) - self.emit(mc, ecx) - if dstop != self.reg_containing_result: - mc.MOV(dstop, self.reg_containing_result) - if dstop == edx: - mc.ADD(esp, imm8(4)) - else: - mc.POP(edx) - if dstop == eax: - mc.ADD(esp, imm8(4)) - else: - mc.POP(eax) + + self.generate2(allocator) + + allocator.end_clobber(eax) + allocator.end_clobber(edx) + allocator.release(self.x) + allocator.release(self.y) + # the target register should still be free, see clobber2() + allocator.create_exactly_at(self, self.reg_containing_result) class OpIntFloorDiv(MulOrDivOp): opname = 'int_floordiv' input_is_64bits = True reg_containing_result = eax unsigned = False - @staticmethod - def emit(mc, op2): + + def generate2(self, allocator): # from the PPC backend which has the same problem: # # grumble, the powerpc handles division when the signs of x @@ -288,234 +302,295 @@ # 20/(-3) = -7,-1 -6, 2 # operand signs differ # (-20)/(-3) = 6,-2 6,-2 # + tmp = allocator.create_scratch_reg() + op2 = allocator.get_operand(self.y) + mc = allocator.mc if isinstance(op2, IMM32): # if op2 is an immediate, we do an initial adjustment of operand 1 # so that we get directly the correct answer if op2.value >= 0: # if op1 is negative, subtract (op2-1) - mc.MOV(ecx, edx) # -1 if op1 is negative, 0 otherwise - mc.AND(ecx, imm(op2.value-1)) - mc.SUB(eax, ecx) + mc.MOV(tmp, edx) # -1 if op1 is negative, 0 otherwise + mc.AND(tmp, imm(op2.value-1)) + mc.SUB(eax, tmp) mc.SBB(edx, imm8(0)) else: # if op1 is positive (or null), add (|op2|-1) - mc.MOV(ecx, edx) - mc.NOT(ecx) # -1 if op1 is positive, 0 otherwise - mc.AND(ecx, imm(-op2.value-1)) - mc.ADD(eax, ecx) + mc.MOV(tmp, edx) + mc.NOT(tmp) # -1 if op1 is positive, 0 otherwise + mc.AND(tmp, imm(-op2.value-1)) + mc.ADD(eax, tmp) mc.ADC(edx, imm8(0)) - mc.MOV(ecx, op2) - mc.IDIV(ecx) + mc.MOV(tmp, op2) + mc.IDIV(tmp) else: # subtract 1 to the result if the operand signs differ and # the remainder is not zero - mc.MOV(ecx, eax) + mc.MOV(tmp, eax) mc.IDIV(op2) - mc.XOR(ecx, op2) - mc.SAR(ecx, imm8(31)) # -1 if signs differ, 0 otherwise - mc.AND(ecx, edx) # nonnull if signs differ and edx != 0 - mc.CMP(ecx, imm8(1)) # no carry flag iff signs differ and edx != 0 + mc.XOR(tmp, op2) + mc.SAR(tmp, imm8(31)) # -1 if signs differ, 0 otherwise + mc.AND(tmp, edx) # nonnull if signs differ and edx != 0 + mc.CMP(tmp, imm8(1)) # no carry flag iff signs differ and edx != 0 mc.ADC(eax, imm8(-1)) # subtract 1 iff no carry flag + allocator.end_clobber(tmp) class OpIntMod(MulOrDivOp): opname = 'int_mod' input_is_64bits = True reg_containing_result = edx unsigned = False - @staticmethod - def emit(mc, op2): + + def generate2(self, allocator): # Python i386 # 20/3 = 6, 2 6, 2 # (-20)/3 = -7, 1 -6,-2 # operand signs differ # 20/(-3) = -7,-1 -6, 2 # operand signs differ # (-20)/(-3) = 6,-2 6,-2 # + tmp = allocator.create_scratch_reg() + op2 = allocator.get_operand(self.y) + mc = allocator.mc if isinstance(op2, IMM32): - mc.MOV(ecx, op2) - mc.IDIV(ecx) + mc.MOV(tmp, op2) + mc.IDIV(tmp) # adjustment needed: # if op2 > 0: if the result is negative, add op2 to it # if op2 < 0: if the result is > 0, subtract |op2| from it - mc.MOV(ecx, edx) + mc.MOV(tmp, edx) if op2.value < 0: - mc.NEG(ecx) - mc.SAR(ecx, imm8(31)) - mc.AND(ecx, imm(op2.value)) - mc.ADD(edx, ecx) + mc.NEG(tmp) + mc.SAR(tmp, imm8(31)) + mc.AND(tmp, imm(op2.value)) + mc.ADD(edx, tmp) else: # if the operand signs differ and the remainder is not zero, # add operand2 to the result - mc.MOV(ecx, eax) + mc.MOV(tmp, eax) mc.IDIV(op2) - mc.XOR(ecx, op2) - mc.SAR(ecx, imm8(31)) # -1 if signs differ, 0 otherwise - mc.AND(ecx, edx) # nonnull if signs differ and edx != 0 - mc.CMOVNZ(ecx, op2) # == op2 if signs differ and edx != 0 - mc.ADD(edx, ecx) + mc.XOR(tmp, op2) + mc.SAR(tmp, imm8(31)) # -1 if signs differ, 0 otherwise + mc.AND(tmp, edx) # nonnull if signs differ and edx != 0 + mc.CMOVNZ(tmp, op2) # == op2 if signs differ and edx != 0 + mc.ADD(edx, tmp) + allocator.end_clobber(tmp) class OpUIntMul(MulOrDivOp): opname = 'uint_mul' input_is_64bits = False reg_containing_result = eax unsigned = True - emit = staticmethod(I386CodeBuilder.MUL) + def generate2(self, allocator): + op2 = allocator.get_operand(self.y) + allocator.mc.MUL(op2) class OpUIntFloorDiv(MulOrDivOp): opname = 'uint_floordiv' input_is_64bits = True reg_containing_result = eax unsigned = True - emit = staticmethod(I386CodeBuilder.DIV) + def generate2(self, allocator): + op2 = allocator.get_operand(self.y) + allocator.mc.DIV(op2) class OpUIntMod(MulOrDivOp): opname = 'uint_mod' input_is_64bits = True reg_containing_result = edx unsigned = True - emit = staticmethod(I386CodeBuilder.DIV) + def generate2(self, allocator): + op2 = allocator.get_operand(self.y) + allocator.mc.DIV(op2) -class OpIntLShift(Op2): - opname = 'int_lshift', 'uint_lshift' - emit = staticmethod(I386CodeBuilder.SHL) - def generate3(self, mc, dstop, op1, op2): - # XXX not optimized +class OpShift(Op2): + side_effects = False + countmax31 = False + + def mark_used_vars(self, allocator): + allocator.using_inplace(self.x, self) + allocator.using(self.y) + # XXX this would be nice + #if not self.countmax31: + # allocator.suggests(self.y, ecx) + + def generate(self, allocator): + op2 = allocator.get_operand(self.y) + mc = allocator.mc if isinstance(op2, IMM32): n = op2.value if n < 0 or n >= 32: - mc.MOV(dstop, imm8(0)) # shift out of range, result is zero - return + # shift out of range + if self.countmax31: + n = 31 # case in which it's equivalent to a shift by 31 + else: + # case in which the result is always zero + allocator.release(self.x) + allocator.release(self.y) + dstop = allocator.create_reg(self) + mc.XOR(dstop, dstop) + return count = imm8(n) else: - mc.MOV(ecx, op2) + allocator.clobber(ecx) + op2 = allocator.get_operand(self.y) + if self.countmax31: + mc.MOV(ecx, imm8(31)) + mc.CMP(op2, ecx) + mc.CMOVBE(ecx, op2) + else: + mc.MOV(ecx, op2) + allocator.release(self.y) count = cl - if dstop != op1: - try: - mc.MOV(dstop, op1) - except FailedToImplement: - mc.PUSH(op1) - mc.POP(dstop) + + if allocator.release(self.x): + dstop = allocator.get_operand(self.x) # in-place operation + allocator.create_exactly_at(self, dstop) + else: + dstop = allocator.create_reg(self) + srcop = allocator.get_operand(self.x) + mc.MOV(dstop, srcop) # make a copy in a new register + self.emit(mc, dstop, count) if count == cl: - mc.CMP(ecx, imm8(32)) - mc.SBB(ecx, ecx) - mc.AND(dstop, ecx) + if not self.countmax31: + mc.CMP(ecx, imm8(32)) + mc.SBB(ecx, ecx) + mc.AND(dstop, ecx) + allocator.end_clobber(ecx) -class OpIntRShift(Op2): - opname = 'int_rshift' - def generate3(self, mc, dstop, op1, op2): - # XXX not optimized - if isinstance(op2, IMM32): - n = op2.value - if n < 0 or n >= 32: - n = 31 # shift out of range, replace with 31 - count = imm8(n) - else: - mc.MOV(ecx, imm(31)) - mc.CMP(op2, ecx) - mc.CMOVBE(ecx, op2) - count = cl - if dstop != op1: - try: - mc.MOV(dstop, op1) - except FailedToImplement: - mc.PUSH(op1) - mc.POP(dstop) - mc.SAR(dstop, count) +class OpIntLShift(OpShift): + opname = 'int_lshift', 'uint_lshift' + emit = staticmethod(I386CodeBuilder.SHL) -class OpUIntRShift(OpIntLShift): +class OpUIntRShift(OpShift): opname = 'uint_rshift' emit = staticmethod(I386CodeBuilder.SHR) +class OpIntRShift(OpShift): + opname = 'int_rshift' + emit = staticmethod(I386CodeBuilder.SAR) + countmax31 = True + class OpCompare2(Op2): - result_kind = RK_CC + side_effects = False + def generate(self, allocator): - srcop = allocator.get_operand(self.x) - dstop = allocator.get_operand(self.y) + op1 = allocator.get_operand(self.x) + op2 = allocator.get_operand(self.y) mc = allocator.mc - # XXX optimize the case CMP(immed, reg-or-modrm) + cond = self.suggested_cc try: - mc.CMP(srcop, dstop) + mc.CMP(op1, op2) except FailedToImplement: - mc.MOV(ecx, srcop) - mc.CMP(ecx, dstop) - def copy(self): - return self.__class__(self.x, self.y) + # try reversing the arguments, for CMP(immed, reg-or-modrm) + try: + mc.CMP(op2, op1) + except FailedToImplement: + # CMP(stack, stack) + reg = allocator.create_scratch_reg(op1) + mc.CMP(reg, op2) + allocator.end_clobber(reg) + else: + cond = cond_swapargs(cond) # worked with arguments reversed + allocator.release(self.x) + allocator.release(self.y) + allocator.create_in_cc(self, ccflags[cond]) class OpIntLt(OpCompare2): opname = 'int_lt', 'char_lt' - cc_result = Conditions['L'] + suggested_cc = Conditions['L'] class OpIntLe(OpCompare2): opname = 'int_le', 'char_le' - cc_result = Conditions['LE'] + suggested_cc = Conditions['LE'] class OpIntEq(OpCompare2): opname = 'int_eq', 'char_eq', 'unichar_eq', 'ptr_eq', 'uint_eq' - cc_result = Conditions['E'] + suggested_cc = Conditions['E'] class OpIntNe(OpCompare2): opname = 'int_ne', 'char_ne', 'unichar_ne', 'ptr_ne', 'uint_ne' - cc_result = Conditions['NE'] + suggested_cc = Conditions['NE'] class OpIntGt(OpCompare2): opname = 'int_gt', 'char_gt' - cc_result = Conditions['G'] + suggested_cc = Conditions['G'] class OpIntGe(OpCompare2): opname = 'int_ge', 'char_ge' - cc_result = Conditions['GE'] + suggested_cc = Conditions['GE'] class OpUIntLt(OpCompare2): opname = 'uint_lt' - cc_result = Conditions['B'] + suggested_cc = Conditions['B'] class OpUIntLe(OpCompare2): opname = 'uint_le' - cc_result = Conditions['BE'] + suggested_cc = Conditions['BE'] class OpUIntGt(OpCompare2): opname = 'uint_gt' - cc_result = Conditions['A'] + suggested_cc = Conditions['A'] class OpUIntGe(OpCompare2): opname = 'uint_ge' - cc_result = Conditions['AE'] + suggested_cc = Conditions['AE'] class JumpIf(Operation): clobbers_cc = False - result_kind = RK_NO_RESULT - def __init__(self, gv_condition, targetbuilder, negate): + negate = False + def __init__(self, gv_condition, targetbuilder): self.gv_condition = gv_condition self.targetbuilder = targetbuilder - self.negate = negate - def allocate(self, allocator): - allocator.using_cc(self.gv_condition) + def mark_used_vars(self, allocator): + allocator.using(self.gv_condition) for gv in self.targetbuilder.inputargs_gv: allocator.using(gv) def generate(self, allocator): - cc = self.gv_condition.cc_result + targetbuilder = self.targetbuilder + op = allocator.get_operand(self.gv_condition) + mc = allocator.mc + if isinstance(op, CCFLAG): + cc = op.cc + else: + allocator.clobber_cc() + op = allocator.get_operand(self.gv_condition) + mc.CMP(op, imm(0)) + cc = Conditions['NE'] + allocator.release(self.gv_condition) + operands = [] + for gv in targetbuilder.inputargs_gv: + operands.append(allocator.get_operand(gv)) + allocator.release(gv) if self.negate: cc = cond_negate(cc) - mc = allocator.mc - targetbuilder = self.targetbuilder targetbuilder.set_coming_from(mc, insncond=cc) - targetbuilder.inputoperands = [allocator.get_operand(gv) - for gv in targetbuilder.inputargs_gv] + targetbuilder.inputoperands = operands + #assert targetbuilder.inputoperands.count(ebx) <= 1 + +class JumpIfNot(JumpIf): + negate = True class OpLabel(Operation): - clobbers_cc = False - result_kind = RK_NO_RESULT + # NB. this is marked to clobber the CC, because it cannot easily + # be saved/restored across a label. The problem is that someone + # might later try to jump to this label with a new value for + # the variable that is different from 0 or 1, i.e. which cannot + # be represented in the CC at all. def __init__(self, lbl, args_gv): self.lbl = lbl self.args_gv = args_gv - def allocate(self, allocator): + def mark_used_vars(self, allocator): for v in self.args_gv: allocator.using(v) def generate(self, allocator): + operands = [] + for v in self.args_gv: + operands.append(allocator.get_operand(v)) + allocator.release(v) lbl = self.lbl lbl.targetaddr = allocator.mc.tell() - lbl.targetstackdepth = allocator.required_frame_depth - lbl.inputoperands = [allocator.get_operand(v) for v in self.args_gv] + lbl.inputoperands = operands lbl.targetbuilder = None # done generating class OpCall(Operation): @@ -523,55 +598,57 @@ self.sigtoken = sigtoken self.gv_fnptr = gv_fnptr self.args_gv = args_gv - def allocate(self, allocator): - # XXX try to use eax for the result + + def mark_used_vars(self, allocator): allocator.using(self.gv_fnptr) for v in self.args_gv: allocator.using(v) + def generate(self, allocator): - try: - dstop = allocator.get_operand(self) - except KeyError: - dstop = None mc = allocator.mc - stack_align_words = PROLOGUE_FIXED_WORDS - if dstop != eax: - mc.PUSH(eax) - if CALL_ALIGN > 1: stack_align_words += 1 - if dstop != edx: - mc.PUSH(edx) - if CALL_ALIGN > 1: stack_align_words += 1 args_gv = self.args_gv - num_placeholders = 0 - if CALL_ALIGN > 1: - stack_align_words += len(args_gv) - stack_align_words &= CALL_ALIGN-1 - if stack_align_words > 0: - num_placeholders = CALL_ALIGN - stack_align_words - mc.SUB(esp, imm(WORD * num_placeholders)) - for i in range(len(args_gv)-1, -1, -1): + + stackargs_i = [] + for i in range(len(args_gv)): srcop = allocator.get_operand(args_gv[i]) - mc.PUSH(srcop) + if isinstance(srcop, MODRM): + stackargs_i.append(i) + else: + mc.MOV(mem(esp, WORD * i), srcop) + allocator.release(args_gv[i]) + + allocator.clobber3(eax, edx, ecx) + allocator.reserve_extra_stack(len(args_gv)) + + if len(stackargs_i) > 0: + tmp = eax + for i in stackargs_i: + srcop = allocator.get_operand(args_gv[i]) + mc.MOV(tmp, srcop) + mc.MOV(mem(esp, WORD * i), tmp) + allocator.release(args_gv[i]) + fnop = allocator.get_operand(self.gv_fnptr) if isinstance(fnop, IMM32): mc.CALL(rel32(fnop.value)) else: mc.CALL(fnop) - mc.ADD(esp, imm(WORD * (len(args_gv) + num_placeholders))) - if dstop != edx: - mc.POP(edx) - if dstop != eax: - if dstop is not None: - mc.MOV(dstop, eax) - mc.POP(eax) -def field_operand(mc, base, fieldtoken): - # may use ecx + allocator.release(self.gv_fnptr) + allocator.end_clobber(eax) + allocator.end_clobber(edx) + allocator.end_clobber(ecx) + if allocator.operation_result_is_used(self): + allocator.create_exactly_at(self, eax) + + +def field_operand(allocator, base, fieldtoken): fieldoffset, fieldsize = fieldtoken if isinstance(base, MODRM): - mc.MOV(ecx, base) - base = ecx + tmp = allocator.create_scratch_reg(base) + allocator.end_clobber(tmp) + base = tmp elif isinstance(base, IMM32): fieldoffset += base.value base = None @@ -581,8 +658,8 @@ else: return mem (base, fieldoffset) -def array_item_operand(mc, base, arraytoken, opindex): - # may use ecx +def array_item_operand(allocator, base, arraytoken, opindex): + tmp = None _, startoffset, itemoffset = arraytoken if isinstance(opindex, IMM32): @@ -591,28 +668,31 @@ indexshift = 0 elif itemoffset in SIZE2SHIFT: if not isinstance(opindex, REG): - mc.MOV(ecx, opindex) - opindex = ecx + tmp = allocator.create_scratch_reg(opindex) + opindex = tmp indexshift = SIZE2SHIFT[itemoffset] else: - mc.IMUL(ecx, opindex, imm(itemoffset)) - opindex = ecx + tmp = allocator.create_scratch_reg() + allocator.mc.IMUL(tmp, opindex, imm(itemoffset)) + opindex = tmp indexshift = 0 - assert base is not ecx if isinstance(base, MODRM): - if opindex != ecx: - mc.MOV(ecx, base) - else: # waaaa + if tmp is None: + tmp = allocator.create_scratch_reg(base) + else: # let's avoid using two scratch registers opindex = None if indexshift > 0: - mc.SHL(ecx, imm8(indexshift)) - mc.ADD(ecx, base) - base = ecx + allocator.mc.SHL(tmp, imm8(indexshift)) + allocator.mc.ADD(tmp, base) + base = tmp elif isinstance(base, IMM32): startoffset += base.value base = None + if tmp is not None: + allocator.end_clobber(tmp) + if itemoffset == 1: return memSIB8(base, opindex, indexshift, startoffset) else: @@ -620,209 +700,141 @@ class OpComputeSize(Operation): clobbers_cc = False + side_effects = False def __init__(self, varsizealloctoken, gv_length): self.varsizealloctoken = varsizealloctoken self.gv_length = gv_length - def allocate(self, allocator): + def mark_used_vars(self, allocator): allocator.using(self.gv_length) def generate(self, allocator): - dstop = allocator.get_operand(self) srcop = allocator.get_operand(self.gv_length) - mc = allocator.mc - op_size = array_item_operand(mc, None, self.varsizealloctoken, srcop) - try: - mc.LEA(dstop, op_size) - except FailedToImplement: - mc.LEA(ecx, op_size) - mc.MOV(dstop, ecx) - -def hard_store(mc, opmemtarget, opvalue, itemsize): - # For the possibly hard cases of stores - # Generates a store to 'opmemtarget' of size 'itemsize' == 1, 2 or 4. - # If it is 1, opmemtarget must be a MODRM8; otherwise, it must be a MODRM. - if itemsize == WORD: - try: - mc.MOV(opmemtarget, opvalue) - except FailedToImplement: - if opmemtarget.involves_ecx(): - mc.PUSH(opvalue) - mc.POP(opmemtarget) - else: - mc.MOV(ecx, opvalue) - mc.MOV(opmemtarget, ecx) - else: - must_pop_eax = False - if itemsize == 1: - if isinstance(opvalue, REG) and opvalue.lowest8bits: - # a register whose lower 8 bits are directly readable - opvalue = opvalue.lowest8bits - elif isinstance(opvalue, IMM8): - pass - else: - if opmemtarget.involves_ecx(): # grumble! - mc.PUSH(eax) - must_pop_eax = True - scratch = eax - else: - scratch = ecx - if opvalue.width == 1: - mc.MOV(scratch.lowest8bits, opvalue) - else: - mc.MOV(scratch, opvalue) - opvalue = scratch.lowest8bits + op_size = array_item_operand(allocator, None, + self.varsizealloctoken, srcop) + allocator.release(self.gv_length) + dstop = allocator.create_reg(self) + allocator.mc.LEA(dstop, op_size) + +class OpGetter(Operation): + side_effects = False + def generate(self, allocator): + opsource = self.generate_opsource(allocator) + dstop = allocator.create_reg(self) + if self.getwidth() == WORD: + allocator.mc.MOV(dstop, opsource) else: - assert itemsize == 2 - if isinstance(opvalue, MODRM) or type(opvalue) is IMM32: - # no support for now to encode 16-bit immediates, - # so we use a scratch register for this case too - if opmemtarget.involves_ecx(): # grumble! - mc.PUSH(eax) - must_pop_eax = True - scratch = eax - else: - scratch = ecx - mc.MOV(scratch, opvalue) - opvalue = scratch - mc.o16() # prefix for the MOV below - # and eventually, the real store: - mc.MOV(opmemtarget, opvalue) - if must_pop_eax: - mc.POP(eax) - -def hard_load(mc, opdst, opmemsource, itemsize): - # For the possibly hard cases of stores - # Generates a load from 'opmemsource' of size 'itemsize' == 1, 2 or 4. - # If it is 1, opmemtarget must be a MODRM8; otherwise, it must be a MODRM. - if itemsize == WORD: - try: - mc.MOV(opdst, opmemsource) - except FailedToImplement: # opdst is a MODRM - if opmemsource.involves_ecx(): - mc.PUSH(opmemsource) - mc.POP(opdst) - else: - mc.MOV(ecx, opmemsource) - mc.MOV(opdst, ecx) - else: - try: - mc.MOVZX(opdst, opmemsource) - except FailedToImplement: # opdst is a MODRM - if opmemsource.involves_ecx(): - mc.PUSH(eax) - mc.MOVZX(eax, opmemsource) - mc.MOV(opdst, eax) - mc.POP(eax) + allocator.mc.MOVZX(dstop, opsource) + +class OpSetter(Operation): + def generate(self, allocator): + tmpval = None + width = self.getwidth() + opvalue = allocator.get_operand(self.gv_value) + if width == 1: + try: + opvalue = opvalue.lowest8bits() + except ValueError: + tmpval = allocator.create_scratch_reg8(opvalue) + opvalue = tmpval else: - mc.MOVZX(ecx, opmemsource) - mc.MOV(opdst, ecx) + if isinstance(opvalue, MODRM8): + tmpval = allocator.create_scratch_reg8(opvalue) + opvalue = tmpval + else: + if isinstance(opvalue, MODRM): + tmpval = allocator.create_scratch_reg(opvalue) + opvalue = tmpval + optarget = self.generate_optarget(allocator) + if width == 2: + if isinstance(opvalue, IMM32): + opvalue = IMM16(opvalue.value) + allocator.mc.o16() + allocator.mc.MOV(optarget, opvalue) + if tmpval is not None: + allocator.end_clobber(tmpval) -class OpGetField(Operation): +class OpGetField(OpGetter): clobbers_cc = False def __init__(self, fieldtoken, gv_ptr): self.fieldtoken = fieldtoken self.gv_ptr = gv_ptr - def allocate(self, allocator): + def getwidth(self): + _, fieldsize = self.fieldtoken + return fieldsize + def mark_used_vars(self, allocator): allocator.using(self.gv_ptr) - def generate(self, allocator): - try: - dstop = allocator.get_operand(self) - except KeyError: - return # result not used + def generate_opsource(self, allocator): opptr = allocator.get_operand(self.gv_ptr) - mc = allocator.mc - opsource = field_operand(mc, opptr, self.fieldtoken) - _, fieldsize = self.fieldtoken - hard_load(mc, dstop, opsource, fieldsize) + opsource = field_operand(allocator, opptr, self.fieldtoken) + allocator.release(self.gv_ptr) + return opsource -class OpSetField(Operation): +class OpSetField(OpSetter): clobbers_cc = False - result_kind = RK_NO_RESULT def __init__(self, fieldtoken, gv_ptr, gv_value): self.fieldtoken = fieldtoken self.gv_ptr = gv_ptr self.gv_value = gv_value - def allocate(self, allocator): + def getwidth(self): + _, fieldsize = self.fieldtoken + return fieldsize + def mark_used_vars(self, allocator): allocator.using(self.gv_ptr) allocator.using(self.gv_value) - def generate(self, allocator): + def generate_optarget(self, allocator): opptr = allocator.get_operand(self.gv_ptr) - opvalue = allocator.get_operand(self.gv_value) - mc = allocator.mc - optarget = field_operand(mc, opptr, self.fieldtoken) - _, fieldsize = self.fieldtoken - hard_store(mc, optarget, opvalue, fieldsize) + optarget = field_operand(allocator, opptr, self.fieldtoken) + allocator.release(self.gv_ptr) + allocator.release(self.gv_value) + return optarget -class OpGetArrayItem(Operation): +class OpGetArrayItem(OpGetter): def __init__(self, arraytoken, gv_array, gv_index): self.arraytoken = arraytoken self.gv_array = gv_array self.gv_index = gv_index - def allocate(self, allocator): + def getwidth(self): + _, _, itemsize = self.arraytoken + return itemsize + def mark_used_vars(self, allocator): allocator.using(self.gv_array) allocator.using(self.gv_index) - def generate(self, allocator): - try: - dstop = allocator.get_operand(self) - except KeyError: - return # result not used + def generate_opsource(self, allocator): oparray = allocator.get_operand(self.gv_array) opindex = allocator.get_operand(self.gv_index) - mc = allocator.mc - opsource = array_item_operand(mc, oparray, self.arraytoken, opindex) - _, _, itemsize = self.arraytoken - hard_load(mc, dstop, opsource, itemsize) + opsource = array_item_operand(allocator, oparray, + self.arraytoken, opindex) + allocator.release(self.gv_array) + allocator.release(self.gv_index) + return opsource + +class OpGetArraySubstruct(OpGetArrayItem): + def generate(self, allocator): + opsource = self.generate_opsource(allocator) + dstop = allocator.create_reg(self) + allocator.mc.LEA(dstop, opsource) -class OpSetArrayItem(Operation): - result_kind = RK_NO_RESULT +class OpSetArrayItem(OpSetter): def __init__(self, arraytoken, gv_array, gv_index, gv_value): self.arraytoken = arraytoken self.gv_array = gv_array self.gv_index = gv_index self.gv_value = gv_value - def allocate(self, allocator): - allocator.using(self.gv_array) - allocator.using(self.gv_index) - allocator.using(self.gv_value) - def generate(self, allocator): - oparray = allocator.get_operand(self.gv_array) - opindex = allocator.get_operand(self.gv_index) - opvalue = allocator.get_operand(self.gv_value) - mc = allocator.mc - optarget = array_item_operand(mc, oparray, self.arraytoken, opindex) + def getwidth(self): _, _, itemsize = self.arraytoken - hard_store(mc, optarget, opvalue, itemsize) - -class OpGetArraySubstruct(Operation): - def __init__(self, arraytoken, gv_array, gv_index): - self.arraytoken = arraytoken - self.gv_array = gv_array - self.gv_index = gv_index - def allocate(self, allocator): + return itemsize + def mark_used_vars(self, allocator): allocator.using(self.gv_array) allocator.using(self.gv_index) - def generate(self, allocator): - try: - dstop = allocator.get_operand(self) - except KeyError: - return # result not used + allocator.using(self.gv_value) + def generate_optarget(self, allocator): oparray = allocator.get_operand(self.gv_array) opindex = allocator.get_operand(self.gv_index) - mc = allocator.mc - opsource = array_item_operand(mc, oparray, self.arraytoken, opindex) - try: - mc.LEA(dstop, opsource) - except FailedToImplement: - mc.LEA(ecx, opsource) - mc.MOV(dstop, ecx) - -class OpGetFrameBase(Operation): - def generate(self, allocator): - try: - dstop = allocator.get_operand(self) - except KeyError: - return # result not used - mc = allocator.mc - mc.MOV(dstop, ebp) + opsource = array_item_operand(allocator, oparray, + self.arraytoken, opindex) + allocator.release(self.gv_array) + allocator.release(self.gv_index) + allocator.release(self.gv_value) + return opsource # ____________________________________________________________ @@ -890,7 +902,88 @@ assert 0 <= cond < INSN_JMP return cond ^ 1 +def cond_swapargs(cond): + return COND_SWAPARGS[cond] + +COND_SWAPARGS = range(16) +COND_SWAPARGS[Conditions['L']] = Conditions['G'] +COND_SWAPARGS[Conditions['G']] = Conditions['L'] +COND_SWAPARGS[Conditions['NL']] = Conditions['NG'] +COND_SWAPARGS[Conditions['NG']] = Conditions['NL'] +COND_SWAPARGS[Conditions['B']] = Conditions['A'] +COND_SWAPARGS[Conditions['A']] = Conditions['B'] +COND_SWAPARGS[Conditions['NB']] = Conditions['NA'] +COND_SWAPARGS[Conditions['NA']] = Conditions['NB'] + SIZE2SHIFT = {1: 0, 2: 1, 4: 2, 8: 3} + +# ____________________________________________________________ + +class CCFLAG(OPERAND): + _attrs_ = ['cc', 'SETCOND', 'load_into_cc'] + def __init__(self, cond, load_into_cc): + self.cond = cond + self.cc = Conditions[cond] + self.SETCOND = getattr(I386CodeBuilder, 'SET' + cond) + self.load_into_cc = load_into_cc + + def assembler(self): + return self.cond + + +def load_into_cc_lt(mc, srcop): + mc.XOR(ecx, ecx) + mc.CMP(ecx, srcop) + +def load_into_cc_le(mc, srcop): + mc.MOV(ecx, imm8(1)) + mc.CMP(ecx, srcop) + +def load_into_cc_eq(mc, srcop): + mc.CMP(srcop, imm8(1)) + +def load_into_cc_ne(mc, srcop): + mc.CMP(srcop, imm8(0)) + +load_into_cc_gt = load_into_cc_ne +load_into_cc_ge = load_into_cc_eq + +ccflag_lt = CCFLAG('L', load_into_cc_lt) +ccflag_le = CCFLAG('LE', load_into_cc_le) +ccflag_eq = CCFLAG('E', load_into_cc_eq) +ccflag_ne = CCFLAG('NE', load_into_cc_ne) +ccflag_gt = CCFLAG('G', load_into_cc_gt) +ccflag_ge = CCFLAG('GE', load_into_cc_ge) + +ccflag_ult = CCFLAG('B', load_into_cc_lt) +ccflag_ule = CCFLAG('BE', load_into_cc_le) +ccflag_ugt = CCFLAG('A', load_into_cc_gt) +ccflag_uge = CCFLAG('AE', load_into_cc_ge) + +ccflags = [None] * 16 +ccflags[Conditions['L']] = ccflag_lt +ccflags[Conditions['LE']] = ccflag_le +ccflags[Conditions['E']] = ccflag_eq +ccflags[Conditions['NE']] = ccflag_ne +ccflags[Conditions['G']] = ccflag_gt +ccflags[Conditions['GE']] = ccflag_ge +ccflags[Conditions['B']] = ccflag_ult +ccflags[Conditions['BE']] = ccflag_ule +ccflags[Conditions['A']] = ccflag_ugt +ccflags[Conditions['AE']] = ccflag_uge + +##def ccmov(mc, dstop, ccop): +## XXX +## if dstop != ccop: +## ccop.SETCOND(mc, cl) +## if isinstance(dstop, CCFLAG): +## dstop.load_into_cc(mc, cl) +## else: +## try: +## mc.MOVZX(dstop, cl) +## except FailedToImplement: +## mc.MOVZX(ecx, cl) +## mc.MOV(dstop, ecx) Modified: pypy/branch/new-jit-codegen/i386/regalloc.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/codegen/i386/regalloc.py (original) +++ pypy/branch/new-jit-codegen/i386/regalloc.py Wed Feb 7 13:44:55 2007 @@ -2,6 +2,7 @@ """ +import sys from pypy.rlib.objectmodel import we_are_translated from pypy.rpython.lltypesystem import lltype from pypy.jit.codegen.i386.operation import * @@ -10,7 +11,7 @@ class StackOpCache: - INITIAL_STACK_EBP_OFS = -4 + INITIAL_STACK_EBP_OFS = -1 stack_op_cache = StackOpCache() stack_op_cache.lst = [] @@ -27,276 +28,541 @@ ofs = op.ofs_relative_to_ebp() return StackOpCache.INITIAL_STACK_EBP_OFS - ofs / WORD +def write_stack_reserve(mc, stackn): + addr = mc.tell() + offset = WORD * ((StackOpCache.INITIAL_STACK_EBP_OFS+1) - stackn) + mc.ADD(esp, IMM32(offset)) # always encode offset on 32 bits + return addr + +def write_stack_adj(mc, stackn): + addr = mc.tell() + offset = WORD * ((StackOpCache.INITIAL_STACK_EBP_OFS+1) - stackn) + mc.LEA(esp, fixedsize_esp_ofs(offset)) + return addr + class RegAllocator(object): - AVAILABLE_REGS = [eax, edx, ebx, esi, edi] # XXX ecx reserved for stuff - # 'gv' -- GenVars, used as arguments and results of operations - # - # 'loc' -- location, a small integer that represents an abstract - # register number - # - # 'operand' -- a concrete machine code operand, which can be a - # register (ri386.eax, etc.) or a stack memory operand - - def __init__(self): - self.nextloc = 0 - self.var2loc = {} - self.available_locs = [] - self.force_loc2operand = {} - self.force_operand2loc = {} - self.initial_moves = [] - self.num_stack_locs = 0 + def __init__(self, operations): + self.operations = operations + self.operationindex = len(operations) + self.lifetime = {} # {variable: operation_index} + self.suggested_location = {} # {variable: location} + self.var2loc = {gv_frame_base: ebp} + + # ---------- def set_final(self, final_vars_gv): for v in final_vars_gv: self.using(v) - def creating(self, v): - try: - loc = self.var2loc[v] - except KeyError: - pass - else: - if loc >= self.num_stack_locs: - self.available_locs.append(loc) # now available again for reuse - - def using(self, v): - if not v.is_const and v not in self.var2loc: - try: - loc = self.available_locs.pop() - except IndexError: - loc = self.nextloc - self.nextloc += 1 - self.var2loc[v] = loc - - def creating_cc(self, v): - if self.need_var_in_cc is v: - # common case: v is a compare operation whose result is precisely - # what we need to be in the CC - self.need_var_in_cc = None - self.creating(v) - - def save_cc(self): - # we need a value to be in the CC, but we see a clobbering - # operation, so we copy the original CC-creating operation down - # past the clobbering operation. - # completely obscure code - # yes, well, needs very careful reviewing I guess :-) - v = self.need_var_in_cc - if not we_are_translated(): - assert v in self.operations[:self.operationindex] - v = v.copy() - self.operations.insert(self.operationindex, v) - v.allocate(self) - self.need_var_in_cc = None - - def using_cc(self, v): - assert isinstance(v, Operation) - assert 0 <= v.cc_result < INSN_JMP - if self.need_var_in_cc is not None and self.need_var_in_cc is not v: - self.save_cc() - self.need_var_in_cc = v + def set_final_at_loc(self, final_vars_gv, locations): + for i in range(len(final_vars_gv)): + v = final_vars_gv[i] + self.using(v) + self.suggested_location[v] = locations[i] - def allocate_locations(self, operations): - # assign locations to gvars - self.operations = operations - self.need_var_in_cc = None - self.operationindex = len(operations) - for i in range(len(operations)-1, -1, -1): - v = operations[i] - if (self.need_var_in_cc is not None and - self.need_var_in_cc is not v and v.clobbers_cc): - self.save_cc() - kind = v.result_kind - if kind == RK_WORD: - self.creating(v) - elif kind == RK_CC: - self.creating_cc(v) - v.allocate(self) + def compute_lifetimes(self): + for i in range(len(self.operations)-1, -1, -1): self.operationindex = i - if self.need_var_in_cc is not None: - self.save_cc() + op = self.operations[i] + if not op.side_effects and op not in self.lifetime: + self.operations[i] = dead_operation # operation not used + else: + op.mark_used_vars(self) + + def using(self, v): + if v.is_const or v in self.lifetime: + return False + else: + self.lifetime[v] = self.operationindex + return True # variable is dying here - def force_var_operands(self, force_vars, force_operands, at_start): - force_loc2operand = self.force_loc2operand - force_operand2loc = self.force_operand2loc - for i in range(len(force_vars)): - v = force_vars[i] - operand = force_operands[i] + def using_inplace(self, v, vtarget): + if self.using(v): + # this operation 'vtarget' can modify its argument 'v' + # in-place, and 'v' is not alive after the operation. + # Propagate the suggested location for 'vtarget' backwards to 'v'. try: - loc = self.var2loc[v] + self.suggested_location[v] = self.suggested_location[vtarget] + return True # got a suggestion except KeyError: - if at_start: - pass # input variable not used anyway - else: - self.add_final_move(v, operand, make_copy=v.is_const) + pass + return False # got no suggestion + + def suggests(self, v, loc): + self.suggested_location[v] = loc + + def varsused(self): + return self.lifetime.keys() + + # ---------- + + AVAILABLE_REGS = (eax.bitmask | + edx.bitmask | + ecx.bitmask | + ebx.bitmask | + esi.bitmask | + edi.bitmask) + + def init_reg_alloc(self, inputvars_gv, inputlocations): + self.registers_free = self.AVAILABLE_REGS # bitmask + self.cc_used_by = None + self.stack_op_used = {} + self.nstackidx = 0 + self.nstackmax = 0 + self.vars_in_use = {} # {variable: dying_operation_index} + self.operationindex = 0 + self.inputvars_gv = inputvars_gv + self.inputlocations = inputlocations + + def force_loc_used(self, v, loc): + if isinstance(loc, MODRM): + assert loc not in self.stack_op_used + self.stack_op_used[loc] = None + n = stack_n_from_op(loc) + if n >= self.nstackmax: + self.nstackmax = n + 1 + elif isinstance(loc, REG): + assert self.registers_free & loc.bitmask + self.registers_free &= ~loc.bitmask + elif isinstance(loc, CCFLAG): + self.cc_used_by = v + else: + raise AssertionError(loc) + + def consume_loc(self, v, loc): + if isinstance(loc, MODRM): + if loc not in self.stack_op_used: + self.stack_op_used[loc] = None + return True + elif isinstance(loc, REG): + if self.registers_free & loc.bitmask: + self.registers_free &= ~loc.bitmask + return True + elif isinstance(loc, CCFLAG): + if self.cc_used_by is None: + self.cc_used_by = v + return True + return False + + def _no_longer_in_use(self, v): + del self.vars_in_use[v] + loc = self.var2loc[v] + if isinstance(loc, CCFLAG): + assert self.cc_used_by is v + self._mark_loc_as_free(loc) + + def _mark_loc_as_free(self, loc): + if isinstance(loc, MODRM): + del self.stack_op_used[loc] + elif isinstance(loc, REG): + self.registers_free |= loc.bitmask + elif isinstance(loc, CCFLAG): + self.cc_used_by = None + + def generate_operations(self, mc): + if not we_are_translated(): + print + + # reserve locations for the inputvars + for i in range(len(self.inputvars_gv)): + v = self.inputvars_gv[i] + if v in self.lifetime: # else: input argument is not used + loc = self.inputlocations[i] + self.var2loc[v] = loc + self.vars_in_use[v] = self.lifetime[v] + self.force_loc_used(v, loc) + if not we_are_translated(): + print 'in %20s: %s' % (loc, short(v)) + + self._check() + self.mc = mc + # Generate all operations. + # Actual registers or stack locations are allocated as we go. + for i in range(len(self.operations)): + op = self.operations[i] + if op.clobbers_cc: + self.clobber_cc() + self._check() + op.generate(self) + if not we_are_translated(): + self._showprogress() + self.operationindex = i + 1 + + def _showprogress(self): + class Collector: + def __init__(self): + self.lst = [] + self.using = self.lst.append + def using_inplace(self, v, _): + self.lst.append(v) + def suggests(self, v, loc): + pass + col = Collector() + i = self.operationindex + op = self.operations[i] + op.mark_used_vars(col) + args = [short(v) for v in col.lst] + args = ', '.join(args) + print ' | %20s: %s (%s)' % (self.var2loc.get(op, ''), + short(op), args) + for v, endtime in self.vars_in_use.items(): + assert endtime > i + self._check() + + def _use_another_stack_loc(self): + for i in range(self.nstackidx, self.nstackmax): + loc = stack_op(i) + if loc not in self.stack_op_used: + self.nstackidx = i + 1 + break + else: + for i in range(self.nstackidx): + loc = stack_op(i) + if loc not in self.stack_op_used: + self.nstackidx = i + 1 + break else: - # we need to make of copy of this var if we have conflicting - # requirements about where it should go: - # * its location is forced to another operand - # * the operand is assigned to another location - # * it should be in the stack, but it is not - if (loc in force_loc2operand or operand in force_operand2loc or - (loc < self.num_stack_locs and not ( - isinstance(operand, MODRM) - and operand.is_relative_to_ebp()))): - if at_start: - self.initial_moves.append((loc, operand)) - else: - self.add_final_move(v, operand, make_copy=True) - else: - force_loc2operand[loc] = operand - force_operand2loc[operand] = loc - - def add_final_move(self, v, targetoperand, make_copy): - if make_copy: - v = OpSameAs(v) - self.operations.append(v) - loc = self.nextloc - self.nextloc += 1 + i = self.nstackidx = self.nstackmax + self.nstackmax = i + 1 + loc = stack_op(i) + assert loc not in self.stack_op_used + self.stack_op_used[loc] = None + return loc + + def reserve_extra_stack(self, extra): + max = self.nstackmax + base = max - extra + if base < 0: + base = 0 + while max > base and stack_op(max-1) not in self.stack_op_used: + max -= 1 + self.nstackmax = max + extra + + def get_operand(self, v): + if v.is_const: + return imm(v.revealconst(lltype.Signed)) + else: + return self.var2loc[v] + + def _use_next_modrm(self, v, regnum_must_be_before=8): + """Select the next mod/rm location to use for the new operation 'v'. + If 'v' is None, this will always return a register; else it might + decide to immediately create 'v' in a stack location. + """ + #print self.registers_free + if self.registers_free: + for i in range(regnum_must_be_before-1, -1, -1): + if self.registers_free & (1 << i): + self.registers_free &= ~ (1 << i) + return registers[i] + # spill the register holding the variable that has the longest + # time remaining to live (it may be our 'v' itself) + if v is None: + dyinglimit = self.operationindex # must pick vars dying after that + spillvar = None + else: + dyinglimit = self.lifetime[v] + spillvar = v # initial guess, can be overridden in the loop below + regloc = None + for v1, dying in self.vars_in_use.iteritems(): + if dying > dyinglimit: + loc = self.var2loc[v1] + if not isinstance(loc, REG): + continue + if loc.op >= regnum_must_be_before: + continue # never reached if regnum_must_be_before == 8 + regloc = loc + dyinglimit = dying + spillvar = v1 + if spillvar is None: + raise OutOfRegistersError + #print 'time span of %s: now is %d, lives until %d' % ( + # v, self.operationindex, self.lifetime[v]) + if spillvar is v: + return self._use_another_stack_loc() + else: + assert regloc is not None + self._spill(spillvar, regloc) + return regloc + + def _spill(self, spillvar, oldloc): + spillloc = self._use_another_stack_loc() + if not we_are_translated(): + print ' # %20s: SPILL %s' % (spillloc, oldloc) + self.mc.MOV(spillloc, oldloc) + self.var2loc[spillvar] = spillloc + return spillloc + + def _use_next_reg(self): + return self._use_next_modrm(None) + + def _use_next_reg_abcd(self): + return self._use_next_modrm(None, regnum_must_be_before=4) + + def _created(self, v, loc): + assert v not in self.var2loc + self.vars_in_use[v] = ltime = self.lifetime[v] + assert ltime > self.operationindex self.var2loc[v] = loc - self.force_loc2operand[loc] = targetoperand - def allocate_registers(self): - # assign registers to locations that don't have one already - force_loc2operand = self.force_loc2operand - operands = [] - seen_regs = 0 - seen_stackn = {} - last_seen_stackn = -1 - for op in force_loc2operand.values(): - if isinstance(op, REG): - seen_regs |= 1 << op.op - elif isinstance(op, MODRM): - n = stack_n_from_op(op) - seen_stackn[n] = None - if n > last_seen_stackn: - last_seen_stackn = n - i = 0 - stackn = 0 - num_stack_locs = self.num_stack_locs - for loc in range(self.nextloc): - try: - operand = force_loc2operand[loc] - except KeyError: - try: - # try to grab the next free register, - # unless this location is forced to go to the stack - if loc < num_stack_locs: - raise IndexError - while True: - operand = RegAllocator.AVAILABLE_REGS[i] - i += 1 - if not (seen_regs & (1 << operand.op)): - break - except IndexError: - while stackn in seen_stackn: - stackn += 1 - operand = stack_op(stackn) - stackn += 1 - operands.append(operand) - self.operands = operands - if stackn <= last_seen_stackn: - stackn = last_seen_stackn + 1 - self.required_frame_depth = stackn - - def get_operand(self, gv_source): - if gv_source.is_const: - return imm(gv_source.revealconst(lltype.Signed)) + def release(self, v): + """Stop using argument 'v'. Must be called for each used argument.""" + ok = self.lastuse(v) and v in self.vars_in_use + if ok: + self._no_longer_in_use(v) + return ok + + def lastuse(self, v): + """Is this the last time the argument 'v' is used?""" + if v.is_const: + return False else: - loc = self.var2loc[gv_source] - return self.operands[loc] + endtime = self.lifetime[v] + assert endtime >= self.operationindex + return endtime == self.operationindex + + def create(self, v, suggested_loc=None): + """Create the result of the operation 'v', possibly at the + suggested location. CAN SPILL ONE REGISTER.""" + if suggested_loc is not None and self.consume_loc(v, suggested_loc): + self._created(v, suggested_loc) + return suggested_loc + suggested_loc = self.suggested_location.get(v, None) + if suggested_loc is not None and self.consume_loc(v, suggested_loc): + self._created(v, suggested_loc) + return suggested_loc + loc = self._use_next_modrm(v) + self._created(v, loc) + return loc + + def create_reg(self, v): + """Create the result of the operation 'v' in any register + currently available. CAN SPILL ONE REGISTER.""" + suggested_loc = self.suggested_location.get(v, None) + if isinstance(suggested_loc, REG): + if self.consume_loc(v, suggested_loc): + self._created(v, suggested_loc) + return suggested_loc + loc = self._use_next_reg() + self._created(v, loc) + return loc + + def create_exactly_at(self, v, loc): + """Create the result of the operation 'v' at 'loc'.""" + ok = self.consume_loc(v, loc) + assert ok + self._created(v, loc) + + def create_in_cc(self, v, ccloc): + """Create the result of the operation 'v' in the given cc flags. + Doesn't move stuff around.""" + assert self.cc_used_by is None + self._created(v, ccloc) + self.cc_used_by = v + + def create_scratch_reg(self, srcloc=None): + """Return a scratch register for the current operation. + Warning, this might be the same register as one of the input args. + CAN SPILL ONE REGISTER. You must eventually call end_clobber().""" + reg = self._use_next_reg() + if srcloc is not None and reg is not srcloc: + self.mc.MOV(reg, srcloc) + return reg + + def create_scratch_reg8(self, srcloc=None): + reg32 = self._use_next_reg_abcd() + reg8 = reg32.lowest8bits() + if srcloc is not None and reg8 is not srcloc and reg32 is not srcloc: + if srcloc.width == 1: + self.mc.MOV(reg8, srcloc) + else: + self.mc.MOV(reg32, srcloc) + return reg8 + + def operation_result_is_used(self, v): + return v in self.lifetime + + def clobber(self, reg): + """Clobbers a register, i.e. move away a value that would be there. + It might go to a different register or to the stack. + You must eventually call end_clobber().""" + assert isinstance(reg, REG) + if not self.registers_free & reg.bitmask: + for v1 in self.vars_in_use: + if self.var2loc[v1] == reg: + self._move_away(v1) + break + assert self.registers_free & reg.bitmask + self.registers_free &= ~reg.bitmask + + def clobber2(self, reg1, reg2): + """Clobbers two registers. Unlike two individual clobber() calls, + where the first call might overwrite the other reg, this one + preserves the current content of both 'reg1' and 'reg2'. + You must eventually call end_clobber() twice.""" + if not self.registers_free & reg2.bitmask: + # order trick: if reg2 is free but reg1 used, doing clobber() in + # the following order could first move reg1 to reg2, and then + # immediately away from reg2. + self.clobber(reg1) # <- here reg1 cannot go to reg2 + self.clobber(reg2) + else: + self.clobber(reg2) # reg2 is free, so it doesn't go anywhere + self.clobber(reg1) + + def clobber3(self, reg1, reg2, reg3): + if not self.registers_free & reg3.bitmask: + self.clobber2(reg1, reg2) # they cannot go to reg3 + self.clobber(reg3) + else: + self.clobber(reg3) # free, so doesn't go anywhere + self.clobber2(reg1, reg2) + + def end_clobber(self, reg): + assert isinstance(reg, REG) + self.registers_free |= reg.bitmask + + def clobber_cc(self): + v = self.cc_used_by + if v is not None: + self.cc_used_by = None + # pick a newloc that is either one of [eax, ecx, edx, ebx] + # or a stack location + oldloc = self.var2loc[v] + newloc = self._use_next_modrm(v, regnum_must_be_before=4) + if not we_are_translated(): + print ' # %20s: MOVE AWAY FROM %s' % (newloc, oldloc) + assert isinstance(oldloc, CCFLAG) + mc = self.mc + newloc8 = newloc.lowest8bits() + if isinstance(newloc, REG): + oldloc.SETCOND(mc, newloc8) + mc.MOVZX(newloc, newloc8) + else: + mc.MOV(newloc, imm8(0)) + oldloc.SETCOND(mc, newloc8) + self._mark_loc_as_free(oldloc) + self.var2loc[v] = newloc + + def lock(self, loc): + """Temporarily prevent 'loc' from being overwritten by the + functions marked as 'moves stuff around'. Return True if the + lock is sucessful, False if the location was not free in the + first place.""" + return self.consume_loc(None, loc) + + def unlock(self, loc): + """Call sometime after a lock() that returned True.""" + self._mark_loc_as_free(loc) + + def _move_away(self, v): + # move 'v' away, into a newly allocated register or stack location, + # possibly spilling another register + oldloc = self.var2loc[v] + newloc = self._use_next_modrm(v) + if not we_are_translated(): + print ' # %20s: MOVE AWAY FROM %s' % (newloc, oldloc) + self.mc.MOV(newloc, oldloc) + self._mark_loc_as_free(oldloc) + self.var2loc[v] = newloc + return newloc - def load_location_with(self, loc, gv_source): - dstop = self.operands[loc] - srcop = self.get_operand(gv_source) - if srcop != dstop: - self.mc.MOV(dstop, srcop) - return dstop - - def generate_initial_moves(self): - initial_moves = self.initial_moves - # first make sure that the reserved stack frame is big enough - last_n = self.required_frame_depth - 1 - for loc, srcoperand in initial_moves: - if isinstance(srcoperand, MODRM): - n = stack_n_from_op(srcoperand) - if last_n < n: - last_n = n - if last_n >= 0: - if CALL_ALIGN > 1: - last_n = (last_n & ~(CALL_ALIGN-1)) + (CALL_ALIGN-1) - self.required_frame_depth = last_n + 1 - self.mc.LEA(esp, stack_op(last_n)) + def _check(self): + if not we_are_translated(): + def unpackbitmask(x): + return dict.fromkeys([r for r in registers if x & r.bitmask]) + rf = unpackbitmask(self.AVAILABLE_REGS) + locs_seen = {} + for v in self.vars_in_use: + loc = self.var2loc[v] + assert loc not in locs_seen + locs_seen[loc] = v + if isinstance(loc, REG): + del rf[loc] + assert unpackbitmask(self.registers_free) == rf + + # ---------- + + def generate_final_moves(self, final_vars_gv, locations): # XXX naive algo for now - for loc, srcoperand in initial_moves: - if self.operands[loc] != srcoperand: - self.mc.PUSH(srcoperand) - initial_moves.reverse() - for loc, srcoperand in initial_moves: - if self.operands[loc] != srcoperand: - self.mc.POP(self.operands[loc]) - - def randomize_stack(self): - import random - last_n = self.required_frame_depth - 1 - for i in range(last_n+1, last_n+50): - self.mc.MOV(ecx, stack_op(i)) - self.mc.LEA(ecx, mem(ecx, random.randrange(-sys.maxint, - sys.maxint))) - self.mc.MOV(stack_op(i), ecx) - self.mc.LEA(ecx, mem(ecx, random.randrange(-sys.maxint, - sys.maxint))) - - def generate_operations(self): - for v in self.operations: - if DEBUG_STACK: - self.randomize_stack() - v.generate(self) - cc = v.cc_result - if cc >= 0 and v in self.var2loc: - # force a comparison instruction's result into a - # regular location - dstop = self.get_operand(v) - mc = self.mc - insn = EMIT_SETCOND[cc] - insn(mc, cl) - try: - mc.MOVZX(dstop, cl) - except FailedToImplement: - mc.MOVZX(ecx, cl) - mc.MOV(dstop, ecx) - if DEBUG_STACK: - self.randomize_stack() - - def force_stack_storage(self, lst): - # this is called at the very beginning, so the 'loc' numbers - # computed here are the smaller ones - N = 0 - for v, place in lst: - self.using(v) - loc = self.var2loc[v] - if loc >= N: - N = loc + 1 - self.num_stack_locs = N - - def save_storage_places(self, lst): - for v, place in lst: - loc = self.var2loc[v] - operand = self.operands[loc] - place.offset = operand.ofs_relative_to_ebp() + pops = [] + for i in range(len(final_vars_gv)): + v = final_vars_gv[i] + if not v.is_const: + srcloc = self.var2loc[v] + dstloc = locations[i] + if srcloc != dstloc: + if not we_are_translated(): + print ' > %20s--->->->---%s' % (srcloc, dstloc) + if isinstance(srcloc, CCFLAG): + self.mc.PUSH(imm8(0)) + srcloc.SETCOND(self.mc, mem8(esp)) + else: + self.mc.PUSH(srcloc) + pops.append(dstloc) + while pops: + dstloc = pops.pop() + self.mc.POP(dstloc) + for i in range(len(final_vars_gv)): + v = final_vars_gv[i] + if v.is_const: + dstloc = locations[i] + self.mc.MOV(dstloc, imm(v.revealconst(lltype.Signed))) + + +class OutOfRegistersError(Exception): + pass +def short(op, memo={}): + key = op.__class__.__name__ + d = memo.setdefault(key, {}) + try: + n = d[op] + except KeyError: + n = d[op] = len(d) + return '%s-%d' % (key, n) + +# ____________________________________________________________ + +class DeadOperation(Operation): + clobbers_cc = False + side_effects = False + def mark_used_vars(self, allocator): + pass + def generate(self, allocator): + pass +dead_operation = DeadOperation() +forget_stack_storage = DeadOperation() -class StorageInStack(GenVar): +class StorageInStack(Op1): """Place of a variable that must live in the stack. Its position is - choosen by the register allocator and put in the 'stackn' attribute.""" - offset = 0 + choosen by the register allocator and put in the 'offset' attribute.""" + + def generate(self, allocator): + # patch the lifetime of the variable if needed (XXX a bit slow) + x = self.x + i = allocator.lifetime.get(x, allocator.operationindex) + operations = allocator.operations + while i < len(operations): + if operations[i] is forget_stack_storage: + break + i += 1 + allocator.lifetime[x] = i + allocator.vars_in_use[x] = i + # force it to be in the stack + srcop = allocator.get_operand(x) + if not isinstance(srcop, MODRM): + oldop = srcop + srcop = allocator._spill(x, srcop) + allocator._mark_loc_as_free(oldop) + # record its location + self.offset = srcop.ofs_relative_to_ebp() + # for places, self.x would keep lots of other Operations alive + self.x = None def get_offset(self): - assert self.offset != 0 # otherwise, RegAllocator bug return self.offset - -class Place(StorageInStack): - pass +gv_frame_base = GenVar() Modified: pypy/branch/new-jit-codegen/i386/rgenop.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/codegen/i386/rgenop.py (original) +++ pypy/branch/new-jit-codegen/i386/rgenop.py Wed Feb 7 13:44:55 2007 @@ -6,8 +6,10 @@ from pypy.jit.codegen.model import ReplayBuilder, dummy_var from pypy.jit.codegen.i386.codebuf import CodeBlockOverflow from pypy.jit.codegen.i386.operation import * -from pypy.jit.codegen.i386.regalloc import RegAllocator, StorageInStack, Place -from pypy.jit.codegen.i386.regalloc import DEBUG_STACK +from pypy.jit.codegen.i386.regalloc import RegAllocator +from pypy.jit.codegen.i386.regalloc import DEBUG_STACK, forget_stack_storage +from pypy.jit.codegen.i386.regalloc import gv_frame_base, StorageInStack +from pypy.jit.codegen.i386.regalloc import write_stack_reserve, write_stack_adj from pypy.jit.codegen import conftest from pypy.rpython.annlowlevel import llhelper @@ -84,16 +86,18 @@ class FlexSwitch(CodeGenSwitch): REG = eax - def __init__(self, rgenop, inputargs_gv, inputoperands): + def __init__(self, rgenop, graphctx, inputargs_gv, inputoperands): self.rgenop = rgenop + self.graphctx = graphctx self.inputargs_gv = inputargs_gv self.inputoperands = inputoperands self.defaultcaseaddr = 0 def initialize(self, mc): + self.graphctx.write_stack_adj(mc, initial=False) self._reserve(mc) - default_builder = Builder(self.rgenop, self.inputargs_gv, - self.inputoperands) + default_builder = Builder(self.rgenop, self.graphctx, + self.inputargs_gv, self.inputoperands) start = self.nextfreepos end = self.endfreepos fullmc = self.rgenop.InMemoryCodeBuilder(start, end) @@ -123,8 +127,8 @@ def add_case(self, gv_case): rgenop = self.rgenop - targetbuilder = Builder(self.rgenop, self.inputargs_gv, - self.inputoperands) + targetbuilder = Builder(self.rgenop, self.graphctx, + self.inputargs_gv, self.inputoperands) try: self._add_case(gv_case, targetbuilder) except CodeBlockOverflow: @@ -206,12 +210,12 @@ class Builder(GenBuilder): coming_from = 0 update_defaultcaseaddr_of = None - force_in_stack = None paused_alive_gv = None order_dependency = None - def __init__(self, rgenop, inputargs_gv, inputoperands): + def __init__(self, rgenop, graphctx, inputargs_gv, inputoperands): self.rgenop = rgenop + self.graphctx = graphctx self.inputargs_gv = inputargs_gv self.inputoperands = inputoperands self.operations = [] @@ -219,34 +223,27 @@ def start_writing(self): self.paused_alive_gv = None - def generate_block_code(self, final_vars_gv, force_vars=[], - force_operands=[], - renaming=True, - minimal_stack_depth=0): + def generate_block_code(self, final_vars_gv, force_vars=None, + force_operands=None, + renaming=True): if self.order_dependency is not None: self.order_dependency.force_generate_code() self.order_dependency = None - allocator = RegAllocator() - if self.force_in_stack is not None: - allocator.force_stack_storage(self.force_in_stack) - allocator.set_final(final_vars_gv) + allocator = RegAllocator(self.operations) + if final_vars_gv is not force_vars: + allocator.set_final(final_vars_gv) + if force_vars is not None: + allocator.set_final_at_loc(force_vars, force_operands) if not renaming: - final_vars_gv = allocator.var2loc.keys() # unique final vars - allocator.allocate_locations(self.operations) - allocator.force_var_operands(force_vars, force_operands, - at_start=False) - allocator.force_var_operands(self.inputargs_gv, self.inputoperands, - at_start=True) - allocator.allocate_registers() - if allocator.required_frame_depth < minimal_stack_depth: - allocator.required_frame_depth = minimal_stack_depth + final_vars_gv = allocator.varsused() # unique final vars + allocator.compute_lifetimes() + allocator.init_reg_alloc(self.inputargs_gv, self.inputoperands) mc = self.start_mc() - allocator.mc = mc - allocator.generate_initial_moves() - allocator.generate_operations() - if self.force_in_stack is not None: - allocator.save_storage_places(self.force_in_stack) - self.force_in_stack = None + allocator.generate_operations(mc) + if force_vars is not None: + allocator.generate_final_moves(force_vars, force_operands) + #print 'NSTACKMAX==============>', allocator.nstackmax + self.graphctx.ensure_stack_vars(allocator.nstackmax) del self.operations[:] if renaming: self.inputargs_gv = [GenVar() for v in final_vars_gv] @@ -257,24 +254,12 @@ return mc def enter_next_block(self, kinds, args_gv): - if self.force_in_stack is not None: - # force_in_stack would keep the variables alive until the end - # of the whole mc block, i.e. past the OpSameAs that we are - # about to introduce => duplication of the value. - mc = self.generate_block_code(args_gv) - assert len(self.inputargs_gv) == len(args_gv) - args_gv[:len(args_gv)] = self.inputargs_gv - self.set_coming_from(mc) - mc.done() - self.rgenop.close_mc(mc) - self.start_writing() - else: - # otherwise, we get better register allocation if we write a - # single larger mc block - for i in range(len(args_gv)): - op = OpSameAs(args_gv[i]) - args_gv[i] = op - self.operations.append(op) + # we get better register allocation if we write a single large mc block + self.operations.append(forget_stack_storage) + for i in range(len(args_gv)): + op = OpSameAs(args_gv[i]) + args_gv[i] = op + self.operations.append(op) lbl = Label(self) lblop = OpLabel(lbl, args_gv) self.operations.append(lblop) @@ -313,23 +298,18 @@ self.coming_from = 0 return mc - def _jump_if(self, gv_condition, args_for_jump_gv, negate): - newbuilder = Builder(self.rgenop, list(args_for_jump_gv), None) + def _jump_if(self, cls, gv_condition, args_for_jump_gv): + newbuilder = Builder(self.rgenop, self.graphctx, + list(args_for_jump_gv), None) newbuilder.order_dependency = self - # if the condition does not come from an obvious comparison operation, - # e.g. a getfield of a Bool or an input argument to the current block, - # then insert an OpIntIsTrue - if gv_condition.cc_result < 0 or gv_condition not in self.operations: - gv_condition = OpIntIsTrue(gv_condition) - self.operations.append(gv_condition) - self.operations.append(JumpIf(gv_condition, newbuilder, negate=negate)) + self.operations.append(cls(gv_condition, newbuilder)) return newbuilder def jump_if_false(self, gv_condition, args_for_jump_gv): - return self._jump_if(gv_condition, args_for_jump_gv, True) + return self._jump_if(JumpIfNot, gv_condition, args_for_jump_gv) def jump_if_true(self, gv_condition, args_for_jump_gv): - return self._jump_if(gv_condition, args_for_jump_gv, False) + return self._jump_if(JumpIf, gv_condition, args_for_jump_gv) def finish_and_goto(self, outputargs_gv, targetlbl): operands = targetlbl.inputoperands @@ -342,20 +322,20 @@ self.start_writing() operands = targetlbl.inputoperands assert operands is not None - mc = self.generate_block_code(outputargs_gv, outputargs_gv, operands, - minimal_stack_depth = targetlbl.targetstackdepth) + mc = self.generate_block_code(outputargs_gv, outputargs_gv, operands) mc.JMP(rel32(targetlbl.targetaddr)) mc.done() self.rgenop.close_mc(mc) def finish_and_return(self, sigtoken, gv_returnvar): - mc = self.generate_block_code([gv_returnvar], [gv_returnvar], [eax]) + gvs = [gv_returnvar] + mc = self.generate_block_code(gvs, gvs, [eax]) # --- epilogue --- - mc.LEA(esp, mem(ebp, -12)) + mc.MOV(esp, ebp) + mc.POP(ebp) mc.POP(edi) mc.POP(esi) mc.POP(ebx) - mc.POP(ebp) mc.RET() # ---------------- mc.done() @@ -488,7 +468,8 @@ reg = FlexSwitch.REG mc = self.generate_block_code(args_gv, [gv_exitswitch], [reg], renaming=False) - result = FlexSwitch(self.rgenop, self.inputargs_gv, self.inputoperands) + result = FlexSwitch(self.rgenop, self.graphctx, + self.inputargs_gv, self.inputoperands) default_builder = result.initialize(mc) mc.done() self.rgenop.close_mc(mc) @@ -502,49 +483,78 @@ # XXX re-do this somehow... def genop_get_frame_base(self): - op = OpGetFrameBase() - self.operations.append(op) - return op + return gv_frame_base def get_frame_info(self, vars_gv): - if self.force_in_stack is None: - self.force_in_stack = [] result = [] for v in vars_gv: if not v.is_const: - place = StorageInStack() - self.force_in_stack.append((v, place)) + place = StorageInStack(v) + self.operations.append(place) v = place result.append(v) return result def alloc_frame_place(self, kind, gv_initial_value=None): - if self.force_in_stack is None: - self.force_in_stack = [] if gv_initial_value is None: v = OpWhatever() else: v = OpSameAs(gv_initial_value) self.operations.append(v) - place = Place() - place.stackvar = v - self.force_in_stack.append((v, place)) + place = StorageInStack(v) + self.operations.append(place) return place def genop_absorb_place(self, kind, place): - v = place.stackvar - place.stackvar = None # break reference to potentially lots of memory - return v + return place.x class Label(GenLabel): targetaddr = 0 - targetstackdepth = 0 inputoperands = None def __init__(self, targetbuilder): self.targetbuilder = targetbuilder + +class GraphCtx: + # keep this in sync with the generated function prologue: + # how many extra words are initially pushed (including the + # return value, pushed by the caller) + PROLOGUE_FIXED_WORDS = 5 + + def __init__(self, rgenop): + self.rgenop = rgenop + self.initial_addr = 0 # position where there is the initial ADD ESP + self.adj_addrs = [] # list of positions where there is a LEA ESP + self.reserved_stack_vars = 0 + + def write_stack_adj(self, mc, initial): + if initial: + addr = write_stack_reserve(mc, self.reserved_stack_vars) + self.initial_addr = addr + else: + addr = write_stack_adj(mc, self.reserved_stack_vars) + self.adj_addrs.append(addr) + + def ensure_stack_vars(self, n): + if CALL_ALIGN > 1: + # align the stack to a multiple of CALL_ALIGN words + stack_words = GraphCtx.PROLOGUE_FIXED_WORDS + n + stack_words = (stack_words + CALL_ALIGN-1) & ~ (CALL_ALIGN-1) + n = stack_words - GraphCtx.PROLOGUE_FIXED_WORDS + # patch all the LEA ESP if the requested amount has grown + if n > self.reserved_stack_vars: + addr = self.initial_addr + patchmc = self.rgenop.InMemoryCodeBuilder(addr, addr+99) + write_stack_reserve(patchmc, n) + patchmc.done() + for addr in self.adj_addrs: + patchmc = self.rgenop.InMemoryCodeBuilder(addr, addr+99) + write_stack_adj(patchmc, n) + patchmc.done() + self.reserved_stack_vars = n + # ____________________________________________________________ @@ -557,39 +567,38 @@ MC_SIZE *= 16 def __init__(self): - self.mcs = [] # machine code blocks where no-one is currently writing + self.allocated_mc = None self.keepalive_gc_refs = [] - self.total_code_blocks = 0 def open_mc(self): - if self.mcs: - # XXX think about inserting NOPS for alignment - return self.mcs.pop() - else: - # XXX supposed infinite for now - self.total_code_blocks += 1 + # XXX supposed infinite for now + mc = self.allocated_mc + if mc is None: return self.MachineCodeBlock(self.MC_SIZE) + else: + self.allocated_mc = None + return mc def close_mc(self, mc): - # an open 'mc' is ready for receiving code... but it's also ready - # for being garbage collected, so be sure to close it if you - # want the generated code to stay around :-) - self.mcs.append(mc) + assert self.allocated_mc is None + self.allocated_mc = mc def check_no_open_mc(self): - assert len(self.mcs) == self.total_code_blocks + pass def newgraph(self, sigtoken, name): + graphctx = GraphCtx(self) # --- prologue --- mc = self.open_mc() entrypoint = mc.tell() if DEBUG_TRAP: mc.BREAKPOINT() - mc.PUSH(ebp) - mc.MOV(ebp, esp) mc.PUSH(ebx) mc.PUSH(esi) mc.PUSH(edi) + mc.PUSH(ebp) + mc.MOV(ebp, esp) + graphctx.write_stack_adj(mc, initial=True) # ^^^ pushed 5 words including the retval ( == PROLOGUE_FIXED_WORDS) # ---------------- numargs = sigtoken # for now @@ -597,8 +606,9 @@ inputoperands = [] for i in range(numargs): inputargs_gv.append(GenVar()) - inputoperands.append(mem(ebp, WORD * (2+i))) - builder = Builder(self, inputargs_gv, inputoperands) + ofs = WORD * (GraphCtx.PROLOGUE_FIXED_WORDS+i) + inputoperands.append(mem(ebp, ofs)) + builder = Builder(self, graphctx, inputargs_gv, inputoperands) # XXX this makes the code layout in memory a bit obscure: we have the # prologue of the new graph somewhere in the middle of its first # caller, all alone... Modified: pypy/branch/new-jit-codegen/i386/ri386.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/codegen/i386/ri386.py (original) +++ pypy/branch/new-jit-codegen/i386/ri386.py Wed Feb 7 13:44:55 2007 @@ -2,16 +2,21 @@ class OPERAND(object): + _attrs_ = [] def __repr__(self): return '<%s %s>' % (self.__class__.__name__, self.assembler()) class REG(OPERAND): width = 4 - lowest8bits = None def __repr__(self): return '<%s>' % self.__class__.__name__.lower() def assembler(self): return '%' + self.__class__.__name__.lower() + def lowest8bits(self): + if self.op < 4: + return registers8[self.op] + else: + raise ValueError class REG8(OPERAND): width = 1 @@ -47,11 +52,18 @@ def assembler(self): return '$%d' % (self.value,) + def lowest8bits(self): + val = self.value & 0xFF + if val > 0x7F: + val -= 0x100 + return IMM8(val) + class IMM8(IMM32): width = 1 class IMM16(OPERAND): # only for RET width = 2 + value = 0 # annotator hack def __init__(self, value): self.value = value @@ -65,6 +77,9 @@ self.byte = byte self.extradata = extradata + def lowest8bits(self): + return MODRM8(self.byte, self.extradata) + def assembler(self): mod = self.byte & 0xC0 rm = self.byte & 0x07 @@ -186,14 +201,13 @@ dh = DH() bh = BH() -eax.lowest8bits = al -ecx.lowest8bits = cl -edx.lowest8bits = dl -ebx.lowest8bits = bl - registers = [eax, ecx, edx, ebx, esp, ebp, esi, edi] registers8 = [al, cl, dl, bl, ah, ch, dh, bh] +for r in registers + registers8: + r.bitmask = 1 << r.op +del r + imm32 = IMM32 imm8 = IMM8 imm16 = IMM16 @@ -257,6 +271,10 @@ else: return cls(0x84, SIB + packimm32(offset)) +def fixedsize_esp_ofs(offset): + SIB = '\x24' + return MODRM(0x84, SIB + packimm32(offset)) + def single_byte(value): return -128 <= value < 128 Modified: pypy/branch/new-jit-codegen/i386/ri386setup.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/codegen/i386/ri386setup.py (original) +++ pypy/branch/new-jit-codegen/i386/ri386setup.py Wed Feb 7 13:44:55 2007 @@ -273,6 +273,10 @@ MOV.mode2(MODRM8,REG8, ['\x88', register(2,8,'b'), modrm(1,'b')]) MOV.mode2(REG8, MODRM8,['\x8A', register(1,8,'b'), modrm(2,'b')]) +# special modes for writing explicit 16-bit immediates (must also use o16!) +MOV.mode2(REG, IMM16, [register(1), '\xB8', immediate(2,'h')]) +MOV.mode2(MODRM, IMM16, ['\xC7', orbyte(0<<3), modrm(1), immediate(2,'h')]) + ADD = Instruction() ADD.common_modes(0) Modified: pypy/branch/new-jit-codegen/i386/test/test_auto_encoding.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/codegen/i386/test/test_auto_encoding.py (original) +++ pypy/branch/new-jit-codegen/i386/test/test_auto_encoding.py Wed Feb 7 13:44:55 2007 @@ -198,6 +198,8 @@ if ((args[1][1] in (i386.eax, i386.al)) and args[0][1].assembler().lstrip('-').isdigit()): return [] # MOV [constant-address], accum + if args[1][1].__class__ == i386.IMM16: + return [] # MOV mod/rm, imm16 if instrname == "LEA": if (args[1][1].__class__ != i386.MODRM or args[1][1].is_register()): Modified: pypy/branch/new-jit-codegen/test/rgenop_tests.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/codegen/test/rgenop_tests.py (original) +++ pypy/branch/new-jit-codegen/test/rgenop_tests.py Wed Feb 7 13:44:55 2007 @@ -13,6 +13,7 @@ FUNC2 = lltype.FuncType([lltype.Signed]*2, lltype.Signed) FUNC3 = lltype.FuncType([lltype.Signed]*3, lltype.Signed) FUNC5 = lltype.FuncType([lltype.Signed]*5, lltype.Signed) +FUNC27= lltype.FuncType([lltype.Signed]*27, lltype.Signed) def make_adder(rgenop, n): # 'return x+n' @@ -1581,6 +1582,142 @@ res = fnptr(2, 10, 10, 400, 0) assert res == 0 + def test_from_random_4_direct(self): +## def dummyfn(counter, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z): +## while True: + +## if b: +## pass + +## g = q and j +## d = intmask(s - y) # d +## # t <0x64(%ebp)> + +## e = y != f # e +## j = c or j +## o = d or t # d o +## t = l > o # t +## if e: +## pass + +## counter -= 1 +## if not counter: break + +## return intmask(a*-468864544+b*-340864157+c*-212863774+d*-84863387+e*43136996+f*171137383+g*299137766+h*427138153+i*555138536+j*683138923+k*811139306+l*939139693+m*1067140076+n*1195140463+o*1323140846+p*1451141233+q*1579141616+r*1707142003+s*1835142386+t*1963142773+u*2091143156+v*-2075823753+w*-1947823370+x*-1819822983+y*-1691822600+z*-1563822213) + + rgenop = self.RGenOp() + signed_kind = rgenop.kindToken(lltype.Signed) + bool_kind = rgenop.kindToken(lltype.Bool) + + builder0, gv_callable, [v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26] = rgenop.newgraph(rgenop.sigToken(FUNC27), 'compiled_dummyfn') + builder0.start_writing() + args_gv = [v0, v1, v2, v3, v6, v8, v9, v10, v11, v12, v13, v14, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26] + label0 = builder0.enter_next_block([signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind], args_gv) + [v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49] = args_gv + v50 = builder0.genop1('int_is_true', v29) + builder1 = builder0.jump_if_true(v50, [v48, v38, v27, v30, v32, v34, v47, v40, v28, v41, v43, v45, v37, v46, v31, v33, v35, v39, v36, v42, v49, v44, v29]) + args_gv = [v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49] + label1 = builder0.enter_next_block([signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind], args_gv) + [v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63, v64, v65, v66, v67, v68, v69, v70, v71, v72, v73] = args_gv + v74 = builder0.genop1('int_is_true', v64) + builder2 = builder0.jump_if_true(v74, [v54, v52, v65, v58, v60, v62, v64, v68, v56, v69, v71, v51, v73, v53, v67, v57, v55, v59, v61, v63, v66, v70, v72]) + args_gv = [v51, v52, v53, v54, v55, v64, v56, v57, v58, v59, v60, v61, v62, v63, v64, v65, v66, v67, v68, v69, v70, v71, v72, v73] + label2 = builder0.enter_next_block([signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind], args_gv) + [v75, v76, v77, v78, v79, v80, v81, v82, v83, v84, v85, v86, v87, v88, v89, v90, v91, v92, v93, v94, v95, v96, v97, v98] = args_gv + v99 = builder0.genop2('int_sub', v91, v97) + v100 = builder0.genop2('int_ne', v97, v79) + v101 = builder0.genop1('int_is_true', v78) + builder3 = builder0.jump_if_true(v101, [v85, v93, v94, v87, v91, v97, v89, v98, v80, v82, v78, v86, v84, v99, v88, v100, v90, v92, v96, v75, v95, v76, v77, v79, v81]) + args_gv = [v75, v76, v77, v78, v99, v100, v79, v80, v81, v82, v83, v84, v85, v86, v87, v88, v89, v90, v91, v92, v93, v94, v95, v96, v97, v98] + label3 = builder0.enter_next_block([signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, bool_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind], args_gv) + [v102, v103, v104, v105, v106, v107, v108, v109, v110, v111, v112, v113, v114, v115, v116, v117, v118, v119, v120, v121, v122, v123, v124, v125, v126, v127] = args_gv + v128 = builder0.genop1('int_is_true', v106) + builder4 = builder0.jump_if_false(v128, [v114, v111, v116, v113, v118, v122, v110, v124, v103, v125, v105, v127, v107, v112, v121, v109, v115, v117, v119, v123, v102, v120, v104, v126, v106, v108]) + args_gv = [v102, v103, v104, v105, v106, v107, v108, v109, v110, v111, v112, v113, v114, v115, v116, v106, v117, v118, v119, v120, v122, v123, v124, v125, v126, v127] + label4 = builder0.enter_next_block([signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, bool_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind], args_gv) + [v129, v130, v131, v132, v133, v134, v135, v136, v137, v138, v139, v140, v141, v142, v143, v144, v145, v146, v147, v148, v149, v150, v151, v152, v153, v154] = args_gv + v155 = builder0.genop2('int_gt', v141, v144) + builder5 = builder0.jump_if_false(v134, [v149, v148, v141, v143, v145, v147, v151, v139, v152, v132, v154, v134, v136, v130, v140, v138, v142, v155, v144, v146, v150, v129, v137, v131, v153, v133, v135]) + args_gv = [v130, v131, v132, v133, v134, v135, v136, v137, v138, v139, v140, v141, v142, v143, v144, v145, v146, v147, v148, v155, v149, v150, v151, v152, v153, v154, v129] + label5 = builder0.enter_next_block([signed_kind, signed_kind, signed_kind, signed_kind, bool_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, bool_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind, signed_kind], args_gv) + [v156, v157, v158, v159, v160, v161, v162, v163, v164, v165, v166, v167, v168, v169, v170, v171, v172, v173, v174, v175, v176, v177, v178, v179, v180, v181, v182] = args_gv + v183 = builder0.genop2('int_sub', v182, rgenop.genconst(1)) + v184 = builder0.genop1('int_is_true', v183) + builder6 = builder0.jump_if_true(v184, [v177, v166, v169, v171, v183, v173, v156, v165, v179, v158, v180, v168, v164, v178, v176, v172, v174, v167, v157, v175, v181, v161, v163]) + v185 = builder0.genop2('int_mul', v156, rgenop.genconst(-468864544)) + v186 = builder0.genop2('int_mul', v157, rgenop.genconst(-340864157)) + v187 = builder0.genop2('int_add', v185, v186) + v188 = builder0.genop2('int_mul', v158, rgenop.genconst(-212863774)) + v189 = builder0.genop2('int_add', v187, v188) + v190 = builder0.genop2('int_mul', v159, rgenop.genconst(-84863387)) + v191 = builder0.genop2('int_add', v189, v190) + v192 = builder0.genop1('cast_bool_to_int', v160) + v193 = builder0.genop2('int_mul', v192, rgenop.genconst(43136996)) + v194 = builder0.genop2('int_add', v191, v193) + v195 = builder0.genop2('int_mul', v161, rgenop.genconst(171137383)) + v196 = builder0.genop2('int_add', v194, v195) + v197 = builder0.genop2('int_mul', v162, rgenop.genconst(299137766)) + v198 = builder0.genop2('int_add', v196, v197) + v199 = builder0.genop2('int_mul', v163, rgenop.genconst(427138153)) + v200 = builder0.genop2('int_add', v198, v199) + v201 = builder0.genop2('int_mul', v164, rgenop.genconst(555138536)) + v202 = builder0.genop2('int_add', v200, v201) + v203 = builder0.genop2('int_mul', v165, rgenop.genconst(683138923)) + v204 = builder0.genop2('int_add', v202, v203) + v205 = builder0.genop2('int_mul', v166, rgenop.genconst(811139306)) + v206 = builder0.genop2('int_add', v204, v205) + v207 = builder0.genop2('int_mul', v167, rgenop.genconst(939139693)) + v208 = builder0.genop2('int_add', v206, v207) + v209 = builder0.genop2('int_mul', v168, rgenop.genconst(1067140076)) + v210 = builder0.genop2('int_add', v208, v209) + v211 = builder0.genop2('int_mul', v169, rgenop.genconst(1195140463)) + v212 = builder0.genop2('int_add', v210, v211) + v213 = builder0.genop2('int_mul', v170, rgenop.genconst(1323140846)) + v214 = builder0.genop2('int_add', v212, v213) + v215 = builder0.genop2('int_mul', v171, rgenop.genconst(1451141233)) + v216 = builder0.genop2('int_add', v214, v215) + v217 = builder0.genop2('int_mul', v172, rgenop.genconst(1579141616)) + v218 = builder0.genop2('int_add', v216, v217) + v219 = builder0.genop2('int_mul', v173, rgenop.genconst(1707142003)) + v220 = builder0.genop2('int_add', v218, v219) + v221 = builder0.genop2('int_mul', v174, rgenop.genconst(1835142386)) + v222 = builder0.genop2('int_add', v220, v221) + v223 = builder0.genop1('cast_bool_to_int', v175) + v224 = builder0.genop2('int_mul', v223, rgenop.genconst(1963142773)) + v225 = builder0.genop2('int_add', v222, v224) + v226 = builder0.genop2('int_mul', v176, rgenop.genconst(2091143156)) + v227 = builder0.genop2('int_add', v225, v226) + v228 = builder0.genop2('int_mul', v177, rgenop.genconst(-2075823753)) + v229 = builder0.genop2('int_add', v227, v228) + v230 = builder0.genop2('int_mul', v178, rgenop.genconst(-1947823370)) + v231 = builder0.genop2('int_add', v229, v230) + v232 = builder0.genop2('int_mul', v179, rgenop.genconst(-1819822983)) + v233 = builder0.genop2('int_add', v231, v232) + v234 = builder0.genop2('int_mul', v180, rgenop.genconst(-1691822600)) + v235 = builder0.genop2('int_add', v233, v234) + v236 = builder0.genop2('int_mul', v181, rgenop.genconst(-1563822213)) + v237 = builder0.genop2('int_add', v235, v236) + builder0.finish_and_return(rgenop.sigToken(FUNC27), v237) + builder2.start_writing() + builder2.finish_and_goto([v51, v52, v53, v54, v55, v58, v56, v57, v58, v59, v60, v61, v62, v63, v64, v65, v66, v67, v68, v69, v70, v71, v72, v73], label2) + builder4.start_writing() + builder4.finish_and_goto([v102, v103, v104, v105, v106, v107, v108, v109, v110, v111, v112, v113, v114, v115, v116, v121, v117, v118, v119, v120, v122, v123, v124, v125, v126, v127], label4) + builder3.start_writing() + builder3.finish_and_goto([v75, v76, v77, v78, v99, v100, v79, v80, v81, v82, v78, v84, v85, v86, v87, v88, v89, v90, v91, v92, v93, v94, v95, v96, v97, v98], label3) + builder1.start_writing() + builder1.finish_and_goto([v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49], label1) + builder5.start_writing() + builder5.finish_and_goto([v130, v131, v132, v133, v134, v135, v136, v137, v138, v139, v140, v141, v142, v143, v144, v145, v146, v147, v148, v155, v149, v150, v151, v152, v153, v154, v129], label5) + builder6.start_writing() + v238 = builder6.genop1('cast_bool_to_int', v175) + builder6.finish_and_goto([v183, v156, v157, v158, v161, v163, v164, v165, v166, v167, v168, v169, v171, v172, v173, v174, v238, v176, v177, v178, v179, v180, v181], label0) + builder6.end() + + fnptr = self.cast(gv_callable, 27) + + res = fnptr(*([5]*27)) + assert res == 967746338 + def test_genzeroconst(self): RGenOp = self.RGenOp gv = RGenOp.genzeroconst(RGenOp.kindToken(lltype.Signed)) From arigo at codespeak.net Wed Feb 7 14:22:39 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 7 Feb 2007 14:22:39 +0100 (CET) Subject: [pypy-svn] r38063 - in pypy/dist/pypy/objspace/std: . test Message-ID: <20070207132239.9D1211007C@code0.codespeak.net> Author: arigo Date: Wed Feb 7 14:22:35 2007 New Revision: 38063 Modified: pypy/dist/pypy/objspace/std/objspace.py pypy/dist/pypy/objspace/std/test/test_intobject.py Log: Test and fix for BINARY_ADD involving int subclasses in the optimized_int_add version. Modified: pypy/dist/pypy/objspace/std/objspace.py ============================================================================== --- pypy/dist/pypy/objspace/std/objspace.py (original) +++ pypy/dist/pypy/objspace/std/objspace.py Wed Feb 7 14:22:35 2007 @@ -63,8 +63,7 @@ W_IntObject, add__Int_Int w_2 = f.popvalue() w_1 = f.popvalue() - if isinstance(w_1, W_IntObject) and \ - isinstance(w_2, W_IntObject): + if type(w_1) is W_IntObject and type(w_2) is W_IntObject: try: w_result = add__Int_Int(f.space, w_1, w_2) except FailedToImplement: 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 Wed Feb 7 14:22:35 2007 @@ -353,6 +353,39 @@ raises(OverflowError,j,sys.maxint+1) raises(OverflowError,j,str(sys.maxint+1)) + def test_int_subclass_ops(self): + import sys + class j(int): + def __add__(self, other): + return "add." + def __iadd__(self, other): + return "iadd." + def __sub__(self, other): + return "sub." + def __isub__(self, other): + return "isub." + def __mul__(self, other): + return "mul." + def __imul__(self, other): + return "imul." + def __lshift__(self, other): + return "lshift." + def __ilshift__(self, other): + return "ilshift." + assert j(100) + 5 == "add." + assert j(100) + str == "add." + assert j(100) - 5 == "sub." + assert j(100) - str == "sub." + assert j(100) * 5 == "mul." + assert j(100) * str == "mul." + assert j(100) << 5 == "lshift." + assert j(100) << str == "lshift." + assert (5 + j(100), type(5 + j(100))) == ( 105, int) + assert (5 - j(100), type(5 - j(100))) == ( -95, int) + assert (5 * j(100), type(5 * j(100))) == ( 500, int) + assert (5 << j(100), type(5 << j(100))) == (5 << 100, long) + assert (j(100) >> 2, type(j(100) >> 2)) == ( 25, int) + def test_special_int(self): class a: def __int__(self): From arigo at codespeak.net Wed Feb 7 15:37:19 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 7 Feb 2007 15:37:19 +0100 (CET) Subject: [pypy-svn] r38065 - pypy/branch/jit-virtual-world/pypy/jit/codegen/i386/test Message-ID: <20070207143719.234081007B@code0.codespeak.net> Author: arigo Date: Wed Feb 7 15:37:16 2007 New Revision: 38065 Modified: pypy/branch/jit-virtual-world/pypy/jit/codegen/i386/test/test_genc_tl.py pypy/branch/jit-virtual-world/pypy/jit/codegen/i386/test/test_genc_tlc.py Log: Modules moved. Modified: pypy/branch/jit-virtual-world/pypy/jit/codegen/i386/test/test_genc_tl.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/codegen/i386/test/test_genc_tl.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/codegen/i386/test/test_genc_tl.py Wed Feb 7 15:37:16 2007 @@ -1,10 +1,10 @@ import py -from pypy.jit.timeshifter.test import test_tl +from pypy.jit.timeshifter.test import test_1tl from pypy.jit.codegen.i386.test.test_genc_ts import I386TimeshiftingTestMixin class TestTLR(I386TimeshiftingTestMixin, - test_tl.TestTL): + test_1tl.TestTL): # for the individual tests see # ====> ../../../timeshifter/test/test_tl.py Modified: pypy/branch/jit-virtual-world/pypy/jit/codegen/i386/test/test_genc_tlc.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/codegen/i386/test/test_genc_tlc.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/codegen/i386/test/test_genc_tlc.py Wed Feb 7 15:37:16 2007 @@ -1,10 +1,10 @@ import py -from pypy.jit.timeshifter.test import test_tlc +from pypy.jit.timeshifter.test import test_0tlc from pypy.jit.codegen.i386.test.test_genc_portal import I386PortalTestMixin class TestTLC(I386PortalTestMixin, - test_tlc.TestTLC): + test_0tlc.TestTLC): # for the individual tests see # ====> ../../../timeshifter/test/test_tlc.py From arigo at codespeak.net Wed Feb 7 15:38:04 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 7 Feb 2007 15:38:04 +0100 (CET) Subject: [pypy-svn] r38066 - pypy/branch/new-jit-codegen/i386/test Message-ID: <20070207143804.1786C10088@code0.codespeak.net> Author: arigo Date: Wed Feb 7 15:38:01 2007 New Revision: 38066 Modified: pypy/branch/new-jit-codegen/i386/test/test_genc_tl.py pypy/branch/new-jit-codegen/i386/test/test_genc_tlc.py Log: Moved modules. Modified: pypy/branch/new-jit-codegen/i386/test/test_genc_tl.py ============================================================================== --- pypy/branch/new-jit-codegen/i386/test/test_genc_tl.py (original) +++ pypy/branch/new-jit-codegen/i386/test/test_genc_tl.py Wed Feb 7 15:38:01 2007 @@ -1,10 +1,10 @@ import py -from pypy.jit.timeshifter.test import test_tl +from pypy.jit.timeshifter.test import test_1tl from pypy.jit.codegen.i386.test.test_genc_ts import I386TimeshiftingTestMixin class TestTLR(I386TimeshiftingTestMixin, - test_tl.TestTL): + test_1tl.TestTL): # for the individual tests see # ====> ../../../timeshifter/test/test_tl.py Modified: pypy/branch/new-jit-codegen/i386/test/test_genc_tlc.py ============================================================================== --- pypy/branch/new-jit-codegen/i386/test/test_genc_tlc.py (original) +++ pypy/branch/new-jit-codegen/i386/test/test_genc_tlc.py Wed Feb 7 15:38:01 2007 @@ -1,10 +1,10 @@ import py -from pypy.jit.timeshifter.test import test_tlc +from pypy.jit.timeshifter.test import test_0tlc from pypy.jit.codegen.i386.test.test_genc_portal import I386PortalTestMixin class TestTLC(I386PortalTestMixin, - test_tlc.TestTLC): + test_0tlc.TestTLC): # for the individual tests see # ====> ../../../timeshifter/test/test_tlc.py From arigo at codespeak.net Wed Feb 7 16:08:53 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 7 Feb 2007 16:08:53 +0100 (CET) Subject: [pypy-svn] r38067 - pypy/branch/jit-virtual-world/pypy/jit/goal/demo Message-ID: <20070207150853.9363610082@code0.codespeak.net> Author: arigo Date: Wed Feb 7 16:08:50 2007 New Revision: 38067 Added: pypy/branch/jit-virtual-world/pypy/jit/goal/demo/ (props changed) pypy/branch/jit-virtual-world/pypy/jit/goal/demo/f1.py (contents, props changed) pypy/branch/jit-virtual-world/pypy/jit/goal/demo/factorial.py (contents, props changed) pypy/branch/jit-virtual-world/pypy/jit/goal/demo/factorialrec.py (contents, props changed) Log: Demo scripts whose machine code can be looked at (run with PYPYJITLOG=filename). Added: pypy/branch/jit-virtual-world/pypy/jit/goal/demo/f1.py ============================================================================== --- (empty file) +++ pypy/branch/jit-virtual-world/pypy/jit/goal/demo/f1.py Wed Feb 7 16:08:50 2007 @@ -0,0 +1,30 @@ +import time + + +ZERO = 0 + +def f1(n): + "Arbitrary test function." + i = 0 + x = 1 + while i 1: + r *= n + n -= 1 + return r + +import pypyjit +pypyjit.enable(f.func_code) + +print f(7) Added: pypy/branch/jit-virtual-world/pypy/jit/goal/demo/factorialrec.py ============================================================================== --- (empty file) +++ pypy/branch/jit-virtual-world/pypy/jit/goal/demo/factorialrec.py Wed Feb 7 16:08:50 2007 @@ -0,0 +1,13 @@ +import time + + +def f(n): + if n > 1: + return n * f(n-1) + else: + return 1 + +import pypyjit +pypyjit.enable(f.func_code) + +print f(7) From arigo at codespeak.net Wed Feb 7 16:16:10 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 7 Feb 2007 16:16:10 +0100 (CET) Subject: [pypy-svn] r38069 - pypy/branch/new-jit-codegen/i386 Message-ID: <20070207151610.14C7F10087@code0.codespeak.net> Author: arigo Date: Wed Feb 7 16:16:09 2007 New Revision: 38069 Modified: pypy/branch/new-jit-codegen/i386/operation.py pypy/branch/new-jit-codegen/i386/regalloc.py pypy/branch/new-jit-codegen/i386/rgenop.py Log: flexswitch() was not really fixed to work in this refactoring. Modified: pypy/branch/new-jit-codegen/i386/operation.py ============================================================================== --- pypy/branch/new-jit-codegen/i386/operation.py (original) +++ pypy/branch/new-jit-codegen/i386/operation.py Wed Feb 7 16:16:09 2007 @@ -836,6 +836,21 @@ allocator.release(self.gv_value) return opsource +class OpGetExitSwitch(Op1): + # a bit of a hack: to put last in a block ending in a flexswitch, + # to load the switch value into a register and remember which + # register it is. + def generate(self, allocator): + op = allocator.get_operand(self.x) + if isinstance(op, REG): + self.reg = op + else: + self.reg = allocator.create_scratch_reg() + op = allocator.get_operand(self.x) + allocator.mc.MOV(self.reg, op) + allocator.end_clobber(self.reg) + allocator.release(self.x) + # ____________________________________________________________ def setup_opclasses(base): Modified: pypy/branch/new-jit-codegen/i386/regalloc.py ============================================================================== --- pypy/branch/new-jit-codegen/i386/regalloc.py (original) +++ pypy/branch/new-jit-codegen/i386/regalloc.py Wed Feb 7 16:16:09 2007 @@ -52,15 +52,12 @@ # ---------- - def set_final(self, final_vars_gv): - for v in final_vars_gv: - self.using(v) - - def set_final_at_loc(self, final_vars_gv, locations): + def set_final(self, final_vars_gv, locations=None): for i in range(len(final_vars_gv)): v = final_vars_gv[i] self.using(v) - self.suggested_location[v] = locations[i] + if locations is not None: + self.suggested_location[v] = locations[i] def compute_lifetimes(self): for i in range(len(self.operations)-1, -1, -1): @@ -421,8 +418,13 @@ self.clobber2(reg1, reg2) def end_clobber(self, reg): - assert isinstance(reg, REG) - self.registers_free |= reg.bitmask + if isinstance(reg, REG): + bitmask = reg.bitmask + else: + assert isinstance(reg, REG8) + assert reg.op < 4 + bitmask = reg.bitmask + self.registers_free |= bitmask def clobber_cc(self): v = self.cc_used_by Modified: pypy/branch/new-jit-codegen/i386/rgenop.py ============================================================================== --- pypy/branch/new-jit-codegen/i386/rgenop.py (original) +++ pypy/branch/new-jit-codegen/i386/rgenop.py Wed Feb 7 16:16:09 2007 @@ -84,11 +84,11 @@ # ____________________________________________________________ class FlexSwitch(CodeGenSwitch): - REG = eax - def __init__(self, rgenop, graphctx, inputargs_gv, inputoperands): + def __init__(self, rgenop, graphctx, reg, inputargs_gv, inputoperands): self.rgenop = rgenop self.graphctx = graphctx + self.reg = reg self.inputargs_gv = inputargs_gv self.inputoperands = inputoperands self.defaultcaseaddr = 0 @@ -142,7 +142,7 @@ end = self.endfreepos mc = self.rgenop.InMemoryCodeBuilder(start, end) value = gv_case.revealconst(lltype.Signed) - mc.CMP(FlexSwitch.REG, imm(value)) + mc.CMP(self.reg, imm(value)) targetbuilder.set_coming_from(mc, Conditions['E']) pos = mc.tell() assert self.defaultcaseaddr != 0 @@ -223,25 +223,22 @@ def start_writing(self): self.paused_alive_gv = None - def generate_block_code(self, final_vars_gv, force_vars=None, - force_operands=None, + def generate_block_code(self, final_vars_gv, final_operands=None, renaming=True): if self.order_dependency is not None: self.order_dependency.force_generate_code() self.order_dependency = None allocator = RegAllocator(self.operations) - if final_vars_gv is not force_vars: - allocator.set_final(final_vars_gv) - if force_vars is not None: - allocator.set_final_at_loc(force_vars, force_operands) + allocator.set_final(final_vars_gv, final_operands) if not renaming: + assert final_operands is None final_vars_gv = allocator.varsused() # unique final vars allocator.compute_lifetimes() allocator.init_reg_alloc(self.inputargs_gv, self.inputoperands) mc = self.start_mc() allocator.generate_operations(mc) - if force_vars is not None: - allocator.generate_final_moves(force_vars, force_operands) + if final_operands is not None: + allocator.generate_final_moves(final_vars_gv, final_operands) #print 'NSTACKMAX==============>', allocator.nstackmax self.graphctx.ensure_stack_vars(allocator.nstackmax) del self.operations[:] @@ -322,14 +319,14 @@ self.start_writing() operands = targetlbl.inputoperands assert operands is not None - mc = self.generate_block_code(outputargs_gv, outputargs_gv, operands) + mc = self.generate_block_code(outputargs_gv, operands) mc.JMP(rel32(targetlbl.targetaddr)) mc.done() self.rgenop.close_mc(mc) def finish_and_return(self, sigtoken, gv_returnvar): gvs = [gv_returnvar] - mc = self.generate_block_code(gvs, gvs, [eax]) + mc = self.generate_block_code(gvs, [eax]) # --- epilogue --- mc.MOV(esp, ebp) mc.POP(ebp) @@ -465,10 +462,10 @@ return op def flexswitch(self, gv_exitswitch, args_gv): - reg = FlexSwitch.REG - mc = self.generate_block_code(args_gv, [gv_exitswitch], [reg], - renaming=False) - result = FlexSwitch(self.rgenop, self.graphctx, + op = OpGetExitSwitch(gv_exitswitch) + self.operations.append(op) + mc = self.generate_block_code(args_gv, renaming=False) + result = FlexSwitch(self.rgenop, self.graphctx, op.reg, self.inputargs_gv, self.inputoperands) default_builder = result.initialize(mc) mc.done() From pedronis at codespeak.net Wed Feb 7 16:24:15 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Wed, 7 Feb 2007 16:24:15 +0100 (CET) Subject: [pypy-svn] r38071 - pypy/branch/jit-virtual-world/pypy/jit/goal/demo Message-ID: <20070207152415.22C5510090@code0.codespeak.net> Author: pedronis Date: Wed Feb 7 16:24:13 2007 New Revision: 38071 Modified: pypy/branch/jit-virtual-world/pypy/jit/goal/demo/f1.py Log: make this goal work on a python without pypyjit too. Modified: pypy/branch/jit-virtual-world/pypy/jit/goal/demo/f1.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/goal/demo/f1.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/goal/demo/f1.py Wed Feb 7 16:24:13 2007 @@ -16,8 +16,12 @@ return x -import pypyjit -pypyjit.enable(f1.func_code) +try: + import pypyjit +except ImportError: + print "No jit" +else: + pypyjit.enable(f1.func_code) res = f1(2117) print res From pedronis at codespeak.net Wed Feb 7 16:26:19 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Wed, 7 Feb 2007 16:26:19 +0100 (CET) Subject: [pypy-svn] r38073 - pypy/branch/jit-virtual-world/pypy/interpreter Message-ID: <20070207152619.31F9010087@code0.codespeak.net> Author: pedronis Date: Wed Feb 7 16:26:17 2007 New Revision: 38073 Modified: pypy/branch/jit-virtual-world/pypy/interpreter/pyframe.py pypy/branch/jit-virtual-world/pypy/interpreter/pyopcode.py Log: (arigo, pedronis) * make it so that calls and other operations don't force the valuestack. * don't allocate a new fastlocals_w when we exit a jitted function, reuse the non-virtual one we got at entry. Modified: pypy/branch/jit-virtual-world/pypy/interpreter/pyframe.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/interpreter/pyframe.py (original) +++ pypy/branch/jit-virtual-world/pypy/interpreter/pyframe.py Wed Feb 7 16:26:17 2007 @@ -6,7 +6,7 @@ from pypy.interpreter.error import OperationError from pypy.interpreter import pytraceback import opcode -from pypy.rlib.objectmodel import we_are_translated, instantiate +from pypy.rlib.objectmodel import we_are_translated, instantiate, hint from pypy.rlib import rstack # for resume points @@ -118,6 +118,47 @@ self.valuestackdepth = depth return w_object + def popstrdictvalues(self, n): + dic_w = {} + while True: + n -= 1 + if n < 0: + break + hint(n, concrete=True) + w_value = self.popvalue() + w_key = self.popvalue() + key = self.space.str_w(w_key) + dic_w[key] = w_value + return dic_w + + def popvalues(self, n): + values_w = [None] * n + while True: + n -= 1 + if n < 0: + break + hint(n, concrete=True) + values_w[n] = self.popvalue() + return values_w + + def pushrevvalues(self, n, values_w): # n should be len(values_w) + while True: + n -= 1 + if n < 0: + break + hint(n, concrete=True) + self.pushvalue(values_w[n]) + + def dupvalues(self, n): + delta = n-1 + while True: + n -= 1 + if n < 0: + break + hint(n, concrete=True) + w_value = self.peekvalue(delta) + self.pushvalue(w_value) + def peekvalue(self, index_from_top=0): index = self.valuestackdepth + ~index_from_top assert index >= 0, "peek past the bottom of the stack" Modified: pypy/branch/jit-virtual-world/pypy/interpreter/pyopcode.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/interpreter/pyopcode.py (original) +++ pypy/branch/jit-virtual-world/pypy/interpreter/pyopcode.py Wed Feb 7 16:26:17 2007 @@ -97,6 +97,8 @@ self.pycode = pycode self.valuestackdepth = depth + + entry_fastlocals_w = self.fastlocals_w self.fastlocals_w = fastlocals_w virtualstack_w = [None] * pycode.co_stacksize @@ -110,7 +112,8 @@ next_instr = r_uint(next_instr) co_code = pycode.co_code - while True: + try: + while True: hint(None, global_merge_point=True) try: self.last_instr = intmask(next_instr) @@ -152,6 +155,18 @@ next_instr = self.handle_asynchronous_error(ec, self.space.w_RuntimeError, self.space.wrap(msg)) + finally: + if JITTING: + i = pycode.co_nlocals + while True: + i -= 1 + if i < 0: + break + hint(i, concrete=True) + entry_fastlocals_w[i] = self.fastlocals_w[i] + + self.fastlocals_w = entry_fastlocals_w + def handle_asynchronous_error(self, ec, w_type, w_value=None): # catch asynchronous exceptions and turn them @@ -270,8 +285,12 @@ return next_instr def unrollstack(self, unroller_kind): - while len(self.blockstack) > 0: + n = len(self.blockstack) + n = hint(n, promote=True) + while n > 0: block = self.blockstack.pop() + n -= 1 + hint(n, concrete=True) if (block.handling_mask & unroller_kind) != 0: return block block.cleanupstack(self) @@ -373,9 +392,7 @@ def DUP_TOPX(f, itemcount, *ignored): assert 1 <= itemcount <= 5, "limitation of the current interpreter" - for i in range(itemcount): - w_1 = f.peekvalue(itemcount-1) - f.pushvalue(w_1) + f.dupvalues(itemcount) UNARY_POSITIVE = unaryoperation("pos") UNARY_NEGATIVE = unaryoperation("neg") @@ -635,9 +652,7 @@ items = f.space.unpackiterable(w_iterable, itemcount) except UnpackValueError, e: raise OperationError(f.space.w_ValueError, f.space.wrap(e.msg)) - items.reverse() - for item in items: - f.pushvalue(item) + f.pushrevvalues(itemcount, items) def STORE_ATTR(f, nameindex, *ignored): "obj.attributename = newvalue" @@ -694,14 +709,12 @@ def BUILD_TUPLE(f, itemcount, *ignored): - items = [f.popvalue() for i in range(itemcount)] - items.reverse() + items = f.popvalues(itemcount) w_tuple = f.space.newtuple(items) f.pushvalue(w_tuple) def BUILD_LIST(f, itemcount, *ignored): - items = [f.popvalue() for i in range(itemcount)] - items.reverse() + items = f.popvalues(itemcount) w_list = f.space.newlist(items) f.pushvalue(w_list) @@ -872,15 +885,8 @@ n_keywords = (oparg>>8) & 0xff keywords = None if n_keywords: - keywords = {} - for i in range(n_keywords): - w_value = f.popvalue() - w_key = f.popvalue() - key = f.space.str_w(w_key) - keywords[key] = w_value - arguments = [None] * n_arguments - for i in range(n_arguments - 1, -1, -1): - arguments[i] = f.popvalue() + keywords = f.popstrdictvalues(n_keywords) + arguments = f.popvalues(n_arguments) args = Arguments(f.space, arguments, keywords, w_star, w_starstar) w_function = f.popvalue() w_result = f.space.call_args(w_function, args) @@ -920,8 +926,7 @@ def MAKE_FUNCTION(f, numdefaults, *ignored): w_codeobj = f.popvalue() codeobj = f.space.interp_w(PyCode, w_codeobj) - defaultarguments = [f.popvalue() for i in range(numdefaults)] - defaultarguments.reverse() + defaultarguments = f.popvalues(numdefaults) fn = function.Function(f.space, codeobj, f.w_globals, defaultarguments) f.pushvalue(f.space.wrap(fn)) From arigo at codespeak.net Wed Feb 7 17:09:13 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 7 Feb 2007 17:09:13 +0100 (CET) Subject: [pypy-svn] r38080 - in pypy/branch/new-jit-codegen: dump test Message-ID: <20070207160913.191011005A@code0.codespeak.net> Author: arigo Date: Wed Feb 7 17:09:11 2007 New Revision: 38080 Modified: pypy/branch/new-jit-codegen/dump/rgenop.py pypy/branch/new-jit-codegen/test/rgenop_tests.py Log: Fixes, and a new test, for places with no initial value. Modified: pypy/branch/new-jit-codegen/dump/rgenop.py ============================================================================== --- pypy/branch/new-jit-codegen/dump/rgenop.py (original) +++ pypy/branch/new-jit-codegen/dump/rgenop.py Wed Feb 7 17:09:11 2007 @@ -295,11 +295,15 @@ def alloc_frame_place(self, kind, gv_initial_value=None): place = self.llbuilder.alloc_frame_place(kind, gv_initial_value) + if gv_initial_value is None: + s = 'None' + else: + s = self.rgenop.vname(gv_initial_value) self.dump("%s = %s.alloc_frame_place(%s, %s)" % ( place, self.name, self.rgenop.kindtokenname(kind), - gv_initial_value and self.rgenop.vname(gv_initial_value))) + s)) return place def genop_absorb_place(self, kind, place): Modified: pypy/branch/new-jit-codegen/test/rgenop_tests.py ============================================================================== --- pypy/branch/new-jit-codegen/test/rgenop_tests.py (original) +++ pypy/branch/new-jit-codegen/test/rgenop_tests.py Wed Feb 7 17:09:11 2007 @@ -671,10 +671,13 @@ def writer(base, value): if value > 5: RGenOp.write_frame_place(lltype.Signed, base, - self.place, value * 7) + self.place1, value * 7) + RGenOp.write_frame_place(lltype.Signed, base, + self.place2, value * 10) self.writer = writer - def get_writer(self, place): - self.place = place + def get_writer(self, place1, place2): + self.place1 = place1 + self.place2 = place2 return llhelper(self.FUNC, self.writer) def make_write_frame_place(rgenop, get_writer): @@ -687,11 +690,14 @@ gv_base = builder.genop_get_frame_base() gv_k = rgenop.genconst(-100) - place = builder.alloc_frame_place(signed_kind, gv_initial_value=gv_k) - gv_writer = rgenop.constPrebuiltGlobal(get_writer(place)) + place1 = builder.alloc_frame_place(signed_kind, gv_initial_value=gv_k) + place2 = builder.alloc_frame_place(signed_kind) + gv_writer = rgenop.constPrebuiltGlobal(get_writer(place1, place2)) builder.genop_call(writertoken, gv_writer, [gv_base, gv_x]) - gv_y = builder.genop_absorb_place(signed_kind, place) - builder.finish_and_return(sigtoken, gv_y) + gv_y = builder.genop_absorb_place(signed_kind, place1) + gv_z = builder.genop_absorb_place(signed_kind, place2) + gv_diff = builder.genop2("int_sub", gv_y, gv_z) + builder.finish_and_return(sigtoken, gv_diff) builder.end() return gv_f @@ -1307,9 +1313,10 @@ assert res == 60 def test_write_frame_place_direct(self): - def get_writer(place): + def get_writer(place1, place2): fvw = FramePlaceWriter(self.RGenOp) - fvw.place = place + fvw.place1 = place1 + fvw.place2 = place2 writer_ptr = self.directtesthelper(fvw.FUNC, fvw.writer) return writer_ptr @@ -1317,16 +1324,16 @@ gv_callable = make_write_frame_place(rgenop, get_writer) fnptr = self.cast(gv_callable, 1) res = fnptr(3) - assert res == -100 + assert res == -100 - 30 res = fnptr(6) - assert res == 42 + assert res == 42 - 60 def test_write_frame_place_compile(self): fn = self.compile(get_write_frame_place_runner(self.RGenOp), [int]) res = fn(-42) - assert res == -100 + assert res == -100 - (-420) res = fn(606) - assert res == 4242 + assert res == 4242 - 6060 def test_read_frame_place_direct(self): def get_reader(place): From arigo at codespeak.net Wed Feb 7 17:09:28 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 7 Feb 2007 17:09:28 +0100 (CET) Subject: [pypy-svn] r38081 - pypy/branch/new-jit-codegen/i386 Message-ID: <20070207160928.5D0DB10077@code0.codespeak.net> Author: arigo Date: Wed Feb 7 17:09:26 2007 New Revision: 38081 Modified: pypy/branch/new-jit-codegen/i386/operation.py pypy/branch/new-jit-codegen/i386/rgenop.py Log: * i386 fixes for places with no initial value. * fixes in array_item_operand. Modified: pypy/branch/new-jit-codegen/i386/operation.py ============================================================================== --- pypy/branch/new-jit-codegen/i386/operation.py (original) +++ pypy/branch/new-jit-codegen/i386/operation.py Wed Feb 7 17:09:26 2007 @@ -23,6 +23,8 @@ clobbers_cc = True side_effects = True + def mark_used_vars(self, allocator): + raise NotImplementedError def generate(self, allocator): raise NotImplementedError @@ -105,6 +107,8 @@ class OpWhatever(Operation): clobbers_cc = False side_effects = False + def mark_used_vars(self, allocator): + pass def generate(self, allocator): allocator.create(self) @@ -642,9 +646,9 @@ allocator.create_exactly_at(self, eax) -def field_operand(allocator, base, fieldtoken): +def field_operand(allocator, gv_base, fieldtoken): fieldoffset, fieldsize = fieldtoken - + base = allocator.get_operand(gv_base) if isinstance(base, MODRM): tmp = allocator.create_scratch_reg(base) allocator.end_clobber(tmp) @@ -652,16 +656,18 @@ elif isinstance(base, IMM32): fieldoffset += base.value base = None + allocator.release(gv_base) if fieldsize == 1: return mem8(base, fieldoffset) else: return mem (base, fieldoffset) -def array_item_operand(allocator, base, arraytoken, opindex): +def array_item_operand(allocator, gv_base, arraytoken, gv_opindex): tmp = None _, startoffset, itemoffset = arraytoken + opindex = allocator.get_operand(gv_opindex) if isinstance(opindex, IMM32): startoffset += itemoffset * opindex.value opindex = None @@ -677,21 +683,27 @@ opindex = tmp indexshift = 0 - if isinstance(base, MODRM): - if tmp is None: - tmp = allocator.create_scratch_reg(base) - else: # let's avoid using two scratch registers - opindex = None - if indexshift > 0: - allocator.mc.SHL(tmp, imm8(indexshift)) - allocator.mc.ADD(tmp, base) - base = tmp - elif isinstance(base, IMM32): - startoffset += base.value + if gv_base is None: base = None + else: + base = allocator.get_operand(gv_base) + if isinstance(base, MODRM): + if tmp is None: + tmp = allocator.create_scratch_reg(base) + else: # let's avoid using two scratch registers + opindex = None + if indexshift > 0: + allocator.mc.SHL(tmp, imm8(indexshift)) + allocator.mc.ADD(tmp, base) + base = tmp + elif isinstance(base, IMM32): + startoffset += base.value + base = None + allocator.release(gv_base) if tmp is not None: allocator.end_clobber(tmp) + allocator.release(gv_opindex) if itemoffset == 1: return memSIB8(base, opindex, indexshift, startoffset) @@ -707,10 +719,8 @@ def mark_used_vars(self, allocator): allocator.using(self.gv_length) def generate(self, allocator): - srcop = allocator.get_operand(self.gv_length) op_size = array_item_operand(allocator, None, - self.varsizealloctoken, srcop) - allocator.release(self.gv_length) + self.varsizealloctoken, self.gv_length) dstop = allocator.create_reg(self) allocator.mc.LEA(dstop, op_size) @@ -763,9 +773,7 @@ def mark_used_vars(self, allocator): allocator.using(self.gv_ptr) def generate_opsource(self, allocator): - opptr = allocator.get_operand(self.gv_ptr) - opsource = field_operand(allocator, opptr, self.fieldtoken) - allocator.release(self.gv_ptr) + opsource = field_operand(allocator, self.gv_ptr, self.fieldtoken) return opsource class OpSetField(OpSetter): @@ -781,9 +789,7 @@ allocator.using(self.gv_ptr) allocator.using(self.gv_value) def generate_optarget(self, allocator): - opptr = allocator.get_operand(self.gv_ptr) - optarget = field_operand(allocator, opptr, self.fieldtoken) - allocator.release(self.gv_ptr) + optarget = field_operand(allocator, self.gv_ptr, self.fieldtoken) allocator.release(self.gv_value) return optarget @@ -799,12 +805,8 @@ allocator.using(self.gv_array) allocator.using(self.gv_index) def generate_opsource(self, allocator): - oparray = allocator.get_operand(self.gv_array) - opindex = allocator.get_operand(self.gv_index) - opsource = array_item_operand(allocator, oparray, - self.arraytoken, opindex) - allocator.release(self.gv_array) - allocator.release(self.gv_index) + opsource = array_item_operand(allocator, self.gv_array, + self.arraytoken, self.gv_index) return opsource class OpGetArraySubstruct(OpGetArrayItem): @@ -827,12 +829,8 @@ allocator.using(self.gv_index) allocator.using(self.gv_value) def generate_optarget(self, allocator): - oparray = allocator.get_operand(self.gv_array) - opindex = allocator.get_operand(self.gv_index) - opsource = array_item_operand(allocator, oparray, - self.arraytoken, opindex) - allocator.release(self.gv_array) - allocator.release(self.gv_index) + opsource = array_item_operand(allocator, self.gv_array, + self.arraytoken, self.gv_index) allocator.release(self.gv_value) return opsource Modified: pypy/branch/new-jit-codegen/i386/rgenop.py ============================================================================== --- pypy/branch/new-jit-codegen/i386/rgenop.py (original) +++ pypy/branch/new-jit-codegen/i386/rgenop.py Wed Feb 7 17:09:26 2007 @@ -266,7 +266,7 @@ self.coming_from_cond = insncond self.coming_from = mc.tell() insnemit = EMIT_JCOND[insncond] - insnemit(mc, rel32(0)) + insnemit(mc, rel32(-1)) self.coming_from_end = mc.tell() def start_mc(self): From arigo at codespeak.net Wed Feb 7 19:05:42 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 7 Feb 2007 19:05:42 +0100 (CET) Subject: [pypy-svn] r38085 - pypy/branch/new-jit-codegen/i386 Message-ID: <20070207180542.6606F1007B@code0.codespeak.net> Author: arigo Date: Wed Feb 7 19:05:40 2007 New Revision: 38085 Modified: pypy/branch/new-jit-codegen/i386/operation.py pypy/branch/new-jit-codegen/i386/regalloc.py pypy/branch/new-jit-codegen/i386/rgenop.py Log: Some more delicate balancing. Now some registers are pinned and cannot be spilled by the current operation, which avoids quite some headaches. Fix the code about Places. Also avoids unnecessary moves when a place is created (in particular, if created uninitialized there should be no MOV at all). Modified: pypy/branch/new-jit-codegen/i386/operation.py ============================================================================== --- pypy/branch/new-jit-codegen/i386/operation.py (original) +++ pypy/branch/new-jit-codegen/i386/operation.py Wed Feb 7 19:05:40 2007 @@ -39,13 +39,14 @@ def mark_used_vars(self, allocator): allocator.using_inplace(self.x, self) def generate(self, allocator): + srcop = allocator.get_operand(self.x) if allocator.release(self.x): - dstop = allocator.get_operand(self.x) # in-place operation + # in-place operation + dstop = srcop allocator.create_exactly_at(self, dstop) else: - dstop = allocator.create_reg(self) - srcop = allocator.get_operand(self.x) - allocator.mc.MOV(dstop, srcop) # make a copy in a new register + # make a copy in a new register + dstop = allocator.create_reg(self, srcop) self.emit(allocator.mc, dstop) class OpIntNeg(UnaryOp): @@ -62,19 +63,15 @@ def mark_used_vars(self, allocator): allocator.using(self.x) def generate(self, allocator): - oldsrcop = allocator.get_operand(self.x) - dstop = allocator.create_reg(self) - srcop = allocator.get_operand(self.x) + srcop = allocator.grab_operand(self.x) + dstop = allocator.create_reg(self, srcop) # ABS-computing code from Psyco, found by exhaustive search # on *all* short sequences of operations :-) mc = allocator.mc - if dstop != oldsrcop: - mc.MOV(dstop, srcop) mc.SHL(dstop, imm8(1)) mc.SBB(dstop, srcop) allocator.release(self.x) tmpop = allocator.create_scratch_reg() - dstop = allocator.get_operand(self) mc.SBB(tmpop, tmpop) mc.XOR(dstop, tmpop) allocator.end_clobber(tmpop) @@ -98,27 +95,18 @@ # so we can reuse it for us allocator.create_in_cc(self, srcop) else: - dstop = allocator.create_reg(self) - srcop = allocator.get_operand(self.x) - if srcop != dstop: + dstop = allocator.create(self) + if srcop != dstop: # else srcop spilled, but still in place allocator.mc.MOV(dstop, srcop) allocator.release(self.x) -class OpWhatever(Operation): - clobbers_cc = False - side_effects = False - def mark_used_vars(self, allocator): - pass - def generate(self, allocator): - allocator.create(self) - class OpCompare1(Op1): clobbers_cc = False # special handling of the cc side_effects = False def generate(self, allocator): mc = allocator.mc - srcop = allocator.get_operand(self.x) + srcop = allocator.grab_operand(self.x) if isinstance(srcop, CCFLAG): ccop = srcop allocator.release(self.x) @@ -128,7 +116,6 @@ ccop = ccflags[cond_negate(ccop.cc)] else: allocator.clobber_cc() - srcop = allocator.get_operand(self.x) mc.CMP(srcop, imm8(0)) allocator.release(self.x) ccop = ccflags[self.suggested_cc] @@ -164,6 +151,8 @@ allocator.using(self.y) def generate(self, allocator): + # warning, subtleties about using get_operand() instead + # of grab_operand() for the best possible results x, y = self.x, self.y op1 = allocator.get_operand(x) op2 = allocator.get_operand(y) @@ -187,11 +176,8 @@ allocator.release(y) allocator.create_exactly_at(self, op1) else: - dstop = allocator.create_reg(self) - if dstop != op1: # else op1 was spilled just now, so its value - # is still in place in its old register - allocator.mc.MOV(dstop, op1) # make a copy in the new register - op2 = allocator.get_operand(y) + dstop = allocator.create_reg(self, op1) + op2 = allocator.get_operand(y) allocator.release(y) self.emit(allocator.mc, dstop, op2) @@ -256,14 +242,11 @@ def generate(self, allocator): # XXX not very efficient but not very common operations either - oldop1 = allocator.get_operand(self.x) - #oldop2 = allocator.get_operand(self.y) allocator.clobber2(eax, edx) - op1 = allocator.get_operand(self.x) - mc = allocator.mc - if oldop1 != eax: + op1 = allocator.get_operand(self.x) + if op1 != eax: mc.MOV(eax, op1) if self.input_is_64bits: if self.unsigned: @@ -271,7 +254,8 @@ else: mc.CDQ() - self.generate2(allocator) + op2 = allocator.grab_operand(self.y) + self.generate2(allocator, op2) allocator.end_clobber(eax) allocator.end_clobber(edx) @@ -286,7 +270,7 @@ reg_containing_result = eax unsigned = False - def generate2(self, allocator): + def generate2(self, allocator, op2): # from the PPC backend which has the same problem: # # grumble, the powerpc handles division when the signs of x @@ -307,7 +291,6 @@ # (-20)/(-3) = 6,-2 6,-2 # tmp = allocator.create_scratch_reg() - op2 = allocator.get_operand(self.y) mc = allocator.mc if isinstance(op2, IMM32): # if op2 is an immediate, we do an initial adjustment of operand 1 @@ -345,7 +328,7 @@ reg_containing_result = edx unsigned = False - def generate2(self, allocator): + def generate2(self, allocator, op2): # Python i386 # 20/3 = 6, 2 6, 2 # (-20)/3 = -7, 1 -6,-2 # operand signs differ @@ -353,7 +336,6 @@ # (-20)/(-3) = 6,-2 6,-2 # tmp = allocator.create_scratch_reg() - op2 = allocator.get_operand(self.y) mc = allocator.mc if isinstance(op2, IMM32): mc.MOV(tmp, op2) @@ -384,8 +366,7 @@ input_is_64bits = False reg_containing_result = eax unsigned = True - def generate2(self, allocator): - op2 = allocator.get_operand(self.y) + def generate2(self, allocator, op2): allocator.mc.MUL(op2) class OpUIntFloorDiv(MulOrDivOp): @@ -393,8 +374,7 @@ input_is_64bits = True reg_containing_result = eax unsigned = True - def generate2(self, allocator): - op2 = allocator.get_operand(self.y) + def generate2(self, allocator, op2): allocator.mc.DIV(op2) class OpUIntMod(MulOrDivOp): @@ -402,8 +382,7 @@ input_is_64bits = True reg_containing_result = edx unsigned = True - def generate2(self, allocator): - op2 = allocator.get_operand(self.y) + def generate2(self, allocator, op2): allocator.mc.DIV(op2) class OpShift(Op2): @@ -413,12 +392,12 @@ def mark_used_vars(self, allocator): allocator.using_inplace(self.x, self) allocator.using(self.y) - # XXX this would be nice - #if not self.countmax31: - # allocator.suggests(self.y, ecx) + if not self.countmax31: + allocator.suggests(self.y, ecx) def generate(self, allocator): - op2 = allocator.get_operand(self.y) + op2 = allocator.grab_operand(self.y) + holds_ecx = False mc = allocator.mc if isinstance(op2, IMM32): n = op2.value @@ -435,32 +414,38 @@ return count = imm8(n) else: - allocator.clobber(ecx) - op2 = allocator.get_operand(self.y) if self.countmax31: + allocator.clobber(ecx) + holds_ecx = True mc.MOV(ecx, imm8(31)) mc.CMP(op2, ecx) mc.CMOVBE(ecx, op2) - else: + allocator.release(self.y) + elif op2 != ecx: + allocator.clobber(ecx) + holds_ecx = True mc.MOV(ecx, op2) - allocator.release(self.y) + allocator.release(self.y) count = cl + srcop = allocator.get_operand(self.x) if allocator.release(self.x): - dstop = allocator.get_operand(self.x) # in-place operation + dstop = srcop # in-place operation allocator.create_exactly_at(self, dstop) else: - dstop = allocator.create_reg(self) - srcop = allocator.get_operand(self.x) - mc.MOV(dstop, srcop) # make a copy in a new register + # make a copy in a new register + dstop = allocator.create_reg(self, srcop) self.emit(mc, dstop, count) - if count == cl: + if count is cl: if not self.countmax31: mc.CMP(ecx, imm8(32)) mc.SBB(ecx, ecx) mc.AND(dstop, ecx) - allocator.end_clobber(ecx) + if holds_ecx: + allocator.end_clobber(ecx) + else: + allocator.release(self.y) class OpIntLShift(OpShift): opname = 'int_lshift', 'uint_lshift' @@ -492,6 +477,7 @@ except FailedToImplement: # CMP(stack, stack) reg = allocator.create_scratch_reg(op1) + op2 = allocator.get_operand(self.y) mc.CMP(reg, op2) allocator.end_clobber(reg) else: @@ -738,7 +724,7 @@ def generate(self, allocator): tmpval = None width = self.getwidth() - opvalue = allocator.get_operand(self.gv_value) + opvalue = allocator.grab_operand(self.gv_value) if width == 1: try: opvalue = opvalue.lowest8bits() @@ -843,9 +829,7 @@ if isinstance(op, REG): self.reg = op else: - self.reg = allocator.create_scratch_reg() - op = allocator.get_operand(self.x) - allocator.mc.MOV(self.reg, op) + self.reg = allocator.create_scratch_reg(op) allocator.end_clobber(self.reg) allocator.release(self.x) Modified: pypy/branch/new-jit-codegen/i386/regalloc.py ============================================================================== --- pypy/branch/new-jit-codegen/i386/regalloc.py (original) +++ pypy/branch/new-jit-codegen/i386/regalloc.py Wed Feb 7 19:05:40 2007 @@ -178,6 +178,7 @@ # Generate all operations. # Actual registers or stack locations are allocated as we go. for i in range(len(self.operations)): + self.registers_pinned = 0 # bitmask op = self.operations[i] if op.clobbers_cc: self.clobber_cc() @@ -243,6 +244,14 @@ else: return self.var2loc[v] + def grab_operand(self, v): + """Like get_operand() but if the result is in a register, it won't + be spilled before the end of the current instruction.""" + loc = self.get_operand(v) + if isinstance(loc, REG): + self.registers_pinned |= loc.bitmask + return loc + def _use_next_modrm(self, v, regnum_must_be_before=8): """Select the next mod/rm location to use for the new operation 'v'. If 'v' is None, this will always return a register; else it might @@ -270,6 +279,8 @@ continue if loc.op >= regnum_must_be_before: continue # never reached if regnum_must_be_before == 8 + if loc.bitmask & self.registers_pinned: + continue # don't spill this register regloc = loc dyinglimit = dying spillvar = v1 @@ -303,6 +314,8 @@ self.vars_in_use[v] = ltime = self.lifetime[v] assert ltime > self.operationindex self.var2loc[v] = loc + if isinstance(loc, REG): + self.registers_pinned |= loc.bitmask def release(self, v): """Stop using argument 'v'. Must be called for each used argument.""" @@ -334,16 +347,20 @@ self._created(v, loc) return loc - def create_reg(self, v): + def create_reg(self, v, srcloc=None): """Create the result of the operation 'v' in any register currently available. CAN SPILL ONE REGISTER.""" suggested_loc = self.suggested_location.get(v, None) - if isinstance(suggested_loc, REG): - if self.consume_loc(v, suggested_loc): - self._created(v, suggested_loc) - return suggested_loc - loc = self._use_next_reg() + if (isinstance(suggested_loc, REG) and + self.consume_loc(v, suggested_loc)): + loc = suggested_loc + else: + loc = self._use_next_reg() self._created(v, loc) + if srcloc is not None and loc is not srcloc: + # if srcop was spilled, srcloc still contains its value right now + # and then it's possible that srcop == dstop (no MOV needed then) + self.mc.MOV(loc, srcloc) return loc def create_exactly_at(self, v, loc): @@ -537,11 +554,39 @@ pass dead_operation = DeadOperation() forget_stack_storage = DeadOperation() +gv_frame_base = GenVar() -class StorageInStack(Op1): +class Place(Operation): """Place of a variable that must live in the stack. Its position is choosen by the register allocator and put in the 'offset' attribute.""" + def __init__(self, x): + self.x = x + def mark_used_vars(self, allocator): + if self.x is not None: + allocator.using(self.x) + def get_offset(self): + return self.offset + def generate(self, allocator): + assert allocator.operation_result_is_used(self), "place not absorbed!" + loc = allocator._use_another_stack_loc() + allocator._created(self, loc) + if self.x is not None: + srcop = allocator.get_operand(self.x) + allocator.mc.MOV(loc, srcop) + allocator.release(self.x) + self.x = None # hack to avoid that the Place keeps a lot of + # memory around + self.offset = loc.ofs_relative_to_ebp() +class OpAbsorbPlace(Op1): + clobbers_cc = False + def generate(self, allocator): + allocator.release(self.x) + if allocator.operation_result_is_used(self): + loc = allocator.get_operand(self.x) + allocator.create_exactly_at(self, loc) + +class StorageInStack(Place): def generate(self, allocator): # patch the lifetime of the variable if needed (XXX a bit slow) x = self.x @@ -561,10 +606,3 @@ allocator._mark_loc_as_free(oldop) # record its location self.offset = srcop.ofs_relative_to_ebp() - # for places, self.x would keep lots of other Operations alive - self.x = None - - def get_offset(self): - return self.offset - -gv_frame_base = GenVar() Modified: pypy/branch/new-jit-codegen/i386/rgenop.py ============================================================================== --- pypy/branch/new-jit-codegen/i386/rgenop.py (original) +++ pypy/branch/new-jit-codegen/i386/rgenop.py Wed Feb 7 19:05:40 2007 @@ -9,6 +9,7 @@ from pypy.jit.codegen.i386.regalloc import RegAllocator from pypy.jit.codegen.i386.regalloc import DEBUG_STACK, forget_stack_storage from pypy.jit.codegen.i386.regalloc import gv_frame_base, StorageInStack +from pypy.jit.codegen.i386.regalloc import Place, OpAbsorbPlace from pypy.jit.codegen.i386.regalloc import write_stack_reserve, write_stack_adj from pypy.jit.codegen import conftest from pypy.rpython.annlowlevel import llhelper @@ -486,24 +487,21 @@ result = [] for v in vars_gv: if not v.is_const: - place = StorageInStack(v) - self.operations.append(place) - v = place + sis = StorageInStack(v) + self.operations.append(sis) + v = sis result.append(v) return result def alloc_frame_place(self, kind, gv_initial_value=None): - if gv_initial_value is None: - v = OpWhatever() - else: - v = OpSameAs(gv_initial_value) - self.operations.append(v) - place = StorageInStack(v) + place = Place(gv_initial_value) self.operations.append(place) return place def genop_absorb_place(self, kind, place): - return place.x + v = OpAbsorbPlace(place) + self.operations.append(v) + return v class Label(GenLabel): From arigo at codespeak.net Wed Feb 7 19:06:08 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 7 Feb 2007 19:06:08 +0100 (CET) Subject: [pypy-svn] r38086 - pypy/branch/new-jit-codegen/test Message-ID: <20070207180608.E16BF10087@code0.codespeak.net> Author: arigo Date: Wed Feb 7 19:06:07 2007 New Revision: 38086 Modified: pypy/branch/new-jit-codegen/test/rgenop_tests.py Log: Forgot this with previous check-in. Modified: pypy/branch/new-jit-codegen/test/rgenop_tests.py ============================================================================== --- pypy/branch/new-jit-codegen/test/rgenop_tests.py (original) +++ pypy/branch/new-jit-codegen/test/rgenop_tests.py Wed Feb 7 19:06:07 2007 @@ -739,6 +739,7 @@ gv_base = builder.genop_get_frame_base() gv_reader = rgenop.constPrebuiltGlobal(get_reader(place)) gv_z = builder.genop_call(readertoken, gv_reader, [gv_base]) + builder.genop_absorb_place(signed_kind, place) # mark end of use builder.finish_and_return(sigtoken, gv_z) builder.end() From pedronis at codespeak.net Wed Feb 7 19:27:31 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Wed, 7 Feb 2007 19:27:31 +0100 (CET) Subject: [pypy-svn] r38093 - pypy/branch/jit-virtual-world/pypy/jit/timeshifter Message-ID: <20070207182731.E4C5B10086@code0.codespeak.net> Author: pedronis Date: Wed Feb 7 19:27:28 2007 New Revision: 38093 Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/rcontainer.py pypy/branch/jit-virtual-world/pypy/jit/timeshifter/rtimeshift.py Log: make the virtualizables code use the place interface as intended, absorb is value copy operation. Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/rcontainer.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/timeshifter/rcontainer.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/timeshifter/rcontainer.py Wed Feb 7 19:27:28 2007 @@ -605,8 +605,9 @@ builder = jitstate.curbuilder place = builder.alloc_frame_place(typedesc.ptrkind) - gv_forced = builder.genop_absorb_place(typedesc.ptrkind, place) vrti.forced_place = place + forced_box = rvalue.PtrRedBox(typedesc.ptrkind) + memo.forced_boxes.append((forced_box, place)) vars_gv = memo.framevars_gv varindexes = vrti.varindexes @@ -625,9 +626,8 @@ vrtis.append(content.make_rti(jitstate, memo)) j -= 1 - self.content_boxes.append(rvalue.PtrRedBox(typedesc.ptrkind, - gv_forced)) - + + self.content_boxes.append(forced_box) return vrti def reshape(self, jitstate, shapemask, memo): Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/rtimeshift.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/timeshifter/rtimeshift.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/timeshifter/rtimeshift.py Wed Feb 7 19:27:28 2007 @@ -933,6 +933,7 @@ next virtualizables shape_place + forced_boxes generated_oop_residual_can_raise """.split() @@ -1009,9 +1010,12 @@ memo.bitcount = 1 memo.frameindex = 0 memo.framevars_gv = [] + memo.forced_boxes = forced_boxes = [] + shape_kind = builder.rgenop.kindToken(lltype.Signed) gv_zero = builder.rgenop.genconst(0) self.shape_place = builder.alloc_frame_place(shape_kind, gv_zero) + self.forced_boxes = forced_boxes vable_rtis = [] for virtualizable_box in virtualizables: @@ -1041,9 +1045,16 @@ assert isinstance(content, rcontainer.VirtualizableStruct) content.check_forced_after_residual_call(self) shape_kind = builder.rgenop.kindToken(lltype.Signed) + + for forced_box, forced_place in self.forced_boxes: + gv_forced = builder.genop_absorb_place(forced_box.kind, forced_place) + forced_box.setgenvar(gv_forced) + self.forced_boxes = None + gv_shape = builder.genop_absorb_place(shape_kind, self.shape_place) self.shape_place = None + return gv_shape else: return None From arigo at codespeak.net Wed Feb 7 19:27:45 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 7 Feb 2007 19:27:45 +0100 (CET) Subject: [pypy-svn] r38094 - pypy/branch/new-jit-codegen/i386 Message-ID: <20070207182745.C1EA910090@code0.codespeak.net> Author: arigo Date: Wed Feb 7 19:27:37 2007 New Revision: 38094 Modified: pypy/branch/new-jit-codegen/i386/operation.py pypy/branch/new-jit-codegen/i386/regalloc.py Log: fixes fixes fixes. Modified: pypy/branch/new-jit-codegen/i386/operation.py ============================================================================== --- pypy/branch/new-jit-codegen/i386/operation.py (original) +++ pypy/branch/new-jit-codegen/i386/operation.py Wed Feb 7 19:27:37 2007 @@ -95,7 +95,10 @@ # so we can reuse it for us allocator.create_in_cc(self, srcop) else: - dstop = allocator.create(self) + if isinstance(srcop, MODRM): + dstop = allocator.create_reg(self) # no stack->stack copy + else: + dstop = allocator.create(self) if srcop != dstop: # else srcop spilled, but still in place allocator.mc.MOV(dstop, srcop) allocator.release(self.x) @@ -396,7 +399,7 @@ allocator.suggests(self.y, ecx) def generate(self, allocator): - op2 = allocator.grab_operand(self.y) + op2 = allocator.get_operand(self.y) holds_ecx = False mc = allocator.mc if isinstance(op2, IMM32): @@ -417,6 +420,7 @@ if self.countmax31: allocator.clobber(ecx) holds_ecx = True + op2 = allocator.get_operand(self.y) mc.MOV(ecx, imm8(31)) mc.CMP(op2, ecx) mc.CMOVBE(ecx, op2) @@ -424,8 +428,12 @@ elif op2 != ecx: allocator.clobber(ecx) holds_ecx = True + op2 = allocator.get_operand(self.y) mc.MOV(ecx, op2) allocator.release(self.y) + else: + op2 = allocator.grab_operand(self.y) + assert op2 == ecx count = cl srcop = allocator.get_operand(self.x) Modified: pypy/branch/new-jit-codegen/i386/regalloc.py ============================================================================== --- pypy/branch/new-jit-codegen/i386/regalloc.py (original) +++ pypy/branch/new-jit-codegen/i386/regalloc.py Wed Feb 7 19:27:37 2007 @@ -114,24 +114,16 @@ self.inputlocations = inputlocations def force_loc_used(self, v, loc): - if isinstance(loc, MODRM): - assert loc not in self.stack_op_used - self.stack_op_used[loc] = None - n = stack_n_from_op(loc) - if n >= self.nstackmax: - self.nstackmax = n + 1 - elif isinstance(loc, REG): - assert self.registers_free & loc.bitmask - self.registers_free &= ~loc.bitmask - elif isinstance(loc, CCFLAG): - self.cc_used_by = v - else: - raise AssertionError(loc) + ok = self.consume_loc(v, loc) + assert ok def consume_loc(self, v, loc): if isinstance(loc, MODRM): if loc not in self.stack_op_used: self.stack_op_used[loc] = None + n = stack_n_from_op(loc) + if n >= self.nstackmax: + self.nstackmax = n + 1 return True elif isinstance(loc, REG): if self.registers_free & loc.bitmask: @@ -404,6 +396,7 @@ You must eventually call end_clobber().""" assert isinstance(reg, REG) if not self.registers_free & reg.bitmask: + assert not (reg.bitmask & self.registers_pinned) for v1 in self.vars_in_use: if self.var2loc[v1] == reg: self._move_away(v1) From cfbolz at codespeak.net Wed Feb 7 23:29:34 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 7 Feb 2007 23:29:34 +0100 (CET) Subject: [pypy-svn] r38126 - pypy/dist/pypy Message-ID: <20070207222934.68B941007F@code0.codespeak.net> Author: cfbolz Date: Wed Feb 7 23:29:30 2007 New Revision: 38126 Modified: pypy/dist/pypy/conftest.py Log: add space.newlist op (to give parsing test a chance to pass). Modified: pypy/dist/pypy/conftest.py ============================================================================== --- pypy/dist/pypy/conftest.py (original) +++ pypy/dist/pypy/conftest.py Wed Feb 7 23:29:30 2007 @@ -93,6 +93,9 @@ def is_true(self, obj): return bool(obj) + def newlist(self): + return {} + class OpErrKeyboardInterrupt(KeyboardInterrupt): pass From arigo at codespeak.net Thu Feb 8 00:18:59 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 8 Feb 2007 00:18:59 +0100 (CET) Subject: [pypy-svn] r38127 - pypy/branch/jit-virtual-world/pypy/jit/timeshifter Message-ID: <20070207231859.893631007B@code0.codespeak.net> Author: arigo Date: Thu Feb 8 00:18:54 2007 New Revision: 38127 Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/hrtyper.py pypy/branch/jit-virtual-world/pypy/jit/timeshifter/rtimeshift.py Log: Reduce the amount of rtimeshift.py code that is duplicated by specialization. Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/hrtyper.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/timeshifter/hrtyper.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/timeshifter/hrtyper.py Thu Feb 8 00:18:54 2007 @@ -1139,6 +1139,8 @@ greens_v.append(v_green) greens_s.append(s_erased_type) + # YYY possibly reorder the variables to avoid too many + # specialized versions of retrieve_jitstate_for_merge v_jitstate = hop.llops.getjitstate() return hop.llops.genmixlevelhelpercall(merge_point, @@ -1369,15 +1371,11 @@ c_calldesc = inputconst(lltype.Void, calldesc) s_calldesc = self.rtyper.annotator.bookkeeper.immutablevalue(calldesc) v_jitstate = hop.llops.getjitstate() - if color == 'red': - s_result = self.s_RedBox - else: - s_result = annmodel.s_None v_res = hop.llops.genmixlevelhelpercall( rtimeshift.ll_gen_residual_call, [self.s_JITState, s_calldesc, self.s_RedBox], [v_jitstate, c_calldesc, v_funcbox ], - s_result) + self.s_RedBox) return v_res def translate_op_residual_gray_call(self, hop): Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/rtimeshift.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/timeshifter/rtimeshift.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/timeshifter/rtimeshift.py Thu Feb 8 00:18:54 2007 @@ -96,6 +96,10 @@ return opdesc.redboxcls(opdesc.result_kind, genvar) def ll_genmalloc_varsize(jitstate, contdesc, sizebox): + # the specialized by contdesc is not useful, unify paths + return genmalloc_varsize(jitstate, contdesc, sizebox) + +def genmalloc_varsize(jitstate, contdesc, sizebox): gv_size = sizebox.getgenvar(jitstate) alloctoken = contdesc.varsizealloctoken genvar = jitstate.curbuilder.genop_malloc_varsize(alloctoken, gv_size) @@ -326,22 +330,8 @@ if exitgvar.is_const: return exitgvar.revealconst(lltype.Bool) else: - # XXX call another function with list(greens_gv) instead - resuming = jitstate.get_resuming() - if resuming is not None and resuming.mergesleft == 0: - node = resuming.path.pop() - assert isinstance(node, PromotionPathSplit) - return node.answer - false_gv = jitstate.get_locals_gv() # alive gvs on the false path - later_builder = jitstate.curbuilder.jump_if_false(exitgvar, false_gv) - memo = rvalue.copy_memo() - jitstate2 = jitstate.split(later_builder, resumepoint, - list(greens_gv), memo) - if resuming is None: - node = jitstate.promotion_path - jitstate2.promotion_path = PromotionPathNo(node) - jitstate .promotion_path = PromotionPathYes(node) - return True + return split_nonconstantcase(jitstate, exitgvar, resumepoint, + None, False, list(greens_gv)) def split_ptr_nonzero(jitstate, switchredbox, resumepoint, ptrbox, reverse, *greens_gv): @@ -349,19 +339,24 @@ if exitgvar.is_const: return exitgvar.revealconst(lltype.Bool) else: - # XXX call another function with list(greens_gv) instead - resuming = jitstate.get_resuming() - if resuming is not None and resuming.mergesleft == 0: - node = resuming.path.pop() - assert isinstance(node, PromotionPathSplit) + return split_nonconstantcase(jitstate, exitgvar, resumepoint, + ptrbox, reverse, list(greens_gv)) + +def split_nonconstantcase(jitstate, exitgvar, resumepoint, + ptrbox, reverse, greens_gv): + resuming = jitstate.get_resuming() + if resuming is not None and resuming.mergesleft == 0: + node = resuming.path.pop() + assert isinstance(node, PromotionPathSplit) + if ptrbox is not None: ptrbox.learn_nonzeroness(jitstate, nonzeroness = node.answer ^ reverse) - return node.answer - false_gv = jitstate.get_locals_gv() # alive gvs on the false path - later_builder = jitstate.curbuilder.jump_if_false(exitgvar, false_gv) - memo = rvalue.copy_memo() - jitstate2 = jitstate.split(later_builder, resumepoint, - list(greens_gv), memo) + return node.answer + false_gv = jitstate.get_locals_gv() # alive gvs on the false path + later_builder = jitstate.curbuilder.jump_if_false(exitgvar, false_gv) + memo = rvalue.copy_memo() + jitstate2 = jitstate.split(later_builder, resumepoint, greens_gv, memo) + if ptrbox is not None: ptrbox.learn_nonzeroness(jitstate, nonzeroness = True ^ reverse) try: copybox = memo.boxes[ptrbox] @@ -369,13 +364,14 @@ pass else: copybox.learn_nonzeroness(jitstate2, nonzeroness = reverse) - if resuming is None: - node = jitstate.promotion_path - jitstate2.promotion_path = PromotionPathNo(node) - jitstate .promotion_path = PromotionPathYes(node) - return True + if resuming is None: + node = jitstate.promotion_path + jitstate2.promotion_path = PromotionPathNo(node) + jitstate .promotion_path = PromotionPathYes(node) + return True def collect_split(jitstate_chain, resumepoint, *greens_gv): + # YYY split to avoid over-specialization # assumes that the head of the jitstate_chain is ready for writing, # and all the other jitstates in the chain are paused greens_gv = list(greens_gv) @@ -509,6 +505,10 @@ return True def ll_gen_residual_call(jitstate, calldesc, funcbox): + # specialization is not useful here, we can unify the calldescs + return gen_residual_call(jitstate, calldesc, funcbox) + +def gen_residual_call(jitstate, calldesc, funcbox): builder = jitstate.curbuilder gv_funcbox = funcbox.getgenvar(jitstate) argboxes = jitstate.frame.local_boxes @@ -668,7 +668,7 @@ class PromotionDesc: - __metatype__ = cachedtype + __metaclass__ = cachedtype def __init__(self, ERASED, hrtyper): state = hrtyper.portalstate @@ -702,6 +702,10 @@ return True def ll_promote(jitstate, promotebox, promotiondesc): + # the specialization by promotiondesc is not useful here, so unify paths + return promote(jitstate, promotebox, promotiondesc) + +def promote(jitstate, promotebox, promotiondesc): builder = jitstate.curbuilder gv_switchvar = promotebox.getgenvar(jitstate) if gv_switchvar.is_const: From arigo at codespeak.net Thu Feb 8 00:19:26 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 8 Feb 2007 00:19:26 +0100 (CET) Subject: [pypy-svn] r38128 - pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test Message-ID: <20070207231926.98B8710082@code0.codespeak.net> Author: arigo Date: Thu Feb 8 00:19:21 2007 New Revision: 38128 Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_virtualizable.py Log: A test mainly to stare at the 386 assembler generated and check if it is reasonable. Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_virtualizable.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_virtualizable.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_virtualizable.py Thu Feb 8 00:19:21 2007 @@ -419,6 +419,27 @@ assert res == 42 self.check_insns(getfield=0, malloc=2) + def test_residual_doing_nothing(self): + def g(xy): + pass + + def f(xy): + hint(None, global_merge_point=True) + g(xy) + return xy.x + 1 + + def main(x, y): + xy = lltype.malloc(XY) + xy.vable_access = lltype.nullptr(XY_ACCESS) + xy.x = x + xy.y = y + v = f(xy) + return v + + res = self.timeshift_from_portal(main, f, [2, 20], + policy=StopAtXPolicy(g)) + assert res == 3 + def test_late_residual_red_call(self): def g(e): xy = e.xy From arigo at codespeak.net Thu Feb 8 00:20:17 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 8 Feb 2007 00:20:17 +0100 (CET) Subject: [pypy-svn] r38129 - pypy/branch/jit-virtual-world/pypy/jit/timeshifter Message-ID: <20070207232017.0BA431007B@code0.codespeak.net> Author: arigo Date: Thu Feb 8 00:20:16 2007 New Revision: 38129 Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/rcontainer.py pypy/branch/jit-virtual-world/pypy/jit/timeshifter/vlist.py Log: (pedronis, arigo) Forgot this file when making the places uninitialized and when moving the absorbs to where they belong. Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/rcontainer.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/timeshifter/rcontainer.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/timeshifter/rcontainer.py Thu Feb 8 00:20:16 2007 @@ -626,7 +626,6 @@ vrtis.append(content.make_rti(jitstate, memo)) j -= 1 - self.content_boxes.append(forced_box) return vrti Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/vlist.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/timeshifter/vlist.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/timeshifter/vlist.py Thu Feb 8 00:20:16 2007 @@ -221,10 +221,10 @@ memo.containers[self] = vrti builder = jitstate.curbuilder - place = builder.alloc_frame_place(typedesc.ptrkind, - typedesc.gv_null) - gv_forced = builder.genop_absorb_place(typedesc.ptrkind, place) + place = builder.alloc_frame_place(typedesc.ptrkind) vrti.forced_place = place + forced_box = rvalue.PtrRedBox(typedesc.ptrkind) + memo.forced_boxes.append((forced_box, place)) vars_gv = memo.framevars_gv varindexes = vrti.varindexes @@ -243,9 +243,7 @@ vrtis.append(content.make_rti(jitstate, memo)) j -= 1 - self.item_boxes.append(rvalue.PtrRedBox(typedesc.ptrkind, - gv_forced)) - + self.item_boxes.append(forced_box) return vrti def reshape(self, jitstate, shapemask, memo): From arigo at codespeak.net Thu Feb 8 00:22:09 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 8 Feb 2007 00:22:09 +0100 (CET) Subject: [pypy-svn] r38130 - in pypy/branch/new-jit-codegen: i386 test Message-ID: <20070207232209.1FD981007B@code0.codespeak.net> Author: arigo Date: Thu Feb 8 00:21:58 2007 New Revision: 38130 Modified: pypy/branch/new-jit-codegen/i386/regalloc.py pypy/branch/new-jit-codegen/i386/rgenop.py pypy/branch/new-jit-codegen/i386/ri386.py pypy/branch/new-jit-codegen/test/rgenop_tests.py Log: Fix the logic about places, yet again. Fix a stupid bug causing a jitted function to consume more and more stack space if it loops and contains a flexswitch. Now this backend seems to be up to running pypy-jits :-) Modified: pypy/branch/new-jit-codegen/i386/regalloc.py ============================================================================== --- pypy/branch/new-jit-codegen/i386/regalloc.py (original) +++ pypy/branch/new-jit-codegen/i386/regalloc.py Thu Feb 8 00:21:58 2007 @@ -30,14 +30,13 @@ def write_stack_reserve(mc, stackn): addr = mc.tell() - offset = WORD * ((StackOpCache.INITIAL_STACK_EBP_OFS+1) - stackn) - mc.ADD(esp, IMM32(offset)) # always encode offset on 32 bits + mc.SUB(esp, IMM32(WORD * stackn)) # always encode offset on 32 bits return addr def write_stack_adj(mc, stackn): addr = mc.tell() - offset = WORD * ((StackOpCache.INITIAL_STACK_EBP_OFS+1) - stackn) - mc.LEA(esp, fixedsize_esp_ofs(offset)) + # always encode offset on 32 bits + mc.LEA(esp, fixedsize_ebp_ofs(-WORD * stackn)) return addr @@ -546,7 +545,6 @@ def generate(self, allocator): pass dead_operation = DeadOperation() -forget_stack_storage = DeadOperation() gv_frame_base = GenVar() class Place(Operation): @@ -581,21 +579,24 @@ class StorageInStack(Place): def generate(self, allocator): - # patch the lifetime of the variable if needed (XXX a bit slow) - x = self.x - i = allocator.lifetime.get(x, allocator.operationindex) - operations = allocator.operations - while i < len(operations): - if operations[i] is forget_stack_storage: - break - i += 1 - allocator.lifetime[x] = i - allocator.vars_in_use[x] = i - # force it to be in the stack - srcop = allocator.get_operand(x) + # force the variable to be in the stack + srcop = allocator.get_operand(self.x) if not isinstance(srcop, MODRM): oldop = srcop - srcop = allocator._spill(x, srcop) + srcop = allocator._spill(self.x, srcop) allocator._mark_loc_as_free(oldop) # record its location self.offset = srcop.ofs_relative_to_ebp() + # hack to avoid this instance keeping a lot of memory around + self.x = None + +class OpTouch(Operation): + side_effects = True # don't remove me! + def __init__(self, args_gv): + self.args_gv = args_gv + def mark_used_vars(self, allocator): + for v in self.args_gv: + allocator.using(v) + def generate(self, allocator): + for v in self.args_gv: + allocator.release(v) Modified: pypy/branch/new-jit-codegen/i386/rgenop.py ============================================================================== --- pypy/branch/new-jit-codegen/i386/rgenop.py (original) +++ pypy/branch/new-jit-codegen/i386/rgenop.py Thu Feb 8 00:21:58 2007 @@ -6,10 +6,9 @@ from pypy.jit.codegen.model import ReplayBuilder, dummy_var from pypy.jit.codegen.i386.codebuf import CodeBlockOverflow from pypy.jit.codegen.i386.operation import * -from pypy.jit.codegen.i386.regalloc import RegAllocator -from pypy.jit.codegen.i386.regalloc import DEBUG_STACK, forget_stack_storage +from pypy.jit.codegen.i386.regalloc import RegAllocator, DEBUG_STACK from pypy.jit.codegen.i386.regalloc import gv_frame_base, StorageInStack -from pypy.jit.codegen.i386.regalloc import Place, OpAbsorbPlace +from pypy.jit.codegen.i386.regalloc import Place, OpAbsorbPlace, OpTouch from pypy.jit.codegen.i386.regalloc import write_stack_reserve, write_stack_adj from pypy.jit.codegen import conftest from pypy.rpython.annlowlevel import llhelper @@ -213,6 +212,7 @@ update_defaultcaseaddr_of = None paused_alive_gv = None order_dependency = None + keepalives_gv = None def __init__(self, rgenop, graphctx, inputargs_gv, inputoperands): self.rgenop = rgenop @@ -226,6 +226,7 @@ def generate_block_code(self, final_vars_gv, final_operands=None, renaming=True): + self.insert_keepalives() if self.order_dependency is not None: self.order_dependency.force_generate_code() self.order_dependency = None @@ -251,9 +252,14 @@ self.inputoperands = [allocator.get_operand(v) for v in final_vars_gv] return mc + def insert_keepalives(self): + if self.keepalives_gv is not None: + self.operations.append(OpTouch(self.keepalives_gv)) + self.keepalives_gv = None + def enter_next_block(self, kinds, args_gv): # we get better register allocation if we write a single large mc block - self.operations.append(forget_stack_storage) + self.insert_keepalives() for i in range(len(args_gv)): op = OpSameAs(args_gv[i]) args_gv[i] = op @@ -487,6 +493,9 @@ result = [] for v in vars_gv: if not v.is_const: + if self.keepalives_gv is None: + self.keepalives_gv = [] + self.keepalives_gv.append(v) sis = StorageInStack(v) self.operations.append(sis) v = sis Modified: pypy/branch/new-jit-codegen/i386/ri386.py ============================================================================== --- pypy/branch/new-jit-codegen/i386/ri386.py (original) +++ pypy/branch/new-jit-codegen/i386/ri386.py Thu Feb 8 00:21:58 2007 @@ -271,9 +271,8 @@ else: return cls(0x84, SIB + packimm32(offset)) -def fixedsize_esp_ofs(offset): - SIB = '\x24' - return MODRM(0x84, SIB + packimm32(offset)) +def fixedsize_ebp_ofs(offset): + return MODRM(0x80 | EBP.op, packimm32(offset)) def single_byte(value): return -128 <= value < 128 Modified: pypy/branch/new-jit-codegen/test/rgenop_tests.py ============================================================================== --- pypy/branch/new-jit-codegen/test/rgenop_tests.py (original) +++ pypy/branch/new-jit-codegen/test/rgenop_tests.py Thu Feb 8 00:21:58 2007 @@ -1354,6 +1354,38 @@ res = fn(-1) assert res == 42 + def test_frame_vars_like_the_frontend_direct(self): + rgenop = self.RGenOp() + sigtoken = rgenop.sigToken(FUNC3) + signed_kind = rgenop.kindToken(lltype.Signed) + # ------------------------------------------ + builder0, gv_callable, [v0, v1, v2] = rgenop.newgraph(sigtoken, + 'fvltf') + builder0.start_writing() + builder1 = builder0.pause_writing([v1, v0, v2]) + builder1.start_writing() + args_gv = [v1, v0, v2] + label0 = builder1.enter_next_block([signed_kind]*3, args_gv) + [v3, v4, v5] = args_gv + place = builder1.alloc_frame_place(signed_kind, rgenop.genconst(0)) + v6 = builder1.genop_get_frame_base() + c_seven = rgenop.genconst(7) + frameinfo = builder1.get_frame_info([v3, v4, c_seven, v5]) + # here would be a call + v8 = builder1.genop_absorb_place(signed_kind, place) + args_gv = [v3, v4, v5, v8] + label1 = builder1.enter_next_block([signed_kind]*4, args_gv) + [v9, v10, v11, v12] = args_gv + flexswitch0, builder2 = builder1.flexswitch(v12, [v9, v10, v12]) + v13 = builder2.genop2("int_add", v9, v10) + v14 = builder2.genop2("int_add", v13, v12) + builder2.finish_and_return(sigtoken, v14) + builder0.end() + + fnptr = self.cast(gv_callable, 3) + res = fnptr(40, 2, 8168126) + assert res == 42 + def test_unaliasing_variables_direct(self): # def f(x, y): # if x: From fijal at codespeak.net Thu Feb 8 02:46:25 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 8 Feb 2007 02:46:25 +0100 (CET) Subject: [pypy-svn] r38133 - pypy/dist/pypy/doc Message-ID: <20070208014625.2641D10083@code0.codespeak.net> Author: fijal Date: Thu Feb 8 02:46:23 2007 New Revision: 38133 Modified: pypy/dist/pypy/doc/index.txt Log: Update links (windows tests are returning 404, while I've revived pypy-c ones) Modified: pypy/dist/pypy/doc/index.txt ============================================================================== --- pypy/dist/pypy/doc/index.txt (original) +++ pypy/dist/pypy/doc/index.txt Thu Feb 8 02:46:23 2007 @@ -121,8 +121,8 @@ an attempt to keep some focus. So PyPy requires a 32-bit machine or OS for now. -PyPy's own tests, daily updated, `on Linux`_ and `on Windows`_ and -on build pypy-c (not available at the moment). +PyPy's own tests, daily updated, `on Linux`_, on Windows (unavailable +at the moment) and `on built pypy-c`_. `Nightly builds and benchmarks`_ of PyPy to C, CLI and LLVM. @@ -156,7 +156,7 @@ .. _`EU reports`: index-report.html .. _`garbage collection`: garbage_collection.html .. _`on Linux`: http://wyvern.cs.uni-duesseldorf.de/pypytest/summary.html -.. _`on Windows`: http://scottdial.com/pypytest/summary.html +.. _`on built pypy-c`: http://wyvern.cs.uni-duesseldorf.de/~fijal/pypy-c-tests/ .. _`ideas for PyPy related projects`: project-ideas.html .. _`Nightly builds and benchmarks`: http://tuatara.cs.uni-duesseldorf.de/benchmark.html .. _`directory reference`: From cfbolz at codespeak.net Thu Feb 8 09:48:29 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 8 Feb 2007 09:48:29 +0100 (CET) Subject: [pypy-svn] r38134 - pypy/dist/pypy Message-ID: <20070208084829.35DFA1008B@code0.codespeak.net> Author: cfbolz Date: Thu Feb 8 09:48:27 2007 New Revision: 38134 Modified: pypy/dist/pypy/conftest.py Log: hm, actually I wanted newdict here. don't check things in when tired. Modified: pypy/dist/pypy/conftest.py ============================================================================== --- pypy/dist/pypy/conftest.py (original) +++ pypy/dist/pypy/conftest.py Thu Feb 8 09:48:27 2007 @@ -93,7 +93,7 @@ def is_true(self, obj): return bool(obj) - def newlist(self): + def newdict(self): return {} From arigo at codespeak.net Thu Feb 8 11:12:35 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 8 Feb 2007 11:12:35 +0100 (CET) Subject: [pypy-svn] r38136 - in pypy/branch: jit-virtual-world/pypy/jit/codegen new-jit-codegen Message-ID: <20070208101235.865A510088@code0.codespeak.net> Author: arigo Date: Thu Feb 8 11:12:34 2007 New Revision: 38136 Added: pypy/branch/jit-virtual-world/pypy/jit/codegen/ - copied from r38134, pypy/branch/new-jit-codegen/ Removed: pypy/branch/new-jit-codegen/ Log: Merge the new 386 jit backend into the jit-virtual-world branch. From arigo at codespeak.net Thu Feb 8 12:58:54 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 8 Feb 2007 12:58:54 +0100 (CET) Subject: [pypy-svn] r38137 - pypy/extradoc/planning/1.0 Message-ID: <20070208115854.62F7B10086@code0.codespeak.net> Author: arigo Date: Thu Feb 8 12:58:51 2007 New Revision: 38137 Added: pypy/extradoc/planning/1.0/ pypy/extradoc/planning/1.0/documentation.txt (contents, props changed) Log: Release 1.0 planning directory, and start documentation planning. Added: pypy/extradoc/planning/1.0/documentation.txt ============================================================================== --- (empty file) +++ pypy/extradoc/planning/1.0/documentation.txt Thu Feb 8 12:58:51 2007 @@ -0,0 +1,71 @@ +Documentation for release 1.0 +================================ + + +config pages, for all the options. +Link to the other pages as much as possible. + + +pypy.net (update translation.txt) + + +js backend (update translation.txt) + + +object-optimizations.txt. I guess we take text from the EU report. + + +objspace-proxies.txt: + + * transparent proxies + + * security prototype + + +jit.txt: copy introduction from pypy-dev e-mail, add examples of nice colors + + +improve getting-started + + +release announcement + + +review - check (or decide to ignore) the following .txt files: + + * architecture.txt + * coding-guide.txt + * configuration.txt + * constraints-and-logic.txt + * contact.txt + * contributor.txt + * dev_method.txt + * dynamic-language-translation.txt + * eventhistory.txt + * extcompiler.txt + * extradoc.txt + * faq.txt + * garbage_collection.txt + * geninterp.txt + * getting-started.txt + * glossary.txt + * how-to-release.txt + * howto-logicobjspace-0.9.txt + * index-report.txt + * index.txt + * interpreter.txt + * low-level-encapsulation.txt + * objspace.txt + * parser.txt + * project-ideas.txt + * pyontology.txt + * rctypes.txt + * rlib.txt + * rtyper.txt + * sprint-reports.txt + * stackless.txt + * standalone-howto.txt + * svn-help.txt + * theory.txt + * translation-aspects.txt + * translation.txt From arigo at codespeak.net Thu Feb 8 13:01:49 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 8 Feb 2007 13:01:49 +0100 (CET) Subject: [pypy-svn] r38138 - pypy/extradoc/planning/1.0 Message-ID: <20070208120149.13D211008B@code0.codespeak.net> Author: arigo Date: Thu Feb 8 13:01:48 2007 New Revision: 38138 Modified: pypy/extradoc/planning/1.0/documentation.txt Log: mention thunk space Modified: pypy/extradoc/planning/1.0/documentation.txt ============================================================================== --- pypy/extradoc/planning/1.0/documentation.txt (original) +++ pypy/extradoc/planning/1.0/documentation.txt Thu Feb 8 13:01:48 2007 @@ -21,6 +21,8 @@ * security prototype + * thunk space (move from objspace.txt) + jit.txt: copy introduction from pypy-dev e-mail, add examples of nice colors From arigo at codespeak.net Thu Feb 8 13:23:47 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 8 Feb 2007 13:23:47 +0100 (CET) Subject: [pypy-svn] r38139 - pypy/extradoc/planning/1.0 Message-ID: <20070208122347.4596410083@code0.codespeak.net> Author: arigo Date: Thu Feb 8 13:23:45 2007 New Revision: 38139 Modified: pypy/extradoc/planning/1.0/documentation.txt Log: updates. assign myself to some tasks. Modified: pypy/extradoc/planning/1.0/documentation.txt ============================================================================== --- pypy/extradoc/planning/1.0/documentation.txt (original) +++ pypy/extradoc/planning/1.0/documentation.txt Thu Feb 8 13:23:45 2007 @@ -2,20 +2,33 @@ ================================ +index.txt: reorder the categories: + + * Meta-Documentation (about PyPy, coding, talks, etc.) + + * User Documentation (for the PyPy user): getting started, + how to translate, and new Python features + + * Status + + * Source Code Documentation, + ending with directory cross-reference + + config pages, for all the options. Link to the other pages as much as possible. -pypy.net (update translation.txt) +pypy.net - also update translation.txt -js backend (update translation.txt) +js backend - is there something to update in translation.txt? object-optimizations.txt. I guess we take text from the EU report. -objspace-proxies.txt: +objspace-proxies.txt: (arigo) * transparent proxies @@ -25,6 +38,7 @@ jit.txt: copy introduction from pypy-dev e-mail, add examples of nice colors + (arigo) improve getting-started From fijal at codespeak.net Thu Feb 8 14:43:27 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 8 Feb 2007 14:43:27 +0100 (CET) Subject: [pypy-svn] r38141 - pypy/extradoc/planning/1.0 Message-ID: <20070208134327.30A8D10088@code0.codespeak.net> Author: fijal Date: Thu Feb 8 14:43:24 2007 New Revision: 38141 Modified: pypy/extradoc/planning/1.0/documentation.txt Log: Update js info Modified: pypy/extradoc/planning/1.0/documentation.txt ============================================================================== --- pypy/extradoc/planning/1.0/documentation.txt (original) +++ pypy/extradoc/planning/1.0/documentation.txt Thu Feb 8 14:43:24 2007 @@ -23,7 +23,7 @@ js backend - is there something to update in translation.txt? - + BasicExternal approach, external functions? (fijal) object-optimizations.txt. I guess we take text from the EU report. From pedronis at codespeak.net Thu Feb 8 15:27:26 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Thu, 8 Feb 2007 15:27:26 +0100 (CET) Subject: [pypy-svn] r38145 - pypy/dist/pypy/translator/goal Message-ID: <20070208142726.5CE9510087@code0.codespeak.net> Author: pedronis Date: Thu Feb 8 15:27:23 2007 New Revision: 38145 Modified: pypy/dist/pypy/translator/goal/app_main.py Log: exit with status 1 if raising an exception, this makes py.test -C report failures correctly. Modified: pypy/dist/pypy/translator/goal/app_main.py ============================================================================== --- pypy/dist/pypy/translator/goal/app_main.py (original) +++ pypy/dist/pypy/translator/goal/app_main.py Thu Feb 8 15:27:23 2007 @@ -225,17 +225,19 @@ if hasattr(signal, "SIGPIPE"): signal.signal(signal.SIGPIPE, signal.SIG_IGN) + success = True + try: if sys.argv: if run_command: cmd = sys.argv.pop(1) def run_it(): exec cmd in mainmodule.__dict__ - run_toplevel(run_it) + success = run_toplevel(run_it) else: scriptdir = resolvedirof(sys.argv[0]) sys.path.insert(0, scriptdir) - run_toplevel(execfile, sys.argv[0], mainmodule.__dict__) + success = run_toplevel(execfile, sys.argv[0], mainmodule.__dict__) else: sys.argv.append('') go_interactive = True @@ -243,11 +245,11 @@ print >> sys.stderr, "debug: importing code" import code print >> sys.stderr, "debug: calling code.interact()" - run_toplevel(code.interact, local=mainmodule.__dict__) + success = run_toplevel(code.interact, local=mainmodule.__dict__) except SystemExit, e: return e.code else: - return 0 + return not success def resolvedirof(filename): try: From mwh at codespeak.net Thu Feb 8 15:34:52 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Thu, 8 Feb 2007 15:34:52 +0100 (CET) Subject: [pypy-svn] r38146 - pypy/dist/pypy/translator/llvm Message-ID: <20070208143452.0BFEF1008D@code0.codespeak.net> Author: mwh Date: Thu Feb 8 15:34:51 2007 New Revision: 38146 Modified: pypy/dist/pypy/translator/llvm/funcnode.py Log: a while-i-was-here rewrite to not use flowmodel.traverse and to not use map() when the applied function doesn't have a return value. Modified: pypy/dist/pypy/translator/llvm/funcnode.py ============================================================================== --- pypy/dist/pypy/translator/llvm/funcnode.py (original) +++ pypy/dist/pypy/translator/llvm/funcnode.py Thu Feb 8 15:34:51 2007 @@ -1,5 +1,5 @@ from pypy.objspace.flow.model import Block, Constant, Link -from pypy.objspace.flow.model import mkentrymap, traverse, c_last_exception +from pypy.objspace.flow.model import mkentrymap, c_last_exception from pypy.rpython.lltypesystem import lltype from pypy.translator.llvm.node import LLVMNode, ConstantLLVMNode from pypy.translator.llvm.opwriter import OpWriter @@ -48,21 +48,21 @@ def __str__(self): return "" %(self.ref,) - + def 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) - assert block.exitswitch != c_last_exception - assert self.graph, "cannot traverse" - traverse(visit, self.graph) + prepare_arg = self.db.prepare_arg + for block in self.graph.iterblocks(): + for arg in block.inputargs: + prepare_arg(arg) + for op in block.operations: + for arg in op.args: + prepare_arg(arg) + prepare_arg(op.result) + assert block.exitswitch != c_last_exception + for link in block.exits: + for arg in link.args: + prepare_arg(arg) # ______________________________________________________________________ # main entry points from genllvm From mwh at codespeak.net Thu Feb 8 15:38:04 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Thu, 8 Feb 2007 15:38:04 +0100 (CET) Subject: [pypy-svn] r38147 - pypy/dist/pypy/translator/llvm Message-ID: <20070208143804.593D41008B@code0.codespeak.net> Author: mwh Date: Thu Feb 8 15:38:03 2007 New Revision: 38147 Modified: pypy/dist/pypy/translator/llvm/database.py Log: small whitespace cleanups Modified: pypy/dist/pypy/translator/llvm/database.py ============================================================================== --- pypy/dist/pypy/translator/llvm/database.py (original) +++ pypy/dist/pypy/translator/llvm/database.py Thu Feb 8 15:38:03 2007 @@ -103,28 +103,30 @@ 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): + + elif isinstance(type_, lltype.Ptr): self.prepare_type(type_.TO) elif isinstance(type_, lltype.FixedSizeArray): self.addpending(type_, FixedSizeArrayTypeNode(self, type_)) - + elif isinstance(type_, lltype.Struct): if type_._arrayfld: self.addpending(type_, StructVarsizeTypeNode(self, type_)) else: - self.addpending(type_, StructTypeNode(self, type_)) + self.addpending(type_, StructTypeNode(self, type_)) - elif isinstance(type_, lltype.FuncType): + elif isinstance(type_, lltype.FuncType): self.addpending(type_, FuncTypeNode(self, type_)) - elif isinstance(type_, lltype.Array): + elif isinstance(type_, lltype.Array): if type_.OF is lltype.Void: self.addpending(type_, VoidArrayTypeNode(self, type_)) else: @@ -132,7 +134,7 @@ elif isinstance(type_, lltype.OpaqueType): if hasattr(type_, '_exttypeinfo'): - self.addpending(type_, ExtOpaqueTypeNode(self, type_)) + self.addpending(type_, ExtOpaqueTypeNode(self, type_)) else: self.addpending(type_, OpaqueTypeNode(self, type_)) @@ -267,7 +269,11 @@ if isinstance(type_, lltype.Primitive): return self.primitives[type_] elif isinstance(type_, lltype.Ptr): - return self.repr_type(type_.TO) + '*' + if isinstance(type_.TO, lltype.FixedSizeArray): + # hack copied from genc + return self.repr_type(type_.TO.OF) + '*' + else: + return self.repr_type(type_.TO) + '*' else: raise TypeError("cannot represent %r" %(type_,)) From antocuni at codespeak.net Thu Feb 8 15:58:11 2007 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Thu, 8 Feb 2007 15:58:11 +0100 (CET) Subject: [pypy-svn] r38149 - pypy/extradoc/planning/1.0 Message-ID: <20070208145811.D0FE010092@code0.codespeak.net> Author: antocuni Date: Thu Feb 8 15:58:05 2007 New Revision: 38149 Modified: pypy/extradoc/planning/1.0/documentation.txt Log: I'll take care of that. Modified: pypy/extradoc/planning/1.0/documentation.txt ============================================================================== --- pypy/extradoc/planning/1.0/documentation.txt (original) +++ pypy/extradoc/planning/1.0/documentation.txt Thu Feb 8 15:58:05 2007 @@ -19,7 +19,7 @@ Link to the other pages as much as possible. -pypy.net - also update translation.txt +pypy.net - also update translation.txt (antocuni) js backend - is there something to update in translation.txt? @@ -43,6 +43,7 @@ improve getting-started +short how to compile on windows (based on docstring of goal/win32/gc_patch_windows.py) (antocuni) release announcement From arigo at codespeak.net Thu Feb 8 16:18:17 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 8 Feb 2007 16:18:17 +0100 (CET) Subject: [pypy-svn] r38152 - pypy/dist/pypy/doc Message-ID: <20070208151817.05C4E10098@code0.codespeak.net> Author: arigo Date: Thu Feb 8 16:18:16 2007 New Revision: 38152 Modified: pypy/dist/pypy/doc/jit.txt Log: Usage and Status section in front of jit.txt. Modified: pypy/dist/pypy/doc/jit.txt ============================================================================== --- pypy/dist/pypy/doc/jit.txt (original) +++ pypy/dist/pypy/doc/jit.txt Thu Feb 8 16:18:16 2007 @@ -1,10 +1,152 @@ -======================= -JIT Generation in PyPy -======================= +======================================================================== + JIT Compilers in PyPy +======================================================================== .. contents:: .. sectnum:: + +------------------------------------------------------------------------ + Usage and Status +------------------------------------------------------------------------ + +.. _warning: + +A foreword of warning about the JIT of PyPy as of February 2007: + + * What it does is produce machine code in memory, and run it. + * What it does not do is gain much speed by doing so. + * Yet. + + +Status +====== + +From a Python programmer's point of view, the JIT is not yet able to +speed up many programs at all. It generally results in slow-downs. + +All the pieces necessary to get a reasonable result are present, but +need to be put together, which we expect to do in March. We fully +expect that the most extremely algorithmic examples will soon run at +about 50% of the speed of compiled C code. + +It is worth underlying that the JIT has some rough edges but nothing +fundamental stops it, and by construction it can JIT absolutely *any* +kind of Python code - generators, nested scopes, ``exec`` statements, +``sys._getframe().f_back.f_back.f_locals``, etc. + + +In more details +--------------- + +So far there is little point in trying out the JIT unless you want to +help find bugs. You can also look at the machine code it produces, but +if you do please keep in mind that the assembler will look fundamentally +different after we extend the range of PyPy that the JIT generator +processes. + +* The produced machine code is kind of good, in the sense that the + backends perform some reasonable register allocation. The 386 backend + computes the lifetime of values within blocks. The PPC backend does + not, but the fact that the processor has plenty of registers mitigates + this problem to some extent. The PPC backend is not 100% complete + yet. An LLVM_ backend is started but blocked half-way on a hard + problem that might not get solved any time soon. + +* The timeshifter_, which produces the JIT frontend, is able to handle + rather incredibly tricky situations successfully. + +* The remaining work is to do the necessary adjustments of the PyPy + interpreter source code so that the timeshifter can process it. At + the moment only the interpreter's main dispatch loop (i.e. mostly only + pyopcode.py) is fed to the timeshifter, so the produced JIT can remove + the bytecode interpretation overhead, but cannot look inside the + implementation of ``space.add()``, for example. + +The results thus look like Python2C+gcc: we produce machine code that is +essentially a sequence of calls to space.add(), space.cmp(), +space.is_true(), etc. A well-known estimate is that Python2C gives a +~2x speed-up; we get about the same with our JIT, except that the +start-up overhead is greater - calling small functions is still quite +slower with the JIT than without. On the other hand, Python2C doesn't +emulate frames, for example, so AFAIK PyPy contains the first Python +compiler ever where ``sys._getframe()`` completely works (Psyco_ +emulates frames but not at 100%). + +.. _LLVM: http://llvm.org/ + + +How to compile a pypy-c with a JIT +================================== + +Go to ``pypy/jit/goal/`` and run:: + + ../../translator/goal/translate.py targetjit.py + +Please first read the warning_ above. This only works for Intel +386-compatible machines yet. **This is not going to speed up your +programs yet!** + +This will produce the C code for a version pypy-c that includes both a +regular interpreter and an automatically generated JIT compiler. This +pypy-c uses its interpreter by default, and due to some overhead we +expect this interpreter to be a bit slower than the one found in a +pypy-c compiled without JIT. + +Usage +===== + +You can mark one or many code objects as candidates for being run by +the JIT as follows:: + + >>>> def f(x): return x*5 + >>>> import pypyjit + >>>> pypyjit.enable(f.func_code) + >>>> f(7) + # the JIT runs here + 35 + >>>> f(8) + # machine code already generated, no more jitting occurs here + 40 + +You can get a dump of the generated machine code by setting the +environment variable ``PYPYJITLOG`` to a file name before you start +pypy-c. See `In more details`_ above. To inspect this file, use the +following tool:: + + python pypy/jit/codegen/i386/viewcode.py dumpfilename + +The viewcode.py script is based on the Linux tool ``objdump`` to produce +a disassembly. If you want to port the tool to Windows, have a look at +http://codespeak.net/svn/psyco/dist/py-utils/xam.py : this is the tool +from which viewcode.py was derived in the first place, but +Windows-specific parts were omitted for lack of a Windows machine to try +them on. + +Caveats +------- + +When running JIT'ed code, the tracing hooks are not invoked. This +should be the only visible effect of the JIT, aside from the debug +prints and the speed/memory impact. In practice, of course, it still +has also got rough edges. + +One of them is that all compile-time errors are fatal for now, because +it is hard to recover from them. Clearly, the compiler is not +*supposed* to fail, but it can occur because the memory runs out, a bug +hits, or for more subtle reasons. For example, overflowing the stack is +likely to cause the JIT compiler to try to compile the app-level +handlers for the RuntimeError, and compiling takes up stack space too - +so the compiler, running on top of the already-full stack, might hit the +stack limit again before it has got a chance to generate code for the +app-level handlers. + + +------------------------------------------------------------------------ + JIT Compiler Generation - Technical Section +------------------------------------------------------------------------ + + Introduction ============= From hpk at codespeak.net Thu Feb 8 16:24:12 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Thu, 8 Feb 2007 16:24:12 +0100 (CET) Subject: [pypy-svn] r38153 - pypy/branch/pytrunkmerge/pypy Message-ID: <20070208152412.A28BD10098@code0.codespeak.net> Author: hpk Date: Thu Feb 8 16:24:11 2007 New Revision: 38153 Modified: pypy/branch/pytrunkmerge/pypy/conftest.py Log: "demo" should also be rsynced to allow successfull dist-testing of docs referencing it. Modified: pypy/branch/pytrunkmerge/pypy/conftest.py ============================================================================== --- pypy/branch/pytrunkmerge/pypy/conftest.py (original) +++ pypy/branch/pytrunkmerge/pypy/conftest.py Thu Feb 8 16:24:11 2007 @@ -7,7 +7,7 @@ rootdir = py.magic.autopath().dirpath() -dist_rsync_roots = ['.', '../lib-python', '../py'] +dist_rsync_roots = ['.', '../lib-python', '../py', '../demo'] dist_rsync_ignore = ['_cache'] # From antocuni at codespeak.net Thu Feb 8 16:36:50 2007 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Thu, 8 Feb 2007 16:36:50 +0100 (CET) Subject: [pypy-svn] r38166 - pypy/dist/pypy/doc Message-ID: <20070208153650.A45931008A@code0.codespeak.net> Author: antocuni Date: Thu Feb 8 16:36:49 2007 New Revision: 38166 Modified: pypy/dist/pypy/doc/getting-started.txt Log: Update gencli sections in getting-started. Modified: pypy/dist/pypy/doc/getting-started.txt ============================================================================== --- pypy/dist/pypy/doc/getting-started.txt (original) +++ pypy/dist/pypy/doc/getting-started.txt Thu Feb 8 16:36:49 2007 @@ -478,10 +478,9 @@ Translating the flow graph to CLI code ++++++++++++++++++++++++++++++++++++++ -The CLI backend aim to translate RPython code into .NET executables: -it is still work-in-progress, but it is already somewhat usable for -small snippets of code since it supports classes, list, dictionaries, -and strings. You can try out the CLI backend from the interactive +Use the CLI backend to translate the flowgraphs into .NET executables: +``gencli`` is quite mature now and can also compile the whole +interpreter. You can try out the CLI backend from the interactive translator shell:: >>> def myfunc(a, b): return a+b @@ -626,6 +625,30 @@ ./translate.py --text --batch --backend=llvm --raisingop2direct_call targetpypystandalone.py +Translating using the CLI backend ++++++++++++++++++++++++++++++++++ + +To create a standalone .NET executable using the CLI backend:: + + ./translate.py --text --batch --backend=cli targetpypystandalone.py + +The executable and all its dependecies will be stored in the +./pypy-cli-data directory. To run pypy.NET, you can run +./pypy-cli-data/main.exe. If you are using Linux or Mac, you can use +the convenience ./pypy-cli script:: + + $ ./pypy-cli + debug: entry point starting + debug: argv -> + debug: importing code + debug: calling code.interact() + Python 2.4.1 (pypy 0.9.0 build 38134) on linux2 + Type "help", "copyright", "credits" or "license" for more information. + (InteractiveConsole) + >>>> 1 + 1 + 2 + >>>> + .. _`start reading sources`: Where to start reading the sources From arigo at codespeak.net Thu Feb 8 16:38:16 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 8 Feb 2007 16:38:16 +0100 (CET) Subject: [pypy-svn] r38167 - in pypy/dist/pypy/objspace: . test Message-ID: <20070208153816.37CA31008B@code0.codespeak.net> Author: arigo Date: Thu Feb 8 16:38:14 2007 New Revision: 38167 Modified: pypy/dist/pypy/objspace/test/test_thunkobjspace.py pypy/dist/pypy/objspace/thunk.py Log: Add a thunk space @pypymagic.lazy, to decorate functions that you want to return a lazy result (the function is really only called when the result is needed). Modified: pypy/dist/pypy/objspace/test/test_thunkobjspace.py ============================================================================== --- pypy/dist/pypy/objspace/test/test_thunkobjspace.py (original) +++ pypy/dist/pypy/objspace/test/test_thunkobjspace.py Thu Feb 8 16:38:14 2007 @@ -84,3 +84,17 @@ pass assert is_thunk(thunk(f)) assert not is_thunk(42) + + def test_lazy(self): + from pypymagic import lazy + lst = [] + def f(x): + lst.append(x) + return x+5 + f = lazy(f) + y = f(3) + assert lst == [] + assert type(y) is int + assert lst == [3] + assert type(y) is int + assert lst == [3] Modified: pypy/dist/pypy/objspace/thunk.py ============================================================================== --- pypy/dist/pypy/objspace/thunk.py (original) +++ pypy/dist/pypy/objspace/thunk.py Thu Feb 8 16:38:14 2007 @@ -1,7 +1,7 @@ """Example usage: $ py.py -o thunk - >>> from pypymagic import thunk, become + >>> from pypymagic import thunk, lazy, become >>> def f(): ... print 'computing...' ... return 6*7 @@ -16,11 +16,22 @@ >>> type(y) computing... + + >>> @lazy + ... def g(n): + ... print 'computing...' + ... return n + 5 + ... + >>> y = g(12) + >>> y + computing... + 17 """ from pypy.objspace.proxy import patch_space_in_place from pypy.interpreter import gateway, baseobjspace, argument from pypy.interpreter.error import OperationError +from pypy.interpreter.typedef import Method # __________________________________________________________________________ @@ -85,6 +96,12 @@ return space.w_None app_become = gateway.interp2app(become) +def lazy(space, w_callable): + meth = Method(space, space.wrap(app_thunk), + w_callable, space.type(w_callable)) + return space.wrap(meth) +app_lazy = gateway.interp2app(lazy) + # __________________________________________________________________________ nb_forcing_args = {} @@ -161,4 +178,6 @@ space.wrap(app_is_thunk)) space.setattr(w_pypymagic, space.wrap('become'), space.wrap(app_become)) + space.setattr(w_pypymagic, space.wrap('lazy'), + space.wrap(app_lazy)) return space From antocuni at codespeak.net Thu Feb 8 16:38:45 2007 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Thu, 8 Feb 2007 16:38:45 +0100 (CET) Subject: [pypy-svn] r38168 - pypy/extradoc/planning/1.0 Message-ID: <20070208153845.DAE081009D@code0.codespeak.net> Author: antocuni Date: Thu Feb 8 16:38:44 2007 New Revision: 38168 Modified: pypy/extradoc/planning/1.0/documentation.txt Log: Remind to do this. Modified: pypy/extradoc/planning/1.0/documentation.txt ============================================================================== --- pypy/extradoc/planning/1.0/documentation.txt (original) +++ pypy/extradoc/planning/1.0/documentation.txt Thu Feb 8 16:38:44 2007 @@ -48,7 +48,9 @@ release announcement -review - check (or decide to ignore) the following .txt files: +review - check (or decide to ignore) the following .txt files. Pay +particular attention to update the release number showed in the output +of some examples: * architecture.txt * coding-guide.txt From arigo at codespeak.net Thu Feb 8 16:45:28 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 8 Feb 2007 16:45:28 +0100 (CET) Subject: [pypy-svn] r38169 - pypy/dist/pypy/doc Message-ID: <20070208154528.1F0F710093@code0.codespeak.net> Author: arigo Date: Thu Feb 8 16:45:26 2007 New Revision: 38169 Modified: pypy/dist/pypy/doc/objspace.txt Log: Thunk space: document pypymagic.lazy. Modified: pypy/dist/pypy/doc/objspace.txt ============================================================================== --- pypy/dist/pypy/doc/objspace.txt (original) +++ pypy/dist/pypy/doc/objspace.txt Thu Feb 8 16:45:26 2007 @@ -325,9 +325,9 @@ $ py.py -o thunk >>>> from pypymagic import thunk >>>> def f(): - ... print 'computing...' - ... return 6*7 - ... + .... print 'computing...' + .... return 6*7 + .... >>>> x = thunk(f) >>>> x computing... @@ -339,6 +339,24 @@ computing... +There is also a decorator for functions whose result can be computed +lazily (the function appears to return a result, but it is not really +invoked before the result is used, if at all): + + $ py.py -o thunk + >>>> from pypymagic import lazy + >>>> @lazy + .... def f(x): + .... print 'computing...' + .... return x * 100 + .... + >>>> lst = [f(i) for i in range(10)] + >>>> del lst[1:9] + >>>> lst + computing... + computing... + [0, 900] + .. _`flow object space`: From cfbolz at codespeak.net Thu Feb 8 16:46:12 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 8 Feb 2007 16:46:12 +0100 (CET) Subject: [pypy-svn] r38170 - pypy/extradoc/planning/1.0 Message-ID: <20070208154612.71C8A10093@code0.codespeak.net> Author: cfbolz Date: Thu Feb 8 16:46:05 2007 New Revision: 38170 Modified: pypy/extradoc/planning/1.0/documentation.txt Log: sign myself up for some things. add random comments about some of the doc files. Modified: pypy/extradoc/planning/1.0/documentation.txt ============================================================================== --- pypy/extradoc/planning/1.0/documentation.txt (original) +++ pypy/extradoc/planning/1.0/documentation.txt Thu Feb 8 16:46:05 2007 @@ -41,49 +41,53 @@ (arigo) -improve getting-started +improve getting-started (cfbolz, partially) short how to compile on windows (based on docstring of goal/win32/gc_patch_windows.py) (antocuni) release announcement +architecture.txt: should maybe grow a bit or at least have an updated "status" +section. + +contributor.txt: needs to be updated review - check (or decide to ignore) the following .txt files. Pay particular attention to update the release number showed in the output of some examples: - * architecture.txt * coding-guide.txt - * configuration.txt + * configuration.txt (cfbolz) * constraints-and-logic.txt * contact.txt - * contributor.txt * dev_method.txt - * dynamic-language-translation.txt + * dynamic-language-translation.txt (old report, leave as it is? or remove and + point to the report?) + + * eventhistory.txt * extcompiler.txt * extradoc.txt - * faq.txt - * garbage_collection.txt - * geninterp.txt - * getting-started.txt - * glossary.txt + * faq.txt (add questions and answers) + * garbage_collection.txt (out of date) + * geninterp.txt (incomplete) + * glossary.txt (add terms) * how-to-release.txt * howto-logicobjspace-0.9.txt - * index-report.txt - * index.txt + * index-report.txt (shouldn't be changed, I guess) * interpreter.txt - * low-level-encapsulation.txt + * low-level-encapsulation.txt (old report, leave as it is? or remove and + point to the report?) * objspace.txt - * parser.txt + * parser.txt (horribly incomplete) * project-ideas.txt * pyontology.txt * rctypes.txt - * rlib.txt + * rlib.txt (cfbolz) * rtyper.txt - * sprint-reports.txt + * sprint-reports.txt (shouldn't be changed, I guess) * stackless.txt - * standalone-howto.txt + * standalone-howto.txt (remove/or update) * svn-help.txt * theory.txt * translation-aspects.txt From antocuni at codespeak.net Thu Feb 8 16:53:47 2007 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Thu, 8 Feb 2007 16:53:47 +0100 (CET) Subject: [pypy-svn] r38171 - pypy/dist/pypy/doc Message-ID: <20070208155347.B291B10097@code0.codespeak.net> Author: antocuni Date: Thu Feb 8 16:53:46 2007 New Revision: 38171 Modified: pypy/dist/pypy/doc/rtyper.txt Log: Copy a section from the WP-12 report about the ootype object model. Modified: pypy/dist/pypy/doc/rtyper.txt ============================================================================== --- pypy/dist/pypy/doc/rtyper.txt (original) +++ pypy/dist/pypy/doc/rtyper.txt Thu Feb 8 16:53:46 2007 @@ -514,6 +514,37 @@ ``oodowncast``. Backends that supports implicit upcasting, such as CLI and Java, can simply ignore only ``ooupcast``. +Object model +++++++++++++ + +The object model implemented by ootype is quite Java-like. The +following is a list of key feature of the ootype object model which +have a direct correspondence in the Java or .NET object: + + - classes have a static set of strongly typed methods and + attributes; + + - methods can be overriden in subclasses; every method is "virtual" + (i.e., can be overridden); methods can be "abstract" (i.e., need + to be overridden in subclasses); + + - classes support single inheritance; all classes inherits directly + or indirectly from the ROOT class; + + - there is some support for method overloading. This feature is not + used by the RTyper itself because RPython doesn't support method + overloading, but it is used by the GenCLI backend for offering + access to the native .NET libraries (see XXX); + + - all classes, attributes and methods are public: ootype is only + used internally by the translator, so there is no need to enforce + accessibility rules; + + - classes and functions are first-class order objects: this feature + can be easly simulated by backends for platform on which it is not + a native feature; + + - there is a set of `built-in types`_ offering standard features; Exception handling ++++++++++++++++++ @@ -530,6 +561,7 @@ ``Instance`` type, so the usual inheritance exception hierarchy is preserved and the native way to catch exception should just work. +.. `built-in types`_ Built-in types ++++++++++++++ From arigo at codespeak.net Thu Feb 8 17:08:19 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 8 Feb 2007 17:08:19 +0100 (CET) Subject: [pypy-svn] r38177 - pypy/dist/demo Message-ID: <20070208160819.B6A9A10092@code0.codespeak.net> Author: arigo Date: Thu Feb 8 17:08:17 2007 New Revision: 38177 Added: pypy/dist/demo/fibonacci2.py Modified: pypy/dist/demo/fibonacci.py Log: A nice and simple fibonnaci numbers demo using @lazy. Modified: pypy/dist/demo/fibonacci.py ============================================================================== --- pypy/dist/demo/fibonacci.py (original) +++ pypy/dist/demo/fibonacci.py Thu Feb 8 17:08:17 2007 @@ -2,7 +2,7 @@ Thunk (a.k.a. lazy objects) in PyPy. To run on top of the thunk object space with the following command-line: - py.py -o thunk thunk-demo.py + py.py -o thunk fibonacci.py This is a typical Functional Programming Languages demo, computing the Fibonacci sequence by using an infinite lazy linked list. Added: pypy/dist/demo/fibonacci2.py ============================================================================== --- (empty file) +++ pypy/dist/demo/fibonacci2.py Thu Feb 8 17:08:17 2007 @@ -0,0 +1,27 @@ +""" +Lazy functions in PyPy. +To run on top of the thunk object space with the following command-line: + + py.py -o thunk fibonacci2.py + +This is a typical Functional Programming Languages demo, computing the +Fibonacci sequence as nested 2-tuples. +""" + +import pprint + +try: + from pypymagic import lazy +except ImportError: + print __doc__ + raise SystemExit(2) + + + at lazy +def fibo(a, b): + return (a, fibo(b, a + b)) + + +fibonacci = fibo(1, 1) + +pprint.pprint(fibonacci, depth=10) From arigo at codespeak.net Thu Feb 8 18:44:27 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 8 Feb 2007 18:44:27 +0100 (CET) Subject: [pypy-svn] r38187 - in pypy/dist/pypy/doc: . config Message-ID: <20070208174427.E19381008A@code0.codespeak.net> Author: arigo Date: Thu Feb 8 18:44:13 2007 New Revision: 38187 Added: pypy/dist/pypy/doc/objspace-proxies.txt - copied, changed from r38177, pypy/dist/pypy/doc/proxy.txt Removed: pypy/dist/pypy/doc/proxy.txt Modified: pypy/dist/pypy/doc/_ref.txt pypy/dist/pypy/doc/config/objspace.name.txt pypy/dist/pypy/doc/config/objspace.std.withtproxy.txt pypy/dist/pypy/doc/dynamic-language-translation.txt pypy/dist/pypy/doc/index.txt pypy/dist/pypy/doc/objspace.txt pypy/dist/pypy/doc/project-ideas.txt pypy/dist/pypy/doc/redirections Log: Started objspace-proxies.txt, to document all our objspace proxies. Modified: pypy/dist/pypy/doc/_ref.txt ============================================================================== --- pypy/dist/pypy/doc/_ref.txt (original) +++ pypy/dist/pypy/doc/_ref.txt Thu Feb 8 18:44:13 2007 @@ -60,7 +60,8 @@ .. _`objspace/logic.py`: ../../pypy/objspace/logic.py .. _`objspace/std/`: .. _`pypy/objspace/std`: ../../pypy/objspace/std -.. _`objspace/thunk.py`: ../../pypy/objspace/thunk.py +.. _`objspace/thunk.py`: +.. _`pypy/objspace/thunk.py`: ../../pypy/objspace/thunk.py .. _`objspace/trace.py`: .. _`pypy/objspace/trace.py`: ../../pypy/objspace/trace.py .. _`pypy/rlib`: Modified: pypy/dist/pypy/doc/config/objspace.name.txt ============================================================================== --- pypy/dist/pypy/doc/config/objspace.name.txt (original) +++ pypy/dist/pypy/doc/config/objspace.name.txt Thu Feb 8 18:44:13 2007 @@ -1,11 +1,17 @@ -Which `Object Space`_ to use. The `Standard Object Space`_ gives the normal -Python semantics, the others give additional features (except the Flow Object -Space which is not intended for normal useage): +Which `Object Space`_ to use. The `Standard Object Space`_ gives the +normal Python semantics, the others are `Object Space Proxies`_ giving +additional features (except the Flow Object Space which is not intended +for normal usage): - * The `Thunk Object Space`_ adds lazy evaluation to Python - -XXX add the others + * thunk_: adds lazy evaluation to Python + * logic_: logical programming features + * taint_: soft security + * dump_: dump all operations to a log .. _`Object Space`: ../objspace.html +.. _`Object Space Proxies`: ../objspace-proxies.html .. _`Standard Object Space`: ../objspace.html#standard-object-space -.. _`Thunk Object Space`: ../objspace.html#thunk-object-space +.. _thunk: ../objspace-proxies.html#thunk +.. _logic: ../objspace-proxies.html#logic +.. _taint: ../objspace-proxies.html#taint +.. _dump: ../objspace-proxies.html#dump Modified: pypy/dist/pypy/doc/config/objspace.std.withtproxy.txt ============================================================================== --- pypy/dist/pypy/doc/config/objspace.std.withtproxy.txt (original) +++ pypy/dist/pypy/doc/config/objspace.std.withtproxy.txt Thu Feb 8 18:44:13 2007 @@ -1,3 +1,3 @@ Enable `transparent proxies`_. -.. _`transparent proxies`: ../proxy.html +.. _`transparent proxies`: ../objspace-proxies.html#tproxy Modified: pypy/dist/pypy/doc/dynamic-language-translation.txt ============================================================================== --- pypy/dist/pypy/doc/dynamic-language-translation.txt (original) +++ pypy/dist/pypy/doc/dynamic-language-translation.txt Thu Feb 8 18:44:13 2007 @@ -2340,7 +2340,7 @@ .. _`Object Space`: objspace.html -.. _`Thunk Object Space`: objspace.html#the-thunk-object-space +.. _`Thunk Object Space`: objspace-proxies.html#thunk .. _`abstract interpretation`: theory.html#abstract-interpretation .. _`formal definition`: http://en.wikipedia.org/wiki/Abstract_interpretation .. _lattice: http://en.wikipedia.org/wiki/Lattice_%28order%29 Modified: pypy/dist/pypy/doc/index.txt ============================================================================== --- pypy/dist/pypy/doc/index.txt (original) +++ pypy/dist/pypy/doc/index.txt Thu Feb 8 18:44:13 2007 @@ -108,7 +108,7 @@ .. _Thunk: getting-started.html#lazily-computed-objects .. _Stackless: stackless.html .. _`Logic and Constraint`: howto-logicobjspace-0.9.html -.. _`Transparent proxy`: proxy.html +.. _`Transparent proxy`: objspace-proxies.html#tproxy Status @@ -295,7 +295,7 @@ .. _`object space`: objspace.html .. _FlowObjSpace: objspace.html#the-flow-object-space .. _`trace object space`: objspace.html#the-trace-object-space -.. _`thunk object space`: objspace.html#the-thunk-object-space +.. _`thunk object space`: objspace-proxies.html#thunk .. _`logic object space`: constraints-and-logic.html#logic-programming .. _StdObjSpace: objspace.html#the-standard-object-space .. _`abstract interpretation`: theory.html#abstract-interpretation Modified: pypy/dist/pypy/doc/objspace.txt ============================================================================== --- pypy/dist/pypy/doc/objspace.txt (original) +++ pypy/dist/pypy/doc/objspace.txt Thu Feb 8 18:44:13 2007 @@ -28,7 +28,7 @@ if-statements (or rather, to be pedantic, to implement the conditional-branching bytecodes into which if-statements get compiled). -We currently have four working object spaces which can be plugged into +We have many working object spaces which can be plugged into the bytecode interpreter: - The *Standard Object Space* is a complete implementation @@ -44,10 +44,10 @@ object space in order to trace the execution of bytecodes, frames and object space operations. -- the *Thunk Object Space* wraps another object space (e.g. the standard - one) and adds two capabilities: lazily computed objects (computed only when - an operation is performed on them), and "become", which completely and - globally replaces one object with another. +- various `Object Space proxies`_ wrap another object space (e.g. the standard + one) and adds new capabilities, like lazily computed objects (computed only + when an operation is performed on them), security-checking objects, + distributed objects living on several machines, etc. - the *Flow Object Space* transforms a Python program into a flow-graph representation, by recording all operations that the bytecode @@ -61,6 +61,7 @@ .. _`application-level`: coding-guide.html#application-level .. _`interpreter-level`: coding-guide.html#interpreter-level .. _`in another document`: translation.html +.. _`Object Space proxies`: objspace-proxies.html Object Space Interface ====================== @@ -313,52 +314,18 @@ .. _`traceconfig.py`: http://codespeak.net/svn/pypy/dist/pypy/tool/traceconfig.py -.. _`thunk object space`: +Proxy Object Spaces +=================== -The Thunk Object Space -====================== - -This small object space, meant as a nice example, wraps another object space (e.g. the standard one) and adds two capabilities: lazily computed objects (computed only when an operation is performed on them), and "become", which completely and globally replaces an object with another. - -Example usage:: +We have implemented several *proxy object spaces* which wrap another +space (typically the standard one) and add some capability to all +objects. These object spaces are documented in a separate page: `What +PyPy can do for your objects`_. - $ py.py -o thunk - >>>> from pypymagic import thunk - >>>> def f(): - .... print 'computing...' - .... return 6*7 - .... - >>>> x = thunk(f) - >>>> x - computing... - 42 - >>>> x - 42 - >>>> y = thunk(f) - >>>> type(y) - computing... - - -There is also a decorator for functions whose result can be computed -lazily (the function appears to return a result, but it is not really -invoked before the result is used, if at all): - - $ py.py -o thunk - >>>> from pypymagic import lazy - >>>> @lazy - .... def f(x): - .... print 'computing...' - .... return x * 100 - .... - >>>> lst = [f(i) for i in range(10)] - >>>> del lst[1:9] - >>>> lst - computing... - computing... - [0, 900] +.. _`What PyPy can do for your objects`: objspace-proxies.html -.. _`flow object space`: +.. _`Flow Object Space`: The Flow Object Space ===================== Modified: pypy/dist/pypy/doc/project-ideas.txt ============================================================================== --- pypy/dist/pypy/doc/project-ideas.txt (original) +++ pypy/dist/pypy/doc/project-ideas.txt Thu Feb 8 18:44:13 2007 @@ -258,4 +258,4 @@ .. _`ZODB's Persistent class`: http://www.zope.org/Documentation/Books/ZDG/current/Persistence.stx .. _`what is pypy.js`: js/whatis.html .. _`using the JavaScript backend`: js/using.html -.. _`transparent proxy`: proxy.html +.. _`transparent proxy`: objspace-proxies.html#tproxy Modified: pypy/dist/pypy/doc/redirections ============================================================================== --- pypy/dist/pypy/doc/redirections (original) +++ pypy/dist/pypy/doc/redirections Thu Feb 8 18:44:13 2007 @@ -34,5 +34,6 @@ 'draft-memory-management-threading-model.html': 'translation-aspects.html', 'ctypes-integration.html': 'rctypes.html', 'cpython-ctypes-behaviour.html': 'rctypes.html#cpython-behavior', + 'proxy.html': 'objspace-proxies.html#tproxy', } From pedronis at codespeak.net Thu Feb 8 18:47:37 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Thu, 8 Feb 2007 18:47:37 +0100 (CET) Subject: [pypy-svn] r38188 - in pypy/dist: lib-python pypy/tool/pytest pypy/tool/pytest/test Message-ID: <20070208174737.AED611008D@code0.codespeak.net> Author: pedronis Date: Thu Feb 8 18:47:34 2007 New Revision: 38188 Modified: pypy/dist/lib-python/conftest.py pypy/dist/pypy/tool/pytest/genreportdata.py pypy/dist/pypy/tool/pytest/htmlreport.py pypy/dist/pypy/tool/pytest/overview.py pypy/dist/pypy/tool/pytest/result.py pypy/dist/pypy/tool/pytest/test/test_new_count.py pypy/dist/pypy/tool/pytest/test/test_overview.py Log: - have options for lib-python conftest to specify a non default test result directory and for -C to specify a different location for the compiled pypy-c - because of previous checking py.test reports properly -C failures as failures - with -C use the pypy revision inside the executable used - use valid header fields names and add sanity checks about that, write some code to be able to read the broken old format with the email package from 2.4 - genreportdata works with 2.4 now - the few tests always passes, dont't need to be skipped on 2.4 - genreportdata takes an optional argument which is a testresultdir - fix some double escaping or broken try at using raw html with genreportdata and newer pylibs Modified: pypy/dist/lib-python/conftest.py ============================================================================== --- pypy/dist/lib-python/conftest.py (original) +++ pypy/dist/lib-python/conftest.py Thu Feb 8 18:47:34 2007 @@ -23,6 +23,8 @@ regrtestdir, modregrtestdir, testresultdir from pypy.tool.pytest.result import Result, ResultFromMime +pypyexecpath = pypydir.join('bin', 'pypy-c') + # # Interfacing/Integrating with py.test's collection process # @@ -37,15 +39,22 @@ 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"), + help="use a compiled version of pypy"), + Option('--compiled-pypy', action="store", type="string", dest="pypy_executable", + default=str(pypyexecpath), + help="to use together with -C to specify the path to the " + "compiled version of pypy, by default expected in pypy/bin/pypy-c"), Option('-E', '--extracttests', action="store_true", default=False, dest="extracttests", help="try to extract single tests and run them via py.test/PyPy"), Option('-T', '--timeout', action="store", type="string", default="100mp", dest="timeout", help="fail a test module after the given timeout. " - "specify in seconds or 'NUMmp' aka Mega-Pystones") - ) + "specify in seconds or 'NUMmp' aka Mega-Pystones"), + Option('--resultdir', action="store", type="string", + default=str(testresultdir), dest="resultdir", + help="directory under which to store results in USER at HOST subdirs"), + ) def gettimeout(): timeout = option.timeout.lower() @@ -796,15 +805,19 @@ return 'unknown' def getexecutable(_cache={}): - execpath = pypydir.join('bin', 'pypy-c') + execpath = py.path.local(option.pypy_executable) if not _cache: text = execpath.sysexec('-c', - 'import sys; print sys.version; print sys.pypy_translation_info') + 'import sys; ' + 'print sys.version; ' + 'print sys.pypy_svn_url; ' + 'print sys.pypy_translation_info; ') lines = text.split('\n') - assert len(lines) == 3 and lines[2] == '' - assert lines[1].startswith('{') and lines[1].endswith('}') - info = eval(lines[1]) + assert len(lines) == 4 and lines[3] == '' + assert lines[2].startswith('{') and lines[2].endswith('}') + info = eval(lines[2]) info['version'] = lines[0] + info['rev'] = eval(lines[1])[1] _cache.update(info) return execpath, _cache @@ -827,7 +840,8 @@ return ReallyRunFileExternal(name, parent=self) -def ensuretestresultdir(): +def ensuretestresultdir(): + testresultdir = py.path.local(option.resultdir) if not testresultdir.check(dir=1): py.test.skip("""'testresult' directory not found. To run tests in reporting mode (without -E), you first have to @@ -836,7 +850,6 @@ testresultdir, )) return testresultdir - # # testmethod: # invoking in a seprate process: py.py TESTFILE @@ -929,7 +942,7 @@ "more interesting non-timeout outcome") fn.write(result.repr_mimemessage().as_string(unixfrom=False)) - if result['exit status']: + if result['exit-status']: time.sleep(0.5) # time for a Ctrl-C to reach us :-) print >>sys.stderr, result.getnamedtext('stderr') py.test.fail("running test failed, see stderr output below") @@ -963,6 +976,7 @@ result['pypy-revision'] = getrev(pypydir) if option.use_compiled: execpath, info = getexecutable() + result['pypy-revision'] = info.pop('rev') result['executable'] = execpath.basename for key, value in info.items(): result['executable-%s' % key] = str(value) @@ -1002,7 +1016,7 @@ else: outcome = "ERR" - result['exit status'] = exit_status + result['exit-status'] = exit_status result['outcome'] = outcome return result Modified: pypy/dist/pypy/tool/pytest/genreportdata.py ============================================================================== --- pypy/dist/pypy/tool/pytest/genreportdata.py (original) +++ pypy/dist/pypy/tool/pytest/genreportdata.py Thu Feb 8 18:47:34 2007 @@ -2,27 +2,29 @@ import autopath import py import sys -if sys.version_info[:2] != (2,3): - raise RuntimeError("Genreportdata.py needs Python 2.3") mydir = py.magic.autopath().dirpath().realpath() from pypy.tool.pytest import htmlreport from pypy.tool.pytest import confpath -if __name__ == '__main__': - testresultdir = confpath.testresultdir - assert testresultdir.check(dir=1) - try: - resultwc = py.path.svnwc(testresultdir) - print "updating", resultwc - resultwc.update() - except KeyboardInterrupt, RuntimeError: - raise - except Exception,e: #py.process.ExecutionFailed,e: - print >> sys.stderr, "Warning: ",e #Subversion update failed" +if __name__ == '__main__': + if len(sys.argv) > 1: + testresultdir = py.path.local(sys.argv[1]) + assert testresultdir.check(dir=1) + else: + testresultdir = confpath.testresultdir + assert testresultdir.check(dir=1) + try: + resultwc = py.path.svnwc(testresultdir) + print "updating", resultwc + resultwc.update() + except KeyboardInterrupt, RuntimeError: + raise + except Exception,e: #py.process.ExecutionFailed,e: + print >> sys.stderr, "Warning: ",e #Subversion update failed" print "traversing", mydir - rep = htmlreport.HtmlReport() + rep = htmlreport.HtmlReport(testresultdir) rep.parselatest() print "making html files" Modified: pypy/dist/pypy/tool/pytest/htmlreport.py ============================================================================== --- pypy/dist/pypy/tool/pytest/htmlreport.py (original) +++ pypy/dist/pypy/tool/pytest/htmlreport.py Thu Feb 8 18:47:34 2007 @@ -14,10 +14,11 @@ # html = py.xml.html +NBSP = py.xml.raw(" ") class HtmlReport(object): - def __init__(self): - self.resultcache = ResultCache() + def __init__(self, resultdir): + self.resultcache = ResultCache(resultdir) def parselatest(self): self.resultcache.parselatest() @@ -49,10 +50,10 @@ def render_result_row(self, result): dp = py.path.local(result['fspath']) - + options = " ".join([x for x in result.get('options', []) if x!= 'core']) if not options: - options=" " + options = NBSP failureratio = 100 * (1.0 - result.ratio_of_passed()) return html.tr( @@ -64,7 +65,7 @@ html.td(result['platform']), html.td("%.2fs" % result['execution-time']), html.td(options), - html.td(result.repr_short_error() or ' ') + html.td(result.repr_short_error() or NBSP) ) def getrelpath(self, p): @@ -89,7 +90,7 @@ def iscore(result): return 'core' in result.get('options', []) coretests = [] - noncoretests = [] + noncoretests = [] for name in self.resultcache.getnames(): result = self.resultcache.getlatestrelevant(name) if iscore(result): @@ -182,7 +183,6 @@ text = result.getnamedtext(name) except KeyError: continue - text = py.xml.escape(text) self.body.append(html.h3(name)) self.body.append(html.pre(text)) Modified: pypy/dist/pypy/tool/pytest/overview.py ============================================================================== --- pypy/dist/pypy/tool/pytest/overview.py (original) +++ pypy/dist/pypy/tool/pytest/overview.py Thu Feb 8 18:47:34 2007 @@ -1,9 +1,9 @@ -from pypy.tool.pytest.confpath import testresultdir from pypy.tool.pytest import result - +import sys class ResultCache: - def __init__(self): + def __init__(self, resultdir): + self.resultdir = resultdir self.name2result = {} def parselatest(self): @@ -11,16 +11,17 @@ return p.check(fnmatch='test_*.txt', file=1) def rec(p): return p.check(dotfile=0) - for x in testresultdir.visit(filefilter, rec): + for x in self.resultdir.visit(filefilter, rec): self.parse_one(x) - def parse_one(self, resultpath): + def parse_one(self, resultpath): try: res = result.ResultFromMime(resultpath) ver = res['testreport-version'] - if ver != "1.1": + if ver != "1.1" and ver != "1.1.1": raise TypeError - except TypeError: + except TypeError: # xxx + print >>sys.stderr, "could not parse %s" % resultpath return name = res.testname print name @@ -35,7 +36,7 @@ resultlist = self.name2result[name] maxrev = 0 maxresult = None - for res in resultlist: + for res in resultlist: resrev = res['pypy-revision'] if resrev == 'unknown': continue Modified: pypy/dist/pypy/tool/pytest/result.py ============================================================================== --- pypy/dist/pypy/tool/pytest/result.py (original) +++ pypy/dist/pypy/tool/pytest/result.py Thu Feb 8 18:47:34 2007 @@ -52,7 +52,10 @@ items = self._headers.items() items.sort() reprs = {} - for name, value in items: + for name, value in items: + assert ':' not in name + chars = map(ord, name) + assert min(chars) >= 33 and max(chars) <= 126 outer[name] = str(value) if not isinstance(value, str): typename = type(value).__name__ @@ -105,17 +108,40 @@ def istimeout(self): return self['outcome'].lower() == 't/o' +# XXX backward compatibility +def sanitize(msg, path): + if 'exit-status' in msg.keys(): + return msg + f = open(str(path), 'r') + msg = f.read() + f.close() + for broken in ('exit status', 'cpu model', 'cpu mhz'): + valid = broken.replace(' ','-') + invalid = msg.find(broken+':') + msg = (msg[:invalid] + valid + + msg[invalid+len(valid):]) + from email import message_from_string + msg = message_from_string(msg) + return msg + +def sanitize_reprs(reprs): + if 'exit status' in reprs: + reprs['exit-status'] = reprs.pop('exit status') + class ResultFromMime(Result): def __init__(self, path): super(ResultFromMime, self).__init__(init=False) - f = open(str(path), 'r') - from email import message_from_file + f = open(str(path), 'r') + from email import message_from_file msg = message_from_file(f) + f.close() + msg = sanitize(msg, path) # XXX security wise evil (keep in mind once we accept reporsts # from anonymous #print msg['_reprs'] - self._reprs = eval(msg['_reprs']) + self._reprs = eval(msg['_reprs']) del msg['_reprs'] + sanitize_reprs(self._reprs) for name, value in msg.items(): if name in self._reprs: value = eval(value) # XXX security @@ -132,7 +158,7 @@ payload = msg.get_payload() if payload: for submsg in payload: - assert submsg.get_main_type() == 'text' + assert submsg.get_content_type() == 'text/plain' fn = submsg.get_filename() assert fn # XXX we need to deal better with encodings to @@ -165,14 +191,14 @@ except: username = 'unknown' userhost = '%s@%s' % (username, socket.gethostname()) - result['testreport-version'] = "1.1" + result['testreport-version'] = "1.1.1" result['userhost'] = userhost result['platform'] = sys.platform result['python-version-info'] = sys.version_info info = try_getcpuinfo() if info is not None: - result['cpu model'] = info.get('model name', "unknown") - result['cpu mhz'] = info.get('cpu mhz', 'unknown') + result['cpu-model'] = info.get('model name', "unknown") + result['cpu-mhz'] = info.get('cpu mhz', 'unknown') # # # Modified: pypy/dist/pypy/tool/pytest/test/test_new_count.py ============================================================================== --- pypy/dist/pypy/tool/pytest/test/test_new_count.py (original) +++ pypy/dist/pypy/tool/pytest/test/test_new_count.py Thu Feb 8 18:47:34 2007 @@ -5,9 +5,6 @@ testpath = py.magic.autopath().dirpath('data') class TestResultCache: - def setup_class(self): - if py.std.sys.version_info >= (2,4): - py.test.skip("does not work on python 2.4 and greater currently") def test_timeout(self): test = ResultFromMime(testpath.join('test___all__.txt')) Modified: pypy/dist/pypy/tool/pytest/test/test_overview.py ============================================================================== --- pypy/dist/pypy/tool/pytest/test/test_overview.py (original) +++ pypy/dist/pypy/tool/pytest/test/test_overview.py Thu Feb 8 18:47:34 2007 @@ -7,7 +7,7 @@ def setup_class(cls): if not testresultdir.check(dir=1): py.test.skip("testresult directory not checked out") - cls.rc = ResultCache() + cls.rc = ResultCache(testresultdir) cls.rc.parselatest() def test_getlatest_all(self): From cfbolz at codespeak.net Thu Feb 8 20:17:12 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 8 Feb 2007 20:17:12 +0100 (CET) Subject: [pypy-svn] r38199 - in pypy/dist/pypy/doc: . image Message-ID: <20070208191712.D65741007E@code0.codespeak.net> Author: cfbolz Date: Thu Feb 8 20:17:07 2007 New Revision: 38199 Added: pypy/dist/pypy/doc/image/parsing_example10.dot Modified: pypy/dist/pypy/doc/rlib.txt Log: small fixes, addition of a slightly larger example Added: pypy/dist/pypy/doc/image/parsing_example10.dot ============================================================================== --- (empty file) +++ pypy/dist/pypy/doc/image/parsing_example10.dot Thu Feb 8 20:17:07 2007 @@ -0,0 +1,37 @@ +digraph G{ +"-1220061652" [label="object"]; +"-1220061652" -> "-1220127636"; +"-1220127636" [label="entry"]; +"-1220127636" -> "-1213915636"; +"-1213915636" [shape=box,label="STRING\n'a'"]; +"-1220127636" -> "-1214251156"; +"-1214251156" [shape=box,label="STRING\n'5'"]; +"-1220061652" -> "-1220063188"; +"-1220063188" [label="entry"]; +"-1220063188" -> "-1214253076"; +"-1214253076" [shape=box,label="STRING\n'b'"]; +"-1220063188" -> "-1220059444"; +"-1220059444" [label="array"]; +"-1220059444" -> "-1214253364"; +"-1214253364" [shape=box,label="NUMBER\n'1'"]; +"-1220059444" -> "-1214254292"; +"-1214254292" [shape=box,label="__0_null\n'null'"]; +"-1220059444" -> "-1214253268"; +"-1214253268" [shape=box,label="NUMBER\n'3'"]; +"-1220059444" -> "-1214252596"; +"-1214252596" [shape=box,label="__1_true\n'true'"]; +"-1220059444" -> "-1220062260"; +"-1220062260" [label="object"]; +"-1220062260" -> "-1220060116"; +"-1220060116" [label="entry"]; +"-1220060116" -> "-1214211860"; +"-1214211860" [shape=box,label="STRING\n'f'"]; +"-1220060116" -> "-1214210132"; +"-1214210132" [shape=box,label="STRING\n'g'"]; +"-1220062260" -> "-1220062868"; +"-1220062868" [label="entry"]; +"-1220062868" -> "-1214211956"; +"-1214211956" [shape=box,label="STRING\n'h'"]; +"-1220062868" -> "-1214212308"; +"-1214212308" [shape=box,label="NUMBER\n'6'"]; +} Modified: pypy/dist/pypy/doc/rlib.txt ============================================================================== --- pypy/dist/pypy/doc/rlib.txt (original) +++ pypy/dist/pypy/doc/rlib.txt Thu Feb 8 20:17:07 2007 @@ -54,7 +54,7 @@ ``ComputedIntSymbolic``: Instances of ``ComputedIntSymbolic`` are treated like integers of unknown - value by the annotator. The value is determined by a non-argument function + value by the annotator. The value is determined by a no-argument function (which needs to be passed into the constructor of the class). When the backend emits code, the function is called to determine the value. @@ -93,7 +93,7 @@ carries exactly one integer field. The class should have ``__slots__`` with exactly one entry defined. After translation, instances of this class won't be allocated but represented by *tagged pointers**, that is pointers - who have the lowest bit set. + that have the lowest bit set. .. _objectmodel: ../../pypy/rlib/objectmodel.py @@ -120,7 +120,7 @@ ``tofloat``. Since RPython does not support operator overloading, all the special methods of ``rbigint`` that would normally start and end with "__" have these underscores left out for better readability (so ``a.add(b)`` can be used -to add two rbigint). +to add two rbigint instances). .. _rbigint: ../../pypy/rlib/rbigint.py @@ -148,7 +148,7 @@ ========== The rstack_ module allows an RPython progam to control its own execution stack. -This is mostly only useful if the program is translated using stackless. An old +This is only useful if the program is translated using stackless. An old description of the exposed functions is below. We introduce an RPython type ``frame_stack_top`` and a built-in function @@ -325,16 +325,15 @@ IGNORE: " "; DECIMAL: "0|[1-9][0-9]*"; additive: multitive "+" additive | - multitive "-" additive | multitive; multitive: primary "*" multitive | - primary "/" multitive | primary; primary: "(" additive ")" | DECIMAL; -This grammar describes the syntax of arithmetic impressions. The tokenizer +This grammar describes the syntax of arithmetic impressions involving addition +and multiplication. The tokenizer produces a stream of either DECIMAL tokens or tokens that have matched one of -the literals "+", "-", "*" or "/". Any space will be ignored. The grammar +the literals "+", "*", "(" or ")". Any space will be ignored. The grammar produces a syntax tree that follows the precedence of the operators. For example the expression ``12 + 4 * 5`` is parsed into the following tree: @@ -378,7 +377,7 @@ contains a lot of nodes that are not really conveying useful information. To get rid of some of them, there is some support in the grammar format to automatically create a visitor that transforms the tree to remove the additional -nodes. The simplest such transformation is to just remove nodes, but there are +nodes. The simplest such transformation just removes nodes, but there are more complex ones. The syntax for these transformations is to enclose symbols in expansions of a @@ -505,7 +504,28 @@ Full Example ------------ -XXX to be written +A semi-complete parser for the `json format`_:: + + STRING: "\\"[^\\\\"]*\\""; + NUMBER: "\-?(0|[1-9][0-9]*)(\.[0-9]+)?([eE][\+\-]?[0-9]+)?"; + IGNORE: " |\n"; + value: | | | | <"null"> | + <"true"> | <"false">; + object: ["{"] (entry [","])* entry ["}"]; + array: ["["] (value [","])* value ["]"]; + entry: STRING [":"] value; + + +The resulting tree for parsing the string:: + + {"a": "5", "b": [1, null, 3, true, {"f": "g", "h": 6}]} + +looks like this: + +.. graphviz:: image/parsing_example10.dot + + .. _`Prolog interpreter`: ../../pypy/lang/prolog/ .. _parsing: ../../pypy/rlib/parsing/ +.. _`json format`: http://www.json.org From cfbolz at codespeak.net Thu Feb 8 20:18:14 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 8 Feb 2007 20:18:14 +0100 (CET) Subject: [pypy-svn] r38200 - in pypy/dist/pypy/rlib/parsing: . test Message-ID: <20070208191814.C9B8510084@code0.codespeak.net> Author: cfbolz Date: Thu Feb 8 20:18:05 2007 New Revision: 38200 Modified: pypy/dist/pypy/rlib/parsing/test/pygrammar.txt pypy/dist/pypy/rlib/parsing/test/test_ebnfparse.py pypy/dist/pypy/rlib/parsing/test/test_pythonparse.py pypy/dist/pypy/rlib/parsing/test/test_regexparse.py pypy/dist/pypy/rlib/parsing/tree.py Log: small changes I had lying around in my working copy Modified: pypy/dist/pypy/rlib/parsing/test/pygrammar.txt ============================================================================== --- pypy/dist/pypy/rlib/parsing/test/pygrammar.txt (original) +++ pypy/dist/pypy/rlib/parsing/test/pygrammar.txt Thu Feb 8 20:18:05 2007 @@ -90,16 +90,16 @@ expr: xor_expr "|" expr | ; xor_expr: and_expr "^" xor_expr | ; and_expr: shift_expr "&" and_expr | ; -shift_expr: arith_expr "<<" shift_expr | # was (("<<"|">>") arith_expr)* - arith_expr ">>" shift_expr | +shift_expr: arith_expr ("<<" arith_expr)+ | # was (("<<"|">>") arith_expr)* + arith_expr (">>" arith_expr)+ | ; -arith_expr: term "+" arith_expr | # was (("+"|"-") term)* - term "-" arith_expr | +arith_expr: term ("+" term)+ | # was (("+"|"-") term)* + term ("-" term)+ | ; -term: factor "*" term | # was (("*"|"/"|"%"|"//") factor)* - factor "/" term | - factor "%" term | - factor "//" term | +term: factor ("*" term)+ | # was (("*"|"/"|"%"|"//") factor)* + factor ("/" term)+ | + factor ("%" term)+ | + factor ("//" term)+ | ; factor: "+" factor | "-" factor | "~" factor | ; power: atom trailer+ ("**" factor)? | atom "**" factor | ; Modified: pypy/dist/pypy/rlib/parsing/test/test_ebnfparse.py ============================================================================== --- pypy/dist/pypy/rlib/parsing/test/test_ebnfparse.py (original) +++ pypy/dist/pypy/rlib/parsing/test/test_ebnfparse.py Thu Feb 8 20:18:05 2007 @@ -181,60 +181,69 @@ """) py.test.raises(AssertionError, make_parse_function, regexs, rules, True) -def test_dictparse(): - regexs, rules, ToAST = parse_ebnf(""" - QUOTED_STRING: "'[^\\']*'"; +def test_jsonparse(): + source = """ + STRING: "\\"[^\\\\"]*\\""; + NUMBER: "\-?(0|[1-9][0-9]*)(\.[0-9]+)?([eE][\+\-]?[0-9]+)?"; IGNORE: " |\n"; - data: | | ; - dict: ["{"] (dictentry [","])* dictentry ["}"]; - dictentry: QUOTED_STRING [":"] data; - list: ["["] (data [","])* data ["]"]; -""") + value: | | | | <"null"> | + <"true"> | <"false">; + object: ["{"] (entry [","])* entry ["}"]; + array: ["["] (value [","])* value ["]"]; + entry: STRING [":"] value; +""" + regexs, rules, ToAST = parse_ebnf(source) parse = make_parse_function(regexs, rules, eof=True) t = parse(""" { - 'type': 'SCRIPT', - '0': { - 'type': 'SEMICOLON', - 'end': '5', - 'expression': { - 'type': 'ASSIGN', - '0': { - 'type': 'IDENTIFIER', - 'assignOp': 'null', - 'end': '1', - 'lineno': '1', - 'start': '0', - 'tokenizer': '[object Object]', - 'value': 'x' + "type": "SCRIPT", + "0": { + "type": "SEMICOLON", + "end": "5", + "expression": { + "type": "ASSIGN", + "0": { + "type": "IDENTIFIER", + "assignOp": "null", + "end": "1", + "lineno": "1", + "start": "0", + "tokenizer": "[object Object]", + "value": "x" } , - '1': { - 'type': 'NUMBER', - 'end': '5', - 'lineno': '1', - 'start': '4', - 'tokenizer': '[object Object]', - 'value': '1' + "1": { + "type": "NUMBER", + "end": "5", + "lineno": "1", + "start": "4", + "tokenizer": "[object Object]", + "value": "1" } , - 'end': '5', - 'length': '2', - 'lineno': '1', - 'start': '0', - 'tokenizer': '[object Object]', - 'value': '=' + "end": "5", + "length": "2", + "lineno": "1", + "start": "0", + "tokenizer": "[object Object]", + "value": "=" } , - 'lineno': '1', - 'start': '0', - 'tokenizer': '[object Object]', - 'value': 'x' + "lineno": "1", + "start": "0", + "tokenizer": "[object Object]", + "value": "x" } , - 'funDecls': '', - 'length': '1', - 'lineno': '1', - 'tokenizer': '[object Object]', - 'varDecls': '' + "funDecls": "", + "length": "1", + "lineno": "1", + "tokenizer": "[object Object]", + "varDecls": "" }""") t = ToAST().transform(t) + t = parse('{"a": "5", "b": [1, null, 3, true, {"f": "g", "h": 6}]}') + print "".join(list(t.dot())) + t.view() + t = ToAST().transform(t) + print "\n".join(list(t.dot())) + t.view() def test_starparse(): regexs, rules, ToAST = parse_ebnf(""" Modified: pypy/dist/pypy/rlib/parsing/test/test_pythonparse.py ============================================================================== --- pypy/dist/pypy/rlib/parsing/test/test_pythonparse.py (original) +++ pypy/dist/pypy/rlib/parsing/test/test_pythonparse.py Thu Feb 8 20:18:05 2007 @@ -231,6 +231,14 @@ error = excinfo.value.errorinformation msg = excinfo.value.nice_error_message("", source) + def test_precedence(self): + source = """ +a = 1 - 2 - 3 +""" + t = self.parse(source) + t = self.ToAST.transform(t) + t.view() + def test_parse_this(self): s = py.magic.autopath().read() t = self.parse(s) Modified: pypy/dist/pypy/rlib/parsing/test/test_regexparse.py ============================================================================== --- pypy/dist/pypy/rlib/parsing/test/test_regexparse.py (original) +++ pypy/dist/pypy/rlib/parsing/test/test_regexparse.py Thu Feb 8 20:18:05 2007 @@ -138,3 +138,9 @@ assert r.recognize(r'"a\"b"') assert r.recognize(r'"\\\""') assert not r.recognize(r'"\\""') + +def test_number(): + r = make_runner(r"\-?(0|[1-9][0-9]*)(\.[0-9]+)?([eE][\+\-]?[0-9]+)?") + assert r.recognize("-0.912E+0001") + assert not r.recognize("-0.a912E+0001") + assert r.recognize("5") Modified: pypy/dist/pypy/rlib/parsing/tree.py ============================================================================== --- pypy/dist/pypy/rlib/parsing/tree.py (original) +++ pypy/dist/pypy/rlib/parsing/tree.py Thu Feb 8 20:18:05 2007 @@ -24,7 +24,7 @@ addinfo = str(self.additional_info).replace('"', "'") or "_" yield ('"%s" [shape=box,label="%s\\n%s"];' % ( id(self), self.symbol.replace("\\", "\\\\"), - repr(addinfo).replace("\\", "\\\\"))) + repr(addinfo).replace('"', '').replace("\\", "\\\\"))) def visit(self, visitor): "NOT_RPYTHON" From cfbolz at codespeak.net Thu Feb 8 20:23:47 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 8 Feb 2007 20:23:47 +0100 (CET) Subject: [pypy-svn] r38202 - pypy/dist/pypy/objspace/std/test Message-ID: <20070208192347.D967D1008A@code0.codespeak.net> Author: cfbolz Date: Thu Feb 8 20:23:43 2007 New Revision: 38202 Modified: pypy/dist/pypy/objspace/std/test/test_listobject.py Log: remove debug print Modified: pypy/dist/pypy/objspace/std/test/test_listobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/test/test_listobject.py (original) +++ pypy/dist/pypy/objspace/std/test/test_listobject.py Thu Feb 8 20:23:43 2007 @@ -594,5 +594,4 @@ l = [Mean2(i) for i in range(10)] # does not crash l.remove(5) - print l assert l[10:] == [0, 1, 2, 3, 4, 6, 7, 8, 9] From hpk at codespeak.net Thu Feb 8 20:48:51 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Thu, 8 Feb 2007 20:48:51 +0100 (CET) Subject: [pypy-svn] r38204 - pypy/branch/pytrunkmerge/pypy/translator/asm/ppcgen Message-ID: <20070208194851.9753210094@code0.codespeak.net> Author: hpk Date: Thu Feb 8 20:48:50 2007 New Revision: 38204 Modified: pypy/branch/pytrunkmerge/pypy/translator/asm/ppcgen/asmfunc.py pypy/branch/pytrunkmerge/pypy/translator/asm/ppcgen/symbol_lookup.py Log: adapt to getpymodule -> _getpymodule Modified: pypy/branch/pytrunkmerge/pypy/translator/asm/ppcgen/asmfunc.py ============================================================================== --- pypy/branch/pytrunkmerge/pypy/translator/asm/ppcgen/asmfunc.py (original) +++ pypy/branch/pytrunkmerge/pypy/translator/asm/ppcgen/asmfunc.py Thu Feb 8 20:48:50 2007 @@ -6,7 +6,7 @@ def get_ppcgen(): global _ppcgen if _ppcgen is None: - _ppcgen = py.magic.autopath().dirpath().join('_ppcgen.c').getpymodule() + _ppcgen = py.magic.autopath().dirpath().join('_ppcgen.c')._getpymodule() return _ppcgen class AsmCode(object): Modified: pypy/branch/pytrunkmerge/pypy/translator/asm/ppcgen/symbol_lookup.py ============================================================================== --- pypy/branch/pytrunkmerge/pypy/translator/asm/ppcgen/symbol_lookup.py (original) +++ pypy/branch/pytrunkmerge/pypy/translator/asm/ppcgen/symbol_lookup.py Thu Feb 8 20:48:50 2007 @@ -3,7 +3,7 @@ global lookup import py - _ppcgen = py.magic.autopath().dirpath().join('_ppcgen.c').getpymodule() + _ppcgen = py.magic.autopath().dirpath().join('_ppcgen.c')._getpymodule() try: from _ppcgen import NSLookupAndBindSymbol From cfbolz at codespeak.net Thu Feb 8 20:53:10 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 8 Feb 2007 20:53:10 +0100 (CET) Subject: [pypy-svn] r38205 - pypy/dist/pypy/objspace/std Message-ID: <20070208195310.8B42B10084@code0.codespeak.net> Author: cfbolz Date: Thu Feb 8 20:53:09 2007 New Revision: 38205 Modified: pypy/dist/pypy/objspace/std/strsliceobject.py Log: oops oops oops, bad plan: don't create a copy of the string again after we have forced the string slice ones. Modified: pypy/dist/pypy/objspace/std/strsliceobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/strsliceobject.py (original) +++ pypy/dist/pypy/objspace/std/strsliceobject.py Thu Feb 8 20:53:09 2007 @@ -15,6 +15,8 @@ w_self.stop = stop def force(w_self): + if w_self.start == 0 and w_self.stop == len(w_self.str): + return w_self.str str = w_self.str[w_self.start:w_self.stop] w_self.str = str w_self.start = 0 From mwh at codespeak.net Thu Feb 8 22:00:33 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Thu, 8 Feb 2007 22:00:33 +0100 (CET) Subject: [pypy-svn] r38209 - in pypy/extradoc/talk/pycon2007: . pycon07.key Message-ID: <20070208210033.3ADA810083@code0.codespeak.net> Author: mwh Date: Thu Feb 8 22:00:31 2007 New Revision: 38209 Added: pypy/extradoc/talk/pycon2007/ pypy/extradoc/talk/pycon2007/pycon07.key/ - copied from r38208, pypy/extradoc/talk/accu2006/accu-2006.key/ Log: start my pycon2007 talk by copying last years accu talk From cfbolz at codespeak.net Thu Feb 8 22:50:12 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 8 Feb 2007 22:50:12 +0100 (CET) Subject: [pypy-svn] r38211 - pypy/dist/pypy/doc Message-ID: <20070208215012.4B36D1007C@code0.codespeak.net> Author: cfbolz Date: Thu Feb 8 22:50:10 2007 New Revision: 38211 Added: pypy/dist/pypy/doc/object-optimizations.txt Log: add object optimization documentation and start writing a bit. Added: pypy/dist/pypy/doc/object-optimizations.txt ============================================================================== --- (empty file) +++ pypy/dist/pypy/doc/object-optimizations.txt Thu Feb 8 22:50:10 2007 @@ -0,0 +1,114 @@ +=================================================================== +Alternative object implementations in the PyPy standard interpreter +=================================================================== + +One of the advantages of the PyPy standard interpreter (compared to CPython) is +that we can provide several implementations of the same object (e.g. for lists +and strings) without the user noticing any difference. This makes it easy to +provide a specialized implementation of a type that is optimized for a certain +situation without disturbing the implementation for the regular case. + +We have implemented several such optimizations. Most of them are not enabled by +default. Also, it is not clear for all there optimizations whether they are +worth it in practice, for a real-world application (they sure make some +microbenchmarks a lot faster of use less memory, which is not saying too much). +If you have any observation in that direction, please let us know! + + +String optimizations +==================== + +string-join objects +------------------- + +String-join objects are a different implementation of the Python ``str`` type, +They represent the lazy addition of several strings without actually performing +the addition (which involves copying etc.). When the actual value of the string +join object is needed, the addition is performed. This makes it possible to +perform repeated string additions in a loop without using the +``"".join(list_of_strings)`` pattern. + +string-slice objects +-------------------- + +String-slice objects are another implementation of the Python ``str`` type. +They represent the lazy slicing of a string without actually performing the +slicing (which would involve copying). This is only done for slices of step +one. When the actual value of the string slice object is needed, the slicing +is done (although a lot of string methods don't make this necessary). This +makes string slicing a very efficient operation. It also saves memory in some +cases but can also lead to memory leaks, since the string slice retains a +reference to the original string (to make this a bit less likely, the slicing +is only done when the length of the slice exceeds a certain number of characters +and when the slice length is a significant amount of the original string's +length). + +Integer optimizations +===================== + +caching small integers +---------------------- + +integers as tagged pointers +--------------------------- + +Dictionary optimizations +======================== + +string-keyed dictionaries +------------------------- + +String-keyed dictionaries are an alternate implmentation of the ``dict`` type. +These dictionaries are optimized for string keys, which is obviously a big win +for most Python programs. As soon as one non-string key is stored in the dict +the whole information in the string-keyed dictionary is copied over into another +RPython-dictionary, where arbitrary Python objects can be used as keys. + +multi-dicts +----------- + +Multi-dicts are another special implementation of dictionaries. While +implementing the string-keyed dictionaries it became clear that it is very +useful to *change* the internal representation of an object during its lifetime. +String-keyed dictionaries already do that in a limited way (changing the +representation from a string-to-object mapping to an object-to-object mapping). +Multi-Dicts are way more general in providing support for this switching of +representations for dicts in a rather general way. + +If you just enable multi-dicts, special representations for empty dictionaries, +for string-keyed dictionaries and for small dictionaries are used (as well as a +general representation that can store arbitrary keys). In addition there are +more specialized dictionary implementations for various purposes (see below). + + +sharing dicts +------------- + +Sharing dictionaries are a special representation used together with multidicts. +This dict representation is used only for instance dictionaries and tries to +make instance dictionaries use less memory (in fact, in the ideal case the +memory behaviour should be mostly like that of using __slots__). + +The idea is the following: Most instances of the same class have very similar +attributes, and are even adding these keys to the dictionary in the same order +while ``__init__`` is being executed. That means that all the dictionaries of +these instances look very similar: they have the same set of keys with different +values per instance. What sharing dicts do is store these common keys into a +common structure object and thus safe the space in the individual instance dict: +the representation of the instance dict contains only a list of values. + +builtin-shadowing +----------------- + +List optimizations +================== + +range-lists +----------- + +multi-lists +----------- + +General type optimizations +========================== + From cfbolz at codespeak.net Fri Feb 9 00:44:03 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 9 Feb 2007 00:44:03 +0100 (CET) Subject: [pypy-svn] r38222 - pypy/dist/pypy/doc Message-ID: <20070208234403.9F57E10088@code0.codespeak.net> Author: cfbolz Date: Fri Feb 9 00:43:57 2007 New Revision: 38222 Modified: pypy/dist/pypy/doc/object-optimizations.txt Log: describe more object optimizations Modified: pypy/dist/pypy/doc/object-optimizations.txt ============================================================================== --- pypy/dist/pypy/doc/object-optimizations.txt (original) +++ pypy/dist/pypy/doc/object-optimizations.txt Fri Feb 9 00:43:57 2007 @@ -12,7 +12,10 @@ default. Also, it is not clear for all there optimizations whether they are worth it in practice, for a real-world application (they sure make some microbenchmarks a lot faster of use less memory, which is not saying too much). -If you have any observation in that direction, please let us know! +If you have any observation in that direction, please let us know! By the way: +alternative object implementations are a great way to get into PyPy development +since you have to know only a rather small part of PyPy to do them. And they are +fun too! String optimizations @@ -49,9 +52,23 @@ caching small integers ---------------------- +Similar to what CPython does it is possible to enable caching of small integer +objects to not have to allocate all the time when doing simple arithmetic. Every +time a new integer object is created it is checked whether the integer is small +enough to be retrieved from the cache. + + integers as tagged pointers --------------------------- +An even more aggressive way to save memory when using integers is "small int" +integer implementation. It is another integer implementation used for integers +that only need 31 bits (respective 63 bits on an 64 bit machine). These integers +are represented as tagged pointers by setting their lowest bits to distinguish +them from normal pointers. This makes boxing of these integers use no memory at +all. + + Dictionary optimizations ======================== @@ -60,7 +77,8 @@ String-keyed dictionaries are an alternate implmentation of the ``dict`` type. These dictionaries are optimized for string keys, which is obviously a big win -for most Python programs. As soon as one non-string key is stored in the dict +for all but the most contrived Python programs. As soon as one non-string key +is stored in the dict the whole information in the string-keyed dictionary is copied over into another RPython-dictionary, where arbitrary Python objects can be used as keys. @@ -97,18 +115,98 @@ common structure object and thus safe the space in the individual instance dict: the representation of the instance dict contains only a list of values. + builtin-shadowing ----------------- +Usually the calling of builtins in Python requires two dictionary lookups: first +to see whether the current global dictionary contains an object with the same +name, then a lookup in the ``__builtin__`` dictionary. This is somehow +circumvented by storing an often used builtin into a local variable to get +the fast local lookup (which is a rather strange and ugly hack). + +The same problem is solved in a different way by "wary" dictionaries. They are +another dictionary representation used together with multidicts. This +representation is used only for module dictionaries. The repesentation checks on +every setitem whether the key that is used is the name of a builtin. If this is +the case, the dictionary is marked as shadowing that particular builtin. + +To identify calls to builtins easily, a new bytecode (``CALL_LIKELY_BUILTIN``) +is introduced. Whenever it is executed, the globals dictionary is checked +whether it masks the builtin (which is possible without a dictionary lookup). +Then the ``__builtin__`` dict is checked whether somebody replaced the real +builtin with something else in the same way. If both these conditions are not +met, the proper builtin is called, using no dictionary lookup at all. + List optimizations ================== range-lists ----------- +Range-lists solve the same problem that the ``xrange`` builtin solves poorly: +the problem that ``range`` allocates memory even if the resulting list is only +ever used for iterating over it. Range lists are a different implementation for +lists. They are created only as a result of a call to ``range``. As long as the +resulting list is used without being mutated, the list stores only start, stop +and step of the range. Only when somebody mutates the list the actual list is +created. This gives the memory and speed behaviour of ``xrange`` and the general +of use of ``range``. + + multi-lists ----------- -General type optimizations -========================== +As with dictionaries it became clear that it is generally useful to allow lists +to change their internal representation over their lifetime. Therefore +multi-lists were implemented, mostly equivalently to multi-dicts. The special +representations you get by default are for empty lists, for lists containing +only strings and ranges again (the reason why range lists and multilists both +implement the same optimization is that range lists came earlier and that +multi-lists are not tried that much so far). + + +fast list slicing +------------------ + +A rather experimental special list representation used with multilists is the +slice list (the original idea is from `Neal Norwitz on pypy-dev`_). The +observation is that slices are often created for iterating over them, so it +seems wasteful to create a full copy of that portion of the list. Instead the +list slice is only created lazily, that is when the original list or the sliced +list are mutated. + + +.. _`Neal Norwitz on pypy-dev`: http://codespeak.net/pipermail/pypy-dev/2005q4/002538.html + + +User class optimizations +======================== + +Shadow tracking +--------------- +Shadow tracking is a general optimization that speeds up method calls for user +classes (that don't have special meta-class). For this a special dict +representation is used together with multidicts. This dict representation is +used only for instance dictionaries. The instance dictionary tracks whether an +instance attribute shadows an attribute of its class. This makes method calls +slightly faster in the following way: When calling a method the first thing that +is checked is the class dictionary to find descriptors. Normally, when a method +is found, the instance dictionary is then checked for instance attributes +shadowing the class attribute. If we know that there is no shadowing (since +instance dict tells us that) we can save this lookup on the instance dictionary. + + +Method caching +-------------- + +Shadow tracking is also an important building block for the method caching +optimization. A method cache is introduced where the result of a method lookup +is stored (which involves potentially many lookups in the base classes of a +class). Entries in the method cache are stored using a hash consisting of the +hash of the name being looked up, the call site (e.g. the bytecode object and +the currend program counter) and a special "version" of the type where the +lookup happens (that version is incremented every time the type or one of its +base classes is changed). On subsequent lookups the cached version can be used +(at least if the instance did not shadow any of its classes attributes). From hpk at codespeak.net Fri Feb 9 01:11:52 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Fri, 9 Feb 2007 01:11:52 +0100 (CET) Subject: [pypy-svn] r38225 - in pypy/dist/pypy: . lang/js/test tool/pytest tool/test translator/asm/ppcgen Message-ID: <20070209001152.1B8611007C@code0.codespeak.net> Author: hpk Date: Fri Feb 9 01:11:47 2007 New Revision: 38225 Modified: pypy/dist/pypy/conftest.py pypy/dist/pypy/lang/js/test/test_interp.py pypy/dist/pypy/tool/pytest/appsupport.py pypy/dist/pypy/tool/test/test_conftest1.py pypy/dist/pypy/translator/asm/ppcgen/asmfunc.py pypy/dist/pypy/translator/asm/ppcgen/symbol_lookup.py Log: adapting to changes coming from the py-trunk/dist merge Modified: pypy/dist/pypy/conftest.py ============================================================================== --- pypy/dist/pypy/conftest.py (original) +++ pypy/dist/pypy/conftest.py Fri Feb 9 01:11:47 2007 @@ -7,6 +7,9 @@ rootdir = py.magic.autopath().dirpath() +dist_rsync_roots = ['.', '../lib-python', '../py', '../demo'] +dist_rsync_ignore = ['_cache'] + # # PyPy's command line extra options (these are added # to py.test's standard options) @@ -221,10 +224,10 @@ _pygame_imported = False class IntTestFunction(PyPyTestFunction): - def haskeyword(self, keyword): + def _haskeyword(self, keyword): if keyword == 'interplevel': return True - return super(IntTestFunction, self).haskeyword(keyword) + return super(IntTestFunction, self)._haskeyword(keyword) def execute(self, target, *args): co = target.func_code @@ -254,8 +257,8 @@ "if conftest.option.view is False") class AppTestFunction(PyPyTestFunction): - def haskeyword(self, keyword): - return keyword == 'applevel' or super(AppTestFunction, self).haskeyword(keyword) + def _haskeyword(self, keyword): + return keyword == 'applevel' or super(AppTestFunction, self)._haskeyword(keyword) def execute(self, target, *args): assert not args @@ -302,9 +305,9 @@ class IntClassCollector(PyPyClassCollector): Function = IntTestFunction - def haskeyword(self, keyword): + def _haskeyword(self, keyword): return keyword == 'interplevel' or \ - super(IntClassCollector, self).haskeyword(keyword) + super(IntClassCollector, self)._haskeyword(keyword) class AppClassInstance(py.test.collect.Instance): Function = AppTestMethod @@ -322,12 +325,12 @@ class AppClassCollector(PyPyClassCollector): Instance = AppClassInstance - def haskeyword(self, keyword): + def _haskeyword(self, keyword): return keyword == 'applevel' or \ - super(AppClassCollector, self).haskeyword(keyword) + super(AppClassCollector, self)._haskeyword(keyword) def setup(self): - super(AppClassCollector, self).setup() + super(AppClassCollector, self).setup() cls = self.obj space = cls.space clsname = cls.__name__ Modified: pypy/dist/pypy/lang/js/test/test_interp.py ============================================================================== --- pypy/dist/pypy/lang/js/test/test_interp.py (original) +++ pypy/dist/pypy/lang/js/test/test_interp.py Fri Feb 9 01:11:47 2007 @@ -454,4 +454,3 @@ def test_unary_plus(self): self.assert_prints("print(+1)", ['1']) - Modified: pypy/dist/pypy/tool/pytest/appsupport.py ============================================================================== --- pypy/dist/pypy/tool/pytest/appsupport.py (original) +++ pypy/dist/pypy/tool/pytest/appsupport.py Fri Feb 9 01:11:47 2007 @@ -4,6 +4,7 @@ from py.__.magic import exprinfo from pypy.interpreter import gateway from pypy.interpreter.error import OperationError +from py.__.test.outcome import ExceptionFailure # ____________________________________________________________ @@ -212,7 +213,7 @@ if not value.match(space, w_ExpectedException): raise type, value, tb return excinfo - except py.test.Item.ExceptionFailure, e: + except ExceptionFailure, e: e.tbindex = getattr(e, 'tbindex', -1) - 1 raise Modified: pypy/dist/pypy/tool/test/test_conftest1.py ============================================================================== --- pypy/dist/pypy/tool/test/test_conftest1.py (original) +++ pypy/dist/pypy/tool/test/test_conftest1.py Fri Feb 9 01:11:47 2007 @@ -3,19 +3,20 @@ innertest = py.magic.autopath().dirpath('conftest1_innertest.py') from py.__.test.terminal.terminal import TerminalSession +from py.__.test.outcome import Passed, Failed, Skipped class TestPyPyTests: def test_select_interplevel(self): config = py.test.config._reparse([innertest, '-k', 'interplevel']) session = TerminalSession(config, py.std.sys.stdout) session.main() - l = session.getitemoutcomepairs(py.test.Item.Passed) + l = session.getitemoutcomepairs(Passed) assert len(l) == 2 for item in l: assert item[0].name in ('test_something', 'test_method') #item = l[0][0] #assert item.name == 'test_one' - l = session.getitemoutcomepairs(py.test.Item.Skipped) + l = session.getitemoutcomepairs(Skipped) assert len(l) == 2 for item in l: assert item[0].name in ('app_test_something', 'test_method_app') @@ -24,13 +25,13 @@ config = py.test.config._reparse([innertest, '-k', 'applevel']) session = TerminalSession(config, py.std.sys.stdout) session.main() - l = session.getitemoutcomepairs(py.test.Item.Passed) + l = session.getitemoutcomepairs(Passed) assert len(l) == 2 for item in l: assert item[0].name in ('app_test_something', 'test_method_app') #item = l[0][0] #assert item.name == 'test_one' - l = session.getitemoutcomepairs(py.test.Item.Skipped) + l = session.getitemoutcomepairs(Skipped) assert len(l) == 2 for item in l: assert item[0].name in ('test_something', 'test_method') @@ -40,13 +41,13 @@ '-k', 'applevel', '--appdirect']) session = TerminalSession(config, py.std.sys.stdout) session.main() - l = session.getitemoutcomepairs(py.test.Item.Passed) + l = session.getitemoutcomepairs(Passed) assert len(l) == 2 for item in l: assert item[0].name in ('app_test_something', 'test_method_app') #item = l[0][0] #assert item.name == 'test_one' - l = session.getitemoutcomepairs(py.test.Item.Skipped) + l = session.getitemoutcomepairs(Skipped) assert len(l) == 2 for item in l: assert item[0].name in ('test_something', 'test_method') 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 Fri Feb 9 01:11:47 2007 @@ -6,7 +6,7 @@ def get_ppcgen(): global _ppcgen if _ppcgen is None: - _ppcgen = py.magic.autopath().dirpath().join('_ppcgen.c').getpymodule() + _ppcgen = py.magic.autopath().dirpath().join('_ppcgen.c')._getpymodule() return _ppcgen class AsmCode(object): 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 Fri Feb 9 01:11:47 2007 @@ -3,7 +3,7 @@ global lookup import py - _ppcgen = py.magic.autopath().dirpath().join('_ppcgen.c').getpymodule() + _ppcgen = py.magic.autopath().dirpath().join('_ppcgen.c')._getpymodule() try: from _ppcgen import NSLookupAndBindSymbol From antocuni at codespeak.net Fri Feb 9 10:42:26 2007 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Fri, 9 Feb 2007 10:42:26 +0100 (CET) Subject: [pypy-svn] r38230 - pypy/dist/pypy/translator/cli Message-ID: <20070209094226.887641007C@code0.codespeak.net> Author: antocuni Date: Fri Feb 9 10:42:25 2007 New Revision: 38230 Modified: pypy/dist/pypy/translator/cli/class_.py Log: Fix both test_overridden_classattr_as_defaults and the translation on windows. Modified: pypy/dist/pypy/translator/cli/class_.py ============================================================================== --- pypy/dist/pypy/translator/cli/class_.py (original) +++ pypy/dist/pypy/translator/cli/class_.py Fri Feb 9 10:42:25 2007 @@ -134,9 +134,10 @@ cts_type = self.cts.lltype_to_cts(F_TYPE) f_name = self.cts.escape_name(f_name) if cts_type != 'void': + INSTANCE_DEF, _ = self.INSTANCE._lookup_field(f_name) self.ilasm.opcode('ldarg.0') push_constant(self.db, F_TYPE, f_default, self.gen) - class_name = self.db.class_name(self.INSTANCE) + class_name = self.db.class_name(INSTANCE_DEF) self.ilasm.set_field((cts_type, class_name, f_name)) self.ilasm.opcode('ret') From antocuni at codespeak.net Fri Feb 9 11:41:57 2007 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Fri, 9 Feb 2007 11:41:57 +0100 (CET) Subject: [pypy-svn] r38231 - pypy/dist/pypy/tool/pytest Message-ID: <20070209104157.9F1BB10094@code0.codespeak.net> Author: antocuni Date: Fri Feb 9 11:41:56 2007 New Revision: 38231 Modified: pypy/dist/pypy/tool/pytest/result.py Log: Don't miss tests whose outcome is FAIL. Modified: pypy/dist/pypy/tool/pytest/result.py ============================================================================== --- pypy/dist/pypy/tool/pytest/result.py (original) +++ pypy/dist/pypy/tool/pytest/result.py Fri Feb 9 11:41:56 2007 @@ -103,7 +103,7 @@ return self['outcome'].lower() == 'ok' def iserror(self): - return self['outcome'].lower()[:3] == 'err' + return self['outcome'].lower()[:3] == 'err' or self['outcome'].lower() == 'fail' def istimeout(self): return self['outcome'].lower() == 't/o' From antocuni at codespeak.net Fri Feb 9 11:45:40 2007 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Fri, 9 Feb 2007 11:45:40 +0100 (CET) Subject: [pypy-svn] r38232 - pypy/dist/lib-python Message-ID: <20070209104540.6E7961006F@code0.codespeak.net> Author: antocuni Date: Fri Feb 9 11:45:39 2007 New Revision: 38232 Modified: pypy/dist/lib-python/conftest.py Log: - on windows sysexec return value contains \r\n instead of \n. Strip the lines to remove potential \r. - don't remove 'rev' from info, because it will be needed also later. Modified: pypy/dist/lib-python/conftest.py ============================================================================== --- pypy/dist/lib-python/conftest.py (original) +++ pypy/dist/lib-python/conftest.py Fri Feb 9 11:45:39 2007 @@ -812,7 +812,7 @@ 'print sys.version; ' 'print sys.pypy_svn_url; ' 'print sys.pypy_translation_info; ') - lines = text.split('\n') + lines = [line.strip() for line in text.split('\n')] assert len(lines) == 4 and lines[3] == '' assert lines[2].startswith('{') and lines[2].endswith('}') info = eval(lines[2]) @@ -976,7 +976,7 @@ result['pypy-revision'] = getrev(pypydir) if option.use_compiled: execpath, info = getexecutable() - result['pypy-revision'] = info.pop('rev') + result['pypy-revision'] = info['rev'] # info.pop('rev') result['executable'] = execpath.basename for key, value in info.items(): result['executable-%s' % key] = str(value) From arigo at codespeak.net Fri Feb 9 12:56:16 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 9 Feb 2007 12:56:16 +0100 (CET) Subject: [pypy-svn] r38236 - pypy/dist/pypy/objspace Message-ID: <20070209115616.D64BE10093@code0.codespeak.net> Author: arigo Date: Fri Feb 9 12:56:11 2007 New Revision: 38236 Modified: pypy/dist/pypy/objspace/thunk.py Log: Fix a not-really-broken-but-strange import. Modified: pypy/dist/pypy/objspace/thunk.py ============================================================================== --- pypy/dist/pypy/objspace/thunk.py (original) +++ pypy/dist/pypy/objspace/thunk.py Fri Feb 9 12:56:11 2007 @@ -31,7 +31,7 @@ from pypy.objspace.proxy import patch_space_in_place from pypy.interpreter import gateway, baseobjspace, argument from pypy.interpreter.error import OperationError -from pypy.interpreter.typedef import Method +from pypy.interpreter.function import Method # __________________________________________________________________________ From arigo at codespeak.net Fri Feb 9 12:57:47 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 9 Feb 2007 12:57:47 +0100 (CET) Subject: [pypy-svn] r38237 - in pypy/dist/pypy/objspace: . test Message-ID: <20070209115747.9886710095@code0.codespeak.net> Author: arigo Date: Fri Feb 9 12:57:37 2007 New Revision: 38237 Added: pypy/dist/pypy/objspace/test/test_taintobjspace.py (contents, props changed) Modified: pypy/dist/pypy/objspace/taint.py Log: * Tests for the taint space. * Add a taint_mode decorator, to mark "trusted" functions. * Add a taint_debug - it's hard to debug failing taint_mode functions without this... Modified: pypy/dist/pypy/objspace/taint.py ============================================================================== --- pypy/dist/pypy/objspace/taint.py (original) +++ pypy/dist/pypy/objspace/taint.py Fri Feb 9 12:57:37 2007 @@ -1,11 +1,13 @@ """ Just an experiment. """ +import os from pypy.objspace.std.objspace import StdObjSpace from pypy.objspace.proxy import patch_space_in_place from pypy.objspace.thunk import nb_forcing_args from pypy.interpreter.error import OperationError -from pypy.interpreter import baseobjspace, gateway +from pypy.interpreter import baseobjspace, gateway, executioncontext +from pypy.interpreter.function import Method from pypy.tool.sourcetools import func_with_new_name from pypy.rlib.unroll import unrolling_iterable @@ -29,12 +31,15 @@ ## ... class W_TaintBomb(baseobjspace.W_Root): - def __init__(self, operr): + def __init__(self, space, operr): + if get_debug_level(space) > 0: + debug_bomb(space, operr) + self.space = space self.operr = operr - def explode(self, space): - msg = self.operr.errorstr(space) - raise OperationError(space.w_TaintError, space.w_None) # space.wrap(msg)) + def explode(self): + #msg = self.operr.errorstr(space) + raise OperationError(self.space.w_TaintError, self.space.w_None) def taint(w_obj): @@ -46,29 +51,100 @@ app_taint = gateway.interp2app(taint) def is_tainted(space, w_obj): - res = isinstance(w_obj, W_Tainted) + res = isinstance(w_obj, W_Tainted) or isinstance(w_obj, W_TaintBomb) return space.wrap(res) app_is_tainted = gateway.interp2app(is_tainted) -def untaint(space, w_obj, w_expectedtype): +def untaint(space, w_expectedtype, w_obj): + if (isinstance(w_expectedtype, W_Tainted) or + isinstance(w_expectedtype, W_TaintBomb)): + raise OperationError(space.w_TypeError, + space.wrap("untaint() arg 1 must be an untainted type")) + if not space.is_true(space.isinstance(w_expectedtype, space.w_type)): + raise OperationError(space.w_TypeError, + space.wrap("untaint() arg 1 must be a type")) if isinstance(w_obj, W_Tainted): w_obj = w_obj.w_obj elif isinstance(w_obj, W_TaintBomb): - w_obj.explode(space) + w_obj.explode() #if isinstance(w_expectedtype, W_Tainted): # w_expectedtype = w_expectedtype.w_obj w_realtype = space.type(w_obj) if not space.is_w(w_realtype, w_expectedtype): - msg = "expected an object of type '%s', got '%s'" % ( - w_expectedtype.getname(space, '?'), - w_realtype.getname(space, '?')) - raise OperationError(space.w_TaintError, - space.wrap(msg)) + #msg = "expected an object of type '%s'" % ( + # w_expectedtype.getname(space, '?'),) + # #w_realtype.getname(space, '?')) + raise OperationError(space.w_TaintError, space.w_None) return w_obj app_untaint = gateway.interp2app(untaint) # ____________________________________________________________ +executioncontext.ExecutionContext.is_taint_mode = False + +def taint_mode_function(space, w_func, __args__): + ec = space.getexecutioncontext() + old_auth = ec.is_taint_mode + try: + ec.is_taint_mode = True + try: + w_res = space.call_args(w_func, __args__) + except OperationError, operr: + if old_auth: + raise + w_res = W_TaintBomb(space, operr) + else: + if not old_auth: + w_res = taint(w_res) + finally: + ec.is_taint_mode = old_auth + return w_res + +app_taint_mode_function = gateway.interp2app( + taint_mode_function, + unwrap_spec=[gateway.ObjSpace, gateway.W_Root, gateway.Arguments]) + +def taint_mode(space, w_callable): + meth = Method(space, space.wrap(app_taint_mode_function), + w_callable, space.type(w_callable)) + return space.wrap(meth) +app_taint_mode = gateway.interp2app(taint_mode) + +def have_taint_mode(space): + return space.getexecutioncontext().is_taint_mode + +# ____________________________________________________________ + +executioncontext.ExecutionContext.taint_debug = 0 + +def taint_debug(space, level): + space.getexecutioncontext().taint_debug = level +app_taint_debug = gateway.interp2app(taint_debug, + unwrap_spec=[gateway.ObjSpace, int]) + +def get_debug_level(space): + return space.getexecutioncontext().taint_debug + +def debug_bomb(space, operr): + from pypy.interpreter.pyframe import PyFrame + ec = space.getexecutioncontext() + filename = '?' + codename = '?' + codeline = 0 + try: + frame = ec.framestack.top() + except IndexError: + pass + else: + if isinstance(frame, PyFrame): + filename = frame.pycode.co_filename + codename = frame.pycode.co_name + codeline = frame.get_last_lineno() + os.write(2, 'Taint Bomb in file "%s", line %d, in %s\n %s\n' % ( + filename, codeline, codename, operr.errorstr(space))) + +# ____________________________________________________________ + class TaintSpace(StdObjSpace): @@ -86,6 +162,12 @@ self.wrap(app_is_tainted)) self.setattr(w_pypymagic, self.wrap('untaint'), self.wrap(app_untaint)) + self.setattr(w_pypymagic, self.wrap('taint_mode'), + self.wrap(app_taint_mode)) + self.setattr(w_pypymagic, self.wrap('TaintError'), + self.w_TaintError) + self.setattr(w_pypymagic, self.wrap('taint_debug'), + self.wrap(app_taint_debug)) patch_space_in_place(self, 'taint', proxymaker) @@ -93,13 +175,18 @@ def tainted_error(space, name): - msg = "operation '%s' forbidden on tainted object" % (name,) - raise OperationError(space.w_TaintError, space.wrap(msg)) + #msg = "operation '%s' forbidden on tainted object" % (name,) + raise OperationError(space.w_TaintError, space.w_None)# space.wrap(msg)) RegularMethods = dict.fromkeys( [name for name, _, _, _ in baseobjspace.ObjSpace.MethodTable]) +TaintResultIrregularMethods = dict.fromkeys( + ['wrap', 'call_args'] + + [name for name in baseobjspace.ObjSpace.IrregularOpTable + if name.startswith('new')]) + def proxymaker(space, name, parentfn): arity = nb_forcing_args[name] indices = unrolling_iterable(range(arity)) @@ -114,17 +201,22 @@ tainted = True w_arg = w_arg.w_obj elif isinstance(w_arg, W_TaintBomb): + if have_taint_mode(space): + raise OperationError, w_arg.operr return w_arg newargs_w += (w_arg,) newargs_w += args_w[arity:] try: w_res = parentfn(*newargs_w) - except OperationError, e: + except OperationError, operr: if not tainted: raise - return W_TaintBomb(e) + return W_TaintBomb(space, operr) if tainted: - w_res = taint(w_res) + if name == 'type' and have_taint_mode(space): + pass + else: + w_res = taint(w_res) return w_res elif arity == 0: @@ -133,13 +225,22 @@ else: def proxy(*args_w): + newargs_w = () for i in indices: w_arg = args_w[i] if isinstance(w_arg, W_Tainted): - tainted_error(space, name) + if have_taint_mode(space): + w_arg = w_arg.w_obj + else: + tainted_error(space, name) elif isinstance(w_arg, W_TaintBomb): - w_arg.explode(space) - return parentfn(*args_w) + if have_taint_mode(space): + raise OperationError, w_arg.operr + else: + w_arg.explode() + newargs_w += (w_arg,) + newargs_w += args_w[arity:] + return parentfn(*newargs_w) proxy = func_with_new_name(proxy, '%s_proxy' % name) return proxy Added: pypy/dist/pypy/objspace/test/test_taintobjspace.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/objspace/test/test_taintobjspace.py Fri Feb 9 12:57:37 2007 @@ -0,0 +1,74 @@ +from pypy.conftest import gettestobjspace + +class AppTest_Taint: + + def setup_class(cls): + cls.space = gettestobjspace('taint') + + def test_simple(self): + from pypymagic import taint, untaint, TaintError + x = taint(6) + x = x * 7 + raises(TaintError, "if x: y = 1") + t = type(x) + raises(TaintError, "if t is int: y = 1") + assert untaint(int, x) == 42 + raises(TaintError, "untaint(float, x)") + + def test_bomb(self): + from pypymagic import taint, untaint, TaintError + x = taint(6) + x = x / 0 + raises(TaintError, "if x: y = 1") + t = type(x) + raises(TaintError, "if t is int: y = 1") + raises(TaintError, "untaint(int, x)") + raises(TaintError, "untaint(float, x)") + + def test_taint_mode(self): + from pypymagic import taint, untaint, TaintError, taint_mode + x = taint(6) + x *= 7 + + def dummy(x): + if x > 40: + return 5 + else: + return 3 + dummy = taint_mode(dummy) + + y = dummy(x) + raises(TaintError, "if y == 3: z = 1") + assert untaint(int, y) == 5 + + def test_taint_mode_exception(self): + from pypymagic import taint, untaint, TaintError, taint_mode + x = taint(6) + x *= 7 + + def dummy(x): + if x + "world" == "hello world": + return 5 + else: + return 3 + dummy = taint_mode(dummy) + + y = dummy(x) + raises(TaintError, "if y == 3: z = 1") + raises(TaintError, "untaint(int, y)") + + def test_taint_mode_incoming_bomb(self): + from pypymagic import taint, untaint, TaintError, taint_mode + x = taint(6) + x /= 0 + + def dummy(x): + if x > 40: + return 5 + else: + return 3 + dummy = taint_mode(dummy) + + y = dummy(x) + raises(TaintError, "if y == 3: z = 1") + raises(TaintError, "untaint(int, y)") From pedronis at codespeak.net Fri Feb 9 13:07:48 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Fri, 9 Feb 2007 13:07:48 +0100 (CET) Subject: [pypy-svn] r38238 - pypy/dist/lib-python Message-ID: <20070209120748.4527C10098@code0.codespeak.net> Author: pedronis Date: Fri Feb 9 13:07:44 2007 New Revision: 38238 Modified: pypy/dist/lib-python/conftest.py Log: this private import from the py lib was not used Modified: pypy/dist/lib-python/conftest.py ============================================================================== --- pypy/dist/lib-python/conftest.py (original) +++ pypy/dist/lib-python/conftest.py Fri Feb 9 13:07:44 2007 @@ -11,7 +11,6 @@ from pypy.interpreter.error import OperationError from pypy.interpreter.module import Module as PyPyModule from pypy.interpreter.main import run_string, run_file -from py.__.misc.simplecapture import callcapture # the following adds command line options as a side effect! from pypy.conftest import gettestobjspace, option as pypy_option From pedronis at codespeak.net Fri Feb 9 13:14:02 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Fri, 9 Feb 2007 13:14:02 +0100 (CET) Subject: [pypy-svn] r38239 - pypy/dist/lib-python Message-ID: <20070209121402.780D610098@code0.codespeak.net> Author: pedronis Date: Fri Feb 9 13:13:56 2007 New Revision: 38239 Modified: pypy/dist/lib-python/conftest.py Log: don't put dup revision info in the result Modified: pypy/dist/lib-python/conftest.py ============================================================================== --- pypy/dist/lib-python/conftest.py (original) +++ pypy/dist/lib-python/conftest.py Fri Feb 9 13:13:56 2007 @@ -975,9 +975,11 @@ result['pypy-revision'] = getrev(pypydir) if option.use_compiled: execpath, info = getexecutable() - result['pypy-revision'] = info['rev'] # info.pop('rev') + result['pypy-revision'] = info['rev'] result['executable'] = execpath.basename for key, value in info.items(): + if key == 'rev': + continue result['executable-%s' % key] = str(value) else: result['executable'] = 'py.py' From pedronis at codespeak.net Fri Feb 9 13:40:48 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Fri, 9 Feb 2007 13:40:48 +0100 (CET) Subject: [pypy-svn] r38243 - pypy/dist/lib-python Message-ID: <20070209124048.9D0D91009B@code0.codespeak.net> Author: pedronis Date: Fri Feb 9 13:40:45 2007 New Revision: 38243 Modified: pypy/dist/lib-python/conftest.py Log: don't skip tests requiring old-style classess if the pypy-c was compiled with them as default. Modified: pypy/dist/lib-python/conftest.py ============================================================================== --- pypy/dist/lib-python/conftest.py (original) +++ pypy/dist/lib-python/conftest.py Fri Feb 9 13:40:45 2007 @@ -883,10 +883,13 @@ alarm_script = pypydir.join('tool', 'alarm.py') regr_script = pypydir.join('tool', 'pytest', 'run-script', 'regrverbose.py') + if option.use_compiled: + execpath, info = getexecutable() pypy_options = [] if regrtest.oldstyle: - if option.use_compiled: - py.test.skip("old-style classes not available in pypy-c") + if (option.use_compiled and + not info.get('objspace.std.oldstyle', False)): + py.test.skip("old-style classes not available with this pypy-c") pypy_options.append('--oldstyle') if regrtest.compiler: pypy_options.append('--compiler=%s' % regrtest.compiler) @@ -902,7 +905,6 @@ TIMEOUT = gettimeout() if option.use_compiled: - execpath, info = getexecutable() cmd = "%s %s %s %s" %( execpath, regrrun, regrrun_verbosity, fspath.purebasename) From arigo at codespeak.net Fri Feb 9 13:41:18 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 9 Feb 2007 13:41:18 +0100 (CET) Subject: [pypy-svn] r38244 - in pypy/dist/pypy/objspace: . test Message-ID: <20070209124118.5FD191009D@code0.codespeak.net> Author: arigo Date: Fri Feb 9 13:41:12 2007 New Revision: 38244 Modified: pypy/dist/pypy/objspace/taint.py pypy/dist/pypy/objspace/test/test_taintobjspace.py Log: Remove the slightly complicated "taint mode", and replace it with "taint_atomic". Modified: pypy/dist/pypy/objspace/taint.py ============================================================================== --- pypy/dist/pypy/objspace/taint.py (original) +++ pypy/dist/pypy/objspace/taint.py Fri Feb 9 13:41:12 2007 @@ -80,38 +80,36 @@ # ____________________________________________________________ -executioncontext.ExecutionContext.is_taint_mode = False - -def taint_mode_function(space, w_func, __args__): - ec = space.getexecutioncontext() - old_auth = ec.is_taint_mode +def taint_atomic_function(space, w_func, args_w): + newargs_w = [] + tainted = False + for w_arg in args_w: + if isinstance(w_arg, W_Tainted): + tainted = True + w_arg = w_arg.w_obj + elif isinstance(w_arg, W_TaintBomb): + return w_arg + newargs_w.append(w_arg) + w_newargs = space.newtuple(newargs_w) try: - ec.is_taint_mode = True - try: - w_res = space.call_args(w_func, __args__) - except OperationError, operr: - if old_auth: - raise - w_res = W_TaintBomb(space, operr) - else: - if not old_auth: - w_res = taint(w_res) - finally: - ec.is_taint_mode = old_auth + w_res = space.call(w_func, w_newargs) + except OperationError, operr: + if not tainted: + raise + return W_TaintBomb(space, operr) + if tainted: + w_res = taint(w_res) return w_res -app_taint_mode_function = gateway.interp2app( - taint_mode_function, - unwrap_spec=[gateway.ObjSpace, gateway.W_Root, gateway.Arguments]) +app_taint_atomic_function = gateway.interp2app( + taint_atomic_function, + unwrap_spec=[gateway.ObjSpace, gateway.W_Root, 'args_w']) -def taint_mode(space, w_callable): - meth = Method(space, space.wrap(app_taint_mode_function), +def taint_atomic(space, w_callable): + meth = Method(space, space.wrap(app_taint_atomic_function), w_callable, space.type(w_callable)) return space.wrap(meth) -app_taint_mode = gateway.interp2app(taint_mode) - -def have_taint_mode(space): - return space.getexecutioncontext().is_taint_mode +app_taint_atomic = gateway.interp2app(taint_atomic) # ____________________________________________________________ @@ -162,8 +160,8 @@ self.wrap(app_is_tainted)) self.setattr(w_pypymagic, self.wrap('untaint'), self.wrap(app_untaint)) - self.setattr(w_pypymagic, self.wrap('taint_mode'), - self.wrap(app_taint_mode)) + self.setattr(w_pypymagic, self.wrap('taint_atomic'), + self.wrap(app_taint_atomic)) self.setattr(w_pypymagic, self.wrap('TaintError'), self.w_TaintError) self.setattr(w_pypymagic, self.wrap('taint_debug'), @@ -201,8 +199,6 @@ tainted = True w_arg = w_arg.w_obj elif isinstance(w_arg, W_TaintBomb): - if have_taint_mode(space): - raise OperationError, w_arg.operr return w_arg newargs_w += (w_arg,) newargs_w += args_w[arity:] @@ -213,10 +209,7 @@ raise return W_TaintBomb(space, operr) if tainted: - if name == 'type' and have_taint_mode(space): - pass - else: - w_res = taint(w_res) + w_res = taint(w_res) return w_res elif arity == 0: @@ -225,22 +218,13 @@ else: def proxy(*args_w): - newargs_w = () for i in indices: w_arg = args_w[i] if isinstance(w_arg, W_Tainted): - if have_taint_mode(space): - w_arg = w_arg.w_obj - else: - tainted_error(space, name) + tainted_error(space, name) elif isinstance(w_arg, W_TaintBomb): - if have_taint_mode(space): - raise OperationError, w_arg.operr - else: - w_arg.explode() - newargs_w += (w_arg,) - newargs_w += args_w[arity:] - return parentfn(*newargs_w) + w_arg.explode() + return parentfn(*args_w) proxy = func_with_new_name(proxy, '%s_proxy' % name) return proxy Modified: pypy/dist/pypy/objspace/test/test_taintobjspace.py ============================================================================== --- pypy/dist/pypy/objspace/test/test_taintobjspace.py (original) +++ pypy/dist/pypy/objspace/test/test_taintobjspace.py Fri Feb 9 13:41:12 2007 @@ -25,8 +25,8 @@ raises(TaintError, "untaint(int, x)") raises(TaintError, "untaint(float, x)") - def test_taint_mode(self): - from pypymagic import taint, untaint, TaintError, taint_mode + def test_taint_atomic(self): + from pypymagic import taint, untaint, TaintError, taint_atomic x = taint(6) x *= 7 @@ -35,14 +35,14 @@ return 5 else: return 3 - dummy = taint_mode(dummy) + dummy = taint_atomic(dummy) y = dummy(x) raises(TaintError, "if y == 3: z = 1") assert untaint(int, y) == 5 - def test_taint_mode_exception(self): - from pypymagic import taint, untaint, TaintError, taint_mode + def test_taint_atomic_exception(self): + from pypymagic import taint, untaint, TaintError, taint_atomic x = taint(6) x *= 7 @@ -51,24 +51,27 @@ return 5 else: return 3 - dummy = taint_mode(dummy) + dummy = taint_atomic(dummy) y = dummy(x) raises(TaintError, "if y == 3: z = 1") raises(TaintError, "untaint(int, y)") - def test_taint_mode_incoming_bomb(self): - from pypymagic import taint, untaint, TaintError, taint_mode + def test_taint_atomic_incoming_bomb(self): + from pypymagic import taint, untaint, TaintError, taint_atomic x = taint(6) x /= 0 + lst = [] def dummy(x): + lst.append("running!") if x > 40: return 5 else: return 3 - dummy = taint_mode(dummy) + dummy = taint_atomic(dummy) y = dummy(x) raises(TaintError, "if y == 3: z = 1") + assert lst == [] raises(TaintError, "untaint(int, y)") From antocuni at codespeak.net Fri Feb 9 13:58:33 2007 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Fri, 9 Feb 2007 13:58:33 +0100 (CET) Subject: [pypy-svn] r38245 - pypy/dist/pypy/doc Message-ID: <20070209125833.93DD610089@code0.codespeak.net> Author: antocuni Date: Fri Feb 9 13:58:32 2007 New Revision: 38245 Modified: pypy/dist/pypy/doc/getting-started.txt Log: Some notes on how to translate pypy under windows, based on the docstring of goal/win32/gc_patch_windows.py Modified: pypy/dist/pypy/doc/getting-started.txt ============================================================================== --- pypy/dist/pypy/doc/getting-started.txt (original) +++ pypy/dist/pypy/doc/getting-started.txt Fri Feb 9 13:58:32 2007 @@ -601,6 +601,111 @@ python translate.py targetrpystone +Translating PyPy under Windows +++++++++++++++++++++++++++++++ + +PyPy can be translated also under Windows. We have tested the +translation toolchain using Visual Studio .NET 2003. It could be +possible that it works also with other configurations: if you succeed +to compile PyPy with a C compiler other that Visual Studio .NET 2003, +please report us. + +To build pypy-c you first need a PyPy compatible version of the Boehm +collector for Windows and Visual Studio .NET 2003. You can either +`build your own copy`_ or download a `pre-compiled binary package`_. + +.. _`build your own copy`: + +How to build the Boehm collector +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +First of all, download the official `Boehm collector suite`_. At +the time of writing (2007-02-09) this contains version gc6.7. + +Unpack this folder somewhere, for instance to ``d:\tmp``. Change to +this folder and copy the file ``NT_THREADS_MAKEFILE`` to +``Makefile``:: + + d: + cd \tmp\gc6.5 + 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. 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`` -- please change the command +according to the location of your PyPy installation):: + + python d:\pypy\dist\pypy\translator\goal\win32\gc_patch_windows.py + +Now, your makefile is patched a little bit. See gc_patch_windows.py_ +for more details. + +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. +Please note that you will need to use Microsoft's cmd, as cygwin bash +doesn't correctly handle the batch file in the next step. + +With my setup, I have to do:: + + c:\Program Files\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 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:: + + nmake CFG="gc - Win32 Release" + +After the build, you will find the ``gc_pypy.dll`` and ``gc_pypy.lib`` +files in the Release folder. + +Copy the file ``gc_pypy.dll`` to ``c:\windows\system32`` or any other +folder that is always in your PATH variable. + +Also, copy ``gc_pypy.lib`` to (in my case) ``c:\Program files\Microsoft +Visual Studio .NET 2003\Vc7\lib``. + +Finally, copy ``d:\tmp\gc6.7\include`` to ``c:\Program +files\Microsoft Visual Studio .NET 2003\Vc7\include`` and rename this +folder to ``gc``, so that ``gc/gc.h`` is valid. + +In case of a debug build also copy ``gc_pypy.pdb`` to your lib +folder. This allows you to use source-level debugging. + +Summary transcript of the steps involved (please adjust paths):: + + d: + cd \tmp\gc6.7 + copy NT_THREADS_MAKEFILE Makefile + python d:\pypy\dist\pypy\translator\goal\win32\gc_patch_windows.py + "c:\Program files\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 "c:\Program files\Microsoft Visual Studio .NET 2003\Vc7\lib" + mkdir "c:\Program files\Microsoft Visual Studio .NET 2003\Vc7\include\gc" + copy include "c:\Program files\Microsoft Visual Studio .NET 2003\Vc7\include\gc" + +.. _`pre-compiled binary package`: + +Installing the pre-compiled Boehm collector +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +First, download and extract the file `gc-windows.zip`_. Then, copy the +file ``gc_pypy.dll`` to ``c:\windows\system32`` or any other folder that is +always in your PATH variable. + +Also, copy ``gc_pypy.lib`` to (in my case) ``c:\Program files\Microsoft +Visual Studio .NET 2003\Vc7\lib``. + +Finally, copy the ``gc`` directory to ``c:\Program files\Microsoft +Visual Studio .NET 2003\Vc7\include``. + + .. _`translate PyPy with the thunk object space`: Translating with the thunk object space @@ -792,6 +897,7 @@ .. _trace: http://codespeak.net/pypy/dist/pypy/objspace/trace.py .. _flow: http://codespeak.net/pypy/dist/pypy/objspace/flow/ .. _translator.py: http://codespeak.net/pypy/dist/pypy/translator/translator.py +.. _gc_patch_windows.py: http://codespeak.net/pypy/dist/pypy/translator/goal/win32/gc_patch_windows.py .. _mailing lists: contact.html .. _documentation: index.html .. _unit tests: coding-guide.html#test-design @@ -799,5 +905,7 @@ .. _`directory reference`: index.html#directory-reference .. _`Boehm-Demers-Weiser garbage collector`: http://www.hpl.hp.com/personal/Hans_Boehm/gc/ +.. _`Boehm collector suite`: http://www.hpl.hp.com/personal/Hans_Boehm/gc/gc_source/gc.tar.gz +.. _`gc-windows.zip`: http://codespeak.net/~antocuni/gc-windows.zip .. include:: _ref.txt From pedronis at codespeak.net Fri Feb 9 14:05:14 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Fri, 9 Feb 2007 14:05:14 +0100 (CET) Subject: [pypy-svn] r38248 - in pypy/dist: lib-python pypy/tool Message-ID: <20070209130514.B484A1009A@code0.codespeak.net> Author: pedronis Date: Fri Feb 9 14:05:09 2007 New Revision: 38248 Added: pypy/dist/pypy/tool/watchdog.py - copied unchanged from r38247, user/pedronis/watchdog/watchdog.py Modified: pypy/dist/lib-python/conftest.py Log: trying simple timeout watchdog approach Modified: pypy/dist/lib-python/conftest.py ============================================================================== --- pypy/dist/lib-python/conftest.py (original) +++ pypy/dist/lib-python/conftest.py Fri Feb 9 14:05:09 2007 @@ -881,8 +881,11 @@ python = sys.executable pypy_script = pypydir.join('bin', 'py.py') alarm_script = pypydir.join('tool', 'alarm.py') + watchdog_script = pypydir.join('tool', 'watchdog.py') + regr_script = pypydir.join('tool', 'pytest', 'run-script', 'regrverbose.py') + if option.use_compiled: execpath, info = getexecutable() pypy_options = [] @@ -908,7 +911,10 @@ cmd = "%s %s %s %s" %( execpath, regrrun, regrrun_verbosity, fspath.purebasename) - print cmd + if sys.platform != 'win32': + cmd = "%s %s %s %s" %( + python, watchdog_script, TIMEOUT, + cmd) else: cmd = "%s %s %d %s %s %s %s %s" %( python, alarm_script, TIMEOUT, From arigo at codespeak.net Fri Feb 9 14:35:46 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 9 Feb 2007 14:35:46 +0100 (CET) Subject: [pypy-svn] r38250 - pypy/dist/pypy/objspace Message-ID: <20070209133546.75B5710093@code0.codespeak.net> Author: arigo Date: Fri Feb 9 14:35:45 2007 New Revision: 38250 Modified: pypy/dist/pypy/objspace/taint.py Log: Added _taint_look(). Modified: pypy/dist/pypy/objspace/taint.py ============================================================================== --- pypy/dist/pypy/objspace/taint.py (original) +++ pypy/dist/pypy/objspace/taint.py Fri Feb 9 14:35:45 2007 @@ -8,6 +8,7 @@ from pypy.interpreter.error import OperationError from pypy.interpreter import baseobjspace, gateway, executioncontext from pypy.interpreter.function import Method +from pypy.interpreter.pyframe import PyFrame from pypy.tool.sourcetools import func_with_new_name from pypy.rlib.unroll import unrolling_iterable @@ -31,11 +32,33 @@ ## ... class W_TaintBomb(baseobjspace.W_Root): + filename = '?' + codename = '?' + codeline = 0 + def __init__(self, space, operr): - if get_debug_level(space) > 0: - debug_bomb(space, operr) self.space = space self.operr = operr + self.record_debug_info() + + def record_debug_info(self): + ec = self.space.getexecutioncontext() + try: + frame = ec.framestack.top() + except IndexError: + pass + else: + if isinstance(frame, PyFrame): + self.filename = frame.pycode.co_filename + self.codename = frame.pycode.co_name + self.codeline = frame.get_last_lineno() + if get_debug_level(self.space) > 0: + self.debug_dump() + + def debug_dump(self): + os.write(2, 'Taint Bomb from file "%s", line %d, in %s\n %s\n' % ( + self.filename, self.codeline, self.codename, + self.operr.errorstr(self.space))) def explode(self): #msg = self.operr.errorstr(space) @@ -120,11 +143,22 @@ app_taint_debug = gateway.interp2app(taint_debug, unwrap_spec=[gateway.ObjSpace, int]) +def taint_look(space, w_obj): + if isinstance(w_obj, W_Tainted): + info = space.type(w_obj.w_obj).getname(space, '?') + msg = space.str_w(w_obj.w_obj.getrepr(space, info)) + msg = 'Taint Box %s\n' % msg + os.write(2, msg) + elif isinstance(w_obj, W_TaintBomb): + w_obj.debug_dump() + else: + os.write(2, 'not tainted\n') +app_taint_look = gateway.interp2app(taint_look) + def get_debug_level(space): return space.getexecutioncontext().taint_debug def debug_bomb(space, operr): - from pypy.interpreter.pyframe import PyFrame ec = space.getexecutioncontext() filename = '?' codename = '?' @@ -164,8 +198,10 @@ self.wrap(app_taint_atomic)) self.setattr(w_pypymagic, self.wrap('TaintError'), self.w_TaintError) - self.setattr(w_pypymagic, self.wrap('taint_debug'), + self.setattr(w_pypymagic, self.wrap('_taint_debug'), self.wrap(app_taint_debug)) + self.setattr(w_pypymagic, self.wrap('_taint_look'), + self.wrap(app_taint_look)) patch_space_in_place(self, 'taint', proxymaker) From arigo at codespeak.net Fri Feb 9 14:35:56 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 9 Feb 2007 14:35:56 +0100 (CET) Subject: [pypy-svn] r38251 - pypy/dist/pypy/doc Message-ID: <20070209133556.A5F561009C@code0.codespeak.net> Author: arigo Date: Fri Feb 9 14:35:53 2007 New Revision: 38251 Modified: pypy/dist/pypy/doc/objspace-proxies.txt Log: Document the Taint Object Space. Modified: pypy/dist/pypy/doc/objspace-proxies.txt ============================================================================== --- pypy/dist/pypy/doc/objspace-proxies.txt (original) +++ pypy/dist/pypy/doc/objspace-proxies.txt Fri Feb 9 14:35:53 2007 @@ -149,7 +149,274 @@ The Taint Object Space ====================== -XXX +Motivation +---------- + +The Taint Object Space provides a form of security: "tainted objects", +inspired by various sources, including Perl's tainting (XXX more +references needed). + +The basic idea of this kind of security is not to protect against +malicious code, unlike sandboxing, for example. The idea is that, +considering a large application that handles sensitive data, there are +typically only a small number of places that need to explicitly +manipulate that sensitive data; all the other places merely pass it +around, or do entierely unrelated things. + +Nevertheless, if a large application needs to be reviewed for security, +it must be entierely carefully checked, because it is possible that a +bug at some apparently unrelated place could lead to a leak of sensitive +information in a way that an external attacker could exploit. For +example, if any part of the application provides web services, an +attacker might be able to issue unexpected requests with a regular web +browser and deduce secret information from the details of the answers he +gets. + +An approach like that of the Taint Object Space allows the small parts +of the program that manipulate sensitive data to be explicitly marked. +The effect of this is that although these small parts still need a +careful security review, the rest of the application no longer does, +because even a bug would be unable to leak the information. + +We have implemented a simple two-levels model: objects are either +regular (untainted), or hidden (tainted). It would be simple to extend +the code for more fine-grained scales of secrecy. For example it is +typical in the literature to consider user-specified lattices of secrecy +levels, corresponding to multiple "owners" that cannot access data +belonging to another "owner" unless explicitly authorized to do so. + +Tainting and untainting +----------------------- + +Start a py.py with the Taint Object Space and try the following example:: + + $ py.py -o taint + >>>> from pypymagic import taint + >>>> x = taint(6) + + # x is secret from now on. We can pass it around and + # even operate on it, but not inspect it. Taintness + # is propagated to operation results. + + >>>> x + TaintError + + >>>> if x > 5: y = 2 + TaintError + + >>>> y = x + 5 # ok + >>>> lst = [x, y] + >>>> z = lst.pop() + >>>> t = type(z) # type() works too, tainted answer + >>>> t + TaintError + >>>> u = t is int # even 'is' works + >>>> u + TaintError + +Notice that using a tainted boolean like ``x > 5`` in an ``if`` +statement is forbidden. This is because knowing which path is followed +would give away a hint about ``x``; in the example above, if the +statement ``if x > 5: y = 2`` were allowed to run, we would know +something about the value of ``x`` by looking at the (untainted) value +in the variable ``y``. + +Of course, there is a way to inspect tainted objects. The basic way is +to explicitly untaint the object. In an application, the places that +use this ``untaint()`` declassification function are the places that +need careful security review. To avoid unexpected objects showing up, +the ``untaint()`` function must be called with the exact type of the +object to declassify. It will raise ``TaintError`` if the type doesn't +match:: + + >>>> from pypymagic import taint + >>>> untaint(int, x) + 6 + >>>> untaint(int, z) + 11 + >>>> untaint(bool, x > 5) + True + >>>> untaint(int, x > 5) + TaintError + + +Taint Bombs +----------- + +In this area, a common problem is what to do about failing operations. +If an operation raises an exception when manipulating a tainted object, +then the very presence of the exception can leak information about the +tainted object itself. Consider:: + + >>>> 5 / (x-6) + +By checking if this raises ``ZeroDivisionError`` or not, we would know +if ``x`` was equal to 6 or not. The solution to this problem in the +Taint Object Space is to introduce *Taint Bombs*. They are a kind of +tainted object that doesn't contain a real object, but a pending +exception. Taint Bombs are undistinguishable from normal tainted +objects to unpriviledged code. See:: + + >>>> x = taint(6) + >>>> i = 5 / (x-6) # no exception here + >>>> j = i + 1 # nor here + >>>> k = j + 5 # nor here + >>>> untaint(int, k) + TaintError + +In the above example, all of ``i``, ``j`` and ``k`` contain a Taint +Bomb. Trying to untaint it raises ``TaintError``, but at the point +where ``untaint()`` is called. This means that all calls to +``untaint()`` must also be carefully reviewed for what occurs if they +receive a Taint Bomb; they might catch the ``TaintError`` and give the +user a generic message that something went wrong, if we are reasonably +careful that the message or even its preserve doesn't give information +away. This might be a decliate problem by itself, but there is no +satisfying general solution to this problem; it must be considered on a +case-by-case basis. Again, what the Taint Object Space approach +achieves is not solving these problems, but localizing them to +well-defined small parts of the application - namely, around calls to +``untaint()``. + +Note that the ``TaintError`` exception is deliberately not including any +useful error message, because that might give information away too. +However, it makes debugging quite harder. This is a difficult problem +to solve in general too; so far we implemented a "debug mode" that dumps +information to the low-level stderr of the application (where we hope +that it is unlikely to be seen by anyone else than the application +developer). The debug mode must be activated with +``pypymagic.taint_debug(1)``. + + +Taint Atomic functions +---------------------- + +Occasionally, a more complicated computation must be performed on a +tainted object. This requires first untainting the object, perform the +computations, and then carefully taint the result again (including +hiding all exceptions that could give information away). + +There is a built-in decorator that does exactly that:: + + >>>> @pypymagic.taint_atomic + >>>> def myop(x, y): + .... while x > 0: + .... x -= y + .... return x + .... + >>>> myop(42, 10) + -8 + >>>> z = myop(taint(42), 10) + >>>> z + TaintError + >>>> untaint(int, z) + -8 + +The decorator makes a whole function behave like a built-in operation. +If no tainted argument is passed in, the function behaves normally. But +if any of the arguments is tainted, it is automatically untainted - so +the function body always sees untainted arguments - and the eventual +result is tainted again (possibly in a Taint Bomb). + +It is important for the function marked as ``taint_atomic`` to have no +visible side effects, otherwise information could be leaked that way. +This is currently not enforced, which means that all ``taint_atomic`` +functions have to be carefully reviewed for security (but not the +callers of ``taint_atomic`` functions). + +A possible future extension would be to forbid side-effects on +non-tainted objects from all ``taint_atomic`` functions. + +An example of usage: given a tainted object ``passwords_db`` that +references a database of passwords, we can write a function +that checks if a password is valid as follows:: + + @taint_atomic + def validate(passwords_db, username, password): + assert type(passwords_db) is PasswordDatabase + assert type(username) is str + assert type(password) is str + ...load username entry from passwords_db... + return expected_password == password + +It returns a tainted boolean answer, or a Taint Bomb if something +went wrong. A caller can do: + + ok = validate(passwords_db, 'john', '1234') + ok = untaint(bool, ok) + +This can give three outcomes: ``True``, ``False``, or a ``TaintError`` +exception (with no information on it) if anything went wrong. If even +this is considered giving too much information away, the ``False`` case +can be made indistinguishable from the ``TaintError`` case (simply by +also raising an exception in ``validate()`` if the password is wrong). + +In the above example, the security achieved is that as long as +``validate()`` does not leak information, no other part of the code can +obtain more information about a passwords database than a Yes/No answer +to a precise query. + +A possible extension of the ``taint_atomic`` decorator would be to check +the argument types as ``untaint()`` does, for the same reason - to +prevent bugs where a function like ``validate()`` above is accidentally +called with the wrong kind of object, and thus leaks information about +it. For now, all ``taint_atomic`` function should be conservative and +carefully check all assumptions on all input arguments. + + +Interface +--------- + +.. _`like a built-in operation`: + +The basic rule of the Tainted Object Space is that it introduces two new +kinds of objects, Tainted Boxes and Tainted Bombs (which are not types +in the Python sense). Each box internally contains a regular object; +each bomb internally contains an exception object. An operation +involving Tainted Boxes is performed on the objects contained in the +boxes, and give a Tainted Box or a Tainted Bomb as a result (such an +operation does not let an exception be raised). An operation called +with a Tainted Bomb argument immediately returns the same Tainted Bomb. + +In a PyPy running with (or translated with) the Taint Object Space, +the ``pypymagic`` module exposes the following interface: + +* ``taint(obj)`` + + Return a new Tainted Box wrapping ``obj``. Return ``obj`` itself + if it is already tainted (a Box or a Bomb). + +* ``is_tainted(obj)`` + + Check if ``obj`` is tainted (a Box or a Bomb). + +* ``untaint(type, obj)`` + + Untaints ``obj`` if it is tainted. Raise ``TaintError`` if the type + of the untainted object is not exactly ``type``, or if ``obj`` is a + Bomb. + +* ``taint_atomic(func)`` + + Return a wrapper function around the callable ``func``. The wrapper + behaves `like a built-in operation`_ with respect to untainting the + arguments, tainting the result, and returning a Bomb. + +* ``TaintError`` + + Exception. On purpose, it provides no attribute or error message. + +* ``_taint_debug(level)`` + + Set the debugging level to ``level`` (0=off). At level 1 or above, + all Taint Bombs print a diagnostic message to stderr when they are + created. + +* ``_taint_look(obj)`` + + For debugging purposes: prints (to stderr) the type and address of + the object in a Tainted Box, or prints the exception if ``obj`` is + a Taint Bomb. .. _dump: From arigo at codespeak.net Fri Feb 9 14:42:59 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 9 Feb 2007 14:42:59 +0100 (CET) Subject: [pypy-svn] r38253 - pypy/dist/pypy/objspace Message-ID: <20070209134259.E817D1009F@code0.codespeak.net> Author: arigo Date: Fri Feb 9 14:42:57 2007 New Revision: 38253 Modified: pypy/dist/pypy/objspace/dump.py Log: Fix the Dump Object Space. Modified: pypy/dist/pypy/objspace/dump.py ============================================================================== --- pypy/dist/pypy/objspace/dump.py (original) +++ pypy/dist/pypy/objspace/dump.py Fri Feb 9 14:42:57 2007 @@ -187,12 +187,12 @@ returns_wrapped = opname in op_returning_wrapped aligned_opname = '%15s' % opname n = nb_args[opname] - def proxy(*args): + def proxy(*args, **kwds): dumper = space.dumper args_w = list(args[:n]) dumper.dump_enter(aligned_opname, args_w) try: - res = parentfn(*args) + res = parentfn(*args, **kwds) except Exception, e: dumper.dump_raised(aligned_opname, e) raise From arigo at codespeak.net Fri Feb 9 14:43:17 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 9 Feb 2007 14:43:17 +0100 (CET) Subject: [pypy-svn] r38254 - pypy/dist/pypy/doc Message-ID: <20070209134317.EE570100A8@code0.codespeak.net> Author: arigo Date: Fri Feb 9 14:43:15 2007 New Revision: 38254 Modified: pypy/dist/pypy/doc/objspace-proxies.txt Log: Document the Taint Object Space. This more or less concludes objspace-proxies.txt. Modified: pypy/dist/pypy/doc/objspace-proxies.txt ============================================================================== --- pypy/dist/pypy/doc/objspace-proxies.txt (original) +++ pypy/dist/pypy/doc/objspace-proxies.txt Fri Feb 9 14:43:15 2007 @@ -424,7 +424,22 @@ The Dump Object Space ===================== -XXX +When PyPy is run with (or translated with) the Dump Object Space, all +operations between objects are dumped to a file called +``pypy-space-dump``. This should give a powerful way to debug +applications, but so far the dump can only be inspected in a text +editor; better browsing tools are needed before it can be really useful. + +Try:: + + $ py.py -o dump + >>>> 2+3 + 5 + >>>> (exit py.py here) + $ more pypy-space-dump + +On my machine the ``add`` between 2 and 3 starts at line 3152 (!) and +returns at line 3164. All the rest is start-up, printing, and shutdown. .. _tproxy: From antocuni at codespeak.net Fri Feb 9 14:50:23 2007 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Fri, 9 Feb 2007 14:50:23 +0100 (CET) Subject: [pypy-svn] r38255 - pypy/dist/pypy/doc Message-ID: <20070209135023.A14DE100A3@code0.codespeak.net> Author: antocuni Date: Fri Feb 9 14:50:22 2007 New Revision: 38255 Modified: pypy/dist/pypy/doc/translation.txt Log: Add link to my thesis, and write something a short paragraph about genjvm. Modified: pypy/dist/pypy/doc/translation.txt ============================================================================== --- pypy/dist/pypy/doc/translation.txt (original) +++ pypy/dist/pypy/doc/translation.txt Fri Feb 9 14:50:22 2007 @@ -638,18 +638,33 @@ GenCLI targets the `Common Language Infrastructure`_, the most famous implementations of which are Microsoft's `.NET`_ and Mono_. -.. _`Common Language Infrastructure`: http://www.ecma-international.org/publications/standards/Ecma-335.htm -.. _`.NET`: http://www.microsoft.com/net/ -.. _Mono: http://www.mono-project.com/ - It is probably the most advanced of the object oriented backends -- it can compile our two standard benchmarks, RPyStone (CPython's PyStone benchmark modified slightly to be RPython) and a RPython version of the common Richards benchmark. -It is almost entirely the work of Antonio Cuni, who worked on this backend as -part of his Bachelor's thesis and is continuing to work on it as part of -Google's Summer of Code 2006 program. +It is almost entirely the work of Antonio Cuni, who started this +backend as part of his `Master's thesis`_, the Google's Summer of Code +2006 program and the Summer of PyPy program. + +.. _`Common Language Infrastructure`: http://www.ecma-international.org/publications/standards/Ecma-335.htm +.. _`.NET`: http://www.microsoft.com/net/ +.. _Mono: http://www.mono-project.com/ +.. _`Master's thesis`: http://codespeak.net/~antocuni/Implementing%20Python%20in%20.NET.pdf + +GenJVM +++++++ + +GenJVM targets the Java Virtual Machine: it translates RPython +programs directly into Java bytecode, similarly to what GenCLI does. + +So far it is the second most mature high level backend after GenCLI: +it still can't translate the full Standard Interpreter, but after the +Leysin sprint we were able to compile and run the rpytstone and +richards benchmarks. + +GenJVM is almost entirely the work of Niko Matsakis, who worked on it +also as part of the Summer of PyPy program. GenSqueak +++++++++ From fijal at codespeak.net Fri Feb 9 14:57:32 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 9 Feb 2007 14:57:32 +0100 (CET) Subject: [pypy-svn] r38256 - pypy/dist/pypy/doc Message-ID: <20070209135732.7FF65100A3@code0.codespeak.net> Author: fijal Date: Fri Feb 9 14:57:31 2007 New Revision: 38256 Modified: pypy/dist/pypy/doc/translation.txt Log: Link to JS backend, rewording. Modified: pypy/dist/pypy/doc/translation.txt ============================================================================== --- pypy/dist/pypy/doc/translation.txt (original) +++ pypy/dist/pypy/doc/translation.txt Fri Feb 9 14:57:31 2007 @@ -690,7 +690,7 @@ Instead, the goal of GenJS is more directed towards allowing one to write Ajax_ web applications entirely in Python (the client side would have to be -restricted to RPython_), and this is the subject of Maciej Fijalkowski's +restricted to RPython_), and this was the subject of Maciej Fijalkowski's Summer Of Code 2006 project. .. _Ajax: http://en.wikipedia.org/wiki/AJAX @@ -699,6 +699,12 @@ for the Summer Of Code project) and now he and Maciej are collaborating on its further development. +To read more about JS backend there is a `whatis document`_ and +a `using document`_. + +.. _`whatis document`: js/whatis.html +.. _`using document`: js/using.html + GenCL +++++ From pedronis at codespeak.net Fri Feb 9 14:59:45 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Fri, 9 Feb 2007 14:59:45 +0100 (CET) Subject: [pypy-svn] r38257 - pypy/dist/lib-python Message-ID: <20070209135945.16F91100A5@code0.codespeak.net> Author: pedronis Date: Fri Feb 9 14:59:44 2007 New Revision: 38257 Modified: pypy/dist/lib-python/conftest.py Log: oops, the py lib capture was used Modified: pypy/dist/lib-python/conftest.py ============================================================================== --- pypy/dist/lib-python/conftest.py (original) +++ pypy/dist/lib-python/conftest.py Fri Feb 9 14:59:44 2007 @@ -1014,7 +1014,7 @@ test_stdout = "%s\n%s" % (self.fspath.purebasename, test_stdout) if test_stdout != expected: exit_status = 2 - res, out, err = callcapture(reportdiff, expected, test_stdout) + res, out, err = py.io.StdCapture.call(reportdiff, expected, test_stdout) outcome = 'ERROUT' result.addnamedtext('reportdiff', out) else: From antocuni at codespeak.net Fri Feb 9 15:02:38 2007 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Fri, 9 Feb 2007 15:02:38 +0100 (CET) Subject: [pypy-svn] r38258 - pypy/dist/pypy/translator/cli Message-ID: <20070209140238.278AB100A8@code0.codespeak.net> Author: antocuni Date: Fri Feb 9 15:02:37 2007 New Revision: 38258 Modified: pypy/dist/pypy/translator/cli/class_.py Log: oops! we must do the lookup *before* we mangle the name! Modified: pypy/dist/pypy/translator/cli/class_.py ============================================================================== --- pypy/dist/pypy/translator/cli/class_.py (original) +++ pypy/dist/pypy/translator/cli/class_.py Fri Feb 9 15:02:37 2007 @@ -131,10 +131,10 @@ default_values = self.INSTANCE._fields.copy() default_values.update(self.INSTANCE._overridden_defaults) for f_name, (F_TYPE, f_default) in default_values.iteritems(): + INSTANCE_DEF, _ = self.INSTANCE._lookup_field(f_name) cts_type = self.cts.lltype_to_cts(F_TYPE) f_name = self.cts.escape_name(f_name) if cts_type != 'void': - INSTANCE_DEF, _ = self.INSTANCE._lookup_field(f_name) self.ilasm.opcode('ldarg.0') push_constant(self.db, F_TYPE, f_default, self.gen) class_name = self.db.class_name(INSTANCE_DEF) From arigo at codespeak.net Fri Feb 9 15:05:50 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 9 Feb 2007 15:05:50 +0100 (CET) Subject: [pypy-svn] r38259 - pypy/dist/pypy/doc Message-ID: <20070209140550.68E6410091@code0.codespeak.net> Author: arigo Date: Fri Feb 9 15:05:42 2007 New Revision: 38259 Modified: pypy/dist/pypy/doc/objspace-proxies.txt Log: Typo-sized changes. Modified: pypy/dist/pypy/doc/objspace-proxies.txt ============================================================================== --- pypy/dist/pypy/doc/objspace-proxies.txt (original) +++ pypy/dist/pypy/doc/objspace-proxies.txt Fri Feb 9 15:05:42 2007 @@ -157,11 +157,15 @@ references needed). The basic idea of this kind of security is not to protect against -malicious code, unlike sandboxing, for example. The idea is that, -considering a large application that handles sensitive data, there are -typically only a small number of places that need to explicitly -manipulate that sensitive data; all the other places merely pass it -around, or do entierely unrelated things. +malicious code, unlike sandboxing, for example. This is about the +handling of "sensitive" data. It covers two kinds of sensitive data: +secret data which should not leak, and untrusted data coming from an +external source and that must be validated before it is used. + +The idea is that, considering a large application that handles these +kinds of sensitive data, there are typically only a small number of +places that need to explicitly manipulate that sensitive data; all the +other places merely pass it around, or do entierely unrelated things. Nevertheless, if a large application needs to be reviewed for security, it must be entierely carefully checked, because it is possible that a @@ -170,7 +174,8 @@ example, if any part of the application provides web services, an attacker might be able to issue unexpected requests with a regular web browser and deduce secret information from the details of the answers he -gets. +gets. Another example is the common CGI attack where an attacker sends +malformed inputs and causes the CGI script to do unintended things. An approach like that of the Taint Object Space allows the small parts of the program that manipulate sensitive data to be explicitly marked. @@ -179,11 +184,16 @@ because even a bug would be unable to leak the information. We have implemented a simple two-levels model: objects are either -regular (untainted), or hidden (tainted). It would be simple to extend -the code for more fine-grained scales of secrecy. For example it is -typical in the literature to consider user-specified lattices of secrecy -levels, corresponding to multiple "owners" that cannot access data -belonging to another "owner" unless explicitly authorized to do so. +regular (untainted), or sensitive (tainted). Objects are marked as +sensitive if they are secret or untrusted, and only declassified at +carefully-checked positions (e.g. where the secret data is needed, or +after the untrusted data has been fully validated). + +It would be simple to extend the code for more fine-grained scales of +secrecy. For example it is typical in the literature to consider +user-specified lattices of secrecy levels, corresponding to multiple +"owners" that cannot access data belonging to another "owner" unless +explicitly authorized to do so. Tainting and untainting ----------------------- @@ -194,23 +204,23 @@ >>>> from pypymagic import taint >>>> x = taint(6) - # x is secret from now on. We can pass it around and + # x is hidden from now on. We can pass it around and # even operate on it, but not inspect it. Taintness # is propagated to operation results. >>>> x TaintError - >>>> if x > 5: y = 2 + >>>> if x > 5: y = 2 # see below TaintError - >>>> y = x + 5 # ok + >>>> y = x + 5 # ok >>>> lst = [x, y] >>>> z = lst.pop() - >>>> t = type(z) # type() works too, tainted answer + >>>> t = type(z) # type() works too, tainted answer >>>> t TaintError - >>>> u = t is int # even 'is' works + >>>> u = t is int # even 'is' works >>>> u TaintError @@ -222,12 +232,11 @@ in the variable ``y``. Of course, there is a way to inspect tainted objects. The basic way is -to explicitly untaint the object. In an application, the places that -use this ``untaint()`` declassification function are the places that -need careful security review. To avoid unexpected objects showing up, -the ``untaint()`` function must be called with the exact type of the -object to declassify. It will raise ``TaintError`` if the type doesn't -match:: +to explicitly "declassify" it with the ``untaint()`` function. In an +application, the places that use ``untaint()`` are the places that need +careful security review. To avoid unexpected objects showing up, the +``untaint()`` function must be called with the exact type of the object +to declassify. It will raise ``TaintError`` if the type doesn't match:: >>>> from pypymagic import taint >>>> untaint(int, x) @@ -265,27 +274,30 @@ TaintError In the above example, all of ``i``, ``j`` and ``k`` contain a Taint -Bomb. Trying to untaint it raises ``TaintError``, but at the point -where ``untaint()`` is called. This means that all calls to -``untaint()`` must also be carefully reviewed for what occurs if they -receive a Taint Bomb; they might catch the ``TaintError`` and give the -user a generic message that something went wrong, if we are reasonably -careful that the message or even its preserve doesn't give information -away. This might be a decliate problem by itself, but there is no -satisfying general solution to this problem; it must be considered on a -case-by-case basis. Again, what the Taint Object Space approach -achieves is not solving these problems, but localizing them to -well-defined small parts of the application - namely, around calls to -``untaint()``. +Bomb. Trying to untaint it raises an exception - a generic +``TaintError``. What we win is that the exception gives little away, +and most importantly it occurs at the point where ``untaint()`` is +called, not where the operation failed. This means that all calls to +``untaint()`` - but not the rest of the code - must be carefully +reviewed for what occurs if they receive a Taint Bomb; they might catch +the ``TaintError`` and give the user a generic message that something +went wrong, if we are reasonably careful that the message or even its +presence doesn't give information away. This might be a decliate +problem by itself, but there is no satisfying general solution to this +problem; it must be considered on a case-by-case basis. Again, what the +Taint Object Space approach achieves is not solving these problems, but +localizing them to well-defined small parts of the application - namely, +around calls to ``untaint()``. Note that the ``TaintError`` exception is deliberately not including any useful error message, because that might give information away too. However, it makes debugging quite harder. This is a difficult problem -to solve in general too; so far we implemented a "debug mode" that dumps -information to the low-level stderr of the application (where we hope +to solve in general too; so far we implemented a way to peek in a Taint +Box or Bomb, ``pypymagic._taint_look(x)``, and a "debug mode" that +prints the exception as soon as a Bomb is created. Both write +information to the low-level stderr of the application, where we hope that it is unlikely to be seen by anyone else than the application -developer). The debug mode must be activated with -``pypymagic.taint_debug(1)``. +developer. Taint Atomic functions @@ -293,8 +305,8 @@ Occasionally, a more complicated computation must be performed on a tainted object. This requires first untainting the object, perform the -computations, and then carefully taint the result again (including -hiding all exceptions that could give information away). +computations, and then carefully tainting the result again (including +hiding all exceptions into Bombs). There is a built-in decorator that does exactly that:: @@ -340,7 +352,7 @@ return expected_password == password It returns a tainted boolean answer, or a Taint Bomb if something -went wrong. A caller can do: +went wrong. A caller can do:: ok = validate(passwords_db, 'john', '1234') ok = untaint(bool, ok) @@ -349,19 +361,20 @@ exception (with no information on it) if anything went wrong. If even this is considered giving too much information away, the ``False`` case can be made indistinguishable from the ``TaintError`` case (simply by -also raising an exception in ``validate()`` if the password is wrong). +raising an exception in ``validate()`` if the password is wrong). -In the above example, the security achieved is that as long as -``validate()`` does not leak information, no other part of the code can -obtain more information about a passwords database than a Yes/No answer -to a precise query. +In the above example, the security results achieved are the following: +as long as ``validate()`` does not leak information, no other part of +the code can obtain more information about a passwords database than a +Yes/No answer to a precise query. A possible extension of the ``taint_atomic`` decorator would be to check -the argument types as ``untaint()`` does, for the same reason - to +the argument types, as ``untaint()`` does, for the same reason: to prevent bugs where a function like ``validate()`` above is accidentally -called with the wrong kind of object, and thus leaks information about -it. For now, all ``taint_atomic`` function should be conservative and -carefully check all assumptions on all input arguments. +called with the wrong kind of tainted object, which would make it +misbehave. For now, all ``taint_atomic`` functions should be +conservative and carefully check all assumptions on their input +arguments. Interface From fijal at codespeak.net Fri Feb 9 15:42:16 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 9 Feb 2007 15:42:16 +0100 (CET) Subject: [pypy-svn] r38260 - in pypy/dist/pypy/translator/js/lib: . test Message-ID: <20070209144216.4D2171009F@code0.codespeak.net> Author: fijal Date: Fri Feb 9 15:42:13 2007 New Revision: 38260 Modified: pypy/dist/pypy/translator/js/lib/server.py pypy/dist/pypy/translator/js/lib/test/test_server.py Log: Add more implicit way of describing static pages Modified: pypy/dist/pypy/translator/js/lib/server.py ============================================================================== --- pypy/dist/pypy/translator/js/lib/server.py (original) +++ pypy/dist/pypy/translator/js/lib/server.py Fri Feb 9 15:42:13 2007 @@ -39,6 +39,16 @@ exported_methods = ExportedMethods() +def patch_handler(handler_class): + """ This function takes care of adding necessary + attributed to Static objects + """ + for name, value in handler_class.__dict__.iteritems(): + if isinstance(value, Static) and value.path is None: + assert hasattr(handler_class, "static_dir") + value.path = os.path.join(str(handler_class.static_dir), + name + ".html") + class TestHandler(BaseHTTPRequestHandler): exported_methods = exported_methods @@ -101,19 +111,40 @@ class Static(object): exposed = True - def __init__(self, path): + def __init__(self, path=None): self.path = path def __call__(self): return open(self.path).read() -def start_server(server_address = ('', 8000), handler=TestHandler, fork=False): - httpd = HTTPServer(server_address, handler) +def start_server(server_address = ('', 8000), handler=TestHandler, fork=False, + timeout=None, server=HTTPServer): + patch_handler(handler) + httpd = server(server_address, handler) + if timeout: + def f(httpd): + while 1: + time.sleep(.3) + if time.time() - httpd.last_activity > timeout: + httpd.server_close() + import os + os.kill(os.getpid(), 15) + import thread + thread.start_new_thread(f, (httpd,)) + httpd.last_activity = time.time() if fork: import thread thread.start_new_thread(httpd.serve_forever, ()) - print "Server started, listening on %s" % (server_address,) + print "Server started, listening on %s:%s" %\ + (httpd.server_address[0],httpd.server_port) + sys.stdout.flush() + return httpd else: - print "Server started, listening on %s" % (server_address,) + print "Server started, listening on %s:%s" %\ + (httpd.server_address[0],httpd.server_port) + sys.stdout.flush() httpd.serve_forever() + +Handler = TestHandler +# deprecate TestHandler name Modified: pypy/dist/pypy/translator/js/lib/test/test_server.py ============================================================================== --- pypy/dist/pypy/translator/js/lib/test/test_server.py (original) +++ pypy/dist/pypy/translator/js/lib/test/test_server.py Fri Feb 9 15:42:13 2007 @@ -37,3 +37,19 @@ thread.start_new_thread(httpd.serve_forever, ()) assert URLopener().open("http://127.0.0.1:21212/index").read() == \ "" + +def test_static_page_implicit(): + import thread + tmpdir = py.test.ensuretemp("server_static_page_implicit") + tmpdir.ensure("index.html").write("") + + class StaticHandler(server.TestHandler): + static_dir = str(tmpdir) + index = server.Static() + + server.patch_handler(StaticHandler) + httpd = server.HTTPServer(('127.0.0.1', 21213), StaticHandler) + thread.start_new_thread(httpd.serve_forever, ()) + assert URLopener().open("http://127.0.0.1:21213/index").read() == \ + "" + From arigo at codespeak.net Fri Feb 9 15:46:03 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 9 Feb 2007 15:46:03 +0100 (CET) Subject: [pypy-svn] r38261 - pypy/dist/pypy/doc Message-ID: <20070209144603.C0186100AB@code0.codespeak.net> Author: arigo Date: Fri Feb 9 15:46:01 2007 New Revision: 38261 Modified: pypy/dist/pypy/doc/objspace-proxies.txt Log: Typo. Modified: pypy/dist/pypy/doc/objspace-proxies.txt ============================================================================== --- pypy/dist/pypy/doc/objspace-proxies.txt (original) +++ pypy/dist/pypy/doc/objspace-proxies.txt Fri Feb 9 15:46:01 2007 @@ -227,7 +227,7 @@ Notice that using a tainted boolean like ``x > 5`` in an ``if`` statement is forbidden. This is because knowing which path is followed would give away a hint about ``x``; in the example above, if the -statement ``if x > 5: y = 2`` were allowed to run, we would know +statement ``if x > 5: y = 2`` was allowed to run, we would know something about the value of ``x`` by looking at the (untainted) value in the variable ``y``. From cfbolz at codespeak.net Fri Feb 9 16:19:47 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 9 Feb 2007 16:19:47 +0100 (CET) Subject: [pypy-svn] r38264 - pypy/dist/pypy/doc Message-ID: <20070209151947.E0CF7100A8@code0.codespeak.net> Author: cfbolz Date: Fri Feb 9 16:19:47 2007 New Revision: 38264 Modified: pypy/dist/pypy/doc/objspace-proxies.txt Log: small typos, very nice document! Modified: pypy/dist/pypy/doc/objspace-proxies.txt ============================================================================== --- pypy/dist/pypy/doc/objspace-proxies.txt (original) +++ pypy/dist/pypy/doc/objspace-proxies.txt Fri Feb 9 16:19:47 2007 @@ -60,7 +60,7 @@ >>>> y = thunk(f) >>>> type(y) computing... - + A related, but more obscure feature, allows one object to be instantly and globally replaced with another:: @@ -165,7 +165,7 @@ The idea is that, considering a large application that handles these kinds of sensitive data, there are typically only a small number of places that need to explicitly manipulate that sensitive data; all the -other places merely pass it around, or do entierely unrelated things. +other places merely pass it around, or do entirely unrelated things. Nevertheless, if a large application needs to be reviewed for security, it must be entierely carefully checked, because it is possible that a From mwh at codespeak.net Fri Feb 9 16:44:56 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 9 Feb 2007 16:44:56 +0100 (CET) Subject: [pypy-svn] r38265 - in pypy/dist/pypy/jit/codegen: ppc test Message-ID: <20070209154456.C0734100A2@code0.codespeak.net> Author: mwh Date: Fri Feb 9 16:44:54 2007 New Revision: 38265 Modified: pypy/dist/pypy/jit/codegen/ppc/rgenop.py pypy/dist/pypy/jit/codegen/test/rgenop_tests.py Log: add a test for calling things via AbstractRGenOpTests.directtesthelper fix bug caused by me reading the ABI docs differently from whoever did libffi for darwin... apparently, if you reserve any parameter space, you should reserve at least 32 bytes. Modified: pypy/dist/pypy/jit/codegen/ppc/rgenop.py ============================================================================== --- pypy/dist/pypy/jit/codegen/ppc/rgenop.py (original) +++ pypy/dist/pypy/jit/codegen/ppc/rgenop.py Fri Feb 9 16:44:54 2007 @@ -596,7 +596,7 @@ into our caller's linkage area.""" assert lv <= 0 if self.max_param_space >= 0: - param = self.max_param_space + 24 + param = max(self.max_param_space, 32) + 24 else: param = 0 return ((4 + param - lv + 15) & ~15) Modified: pypy/dist/pypy/jit/codegen/test/rgenop_tests.py ============================================================================== --- pypy/dist/pypy/jit/codegen/test/rgenop_tests.py (original) +++ pypy/dist/pypy/jit/codegen/test/rgenop_tests.py Fri Feb 9 16:44:54 2007 @@ -767,6 +767,33 @@ return cast(callback, c_void_p).value # NB. returns the address as an integer + def test_directtesthelper_direct(self): + # def callable(x, y): + # return f(x) + x + y + rgenop = self.RGenOp() + + def f(x): + return x + 1 + + gv_f = rgenop.genconst(self.directtesthelper(lltype.Ptr(FUNC), f)) + + signed_kind = rgenop.kindToken(lltype.Signed) + sigtoken1 = rgenop.sigToken(FUNC) + sigtoken2 = rgenop.sigToken(FUNC2) + builder, gv_callable, [gv_x, gv_y] = rgenop.newgraph(sigtoken2, "callable") + builder.start_writing() + + gv_t1 = builder.genop_call(sigtoken1, gv_f, [gv_x]) + gv_t2 = builder.genop2("int_add", gv_t1, gv_x) + gv_result = builder.genop2("int_add", gv_t2, gv_y) + builder.finish_and_return(sigtoken2, gv_result) + builder.end() + + fnptr = self.cast(gv_callable, 2) + + res = fnptr(10, 5) + assert res == 11 + 10 + 5 + def test_adder_direct(self): rgenop = self.RGenOp() gv_add_5 = make_adder(rgenop, 5) From mwh at codespeak.net Fri Feb 9 16:48:44 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 9 Feb 2007 16:48:44 +0100 (CET) Subject: [pypy-svn] r38266 - in pypy/dist/pypy/jit/codegen/ppc: . test Message-ID: <20070209154844.7A33C1009D@code0.codespeak.net> Author: mwh Date: Fri Feb 9 16:48:40 2007 New Revision: 38266 Modified: pypy/dist/pypy/jit/codegen/ppc/instruction.py pypy/dist/pypy/jit/codegen/ppc/rgenop.py pypy/dist/pypy/jit/codegen/ppc/test/test_rgenop.py Log: pass the frame_var tests on ppc Modified: pypy/dist/pypy/jit/codegen/ppc/instruction.py ============================================================================== --- pypy/dist/pypy/jit/codegen/ppc/instruction.py (original) +++ pypy/dist/pypy/jit/codegen/ppc/instruction.py Fri Feb 9 16:48:40 2007 @@ -509,6 +509,33 @@ def emit(self, asm): self.label.startaddr = asm.mc.tell() +class LoadFramePointer(Insn): + def __init__(self, result): + Insn.__init__(self) + self.reg_args = [] + self.reg_arg_regclasses = [] + self.result = result + self.result_regclass = GP_REGISTER + def allocate(self, allocator): + self.result_reg = allocator.loc_of(self.result) + def emit(self, asm): + asm.mr(self.result_reg.number, rFP) + +class CopyIntoStack(Insn): + def __init__(self, place, v): + Insn.__init__(self) + self.reg_args = [v] + self.reg_arg_regclasses = [GP_REGISTER] + self.result = None + self.result_regclass = NO_REGISTER + self.place = place + def allocate(self, allocator): + self.arg_reg = allocator.loc_of(self.reg_args[0]) + self.target_slot = allocator.spill_slot() + self.place.offset = self.target_slot.offset + def emit(self, asm): + asm.stw(self.arg_reg.number, rFP, self.target_slot.offset) + class SpillCalleeSaves(Insn): def __init__(self): Insn.__init__(self) Modified: pypy/dist/pypy/jit/codegen/ppc/rgenop.py ============================================================================== --- pypy/dist/pypy/jit/codegen/ppc/rgenop.py (original) +++ pypy/dist/pypy/jit/codegen/ppc/rgenop.py Fri Feb 9 16:48:40 2007 @@ -158,6 +158,12 @@ def create_fresh_location(self): return self.allocator.spill_slot() +class StackInfo(Var): + # not really a Var at all, but needs to be mixable with Consts.... + # offset will be assigned later + offset = 0 + pass + def prepare_for_jump(insns, sourcevars, src2loc, target, allocator): tar2src = {} # tar var -> src var @@ -237,6 +243,7 @@ self.initial_var2loc = None self.max_param_space = -1 self.final_jump_addr = 0 + self.forced_into_stack = None self.start = 0 self.closed = True @@ -369,6 +376,26 @@ ## def genop_debug_pdb(self): # may take an args_gv later + def genop_get_frame_base(self): + gv_result = Var() + self.insns.append( + insn.LoadFramePointer(gv_result)) + return gv_result + + def get_frame_info(self, vars_gv): + if self.forced_into_stack is None: + self.forced_into_stack = [] + result = [] + for v in vars_gv: + if isinstance(v, Var): + place = StackInfo() + self.insns.append(insn.CopyIntoStack(place, v)) + self.forced_into_stack.append((v, place)) + result.append(place) + else: + result.append(None) + return result + def enter_next_block(self, kinds, args_gv): if DEBUG_PRINT: print 'enter_next_block1', args_gv @@ -1036,6 +1063,14 @@ # ... address operations ... + at specialize.arg(0) +def cast_int_to_whatever(T, value): + if isinstance(T, lltype.Ptr): + return lltype.cast_int_to_ptr(T, value) + elif T is llmemory.Address: + return llmemory.cast_int_to_adr(value) + else: + return lltype.cast_primitive(T, value) class RPPCGenOp(AbstractRGenOp): @@ -1146,6 +1181,40 @@ def sigToken(FUNCTYPE): return len(FUNCTYPE.ARGS) # for now + @staticmethod + @specialize.arg(0) + def read_frame_var(T, base, info, index): + """Read from the stack frame of a caller. The 'base' is the + frame stack pointer captured by the operation generated by + genop_get_frame_base(). The 'info' is the object returned by + get_frame_info(); we are looking for the index-th variable + in the list passed to get_frame_info().""" + place = info[index] + if isinstance(place, StackInfo): + #print '!!!', base, place.offset + #print '???', [peek_word_at(base + place.offset + i) + # for i in range(-64, 65, 4)] + assert place.offset != 0 + value = peek_word_at(base + place.offset) + return cast_int_to_whatever(T, value) + else: + assert isinstance(place, GenConst) + return place.revealconst(T) + + #@staticmethod + #@specialize.arg(0) + #def write_frame_place(T, base, place, value): + # """Write into a place in the stack frame of a caller. The + # 'base' is the frame stack pointer captured by the operation + # generated by genop_get_frame_base().""" + + #@staticmethod + #@specialize.arg(0) + #def read_frame_place(T, base, place): + # """Read from a place in the stack frame of a caller. The + # 'base' is the frame stack pointer captured by the operation + # generated by genop_get_frame_base().""" + def check_no_open_mc(self): pass @@ -1249,3 +1318,14 @@ global_rgenop = RPPCGenOp() RPPCGenOp.constPrebuiltGlobal = global_rgenop.genconst + +def peek_word_at(addr): + # now the Very Obscure Bit: when translated, 'addr' is an + # address. When not, it's an integer. It just happens to + # make the test pass, but that's probably going to change. + if we_are_translated(): + return addr.signed[0] + else: + from ctypes import cast, c_void_p, c_int, POINTER + p = cast(c_void_p(addr), POINTER(c_int)) + return p[0] Modified: pypy/dist/pypy/jit/codegen/ppc/test/test_rgenop.py ============================================================================== --- pypy/dist/pypy/jit/codegen/ppc/test/test_rgenop.py (original) +++ pypy/dist/pypy/jit/codegen/ppc/test/test_rgenop.py Fri Feb 9 16:48:40 2007 @@ -21,8 +21,8 @@ class TestRPPCGenop(AbstractRGenOpTests): RGenOp = RPPCGenOp - def test_read_frame_var_direct(self): py.test.skip("in-progress") - def test_read_frame_var_compile(self): py.test.skip("in-progress") +# def test_read_frame_var_direct(self): py.test.skip("in-progress") +# def test_read_frame_var_compile(self): py.test.skip("in-progress") def test_write_frame_place_direct(self): py.test.skip("in-progress") def test_write_frame_place_compile(self): py.test.skip("in-progress") def test_read_frame_place_direct(self): py.test.skip("in-progress") From fijal at codespeak.net Fri Feb 9 17:25:47 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 9 Feb 2007 17:25:47 +0100 (CET) Subject: [pypy-svn] r38267 - pypy/dist/pypy/doc Message-ID: <20070209162547.A79EC100A0@code0.codespeak.net> Author: fijal Date: Fri Feb 9 17:25:41 2007 New Revision: 38267 Modified: pypy/dist/pypy/doc/translation.txt Log: Don't point to wikipedia's redirection page Modified: pypy/dist/pypy/doc/translation.txt ============================================================================== --- pypy/dist/pypy/doc/translation.txt (original) +++ pypy/dist/pypy/doc/translation.txt Fri Feb 9 17:25:41 2007 @@ -693,7 +693,7 @@ restricted to RPython_), and this was the subject of Maciej Fijalkowski's Summer Of Code 2006 project. -.. _Ajax: http://en.wikipedia.org/wiki/AJAX +.. _Ajax: http://en.wikipedia.org/wiki/Ajax The first version of GenJS was written by Eric van Riet Paap (Maciej's mentor for the Summer Of Code project) and now he and Maciej are collaborating on its From arigo at codespeak.net Fri Feb 9 17:33:15 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 9 Feb 2007 17:33:15 +0100 (CET) Subject: [pypy-svn] r38269 - pypy/dist/pypy/doc Message-ID: <20070209163315.84D74100A5@code0.codespeak.net> Author: arigo Date: Fri Feb 9 17:33:06 2007 New Revision: 38269 Modified: pypy/dist/pypy/doc/faq.txt pypy/dist/pypy/doc/standalone-howto.txt Log: More FAQ entries from #pypy. Modified: pypy/dist/pypy/doc/faq.txt ============================================================================== --- pypy/dist/pypy/doc/faq.txt (original) +++ pypy/dist/pypy/doc/faq.txt Fri Feb 9 17:33:06 2007 @@ -6,15 +6,87 @@ General -============================================================ +======================================================================== -Do I have to rewrite my programs in RPython? --------------------------------------------- +------------------------------------------------------ +Why a new implementation of Python? What does it add? +------------------------------------------------------ -No. PyPy always runs your code in its own interpreter, which is a full -and compliant Python 2.4 interpreter. RPython_ is only the language in -which parts of PyPy itself are written. +XXX + +------------------------------------------------------------------- +What is the status of the project? Can it be used in practice yet? +------------------------------------------------------------------- + +XXX + +------------------------------ +On what platforms does it run? +------------------------------ + +XXX + +---------------------------------------------- +Which Python version (2.x?) does PyPy support? +---------------------------------------------- + +XXX + +------------------------------------------------- +Do threads work? What are the modules that work? +------------------------------------------------- + +XXX + +------------------------------------ +Can I use CPython extension modules? +------------------------------------ + +XXX +------------------------------------------ +How do I write extension modules for PyPy? +------------------------------------------ + +XXX + +----------------- +How fast is PyPy? +----------------- + +.. _whysoslow: + +As of August 2005, PyPy was successfully translated to C. Compared to +CPython the version of PyPy that still runs on top of CPython is slower by +a factor of 2000. The first translated version was roughly 300 times slower +than CPython, version 0.8.0 about 10-20 times and the current version (0.9) +is about 4-7 times slower than CPython. + +Our translation process does not try to optimize the produced code very +much. So far the project has been focused on getting a well tested very +compliant self-contained static Python implementation. During end 2005 +and 2006 we are targetting optimizations at various levels. If you then +still think that PyPy is slow then we will have to find a better answer +:-) XXX + + + +Development +======================================================================== + +----------------------------------------------------------- +How do I get into PyPy development? Can I come to sprints? +----------------------------------------------------------- + +XXX + +---------------------------------- +Why so many levels of abstraction? +---------------------------------- + +XXX see pypy-vm-construction + +---------------------------------------------------------------------- I am getting strange errors while playing with PyPy, what should I do? ---------------------------------------------------------------------- @@ -25,17 +97,66 @@ treatment please send us a bug report (or even better, a fix :-) -Using the PyPy translation tool chain -============================================================ +PyPy translation tool chain +======================================================================== + +------------------------------ +What is this RPython language? +------------------------------ + +XXX + +------------------------------------------------------------------- +Couldn't we simply take a Python syntax tree and turn it into Lisp? +------------------------------------------------------------------- + +It's not necessarily nonsense, but it's not really The PyPy Way. It's +pretty hard, without some kind of type inference, to translate, say this +Python:: + + a + b + +into anything significantly more efficient than this Common Lisp:: + + (py:add a b) + +And making type inference possible is what RPython is all about. + +You could make ``#'py:add`` a generic function and see if a given CLOS +implementation is fast enough to give a useful speed (but I think the +coercion rules would probably drive you insane first). -- mwh + +-------------------------------------------- +Do I have to rewrite my programs in RPython? +-------------------------------------------- + +No. PyPy always runs your code in its own interpreter, which is a full +and compliant Python 2.4 interpreter. RPython_ is only the language in +which parts of PyPy itself are written. XXX + +------------------------- +Which backends are there? +------------------------- + +XXX + +------------------------------------------------------- +Are there other projects that need the PyPy tool chain? +------------------------------------------------------- + +XXX + +---------------------- How do I compile PyPy? ---------------------- See the `getting-started`_ guide. Note that at the moment this produces an executable that contains a lot of things that are hard-coded for your particular system (including paths and other stuff), so it's not -suitable for being installed or redistributed. +suitable for being installed or redistributed. XXX +--------------------------------- How do I compile my own programs? --------------------------------- @@ -48,14 +169,17 @@ You can have a look at intermediate C source code, which is (at the moment) put in ``/tmp/usession-*/testing_1/testing_1.c``. Of course, all the function and stuff indirectly used by your ``entry_point()`` -function has to be RPython_. +function has to be RPython_. XXX +-------------------------------------------- Why isn't there a simpler way of doing that? -------------------------------------------- One answer is that "officially speaking" supporting this is not a goal of the PyPy project (RPython is essentially an implementation detail). +XXX + A better answer might be that when the target of compilation turns out not to be RPython, working out *why* can be very difficult, and working on the annotator to make these messages clearer -- even if @@ -68,55 +192,11 @@ "RPython standard library"). -Compiling to other languages -============================================================ - -Couldn't we simply take a Python syntax tree and turn it into Lisp? -------------------------------------------------------------------- - -It's not necessarily nonsense, but it's not really The PyPy Way. It's -pretty hard, without some kind of type inference, to translate, say this -Python:: - - a + b - -into anything significantly more efficient than this Common Lisp:: - - (py:add a b) - -And making type inference possible is what RPython is all about. - -You could make ``#'py:add`` a generic function and see if a given CLOS -implementation is fast enough to give a useful speed (but I think the -coercion rules would probably drive you insane first). -- mwh - - -Speed -============================================================ - -How fast is PyPy? ------------------ - -As of August 2005, PyPy was successfully translated to C. Compared to -CPython the version of PyPy that still runs on top of CPython is slower by -a factor of 2000. The first translated version was roughly 300 times slower -than CPython, version 0.8.0 about 10-20 times and the current version (0.9) -is about 4-7 times slower than CPython. - -On the other hand, the really interesting -question is: Why is PyPy so slow? +--------------------------------------------------------------------------- +What does the error message "slice start must be proven non-negative" mean? +--------------------------------------------------------------------------- -.. _whysoslow: - -Why is PyPy so slow? --------------------- - -Our translation process does not try to optimize the produced code very -much. So far the project has been focused on getting a well tested very -compliant self-contained static Python implementation. During end 2005 -and 2006 we are targetting optimizations at various levels. If you then -still think that PyPy is slow then we will have to find a better answer -:-) +XXX Modified: pypy/dist/pypy/doc/standalone-howto.txt ============================================================================== --- pypy/dist/pypy/doc/standalone-howto.txt (original) +++ pypy/dist/pypy/doc/standalone-howto.txt Fri Feb 9 17:33:06 2007 @@ -122,7 +122,7 @@ equivalents. -.. _`FAQ Entries`: faq.html#using-the-pypy-translation-tool-chain +.. _`FAQ Entries`: faq.html#pypy-translation-tool-chain .. _`RPython`: coding-guide.html#restricted-python .. _`Annotator`: dynamic-language-translation.html#annotator .. _`RTyper`: dynamic-language-translation.html#rtyper From mwh at codespeak.net Fri Feb 9 17:38:23 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 9 Feb 2007 17:38:23 +0100 (CET) Subject: [pypy-svn] r38270 - in pypy/dist/pypy/jit/codegen/ppc: . test Message-ID: <20070209163823.946AE1009D@code0.codespeak.net> Author: mwh Date: Fri Feb 9 17:38:09 2007 New Revision: 38270 Modified: pypy/dist/pypy/jit/codegen/ppc/instruction.py pypy/dist/pypy/jit/codegen/ppc/rgenop.py pypy/dist/pypy/jit/codegen/ppc/test/test_rgenop.py Log: pass the read_frame_var tests too. Modified: pypy/dist/pypy/jit/codegen/ppc/instruction.py ============================================================================== --- pypy/dist/pypy/jit/codegen/ppc/instruction.py (original) +++ pypy/dist/pypy/jit/codegen/ppc/instruction.py Fri Feb 9 17:38:09 2007 @@ -536,6 +536,20 @@ def emit(self, asm): asm.stw(self.arg_reg.number, rFP, self.target_slot.offset) +class CopyOffStack(Insn): + def __init__(self, v, place): + Insn.__init__(self) + self.reg_args = [] + self.reg_arg_regclasses = [] + self.result = v + self.result_regclass = GP_REGISTER + self.place = place + def allocate(self, allocator): + self.result_reg = allocator.loc_of(self.result) + allocator.free_stack_slots.append(stack_slot(self.place.offset)) + def emit(self, asm): + asm.lwz(self.result_reg.number, rFP, self.place.offset) + class SpillCalleeSaves(Insn): def __init__(self): Insn.__init__(self) Modified: pypy/dist/pypy/jit/codegen/ppc/rgenop.py ============================================================================== --- pypy/dist/pypy/jit/codegen/ppc/rgenop.py (original) +++ pypy/dist/pypy/jit/codegen/ppc/rgenop.py Fri Feb 9 17:38:09 2007 @@ -243,7 +243,6 @@ self.initial_var2loc = None self.max_param_space = -1 self.final_jump_addr = 0 - self.forced_into_stack = None self.start = 0 self.closed = True @@ -383,19 +382,26 @@ return gv_result def get_frame_info(self, vars_gv): - if self.forced_into_stack is None: - self.forced_into_stack = [] result = [] for v in vars_gv: if isinstance(v, Var): place = StackInfo() self.insns.append(insn.CopyIntoStack(place, v)) - self.forced_into_stack.append((v, place)) result.append(place) else: result.append(None) return result + def alloc_frame_place(self, kind, gv_initial_value): + place = StackInfo() + self.insns.append(insn.CopyIntoStack(place, gv_initial_value)) + return place + + def genop_absorb_place(self, kind, place): + var = Var() + self.insns.append(insn.CopyOffStack(var, place)) + return var + def enter_next_block(self, kinds, args_gv): if DEBUG_PRINT: print 'enter_next_block1', args_gv @@ -1072,6 +1078,15 @@ else: return lltype.cast_primitive(T, value) + at specialize.arg(0) +def cast_whatever_to_int(T, value): + if isinstance(T, lltype.Ptr): + return lltype.cast_ptr_to_int(value) + elif T is llmemory.Address: + return llmemory.cast_adr_to_int(value) + else: + return lltype.cast_primitive(lltype.Signed, value) + class RPPCGenOp(AbstractRGenOp): # the set of registers we consider available for allocation @@ -1201,19 +1216,19 @@ assert isinstance(place, GenConst) return place.revealconst(T) - #@staticmethod - #@specialize.arg(0) - #def write_frame_place(T, base, place, value): - # """Write into a place in the stack frame of a caller. The - # 'base' is the frame stack pointer captured by the operation - # generated by genop_get_frame_base().""" - - #@staticmethod - #@specialize.arg(0) - #def read_frame_place(T, base, place): - # """Read from a place in the stack frame of a caller. The - # 'base' is the frame stack pointer captured by the operation - # generated by genop_get_frame_base().""" + + @staticmethod + @specialize.arg(0) + def write_frame_place(T, base, place, value): + assert place.offset != 0 + value = cast_whatever_to_int(T, value) + poke_word_into(base + place.offset, value) + + @staticmethod + @specialize.arg(0) + def read_frame_place(T, base, place): + value = peek_word_at(base + place.offset) + return cast_int_to_whatever(T, value) def check_no_open_mc(self): pass @@ -1329,3 +1344,14 @@ from ctypes import cast, c_void_p, c_int, POINTER p = cast(c_void_p(addr), POINTER(c_int)) return p[0] + +def poke_word_into(addr, value): + # now the Very Obscure Bit: when translated, 'addr' is an + # address. When not, it's an integer. It just happens to + # make the test pass, but that's probably going to change. + if we_are_translated(): + addr.signed[0] = value + else: + from ctypes import cast, c_void_p, c_int, POINTER + p = cast(c_void_p(addr), POINTER(c_int)) + p[0] = value Modified: pypy/dist/pypy/jit/codegen/ppc/test/test_rgenop.py ============================================================================== --- pypy/dist/pypy/jit/codegen/ppc/test/test_rgenop.py (original) +++ pypy/dist/pypy/jit/codegen/ppc/test/test_rgenop.py Fri Feb 9 17:38:09 2007 @@ -21,13 +21,6 @@ class TestRPPCGenop(AbstractRGenOpTests): RGenOp = RPPCGenOp -# def test_read_frame_var_direct(self): py.test.skip("in-progress") -# def test_read_frame_var_compile(self): py.test.skip("in-progress") - def test_write_frame_place_direct(self): py.test.skip("in-progress") - def test_write_frame_place_compile(self): py.test.skip("in-progress") - def test_read_frame_place_direct(self): py.test.skip("in-progress") - def test_read_frame_place_compile(self): py.test.skip("in-progress") - class TestRPPCGenopNoRegs(TestRPPCGenop): RGenOp = FewRegisters From cfbolz at codespeak.net Fri Feb 9 17:49:12 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 9 Feb 2007 17:49:12 +0100 (CET) Subject: [pypy-svn] r38271 - pypy/dist/pypy/doc Message-ID: <20070209164912.5561E1009D@code0.codespeak.net> Author: cfbolz Date: Fri Feb 9 17:48:53 2007 New Revision: 38271 Modified: pypy/dist/pypy/doc/coding-guide.txt pypy/dist/pypy/doc/objspace.txt Log: unify the lists of the object space interface in coding-guide and objspace. Clean up the coding guide a bit. Modified: pypy/dist/pypy/doc/coding-guide.txt ============================================================================== --- pypy/dist/pypy/doc/coding-guide.txt (original) +++ pypy/dist/pypy/doc/coding-guide.txt Fri Feb 9 17:48:53 2007 @@ -31,7 +31,7 @@ Compared to the CPython implementation, Python takes the role of the C Code. We rewrite the CPython interpreter in Python itself. We could -also aim at writing a more flexible interpreter at C level but but we +also aim at writing a more flexible interpreter at C level but we want to use Python to give an alternative description of the interpreter. The clear advantage is that such a description is shorter and simpler to @@ -121,7 +121,8 @@ In any case, it should be obvious that the application-level implementation is definitely more readable, more elegant and more maintainable than the -interpreter-level one. +interpreter-level one (and indeed, dict.update is really implemented at appleve +in PyPy). In fact, in almost all parts of PyPy, you find application level code in the middle of interpreter-level code. Apart from some bootstrapping @@ -140,17 +141,20 @@ rules which make translation to lower level languages feasible. Code on application level can still use the full expressivity of Python. -Unlike source-to-source translations (like e.g. Starkiller_) we start +Unlike source-to-source translations (like e.g. Starkiller_ or more recently +ShedSkin_) we start translation from live python code objects which constitute our Python interpreter. When doing its work of interpreting bytecode our Python implementation must behave in a static way often referenced as "RPythonic". .. _Starkiller: http://www.python.org/pycon/dc2004/papers/1/paper.pdf +.. _ShedSkin: http://shed-skin.blogspot.com/ However, when the PyPy interpreter is started as a Python program, it -can use all of the Python language until it reaches interpretation -runtime. That is, during initialization our program is free to use the +can use all of the Python language until it reaches a certain point in +time, from which on everything that is being executed must be static. +That is, during initialization our program is free to use the full dynamism of Python, including dynamic code generation. An example can be found in the current implementation which is quite @@ -240,7 +244,9 @@ **integer, float, string, boolean** - avoid string methods and complex operations like slicing with a step + a lot of, but not all string methods are supported. When slicing a string + it is necessary to prove that the slice start and stop indexes are + non-negative. **tuples** @@ -312,7 +318,10 @@ **classes** + methods and other class attributes do not change after startup -+ inheritance is supported ++ single inheritance is fully supported ++ simple mixins work too, but the mixed in class needs a ``_mixin_ = True`` + class attribute + + classes are first-class objects too **objects** @@ -342,6 +351,7 @@ .. _`pypy/rlib/rarithmetic.py`: ../../pypy/rlib/rarithmetic.py + **ovfcheck()** This special function should only be used with a single arithmetic operation @@ -509,117 +519,20 @@ It is not allowed to inspect them directly. The allowed operations are all implemented on the object space: they are called ``space.xxx()``, where ``xxx`` is a standard operation -name (``add``, ``getattr``, ``call``, ``eq``...). The list of -standard operations is found in the large table near the end -of ``pypy.interpreter.baseobjspace``. These operations take -wrapped arguments and return a wrapped result (or sometimes -just None). - -Also note some helpers: - -* ``space.call_function(w_callable, ...)``: collects the given - (already-wrapped) arguments, builds a wrapped tuple for - them, and uses ``space.call()`` to perform the call. - -* ``space.call_method(w_object, 'method', ...)``: uses - ``space.getattr()`` to get the method object, and then - ``space.call_function()`` to invoke it. - - -Building ``w_xxx`` objects --------------------------- - -From the bytecode interpreter, wrapped objects are usually built as the result of -an object space operation. The ways to directly create a wrapped object are: +name (``add``, ``getattr``, ``call``, ``eq``...). They are documented in the +`object space document`_. -* ``space.wrap(x)``: returns a wrapped object containing the - value ``x``. Only works if ``x`` is either a simple value - (integer, float, string) or an instance of an internal - bytecode interpreter class (Function, Code, Frame...). - -* ``space.newlist([w_x, w_y, w_z...])``: returns a wrapped - list from a list of already-wrapped objects. - -* ``space.newtuple([w_x, w_y, w_z...])``: returns a wrapped - tuple from a list of already-wrapped objects. - -* ``space.newdict([])``: returns a new, empty wrapped - dictionary. (The argument list can contain tuples ``(w_key, - w_value)`` but it seems that such a use is not common.) - -* ``space.newbool(x)``: returns ``space.w_False`` or - ``space.w_True`` depending on the truth value of ``x``. - -There are a few less common constructors, described in the -comments at the end of ``pypy.interpreter.baseobjspace``. - - -Constant ``w_xxx`` objects --------------------------- +A short warning: **don't do** ``w_x == w_y`` or ``w_x is w_y``! +rationale for this rule is that there is no reason that two +wrappers are related in any way even if they contain what +looks like the same object at application-level. To check +for equality, use ``space.is_true(space.eq(w_x, w_y))`` or +even better the short-cut ``space.eq_w(w_x, w_y)`` returning +directly a interpreter-level bool. To check for identity, +use ``space.is_true(space.is_(w_x, w_y))`` or better +``space.is_w(w_x, w_y)``. -The object space holds a number of predefined wrapped objects. -The most common ones are ``space.w_None`` and -``space.w_XxxError`` for each exception class ``XxxError`` -(e.g. ``space.w_KeyError``, ``space.w_IndexError``, etc.). - - -Inspecting and unwrapping ``w_xxx`` objects --------------------------------------------- - -The most delicate operation is for the bytecode interpreter to inspect -a wrapped object, which must be done via the object space. - -* ``space.is_true(w_x)``: checks if the given wrapped object - is considered to be ``True`` or ``False``. You must never - use the truth-value of ``w_x`` directly; doing so (e.g. - writing ``if w_x:``) will give you an error reminding you of - the problem. - -* ``w_x == w_y`` or ``w_x is w_y``: DON'T DO THAT. The - rationale for this rule is that there is no reason that two - wrappers are related in any way even if they contain what - looks like the same object at application-level. To check - for equality, use ``space.is_true(space.eq(w_x, w_y))`` or - even better the short-cut ``space.eq_w(w_x, w_y)`` returning - directly a interpreter-level bool. To check for identity, - use ``space.is_true(space.is_(w_x, w_y))`` or better - ``space.is_w(w_x, w_y)``. - -* ``space.unpackiterable(w_x)``: this helper iterates ``w_x`` - (using ``space.iter()`` and ``space.next()``) and collects - the resulting wrapped objects in a list. Of course, in - cases where iterating directly is better than collecting the - elements in a list first, you should use ``space.iter()`` - and ``space.next()`` directly. - -* ``space.unwrap(w_x)``: inverse of ``space.wrap()``. - Attention! Using ``space.unwrap()`` must be avoided - whenever possible, i.e. only use this when you are well - aware that you are cheating, in unit tests or bootstrapping - code. - -* ``space.interpclass_w(w_x)``: If w_x is a wrapped instance - of an interpreter class -- for example Function, Frame, - Cell, etc. -- return it unwrapped. Otherwise return None. - -* ``space.int_w(w_x)``: If w_x is an application-level integer - or long which can be converted without overflow to an - integer, return an interpreter-level integer. Otherwise - raise TypeError or OverflowError. - -* ``space.str_w(w_x)``: If w_x is an application-level string, - return an interpreter-level string. Otherwise raise - TypeError. - -* ``space.float_w(w_x)``: If w_x is an application-level - float, integer or long, return interpreter-level float. - Otherwise raise TypeError or OverflowError in case of very - large longs. - -Remember that you can usually obtain the information you want -by invoking operations or methods on the wrapped objects; e.g. -``space.call_method(w_dict, 'iterkeys')`` returns a wrapped -iterable that you can decode with ``space.unpackiterable()``. +.. _`object space document`: objspace.html#interface .. _`applevel-exceptions`: @@ -679,14 +592,15 @@ When we need access to interpreter-level objects we put the module into `pypy/module`_. Such modules use a `mixed module mechanism`_ -which makes it convenient to use both interpreter- and applicationlevel -parts for the implementation. Note that there is no extra facility for -pure-interpreter level modules because we haven't needed it so far. +which makes it convenient to use both interpreter- and applicationlevel parts +for the implementation. Note that there is no extra facility for +pure-interpreter level modules, you just write a mixed module and leave the +application-level part empty. Determining the location of a module implementation --------------------------------------------------- -You can interactively find out where a module comes from, +You can interactively find out where a module comes from, when running py.py. here are examples for the possible locations:: >>>> import sys @@ -734,7 +648,7 @@ *lib-python/2.4.1/* - The unmodified CPython library. **Never ever checkin anything here**. + The unmodified CPython library. **Never ever check anything in there**. .. _`modify modules`: Modified: pypy/dist/pypy/doc/objspace.txt ============================================================================== --- pypy/dist/pypy/doc/objspace.txt (original) +++ pypy/dist/pypy/doc/objspace.txt Fri Feb 9 17:48:53 2007 @@ -63,6 +63,8 @@ .. _`in another document`: translation.html .. _`Object Space proxies`: objspace-proxies.html +.. _interface: + Object Space Interface ====================== @@ -105,9 +107,6 @@ **call(w_callable, w_args, w_kwds):** Call a function with the given args and keywords. -**call_function(w_callable, *args_w, **kw_w):** - Convenience function that collects the arguments in a wrapped tuple and dict and invokes 'call()'. - **is_(w_x, w_y):** Implements 'w_x is w_y'. (Returns a wrapped result too!) @@ -117,6 +116,44 @@ **exception_match(w_exc_type, w_check_class):** Checks if the given exception type matches 'w_check_class'. Used in matching the actual exception raised with the list of those to catch in an except clause. (Returns a wrapped result too!) +Convenience Functions +--------------------- + +The following functions are part of the object space interface but would not be +strictly necessary because they can be expressed using several other object +space methods. However, they are used so often that it seemed worthwhile to +introduce them as shortcuts. + +**eq_w(w_obj1, w_obj2):** + Returns true when w_obj1 and w_obj2 are equal. Shortcut for + space.is_true(space.eq(w_obj1, w_obj2)) + +**is_w(w_obj1, w_obj2):** + Shortcut for space.is_true(space.is_(w_obj1, w_obj2)) + +**hash_w(w_obj):** + Shortcut for space.int_w(space.hash(w_obj)) + +**call_function(w_callable, *args_w, **kw_w):** + Convenience function that collects the arguments in a wrapped tuple and dict + and invokes 'space.call(w_callable, ...)'. + +**space.call_method(w_object, 'method', ...)**: uses + ``space.getattr()`` to get the method object, and then + ``space.call_function()`` to invoke it. + +**unpackiterable(w_iterable, expected_length=-1):** + this helper iterates ``w_x`` + (using ``space.iter()`` and ``space.next()``) and collects + the resulting wrapped objects in a list. If ``expected_length`` is given and + the length does not match, an exception is raised. Of course, in cases where + iterating directly is better than collecting the elements in a list first, + you should use ``space.iter()`` and ``space.next()`` directly. + +**unpacktuple(w_tuple, expected_length=None):** + Same as unpackiterable(), but only for tuples. + + Creation of Application Level objects --------------------------------------- @@ -128,16 +165,16 @@ internal bytecode interpreter classes). **newbool(b):** - Creates a Bool Object from an interpreter level object. + Creates a wrapped bool object from an interpreter level object. -**newtuple([..]):** - Take an interpreter level list of wrapped objects. +**newtuple([w_x, w_y, w_z, ...]):** + Makes a new wrapped tuple out of an interpreter level list of wrapped objects. **newlist([..]):** Takes an interpreter level list of wrapped objects. -**newdict([..]):** - Takes an interpreter level list of interpreter level pairs of wrapped key:wrapped value entries (and NOT an interpreter level dictionary!). +**newdict():** + Returns a new empty dictionary. **newslice(w_start, w_end, w_step):** Makes a new slice object. @@ -152,7 +189,11 @@ ---------------------------------------------------------- **unwrap(w_x):** - Return Interpreter Level equivalent of w_x + Return Interpreter Level equivalent of w_x. + Attention! Using ``space.unwrap()`` must be avoided + whenever possible, i.e. only use this when you are well + aware that you are cheating, in unit tests or bootstrapping + code. **interpclass_w(w_x):** If w_x is a wrapped instance of an bytecode interpreter class -- for example @@ -173,23 +214,20 @@ **is_true(w_x):** Return a interpreter level bool (True or False). -**unpackiterable(w_iterable, expected_length=None):** - Unpack an iterable object into a real (interpreter level) list. Raise a real ValueError if the expected_length is wrong. - -**unpacktuple(w_tuple, expected_length=None):** - Same as unpackiterable(), but only for tuples. - Data Members ----------------- -+ self.builtin -+ self.sys -+ self.w_None: The ObjSpace's None -+ self.w_True: The ObjSpace's True -+ self.w_False: The ObjSpace's False -+ self.w_Ellipsis: The ObjSpace's Ellipsis -+ self.w_NotImplemented: The ObjSpace's NotImplemented ++ space.builtin ++ space.sys ++ space.w_None: The ObjSpace's None ++ space.w_True: The ObjSpace's True ++ space.w_False: The ObjSpace's False ++ space.w_Ellipsis: The ObjSpace's Ellipsis ++ space.w_NotImplemented: The ObjSpace's NotImplemented + ++ space.w_XxxError`` for each exception class ``XxxError`` + (e.g. ``space.w_KeyError``, ``space.w_IndexError``, etc.). + ObjSpace.MethodTable: List of tuples (method name, symbol, number of arguments, list of special names) for the regular part of the interface. (Tuples are interpreter level.) @@ -204,6 +242,7 @@ List of names of exception classes. + .. _`standard object space`: The Standard Object Space From arigo at codespeak.net Fri Feb 9 17:56:55 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 9 Feb 2007 17:56:55 +0100 (CET) Subject: [pypy-svn] r38272 - pypy/dist/pypy/doc Message-ID: <20070209165655.950DC10094@code0.codespeak.net> Author: arigo Date: Fri Feb 9 17:56:45 2007 New Revision: 38272 Modified: pypy/dist/pypy/doc/glossary.txt Log: links to theory.html from glossary.txt. Modified: pypy/dist/pypy/doc/glossary.txt ============================================================================== --- pypy/dist/pypy/doc/glossary.txt (original) +++ pypy/dist/pypy/doc/glossary.txt Fri Feb 9 17:56:45 2007 @@ -2,6 +2,12 @@ document gives brief definition of some of these terms and provides links to more information. +**abstract interpretation** + The technique of interpreting the bytecode of a user program with + an interpreter that handles abstract objects instead of concrete ones. + It can be used to check the bytecode or see what it does, without + actually executing it with concrete values. See Theory_. + .. _annotator: **annotator** @@ -98,6 +104,11 @@ .. _`object space`: +**multimethod** + A callable object that invokes a different Python function based + on the type of all its arguments (instead of just the class of the + first argument, as with normal methods). See Theory_. + **object space** The `object space `__ (often abbreviated to "objspace") creates all objects and knows how to perform operations @@ -228,5 +239,6 @@ .. _Python: http://www.python.org .. _`RPython Typer`: rtyper.html .. _`subsystem implementing the Python language`: architecture.html#standard-interpreter +.. _Theory: theory.html .. include:: _ref.txt From arigo at codespeak.net Fri Feb 9 18:06:02 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 9 Feb 2007 18:06:02 +0100 (CET) Subject: [pypy-svn] r38273 - pypy/dist/pypy/doc Message-ID: <20070209170602.92C1B100A0@code0.codespeak.net> Author: arigo Date: Fri Feb 9 18:05:57 2007 New Revision: 38273 Modified: pypy/dist/pypy/doc/_ref.txt pypy/dist/pypy/doc/index.txt Log: Trying to reorder the index.txt entries again. Modified: pypy/dist/pypy/doc/_ref.txt ============================================================================== --- pypy/dist/pypy/doc/_ref.txt (original) +++ pypy/dist/pypy/doc/_ref.txt Fri Feb 9 18:05:57 2007 @@ -60,6 +60,7 @@ .. _`objspace/logic.py`: ../../pypy/objspace/logic.py .. _`objspace/std/`: .. _`pypy/objspace/std`: ../../pypy/objspace/std +.. _`objspace/taint.py`: ../../pypy/objspace/taint.py .. _`objspace/thunk.py`: .. _`pypy/objspace/thunk.py`: ../../pypy/objspace/thunk.py .. _`objspace/trace.py`: Modified: pypy/dist/pypy/doc/index.txt ============================================================================== --- pypy/dist/pypy/doc/index.txt (original) +++ pypy/dist/pypy/doc/index.txt Fri Feb 9 18:05:57 2007 @@ -5,15 +5,31 @@ .. _Python: http://www.python.org/dev/doc/maint24/ref/ref.html .. sectnum:: -.. contents:: +.. contents:: :depth: 1 -Meta-documentation -===================================== +PyPy User Documentation +=============================================== `getting started`_ provides hands-on instructions including a two-liner to run PyPy on your system. +`FAQ`_ contains some frequently asked questions. + +New features of PyPy (available from optional built-in modules): + * `What PyPy can do for your objects`_ + * `Stackless and coroutines`_ + +`extension compiler`_ describes the (in-progress) tool that can be used +to write modules in PyPy's style and compile them into regular CPython +extension modules. + +Status_ of the project. + + +Meta-Documentation +===================================== + `coding guide`_ helps you to write code for PyPy (especially also describes coding in RPython a bit). @@ -31,16 +47,37 @@ `PyPy video documentation`_ is a page linking to the videos (e.g. of talks and introductions) that are available. -`license`_ contains licensing details (basically a straight MIT-license). +`EU reports`_ is a page that contains links to the +reports that we submitted to the European Union. -`FAQ`_ contains the beginning of frequently asked questions. -Right now it's a bit empty. +`license`_ contains licensing details (basically a straight MIT-license). `Glossary`_ of PyPy words to help you align your inner self with the PyPy universe. -PyPy documentation +Status +=================================== + +PyPy is mainly developed on Linux and Mac OS X. Windows is supported, +but platform-specific bugs tend to take longer before we notice and fix +them. About 64-bit machines: although support is mostly present, we +decided to stop tracking and fixing the remaining issues for a while, as +an attempt to keep some focus. So PyPy requires a 32-bit machine or OS +for now. + +PyPy's own tests, daily updated, `on Linux`_, on Windows (unavailable +at the moment) and `on built pypy-c`_. + +`Nightly builds and benchmarks`_ of PyPy to C, CLI and LLVM (PowerPC machine). + +`compliance test status`_ shows outcomes of +recent compliance test runs against PyPy. + +`PyPy statistics`_ shows LOC statistics about PyPy. + + +Source Code Documentation =============================================== architecture_ gives a complete view of PyPy's basic design. @@ -73,10 +110,6 @@ `garbage collection`_ contains documentation about garbage collection in PyPy. -`extension compiler`_ describes the (in-progress) tool that can be used -to write modules in PyPy's style and compile them into regular CPython -extension modules. - `rlib`_ describes some modules that can be used when implementing programs in RPython. @@ -86,50 +119,6 @@ `JIT Generation in PyPy`_ describes how we produce the Python Just-in-time Compiler from our Python interpreter. -`EU reports`_ is a page that contains links to the -preliminary reports that we submitted to the European Union. - - -New Python features -========================================== - -(Note that emphasis so far has not been on adding new features to the -Python language. These new features are experimental, and require you -to enable them explicitly while running or translating PyPy.) - -The Thunk_ Object Space: lazily computed objects. - -Stackless_ and coroutines - -`Logic and Constraint`_ programming features - -`Transparent proxy`_ implementation - -.. _Thunk: getting-started.html#lazily-computed-objects -.. _Stackless: stackless.html -.. _`Logic and Constraint`: howto-logicobjspace-0.9.html -.. _`Transparent proxy`: objspace-proxies.html#tproxy - - -Status -====================================== - -PyPy is mainly developed on Linux and Mac OS X. Windows is supported, -but platform-specific bugs tend to take longer before we notice and fix -them. About 64-bit machines: although support is mostly present, we -decided to stop tracking and fixing the remaining issues for a while, as -an attempt to keep some focus. So PyPy requires a 32-bit machine or OS -for now. - -PyPy's own tests, daily updated, `on Linux`_, on Windows (unavailable -at the moment) and `on built pypy-c`_. - -`Nightly builds and benchmarks`_ of PyPy to C, CLI and LLVM. - -`compliance test status`_ shows outcomes of -recent compliance test runs against PyPy. - -`PyPy statistics`_ shows LOC statistics about PyPy. .. _`FAQ`: faq.html @@ -163,7 +152,7 @@ .. _`rlib`: rlib.html PyPy directory cross-reference -====================================================== +------------------------------ Here is a fully referenced alphabetical two-level deep directory overview of PyPy: @@ -223,6 +212,8 @@ `objspace/dump.py`_ the dump object space saves a large, searchable log file with all operations +`objspace/taint.py`_ the `taint object space`_, providing object tainting + `objspace/thunk.py`_ the `thunk object space`_, providing unique object features `objspace/logic.py`_ the `logic object space`_, providing Prolog-like logic variables @@ -295,8 +286,11 @@ .. _`object space`: objspace.html .. _FlowObjSpace: objspace.html#the-flow-object-space .. _`trace object space`: objspace.html#the-trace-object-space +.. _`taint object space`: objspace-proxies.html#taint .. _`thunk object space`: objspace-proxies.html#thunk -.. _`logic object space`: constraints-and-logic.html#logic-programming +.. _`logic object space`: objspace-proxies.html#logic +.. _`What PyPy can do for your objects`: objspace-proxies.html +.. _`Stackless and coroutines`: stackless.html .. _StdObjSpace: objspace.html#the-standard-object-space .. _`abstract interpretation`: theory.html#abstract-interpretation .. _`rpython`: coding-guide.html#rpython From cfbolz at codespeak.net Fri Feb 9 18:07:31 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 9 Feb 2007 18:07:31 +0100 (CET) Subject: [pypy-svn] r38274 - pypy/dist/pypy/doc Message-ID: <20070209170731.E21A71008D@code0.codespeak.net> Author: cfbolz Date: Fri Feb 9 18:07:27 2007 New Revision: 38274 Modified: pypy/dist/pypy/doc/objspace.txt Log: consistently mark up code with ``...`` instead of **...**. Reflow some veeery loong paragraphs (no content changes). Modified: pypy/dist/pypy/doc/objspace.txt ============================================================================== --- pypy/dist/pypy/doc/objspace.txt (original) +++ pypy/dist/pypy/doc/objspace.txt Fri Feb 9 18:07:27 2007 @@ -74,10 +74,10 @@ Administrative Functions ---------------------------- -**initialize():** +``initialize():`` Function which initializes w_builtins and the other w_constants. -**getexecutioncontext():** +``getexecutioncontext():`` Return current active execution context. Operations on Objects in ObjSpace @@ -97,23 +97,25 @@ ``lt, le, eq, ne, gt, ge, contains,`` -``inplace_add, inplace_sub, inplace_mul, inplace_truediv, inplace_floordiv, inplace_div, inplace_mod, inplace_pow, inplace_lshift, inplace_rshift, inplace_and, inplace_or, inplace_xor,`` +``inplace_add, inplace_sub, inplace_mul, inplace_truediv, inplace_floordiv, +inplace_div, inplace_mod, inplace_pow, inplace_lshift, inplace_rshift, +inplace_and, inplace_or, inplace_xor,`` ``get, set, delete`` -**next(w):** +``next(w):`` Call the next function for iterator w, or raises a real NoValue. -**call(w_callable, w_args, w_kwds):** +``call(w_callable, w_args, w_kwds):`` Call a function with the given args and keywords. -**is_(w_x, w_y):** +``is_(w_x, w_y):`` Implements 'w_x is w_y'. (Returns a wrapped result too!) -**isinstance(w_obj, w_type):** +``isinstance(w_obj, w_type):`` Implements 'issubtype(type(w_obj), w_type)'. (Returns a wrapped result too!) -**exception_match(w_exc_type, w_check_class):** +``exception_match(w_exc_type, w_check_class):`` Checks if the given exception type matches 'w_check_class'. Used in matching the actual exception raised with the list of those to catch in an except clause. (Returns a wrapped result too!) Convenience Functions @@ -124,25 +126,26 @@ space methods. However, they are used so often that it seemed worthwhile to introduce them as shortcuts. -**eq_w(w_obj1, w_obj2):** +``eq_w(w_obj1, w_obj2):`` Returns true when w_obj1 and w_obj2 are equal. Shortcut for space.is_true(space.eq(w_obj1, w_obj2)) -**is_w(w_obj1, w_obj2):** +``is_w(w_obj1, w_obj2):`` Shortcut for space.is_true(space.is_(w_obj1, w_obj2)) -**hash_w(w_obj):** +``hash_w(w_obj):`` Shortcut for space.int_w(space.hash(w_obj)) -**call_function(w_callable, *args_w, **kw_w):** +``call_function(w_callable, *args_w, **kw_w):`` Convenience function that collects the arguments in a wrapped tuple and dict and invokes 'space.call(w_callable, ...)'. -**space.call_method(w_object, 'method', ...)**: uses +``space.call_method(w_object, 'method', ...)`` + uses ``space.getattr()`` to get the method object, and then ``space.call_function()`` to invoke it. -**unpackiterable(w_iterable, expected_length=-1):** +``unpackiterable(w_iterable, expected_length=-1):`` this helper iterates ``w_x`` (using ``space.iter()`` and ``space.next()``) and collects the resulting wrapped objects in a list. If ``expected_length`` is given and @@ -150,68 +153,68 @@ iterating directly is better than collecting the elements in a list first, you should use ``space.iter()`` and ``space.next()`` directly. -**unpacktuple(w_tuple, expected_length=None):** +``unpacktuple(w_tuple, expected_length=None):`` Same as unpackiterable(), but only for tuples. Creation of Application Level objects --------------------------------------- -**wrap(x):** +``wrap(x):`` Returns a wrapped object that is a reference to the interpreter-level object x. This can be used either on simple immutable objects (integers, strings...) to create a new wrapped object, or on complex mutable objects to obtain an application-level-visible reference to them (e.g. instances of internal bytecode interpreter classes). -**newbool(b):** +``newbool(b):`` Creates a wrapped bool object from an interpreter level object. -**newtuple([w_x, w_y, w_z, ...]):** +``newtuple([w_x, w_y, w_z, ...]):`` Makes a new wrapped tuple out of an interpreter level list of wrapped objects. -**newlist([..]):** +``newlist([..]):`` Takes an interpreter level list of wrapped objects. -**newdict():** +``newdict():`` Returns a new empty dictionary. -**newslice(w_start, w_end, w_step):** +``newslice(w_start, w_end, w_step):`` Makes a new slice object. -**newstring(asciilist):** +``newstring(asciilist):`` Creates a string from a list of wrapped integers. -**newunicode(codelist):** +``newunicode(codelist):`` Creates a unicode string from a list of integers. Conversions from Application Level to Interpreter Level ---------------------------------------------------------- -**unwrap(w_x):** +``unwrap(w_x):`` Return Interpreter Level equivalent of w_x. Attention! Using ``space.unwrap()`` must be avoided whenever possible, i.e. only use this when you are well aware that you are cheating, in unit tests or bootstrapping code. -**interpclass_w(w_x):** +``interpclass_w(w_x):`` If w_x is a wrapped instance of an bytecode interpreter class -- for example Function, Frame, Cell, etc. -- return it unwrapped. Otherwise return None. -**int_w(w_x):** +``int_w(w_x):`` If w_x is an application-level integer or long which can be converted without overflow to an integer, return an interpreter-level integer. Otherwise raise TypeError or OverflowError. -**bigint_w(w_x):** +``bigint_w(w_x):`` If w_x is an application-level integer or long, return an interpreter-level rbigint. Otherwise raise TypeError. -**str_w(w_x):** +``str_w(w_x):`` If w_x is an application-level string, return an interpreter-level string. Otherwise raise TypeError. -**float_w(w_x):** +``float_w(w_x):`` If w_x is an application-level float, integer or long, return interpreter-level float. Otherwise raise TypeError or OverflowError in case of very large longs. -**is_true(w_x):** +``is_true(w_x):`` Return a interpreter level bool (True or False). @@ -251,7 +254,9 @@ Introduction ------------ -The Standard Object Space (StdObjSpace_) is the direct equivalent of CPython's object library (the "Objects/" subdirectory in the distribution). It is an implementation of the common Python types in a lower-level language. +The Standard Object Space (StdObjSpace_) is the direct equivalent of CPython's +object library (the "Objects/" subdirectory in the distribution). It is an +implementation of the common Python types in a lower-level language. The Standard Object Space defines an abstract parent class, W_Object, and a bunch of subclasses like W_IntObject, W_ListObject, and so on. A wrapped @@ -275,11 +280,30 @@ space.wrap("integer addition")) return W_IntObject(space, z) -Why such a burden just for integer objects? Why did we have to wrap them into W_IntObject instances? For them it seems it would have been sufficient just to use plain Python integers. But this argumentation fails just like it fails for more complex kind of objects. Wrapping them just like everything else is the cleanest solution. You could introduce case testing wherever you use a wrapped object, to know if it is a plain integer or an instance of (a subclass of) W_Object. But that makes the whole program more complicated. The equivalent in CPython would be to use PyObject* pointers all around except when the object is an integer (after all, integers are directly available in C too). You could represent small integers as odd-valuated pointers. But it puts extra burden on the whole C code, so the CPython team avoided it. - -In our case it is a later optimization that we could make. We just don't want to make it now (and certainly not hard-coded at this level -- it could be introduced by the code generators at translation time). So in summary: wrapping integers as instances is the simple path, while using plain integers instead is the complex path, not the other way around. - -Note that the Standard Object Space implementation uses MultiMethod_ dispatch instead of the complex rules of "Object/abstract.c". This can probably be translated to a different low-level dispatch implementation that would be binary compatible with CPython's (basically the PyTypeObject structure and its function pointers). If compatibility is not required it will be more straightforwardly converted into some efficient multimethod code. +Why such a burden just for integer objects? Why did we have to wrap them into +W_IntObject instances? For them it seems it would have been sufficient just to +use plain Python integers. But this argumentation fails just like it fails for +more complex kind of objects. Wrapping them just like everything else is the +cleanest solution. You could introduce case testing wherever you use a wrapped +object, to know if it is a plain integer or an instance of (a subclass of) +W_Object. But that makes the whole program more complicated. The equivalent in +CPython would be to use PyObject* pointers all around except when the object is +an integer (after all, integers are directly available in C too). You could +represent small integers as odd-valuated pointers. But it puts extra burden on +the whole C code, so the CPython team avoided it. + +In our case it is a later optimization that we could make. We just don't want +to make it now (and certainly not hard-coded at this level -- it could be +introduced by the code generators at translation time). So in summary: wrapping +integers as instances is the simple path, while using plain integers instead is +the complex path, not the other way around. + +Note that the Standard Object Space implementation uses MultiMethod_ dispatch +instead of the complex rules of "Object/abstract.c". This can probably be +translated to a different low-level dispatch implementation that would be +binary compatible with CPython's (basically the PyTypeObject structure and its +function pointers). If compatibility is not required it will be more +straightforwardly converted into some efficient multimethod code. .. _StdObjSpace: http://codespeak.net/svn/pypy/dist/pypy/objspace/std/ .. _MultiMethod: theory.html#multimethods @@ -288,17 +312,39 @@ Object types ------------ -The larger part of the `StdObjSpace`_ package defines and implements the library of Python's standard built-in object types. Each type (int, float, list, tuple, str, type, etc.) is typically implemented by two modules: +The larger part of the `StdObjSpace`_ package defines and implements the +library of Python's standard built-in object types. Each type (int, float, +list, tuple, str, type, etc.) is typically implemented by two modules: * the *type specification* module, which for a type ``xxx`` is called ``xxxtype.py``; * the *implementation* module, called ``xxxobject.py``. -The ``xxxtype.py`` module basically defines the type object itself. For example, `listtype.py`_ contains the specification of the object you get when you type ``list`` in a PyPy prompt. `listtype.py`_ enumerates the methods specific to lists, like ``append()``. - -A particular method implemented by all types is the ``__new__()`` special method, which in Python's new-style-classes world is responsible for creating an instance of the type. In PyPy, ``__new__()`` locates and imports the module implementing *instances* of the type, and creates such an instance based on the arguments the user supplied to the constructor. For example, `tupletype.py`_ defines ``__new__()`` to import the class ``W_TupleObject`` from `tupleobject.py`_ and instantiate it. The `tupleobject.py`_ then contains a "real" implementation of tuples: the way the data is stored in the ``W_TupleObject`` class, how the operations work, etc. - -The goal of the above module layout is to cleanly separate the Python type object, visible to the user, and the actual implementation of its instances. It is possible (though not done so far) to provide *several* implementations of the instances of the same Python type. The ``__new__()`` method could decide to create one or the other. From the user's point of view, they are still all instances of exactly the same type; the possibly multiple internal ``W_XxxObject`` classes are not visible. PyPy knows that (e.g.) the application-level type of its interpreter-level ``W_TupleObject`` instances is "tuple" because there is a ``typedef`` class attribute in ``W_TupleObject`` which points back to the tuple type specification from `tupletype.py`_. +The ``xxxtype.py`` module basically defines the type object itself. For +example, `listtype.py`_ contains the specification of the object you get when +you type ``list`` in a PyPy prompt. `listtype.py`_ enumerates the methods +specific to lists, like ``append()``. + +A particular method implemented by all types is the ``__new__()`` special +method, which in Python's new-style-classes world is responsible for creating +an instance of the type. In PyPy, ``__new__()`` locates and imports the module +implementing *instances* of the type, and creates such an instance based on the +arguments the user supplied to the constructor. For example, `tupletype.py`_ +defines ``__new__()`` to import the class ``W_TupleObject`` from +`tupleobject.py`_ and instantiate it. The `tupleobject.py`_ then contains a +"real" implementation of tuples: the way the data is stored in the +``W_TupleObject`` class, how the operations work, etc. + +The goal of the above module layout is to cleanly separate the Python type +object, visible to the user, and the actual implementation of its instances. It +is possible (though not done so far) to provide *several* implementations of the +instances of the same Python type. The ``__new__()`` method could decide to +create one or the other. From the user's point of view, they are still all +instances of exactly the same type; the possibly multiple internal +``W_XxxObject`` classes are not visible. PyPy knows that (e.g.) the +application-level type of its interpreter-level ``W_TupleObject`` instances is +"tuple" because there is a ``typedef`` class attribute in ``W_TupleObject`` +which points back to the tuple type specification from `tupletype.py`_. .. _`listtype.py`: http://codespeak.net/svn/pypy/dist/pypy/objspace/std/listtype.py .. _`tupletype.py`: http://codespeak.net/svn/pypy/dist/pypy/objspace/std/tupletype.py @@ -372,7 +418,9 @@ Introduction ------------ -The task of the FlowObjSpace_ is to generate a control-flow graph from a function. This graph will also contain a trace of the individual operations, so that it is actually just an alternate representation for the function. +The task of the FlowObjSpace_ is to generate a control-flow graph from a +function. This graph will also contain a trace of the individual operations, so +that it is actually just an alternate representation for the function. The FlowObjSpace is an object space, which means that it exports the standard object space interface and it is driven by the bytecode interpreter. @@ -382,7 +430,13 @@ def f(n): return 3*n+2 -it will do whatever bytecode dispatching and stack-shuffling needed, during which it issues a sequence of calls to the object space. The FlowObjSpace merely records these calls (corresponding to "operations") in a structure called a basic block. To track which value goes where, the FlowObjSpace invents placeholder "wrapped objects" and give them to the interpreter, so that they appear in some next operation. This technique is an example of `Abstract Interpretation`_. +it will do whatever bytecode dispatching and stack-shuffling needed, during +which it issues a sequence of calls to the object space. The FlowObjSpace +merely records these calls (corresponding to "operations") in a structure called +a basic block. To track which value goes where, the FlowObjSpace invents +placeholder "wrapped objects" and give them to the interpreter, so that they +appear in some next operation. This technique is an example of `Abstract +Interpretation`_. .. _`Abstract Interpretation`: theory.html#abstract-interpretation @@ -402,73 +456,143 @@ The Flow model -------------- -``pypy.objspace.flow.model`` defines the data model used by the flow graphs, as created by the FlowObjSpace, manipulated by ``pypy.translator.simplify`` and ``pypy.translator.transform``, and in general read by almost all the modules in ``pypy.translator``. - -It is recommended to play with ``python translator.py`` on a few examples to get an idea of the structure of flow graphs. Here is a short summary of the non-obvious parts. +``pypy.objspace.flow.model`` defines the data model used by the flow graphs, as +created by the FlowObjSpace, manipulated by ``pypy.translator.simplify`` and +``pypy.translator.transform``, and in general read by almost all the modules in +``pypy.translator``. + +It is recommended to play with ``python translator.py`` on a few examples to get +an idea of the structure of flow graphs. Here is a short summary of the +non-obvious parts. FunctionGraph A container for one graph (corresponding to one function). - :startblock: the first block. It is where the control goes when the function is called. The input arguments of the startblock are the function's arguments. If the function takes a ``*args`` argument, the ``args`` tuple is given as the last input argument of the startblock. - :returnblock: the (unique) block that performs a function return. It is empty, not actually containing any ``return`` operation; the return is implicit. The returned value is the unique input variable of the returnblock. - :exceptblock: the (unique) block that raises an exception out of the function. The two input variables are the exception class and the exception value, respectively. (No other block will actually link to the exceptblock if the function does not explicitely raise exceptions.) + :startblock: the first block. It is where the control goes when the + function is called. The input arguments of the startblock are the + function's arguments. If the function takes a ``*args`` argument, the + ``args`` tuple is given as the last input argument of the startblock. + + :returnblock: the (unique) block that performs a function return. It is + empty, not actually containing any ``return`` operation; the return is + implicit. The returned value is the unique input variable of the + returnblock. + + :exceptblock: the (unique) block that raises an exception out of the + function. The two input variables are the exception class and the exception + value, respectively. (No other block will actually link to the exceptblock + if the function does not explicitely raise exceptions.) Block - A basic block, containing a list of operations and ending in jumps to other basic blocks. All the values that are "live" during the execution of the block are stored in Variables. Each basic block uses its own distinct Variables. + A basic block, containing a list of operations and ending in jumps to other + basic blocks. All the values that are "live" during the execution of the + block are stored in Variables. Each basic block uses its own distinct + Variables. + + :inputargs: list of fresh, distinct Variables that represent all the + values that can enter this block from any of the previous blocks. - :inputargs: list of fresh, distinct Variables that represent all the values that can enter this block from any of the previous blocks. :operations: list of SpaceOperations. :exitswitch: see below - :exits: list of Links representing possible jumps from the end of this basic block to the beginning of other basic blocks. + + :exits: list of Links representing possible jumps from the end of this + basic block to the beginning of other basic blocks. Each Block ends in one of the following ways: * unconditional jump: exitswitch is None, exits contains a single Link. - * conditional jump: exitswitch is one of the Variables that appear in the Block, and exits contains one or more Links (usually 2). Each Link's exitcase gives a concrete value. This is the equivalent of a "switch": the control follows the Link whose exitcase matches the run-time value of the exitswitch Variable. It is a run-time error if the Variable doesn't match any exitcase. - * exception catching: exitswitch is ``Constant(last_exception)``. The first Link has exitcase set to None and represents the non-exceptional path. The next Links have exitcase set to a subclass of Exception, and are taken when the *last* operation of the basic block raises a matching exception. (Thus the basic block must not be empty, and only the last operation is protected by the handler.) - * return or except: the returnblock and the exceptblock have operations set to an empty tuple, exitswitch to None, and exits empty. + + * conditional jump: exitswitch is one of the Variables that appear in the + Block, and exits contains one or more Links (usually 2). Each Link's + exitcase gives a concrete value. This is the equivalent of a "switch": + the control follows the Link whose exitcase matches the run-time value of + the exitswitch Variable. It is a run-time error if the Variable doesn't + match any exitcase. + + * exception catching: exitswitch is ``Constant(last_exception)``. The first + Link has exitcase set to None and represents the non-exceptional path. + The next Links have exitcase set to a subclass of Exception, and are taken + when the *last* operation of the basic block raises a matching exception. + (Thus the basic block must not be empty, and only the last operation is + protected by the handler.) + + * return or except: the returnblock and the exceptblock have operations set + to an empty tuple, exitswitch to None, and exits empty. Link A link from one basic block to another. :prevblock: the Block that this Link is an exit of. + :target: the target Block to which this Link points to. - :args: a list of Variables and Constants, of the same size as the target Block's inputargs, which gives all the values passed into the next block. (Note that each Variable used in the prevblock may appear zero, one or more times in the ``args`` list.) + + :args: a list of Variables and Constants, of the same size as the + target Block's inputargs, which gives all the values passed + into the next block. (Note that each Variable used in the + prevblock may appear zero, one or more times in the ``args`` + list.) + :exitcase: see above. + :last_exception: None or a Variable; see below. - :last_exc_value: None or a Variable; see below. - Note that ``args`` uses Variables from the prevblock, which are matched to the target block's ``inputargs`` by position, as in a tuple assignment or function call would do. + :last_exc_value: None or a Variable; see below. - If the link is an exception-catching one, the ``last_exception`` and ``last_exc_value`` are set to two fresh Variables that are considered to be created when the link is entered; at run-time, they will hold the exception class and value, respectively. These two new variables can only be used in the same link's ``args`` list, to be passed to the next block (as usual, they may actually not appear at all, or appear several times in ``args``). + Note that ``args`` uses Variables from the prevblock, which are matched to + the target block's ``inputargs`` by position, as in a tuple assignment or + function call would do. + + If the link is an exception-catching one, the ``last_exception`` and + ``last_exc_value`` are set to two fresh Variables that are considered to be + created when the link is entered; at run-time, they will hold the exception + class and value, respectively. These two new variables can only be used in + the same link's ``args`` list, to be passed to the next block (as usual, + they may actually not appear at all, or appear several times in ``args``). SpaceOperation A recorded (or otherwise generated) basic operation. - :opname: the name of the operation. Generally one from the list in ``pypy.interpreter.baseobjspace``. - :args: list of arguments. Each one is a Constant or a Variable seen previously in the basic block. + :opname: the name of the operation. Generally one from the list in + ``pypy.interpreter.baseobjspace``. + + :args: list of arguments. Each one is a Constant or a Variable seen + previously in the basic block. + :result: a *new* Variable into which the result is to be stored. - Note that operations usually cannot implicitly raise exceptions at run-time; so for example, code generators can assume that a ``getitem`` operation on a list is safe and can be performed without bound checking. The exceptions to this rule are: (1) if the operation is the last in the block, which ends with ``exitswitch == Constant(last_exception)``, then the implicit exceptions must be checked for, generated, and caught appropriately; (2) calls to other functions, as per ``simple_call`` or ``call_args``, can always raise whatever the called function can raise --- and such exceptions must be passed through to the parent unless they are caught as above. + Note that operations usually cannot implicitly raise exceptions at run-time; + so for example, code generators can assume that a ``getitem`` operation on a + list is safe and can be performed without bound checking. The exceptions to + this rule are: (1) if the operation is the last in the block, which ends + with ``exitswitch == Constant(last_exception)``, then the implicit + exceptions must be checked for, generated, and caught appropriately; (2) + calls to other functions, as per ``simple_call`` or ``call_args``, can + always raise whatever the called function can raise --- and such exceptions + must be passed through to the parent unless they are caught as above. Variable A placeholder for a run-time value. There is mostly debugging stuff here. - :name: it is good style to use the Variable object itself instead of its ``name`` attribute to reference a value, although the ``name`` is guaranteed unique. + :name: it is good style to use the Variable object itself instead of its + ``name`` attribute to reference a value, although the ``name`` is guaranteed + unique. Constant - A constant value used as argument to a SpaceOperation, or as value to pass across a Link to initialize an input Variable in the target Block. + A constant value used as argument to a SpaceOperation, or as value to pass + across a Link to initialize an input Variable in the target Block. :value: the concrete value represented by this Constant. :key: a hashable object representing the value. - A Constant can occasionally store a mutable Python object. It represents a static, pre-initialized, read-only version of that object. The flow graph should not attempt to actually mutate such Constants. + A Constant can occasionally store a mutable Python object. It represents a + static, pre-initialized, read-only version of that object. The flow graph + should not attempt to actually mutate such Constants. How the FlowObjSpace works From arigo at codespeak.net Fri Feb 9 18:07:33 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 9 Feb 2007 18:07:33 +0100 (CET) Subject: [pypy-svn] r38275 - pypy/extradoc/planning/1.0 Message-ID: <20070209170733.2EBE010092@code0.codespeak.net> Author: arigo Date: Fri Feb 9 18:07:29 2007 New Revision: 38275 Modified: pypy/extradoc/planning/1.0/documentation.txt Log: entries done. Assign myself to more. Modified: pypy/extradoc/planning/1.0/documentation.txt ============================================================================== --- pypy/extradoc/planning/1.0/documentation.txt (original) +++ pypy/extradoc/planning/1.0/documentation.txt Fri Feb 9 18:07:29 2007 @@ -2,17 +2,7 @@ ================================ -index.txt: reorder the categories: - - * Meta-Documentation (about PyPy, coding, talks, etc.) - - * User Documentation (for the PyPy user): getting started, - how to translate, and new Python features - - * Status - - * Source Code Documentation, - ending with directory cross-reference +index.txt: review the directory cross-reference (arigo) config pages, for all the options. @@ -25,16 +15,7 @@ js backend - is there something to update in translation.txt? BasicExternal approach, external functions? (fijal) -object-optimizations.txt. I guess we take text from the EU report. - - -objspace-proxies.txt: (arigo) - - * transparent proxies - - * security prototype - - * thunk space (move from objspace.txt) +object-optimizations.txt. (arigo) jit.txt: copy introduction from pypy-dev e-mail, add examples of nice colors From arigo at codespeak.net Fri Feb 9 18:12:28 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 9 Feb 2007 18:12:28 +0100 (CET) Subject: [pypy-svn] r38276 - pypy/extradoc/planning/1.0 Message-ID: <20070209171228.1EA0C100A5@code0.codespeak.net> Author: arigo Date: Fri Feb 9 18:12:25 2007 New Revision: 38276 Modified: pypy/extradoc/planning/1.0/documentation.txt Log: faq.txt. Modified: pypy/extradoc/planning/1.0/documentation.txt ============================================================================== --- pypy/extradoc/planning/1.0/documentation.txt (original) +++ pypy/extradoc/planning/1.0/documentation.txt Fri Feb 9 18:12:25 2007 @@ -22,6 +22,9 @@ (arigo) +faq.txt: write answers (arigo, fijal, cfbolz) + + improve getting-started (cfbolz, partially) short how to compile on windows (based on docstring of goal/win32/gc_patch_windows.py) (antocuni) @@ -49,7 +52,6 @@ * eventhistory.txt * extcompiler.txt * extradoc.txt - * faq.txt (add questions and answers) * garbage_collection.txt (out of date) * geninterp.txt (incomplete) * glossary.txt (add terms) From pedronis at codespeak.net Fri Feb 9 18:13:14 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Fri, 9 Feb 2007 18:13:14 +0100 (CET) Subject: [pypy-svn] r38277 - pypy/dist/pypy/tool/pytest Message-ID: <20070209171314.55638100AB@code0.codespeak.net> Author: pedronis Date: Fri Feb 9 18:13:04 2007 New Revision: 38277 Modified: pypy/dist/pypy/tool/pytest/htmlreport.py Log: write a data file for a summarizer to use Modified: pypy/dist/pypy/tool/pytest/htmlreport.py ============================================================================== --- pypy/dist/pypy/tool/pytest/htmlreport.py (original) +++ pypy/dist/pypy/tool/pytest/htmlreport.py Fri Feb 9 18:13:04 2007 @@ -5,6 +5,7 @@ """ import sys, os, re +import pprint import py from pypy.tool.pytest import result from pypy.tool.pytest.overview import ResultCache @@ -56,6 +57,7 @@ options = NBSP failureratio = 100 * (1.0 - result.ratio_of_passed()) + self.data[result.testname] = failureratio return html.tr( html.td("%.2f%%" % failureratio, style = "background-color: %s" % (getresultcolor(result),)), @@ -102,22 +104,29 @@ # generate html files # def makeindex(self, indexpath): - self.indexpath = indexpath + self.indexpath = indexpath + self.data = {} doc = Document(title='pypy test results') body = doc.body coretests, noncoretests = self.getcorelists() body.append(html.h2("PyPy - latest compliance test results - " "core tests")) - body.append(self.render_test_summary(coretests)) + body.append(self.render_test_summary('core', coretests)) body.append(self.render_latest_table(coretests)) body.append( html.h2("PyPy - latest compliance test results - non-core tests")) - body.append(self.render_test_summary(noncoretests)) + body.append(self.render_test_summary('noncore', noncoretests)) body.append(self.render_latest_table(noncoretests)) - doc.writetopath(indexpath) - - def render_test_summary(self, tests): + doc.writetopath(indexpath) + datapath = indexpath.dirpath().join('data') + d = datapath.open('w') + print >>d, "data = ", + pprint.pprint(self.data, stream=d) + d.close() + self.data = None + + def render_test_summary(self, tag, tests): ok = len([x for x in tests if x.isok()]) err = len([x for x in tests if x.iserror()]) to = len([x for x in tests if x.istimeout()]) @@ -131,12 +140,20 @@ return html.tr(*[html.td(arg) for arg in args]) sum_passed = sum([x.ratio_of_passed() for x in tests]) + compliancy = sum_passed/sum100 + self.data['%s-compliancy' % tag] = compliancy t.append(row(html.b("tests compliancy"), - html.b("%.2f%%" % (sum_passed/sum100,)))) + html.b("%.2f%%" % (compliancy,)))) - t.append(row("testmodules passed completely", "%.2f%%" % (ok/sum100))) - t.append(row("testmodules (partially) failed", "%.2f%%" % (err/sum100))) - t.append(row("testmodules timeout", "%.2f%%" % (to/sum100))) + passed = ok/sum100 + self.data['%s-passed' % tag] = passed + t.append(row("testmodules passed completely", "%.2f%%" % passed)) + failed = err/sum100 + self.data['%s-failed' % tag] = failed + t.append(row("testmodules (partially) failed", "%.2f%%" % failed)) + timedout = to/sum100 + self.data['%s-timedout' % tag] = timedout + t.append(row("testmodules timeout", "%.2f%%" % timedout)) return t class Document(object): From cfbolz at codespeak.net Fri Feb 9 18:21:19 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 9 Feb 2007 18:21:19 +0100 (CET) Subject: [pypy-svn] r38278 - pypy/dist/pypy/doc Message-ID: <20070209172119.F0195100A6@code0.codespeak.net> Author: cfbolz Date: Fri Feb 9 18:21:18 2007 New Revision: 38278 Modified: pypy/dist/pypy/doc/objspace.txt Log: reflowing some more. rest is strange sometimes Modified: pypy/dist/pypy/doc/objspace.txt ============================================================================== --- pypy/dist/pypy/doc/objspace.txt (original) +++ pypy/dist/pypy/doc/objspace.txt Fri Feb 9 18:21:18 2007 @@ -140,10 +140,9 @@ Convenience function that collects the arguments in a wrapped tuple and dict and invokes 'space.call(w_callable, ...)'. -``space.call_method(w_object, 'method', ...)`` - uses - ``space.getattr()`` to get the method object, and then - ``space.call_function()`` to invoke it. +``space.call_method(w_object, 'method', ...):`` + uses ``space.getattr()`` to get the method object, and then + ``space.call_function()`` to invoke it. ``unpackiterable(w_iterable, expected_length=-1):`` this helper iterates ``w_x`` @@ -470,19 +469,21 @@ A container for one graph (corresponding to one function). :startblock: the first block. It is where the control goes when the - function is called. The input arguments of the startblock are the - function's arguments. If the function takes a ``*args`` argument, the - ``args`` tuple is given as the last input argument of the startblock. + function is called. The input arguments of the startblock + are the function's arguments. If the function takes a + ``*args`` argument, the ``args`` tuple is given as the last + input argument of the startblock. :returnblock: the (unique) block that performs a function return. It is - empty, not actually containing any ``return`` operation; the return is - implicit. The returned value is the unique input variable of the - returnblock. + empty, not actually containing any ``return`` operation; the + return is implicit. The returned value is the unique input + variable of the returnblock. :exceptblock: the (unique) block that raises an exception out of the - function. The two input variables are the exception class and the exception - value, respectively. (No other block will actually link to the exceptblock - if the function does not explicitely raise exceptions.) + function. The two input variables are the exception class + and the exception value, respectively. (No other block will + actually link to the exceptblock if the function does not + explicitely raise exceptions.) Block @@ -492,13 +493,14 @@ Variables. :inputargs: list of fresh, distinct Variables that represent all the - values that can enter this block from any of the previous blocks. + values that can enter this block from any of the previous + blocks. :operations: list of SpaceOperations. :exitswitch: see below :exits: list of Links representing possible jumps from the end of this - basic block to the beginning of other basic blocks. + basic block to the beginning of other basic blocks. Each Block ends in one of the following ways: @@ -557,10 +559,10 @@ A recorded (or otherwise generated) basic operation. :opname: the name of the operation. Generally one from the list in - ``pypy.interpreter.baseobjspace``. + ``pypy.interpreter.baseobjspace``. :args: list of arguments. Each one is a Constant or a Variable seen - previously in the basic block. + previously in the basic block. :result: a *new* Variable into which the result is to be stored. @@ -579,8 +581,8 @@ A placeholder for a run-time value. There is mostly debugging stuff here. :name: it is good style to use the Variable object itself instead of its - ``name`` attribute to reference a value, although the ``name`` is guaranteed - unique. + ``name`` attribute to reference a value, although the ``name`` is + guaranteed unique. Constant From cfbolz at codespeak.net Fri Feb 9 18:37:49 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 9 Feb 2007 18:37:49 +0100 (CET) Subject: [pypy-svn] r38280 - pypy/dist/pypy/doc Message-ID: <20070209173749.82C2E1009A@code0.codespeak.net> Author: cfbolz Date: Fri Feb 9 18:37:49 2007 New Revision: 38280 Modified: pypy/dist/pypy/doc/objspace.txt pypy/dist/pypy/doc/translation.txt Log: move the description of the flow model classes to translation.txt Modified: pypy/dist/pypy/doc/objspace.txt ============================================================================== --- pypy/dist/pypy/doc/objspace.txt (original) +++ pypy/dist/pypy/doc/objspace.txt Fri Feb 9 18:37:49 2007 @@ -455,146 +455,10 @@ The Flow model -------------- -``pypy.objspace.flow.model`` defines the data model used by the flow graphs, as -created by the FlowObjSpace, manipulated by ``pypy.translator.simplify`` and -``pypy.translator.transform``, and in general read by almost all the modules in -``pypy.translator``. +The data structures built up by the flow object space are described in the +`translation document`_. -It is recommended to play with ``python translator.py`` on a few examples to get -an idea of the structure of flow graphs. Here is a short summary of the -non-obvious parts. - - -FunctionGraph - A container for one graph (corresponding to one function). - - :startblock: the first block. It is where the control goes when the - function is called. The input arguments of the startblock - are the function's arguments. If the function takes a - ``*args`` argument, the ``args`` tuple is given as the last - input argument of the startblock. - - :returnblock: the (unique) block that performs a function return. It is - empty, not actually containing any ``return`` operation; the - return is implicit. The returned value is the unique input - variable of the returnblock. - - :exceptblock: the (unique) block that raises an exception out of the - function. The two input variables are the exception class - and the exception value, respectively. (No other block will - actually link to the exceptblock if the function does not - explicitely raise exceptions.) - - -Block - A basic block, containing a list of operations and ending in jumps to other - basic blocks. All the values that are "live" during the execution of the - block are stored in Variables. Each basic block uses its own distinct - Variables. - - :inputargs: list of fresh, distinct Variables that represent all the - values that can enter this block from any of the previous - blocks. - - :operations: list of SpaceOperations. - :exitswitch: see below - - :exits: list of Links representing possible jumps from the end of this - basic block to the beginning of other basic blocks. - - Each Block ends in one of the following ways: - - * unconditional jump: exitswitch is None, exits contains a single Link. - - * conditional jump: exitswitch is one of the Variables that appear in the - Block, and exits contains one or more Links (usually 2). Each Link's - exitcase gives a concrete value. This is the equivalent of a "switch": - the control follows the Link whose exitcase matches the run-time value of - the exitswitch Variable. It is a run-time error if the Variable doesn't - match any exitcase. - - * exception catching: exitswitch is ``Constant(last_exception)``. The first - Link has exitcase set to None and represents the non-exceptional path. - The next Links have exitcase set to a subclass of Exception, and are taken - when the *last* operation of the basic block raises a matching exception. - (Thus the basic block must not be empty, and only the last operation is - protected by the handler.) - - * return or except: the returnblock and the exceptblock have operations set - to an empty tuple, exitswitch to None, and exits empty. - - -Link - A link from one basic block to another. - - :prevblock: the Block that this Link is an exit of. - - :target: the target Block to which this Link points to. - - :args: a list of Variables and Constants, of the same size as the - target Block's inputargs, which gives all the values passed - into the next block. (Note that each Variable used in the - prevblock may appear zero, one or more times in the ``args`` - list.) - - :exitcase: see above. - - :last_exception: None or a Variable; see below. - - :last_exc_value: None or a Variable; see below. - - Note that ``args`` uses Variables from the prevblock, which are matched to - the target block's ``inputargs`` by position, as in a tuple assignment or - function call would do. - - If the link is an exception-catching one, the ``last_exception`` and - ``last_exc_value`` are set to two fresh Variables that are considered to be - created when the link is entered; at run-time, they will hold the exception - class and value, respectively. These two new variables can only be used in - the same link's ``args`` list, to be passed to the next block (as usual, - they may actually not appear at all, or appear several times in ``args``). - - -SpaceOperation - A recorded (or otherwise generated) basic operation. - - :opname: the name of the operation. Generally one from the list in - ``pypy.interpreter.baseobjspace``. - - :args: list of arguments. Each one is a Constant or a Variable seen - previously in the basic block. - - :result: a *new* Variable into which the result is to be stored. - - Note that operations usually cannot implicitly raise exceptions at run-time; - so for example, code generators can assume that a ``getitem`` operation on a - list is safe and can be performed without bound checking. The exceptions to - this rule are: (1) if the operation is the last in the block, which ends - with ``exitswitch == Constant(last_exception)``, then the implicit - exceptions must be checked for, generated, and caught appropriately; (2) - calls to other functions, as per ``simple_call`` or ``call_args``, can - always raise whatever the called function can raise --- and such exceptions - must be passed through to the parent unless they are caught as above. - - -Variable - A placeholder for a run-time value. There is mostly debugging stuff here. - - :name: it is good style to use the Variable object itself instead of its - ``name`` attribute to reference a value, although the ``name`` is - guaranteed unique. - - -Constant - A constant value used as argument to a SpaceOperation, or as value to pass - across a Link to initialize an input Variable in the target Block. - - :value: the concrete value represented by this Constant. - :key: a hashable object representing the value. - - A Constant can occasionally store a mutable Python object. It represents a - static, pre-initialized, read-only version of that object. The flow graph - should not attempt to actually mutate such Constants. +.. _`translation document`: translation.html#flow-model How the FlowObjSpace works Modified: pypy/dist/pypy/doc/translation.txt ============================================================================== --- pypy/dist/pypy/doc/translation.txt (original) +++ pypy/dist/pypy/doc/translation.txt Fri Feb 9 18:37:49 2007 @@ -104,16 +104,18 @@ .. _`interactive interface`: getting-started.html#try-out-the-translator .. _`translatorshell.py`: http://codespeak.net/pypy/dist/pypy/bin/translatorshell.py +.. _`flow model`: + The Flow Model ============== -The `Flow Object Space`_ is described in detail in the `document -describing object spaces`_, but as the data structures produced by the -Flow Object Space are the basic data structures of the translation -process, we quickly summarize them here. +The `Flow Object Space`_ is described in the `document +describing object spaces`_. Here we describe the data structures produced by it, +which are the basic data structures of the translation +process. -All these types are defined in `pypy.objspace.flow.model`_ (which is the -most imported module in the PyPy source base, to reinforce the point). +All these types are defined in `pypy.objspace.flow.model`_ (which is a rather +important module in the PyPy source base, to reinforce the point). The flow graph of a function is represented by the class ``FunctionGraph``. It contains a reference to a collection of ``Block``\ s connected by ``Link``\ s. @@ -128,8 +130,146 @@ .. image:: image/bpnn_update.png +It is recommended to play with ``python bin/translatorshell.py`` on a few +examples to get an idea of the structure of flow graphs. The following describes +the types and their attributes in some detail: + + +``FunctionGraph`` + A container for one graph (corresponding to one function). + + :startblock: the first block. It is where the control goes when the + function is called. The input arguments of the startblock + are the function's arguments. If the function takes a + ``*args`` argument, the ``args`` tuple is given as the last + input argument of the startblock. + + :returnblock: the (unique) block that performs a function return. It is + empty, not actually containing any ``return`` operation; the + return is implicit. The returned value is the unique input + variable of the returnblock. + + :exceptblock: the (unique) block that raises an exception out of the + function. The two input variables are the exception class + and the exception value, respectively. (No other block will + actually link to the exceptblock if the function does not + explicitely raise exceptions.) + + +``Block`` + A basic block, containing a list of operations and ending in jumps to other + basic blocks. All the values that are "live" during the execution of the + block are stored in Variables. Each basic block uses its own distinct + Variables. + + :inputargs: list of fresh, distinct Variables that represent all the + values that can enter this block from any of the previous + blocks. + + :operations: list of SpaceOperations. + :exitswitch: see below + + :exits: list of Links representing possible jumps from the end of this + basic block to the beginning of other basic blocks. + + Each Block ends in one of the following ways: + + * unconditional jump: exitswitch is None, exits contains a single Link. + + * conditional jump: exitswitch is one of the Variables that appear in the + Block, and exits contains one or more Links (usually 2). Each Link's + exitcase gives a concrete value. This is the equivalent of a "switch": + the control follows the Link whose exitcase matches the run-time value of + the exitswitch Variable. It is a run-time error if the Variable doesn't + match any exitcase. + + * exception catching: exitswitch is ``Constant(last_exception)``. The first + Link has exitcase set to None and represents the non-exceptional path. + The next Links have exitcase set to a subclass of Exception, and are taken + when the *last* operation of the basic block raises a matching exception. + (Thus the basic block must not be empty, and only the last operation is + protected by the handler.) + + * return or except: the returnblock and the exceptblock have operations set + to an empty tuple, exitswitch to None, and exits empty. + + +``Link`` + A link from one basic block to another. + + :prevblock: the Block that this Link is an exit of. + + :target: the target Block to which this Link points to. + + :args: a list of Variables and Constants, of the same size as the + target Block's inputargs, which gives all the values passed + into the next block. (Note that each Variable used in the + prevblock may appear zero, one or more times in the ``args`` + list.) + + :exitcase: see above. + + :last_exception: None or a Variable; see below. + + :last_exc_value: None or a Variable; see below. + + Note that ``args`` uses Variables from the prevblock, which are matched to + the target block's ``inputargs`` by position, as in a tuple assignment or + function call would do. + + If the link is an exception-catching one, the ``last_exception`` and + ``last_exc_value`` are set to two fresh Variables that are considered to be + created when the link is entered; at run-time, they will hold the exception + class and value, respectively. These two new variables can only be used in + the same link's ``args`` list, to be passed to the next block (as usual, + they may actually not appear at all, or appear several times in ``args``). + + +``SpaceOperation`` + A recorded (or otherwise generated) basic operation. + + :opname: the name of the operation. The Flow Space produces only operations + from the list in ``pypy.interpreter.baseobjspace``, but later the + names can be changed arbitrarily. + + :args: list of arguments. Each one is a Constant or a Variable seen + previously in the basic block. + + :result: a *new* Variable into which the result is to be stored. + + Note that operations usually cannot implicitly raise exceptions at run-time; + so for example, code generators can assume that a ``getitem`` operation on a + list is safe and can be performed without bound checking. The exceptions to + this rule are: (1) if the operation is the last in the block, which ends + with ``exitswitch == Constant(last_exception)``, then the implicit + exceptions must be checked for, generated, and caught appropriately; (2) + calls to other functions, as per ``simple_call`` or ``call_args``, can + always raise whatever the called function can raise --- and such exceptions + must be passed through to the parent unless they are caught as above. + + +``Variable`` + A placeholder for a run-time value. There is mostly debugging stuff here. + + :name: it is good style to use the Variable object itself instead of its + ``name`` attribute to reference a value, although the ``name`` is + guaranteed unique. + + +``Constant`` + A constant value used as argument to a SpaceOperation, or as value to pass + across a Link to initialize an input Variable in the target Block. + + :value: the concrete value represented by this Constant. + :key: a hashable object representing the value. + + A Constant can occasionally store a mutable Python object. It represents a + static, pre-initialized, read-only version of that object. The flow graph + should not attempt to actually mutate such Constants. + .. _`document describing object spaces`: objspace.html -.. _`pypy.objspace.flow.model`: http://codespeak.net/pypy/dist/pypy/objspace/flow/model.py +.. _`pypy.objspace.flow.model`: ../objspace/flow/model.py + .. _Annotator: From cfbolz at codespeak.net Fri Feb 9 18:48:42 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 9 Feb 2007 18:48:42 +0100 (CET) Subject: [pypy-svn] r38284 - pypy/dist/pypy/doc Message-ID: <20070209174842.7761A10094@code0.codespeak.net> Author: cfbolz Date: Fri Feb 9 18:48:42 2007 New Revision: 38284 Modified: pypy/dist/pypy/doc/objspace.txt Log: point to alternative object implementations (that exist now!) Modified: pypy/dist/pypy/doc/objspace.txt ============================================================================== --- pypy/dist/pypy/doc/objspace.txt (original) +++ pypy/dist/pypy/doc/objspace.txt Fri Feb 9 18:48:42 2007 @@ -304,7 +304,7 @@ function pointers). If compatibility is not required it will be more straightforwardly converted into some efficient multimethod code. -.. _StdObjSpace: http://codespeak.net/svn/pypy/dist/pypy/objspace/std/ +.. _StdObjSpace: ../objspace/std/ .. _MultiMethod: theory.html#multimethods @@ -336,19 +336,22 @@ The goal of the above module layout is to cleanly separate the Python type object, visible to the user, and the actual implementation of its instances. It -is possible (though not done so far) to provide *several* implementations of the +is possible to provide *several* implementations of the instances of the same Python type. The ``__new__()`` method could decide to create one or the other. From the user's point of view, they are still all instances of exactly the same type; the possibly multiple internal ``W_XxxObject`` classes are not visible. PyPy knows that (e.g.) the application-level type of its interpreter-level ``W_TupleObject`` instances is "tuple" because there is a ``typedef`` class attribute in ``W_TupleObject`` -which points back to the tuple type specification from `tupletype.py`_. - -.. _`listtype.py`: http://codespeak.net/svn/pypy/dist/pypy/objspace/std/listtype.py -.. _`tupletype.py`: http://codespeak.net/svn/pypy/dist/pypy/objspace/std/tupletype.py -.. _`tupleobject.py`: http://codespeak.net/svn/pypy/dist/pypy/objspace/std/tupleobject.py +which points back to the tuple type specification from `tupletype.py`_. For +examples of having several implementations of the same type, see the `object +optimizations`_ page. + +.. _`listtype.py`: ../objspace/std/listtype.py +.. _`tupletype.py`: ../objspace/std/tupletype.py +.. _`tupleobject.py`: ../objspace/std/tupleobject.py +.. _`object optimizations`: object-optimizations.html The Trace Object Space @@ -395,7 +398,7 @@ .. _`found here` : getting-started.html#tracing-bytecode-and-operations-on-objects .. _`Abstract Interpretation`: theory.html#abstract-interpretation -.. _`traceconfig.py`: http://codespeak.net/svn/pypy/dist/pypy/tool/traceconfig.py +.. _`traceconfig.py`: ../tool/traceconfig.py Proxy Object Spaces @@ -449,7 +452,7 @@ v3 = add(v2, Constant(2)) -.. _FlowObjSpace: http://codespeak.net/svn/pypy/dist/pypy/objspace/flow/ +.. _FlowObjSpace: ../objspace/flow/ The Flow model From arigo at codespeak.net Fri Feb 9 18:49:37 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 9 Feb 2007 18:49:37 +0100 (CET) Subject: [pypy-svn] r38285 - pypy/dist/pypy/doc Message-ID: <20070209174937.E74141009A@code0.codespeak.net> Author: arigo Date: Fri Feb 9 18:49:35 2007 New Revision: 38285 Modified: pypy/dist/pypy/doc/_ref.txt pypy/dist/pypy/doc/objspace.txt Log: Small updates to the ObjSpace interface. Modified: pypy/dist/pypy/doc/_ref.txt ============================================================================== --- pypy/dist/pypy/doc/_ref.txt (original) +++ pypy/dist/pypy/doc/_ref.txt Fri Feb 9 18:49:35 2007 @@ -17,11 +17,13 @@ .. _`pypy/interpreter/argument.py`: ../../pypy/interpreter/argument.py .. _`interpreter/astcompiler/`: .. _`pypy/interpreter/astcompiler`: ../../pypy/interpreter/astcompiler +.. _`pypy/interpreter/executioncontext.py`: ../../pypy/interpreter/executioncontext.py .. _`pypy/interpreter/function.py`: ../../pypy/interpreter/function.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/module.py`: ../../pypy/interpreter/module.py .. _`pypy/interpreter/nestedscope.py`: ../../pypy/interpreter/nestedscope.py .. _`pypy/interpreter/pyopcode.py`: ../../pypy/interpreter/pyopcode.py .. _`interpreter/pyparser/`: Modified: pypy/dist/pypy/doc/objspace.txt ============================================================================== --- pypy/dist/pypy/doc/objspace.txt (original) +++ pypy/dist/pypy/doc/objspace.txt Fri Feb 9 18:49:35 2007 @@ -61,50 +61,49 @@ .. _`application-level`: coding-guide.html#application-level .. _`interpreter-level`: coding-guide.html#interpreter-level .. _`in another document`: translation.html -.. _`Object Space proxies`: objspace-proxies.html .. _interface: Object Space Interface ====================== -This is a draft version of the Object Space interface. It is still evolving, although the public interface is not evolving as much as the internal interface that subclasses need to know about. This document now generally refers to the public interface; for subclassing you need to poke at the code in detail anyway. +This is the public API that all Object Spaces implement. Administrative Functions ---------------------------- -``initialize():`` - Function which initializes w_builtins and the other w_constants. - ``getexecutioncontext():`` - Return current active execution context. + Return current active execution context + (`pypy/interpreter/executioncontext.py`_). + +``getbuiltinmodule(name):`` + Return a Module object for the built-in module given by name + (`pypy/interpreter/module.py`_). -Operations on Objects in ObjSpace +Operations on Objects in the Object Space ----------------------------------------- These functions both take and return "wrapped" objects. -*The following functions implement the same operations as those in CPython:* - -``id, type, issubtype, iter, repr, str, len, hash, callable,`` +The following functions implement operations with a straightforward +semantic - they directly correspond to language-level constructs: -``getattr, setattr, delattr, getitem, setitem, delitem,`` + ``id, type, issubtype, iter, next, repr, str, len, hash,`` -``pos, neg, not_, abs, invert, add, sub, mul, truediv, floordiv, div, mod, divmod, pow, lshift, rshift, and_, or_, xor,`` + ``getattr, setattr, delattr, getitem, setitem, delitem,`` -``hex, oct, int, float, ord,`` + ``pos, neg, abs, invert, add, sub, mul, truediv, floordiv, div, mod, divmod, pow, lshift, rshift, and_, or_, xor,`` -``lt, le, eq, ne, gt, ge, contains,`` + ``nonzero, hex, oct, int, float, long, ord,`` -``inplace_add, inplace_sub, inplace_mul, inplace_truediv, inplace_floordiv, -inplace_div, inplace_mod, inplace_pow, inplace_lshift, inplace_rshift, -inplace_and, inplace_or, inplace_xor,`` + ``lt, le, eq, ne, gt, ge, cmp, coerce, contains,`` -``get, set, delete`` + ``inplace_add, inplace_sub, inplace_mul, inplace_truediv, inplace_floordiv, + inplace_div, inplace_mod, inplace_pow, inplace_lshift, inplace_rshift, + inplace_and, inplace_or, inplace_xor,`` -``next(w):`` - Call the next function for iterator w, or raises a real NoValue. + ``get, set, delete, userdel`` ``call(w_callable, w_args, w_kwds):`` Call a function with the given args and keywords. @@ -136,11 +135,18 @@ ``hash_w(w_obj):`` Shortcut for space.int_w(space.hash(w_obj)) +``not_(w_obj):`` + Shortcut for space.newbool(not space.is_true(w_obj)) + +``finditem(w_obj, w_key):`` + Equivalent to ``getitem(w_obj, w_key)`` but returns an interp-level None + instead of raising a KeyError if the key is not found. + ``call_function(w_callable, *args_w, **kw_w):`` Convenience function that collects the arguments in a wrapped tuple and dict and invokes 'space.call(w_callable, ...)'. -``space.call_method(w_object, 'method', ...):`` +``call_method(w_object, 'method', ...):`` uses ``space.getattr()`` to get the method object, and then ``space.call_function()`` to invoke it. @@ -155,6 +161,9 @@ ``unpacktuple(w_tuple, expected_length=None):`` Same as unpackiterable(), but only for tuples. +``callable(w_obj):`` + implements the built-in ``callable()``. Returns a wrapped True or False. + Creation of Application Level objects --------------------------------------- @@ -162,9 +171,11 @@ ``wrap(x):`` Returns a wrapped object that is a reference to the interpreter-level object x. This can be used either on simple immutable objects (integers, - strings...) to create a new wrapped object, or on complex mutable objects to - obtain an application-level-visible reference to them (e.g. instances of - internal bytecode interpreter classes). + strings...) to create a new wrapped object, or on instances of ``Wrappable`` + to obtain an application-level-visible reference to them. For example, + most classes of the bytecode interpreter subclass ``Wrappable`` and can + be directly exposed to app-level in this way - functions, frames, code + objects, etc. ``newbool(b):`` Creates a wrapped bool object from an interpreter level object. @@ -182,7 +193,9 @@ Makes a new slice object. ``newstring(asciilist):`` - Creates a string from a list of wrapped integers. + Creates a string from a list of wrapped integers. Note that this + is not a very useful method; usually you can just say + space.wrap("mystring"). ``newunicode(codelist):`` Creates a unicode string from a list of integers. @@ -191,15 +204,12 @@ ---------------------------------------------------------- ``unwrap(w_x):`` - Return Interpreter Level equivalent of w_x. - Attention! Using ``space.unwrap()`` must be avoided - whenever possible, i.e. only use this when you are well - aware that you are cheating, in unit tests or bootstrapping - code. + Return the Interpreter Level equivalent of w_x. DO NOT USE! + Only for testing. Use the functions described below instead. -``interpclass_w(w_x):`` - If w_x is a wrapped instance of an bytecode interpreter class -- for example - Function, Frame, Cell, etc. -- return it unwrapped. Otherwise return None. +``is_true(w_x):`` + Return a interpreter level bool (True or False) that gives the truth + value of the wrapped object w_x. ``int_w(w_x):`` If w_x is an application-level integer or long which can be converted without overflow to an integer, return an interpreter-level integer. Otherwise raise TypeError or OverflowError. @@ -213,20 +223,29 @@ ``float_w(w_x):`` If w_x is an application-level float, integer or long, return interpreter-level float. Otherwise raise TypeError or OverflowError in case of very large longs. -``is_true(w_x):`` - Return a interpreter level bool (True or False). +``interp_w(RequiredClass, w_x, can_be_None=False):`` + If w_x is a wrapped instance of the given bytecode interpreter class, + unwrap it and return it. If can_be_None is True, a wrapped None is also + accepted and returns an interp-level None. Otherwise, raises an + OperationError encapsulating a TypeError with a nice error message. + +``interpclass_w(w_x):`` + If w_x is a wrapped instance of an bytecode interpreter class -- for example + Function, Frame, Cell, etc. -- return it unwrapped. Otherwise return None. Data Members ----------------- -+ space.builtin -+ space.sys ++ space.builtin: The Module containing the builtins ++ space.sys: The 'sys' Module + space.w_None: The ObjSpace's None + space.w_True: The ObjSpace's True + space.w_False: The ObjSpace's False + space.w_Ellipsis: The ObjSpace's Ellipsis + space.w_NotImplemented: The ObjSpace's NotImplemented ++ space.w_int, w_float, w_long, w_tuple, w_str, w_unicode, w_type, + w_instance, w_slice: Python's most common type objects + space.w_XxxError`` for each exception class ``XxxError`` (e.g. ``space.w_KeyError``, ``space.w_IndexError``, etc.). @@ -243,6 +262,9 @@ + ObjSpace.ExceptionTable: List of names of exception classes. ++ ObjSpace.IrregularOpTable: + List of names of methods that have an irregular API (take and/or return + non-wrapped objects). .. _`standard object space`: @@ -401,17 +423,6 @@ .. _`traceconfig.py`: ../tool/traceconfig.py -Proxy Object Spaces -=================== - -We have implemented several *proxy object spaces* which wrap another -space (typically the standard one) and add some capability to all -objects. These object spaces are documented in a separate page: `What -PyPy can do for your objects`_. - -.. _`What PyPy can do for your objects`: objspace-proxies.html - - .. _`Flow Object Space`: The Flow Object Space @@ -491,4 +502,15 @@ (This section to be extended...) + +Object Space proxies +==================== + +We have implemented several *proxy object spaces* which wrap another +space (typically the standard one) and add some capability to all +objects. These object spaces are documented in a separate page: `What +PyPy can do for your objects`_. + +.. _`What PyPy can do for your objects`: objspace-proxies.html + .. include:: _ref.txt From hpk at codespeak.net Fri Feb 9 18:51:31 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Fri, 9 Feb 2007 18:51:31 +0100 (CET) Subject: [pypy-svn] r38286 - pypy/dist/pypy/tool Message-ID: <20070209175131.2A6DD10094@code0.codespeak.net> Author: hpk Date: Fri Feb 9 18:51:29 2007 New Revision: 38286 Modified: pypy/dist/pypy/tool/genstatistic.py Log: using a default of curdir.join("index.html" for generating statistics and fixing xml escaping issues. Modified: pypy/dist/pypy/tool/genstatistic.py ============================================================================== --- pypy/dist/pypy/tool/genstatistic.py (original) +++ pypy/dist/pypy/tool/genstatistic.py Fri Feb 9 18:51:29 2007 @@ -2,6 +2,7 @@ import autopath import py from py.__.misc.cmdline import countloc +from py.xml import raw pypydir = py.path.local(autopath.pypydir) @@ -67,13 +68,13 @@ def viewlocsummary(model): t = html.table( - row("total number of lines", model.totallines, " "), + row("total number of lines", model.totallines, raw(" ")), row("number of testlines", model.testlines, percent(model.testlines, model.totallines)), row("number of non-testlines", model.notestlines, percent(model.notestlines, model.totallines)), - row("total number of files", model.totalfiles, " "), + row("total number of files", model.totalfiles, raw(" ")), row("number of testfiles", model.testfiles, percent(model.testfiles, model.totalfiles)), row("number of non-testfiles", model.notestfiles, @@ -112,6 +113,11 @@ return t if __name__ == '__main__': + if len(py.std.sys.argv) >= 2: + target = py.path.local(py.std.sys.argv[1]) + else: + target = py.path.local('index.html') + print "writing source statistics to", target pypycounter = getpypycounter() model = CounterModel(pypycounter) rev = py.path.svnwc(autopath.pypydir).info().rev @@ -130,4 +136,6 @@ html.p("files with less than 3 lines ignored") ) ) - print doc.unicode(indent=2).encode('utf8') + content = doc.unicode(indent=2).encode('utf8') + target.write(content) + From antocuni at codespeak.net Fri Feb 9 19:02:51 2007 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Fri, 9 Feb 2007 19:02:51 +0100 (CET) Subject: [pypy-svn] r38288 - pypy/dist/pypy/doc Message-ID: <20070209180251.BE7A8100A5@code0.codespeak.net> Author: antocuni Date: Fri Feb 9 19:02:47 2007 New Revision: 38288 Modified: pypy/dist/pypy/doc/getting-started.txt Log: Add a note explaning why you can't build pypy.net on windows :-( Modified: pypy/dist/pypy/doc/getting-started.txt ============================================================================== --- pypy/dist/pypy/doc/getting-started.txt (original) +++ pypy/dist/pypy/doc/getting-started.txt Fri Feb 9 19:02:47 2007 @@ -754,6 +754,14 @@ 2 >>>> +Unfortunately, at the moment it's impossible to do the translation +under Windows because of a bug of Microsoft ilasm that crashes when +trying to assemble the huge IL file produced by GenCLI. + +As a workaround you can use the Mono ilasm, which does the job +fine. Once assembled, you can run the produced executable with the +Microsoft Runtime. + .. _`start reading sources`: Where to start reading the sources From arigo at codespeak.net Fri Feb 9 19:15:11 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 9 Feb 2007 19:15:11 +0100 (CET) Subject: [pypy-svn] r38295 - pypy/dist/pypy/doc Message-ID: <20070209181511.7B68210093@code0.codespeak.net> Author: arigo Date: Fri Feb 9 19:15:09 2007 New Revision: 38295 Modified: pypy/dist/pypy/doc/object-optimizations.txt Log: Typos. Modified: pypy/dist/pypy/doc/object-optimizations.txt ============================================================================== --- pypy/dist/pypy/doc/object-optimizations.txt (original) +++ pypy/dist/pypy/doc/object-optimizations.txt Fri Feb 9 19:15:09 2007 @@ -9,9 +9,9 @@ situation without disturbing the implementation for the regular case. We have implemented several such optimizations. Most of them are not enabled by -default. Also, it is not clear for all there optimizations whether they are +default. Also, it is not clear for all these optimizations whether they are worth it in practice, for a real-world application (they sure make some -microbenchmarks a lot faster of use less memory, which is not saying too much). +microbenchmarks a lot faster and use less memory, which is not saying too much). If you have any observation in that direction, please let us know! By the way: alternative object implementations are a great way to get into PyPy development since you have to know only a rather small part of PyPy to do them. And they are @@ -41,10 +41,10 @@ is done (although a lot of string methods don't make this necessary). This makes string slicing a very efficient operation. It also saves memory in some cases but can also lead to memory leaks, since the string slice retains a -reference to the original string (to make this a bit less likely, the slicing -is only done when the length of the slice exceeds a certain number of characters -and when the slice length is a significant amount of the original string's -length). +reference to the original string (to make this a bit less likely, we don't +use lazy slicing when the slice would be much shorter than the original +string. There is also a minimum number of characters below which being lazy +is not saving any time over making the copy). Integer optimizations ===================== @@ -63,10 +63,10 @@ An even more aggressive way to save memory when using integers is "small int" integer implementation. It is another integer implementation used for integers -that only need 31 bits (respective 63 bits on an 64 bit machine). These integers +that only needs 31 bits (or 63 bits on a 64 bit machine). These integers are represented as tagged pointers by setting their lowest bits to distinguish -them from normal pointers. This makes boxing of these integers use no memory at -all. +them from normal pointers. This completely avoids the boxing step, saving +time and memory. Dictionary optimizations @@ -75,7 +75,7 @@ string-keyed dictionaries ------------------------- -String-keyed dictionaries are an alternate implmentation of the ``dict`` type. +String-keyed dictionaries are an alternate implementation of the ``dict`` type. These dictionaries are optimized for string keys, which is obviously a big win for all but the most contrived Python programs. As soon as one non-string key is stored in the dict @@ -90,8 +90,8 @@ useful to *change* the internal representation of an object during its lifetime. String-keyed dictionaries already do that in a limited way (changing the representation from a string-to-object mapping to an object-to-object mapping). -Multi-Dicts are way more general in providing support for this switching of -representations for dicts in a rather general way. +Multi-Dicts are way more general: they provide generic support for such +switching of representations for dicts. If you just enable multi-dicts, special representations for empty dictionaries, for string-keyed dictionaries and for small dictionaries are used (as well as a @@ -109,10 +109,11 @@ The idea is the following: Most instances of the same class have very similar attributes, and are even adding these keys to the dictionary in the same order -while ``__init__`` is being executed. That means that all the dictionaries of +while ``__init__()`` is being executed. That means that all the dictionaries of these instances look very similar: they have the same set of keys with different values per instance. What sharing dicts do is store these common keys into a -common structure object and thus safe the space in the individual instance dict: +common structure object and thus save the space in the individual instance +dicts: the representation of the instance dict contains only a list of values. @@ -127,16 +128,17 @@ The same problem is solved in a different way by "wary" dictionaries. They are another dictionary representation used together with multidicts. This -representation is used only for module dictionaries. The repesentation checks on +representation is used only for module dictionaries. The representation checks on every setitem whether the key that is used is the name of a builtin. If this is the case, the dictionary is marked as shadowing that particular builtin. To identify calls to builtins easily, a new bytecode (``CALL_LIKELY_BUILTIN``) is introduced. Whenever it is executed, the globals dictionary is checked -whether it masks the builtin (which is possible without a dictionary lookup). -Then the ``__builtin__`` dict is checked whether somebody replaced the real -builtin with something else in the same way. If both these conditions are not -met, the proper builtin is called, using no dictionary lookup at all. +to see whether it masks the builtin (which is possible without a dictionary +lookup). Then the ``__builtin__`` dict is checked in the same way, +to see whether somebody replaced the real builtin with something else. In the +common case, the program didn't do any of these; the proper builtin can then +be called without using any dictionary lookup at all. List optimizations ================== @@ -148,10 +150,10 @@ the problem that ``range`` allocates memory even if the resulting list is only ever used for iterating over it. Range lists are a different implementation for lists. They are created only as a result of a call to ``range``. As long as the -resulting list is used without being mutated, the list stores only start, stop +resulting list is used without being mutated, the list stores only the start, stop and step of the range. Only when somebody mutates the list the actual list is -created. This gives the memory and speed behaviour of ``xrange`` and the general -of use of ``range``. +created. This gives the memory and speed behaviour of ``xrange`` and the generality +of use of ``range``, and makes ``xrange`` essentially useless. multi-lists @@ -163,7 +165,7 @@ representations you get by default are for empty lists, for lists containing only strings and ranges again (the reason why range lists and multilists both implement the same optimization is that range lists came earlier and that -multi-lists are not tried that much so far). +multi-lists are not tested that much so far). fast list slicing @@ -173,8 +175,8 @@ slice list (the original idea is from `Neal Norwitz on pypy-dev`_). The observation is that slices are often created for iterating over them, so it seems wasteful to create a full copy of that portion of the list. Instead the -list slice is only created lazily, that is when the original list or the sliced -list are mutated. +list slice is only created lazily, that is when either the original list or +the sliced list is mutated. .. _`Neal Norwitz on pypy-dev`: http://codespeak.net/pipermail/pypy-dev/2005q4/002538.html @@ -204,9 +206,9 @@ Shadow tracking is also an important building block for the method caching optimization. A method cache is introduced where the result of a method lookup is stored (which involves potentially many lookups in the base classes of a -class). Entries in the method cache are stored using a hash consisting of the -hash of the name being looked up, the call site (e.g. the bytecode object and -the currend program counter) and a special "version" of the type where the -lookup happens (that version is incremented every time the type or one of its -base classes is changed). On subsequent lookups the cached version can be used -(at least if the instance did not shadow any of its classes attributes). +class). Entries in the method cache are stored using a hash computed from +the name being looked up, the call site (i.e. the bytecode object and +the current program counter), and a special "version" of the type where the +lookup happens (this version is incremented every time the type or one of its +base classes is changed). On subsequent lookups the cached version can be used, +as long as the instance did not shadow any of its classes attributes. From arigo at codespeak.net Fri Feb 9 19:38:42 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 9 Feb 2007 19:38:42 +0100 (CET) Subject: [pypy-svn] r38304 - pypy/extradoc/planning/1.0 Message-ID: <20070209183842.509311008E@code0.codespeak.net> Author: arigo Date: Fri Feb 9 19:38:41 2007 New Revision: 38304 Modified: pypy/extradoc/planning/1.0/documentation.txt Log: theory.txt Modified: pypy/extradoc/planning/1.0/documentation.txt ============================================================================== --- pypy/extradoc/planning/1.0/documentation.txt (original) +++ pypy/extradoc/planning/1.0/documentation.txt Fri Feb 9 19:38:41 2007 @@ -36,6 +36,8 @@ contributor.txt: needs to be updated +theory.txt: add specialization + review - check (or decide to ignore) the following .txt files. Pay particular attention to update the release number showed in the output of some examples: @@ -72,6 +74,5 @@ * stackless.txt * standalone-howto.txt (remove/or update) * svn-help.txt - * theory.txt * translation-aspects.txt * translation.txt From antocuni at codespeak.net Fri Feb 9 19:52:20 2007 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Fri, 9 Feb 2007 19:52:20 +0100 (CET) Subject: [pypy-svn] r38305 - pypy/dist/pypy/doc Message-ID: <20070209185220.7CD5410090@code0.codespeak.net> Author: antocuni Date: Fri Feb 9 19:52:19 2007 New Revision: 38305 Modified: pypy/dist/pypy/doc/getting-started.txt Log: Mention the exact version of the SDK we tested against. Modified: pypy/dist/pypy/doc/getting-started.txt ============================================================================== --- pypy/dist/pypy/doc/getting-started.txt (original) +++ pypy/dist/pypy/doc/getting-started.txt Fri Feb 9 19:52:19 2007 @@ -754,9 +754,12 @@ 2 >>>> -Unfortunately, at the moment it's impossible to do the translation -under Windows because of a bug of Microsoft ilasm that crashes when -trying to assemble the huge IL file produced by GenCLI. +Unfortunately, at the moment it's very likely that you won't be able +to do the translation under Windows because of a bug of Microsoft +ilasm that crashes when trying to assemble the huge IL file produced +by GenCLI. Microsoft .NET SDK 2.0.50727.42 is affected by this bug; +other version could be affected as well: if you find a version of the +SDK that works, please tell us. As a workaround you can use the Mono ilasm, which does the job fine. Once assembled, you can run the produced executable with the From pedronis at codespeak.net Fri Feb 9 21:03:52 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Fri, 9 Feb 2007 21:03:52 +0100 (CET) Subject: [pypy-svn] r38311 - pypy/dist/pypy/tool Message-ID: <20070209200352.A2D301007E@code0.codespeak.net> Author: pedronis Date: Fri Feb 9 21:03:49 2007 New Revision: 38311 Modified: pypy/dist/pypy/tool/watchdog.py Log: oops, wrong handling of child exit status Modified: pypy/dist/pypy/tool/watchdog.py ============================================================================== --- pypy/dist/pypy/tool/watchdog.py (original) +++ pypy/dist/pypy/tool/watchdog.py Fri Feb 9 21:03:49 2007 @@ -24,7 +24,10 @@ else: t.cancel() break - sys.exit(status) + if os.WIFEXITED(status): + sys.exit(os.WEXITSTATUS(status)) + else: + sys.exit(1) From cfbolz at codespeak.net Fri Feb 9 23:26:08 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 9 Feb 2007 23:26:08 +0100 (CET) Subject: [pypy-svn] r38325 - pypy/dist/pypy/translator/goal Message-ID: <20070209222608.568CE10095@code0.codespeak.net> Author: cfbolz Date: Fri Feb 9 23:26:06 2007 New Revision: 38325 Modified: pypy/dist/pypy/translator/goal/targetpypystandalone.py Log: ouch, add sys.pypy_translation_info only _after_ the thread option was handled. Is there a good reason not to do this as a dependency? Modified: pypy/dist/pypy/translator/goal/targetpypystandalone.py ============================================================================== --- pypy/dist/pypy/translator/goal/targetpypystandalone.py (original) +++ pypy/dist/pypy/translator/goal/targetpypystandalone.py Fri Feb 9 23:26:06 2007 @@ -118,12 +118,6 @@ # expose the following variables to ease debugging global space, entry_point - # obscure hack to stuff the translation options into the translated PyPy - import pypy.module.sys - options = make_dict(config) - wrapstr = 'space.wrap(%r)' % (options) - pypy.module.sys.Module.interpleveldefs['pypy_translation_info'] = wrapstr - if config.translation.thread: config.objspace.usemodules.thread = True elif config.objspace.usemodules.thread: @@ -141,6 +135,12 @@ import translate translate.log_config(config.objspace, "PyPy config object") + # obscure hack to stuff the translation options into the translated PyPy + import pypy.module.sys + options = make_dict(config) + wrapstr = 'space.wrap(%r)' % (options) + pypy.module.sys.Module.interpleveldefs['pypy_translation_info'] = wrapstr + return self.get_entry_point(config) def get_entry_point(self, config): From cfbolz at codespeak.net Fri Feb 9 23:45:35 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 9 Feb 2007 23:45:35 +0100 (CET) Subject: [pypy-svn] r38326 - pypy/dist/pypy/doc Message-ID: <20070209224535.2A2DD10095@code0.codespeak.net> Author: cfbolz Date: Fri Feb 9 23:45:33 2007 New Revision: 38326 Modified: pypy/dist/pypy/doc/faq.txt Log: add answers to three of the FAQs Modified: pypy/dist/pypy/doc/faq.txt ============================================================================== --- pypy/dist/pypy/doc/faq.txt (original) +++ pypy/dist/pypy/doc/faq.txt Fri Feb 9 23:45:33 2007 @@ -24,19 +24,55 @@ On what platforms does it run? ------------------------------ -XXX +PyPy is regularly and extensively tested on Linux machines and on Mac OS X and +mostly works under Windows too (but is tested there less extensively). PyPy +needs a CPython running on the target platform to bootstrap, cross compilation +is not really meant to work, currently. Apart from that restriction, translating +PyPy is supposed to produce nice platform-independent code, so the chances are +not too bad that it works. + +Currently (due to time restrictions) we are not trying hard to make PyPy support +64 bit platforms. While this seems to still mostly work out, a few modules won't +work on 64 bit machines, such as ``bz2``. ---------------------------------------------- Which Python version (2.x?) does PyPy support? ---------------------------------------------- -XXX +PyPy currently targets to be fully compatible with Python 2.4. That means that +it contains the stdandard library of Python 2.4 and that it supports 2.4 +features (such as decorators) but not the 2.5 features (with statement, ternary +operators). The 2.5 features will probably be eventually suported, the most +important reasons why nobody is working on them is that we did not promise this +to the EU and have currently enough other tasks. ------------------------------------------------- Do threads work? What are the modules that work? ------------------------------------------------- -XXX +Operating-System threads work in a limited way. If you enable the ``thread`` +module then PyPy will get support for GIL based threading. The limitations are +that not that many IO operations actually release the GIL, which reduces the +usefulness of threads. On the other hand, PyPy fully supports `stackless-like +microthreads`_. + +As for other modules: The general rule of thumb is that pure-Python modules +work, C extension modules don't. Some of the C extension modules of the standard +library have been re-implemented in pure Python or as a mixed module (for some +there were also older pure-Python versions available). A (probably incomplete) +list: + + * pure Python implementations: binascii, cmath, collections, cPickle, + cStringIO, datetime, functional, imp, itertools, md5, operator, + sha, struct + + * mixed module implementations: exceptions, sys, __builtin__, posix + _codecs, gc, _weakref, array, marshal, errno, math, _sre, parser, symbol, + _random, socket, unicodedata, mmap, fcntl, time, select, bz2, crypt, + signal + + +.. _`stackless-like microthreads`: stackless.html ------------------------------------ Can I use CPython extension modules? From cfbolz at codespeak.net Fri Feb 9 23:48:42 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 9 Feb 2007 23:48:42 +0100 (CET) Subject: [pypy-svn] r38327 - pypy/dist/pypy/doc/js Message-ID: <20070209224842.6D4DE10095@code0.codespeak.net> Author: cfbolz Date: Fri Feb 9 23:48:41 2007 New Revision: 38327 Modified: pypy/dist/pypy/doc/js/whatis.txt Log: some fixes. needs some work before the release, I think Modified: pypy/dist/pypy/doc/js/whatis.txt ============================================================================== --- pypy/dist/pypy/doc/js/whatis.txt (original) +++ pypy/dist/pypy/doc/js/whatis.txt Fri Feb 9 23:48:41 2007 @@ -10,10 +10,10 @@ Purpose: ======== -This document explains what is pypy.js and mostly, what is not. +This document explains what pypy.js is and (just as important) what it is not. -What is? --------- +What is it? +----------- Pypy.js is mostly RPython to javascript converter. Nothing more, nothing less. By `using`_ it you can write down RPython code (static enough subset @@ -31,26 +31,26 @@ exception handling etc. But you'll not get python dynamic features - modifying dict access etc. -This also means, that it is much easier to write code in pypy.js than in -JavaScript itself. Whole b'n'b demo is just about 250 lines of code, with +This also means that it is much easier to write code in pypy.js than in +JavaScript itself. The whole b'n'b demo is just about 250 lines of code, with many AJAX calls. Imagine writing it in JavaScript. We can say that pypy.js extends Mochikit's motto ("Makes JavaScript suck less"), by "Makes JavaScript suck less, by not using it". -.. _`using`: http://codespeak.net/XXX +.. _`using`: using.html -What is not? ------------- +What is it not? +--------------- -Pypy.js is definitely not browser-abstract library (with exceptions to -semi-transparent AJAX calls, which are trying to be browser-independend). -Pypy.js is trying to expose browser API as it comes, with all shortcoming. +Pypy.js is definitely not a browser-abstract library (with exceptions to +the semi-transparent AJAX calls, which are trying to be browser-independent). +Pypy.js is trying to expose the browser API as it comes, with all shortcomings. If you need something like that you can expose any existing JS library -(there is example with few mochikit calls in modules). But it seems evident +(there is an example with a few mochikit calls in modules). But it seems evident that writing such a library on top of pypy.js sounds more interesting. -Pypy.js is not browser for python. Right now you cannot run your DOM-dependent +Pypy.js is not a browser for python. Right now you cannot run your DOM-dependent code on top of CPython (and this is unlikely to change in a future, because we don't want to have just-another-browser-problem, do we?). Altough because RPython is just subset of python, nothing stops you from separating code From cfbolz at codespeak.net Sat Feb 10 00:01:00 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sat, 10 Feb 2007 00:01:00 +0100 (CET) Subject: [pypy-svn] r38328 - pypy/dist/pypy/doc Message-ID: <20070209230100.32AB410097@code0.codespeak.net> Author: cfbolz Date: Sat Feb 10 00:00:59 2007 New Revision: 38328 Modified: pypy/dist/pypy/doc/getting-started.txt Log: some small fixes and additions Modified: pypy/dist/pypy/doc/getting-started.txt ============================================================================== --- pypy/dist/pypy/doc/getting-started.txt (original) +++ pypy/dist/pypy/doc/getting-started.txt Sat Feb 10 00:00:59 2007 @@ -183,6 +183,9 @@ cd pypy/bin python py.py --help +(this will give you a daunting list, so it is a good idea to use a pager). +py.py supports most of the options that CPython supports too (in addition to a +large amount of options that can be used to customize py.py). As an example of using PyPy from the command line, you could type:: python py.py -c "from test import pystone; pystone.main(10)" @@ -198,7 +201,7 @@ Interpreter-level console +++++++++++++++++++++++++ -There are a few extra features of the PyPy console: If you press +There are quite a few extra features of the PyPy console: If you press on the console you enter the interpreter-level console, a usual CPython console. You can then access internal objects of PyPy (e.g. the object space) and any variables you have created on the PyPy @@ -330,6 +333,7 @@ cd pypy python test_all.py +(this is not recommended, since it takes hours and uses huge amounts of RAM). Alternatively, you may run subtests by going to the correct subdirectory and running them individually:: @@ -457,7 +461,8 @@ Translating the flow graph to Javascript code +++++++++++++++++++++++++++++++++++++++++++++ -The Javascript backend is still experimental but will be worked on during this +The Javascript backend is still experimental but was heavily improved +during last years `Google summer of code`_. It contains some rudimentary support for the document object model and a good integration with PyPy's unittesting framework. Code can be tested with the `Spidermonkey`_ commandline javascript @@ -475,6 +480,11 @@ >>> a = t.annotate([int, int]) >>> source = t.source_js() +If you want to know more about the JavaScript backend please refer to the +`JavaScript docs`_. + +.. _`JavaScript docs`: js/whatis.html + Translating the flow graph to CLI code ++++++++++++++++++++++++++++++++++++++ @@ -537,7 +547,7 @@ By default the translation process will try to use the `Boehm-Demers-Weiser garbage collector`_ for the translated PyPy (Use -``--gc=ref`` to use our own reference counting implementation which +``--gc=framework`` to use our own exact mark-n-sweep implementation which at the moment is slower but doesn't have external dependencies). Otherwise, be sure to install Boehm before starting the translation (e.g. by running ``apt-get install libgc-dev`` on Debian). @@ -598,7 +608,7 @@ programs, e.g. a slightly changed version of Pystone:: cd pypy/translator/goal - python translate.py targetrpystone + python translate.py targetrpystonedalone Translating PyPy under Windows From cfbolz at codespeak.net Sat Feb 10 00:02:04 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sat, 10 Feb 2007 00:02:04 +0100 (CET) Subject: [pypy-svn] r38329 - pypy/extradoc/planning/1.0 Message-ID: <20070209230204.E0C581009A@code0.codespeak.net> Author: cfbolz Date: Sat Feb 10 00:02:03 2007 New Revision: 38329 Modified: pypy/extradoc/planning/1.0/documentation.txt Log: some updates Modified: pypy/extradoc/planning/1.0/documentation.txt ============================================================================== --- pypy/extradoc/planning/1.0/documentation.txt (original) +++ pypy/extradoc/planning/1.0/documentation.txt Sat Feb 10 00:02:03 2007 @@ -26,13 +26,14 @@ improve getting-started (cfbolz, partially) + XXX put the windows things into their own file? + XXX add optional tools needed short how to compile on windows (based on docstring of goal/win32/gc_patch_windows.py) (antocuni) release announcement -architecture.txt: should maybe grow a bit or at least have an updated "status" -section. +architecture.txt: should grow a bit and have an updated "status" section. contributor.txt: needs to be updated @@ -42,7 +43,7 @@ particular attention to update the release number showed in the output of some examples: - * coding-guide.txt + * coding-guide.txt (reviewed by cfbolz) * configuration.txt (cfbolz) * constraints-and-logic.txt * contact.txt From pedronis at codespeak.net Sat Feb 10 01:07:32 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 10 Feb 2007 01:07:32 +0100 (CET) Subject: [pypy-svn] r38335 - pypy/dist/pypy/tool/pytest Message-ID: <20070210000732.82CE910093@code0.codespeak.net> Author: pedronis Date: Sat Feb 10 01:07:29 2007 New Revision: 38335 Modified: pypy/dist/pypy/tool/pytest/htmlreport.py Log: let tweak the section headers Modified: pypy/dist/pypy/tool/pytest/htmlreport.py ============================================================================== --- pypy/dist/pypy/tool/pytest/htmlreport.py (original) +++ pypy/dist/pypy/tool/pytest/htmlreport.py Sat Feb 10 01:07:29 2007 @@ -103,19 +103,19 @@ # generate html files # - def makeindex(self, indexpath): + def makeindex(self, indexpath, detail="PyPy - latest"): self.indexpath = indexpath self.data = {} doc = Document(title='pypy test results') body = doc.body coretests, noncoretests = self.getcorelists() - body.append(html.h2("PyPy - latest compliance test results - " - "core tests")) + body.append(html.h2("%s compliance test results - " + "core tests" % detail)) body.append(self.render_test_summary('core', coretests)) body.append(self.render_latest_table(coretests)) body.append( - html.h2("PyPy - latest compliance test results - non-core tests")) + html.h2("%s compliance test results - non-core tests" % detail)) body.append(self.render_test_summary('noncore', noncoretests)) body.append(self.render_latest_table(noncoretests)) doc.writetopath(indexpath) From antocuni at codespeak.net Sat Feb 10 10:46:40 2007 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Sat, 10 Feb 2007 10:46:40 +0100 (CET) Subject: [pypy-svn] r38355 - pypy/dist/pypy/doc Message-ID: <20070210094640.558D210032@code0.codespeak.net> Author: antocuni Date: Sat Feb 10 10:46:39 2007 New Revision: 38355 Added: pypy/dist/pypy/doc/cli-backend.txt (contents, props changed) Modified: pypy/dist/pypy/doc/index.txt Log: - Move the JS-backend tutorial to the user section; - Add some documentation on the CLI backend, partly borrowed from my thesis Added: pypy/dist/pypy/doc/cli-backend.txt ============================================================================== --- (empty file) +++ pypy/dist/pypy/doc/cli-backend.txt Sat Feb 10 10:46:39 2007 @@ -0,0 +1,431 @@ +=============== +The CLI backend +=============== + +The goal of GenCLI is to compile RPython programs to the CLI virtual +machine. + + +Target environment and language +=============================== + +The target of GenCLI is the Common Language Infrastructure environment +as defined by the `Standard Ecma 335`_. + +While in an ideal world we might suppose GenCLI to run fine with +every implementation conforming to that standard, we know the world we +live in is far from ideal, so extra efforts can be needed to mantain +compatibility with more than one implementation. + +At the moment of writing the two most popular implementations of the +standard are supported: Microsoft Common Language Runtime (CLR) and +Mono. + +Then we have to choose how to generate the real executables. There are +two main alternatives: generating source files in some high level +language (such as C#) or generating assembly level code in +Intermediate Language (IL). + +The IL approach is much faster during the code generation +phase, because it doesn't need to call a compiler. By contrast the +high level approach has two main advantages: + + - the code generation part could be easier because the target + language supports high level control structures such as + structured loops; + + - the generated executables take advantage of compiler's + optimizations. + +In reality the first point is not an advantage in the PyPy context, +because the `flow graph`_ we start from is quite low level and Python +loops are already expressed in terms of branches (i.e., gotos). + +About the compiler optimizations we must remember that the flow graph +we receive from earlier stages is already optimized: PyPy implements +a number of optimizations such a constant propagation and +dead code removal, so it's not obvious if the compiler could +do more. + +Moreover by emitting IL instruction we are not constrained to rely on +compiler choices but can directly choose how to map CLI opcodes: since +the backend often know more than the compiler about the context, we +might expect to produce more efficient code by selecting the most +appropriate instruction; e.g., we can check for arithmetic overflow +only when strictly necessary. + +The last but not least reason for choosing the low level approach is +flexibility in how to get an executable starting from the IL code we +generate: + + - write IL code to a file, then call the ilasm assembler; + + - directly generate code on the fly by accessing the facilities + exposed by the System.Reflection.Emit API. + +The second point is not feasible yet because at the moment there is no +support for accessing system libraries, but in future it could lead to +an interesting GenCLI feature, i.e. the ability of emitting dynamic +code at runtime. + + +Handling platform differences +============================= + +Since our goal is to support both Microsoft CLR we have to handle the +differences between the twos; in particular the main differences are +in the name of the helper tools we need to call: + +=============== ======== ====== +Tool CLR Mono +=============== ======== ====== +IL assembler ilasm ilasm2 +C# compiler csc gmcs +Runtime ... mono +=============== ======== ====== + +The code that handles these differences is located in the sdk.py +module: it defines an abstract class exposing some methods returning +the name of the helpers and one subclass for each of the two supported +platforms. + + +Targeting the CLI Virtual Machine +================================= + +In order to write a CLI backend we have to take a number of decisions. +First, we have to choose the typesystem to use: given that CLI +natively supports primitives like classes and instances, +ootypesystem is the most natural choice. + +Once the typesystem has been chosen there is a number of steps we have +to do for completing the backend: + + - map ootypesystem's types to CLI Common Type System's + types; + + - map ootypesystem's low level operation to CLI instructions; + + - map Python exceptions to CLI exceptions; + + - write a code generator that translates a flow graph + into a list of CLI instructions; + + - write a class generator that translates ootypesystem + classes into CLI classes. + + +Mapping primitive types +----------------------- + +The `rtyper` give us a flow graph annotated with types belonging to +ootypesystem: in order to produce CLI code we need to translate these +types into their Common Type System equivalents. + +For numeric types the conversion is straightforward, since +there is a one-to-one mapping between the two typesystems, so that +e.g. Float maps to float64. + +For character types the choice is more difficult: RPython has two +distinct types for plain ASCII and Unicode characters (named UniChar), +while .NET only supports Unicode with the char type. There are at +least two ways to map plain Char to CTS: + + - map UniChar to char, thus mantaining the original distinction + between the two types: this has the advantage of being a + one-to-one translation, but has the disadvantage that RPython + strings will not be recognized as .NET strings, since they only + would be sequences of bytes; + + - map both char, so that Python strings will be treated as strings + also by .NET: in this case there could be problems with existing + Python modules that use strings as sequences of byte, such as the + built-in struct module, so we need to pay special attention. + +We think that mapping Python strings to .NET strings is +fundamental, so we chose the second option. + +Mapping built-in types +---------------------- + +As we saw in section ootypesystem defines a set of types that take +advantage of built-in types offered by the platform. + +For the sake of simplicity we decided to write wrappers +around .NET classes in order to match the signatures required by +pypylib.dll: + +=================== =========================================== +ootype CLI +=================== =========================================== +String System.String +StringBuilder System.Text.StringBuilder +List System.Collections.Generic.List +Dict System.Collections.Generic.Dictionary +CustomDict pypy.runtime.Dict +DictItemsIterator pypy.runtime.DictItemsIterator +=================== =========================================== + +Wrappers exploit inheritance for wrapping the original classes, so, +for example, pypy.runtime.List is a subclass of +System.Collections.Generic.List that provides methods whose names +match those found in the _GENERIC_METHODS of ootype.List + +The only exception to this rule is the String class, which is not +wrapped since in .NET we can not subclass System.String. Instead, we +provide a bunch of static methods in pypylib.dll that implement the +methods declared by ootype.String._GENERIC_METHODS, then we call them +by explicitly passing the string object in the argument list. + + +Mapping instructions +-------------------- + +PyPy's low level operations are expressed in Static Single Information +(SSI) form, such as this:: + + v2 = int_add(v0, v1) + +By contrast the CLI virtual machine is stack based, which means the +each operation pops its arguments from the top of the stacks and +pushes its result there. The most straightforward way to translate SSI +operations into stack based operations is to explicitly load the +arguments and store the result into the appropriate places:: + + LOAD v0 + LOAD v1 + int_add + STORE v2 + +The code produced works correctly but has some inefficiency issue that +can be addressed during the optimization phase. + +The CLI Virtual Machine is fairly expressive, so the conversion +between PyPy's low level operations and CLI instruction is relatively +simple: many operations maps directly to the correspondent +instruction, e.g int_add and sub. + +By contrast some instructions do not have a direct correspondent and +have to be rendered as a sequence of CLI instructions: this is the +case of the "less-equal" and "greater-equal" family of instructions, +that are rendered as "greater" or "less" followed by a boolean "not", +respectively. + +Finally, there are some instructions that cannot be rendered directly +without increasing the complexity of the code generator, such as +int_abs (which returns the absolute value of its argument). These +operations are translated by calling some helper function written in +C#. + +The code that implements the mapping is in the modules opcodes.py. + +Mapping exceptions +------------------ + +Both RPython and CLI have its own set of exception classes: some of +these are pretty similar; e.g., we have OverflowError, +ZeroDivisionError and IndexError on the first side and +OverflowException, DivideByZeroException and IndexOutOfRangeException +on the other side. + +The first attempt was to map RPython classes to their corresponding +CLI ones: this worked for simple cases, but it would have triggered +subtle bugs in more complex ones, because the two exception +hierarchies don't completely overlap. + +At the moment we've choosen to build an RPython exception hierarchy +completely independent from the CLI one, but this means that we can't +rely on exceptions raised by built-in operations. The currently +implemented solution is to do an exception translation on-the-fly. + +As an example consider the RPython int_add_ovf operation, that sums +two integers and raises an OverflowError exception in case of +overflow. For implementing it we can use the built-in add.ovf CLI +instruction that raises System.OverflowExcepion when the result +overflows, catch that exception and throw a new one:: + + .try + { + ldarg 'x_0' + ldarg 'y_0' + add.ovf + stloc 'v1' + leave __check_block_2 + } + catch [mscorlib]System.OverflowException + { + newobj instance void class OverflowError::.ctor() + throw + } + + +Translating flow graphs +----------------------- + +As we saw previously in PyPy\ function and method bodies are +represented by flow graphs that we need to translate CLI IL code. Flow +graphs are expressed in a format that is very suitable for being +translated to low level code, so that phase is quite straightforward, +though the code is a bit involed because we need to take care of three +different types of blocks. + +The code doing this work is located in the Function.render +method in the file function.py. + +First of all it searches for variable names and types used by +each block; once they are collected it emits a .local IL +statement used for indicating the virtual machine the number and type +of local variables used. + +Then it sequentally renders all blocks in the graph, starting from the +start block; special care is taken for the return block which is +always rendered at last to meet CLI requirements. + +Each block starts with an unique label that is used for jumping +across, followed by the low level instructions the block is composed +of; finally there is some code that jumps to the appropriate next +block. + +Conditional and unconditional jumps are rendered with their +corresponding IL instructions: brtrue, brfalse. + +Blocks that needs to catch exceptions use the native facilities +offered by the CLI virtual machine: the entire block is surrounded by +a .try statement followed by as many catch as needed: each catching +sub-block then branches to the appropriate block:: + + + # RPython + try: + # block0 + ... + except ValueError: + # block1 + ... + except TypeError: + # block2 + ... + + // IL + block0: + .try { + ... + leave block3 + } + catch ValueError { + ... + leave block1 + } + catch TypeError { + ... + leave block2 + } + block1: + ... + br block3 + block2: + ... + br block3 + block3: + ... + +There is also an experimental feature that makes GenCLI to use its own +exception handling mechanism instead of relying on the .NET +one. Surprisingly enough, benchmarks are about 40% faster with our own +exception handling machinery. + + +Translating classes +------------------- + +As we saw in section sec:ootypes, the semantic of ootypesystem classes +is very similar to the .NET one, so the translation is mostly +straightforward. + +The related code is located in the module class\_.py. Rendered classes +are composed of four parts: + + - fields; + - user defined methods; + - default constructor; + - the ToString method, mainly for testing purposes + +Since ootype implicitly assumes all method calls to be late bound, as +an optimization before rendering the classes we search for methods +that are not overridden in subclasses, and declare as "virtual" only +the one that needs to. + +The constructor does nothing more than calling the base class +constructor and initializing class fields to their default value. + +Inheritance is straightforward too, as it is natively supported by +CLI. The only noticeable thing is that we map ootypesystem's ROOT +class to the CLI equivalent System.Object. + +The Runtime Environment +----------------------- + +The runtime environment is a collection of helper classes and +functions used and referenced by many of the GenCLI submodules. It is +written in C#, compiled to a DLL (Dynamic Link Library), then linked +to generated code at compile-time. + +The DLL is called pypylib and is composed of three parts: + + - a set of helper functions used to implements complex RPython + low-level instructions such as runtimenew and ooparse_int; + + - a set of helper classes wrapping built-in types + + - a set of helpers used by the test framework + + +The first two parts are contained in the pypy.runtime namespace, while +the third is in the pypy.test one. + + +Testing GenCLI +============== + +As the rest of PyPy, GenCLI is a test-driven project: there is at +least one unit test for almost each single feature of the +backend. This development methodology allowed us to early discover +many subtle bugs and to do some big refactoring of the code with the +confidence not to break anything. + +The core of the testing framework is in the module +pypy.translator.cli.test.runtest; one of the most important function +of this module is compile_function(): it takes a Python function, +compiles it to CLI and returns a Python object that runs the just +created executable when called. + +This way we can test GenCLI generated code just as if it were a simple +Python function; we can also directly run the generated executable, +whose default name is main.exe, from a shell: the function parameters +are passed as command line arguments, and the return value is printed +on the standard output:: + + # Python source: foo.py + from pypy.translator.cli.test.runtest import compile_function + + def foo(x, y): + return x+y, x*y + + f = compile_function(foo, [int, int]) + assert f(3, 4) == (7, 12) + + + # shell + $ mono main.exe 3 4 + (7, 12) + +GenCLI supports only few RPython types as parameters: int, r_uint, +r_longlong, r_ulonglong, bool, float and one-length strings (i.e., +chars). By contrast, most types are fine for being returned: these +include all primitive types, list, tuples and instances. + + + +.. _`Standard Ecma 335`: http://www.ecma-international.org/\\publications/standards/Ecma-335.htm +.. _`flow graph`: http://codespeak.net/pypy/dist/pypy/doc/translation.html#the-flow-model +.. _`rtyper`: http://codespeak.net/pypy/dist/pypy/doc/rtyper.html Modified: pypy/dist/pypy/doc/index.txt ============================================================================== --- pypy/dist/pypy/doc/index.txt (original) +++ pypy/dist/pypy/doc/index.txt Sat Feb 10 10:46:39 2007 @@ -24,6 +24,9 @@ to write modules in PyPy's style and compile them into regular CPython extension modules. +`JavaScript backend`_ describes how to use the JavaScript backend to create +AJAX-based web pages. + Status_ of the project. @@ -113,8 +116,7 @@ `rlib`_ describes some modules that can be used when implementing programs in RPython. -`JavaScript backend`_ describes how to use the JavaScript backend to create -AJAX-based web pages. +`CLI backend`_ describes the details of the .NET backend. `JIT Generation in PyPy`_ describes how we produce the Python Just-in-time Compiler from our Python interpreter. @@ -300,7 +302,7 @@ .. _`translation`: translation.html .. _`GenC backend`: translation.html#genc .. _`LLVM backend`: translation.html#llvm -.. _`CLI backend`: translation.html#gencli +.. _`CLI backend`: cli-backend.html .. _`Common Lisp backend`: translation.html#gencl .. _`Squeak backend`: translation.html#gensqueak .. _`revision report`: http://codespeak.net/pypy/rev/current From antocuni at codespeak.net Sat Feb 10 11:05:27 2007 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Sat, 10 Feb 2007 11:05:27 +0100 (CET) Subject: [pypy-svn] r38356 - pypy/dist/pypy/translator/cli Message-ID: <20070210100527.DE7831009D@code0.codespeak.net> Author: antocuni Date: Sat Feb 10 11:05:27 2007 New Revision: 38356 Modified: pypy/dist/pypy/translator/cli/function.py Log: Use native .NET exception by default, else we would break the clr module. Modified: pypy/dist/pypy/translator/cli/function.py ============================================================================== --- pypy/dist/pypy/translator/cli/function.py (original) +++ pypy/dist/pypy/translator/cli/function.py Sat Feb 10 11:05:27 2007 @@ -17,7 +17,7 @@ from pypy.translator.cli.support import log from pypy.translator.cli.ilgenerator import CLIBaseGenerator -USE_LAST = True +USE_LAST = False class NativeExceptionHandler(object): def begin_try(self): From antocuni at codespeak.net Sat Feb 10 14:21:25 2007 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Sat, 10 Feb 2007 14:21:25 +0100 (CET) Subject: [pypy-svn] r38377 - pypy/dist/pypy/translator/cli Message-ID: <20070210132125.908BA10087@code0.codespeak.net> Author: antocuni Date: Sat Feb 10 14:21:25 2007 New Revision: 38377 Modified: pypy/dist/pypy/translator/cli/dotnet.py pypy/dist/pypy/translator/cli/metavm.py Log: Don't crash when setting an array item to None. Modified: pypy/dist/pypy/translator/cli/dotnet.py ============================================================================== --- pypy/dist/pypy/translator/cli/dotnet.py (original) +++ pypy/dist/pypy/translator/cli/dotnet.py Sat Feb 10 14:21:25 2007 @@ -4,6 +4,7 @@ from pypy.annotation.model import SomeObject, SomeInstance, SomeOOInstance, SomeInteger, s_None,\ s_ImpossibleValue, lltype_to_annotation, annotation_to_lltype, SomeChar, SomeString, SomePBC from pypy.annotation.binaryop import _make_none_union +from pypy.annotation import model as annmodel from pypy.rlib.rarithmetic import r_uint, r_longlong, r_ulonglong from pypy.rpython.error import TyperError from pypy.rpython.extregistry import ExtRegistryEntry @@ -56,6 +57,8 @@ def setitem((ooinst, index), s_value): if ooinst.ootype._isArray: + if s_value is annmodel.s_None: + return s_None ELEMENT = ooinst.ootype._ELEMENT VALUE = s_value.ootype assert ootype.isSubclass(VALUE, ELEMENT) @@ -114,7 +117,7 @@ def rtype_setitem((r_inst, r_int), hop): if not r_inst.lowleveltype._isArray: - raise TyperError("setitem() on a non-array instance") + raise TyperError("setitem() on a non-array instance") vlist = hop.inputargs(*hop.args_r) hop.exception_is_here() return hop.genop('cli_setelem', vlist, hop.r_result.lowleveltype) @@ -446,7 +449,7 @@ def init_array(type, *args): # PythonNet doesn't provide a straightforward way to create arrays... fake it with a list - return args + return list(args) class Entry(ExtRegistryEntry): _about_ = new_array Modified: pypy/dist/pypy/translator/cli/metavm.py ============================================================================== --- pypy/dist/pypy/translator/cli/metavm.py (original) +++ pypy/dist/pypy/translator/cli/metavm.py Sat Feb 10 14:21:25 2007 @@ -235,7 +235,10 @@ v_array, v_index, v_elem = op.args generator.load(v_array) generator.load(v_index) - generator.load(v_elem) + if v_elem.concretetype is ootype.Void and v_elem.value is None: + generator.ilasm.opcode('ldnull') + else: + generator.load(v_elem) elemtype = generator.cts.lltype_to_cts(v_array.concretetype) generator.ilasm.opcode('stelem', elemtype) From hpk at codespeak.net Sat Feb 10 14:22:42 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sat, 10 Feb 2007 14:22:42 +0100 (CET) Subject: [pypy-svn] r38379 - pypy/branch/pytrunkmerge/pypy Message-ID: <20070210132242.A73F91007E@code0.codespeak.net> Author: hpk Date: Sat Feb 10 14:22:42 2007 New Revision: 38379 Removed: pypy/branch/pytrunkmerge/pypy/ Log: getting a new pypy-dist to the pytrunkmerge branch From hpk at codespeak.net Sat Feb 10 14:24:36 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sat, 10 Feb 2007 14:24:36 +0100 (CET) Subject: [pypy-svn] r38380 - pypy/branch/pytrunkmerge/pypy Message-ID: <20070210132436.5C59D10081@code0.codespeak.net> Author: hpk Date: Sat Feb 10 14:24:35 2007 New Revision: 38380 Added: pypy/branch/pytrunkmerge/pypy/ - copied from r38379, pypy/dist/pypy/ Log: copying over dist/pypy to merge branch From pedronis at codespeak.net Sat Feb 10 14:47:14 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 10 Feb 2007 14:47:14 +0100 (CET) Subject: [pypy-svn] r38381 - pypy/extradoc/planning/1.0 Message-ID: <20070210134714.282791007E@code0.codespeak.net> Author: pedronis Date: Sat Feb 10 14:47:13 2007 New Revision: 38381 Modified: pypy/extradoc/planning/1.0/documentation.txt Log: remark about empty sections in translation.txt Modified: pypy/extradoc/planning/1.0/documentation.txt ============================================================================== --- pypy/extradoc/planning/1.0/documentation.txt (original) +++ pypy/extradoc/planning/1.0/documentation.txt Sat Feb 10 14:47:13 2007 @@ -76,4 +76,5 @@ * standalone-howto.txt (remove/or update) * svn-help.txt * translation-aspects.txt - * translation.txt + * translation.txt (contains long standing XXXd sections, kill them + or put something in them) From pedronis at codespeak.net Sat Feb 10 14:49:38 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 10 Feb 2007 14:49:38 +0100 (CET) Subject: [pypy-svn] r38382 - pypy/extradoc/planning/1.0 Message-ID: <20070210134938.14B0110081@code0.codespeak.net> Author: pedronis Date: Sat Feb 10 14:49:37 2007 New Revision: 38382 Added: pypy/extradoc/planning/1.0/testing.txt (contents, props changed) Log: created a file for testing todos Added: pypy/extradoc/planning/1.0/testing.txt ============================================================================== --- (empty file) +++ pypy/extradoc/planning/1.0/testing.txt Sat Feb 10 14:49:37 2007 @@ -0,0 +1,5 @@ +Testing and testing infrastructure for release 1.0 +==================================================== + +compliance tests for pypy-c's: (pedronis) testing it + From pedronis at codespeak.net Sat Feb 10 14:57:44 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 10 Feb 2007 14:57:44 +0100 (CET) Subject: [pypy-svn] r38383 - pypy/extradoc/planning/1.0 Message-ID: <20070210135744.3754110094@code0.codespeak.net> Author: pedronis Date: Sat Feb 10 14:57:43 2007 New Revision: 38383 Modified: pypy/extradoc/planning/1.0/testing.txt Log: some more testing related stuff I know about Modified: pypy/extradoc/planning/1.0/testing.txt ============================================================================== --- pypy/extradoc/planning/1.0/testing.txt (original) +++ pypy/extradoc/planning/1.0/testing.txt Sat Feb 10 14:57:43 2007 @@ -3,3 +3,8 @@ compliance tests for pypy-c's: (pedronis) testing it +pypy-c py.test -A tests: in-progress, fixing to be tested + +windows testing: antocuni, http://scottdial.com/pypytest/summary.html (?) + +we have nightly builds and tests going From antocuni at codespeak.net Sat Feb 10 15:05:05 2007 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Sat, 10 Feb 2007 15:05:05 +0100 (CET) Subject: [pypy-svn] r38384 - pypy/dist/pypy/doc Message-ID: <20070210140505.D190D1009B@code0.codespeak.net> Author: antocuni Date: Sat Feb 10 15:05:05 2007 New Revision: 38384 Modified: pypy/dist/pypy/doc/getting-started.txt pypy/dist/pypy/doc/translation.txt Log: Some more info about pypy.net Modified: pypy/dist/pypy/doc/getting-started.txt ============================================================================== --- pypy/dist/pypy/doc/getting-started.txt (original) +++ pypy/dist/pypy/doc/getting-started.txt Sat Feb 10 15:05:05 2007 @@ -488,9 +488,9 @@ Translating the flow graph to CLI code ++++++++++++++++++++++++++++++++++++++ -Use the CLI backend to translate the flowgraphs into .NET executables: +Use the `CLI backend`_ to translate the flowgraphs into .NET executables: ``gencli`` is quite mature now and can also compile the whole -interpreter. You can try out the CLI backend from the interactive +interpreter. You can try out the `CLI backend`_ from the interactive translator shell:: >>> def myfunc(a, b): return a+b @@ -743,7 +743,7 @@ Translating using the CLI backend +++++++++++++++++++++++++++++++++ -To create a standalone .NET executable using the CLI backend:: +To create a standalone .NET executable using the `CLI backend`_:: ./translate.py --text --batch --backend=cli targetpypystandalone.py @@ -775,6 +775,36 @@ fine. Once assembled, you can run the produced executable with the Microsoft Runtime. +You can also try the still very experimental ``clr`` module that +enables integration with the surrounding .NET environment. First, you +have to tell translate.py to include the ``clr`` module:: + + ./translate.py --text --batch --backend=cli targetpypystandalone.py --withmod-clr + +Then, you can dynamically load .NET classes using the +``clr.load_cli_classe`` method. After a class has been loaded, you can +instantiate and use it as it were a normal Python class. Special +methods such as indexers and properties are supported using the usual +Python syntax: + + >>>> import clr + >>>> ArrayList = clr.load_cli_class('System.Collections', 'ArrayList') + >>>> obj.Add(1) + 0 + >>>> obj.Add(2) + 1 + >>>> obj.Add("foo") + 2 + >>>> print obj[0], obj[1], obj[2] + 1 2 foo + >>>> print obj.Count + 3 + +At the moment the only way to load a .NET class is to explicitly use +``clr.load_cli_class``; in the future they will be automatically +loaded when accessing .NET namespaces as they were Python modules, as +IronPython does. + .. _`start reading sources`: Where to start reading the sources @@ -900,6 +930,7 @@ .. _`.NET Frameword SDK 2.0`: http://msdn.microsoft.com/netframework/downloads/updates/default.aspx .. _Mono: http://www.mono-project.com/Main_Page +.. _`CLI backend`: cli-backend.html .. _Dot Graphviz: http://www.graphviz.org/ .. _Pygame: http://www.pygame.org/ Modified: pypy/dist/pypy/doc/translation.txt ============================================================================== --- pypy/dist/pypy/doc/translation.txt (original) +++ pypy/dist/pypy/doc/translation.txt Sat Feb 10 15:05:05 2007 @@ -775,13 +775,13 @@ GenCLI ++++++ -GenCLI targets the `Common Language Infrastructure`_, the most famous +GenCLI_ targets the `Common Language Infrastructure`_, the most famous implementations of which are Microsoft's `.NET`_ and Mono_. -It is probably the most advanced of the object oriented backends -- it can -compile our two standard benchmarks, RPyStone (CPython's PyStone benchmark -modified slightly to be RPython) and a RPython version of the common Richards -benchmark. +It is the most advanced of the object oriented backends -- it can +compile the PyPy interpreter as well as our two standard benchmarks, +RPyStone (CPython's PyStone benchmark modified slightly to be RPython) +and a RPython version of the common Richards benchmark. It is almost entirely the work of Antonio Cuni, who started this backend as part of his `Master's thesis`_, the Google's Summer of Code @@ -791,6 +791,7 @@ .. _`.NET`: http://www.microsoft.com/net/ .. _Mono: http://www.mono-project.com/ .. _`Master's thesis`: http://codespeak.net/~antocuni/Implementing%20Python%20in%20.NET.pdf +.. _GenCLI: cli-backend.html GenJVM ++++++ From antocuni at codespeak.net Sat Feb 10 15:06:43 2007 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Sat, 10 Feb 2007 15:06:43 +0100 (CET) Subject: [pypy-svn] r38385 - pypy/extradoc/planning/1.0 Message-ID: <20070210140643.837AB1009B@code0.codespeak.net> Author: antocuni Date: Sat Feb 10 15:06:42 2007 New Revision: 38385 Modified: pypy/extradoc/planning/1.0/documentation.txt Log: update status Modified: pypy/extradoc/planning/1.0/documentation.txt ============================================================================== --- pypy/extradoc/planning/1.0/documentation.txt (original) +++ pypy/extradoc/planning/1.0/documentation.txt Sat Feb 10 15:06:42 2007 @@ -9,7 +9,7 @@ Link to the other pages as much as possible. -pypy.net - also update translation.txt (antocuni) +pypy.net - also update translation.txt (antocuni, done) js backend - is there something to update in translation.txt? @@ -29,7 +29,8 @@ XXX put the windows things into their own file? XXX add optional tools needed -short how to compile on windows (based on docstring of goal/win32/gc_patch_windows.py) (antocuni) +short how to compile on windows (based on docstring of +goal/win32/gc_patch_windows.py) (antocuni, done) release announcement From tismer at codespeak.net Sat Feb 10 15:21:25 2007 From: tismer at codespeak.net (tismer at codespeak.net) Date: Sat, 10 Feb 2007 15:21:25 +0100 (CET) Subject: [pypy-svn] r38387 - pypy/extradoc/sprintinfo/trillke-2007 Message-ID: <20070210142125.D35101007E@code0.codespeak.net> Author: tismer Date: Sat Feb 10 15:21:22 2007 New Revision: 38387 Modified: pypy/extradoc/sprintinfo/trillke-2007/people.txt Log: my travel data Modified: pypy/extradoc/sprintinfo/trillke-2007/people.txt ============================================================================== --- pypy/extradoc/sprintinfo/trillke-2007/people.txt (original) +++ pypy/extradoc/sprintinfo/trillke-2007/people.txt Sat Feb 10 15:21:22 2007 @@ -20,6 +20,7 @@ Antonio Cuni 25th-5th no idea Samuele Pedroni 25th-5th TBD Anders Chrigstr?m 25th-5th TBD +Christian Tismer 28th-5th Klocke ==================== ============== ===================== People on the following list were present at previous sprints: From hpk at codespeak.net Sat Feb 10 21:54:10 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sat, 10 Feb 2007 21:54:10 +0100 (CET) Subject: [pypy-svn] r38414 - pypy/branch/pytrunkmerge/pypy/rlib/parsing/test Message-ID: <20070210205410.4CE8D10094@code0.codespeak.net> Author: hpk Date: Sat Feb 10 21:54:08 2007 New Revision: 38414 Modified: pypy/branch/pytrunkmerge/pypy/rlib/parsing/test/test_ebnfparse.py Log: do view() and implicated pygame imports only if "--view" is specified Modified: pypy/branch/pytrunkmerge/pypy/rlib/parsing/test/test_ebnfparse.py ============================================================================== --- pypy/branch/pytrunkmerge/pypy/rlib/parsing/test/test_ebnfparse.py (original) +++ pypy/branch/pytrunkmerge/pypy/rlib/parsing/test/test_ebnfparse.py Sat Feb 10 21:54:08 2007 @@ -240,10 +240,12 @@ t = ToAST().transform(t) t = parse('{"a": "5", "b": [1, null, 3, true, {"f": "g", "h": 6}]}') print "".join(list(t.dot())) - t.view() + if py.test.config.option.view: + t.view() t = ToAST().transform(t) print "\n".join(list(t.dot())) - t.view() + if py.test.config.option.view: + t.view() def test_starparse(): regexs, rules, ToAST = parse_ebnf(""" From cfbolz at codespeak.net Sat Feb 10 21:54:28 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sat, 10 Feb 2007 21:54:28 +0100 (CET) Subject: [pypy-svn] r38415 - pypy/dist/pypy/rlib/parsing/test Message-ID: <20070210205428.30F6910098@code0.codespeak.net> Author: cfbolz Date: Sat Feb 10 21:54:27 2007 New Revision: 38415 Modified: pypy/dist/pypy/rlib/parsing/test/test_ebnfparse.py Log: oops, remove views, sorry for this Modified: pypy/dist/pypy/rlib/parsing/test/test_ebnfparse.py ============================================================================== --- pypy/dist/pypy/rlib/parsing/test/test_ebnfparse.py (original) +++ pypy/dist/pypy/rlib/parsing/test/test_ebnfparse.py Sat Feb 10 21:54:27 2007 @@ -240,10 +240,8 @@ t = ToAST().transform(t) t = parse('{"a": "5", "b": [1, null, 3, true, {"f": "g", "h": 6}]}') print "".join(list(t.dot())) - t.view() t = ToAST().transform(t) print "\n".join(list(t.dot())) - t.view() def test_starparse(): regexs, rules, ToAST = parse_ebnf(""" From cfbolz at codespeak.net Sat Feb 10 22:13:55 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sat, 10 Feb 2007 22:13:55 +0100 (CET) Subject: [pypy-svn] r38416 - in pypy/dist/pypy/rlib/parsing: . test Message-ID: <20070210211355.AC1D910095@code0.codespeak.net> Author: cfbolz Date: Sat Feb 10 22:13:55 2007 New Revision: 38416 Modified: pypy/dist/pypy/rlib/parsing/ebnfparse.py pypy/dist/pypy/rlib/parsing/test/test_pythonparse.py pypy/dist/pypy/rlib/parsing/test/test_regex.py Log: try to fix failures / skip a work in progress one. also make --view on py.test in this dir work properly. Modified: pypy/dist/pypy/rlib/parsing/ebnfparse.py ============================================================================== --- pypy/dist/pypy/rlib/parsing/ebnfparse.py (original) +++ pypy/dist/pypy/rlib/parsing/ebnfparse.py Sat Feb 10 22:13:55 2007 @@ -6,6 +6,7 @@ from pypy.rlib.parsing.regex import * from pypy.rlib.parsing.deterministic import DFA from pypy.rlib.parsing.lexer import Lexer, DummyLexer +from pypy.rlib.objectmodel import we_are_translated def make_ebnf_parser(): NONTERMINALNAME = parse_regex("([a-z]|_)[a-z0-9_]*") @@ -83,6 +84,9 @@ def parse(s): tokens = lexer.tokenize(s, eof=eof) s = parser.parse(tokens) + if not we_are_translated(): + if py.test.config.option.view: + s.view() return s return parse @@ -287,6 +291,11 @@ self.emit("assert tree.symbol == %r" % (startsymbol, )) self.emit("r = self.visit_%s(tree)" % (startsymbol, )) self.emit("assert len(r) == 1") + self.start_block("if not we_are_translated():") + self.start_block("if py.test.config.option.view:") + self.emit("r[0].view()") + self.end_block("option.view") + self.end_block("we_are_translated") self.emit("return r[0]") self.end_block("transform") self.end_block("ToAST") @@ -294,7 +303,8 @@ code = "\n".join(self.code) if print_code: print code - ns = {"RPythonVisitor": RPythonVisitor, "Nonterminal": Nonterminal} + ns = {"RPythonVisitor": RPythonVisitor, "Nonterminal": Nonterminal, + "we_are_translated": we_are_translated, "py": py} exec py.code.Source(code).compile() in ns ToAST = ns["ToAST"] ToAST.__module__ = "pypy.rlib.parsing.ebnfparse" Modified: pypy/dist/pypy/rlib/parsing/test/test_pythonparse.py ============================================================================== --- pypy/dist/pypy/rlib/parsing/test/test_pythonparse.py (original) +++ pypy/dist/pypy/rlib/parsing/test/test_pythonparse.py Sat Feb 10 22:13:55 2007 @@ -212,6 +212,7 @@ t = self.ToAST.transform(t) def test_trailers(self): + py.test.skip("in progress") t = self.parse(""" (a + b).foo[1 + i - j:](32, *args) """) @@ -237,7 +238,6 @@ """ t = self.parse(source) t = self.ToAST.transform(t) - t.view() def test_parse_this(self): s = py.magic.autopath().read() Modified: pypy/dist/pypy/rlib/parsing/test/test_regex.py ============================================================================== --- pypy/dist/pypy/rlib/parsing/test/test_regex.py (original) +++ pypy/dist/pypy/rlib/parsing/test/test_regex.py Sat Feb 10 22:13:55 2007 @@ -1,6 +1,7 @@ +import py from pypy.rlib.parsing.regex import * -def compile_rex(rex, view=False): +def compile_rex(rex): try: from pypy.translator.interactive import Translation except ImportError: @@ -10,7 +11,7 @@ fn = fda.make_code() t = Translation(fn) t.backendopt([str], backend="c") - if view: + if py.test.config.option.view: t.view() return t.compile_c() @@ -98,7 +99,7 @@ assert recognize("101010") assert recognize("101100") assert recognize("110000") - fn = compile_rex(rex, view=False) + fn = compile_rex(rex) assert fn("1000000") assert fn("101010") assert fn("101100") @@ -132,7 +133,7 @@ r = dfa.get_runner() assert r.recognize("aASsdFAASaSFasdfaSFD") assert not r.recognize("ASsdFAASaSFasdfaSFD") - fn = compile_rex(atoms, view=False) + fn = compile_rex(atoms) assert fn("a") assert fn("aaaaaAAAAaAAzAzaslwer") @@ -162,4 +163,4 @@ dfa = nfa.make_deterministic() r = dfa.get_runner() dfa.optimize() - fn = compile_rex(all, view=False) + fn = compile_rex(all) From fijal at codespeak.net Sat Feb 10 22:39:33 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 10 Feb 2007 22:39:33 +0100 (CET) Subject: [pypy-svn] r38420 - pypy/dist/pypy/doc Message-ID: <20070210213933.60C3510093@code0.codespeak.net> Author: fijal Date: Sat Feb 10 22:39:32 2007 New Revision: 38420 Modified: pypy/dist/pypy/doc/index.txt Log: Link to windows tests Modified: pypy/dist/pypy/doc/index.txt ============================================================================== --- pypy/dist/pypy/doc/index.txt (original) +++ pypy/dist/pypy/doc/index.txt Sat Feb 10 22:39:32 2007 @@ -69,8 +69,8 @@ an attempt to keep some focus. So PyPy requires a 32-bit machine or OS for now. -PyPy's own tests, daily updated, `on Linux`_, on Windows (unavailable -at the moment) and `on built pypy-c`_. +PyPy's own tests, daily updated, `on Linux`_, `on Windows`_ + and `on built pypy-c`_. `Nightly builds and benchmarks`_ of PyPy to C, CLI and LLVM (PowerPC machine). @@ -147,6 +147,7 @@ .. _`EU reports`: index-report.html .. _`garbage collection`: garbage_collection.html .. _`on Linux`: http://wyvern.cs.uni-duesseldorf.de/pypytest/summary.html +.. _`on Windows`: http://scottdial.com/pypytest/ .. _`on built pypy-c`: http://wyvern.cs.uni-duesseldorf.de/~fijal/pypy-c-tests/ .. _`ideas for PyPy related projects`: project-ideas.html .. _`Nightly builds and benchmarks`: http://tuatara.cs.uni-duesseldorf.de/benchmark.html From hpk at codespeak.net Sat Feb 10 22:46:25 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sat, 10 Feb 2007 22:46:25 +0100 (CET) Subject: [pypy-svn] r38421 - pypy/dist/pypy/doc Message-ID: <20070210214625.D64F710093@code0.codespeak.net> Author: hpk Date: Sat Feb 10 22:46:24 2007 New Revision: 38421 Modified: pypy/dist/pypy/doc/index.txt Log: remove revision report link (was not used, anyway) IIRC it was about showing which methods/builtins pypy supports, i don't think that's too interesting anymore. Modified: pypy/dist/pypy/doc/index.txt ============================================================================== --- pypy/dist/pypy/doc/index.txt (original) +++ pypy/dist/pypy/doc/index.txt Sat Feb 10 22:46:24 2007 @@ -306,7 +306,6 @@ .. _`CLI backend`: cli-backend.html .. _`Common Lisp backend`: translation.html#gencl .. _`Squeak backend`: translation.html#gensqueak -.. _`revision report`: http://codespeak.net/pypy/rev/current .. _`garbage collector`: garbage_collection.html .. _`extension compiler`: extcompiler.html .. _`py.py`: getting-started.html#main-entry-point From fijal at codespeak.net Sat Feb 10 23:22:19 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 10 Feb 2007 23:22:19 +0100 (CET) Subject: [pypy-svn] r38428 - pypy/dist/pypy/doc Message-ID: <20070210222219.8533210093@code0.codespeak.net> Author: fijal Date: Sat Feb 10 23:22:17 2007 New Revision: 38428 Modified: pypy/dist/pypy/doc/faq.txt Log: Two more points. Modified: pypy/dist/pypy/doc/faq.txt ============================================================================== --- pypy/dist/pypy/doc/faq.txt (original) +++ pypy/dist/pypy/doc/faq.txt Sat Feb 10 23:22:17 2007 @@ -78,7 +78,12 @@ Can I use CPython extension modules? ------------------------------------ -XXX +No and there are no current plans to implement so. CPython extension modules +relies heavily on CPython's C API which contains a lot of implementation details +like reference counting, exact C-level objects implementations etc. + +Although if your module uses ctypes rather than C-level code, there is a hope. +You can try to write a mixed module (see next question). ------------------------------------------ How do I write extension modules for PyPy? @@ -127,13 +132,12 @@ ---------------------------------------------------------------------- It seems that a lot of strange, unexplainable problems can be magically -solved by removing all the \*.pyc files from the PyPy source -tree. Another thing you can do is removing the pypy/_cache +solved by removing all the \*.pyc files from the PyPy source tree +(script py.cleanup from py/bin will do that for you). +Another thing you can do is removing the pypy/_cache completely. If the error is persistent and still annoys you after this treatment please send us a bug report (or even better, a fix :-) - - PyPy translation tool chain ======================================================================== @@ -141,7 +145,17 @@ What is this RPython language? ------------------------------ -XXX +RPython is a way of interpreting your python program, already running. +This means that term *RPython* is about some part of your program, +beggining from your entry point (function which you explicitely +specify) to whatever is called from that point, also across modules. + +It's a subset of Python which allows full type inference (ie. you can +deduct at compile time what are arguments of certain function), +which puts it a bit closer to C++ or Java. To read more about RPython +limitations read `RPython description`_ + +.. _`RPython description`: coding-guide.html#Restriced_Python ------------------------------------------------------------------- Couldn't we simply take a Python syntax tree and turn it into Lisp? From fijal at codespeak.net Sat Feb 10 23:23:16 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 10 Feb 2007 23:23:16 +0100 (CET) Subject: [pypy-svn] r38429 - pypy/dist/pypy/doc Message-ID: <20070210222316.7718510093@code0.codespeak.net> Author: fijal Date: Sat Feb 10 23:23:15 2007 New Revision: 38429 Modified: pypy/dist/pypy/doc/faq.txt Log: Fix ReST Modified: pypy/dist/pypy/doc/faq.txt ============================================================================== --- pypy/dist/pypy/doc/faq.txt (original) +++ pypy/dist/pypy/doc/faq.txt Sat Feb 10 23:23:15 2007 @@ -155,7 +155,7 @@ which puts it a bit closer to C++ or Java. To read more about RPython limitations read `RPython description`_ -.. _`RPython description`: coding-guide.html#Restriced_Python +.. _`RPython description`: coding-guide.html#restricted-python ------------------------------------------------------------------- Couldn't we simply take a Python syntax tree and turn it into Lisp? From xoraxax at codespeak.net Sat Feb 10 23:31:38 2007 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sat, 10 Feb 2007 23:31:38 +0100 (CET) Subject: [pypy-svn] r38430 - pypy/dist/pypy/doc Message-ID: <20070210223138.1752B10093@code0.codespeak.net> Author: xoraxax Date: Sat Feb 10 23:31:37 2007 New Revision: 38430 Modified: pypy/dist/pypy/doc/faq.txt Log: Added current speed figures to the FAQ. Modified: pypy/dist/pypy/doc/faq.txt ============================================================================== --- pypy/dist/pypy/doc/faq.txt (original) +++ pypy/dist/pypy/doc/faq.txt Sat Feb 10 23:31:37 2007 @@ -98,17 +98,12 @@ .. _whysoslow: As of August 2005, PyPy was successfully translated to C. Compared to -CPython the version of PyPy that still runs on top of CPython is slower by +CPython, the version of PyPy that still runs on top of CPython is slower by a factor of 2000. The first translated version was roughly 300 times slower -than CPython, version 0.8.0 about 10-20 times and the current version (0.9) -is about 4-7 times slower than CPython. +than CPython, version 0.8.0 about 10-20 times, version 0.9 about 4-7 times +and the current version (1.0) is about 2.4 - 5 times slower than CPython. +Note that the speed heavily depends on the enabled options at compile time. -Our translation process does not try to optimize the produced code very -much. So far the project has been focused on getting a well tested very -compliant self-contained static Python implementation. During end 2005 -and 2006 we are targetting optimizations at various levels. If you then -still think that PyPy is slow then we will have to find a better answer -:-) XXX From fijal at codespeak.net Sat Feb 10 23:33:33 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 10 Feb 2007 23:33:33 +0100 (CET) Subject: [pypy-svn] r38431 - pypy/dist/pypy/doc Message-ID: <20070210223333.E37BB10093@code0.codespeak.net> Author: fijal Date: Sat Feb 10 23:33:33 2007 New Revision: 38431 Modified: pypy/dist/pypy/doc/faq.txt Log: backend list + typo Modified: pypy/dist/pypy/doc/faq.txt ============================================================================== --- pypy/dist/pypy/doc/faq.txt (original) +++ pypy/dist/pypy/doc/faq.txt Sat Feb 10 23:33:33 2007 @@ -140,7 +140,7 @@ What is this RPython language? ------------------------------ -RPython is a way of interpreting your python program, already running. +RPython is a way of interpreting your python program, running already. This means that term *RPython* is about some part of your program, beggining from your entry point (function which you explicitely specify) to whatever is called from that point, also across modules. @@ -184,7 +184,25 @@ Which backends are there? ------------------------- -XXX +Somewhat mature backends: + +* Low level backends: C_, LLVM_ +* High level backends: CLI_, JVM_, JavaScript_ + +Partially implemented backends: + +* Squeak_, `Common Lisp`_ + +To learn more about backends take a look at a `translation document`_ + +.. _CLI: cli-backend.html +.. _JavaScript: js/whatis.html +.. _C: translation.html#the-c-back-end +.. _LLVM: translation.html#the-llvm-back-end +.. _`translation document`: translation.html +.. _JVM: translation.html#GenJVM +.. _Squeak: translation.html#GenSqueak +.. _`Common Lisp`: translation.html#GenCL ------------------------------------------------------- Are there other projects that need the PyPy tool chain? From xoraxax at codespeak.net Sat Feb 10 23:35:40 2007 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sat, 10 Feb 2007 23:35:40 +0100 (CET) Subject: [pypy-svn] r38432 - pypy/dist/pypy/doc Message-ID: <20070210223540.4579310093@code0.codespeak.net> Author: xoraxax Date: Sat Feb 10 23:35:39 2007 New Revision: 38432 Modified: pypy/dist/pypy/doc/faq.txt Log: Added XXX badge, fixed speed comparison from slower than to as slow as (there is a difference!). Modified: pypy/dist/pypy/doc/faq.txt ============================================================================== --- pypy/dist/pypy/doc/faq.txt (original) +++ pypy/dist/pypy/doc/faq.txt Sat Feb 10 23:35:39 2007 @@ -101,7 +101,7 @@ CPython, the version of PyPy that still runs on top of CPython is slower by a factor of 2000. The first translated version was roughly 300 times slower than CPython, version 0.8.0 about 10-20 times, version 0.9 about 4-7 times -and the current version (1.0) is about 2.4 - 5 times slower than CPython. +and the current version (1.0) is about 2.4 - 5 times as slow as CPython. Note that the speed heavily depends on the enabled options at compile time. @@ -252,7 +252,7 @@ of rpythonc compiling tool there would be much more temptation to try to compile arbitrary, pre-existing Python programs and this is fairly unlikely to work (to start, there is very little in the way of an -"RPython standard library"). +"RPython standard library"). XXX outdated --------------------------------------------------------------------------- From fijal at codespeak.net Sat Feb 10 23:43:36 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 10 Feb 2007 23:43:36 +0100 (CET) Subject: [pypy-svn] r38433 - pypy/dist/pypy/doc Message-ID: <20070210224336.B2DE010094@code0.codespeak.net> Author: fijal Date: Sat Feb 10 23:43:35 2007 New Revision: 38433 Modified: pypy/dist/pypy/doc/faq.txt Log: Fix rest. Rewording to give less hope about threads. Kill outdated sentence. Modified: pypy/dist/pypy/doc/faq.txt ============================================================================== --- pypy/dist/pypy/doc/faq.txt (original) +++ pypy/dist/pypy/doc/faq.txt Sat Feb 10 23:43:35 2007 @@ -51,10 +51,10 @@ ------------------------------------------------- Operating-System threads work in a limited way. If you enable the ``thread`` -module then PyPy will get support for GIL based threading. The limitations are +module then PyPy will get support for GIL based threading. One limitation is that not that many IO operations actually release the GIL, which reduces the usefulness of threads. On the other hand, PyPy fully supports `stackless-like -microthreads`_. +microthreads`_ (although both cannot be mixed yet). As for other modules: The general rule of thumb is that pure-Python modules work, C extension modules don't. Some of the C extension modules of the standard @@ -200,9 +200,9 @@ .. _C: translation.html#the-c-back-end .. _LLVM: translation.html#the-llvm-back-end .. _`translation document`: translation.html -.. _JVM: translation.html#GenJVM -.. _Squeak: translation.html#GenSqueak -.. _`Common Lisp`: translation.html#GenCL +.. _JVM: translation.html#genjvm +.. _Squeak: translation.html#gensqueak +.. _`Common Lisp`: translation.html#gencl ------------------------------------------------------- Are there other projects that need the PyPy tool chain? @@ -239,7 +239,7 @@ -------------------------------------------- One answer is that "officially speaking" supporting this is not a goal -of the PyPy project (RPython is essentially an implementation detail). +of the PyPy project. XXX From fijal at codespeak.net Sat Feb 10 23:45:34 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 10 Feb 2007 23:45:34 +0100 (CET) Subject: [pypy-svn] r38434 - pypy/dist/pypy/doc Message-ID: <20070210224534.E476010095@code0.codespeak.net> Author: fijal Date: Sat Feb 10 23:45:34 2007 New Revision: 38434 Modified: pypy/dist/pypy/doc/faq.txt Log: A bit more english than polish Modified: pypy/dist/pypy/doc/faq.txt ============================================================================== --- pypy/dist/pypy/doc/faq.txt (original) +++ pypy/dist/pypy/doc/faq.txt Sat Feb 10 23:45:34 2007 @@ -193,7 +193,7 @@ * Squeak_, `Common Lisp`_ -To learn more about backends take a look at a `translation document`_ +To learn more about backends take a look at the `translation document`_ .. _CLI: cli-backend.html .. _JavaScript: js/whatis.html From fijal at codespeak.net Sun Feb 11 00:11:40 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 11 Feb 2007 00:11:40 +0100 (CET) Subject: [pypy-svn] r38435 - pypy/dist/pypy/doc Message-ID: <20070210231140.E30C61008E@code0.codespeak.net> Author: fijal Date: Sun Feb 11 00:11:39 2007 New Revision: 38435 Modified: pypy/dist/pypy/doc/faq.txt Log: Rename Modified: pypy/dist/pypy/doc/faq.txt ============================================================================== --- pypy/dist/pypy/doc/faq.txt (original) +++ pypy/dist/pypy/doc/faq.txt Sun Feb 11 00:11:39 2007 @@ -227,7 +227,7 @@ `pypy/translator/goal/targetnopstandalone.py`_, which you compile by typing:: - python translate_pypy.py targetnopstandalone + python translate.py targetnopstandalone You can have a look at intermediate C source code, which is (at the moment) put in ``/tmp/usession-*/testing_1/testing_1.c``. Of course, From arigo at codespeak.net Sun Feb 11 02:00:57 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 11 Feb 2007 02:00:57 +0100 (CET) Subject: [pypy-svn] r38437 - in pypy/dist/pypy: rpython rpython/lltypesystem rpython/memory/gctransform translator/backendopt translator/c translator/stackless Message-ID: <20070211010057.15C1910093@code0.codespeak.net> Author: arigo Date: Sun Feb 11 02:00:53 2007 New Revision: 38437 Modified: pypy/dist/pypy/rpython/llinterp.py pypy/dist/pypy/rpython/lltypesystem/lloperation.py pypy/dist/pypy/rpython/memory/gctransform/framework.py pypy/dist/pypy/translator/backendopt/graphanalyze.py pypy/dist/pypy/translator/c/funcgen.py pypy/dist/pypy/translator/stackless/code.py pypy/dist/pypy/translator/stackless/frame.py pypy/dist/pypy/translator/stackless/transform.py Log: (pedronis, arigo) Remove the unsafe_call operation because its C equivalent is really unsafe: passing less arguments than expected in a C call is not really valid and crashes on some platforms with some optimization levels. Whacked instead at the stackless transform to avoid the operation. The principle of conservation of mess means that we had to introduce another similar operation, though, 'adr_call'. Don't use it. Modified: pypy/dist/pypy/rpython/llinterp.py ============================================================================== --- pypy/dist/pypy/rpython/llinterp.py (original) +++ pypy/dist/pypy/rpython/llinterp.py Sun Feb 11 02:00:53 2007 @@ -576,20 +576,20 @@ log.warn("op_indirect_call with graphs=None:", f) return self.op_direct_call(f, *args) - def op_unsafe_call(self, TGT, f): + def op_adr_call(self, TGT, f, *inargs): checkadr(f) obj = self.llinterpreter.typer.type_system.deref(f.ref()) assert hasattr(obj, 'graph') # don't want to think about that graph = obj.graph args = [] - for arg in obj.graph.startblock.inputargs: - args.append(arg.concretetype._defl()) + for inarg, arg in zip(inargs, obj.graph.startblock.inputargs): + args.append(lltype._cast_whatever(arg.concretetype, inarg)) frame = self.__class__(graph, args, self.llinterpreter, self) result = frame.eval() from pypy.translator.stackless.frame import storage_type assert storage_type(lltype.typeOf(result)) == TGT return lltype._cast_whatever(TGT, result) - op_unsafe_call.need_result_type = True + op_adr_call.need_result_type = True def op_malloc(self, obj): if self.llinterpreter.gc is not None: Modified: pypy/dist/pypy/rpython/lltypesystem/lloperation.py ============================================================================== --- pypy/dist/pypy/rpython/lltypesystem/lloperation.py (original) +++ pypy/dist/pypy/rpython/lltypesystem/lloperation.py Sun Feb 11 02:00:53 2007 @@ -135,8 +135,6 @@ 'direct_call': LLOp(canraise=(Exception,)), 'indirect_call': LLOp(canraise=(Exception,)), - #'safe_call': LLOp(), - 'unsafe_call': LLOp(canraise=(Exception,)), # __________ numeric operations __________ @@ -347,6 +345,7 @@ 'adr_ne': LLOp(canfold=True), 'adr_gt': LLOp(canfold=True), 'adr_ge': LLOp(canfold=True), + 'adr_call': LLOp(canraise=(Exception,)), 'cast_ptr_to_adr': LLOp(canfold=True), 'cast_adr_to_ptr': LLOp(canfold=True), 'cast_ptr_to_weakadr': LLOp(canfold=True), Modified: pypy/dist/pypy/rpython/memory/gctransform/framework.py ============================================================================== --- pypy/dist/pypy/rpython/memory/gctransform/framework.py (original) +++ pypy/dist/pypy/rpython/memory/gctransform/framework.py Sun Feb 11 02:00:53 2007 @@ -443,7 +443,6 @@ self.default(hop) gct_indirect_call = gct_direct_call - gct_unsafe_call = gct_direct_call def gct_malloc(self, hop): op = hop.spaceop Modified: pypy/dist/pypy/translator/backendopt/graphanalyze.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/graphanalyze.py (original) +++ pypy/dist/pypy/translator/backendopt/graphanalyze.py Sun Feb 11 02:00:53 2007 @@ -38,8 +38,6 @@ if op.args[-1].value is None: return True return self.analyze_indirect_call(op.args[-1].value, seen) - elif op.opname == "unsafe_call": - return True if self.operation_is_true(op): return True Modified: pypy/dist/pypy/translator/c/funcgen.py ============================================================================== --- pypy/dist/pypy/translator/c/funcgen.py (original) +++ pypy/dist/pypy/translator/c/funcgen.py Sun Feb 11 02:00:53 2007 @@ -10,7 +10,7 @@ from pypy.rpython.lltypesystem.lltype import UnsignedLongLong, Char, UniChar from pypy.rpython.lltypesystem.lltype import pyobjectptr, ContainerType from pypy.rpython.lltypesystem.lltype import Struct, Array, FixedSizeArray -from pypy.rpython.lltypesystem.lltype import ForwardReference +from pypy.rpython.lltypesystem.lltype import ForwardReference, FuncType from pypy.rpython.lltypesystem.llmemory import Address, WeakGcAddress from pypy.translator.backendopt.ssa import SSI_to_SSA @@ -377,10 +377,10 @@ r = self.expr(op.result) return 'OP_CALL_ARGS((%s), %s);' % (', '.join(args), r) - def OP_DIRECT_CALL(self, op): + def generic_call(self, FUNC, fnexpr, args_v, v_result): args = [] - fn = op.args[0] - for v, ARGTYPE in zip(op.args[1:], fn.concretetype.TO.ARGS): + assert len(args_v) == len(FUNC.TO.ARGS) + for v, ARGTYPE in zip(args_v, FUNC.TO.ARGS): if ARGTYPE is Void: continue # skip 'void' argument args.append(self.expr(v)) @@ -388,25 +388,32 @@ if isinstance(ARGTYPE, ContainerType): args[-1] = '*%s' % (args[-1],) - line = '%s(%s);' % (self.expr(fn), ', '.join(args)) - if self.lltypemap(op.result) is not Void: + line = '%s(%s);' % (fnexpr, ', '.join(args)) + if self.lltypemap(v_result) is not Void: # skip assignment of 'void' return value - r = self.expr(op.result) + r = self.expr(v_result) line = '%s = %s' % (r, line) return line - # the following works since the extra arguments that indirect_call has - # is removed by zip() - OP_INDIRECT_CALL = OP_DIRECT_CALL - - def OP_UNSAFE_CALL(self, op): - line = '((%s (*)())(%s))();' % (cdecl(self.lltypename(op.result), ''), - self.expr(op.args[0])) - if self.lltypemap(op.result) is not Void: - r = self.expr(op.result) - line = '%s = %s' % (r, line) - return line - + def OP_DIRECT_CALL(self, op): + fn = op.args[0] + return self.generic_call(fn.concretetype, self.expr(fn), + op.args[1:], op.result) + + def OP_INDIRECT_CALL(self, op): + fn = op.args[0] + return self.generic_call(fn.concretetype, self.expr(fn), + op.args[1:-1], op.result) + + def OP_ADR_CALL(self, op): + ARGTYPES = [v.concretetype for v in op.args[1:]] + RESTYPE = op.result.concretetype + FUNC = Ptr(FuncType(ARGTYPES, RESTYPE)) + typename = self.db.gettype(FUNC) + fnaddr = op.args[0] + fnexpr = '((%s)%s)' % (cdecl(typename, ''), self.expr(fnaddr)) + return self.generic_call(FUNC, fnexpr, op.args[1:], op.result) + # low-level operations def generic_get(self, op, sourceexpr): T = self.lltypemap(op.result) Modified: pypy/dist/pypy/translator/stackless/code.py ============================================================================== --- pypy/dist/pypy/translator/stackless/code.py (original) +++ pypy/dist/pypy/translator/stackless/code.py Sun Feb 11 02:00:53 2007 @@ -1,4 +1,5 @@ from pypy.rpython.lltypesystem import lltype, llmemory, lloperation +from pypy.tool.sourcetools import func_with_new_name from pypy.rlib import rarithmetic from pypy.rpython import extfunctable from pypy.translator.stackless import frame @@ -282,7 +283,6 @@ for _lltype, typename in STORAGE_TYPES_AND_FIELDS: if typename == 'void': continue - if typename == 'weak': continue exec template%dict(typename=typename, TYPENAME=typename.upper()) # ____________________________________________________________ @@ -296,30 +296,54 @@ self.retval_float = 0.0 self.retval_addr = llmemory.NULL self.retval_ref = frame.null_saved_ref + self.retval_weak = llmemory.WEAKNULL self.exception = None self.masterarray = lltype.malloc(frame.FRAME_INFO_ARRAY, 0, immortal=True) global_state = StacklessData() -def call_function(fn, retval_code): +# the following functions are patched by transform.py in finish() +# so that they don't really do what they appear to - we discovered +# that it was not safe at all to produce this kind of C code +def define_call_function_retval(TYPE, typename): + FUNCTYPE = lltype.Ptr(lltype.FuncType([], TYPE)) + def call_function_retval_xyz(fnaddr, signature_index): + fn = llmemory.cast_adr_to_ptr(fnaddr, FUNCTYPE) + return fn() + call_function_retval_xyz.stackless_explicit = True + call_function_retval_xyz.dont_inline = True + fnname = 'call_function_retval_' + typename + fn = func_with_new_name(call_function_retval_xyz, fnname) + globals()[fnname] = fn +for _lltype, _typename in STORAGE_TYPES_AND_FIELDS: + define_call_function_retval(_lltype, _typename) + + +def call_function(fn, signature_index): + retval_code = signature_index & frame.storage_type_bitmask if retval_code == frame.RETVAL_VOID: - lloperation.llop.unsafe_call(lltype.Void, fn) + call_function_retval_void(fn, signature_index) elif retval_code == frame.RETVAL_REF: - global_state.retval_ref = lloperation.llop.unsafe_call( - SAVED_REFERENCE, fn) + global_state.retval_ref = ( + call_function_retval_ref(fn, signature_index)) elif retval_code == frame.RETVAL_ADDR: - global_state.retval_addr = lloperation.llop.unsafe_call( - llmemory.Address, fn) + global_state.retval_addr = ( + call_function_retval_addr(fn, signature_index)) elif retval_code == frame.RETVAL_LONG: - global_state.retval_long = lloperation.llop.unsafe_call( - lltype.Signed, fn) + global_state.retval_long = ( + call_function_retval_long(fn, signature_index)) elif retval_code == frame.RETVAL_FLOAT: - global_state.retval_float = lloperation.llop.unsafe_call( - lltype.Float, fn) + global_state.retval_float = ( + call_function_retval_float(fn, signature_index)) elif retval_code == frame.RETVAL_LONGLONG: - global_state.retval_longlong = lloperation.llop.unsafe_call( - lltype.SignedLongLong, fn) + global_state.retval_longlong = ( + call_function_retval_longlong(fn, signature_index)) + elif retval_code == frame.RETVAL_WEAK: + global_state.retval_weak = ( + call_function_retval_weak(fn, signature_index)) + else: + assert False call_function.stackless_explicit = True class UnwindException(lloperation.StackException): @@ -343,9 +367,9 @@ while True: back = pending.f_back decoded = frame.decodestate(pending.f_restart) - (fn, global_state.restart_substate, retval_type) = decoded + (fn, global_state.restart_substate, signature_index) = decoded try: - call_function(fn, retval_type) + call_function(fn, signature_index) except UnwindException, u: #XXX annotation support needed if u.frame_bottom: u.frame_bottom.f_back = back @@ -425,3 +449,12 @@ global_state.retval_ref = frame.null_saved_ref return res fetch_retval_ref.stackless_explicit = True + +def fetch_retval_weak(): + e = global_state.exception + if e: + global_state.exception = None + raise e + else: + return global_state.retval_weak +fetch_retval_weak.stackless_explicit = True Modified: pypy/dist/pypy/translator/stackless/frame.py ============================================================================== --- pypy/dist/pypy/translator/stackless/frame.py (original) +++ pypy/dist/pypy/translator/stackless/frame.py Sun Feb 11 02:00:53 2007 @@ -30,6 +30,9 @@ if _TYPE not in STORAGE_TYPES: STORAGE_TYPES.append(_TYPE) +storage_type_bitmask = 0x07 # a power of two - 1 +assert storage_type_bitmask >= len(STORAGE_TYPES) + STORAGE_FIELDS = dict(STORAGE_TYPES_AND_FIELDS) del STORAGE_FIELDS[lltype.Void] @@ -98,7 +101,7 @@ finfo = masterarray[index - restartstate] return (finfo.fnaddr, # function ptr restartstate, # restart state within function - finfo.info) # retval_type + finfo.info) # signature_index decodestate.stackless_explicit = True @@ -116,7 +119,7 @@ self.resume_point_count = resume_point_count self.frame_types = () - def compress(self, rtyper): + def compress(self, signaturecodes, rtyper): """This returns sufficient information to be able to build the entries that will go in the global array of restart information.""" @@ -126,10 +129,18 @@ if not isinstance(graph, FunctionGraph): graph = bk.getdesc(graph).getuniquegraph() funcptr = getfunctionptr(graph) - rettype = lltype.typeOf(funcptr).TO.RESULT - retval_type = STORAGE_TYPES.index(storage_type(rettype)) - - result = [(llmemory.cast_ptr_to_adr(funcptr), retval_type)] + FUNC = lltype.typeOf(funcptr).TO + rettype_index = STORAGE_TYPES.index(storage_type(FUNC.RESULT)) + cache = signaturecodes[rettype_index] + key = tuple([storage_type(ARG) for ARG in FUNC.ARGS]) + try: + signature_index = cache[key] + except KeyError: + signature_index = len(cache) * (storage_type_bitmask+1) + signature_index |= rettype_index + cache[key] = signature_index + assert (signature_index & storage_type_bitmask) == rettype_index + result = [(llmemory.cast_ptr_to_adr(funcptr), signature_index)] for i in range(1, self.resume_point_count): result.append((llmemory.NULL, i)) else: Modified: pypy/dist/pypy/translator/stackless/transform.py ============================================================================== --- pypy/dist/pypy/translator/stackless/transform.py (original) +++ pypy/dist/pypy/translator/stackless/transform.py Sun Feb 11 02:00:53 2007 @@ -293,7 +293,14 @@ self.frametyper = FrameTyper(stackless_gc, self) self.masterarray1 = [] self.curr_graph = None - + + self.signaturecodes = [{} for RETTYPE in frame.STORAGE_TYPES] + # self.signaturecodes[n] is a dict {ARGTYPES: signature_index} + # where n is the return type as an index in STORAGE_TYPES. + # the signature_index is an arbitrary number but it encodes + # the type of the result, i.e. + # n == (signature_index & storage_type_bitmask) + bk = translator.annotator.bookkeeper self.unwind_exception_type = getinstancerepr( @@ -363,6 +370,8 @@ code.fetch_retval_addr, [], annmodel.SomeAddress()), SAVED_REFERENCE: mixlevelannotator.constfunc( code.fetch_retval_ref, [], annmodel.SomePtr(SAVED_REFERENCE)), + llmemory.WeakGcAddress: mixlevelannotator.constfunc( + code.fetch_retval_weak, [], annmodel.SomeWeakGcAddress()), } s_StatePtr = annmodel.SomePtr(frame.OPAQUE_STATE_HEADER_PTR) @@ -413,6 +422,10 @@ code.resume_after_ref, [s_StatePtr, annmodel.SomePtr(SAVED_REFERENCE)], annmodel.s_None), + llmemory.WeakGcAddress: mixlevelannotator.constfunc( + code.resume_after_weak, + [s_StatePtr, annmodel.SomeWeakGcAddress()], + annmodel.s_None), } exception_def = bk.getuniqueclassdef(Exception) self.resume_after_raising_ptr = mixlevelannotator.constfunc( @@ -1098,7 +1111,7 @@ def register_restart_info(self, restartinfo): assert not self.is_finished rtyper = self.translator.rtyper - for frame_info in restartinfo.compress(rtyper): + for frame_info in restartinfo.compress(self.signaturecodes, rtyper): self.masterarray1.append(frame_info) def finish(self): @@ -1108,6 +1121,44 @@ import cPickle cPickle.dump(self.stats, open('stackless-stats.pickle', 'wb')) + # fun fun fun patching the call_function_retval_xyz() functions! + for RESTYPE, typename in frame.STORAGE_TYPES_AND_FIELDS: + rettype_index = STORAGE_TYPES.index(RESTYPE) + cache = self.signaturecodes[rettype_index] + if not cache: + continue # not used anyway, don't produce a broken empty switch + func = getattr(code, 'call_function_retval_' + typename) + desc = self.translator.annotator.bookkeeper.getdesc(func) + graph = desc.getuniquegraph() + + [v_fnaddr, v_signature_index] = graph.getargs() + block = model.Block([v_fnaddr, v_signature_index]) + block.exitswitch = v_signature_index + block.isstartblock = True + graph.startblock = block + switchlinks = [] + + for ARGTYPES, signature_index in cache.items(): + # XXX because of type erasure, the following cast is + # kind of invalid, but we hope that nobody will notice + FUNCTYPE = lltype.Ptr(lltype.FuncType(ARGTYPES, RESTYPE)) + v_fnaddr1 = varoftype(v_fnaddr.concretetype) + callblock = model.Block([v_fnaddr1]) + llops = LowLevelOpList() + args_v = [model.Constant(TYPE._defl(), concretetype=TYPE) + for TYPE in ARGTYPES] + v_res = llops.genop('adr_call', [v_fnaddr1] + args_v, + resulttype = RESTYPE) + callblock.operations[:] = llops + callblock.closeblock(model.Link([v_res], graph.returnblock)) + link = model.Link([v_fnaddr], callblock) + link.exitcase = signature_index + link.llexitcase = signature_index + switchlinks.append(link) + + block.closeblock(*switchlinks) + model.checkgraph(graph) + self.is_finished = True masterarray = lltype.malloc(frame.FRAME_INFO_ARRAY, len(self.masterarray1), From arigo at codespeak.net Sun Feb 11 10:10:09 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 11 Feb 2007 10:10:09 +0100 (CET) Subject: [pypy-svn] r38443 - pypy/extradoc/planning/1.0 Message-ID: <20070211091009.498D510094@code0.codespeak.net> Author: arigo Date: Sun Feb 11 10:10:08 2007 New Revision: 38443 Modified: pypy/extradoc/planning/1.0/documentation.txt Log: updates. Modified: pypy/extradoc/planning/1.0/documentation.txt ============================================================================== --- pypy/extradoc/planning/1.0/documentation.txt (original) +++ pypy/extradoc/planning/1.0/documentation.txt Sun Feb 11 10:10:08 2007 @@ -15,11 +15,8 @@ js backend - is there something to update in translation.txt? BasicExternal approach, external functions? (fijal) -object-optimizations.txt. (arigo) - -jit.txt: copy introduction from pypy-dev e-mail, add examples of nice colors - (arigo) +jit.txt: add examples of nice colors - postponed faq.txt: write answers (arigo, fijal, cfbolz) @@ -53,7 +50,6 @@ point to the report?) - * eventhistory.txt * extcompiler.txt * extradoc.txt * garbage_collection.txt (out of date) From xoraxax at codespeak.net Sun Feb 11 11:40:23 2007 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sun, 11 Feb 2007 11:40:23 +0100 (CET) Subject: [pypy-svn] r38444 - pypy/dist/pypy/translator/microbench Message-ID: <20070211104023.3AA1010089@code0.codespeak.net> Author: xoraxax Date: Sun Feb 11 11:40:22 2007 New Revision: 38444 Modified: pypy/dist/pypy/translator/microbench/test_bltn.py Log: Two isinstance checks. Modified: pypy/dist/pypy/translator/microbench/test_bltn.py ============================================================================== --- pypy/dist/pypy/translator/microbench/test_bltn.py (original) +++ pypy/dist/pypy/translator/microbench/test_bltn.py Sun Feb 11 11:40:22 2007 @@ -20,3 +20,29 @@ while c < n: x = fabs(x) c += 1 + +class foo: + pass + +class bar(foo): + pass + +class baz(bar): + pass + +def test_isinstance1(): + f = foo() + b1 = bar() + b2 = baz() + for x in xrange(100000): + isinstance(b1, foo) + isinstance(b1, baz) + isinstance(f, bar) + isinstance(b2, foo) + +def test_isinstance2(): + for x in xrange(100000): + isinstance(1, float) + isinstance(1, int) + isinstance("foo", basestring) + From xoraxax at codespeak.net Sun Feb 11 11:44:19 2007 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sun, 11 Feb 2007 11:44:19 +0100 (CET) Subject: [pypy-svn] r38445 - pypy/dist/pypy/module/__builtin__ Message-ID: <20070211104419.52AD010089@code0.codespeak.net> Author: xoraxax Date: Sun Feb 11 11:44:18 2007 New Revision: 38445 Modified: pypy/dist/pypy/module/__builtin__/__init__.py pypy/dist/pypy/module/__builtin__/app_inspect.py pypy/dist/pypy/module/__builtin__/operation.py Log: Rewrote isinstance and issubclass in RPython, gives 25% speed boost. Things to check: why is it still 10 times slower than CPython? How do the space method isinstance etc. relate to this code? Modified: pypy/dist/pypy/module/__builtin__/__init__.py ============================================================================== --- pypy/dist/pypy/module/__builtin__/__init__.py (original) +++ pypy/dist/pypy/module/__builtin__/__init__.py Sun Feb 11 11:44:18 2007 @@ -55,8 +55,6 @@ '_install_pickle_support_for_reversed_iterator': 'app_functional._install_pickle_support_for_reversed_iterator', - 'issubclass' : 'app_inspect.issubclass', - 'isinstance' : 'app_inspect.isinstance', 'hasattr' : 'app_inspect.hasattr', 'globals' : 'app_inspect.globals', 'locals' : 'app_inspect.locals', @@ -114,6 +112,8 @@ 'coerce' : 'operation.coerce', 'divmod' : 'operation.divmod', '_issubtype' : 'operation._issubtype', + 'issubclass' : 'operation.issubclass', + 'isinstance' : 'operation.isinstance', 'getattr' : 'operation.getattr', 'setattr' : 'operation.setattr', 'delattr' : 'operation.delattr', Modified: pypy/dist/pypy/module/__builtin__/app_inspect.py ============================================================================== --- pypy/dist/pypy/module/__builtin__/app_inspect.py (original) +++ pypy/dist/pypy/module/__builtin__/app_inspect.py Sun Feb 11 11:44:18 2007 @@ -17,55 +17,6 @@ def _caller_locals(): return sys._getframe(0).f_locals -def _recursive_issubclass(cls, klass_or_tuple): - if cls is klass_or_tuple: - return True - for base in getattr(cls, '__bases__', ()): - if _recursive_issubclass(base, klass_or_tuple): - return True - return False - -def _issubclass(cls, klass_or_tuple, check_cls, depth): - if depth == 0: - # XXX overzealous test compliance hack - raise RuntimeError,"maximum recursion depth excedeed" - if _issubtype(type(klass_or_tuple), tuple): - for klass in klass_or_tuple: - if _issubclass(cls, klass, True, depth-1): - return True - return False - try: - return _issubtype(cls, klass_or_tuple) - except TypeError: - if check_cls and not hasattr(cls, '__bases__'): - raise TypeError, "arg 1 must be a class or type" - if not hasattr(klass_or_tuple, '__bases__'): - raise TypeError, "arg 2 must be a class or type or a tuple thereof" - return _recursive_issubclass(cls, klass_or_tuple) - -def issubclass(cls, klass_or_tuple): - """Check whether a class 'cls' is a subclass (i.e., a derived class) of -another class. When using a tuple as the second argument, check whether -'cls' is a subclass of any of the classes listed in the tuple.""" - import sys - return _issubclass(cls, klass_or_tuple, True, sys.getrecursionlimit()) - -def isinstance(obj, klass_or_tuple): - """Check whether an object is an instance of a class (or of a subclass -thereof). When using a tuple as the second argument, check whether 'obj' -is an instance of any of the classes listed in the tuple.""" - if issubclass(type(obj), klass_or_tuple): - return True - try: - objcls = obj.__class__ - except AttributeError: - return False - else: - import sys - return (objcls is not type(obj) and - _issubclass(objcls, klass_or_tuple, False, sys.getrecursionlimit())) - - def vars(*obj): """Return a dictionary of all the attributes currently bound in obj. If called with no argument, return the variables bound in local scope.""" Modified: pypy/dist/pypy/module/__builtin__/operation.py ============================================================================== --- pypy/dist/pypy/module/__builtin__/operation.py (original) +++ pypy/dist/pypy/module/__builtin__/operation.py Sun Feb 11 11:44:18 2007 @@ -199,3 +199,92 @@ """Check whether the object appears to be callable (i.e., some kind of function). Note that classes are callable.""" return space.callable(w_object) + + + +def _recursive_issubclass(space, w_cls, w_klass_or_tuple): # returns interp-level bool + if space.is_w(w_cls, w_klass_or_tuple): + return True + try: + w_bases = space.getattr(w_cls, space.wrap("__bases__")) + except OperationError: + return False + w_iterator = space.iter(w_bases) + while True: + try: + w_base = space.next(w_iterator) + except OperationError, e: + if not e.match(space, space.w_StopIteration): + raise + break + if _recursive_issubclass(space, w_base, w_klass_or_tuple): + return True + return False + +def _issubclass(space, w_cls, w_klass_or_tuple, check_cls, depth): # returns interp-level bool + if depth == 0: + # XXX overzealous test compliance hack + raise OperationError(space.w_RuntimeError, space.wrap("maximum recursion depth exceeded")) + if space.is_true(space.issubtype(space.type(w_klass_or_tuple), space.w_tuple)): + w_iter = space.iter(w_klass_or_tuple) + while True: + try: + w_klass = space.next(w_iter) + except OperationError, e: + if not e.match(space, space.w_StopIteration): + raise + break + if _issubclass(space, w_cls, w_klass, True, depth - 1): + return True + return False + + try: + return space.is_true(space.issubtype(w_cls, w_klass_or_tuple)) + except OperationError, e: + e.normalize_exception(space) + if space.is_true(space.issubtype(e.w_type, space.w_TypeError)): + w_bases = space.wrap('__bases__') + if check_cls: + try: + space.getattr(w_cls, w_bases) + except OperationError: + raise OperationError(space.w_TypeError, space.wrap('arg 1 must be a class or type')) + try: + space.getattr(w_klass_or_tuple, w_bases) + except OperationError: + raise OperationError(space.w_TypeError, space.wrap('arg 2 must be a class or type or a tuple thereof')) + return _recursive_issubclass(space, w_cls, w_klass_or_tuple) + else: + raise + + +def issubclass(space, w_cls, w_klass_or_tuple): + """Check whether a class 'cls' is a subclass (i.e., a derived class) of +another class. When using a tuple as the second argument, check whether +'cls' is a subclass of any of the classes listed in the tuple.""" + w_getlimit = space.getattr(space.getbuiltinmodule('sys'), space.wrap('getrecursionlimit')) + w_limit = space.call_function(w_getlimit, ) + return space.wrap(_issubclass(space, w_cls, w_klass_or_tuple, True, space.int_w(w_limit))) + + +def isinstance(space, w_obj, w_klass_or_tuple): + """Check whether an object is an instance of a class (or of a subclass +thereof). When using a tuple as the second argument, check whether 'obj' +is an instance of any of the classes listed in the tuple.""" + if space.is_true(issubclass(space, space.type(w_obj), w_klass_or_tuple)): + return space.w_True + try: + w_objcls = space.getattr(w_obj, space.wrap("__class__")) + except OperationError, e: + e.normalize_exception(space) + if space.is_true(space.issubtype(e.w_type, space.w_AttributeError)): + return space.w_False + else: + raise + if space.is_w(w_objcls, space.type(w_obj)): + return space.w_False + else: + w_getlimit = space.getattr(space.getbuiltinmodule('sys'), space.wrap('getrecursionlimit')) + limit = space.int_w(space.call_function(w_getlimit, )) + return space.wrap(_issubclass(space, w_objcls, w_klass_or_tuple, False, limit)) + From arigo at codespeak.net Sun Feb 11 11:52:44 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 11 Feb 2007 11:52:44 +0100 (CET) Subject: [pypy-svn] r38446 - in pypy/dist/pypy: module/unicodedata objspace/std Message-ID: <20070211105244.81C6110089@code0.codespeak.net> Author: arigo Date: Sun Feb 11 11:52:41 2007 New Revision: 38446 Modified: pypy/dist/pypy/module/unicodedata/generate_unicodedb.py pypy/dist/pypy/module/unicodedata/unicodedb_3_2_0.py pypy/dist/pypy/module/unicodedata/unicodedb_4_1_0.py pypy/dist/pypy/module/unicodedata/unicodedb_5_0_0.py pypy/dist/pypy/objspace/std/unicodeobject.py Log: Typo in the function name isalnum(). Let's use it from unicodeobject.py. Modified: pypy/dist/pypy/module/unicodedata/generate_unicodedb.py ============================================================================== --- pypy/dist/pypy/module/unicodedata/generate_unicodedb.py (original) +++ pypy/dist/pypy/module/unicodedata/generate_unicodedb.py Sun Feb 11 11:52:41 2007 @@ -301,7 +301,7 @@ print >> outfile, 'def isnumeric(code): return _get_record(code)[3] & %d != 0'% IS_NUMERIC print >> outfile, 'def isdigit(code): return _get_record(code)[3] & %d != 0'% IS_DIGIT print >> outfile, 'def isdecimal(code): return _get_record(code)[3] & %d != 0'% IS_DECIMAL - print >> outfile, 'def isalunm(code): return _get_record(code)[3] & %d != 0'% (IS_ALPHA | IS_NUMERIC) + print >> outfile, 'def isalnum(code): return _get_record(code)[3] & %d != 0'% (IS_ALPHA | IS_NUMERIC) print >> outfile, 'def isupper(code): return _get_record(code)[3] & %d != 0'% IS_UPPER print >> outfile, 'def istitle(code): return _get_record(code)[3] & %d != 0'% IS_TITLE print >> outfile, 'def islower(code): return _get_record(code)[3] & %d != 0'% IS_LOWER Modified: pypy/dist/pypy/module/unicodedata/unicodedb_3_2_0.py ============================================================================== --- pypy/dist/pypy/module/unicodedata/unicodedb_3_2_0.py (original) +++ pypy/dist/pypy/module/unicodedata/unicodedb_3_2_0.py Sun Feb 11 11:52:41 2007 @@ -14539,7 +14539,7 @@ def isnumeric(code): return _get_record(code)[3] & 64 != 0 def isdigit(code): return _get_record(code)[3] & 128 != 0 def isdecimal(code): return _get_record(code)[3] & 256 != 0 -def isalunm(code): return _get_record(code)[3] & 66 != 0 +def isalnum(code): return _get_record(code)[3] & 66 != 0 def isupper(code): return _get_record(code)[3] & 8 != 0 def istitle(code): return _get_record(code)[3] & 16 != 0 def islower(code): return _get_record(code)[3] & 32 != 0 Modified: pypy/dist/pypy/module/unicodedata/unicodedb_4_1_0.py ============================================================================== --- pypy/dist/pypy/module/unicodedata/unicodedb_4_1_0.py (original) +++ pypy/dist/pypy/module/unicodedata/unicodedb_4_1_0.py Sun Feb 11 11:52:41 2007 @@ -17139,7 +17139,7 @@ def isnumeric(code): return _get_record(code)[3] & 64 != 0 def isdigit(code): return _get_record(code)[3] & 128 != 0 def isdecimal(code): return _get_record(code)[3] & 256 != 0 -def isalunm(code): return _get_record(code)[3] & 66 != 0 +def isalnum(code): return _get_record(code)[3] & 66 != 0 def isupper(code): return _get_record(code)[3] & 8 != 0 def istitle(code): return _get_record(code)[3] & 16 != 0 def islower(code): return _get_record(code)[3] & 32 != 0 Modified: pypy/dist/pypy/module/unicodedata/unicodedb_5_0_0.py ============================================================================== --- pypy/dist/pypy/module/unicodedata/unicodedb_5_0_0.py (original) +++ pypy/dist/pypy/module/unicodedata/unicodedb_5_0_0.py Sun Feb 11 11:52:41 2007 @@ -18528,7 +18528,7 @@ def isnumeric(code): return _get_record(code)[3] & 64 != 0 def isdigit(code): return _get_record(code)[3] & 128 != 0 def isdecimal(code): return _get_record(code)[3] & 256 != 0 -def isalunm(code): return _get_record(code)[3] & 66 != 0 +def isalnum(code): return _get_record(code)[3] & 66 != 0 def isupper(code): return _get_record(code)[3] & 8 != 0 def istitle(code): return _get_record(code)[3] & 16 != 0 def islower(code): return _get_record(code)[3] & 32 != 0 Modified: pypy/dist/pypy/objspace/std/unicodeobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/unicodeobject.py (original) +++ pypy/dist/pypy/objspace/std/unicodeobject.py Sun Feb 11 11:52:41 2007 @@ -285,8 +285,7 @@ if len(w_unicode._value) == 0: return space.w_False for uchar in w_unicode._value: - if not (unicodedb.isalpha(ord(uchar)) or - unicodedb.isnumeric(ord(uchar))): + if not unicodedb.isalnum(ord(uchar)): return space.w_False return space.w_True From pedronis at codespeak.net Sun Feb 11 12:48:24 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sun, 11 Feb 2007 12:48:24 +0100 (CET) Subject: [pypy-svn] r38450 - pypy/dist/pypy/tool Message-ID: <20070211114824.4310510087@code0.codespeak.net> Author: pedronis Date: Sun Feb 11 12:48:23 2007 New Revision: 38450 Modified: pypy/dist/pypy/tool/watchdog.py Log: if the watched process died with a signal, print the signal name and consider this a variation on "timeout" Modified: pypy/dist/pypy/tool/watchdog.py ============================================================================== --- pypy/dist/pypy/tool/watchdog.py (original) +++ pypy/dist/pypy/tool/watchdog.py Sun Feb 11 12:48:23 2007 @@ -1,9 +1,18 @@ import sys, os, signal import threading +def getsignalname(n): + for name, value in signal.__dict__.items(): + if value == n and name.startswith('SIG'): + return name + return 'signal %d' % (n,) + timeout = float(sys.argv[1]) +timedout = False def childkill(): + global timedout + timedout = True sys.stderr.write("="*26 + "timedout" + "="*26 + "\n") try: os.kill(pid, signal.SIGTERM) @@ -27,6 +36,13 @@ if os.WIFEXITED(status): sys.exit(os.WEXITSTATUS(status)) else: + assert os.WIFSIGNALED(status) + sign = os.WTERMSIG(status) + if timedout and sign == signal.SIGTERM: + sys.exit(1) + signame = getsignalname(sign) + sys.stderr.write("="*26 + "timedout" + "="*26 + "\n") + sys.stderr.write("="*25 + " %-08s " % signame + "="*25 + "\n") sys.exit(1) From xoraxax at codespeak.net Sun Feb 11 13:31:32 2007 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sun, 11 Feb 2007 13:31:32 +0100 (CET) Subject: [pypy-svn] r38453 - pypy/dist/pypy/doc Message-ID: <20070211123132.55B121008D@code0.codespeak.net> Author: xoraxax Date: Sun Feb 11 13:31:31 2007 New Revision: 38453 Modified: pypy/dist/pypy/doc/faq.txt Log: Clarified speed part of the faq. Modified: pypy/dist/pypy/doc/faq.txt ============================================================================== --- pypy/dist/pypy/doc/faq.txt (original) +++ pypy/dist/pypy/doc/faq.txt Sun Feb 11 13:31:31 2007 @@ -100,8 +100,9 @@ As of August 2005, PyPy was successfully translated to C. Compared to CPython, the version of PyPy that still runs on top of CPython is slower by a factor of 2000. The first translated version was roughly 300 times slower -than CPython, version 0.8.0 about 10-20 times, version 0.9 about 4-7 times -and the current version (1.0) is about 2.4 - 5 times as slow as CPython. +than CPython. In later versions, we increased the speed. CPython was about +10-20 times as fast as version 0.8.0, 4-7 times as fast as version 0.9 and +2.4 - 5 times as fast as the current version (1.0). Note that the speed heavily depends on the enabled options at compile time. From xoraxax at codespeak.net Sun Feb 11 14:17:45 2007 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sun, 11 Feb 2007 14:17:45 +0100 (CET) Subject: [pypy-svn] r38454 - pypy/dist/pypy/module/__builtin__ Message-ID: <20070211131745.325A710093@code0.codespeak.net> Author: xoraxax Date: Sun Feb 11 14:17:44 2007 New Revision: 38454 Modified: pypy/dist/pypy/module/__builtin__/operation.py Log: Speedup the access to the recursion limit in isinstance. Modified: pypy/dist/pypy/module/__builtin__/operation.py ============================================================================== --- pypy/dist/pypy/module/__builtin__/operation.py (original) +++ pypy/dist/pypy/module/__builtin__/operation.py Sun Feb 11 14:17:44 2007 @@ -262,9 +262,7 @@ """Check whether a class 'cls' is a subclass (i.e., a derived class) of another class. When using a tuple as the second argument, check whether 'cls' is a subclass of any of the classes listed in the tuple.""" - w_getlimit = space.getattr(space.getbuiltinmodule('sys'), space.wrap('getrecursionlimit')) - w_limit = space.call_function(w_getlimit, ) - return space.wrap(_issubclass(space, w_cls, w_klass_or_tuple, True, space.int_w(w_limit))) + return space.wrap(_issubclass(space, w_cls, w_klass_or_tuple, True, space.sys.recursionlimit)) def isinstance(space, w_obj, w_klass_or_tuple): @@ -284,7 +282,5 @@ if space.is_w(w_objcls, space.type(w_obj)): return space.w_False else: - w_getlimit = space.getattr(space.getbuiltinmodule('sys'), space.wrap('getrecursionlimit')) - limit = space.int_w(space.call_function(w_getlimit, )) - return space.wrap(_issubclass(space, w_objcls, w_klass_or_tuple, False, limit)) + return space.wrap(_issubclass(space, w_objcls, w_klass_or_tuple, False, space.sys.recursionlimit)) From arigo at codespeak.net Sun Feb 11 15:04:18 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 11 Feb 2007 15:04:18 +0100 (CET) Subject: [pypy-svn] r38461 - pypy/dist/lib-python/modified-2.4.1/test Message-ID: <20070211140418.B8ACB10097@code0.codespeak.net> Author: arigo Date: Sun Feb 11 15:04:17 2007 New Revision: 38461 Modified: pypy/dist/lib-python/modified-2.4.1/test/test_sort.py Log: PyPy doesn't detect all cases of lists mutated while they are sorted. Modified: pypy/dist/lib-python/modified-2.4.1/test/test_sort.py ============================================================================== --- pypy/dist/lib-python/modified-2.4.1/test/test_sort.py (original) +++ pypy/dist/lib-python/modified-2.4.1/test/test_sort.py Sun Feb 11 15:04:17 2007 @@ -130,6 +130,9 @@ # bug 453523 -- list.sort() crasher. # If this fails, the most likely outcome is a core dump. # Mutations during a list sort should raise a ValueError. + # XXX PyPy does not detect all cases (more precisely, + # if the list is mutated but ends up being empty again). + # Let's test at least that there is no crash. class C: def __lt__(self, other): @@ -140,7 +143,11 @@ return random.random() < 0.5 L = [C() for i in range(50)] - self.assertRaises(ValueError, L.sort) + #self.assertRaises(ValueError, L.sort) + try: + L.sort() + except ValueError: + pass def test_cmpNone(self): # Testing None as a comparison function. From arigo at codespeak.net Sun Feb 11 15:21:43 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 11 Feb 2007 15:21:43 +0100 (CET) Subject: [pypy-svn] r38463 - pypy/dist/pypy/module/__builtin__ Message-ID: <20070211142143.F31731009C@code0.codespeak.net> Author: arigo Date: Sun Feb 11 15:21:42 2007 New Revision: 38463 Modified: pypy/dist/pypy/module/__builtin__/operation.py Log: * use e.match() to check exception classes. * fix all places that eats arbitrary OperationErrors. Makes lib-python/2.4.1/test/test_isinstance pass. Modified: pypy/dist/pypy/module/__builtin__/operation.py ============================================================================== --- pypy/dist/pypy/module/__builtin__/operation.py (original) +++ pypy/dist/pypy/module/__builtin__/operation.py Sun Feb 11 15:21:42 2007 @@ -207,8 +207,11 @@ return True try: w_bases = space.getattr(w_cls, space.wrap("__bases__")) - except OperationError: - return False + except OperationError, e: + if e.match(space, space.w_AttributeError): + return False + else: + raise w_iterator = space.iter(w_bases) while True: try: @@ -241,17 +244,20 @@ try: return space.is_true(space.issubtype(w_cls, w_klass_or_tuple)) except OperationError, e: - e.normalize_exception(space) - if space.is_true(space.issubtype(e.w_type, space.w_TypeError)): + if e.match(space, space.w_TypeError): w_bases = space.wrap('__bases__') if check_cls: try: space.getattr(w_cls, w_bases) - except OperationError: + except OperationError, e: + if not e.match(space, space.w_AttributeError): + raise raise OperationError(space.w_TypeError, space.wrap('arg 1 must be a class or type')) try: space.getattr(w_klass_or_tuple, w_bases) - except OperationError: + except OperationError, e: + if not e.match(space, space.w_AttributeError): + raise raise OperationError(space.w_TypeError, space.wrap('arg 2 must be a class or type or a tuple thereof')) return _recursive_issubclass(space, w_cls, w_klass_or_tuple) else: @@ -262,25 +268,27 @@ """Check whether a class 'cls' is a subclass (i.e., a derived class) of another class. When using a tuple as the second argument, check whether 'cls' is a subclass of any of the classes listed in the tuple.""" - return space.wrap(_issubclass(space, w_cls, w_klass_or_tuple, True, space.sys.recursionlimit)) + return space.wrap(issubclass_w(space, w_cls, w_klass_or_tuple)) + +def issubclass_w(space, w_cls, w_klass_or_tuple): + return _issubclass(space, w_cls, w_klass_or_tuple, True, space.sys.recursionlimit) def isinstance(space, w_obj, w_klass_or_tuple): """Check whether an object is an instance of a class (or of a subclass thereof). When using a tuple as the second argument, check whether 'obj' is an instance of any of the classes listed in the tuple.""" - if space.is_true(issubclass(space, space.type(w_obj), w_klass_or_tuple)): + w_objtype = space.type(w_obj) + if issubclass_w(space, w_objtype, w_klass_or_tuple): return space.w_True try: w_objcls = space.getattr(w_obj, space.wrap("__class__")) except OperationError, e: - e.normalize_exception(space) - if space.is_true(space.issubtype(e.w_type, space.w_AttributeError)): + if e.match(space, space.w_AttributeError): return space.w_False else: raise - if space.is_w(w_objcls, space.type(w_obj)): + if space.is_w(w_objcls, w_objtype): return space.w_False else: return space.wrap(_issubclass(space, w_objcls, w_klass_or_tuple, False, space.sys.recursionlimit)) - From arigo at codespeak.net Sun Feb 11 15:25:33 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 11 Feb 2007 15:25:33 +0100 (CET) Subject: [pypy-svn] r38464 - pypy/dist/pypy/module/_sre/test Message-ID: <20070211142533.696861009C@code0.codespeak.net> Author: arigo Date: Sun Feb 11 15:25:32 2007 New Revision: 38464 Modified: pypy/dist/pypy/module/_sre/test/test_app_sre.py Log: Change the obscure path hacks to make "py.test -A" happy. Modified: pypy/dist/pypy/module/_sre/test/test_app_sre.py ============================================================================== --- pypy/dist/pypy/module/_sre/test/test_app_sre.py (original) +++ pypy/dist/pypy/module/_sre/test/test_app_sre.py Sun Feb 11 15:25:32 2007 @@ -1,15 +1,14 @@ """Regular expression tests specific to _sre.py and accumulated during TDD.""" +import autopath from py.test import raises, skip from pypy.interpreter.gateway import app2interp_temp def init_globals_hack(space): - space.appexec([], """(): + space.appexec([autopath.this_dir], """(this_dir): import __builtin__ as b import sys, os.path # Uh-oh, ugly hack - test_path = os.path.join( - os.path.dirname(sys.modules["sys"].__file__), "../_sre/test") - sys.path.insert(0, test_path) + sys.path.insert(0, this_dir) import support_test_app_sre b.s = support_test_app_sre sys.path.pop(0) @@ -189,6 +188,12 @@ return ret assert ("bbbbb", 3) == re.subn("a", call_me, "ababa") + def test_match_array(self): + import re, array + a = array.array('c', 'hello') + m = re.match('hel+', a) + assert m.end() == 4 + class AppTestSreScanner: From arigo at codespeak.net Sun Feb 11 15:48:05 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 11 Feb 2007 15:48:05 +0100 (CET) Subject: [pypy-svn] r38465 - in pypy/dist/pypy: interpreter objspace objspace/std Message-ID: <20070211144805.8317610089@code0.codespeak.net> Author: arigo Date: Sun Feb 11 15:48:02 2007 New Revision: 38465 Modified: pypy/dist/pypy/interpreter/baseobjspace.py pypy/dist/pypy/objspace/dump.py pypy/dist/pypy/objspace/logic.py pypy/dist/pypy/objspace/std/objspace.py pypy/dist/pypy/objspace/std/unicodeobject.py pypy/dist/pypy/objspace/thunk.py Log: Add a space.unichars_w() as a hack to get at the list of characters of a unicode string. Modified: pypy/dist/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/dist/pypy/interpreter/baseobjspace.py (original) +++ pypy/dist/pypy/interpreter/baseobjspace.py Sun Feb 11 15:48:02 2007 @@ -922,6 +922,7 @@ 'float_w', 'uint_w', 'bigint_w', + 'unichars_w', 'interpclass_w', 'unwrap', 'is_true', Modified: pypy/dist/pypy/objspace/dump.py ============================================================================== --- pypy/dist/pypy/objspace/dump.py (original) +++ pypy/dist/pypy/objspace/dump.py Sun Feb 11 15:48:02 2007 @@ -145,6 +145,7 @@ 'int_w': 1, 'float_w': 1, 'uint_w': 1, + 'unichars_w': 1, 'bigint_w': 1, 'interpclass_w': 1, 'unwrap': 1, Modified: pypy/dist/pypy/objspace/logic.py ============================================================================== --- pypy/dist/pypy/objspace/logic.py (original) +++ pypy/dist/pypy/objspace/logic.py Sun Feb 11 15:48:02 2007 @@ -69,6 +69,7 @@ 'int_w': 1, 'float_w': 1, 'uint_w': 1, + 'unichars_w': 1, 'bigint_w': 1, 'interpclass_w': 1, 'unwrap': 1, Modified: pypy/dist/pypy/objspace/std/objspace.py ============================================================================== --- pypy/dist/pypy/objspace/std/objspace.py (original) +++ pypy/dist/pypy/objspace/std/objspace.py Sun Feb 11 15:48:02 2007 @@ -573,6 +573,7 @@ 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) + unichars_w = StdObjSpaceMultiMethod('unichars_w', 1, []) # returns an unwrapped list of unicode characters bigint_w = StdObjSpaceMultiMethod('bigint_w', 1, []) # returns an unwrapped rbigint marshal_w = StdObjSpaceMultiMethod('marshal_w', 1, [], extra_args=['marshaller']) log = StdObjSpaceMultiMethod('log', 1, [], extra_args=['base']) Modified: pypy/dist/pypy/objspace/std/unicodeobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/unicodeobject.py (original) +++ pypy/dist/pypy/objspace/std/unicodeobject.py Sun Feb 11 15:48:02 2007 @@ -59,6 +59,9 @@ def str_w__Unicode(space, w_uni): return space.str_w(space.str(w_uni)) +def unichars_w__Unicode(space, w_uni): + return w_uni._value + def str__Unicode(space, w_uni): return space.call_method(w_uni, 'encode') Modified: pypy/dist/pypy/objspace/thunk.py ============================================================================== --- pypy/dist/pypy/objspace/thunk.py (original) +++ pypy/dist/pypy/objspace/thunk.py Sun Feb 11 15:48:02 2007 @@ -117,6 +117,7 @@ 'int_w': 1, 'float_w': 1, 'uint_w': 1, + 'unichars_w': 1, 'bigint_w': 1, 'interpclass_w': 1, 'unwrap': 1, From arigo at codespeak.net Sun Feb 11 15:50:51 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 11 Feb 2007 15:50:51 +0100 (CET) Subject: [pypy-svn] r38466 - in pypy/dist/pypy: module/_sre module/_sre/test rlib/rsre rlib/rsre/test Message-ID: <20070211145051.764F410089@code0.codespeak.net> Author: arigo Date: Sun Feb 11 15:50:48 2007 New Revision: 38466 Added: pypy/dist/pypy/rlib/rsre/ (props changed) pypy/dist/pypy/rlib/rsre/__init__.py (contents, props changed) pypy/dist/pypy/rlib/rsre/autopath.py - copied unchanged from r38442, pypy/dist/pypy/rlib/autopath.py pypy/dist/pypy/rlib/rsre/rsre.py - copied, changed from r38442, pypy/dist/pypy/module/_sre/interp_sre.py pypy/dist/pypy/rlib/rsre/rsre_char.py - copied, changed from r38442, pypy/dist/pypy/module/_sre/interp_sre.py pypy/dist/pypy/rlib/rsre/rsre_core.py - copied, changed from r38442, pypy/dist/pypy/module/_sre/interp_sre.py pypy/dist/pypy/rlib/rsre/test/ (props changed) pypy/dist/pypy/rlib/rsre/test/__init__.py (contents, props changed) pypy/dist/pypy/rlib/rsre/test/autopath.py - copied unchanged from r38442, pypy/dist/pypy/rlib/autopath.py pypy/dist/pypy/rlib/rsre/test/test_rsre.py - copied, changed from r38442, pypy/dist/pypy/module/_sre/test/test_interp_sre.py Removed: pypy/dist/pypy/module/_sre/test/test_interp_sre.py Modified: pypy/dist/pypy/module/_sre/app_sre.py pypy/dist/pypy/module/_sre/interp_sre.py Log: Move the regexp core to pypy/rlib/rsre. Split it and hack a bit so that it can be parametrized by how input characters are fetched. The module/_sre has three variants: one for matching or searching strings, one for unicode strings, and a general one that handles a wrapped object. There is support for a space-vs-time kind of optimization: if you set a flag to True you get three copies of the whole regexp core (string, unicode, wrapped). The time gains are probably minor (didn't try yet) so it's False by default. Modified: pypy/dist/pypy/module/_sre/app_sre.py ============================================================================== --- pypy/dist/pypy/module/_sre/app_sre.py (original) +++ pypy/dist/pypy/module/_sre/app_sre.py Sun Feb 11 15:50:48 2007 @@ -54,7 +54,6 @@ state = _sre._State(string, pos, endpos, self.flags) while state.start <= state.end: state.reset() - state.string_position = state.start if not _sre._search(state, self._code): break match = SRE_Match(self, state) @@ -84,7 +83,6 @@ n = last_pos = 0 while not count or n < count: state.reset() - state.string_position = state.start if not _sre._search(state, self._code): break if last_pos < state.start: @@ -122,7 +120,6 @@ last = state.start while not maxsplit or n < maxsplit: state.reset() - state.string_position = state.start if not _sre._search(state, self._code): break if state.start == state.string_position: # zero-width match @@ -165,7 +162,6 @@ def _match_search(self, matcher): state = self._state state.reset() - state.string_position = state.start match = None if matcher(state, self.pattern._code): match = SRE_Match(self.pattern, state) Modified: pypy/dist/pypy/module/_sre/interp_sre.py ============================================================================== --- pypy/dist/pypy/module/_sre/interp_sre.py (original) +++ pypy/dist/pypy/module/_sre/interp_sre.py Sun Feb 11 15:50:48 2007 @@ -4,129 +4,104 @@ from pypy.interpreter.gateway import interp2app, ObjSpace, W_Root from pypy.interpreter.error import OperationError from pypy.rlib.rarithmetic import intmask -import sys -#### Constants and exposed functions - -# Identifying as _sre from Python 2.3 or 2.4 -MAGIC = 20031017 +# This can be compiled in two ways: +# +# * THREE_VERSIONS_OF_CORE=True: you get three copies of the whole +# regexp searching and matching code: for strings, for unicode strings, +# and for generic wrapped objects (like mmap.mmap or array.array). +# +# * THREE_VERSIONS_OF_CORE=False: there is only one copy of the code, +# at the cost of an indirect method call to fetch each character. -# In _sre.c this is bytesize of the code word type of the C implementation. -# There it's 2 for normal Python builds and more for wide unicode builds (large -# enough to hold a 32-bit UCS-4 encoded character). Since here in pure Python -# we only see re bytecodes as Python longs, we shouldn't have to care about the -# codesize. But sre_compile will compile some stuff differently depending on the -# codesize (e.g., charsets). -if sys.maxunicode == 65535: - CODESIZE = 2 -else: - CODESIZE = 4 +THREE_VERSIONS_OF_CORE = False -copyright = "_sre.py 2.4 Copyright 2005 by Nik Haldimann" -BIG_ENDIAN = sys.byteorder == "big" +#### Constants and exposed functions -# XXX can we import those safely from sre_constants? -SRE_INFO_PREFIX = 1 -SRE_INFO_LITERAL = 2 -SRE_FLAG_LOCALE = 4 # honour system locale -SRE_FLAG_UNICODE = 32 # use unicode locale -OPCODE_INFO = 17 -OPCODE_LITERAL = 19 -MAXREPEAT = 65535 +from pypy.rlib.rsre import rsre +from pypy.rlib.rsre.rsre_char import MAGIC, CODESIZE, getlower +copyright = "_sre.py 2.4 Copyright 2005 by Nik Haldimann" def w_getlower(space, char_ord, flags): - return space.wrap(getlower(space, char_ord, flags)) + return space.wrap(getlower(char_ord, flags)) w_getlower.unwrap_spec = [ObjSpace, int, int] -def getlower(space, char_ord, flags): - if (char_ord < 128) or (flags & SRE_FLAG_UNICODE) \ - or (flags & SRE_FLAG_LOCALE and char_ord < 256): - w_uni_char = space.newunicode([char_ord]) - w_lowered = space.call_method(w_uni_char, "lower") - return space.int_w(space.ord(w_lowered)) - else: - return char_ord - def w_getcodesize(space): return space.wrap(CODESIZE) -#### Core classes +# use the same version of unicodedb as the standard objspace +from pypy.objspace.std.unicodeobject import unicodedb +rsre.set_unicode_db(unicodedb) + +#### State classes def make_state(space, w_string, start, end, flags): # XXX maybe turn this into a __new__ method of W_State - return space.wrap(W_State(space, w_string, start, end, flags)) + if space.is_true(space.isinstance(w_string, space.w_str)): + cls = W_StringState + elif space.is_true(space.isinstance(w_string, space.w_unicode)): + cls = W_UnicodeState + else: + cls = W_GenericState + return space.wrap(cls(space, w_string, start, end, flags)) make_state.unwrap_spec = [ObjSpace, W_Root, int, int, int] + class W_State(Wrappable): + if not THREE_VERSIONS_OF_CORE: + rsre.insert_sre_methods(locals(), 'all') def __init__(self, space, w_string, start, end, flags): self.space = space self.w_string = w_string + length = self.unwrap_object() if start < 0: start = 0 - if end > space.int_w(space.len(w_string)): - end = space.int_w(space.len(w_string)) + if end > length: + end = length self.start = start - self.string_position = start - self.end = end - self.pos = start + self.pos = start # records the original start position + self.end = end self.flags = flags - self.w_reset() + self.reset() - def w_reset(self): - self.marks = [] - self.lastindex = -1 - self.marks_stack = [] - self.context_stack = [] - self.repeat = None + def lower(self, char_ord): + return getlower(char_ord, self.flags) - def w_create_regs(self, w_group_count): - """Creates a tuple of index pairs representing matched groups, a format - that's convenient for SRE_Match.""" - regs = [self.space.newtuple([self.space.wrap(self.start), self.space.wrap(self.string_position)])] - for group in range(self.space.int_w(w_group_count)): - mark_index = 2 * group - if mark_index + 1 < len(self.marks): - regs.append(self.space.newtuple([self.space.wrap(self.marks[mark_index]), - self.space.wrap(self.marks[mark_index + 1])])) - else: - regs.append(self.space.newtuple([self.space.wrap(-1), - self.space.wrap(-1)])) - return self.space.newtuple(regs) - - def set_mark(self, mark_nr, position): - if mark_nr & 1: - # This id marks the end of a group. - self.lastindex = mark_nr / 2 + 1 - if mark_nr >= len(self.marks): - self.marks.extend([-1] * (mark_nr - len(self.marks) + 1)) - self.marks[mark_nr] = position - - def get_marks(self, group_index): - marks_index = 2 * group_index - if len(self.marks) > marks_index + 1: - return self.marks[marks_index], self.marks[marks_index + 1] - else: - return -1, -1 - - def marks_push(self): - self.marks_stack.append((self.marks[:], self.lastindex)) + # methods overridden by subclasses - def marks_pop(self): - self.marks, self.lastindex = self.marks_stack.pop() + def unwrap_object(self): + raise NotImplementedError - def marks_pop_keep(self): - self.marks, self.lastindex = self.marks_stack[-1] + if 'reset' not in locals(): + def reset(self): + raise NotImplementedError - def marks_pop_discard(self): - self.marks_stack.pop() + if 'search' not in locals(): + def search(self, pattern_codes): + raise NotImplementedError - def lower(self, char_ord): - return getlower(self.space, char_ord, self.flags) + if 'match' not in locals(): + def match(self, pattern_codes): + raise NotImplementedError # Accessors for the typedef - + + def w_reset(self): + self.reset() + + def w_create_regs(self, group_count): + """Creates a tuple of index pairs representing matched groups, a format + that's convenient for SRE_Match.""" + space = self.space + lst = [] + for value1, value2 in self.create_regs(group_count): + lst.append(space.newtuple([space.wrap(value1), + space.wrap(value2)])) + return space.newtuple(lst) + w_create_regs.unwrap_spec = ['self', int] + def fget_start(space, self): return space.wrap(self.start) @@ -154,1035 +129,54 @@ create_regs = interp2app(W_State.w_create_regs), ) -class MatchContext(object): - UNDECIDED = 0 - MATCHED = 1 - NOT_MATCHED = 2 - - def __init__(self, space, state, pattern_codes, offset=0): - self.space = space - self.state = state - self.pattern_codes = pattern_codes - self.string_position = state.string_position - self.code_position = offset - self.has_matched = self.UNDECIDED - self.backup = [] - self.resume_at_opcode = -1 - - def push_new_context(self, pattern_offset): - """Creates a new child context of this context and pushes it on the - stack. pattern_offset is the offset off the current code position to - start interpreting from.""" - offset = self.code_position + pattern_offset - assert offset >= 0 - child_context = MatchContext(self.space, self.state, self.pattern_codes, offset) - self.state.context_stack.append(child_context) - self.child_context = child_context - return child_context - - def is_resumed(self): - return self.resume_at_opcode > -1 - - def backup_value(self, value): - self.backup.append(value) - - def restore_values(self): - values = self.backup - self.backup = [] - return values - - def peek_char(self, peek=0): - return self.space.getitem(self.state.w_string, - self.space.wrap(self.string_position + peek)) - - def peek_char_ord(self, peek=0): - # XXX this is not very nice - return self.space.int_w(self.space.ord(self.peek_char(peek))) - - def skip_char(self, skip_count): - self.string_position = self.string_position + skip_count - - def remaining_chars(self): - return self.state.end - self.string_position - - def peek_code(self, peek=0): - return self.pattern_codes[self.code_position + peek] - - def skip_code(self, skip_count): - self.code_position = self.code_position + skip_count - - def has_remaining_codes(self): - return len(self.pattern_codes) != self.code_position - - def at_beginning(self): - return self.string_position == 0 - - def at_end(self): - return self.string_position == self.state.end - - def at_linebreak(self): - return not self.at_end() and is_linebreak(self.space, self.peek_char()) - - def at_boundary(self, word_checker): - if self.at_beginning() and self.at_end(): - return False - that = not self.at_beginning() \ - and word_checker(self.space, self.peek_char(-1)) - this = not self.at_end() \ - and word_checker(self.space, self.peek_char()) - return this != that - - -class RepeatContext(MatchContext): - - def __init__(self, space, context): - offset = context.code_position - assert offset >= 0 - MatchContext.__init__(self, space, context.state, - context.pattern_codes, offset) - self.count = -1 - self.previous = context.state.repeat - self.last_position = -1 - self.repeat_stack = [] - -#### Main opcode dispatch loop - -def w_search(space, w_state, w_pattern_codes): - state = space.interp_w(W_State, w_state) - pattern_codes = [intmask(space.uint_w(code)) for code - in space.unpackiterable(w_pattern_codes)] - return space.newbool(search(space, state, pattern_codes)) +class W_StringState(W_State): + if THREE_VERSIONS_OF_CORE: + rsre.insert_sre_methods(locals(), 'str') -def search(space, state, pattern_codes): - flags = 0 - if pattern_codes[0] == OPCODE_INFO: - # optimization info block - # <1=skip> <2=flags> <3=min> <4=max> <5=prefix info> - if pattern_codes[2] & SRE_INFO_PREFIX and pattern_codes[5] > 1: - return fast_search(space, state, pattern_codes) - flags = pattern_codes[2] - offset = pattern_codes[1] + 1 - assert offset >= 0 - #pattern_codes = pattern_codes[offset:] - - string_position = state.start - while string_position <= state.end: - state.w_reset() - state.start = state.string_position = string_position - if match(space, state, pattern_codes): - return True - string_position += 1 - return False - -def fast_search(space, state, pattern_codes): - """Skips forward in a string as fast as possible using information from - an optimization info block.""" - # pattern starts with a known prefix - # <5=length> <6=skip> <7=prefix data> - flags = pattern_codes[2] - prefix_len = pattern_codes[5] - assert prefix_len >= 0 - prefix_skip = pattern_codes[6] # don't really know what this is good for - assert prefix_skip >= 0 - prefix = pattern_codes[7:7 + prefix_len] - overlap_offset = 7 + prefix_len - 1 - overlap_stop = pattern_codes[1] + 1 - assert overlap_offset >= 0 - assert overlap_stop >= 0 - overlap = pattern_codes[overlap_offset:overlap_stop] - pattern_offset = pattern_codes[1] + 1 - assert pattern_offset >= 0 - pattern_codes = pattern_codes[pattern_offset:] - i = 0 - string_position = state.string_position - while string_position < state.end: - while True: - char_ord = space.int_w(space.ord( - space.getitem(state.w_string, space.wrap(string_position)))) - if char_ord != prefix[i]: - if i == 0: - break - else: - i = overlap[i] - else: - i += 1 - if i == prefix_len: - # found a potential match - state.start = string_position + 1 - prefix_len - state.string_position = string_position + 1 \ - - prefix_len + prefix_skip - if flags & SRE_INFO_LITERAL: - return True # matched all of pure literal pattern - if match(space, state, pattern_codes[2 * prefix_skip:]): - return True - i = overlap[i] - break - string_position += 1 - return False + def unwrap_object(self): + self.string = self.space.str_w(self.w_string) + return len(self.string) -def w_match(space, w_state, w_pattern_codes): - state = space.interp_w(W_State, w_state) - pattern_codes = [intmask(space.uint_w(code)) for code - in space.unpackiterable(w_pattern_codes)] - return space.newbool(match(space, state, pattern_codes)) + def get_char_ord(self, p): + return ord(self.string[p]) -def match(space, state, pattern_codes): - # Optimization: Check string length. pattern_codes[3] contains the - # minimum length for a string to possibly match. - if pattern_codes[0] == OPCODE_INFO and pattern_codes[3] > 0: - if state.end - state.string_position < pattern_codes[3]: - return False - state.context_stack.append(MatchContext(space, state, pattern_codes)) - has_matched = MatchContext.UNDECIDED - while len(state.context_stack) > 0: - context = state.context_stack[-1] - if context.has_matched == context.UNDECIDED: - has_matched = dispatch_loop(space, context) - else: - has_matched = context.has_matched - if has_matched != context.UNDECIDED: # don't pop if context isn't done - state.context_stack.pop() - return has_matched == MatchContext.MATCHED - -def dispatch_loop(space, context): - """Returns MATCHED if the current context matches, NOT_MATCHED if it doesn't - and UNDECIDED if matching is not finished, ie must be resumed after child - contexts have been matched.""" - while context.has_remaining_codes() and context.has_matched == context.UNDECIDED: - if context.is_resumed(): - opcode = context.resume_at_opcode - else: - opcode = context.peek_code() - try: - has_finished = opcode_dispatch_table[opcode](space, context) - except IndexError: - raise RuntimeError("Internal re error. Unknown opcode: %s" % opcode) - if not has_finished: - context.resume_at_opcode = opcode - return context.UNDECIDED - context.resume_at_opcode = -1 - if context.has_matched == context.UNDECIDED: - context.has_matched = context.NOT_MATCHED - return context.has_matched - -def op_success(space, ctx): - # end of pattern - ctx.state.string_position = ctx.string_position - ctx.has_matched = ctx.MATCHED - return True - -def op_failure(space, ctx): - # immediate failure - ctx.has_matched = ctx.NOT_MATCHED - return True - -def op_literal(space, ctx): - # match literal string - # - if ctx.at_end() or ctx.peek_char_ord() != ctx.peek_code(1): - ctx.has_matched = ctx.NOT_MATCHED - ctx.skip_code(2) - ctx.skip_char(1) - return True - -def op_not_literal(space, ctx): - # match anything that is not the given literal character - # - if ctx.at_end() or ctx.peek_char_ord() == ctx.peek_code(1): - ctx.has_matched = ctx.NOT_MATCHED - ctx.skip_code(2) - ctx.skip_char(1) - return True - -def op_literal_ignore(space, ctx): - # match literal regardless of case - # - if ctx.at_end() or \ - ctx.state.lower(ctx.peek_char_ord()) != ctx.state.lower(ctx.peek_code(1)): - ctx.has_matched = ctx.NOT_MATCHED - ctx.skip_code(2) - ctx.skip_char(1) - return True - -def op_not_literal_ignore(space, ctx): - # match literal regardless of case - # - if ctx.at_end() or \ - ctx.state.lower(ctx.peek_char_ord()) == ctx.state.lower(ctx.peek_code(1)): - ctx.has_matched = ctx.NOT_MATCHED - ctx.skip_code(2) - ctx.skip_char(1) - return True - -def op_at(space, ctx): - # match at given position - # - if not at_dispatch(space, ctx.peek_code(1), ctx): - ctx.has_matched = ctx.NOT_MATCHED - return True - ctx.skip_code(2) - return True - -def op_category(space, ctx): - # match at given category - # - if ctx.at_end() or \ - not category_dispatch(space, ctx.peek_code(1), ctx.peek_char()): - ctx.has_matched = ctx.NOT_MATCHED - return True - ctx.skip_code(2) - ctx.skip_char(1) - return True - -def op_any(self, ctx): - # match anything (except a newline) - # - if ctx.at_end() or ctx.at_linebreak(): - ctx.has_matched = ctx.NOT_MATCHED - return True - ctx.skip_code(1) - ctx.skip_char(1) - return True - -def op_any_all(space, ctx): - # match anything - # - if ctx.at_end(): - ctx.has_matched = ctx.NOT_MATCHED - return True - ctx.skip_code(1) - ctx.skip_char(1) - return True - -def general_op_in(space, ctx, ignore=False): - if ctx.at_end(): - ctx.has_matched = ctx.NOT_MATCHED - return - skip = ctx.peek_code(1) - ctx.skip_code(2) # set op pointer to the set code - char_code = ctx.peek_char_ord() - if ignore: - char_code = ctx.state.lower(char_code) - if not check_charset(space, char_code, ctx): - ctx.has_matched = ctx.NOT_MATCHED - return - ctx.skip_code(skip - 1) - ctx.skip_char(1) - -def op_in(space, ctx): - # match set member (or non_member) - # - general_op_in(space, ctx) - return True - -def op_in_ignore(space, ctx): - # match set member (or non_member), disregarding case of current char - # - general_op_in(space, ctx, ignore=True) - return True - -def op_branch(space, ctx): - # alternation - # <0=skip> code ... - if not ctx.is_resumed(): - ctx.state.marks_push() - ctx.skip_code(1) - current_branch_length = ctx.peek_code(0) - else: - if ctx.child_context.has_matched == ctx.MATCHED: - ctx.has_matched = ctx.MATCHED - return True - ctx.state.marks_pop_keep() - last_branch_length = ctx.restore_values()[0] - ctx.skip_code(last_branch_length) - current_branch_length = ctx.peek_code(0) - if current_branch_length: - ctx.state.string_position = ctx.string_position - ctx.push_new_context(1) - ctx.backup_value(current_branch_length) - return False - ctx.state.marks_pop_discard() - ctx.has_matched = ctx.NOT_MATCHED - return True - -def op_repeat_one(space, ctx): - # match repeated sequence (maximizing). - # this operator only works if the repeated item is exactly one character - # wide, and we're not already collecting backtracking points. - # <1=min> <2=max> item tail - - # Case 1: First entry point - if not ctx.is_resumed(): - mincount = ctx.peek_code(2) - maxcount = ctx.peek_code(3) - if ctx.remaining_chars() < mincount: - ctx.has_matched = ctx.NOT_MATCHED - return True - ctx.state.string_position = ctx.string_position - count = count_repetitions(space, ctx, maxcount) - ctx.skip_char(count) - if count < mincount: - ctx.has_matched = ctx.NOT_MATCHED - return True - if ctx.peek_code(ctx.peek_code(1) + 1) == 1: # 1 == OPCODES["success"] - # tail is empty. we're finished - ctx.state.string_position = ctx.string_position - ctx.has_matched = ctx.MATCHED - return True - ctx.state.marks_push() - # XXX literal optimization missing here - # Case 2: Repetition is resumed (aka backtracked) - else: - if ctx.child_context.has_matched == ctx.MATCHED: - ctx.has_matched = ctx.MATCHED - return True - values = ctx.restore_values() - mincount = values[0] - count = values[1] - ctx.skip_char(-1) - count -= 1 - ctx.state.marks_pop_keep() - - # Initialize the actual backtracking - if count >= mincount: - ctx.state.string_position = ctx.string_position - ctx.push_new_context(ctx.peek_code(1) + 1) - ctx.backup_value(mincount) - ctx.backup_value(count) - return False - - # Backtracking failed - ctx.state.marks_pop_discard() - ctx.has_matched = ctx.NOT_MATCHED - return True - -def op_min_repeat_one(space, ctx): - # match repeated sequence (minimizing) - # <1=min> <2=max> item tail - - # Case 1: First entry point - if not ctx.is_resumed(): - mincount = ctx.peek_code(2) - maxcount = ctx.peek_code(3) - if ctx.remaining_chars() < mincount: - ctx.has_matched = ctx.NOT_MATCHED - return True - ctx.state.string_position = ctx.string_position - if mincount == 0: - count = 0 - else: - count = count_repetitions(space, ctx, mincount) - if count < mincount: - ctx.has_matched = ctx.NOT_MATCHED - return True - ctx.skip_char(count) - if ctx.peek_code(ctx.peek_code(1) + 1) == 1: # OPCODES["success"] - # tail is empty. we're finished - ctx.state.string_position = ctx.string_position - ctx.has_matched = ctx.MATCHED - return True - ctx.state.marks_push() +class W_UnicodeState(W_State): + if THREE_VERSIONS_OF_CORE: + rsre.insert_sre_methods(locals(), 'unicode') - # Case 2: Repetition resumed, "forwardtracking" - else: - if ctx.child_context.has_matched == ctx.MATCHED: - ctx.has_matched = ctx.MATCHED - return True - values = ctx.restore_values() - maxcount = values[0] - count = values[1] - ctx.state.string_position = ctx.string_position - if count_repetitions(space, ctx, 1) == 0: - # Tail didn't match and no more repetitions --> fail - ctx.state.marks_pop_discard() - ctx.has_matched = ctx.NOT_MATCHED - return True - ctx.skip_char(1) - count += 1 - ctx.state.marks_pop_keep() - - # Try to match tail - if maxcount == MAXREPEAT or count <= maxcount: - ctx.state.string_position = ctx.string_position - ctx.push_new_context(ctx.peek_code(1) + 1) - ctx.backup_value(maxcount) - ctx.backup_value(count) - return False - - # Failed - ctx.state.marks_pop_discard() - ctx.has_matched = ctx.NOT_MATCHED - return True - -def op_repeat(space, ctx): - # create repeat context. all the hard work is done by the UNTIL - # operator (MAX_UNTIL, MIN_UNTIL) - # <1=min> <2=max> item tail - if not ctx.is_resumed(): - ctx.repeat = RepeatContext(space, ctx) - ctx.state.repeat = ctx.repeat - ctx.state.string_position = ctx.string_position - ctx.push_new_context(ctx.peek_code(1) + 1) - return False - else: - ctx.state.repeat = ctx.repeat - ctx.has_matched = ctx.child_context.has_matched - return True - -def op_max_until(space, ctx): - # maximizing repeat - # <1=min> <2=max> item tail - - # Case 1: First entry point - if not ctx.is_resumed(): - repeat = ctx.state.repeat - if repeat is None: - raise RuntimeError("Internal re error: MAX_UNTIL without REPEAT.") - mincount = repeat.peek_code(2) - maxcount = repeat.peek_code(3) - ctx.state.string_position = ctx.string_position - count = repeat.count + 1 - if count < mincount: - # not enough matches - repeat.count = count - repeat.repeat_stack.append(repeat.push_new_context(4)) - ctx.backup_value(mincount) - ctx.backup_value(maxcount) - ctx.backup_value(count) - ctx.backup_value(0) # Dummy for last_position - ctx.backup_value(0) - ctx.repeat = repeat - return False - if (count < maxcount or maxcount == MAXREPEAT) \ - and ctx.state.string_position != repeat.last_position: - # we may have enough matches, if we can match another item, do so - repeat.count = count - ctx.state.marks_push() - repeat.last_position = ctx.state.string_position - repeat.repeat_stack.append(repeat.push_new_context(4)) - ctx.backup_value(mincount) - ctx.backup_value(maxcount) - ctx.backup_value(count) - ctx.backup_value(repeat.last_position) # zero-width match protection - ctx.backup_value(2) # more matching - ctx.repeat = repeat - return False - - # Cannot match more repeated items here. Make sure the tail matches. - ctx.state.repeat = repeat.previous - ctx.push_new_context(1) - ctx.backup_value(mincount) - ctx.backup_value(maxcount) - ctx.backup_value(count) - ctx.backup_value(repeat.last_position) # zero-width match protection - ctx.backup_value(1) # tail matching - ctx.repeat = repeat - return False + def unwrap_object(self): + self.unichars = self.space.unichars_w(self.w_string) + return len(self.unichars) - # Case 2: Resumed - else: - repeat = ctx.repeat - values = ctx.restore_values() - mincount = values[0] - maxcount = values[1] - count = values[2] - save_last_position = values[3] - tail_matching = values[4] - - if tail_matching == 0: - ctx.has_matched = repeat.repeat_stack.pop().has_matched - if ctx.has_matched == ctx.NOT_MATCHED: - repeat.count = count - 1 - ctx.state.string_position = ctx.string_position - return True - elif tail_matching == 2: - repeat.last_position = save_last_position - if repeat.repeat_stack.pop().has_matched == ctx.MATCHED: - ctx.state.marks_pop_discard() - ctx.has_matched = ctx.MATCHED - return True - ctx.state.marks_pop() - repeat.count = count - 1 - ctx.state.string_position = ctx.string_position - - # Cannot match more repeated items here. Make sure the tail matches. - ctx.state.repeat = repeat.previous - ctx.push_new_context(1) - ctx.backup_value(mincount) - ctx.backup_value(maxcount) - ctx.backup_value(count) - ctx.backup_value(repeat.last_position) # zero-width match protection - ctx.backup_value(1) # tail matching - return False - - else: # resuming after tail matching - ctx.has_matched = ctx.child_context.has_matched - if ctx.has_matched == ctx.NOT_MATCHED: - ctx.state.repeat = repeat - ctx.state.string_position = ctx.string_position - return True - -def op_min_until(space, ctx): - # minimizing repeat - # <1=min> <2=max> item tail - - # Case 1: First entry point - if not ctx.is_resumed(): - repeat = ctx.state.repeat - if repeat is None: - raise RuntimeError("Internal re error: MIN_UNTIL without REPEAT.") - mincount = repeat.peek_code(2) - maxcount = repeat.peek_code(3) - ctx.state.string_position = ctx.string_position - count = repeat.count + 1 - - if count < mincount: - # not enough matches - repeat.count = count - repeat.repeat_stack.append(repeat.push_new_context(4)) - ctx.backup_value(mincount) - ctx.backup_value(maxcount) - ctx.backup_value(count) - ctx.backup_value(0) - ctx.repeat = repeat - return False - - # see if the tail matches - ctx.state.marks_push() - ctx.state.repeat = repeat.previous - ctx.push_new_context(1) - ctx.backup_value(mincount) - ctx.backup_value(maxcount) - ctx.backup_value(count) - ctx.backup_value(1) - ctx.repeat = repeat - return False + def get_char_ord(self, p): + return ord(self.unichars[p]) - # Case 2: Resumed - else: - repeat = ctx.repeat - if repeat.has_matched == ctx.MATCHED: - ctx.has_matched = ctx.MATCHED - return True - values = ctx.restore_values() - mincount = values[0] - maxcount = values[1] - count = values[2] - matching_state = values[3] - - if count < mincount: - # not enough matches - ctx.has_matched = repeat.repeat_stack.pop().has_matched - if ctx.has_matched == ctx.NOT_MATCHED: - repeat.count = count - 1 - ctx.state.string_position = ctx.string_position - return True - - if matching_state == 1: - # returning from tail matching - if ctx.child_context.has_matched == ctx.MATCHED: - ctx.has_matched = ctx.MATCHED - return True - ctx.state.repeat = repeat - ctx.state.string_position = ctx.string_position - ctx.state.marks_pop() - - if not matching_state == 2: - # match more until tail matches - if count >= maxcount and maxcount != MAXREPEAT: - ctx.has_matched = ctx.NOT_MATCHED - return True - repeat.count = count - repeat.repeat_stack.append(repeat.push_new_context(4)) - ctx.backup_value(mincount) - ctx.backup_value(maxcount) - ctx.backup_value(count) - ctx.backup_value(2) - ctx.repeat = repeat - return False - - # Final return - ctx.has_matched = repeat.repeat_stack.pop().has_matched - repeat.has_matched = ctx.has_matched - if ctx.has_matched == ctx.NOT_MATCHED: - repeat.count = count - 1 - ctx.state.string_position = ctx.string_position - return True - -def op_jump(space, ctx): - # jump forward - # / - ctx.skip_code(ctx.peek_code(1) + 1) - return True - -def op_mark(space, ctx): - # set mark - # - ctx.state.set_mark(ctx.peek_code(1), ctx.string_position) - ctx.skip_code(2) - return True - -def general_op_groupref(space, ctx, ignore=False): - group_start, group_end = ctx.state.get_marks(ctx.peek_code(1)) - if group_start == -1 or group_end == -1 or group_end < group_start \ - or group_end - group_start > ctx.remaining_chars(): - ctx.has_matched = ctx.NOT_MATCHED - return True - while group_start < group_end: - # XXX This is really a bit unwieldy. Can this be improved? - new_char = ctx.peek_char_ord() - old_char = space.int_w(space.ord( - space.getitem(ctx.state.w_string, space.wrap(group_start)))) - if ctx.at_end() or (not ignore and old_char != new_char) \ - or (ignore and ctx.state.lower(old_char) != ctx.state.lower(new_char)): - ctx.has_matched = ctx.NOT_MATCHED - return True - group_start += 1 - ctx.skip_char(1) - ctx.skip_code(2) - return True - -def op_groupref(space, ctx): - # match backreference - # - return general_op_groupref(space, ctx) - -def op_groupref_ignore(space, ctx): - # match backreference case-insensitive - # - return general_op_groupref(space, ctx, ignore=True) - -def op_groupref_exists(space, ctx): - # codeyes codeno ... - group_start, group_end = ctx.state.get_marks(ctx.peek_code(1)) - if group_start == -1 or group_end == -1 or group_end < group_start: - ctx.skip_code(ctx.peek_code(2) + 1) - else: - ctx.skip_code(3) - return True -def op_assert(space, ctx): - # assert subpattern - # - if not ctx.is_resumed(): - ctx.state.string_position = ctx.string_position - ctx.peek_code(2) - if ctx.state.string_position < 0: - ctx.has_matched = ctx.NOT_MATCHED - return True - ctx.push_new_context(3) - return False - else: - if ctx.child_context.has_matched == ctx.MATCHED: - ctx.skip_code(ctx.peek_code(1) + 1) - else: - ctx.has_matched = ctx.NOT_MATCHED - return True - -def op_assert_not(space, ctx): - # assert not subpattern - # - if not ctx.is_resumed(): - ctx.state.string_position = ctx.string_position - ctx.peek_code(2) - if ctx.state.string_position >= 0: - ctx.push_new_context(3) - return False - else: - if ctx.child_context.has_matched == ctx.MATCHED: - ctx.has_matched = ctx.NOT_MATCHED - return True - ctx.skip_code(ctx.peek_code(1) + 1) - return True - -def count_repetitions(space, ctx, maxcount): - """Returns the number of repetitions of a single item, starting from the - current string position. The code pointer is expected to point to a - REPEAT_ONE operation (with the repeated 4 ahead).""" - count = 0 - real_maxcount = ctx.state.end - ctx.string_position - if maxcount < real_maxcount and maxcount != MAXREPEAT: - real_maxcount = maxcount - # XXX could special case every single character pattern here, as in C. - # This is a general solution, a bit hackisch, but works and should be - # efficient. - code_position = ctx.code_position - string_position = ctx.string_position - ctx.skip_code(4) - reset_position = ctx.code_position - while count < real_maxcount: - # this works because the single character pattern is followed by - # a success opcode - ctx.code_position = reset_position - opcode_dispatch_table[ctx.peek_code()](space, ctx) - if ctx.has_matched == ctx.NOT_MATCHED: - break - count += 1 - ctx.has_matched = ctx.UNDECIDED - ctx.code_position = code_position - ctx.string_position = string_position - return count - -opcode_dispatch_table = [ - op_failure, op_success, - op_any, op_any_all, - op_assert, op_assert_not, - op_at, - op_branch, - None, #CALL, - op_category, - None, None, #CHARSET, BIGCHARSET, - op_groupref, op_groupref_exists, op_groupref_ignore, - op_in, op_in_ignore, - op_jump, op_jump, - op_literal, op_literal_ignore, - op_mark, - op_max_until, - op_min_until, - op_not_literal, op_not_literal_ignore, - None, #NEGATE, - None, #RANGE, - op_repeat, - op_repeat_one, - None, #SUBPATTERN, - op_min_repeat_one, -] - - -#### Category helpers - -ascii_char_info = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 6, 2, -2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 25, 25, 25, 25, 25, 25, 25, -25, 25, 0, 0, 0, 0, 0, 0, 0, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, -24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 0, 0, -0, 0, 16, 0, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, -24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 0, 0, 0, 0, 0 ] - -linebreak = ord("\n") -underline = ord("_") - -# Static list of all unicode codepoints reported by Py_UNICODE_ISLINEBREAK. -uni_linebreaks = [10, 13, 28, 29, 30, 133, 8232, 8233] - -def is_digit(space, w_char): - code = space.int_w(space.ord(w_char)) - return code < 128 and (ascii_char_info[code] & 1 != 0) - -def is_uni_digit(space, w_char): - return space.is_true(space.call_method(w_char, "isdigit")) - -def is_space(space, w_char): - code = space.int_w(space.ord(w_char)) - return code < 128 and (ascii_char_info[code] & 2 != 0) - -def is_uni_space(space, w_char): - return space.is_true(space.call_method(w_char, "isspace")) - -def is_word(space, w_char): - code = space.int_w(space.ord(w_char)) - return code < 128 and (ascii_char_info[code] & 16 != 0) - -def is_uni_word(space, w_char): - code = space.int_w(space.ord(w_char)) - w_unichar = space.newunicode([code]) - isalnum = space.is_true(space.call_method(w_unichar, "isalnum")) - return isalnum or code == underline - -def is_loc_word(space, w_char): - code = space.int_w(space.ord(w_char)) - if code > 255: - return False - # Need to use this new w_char_not_uni from here on, because this one is - # guaranteed to be not unicode. - w_char_not_uni = space.wrap(chr(code)) - isalnum = space.is_true(space.call_method(w_char_not_uni, "isalnum")) - return isalnum or code == underline - -def is_linebreak(space, w_char): - return space.int_w(space.ord(w_char)) == linebreak - -def is_uni_linebreak(space, w_char): - code = space.int_w(space.ord(w_char)) - return code in uni_linebreaks - - -#### Category dispatch - -def category_dispatch(space, chcode, w_char): - try: - function, negate = category_dispatch_table[chcode] - except IndexError: - return False - result = function(space, w_char) - if negate: - return not result - else: - return result +class W_GenericState(W_State): + if THREE_VERSIONS_OF_CORE: + rsre.insert_sre_methods(locals(), 'generic') -# Maps opcodes by indices to (function, negate) tuples. -category_dispatch_table = [ - (is_digit, False), (is_digit, True), (is_space, False), - (is_space, True), (is_word, False), (is_word, True), - (is_linebreak, False), (is_linebreak, True), (is_loc_word, False), - (is_loc_word, True), (is_uni_digit, False), (is_uni_digit, True), - (is_uni_space, False), (is_uni_space, True), (is_uni_word, False), - (is_uni_word, True), (is_uni_linebreak, False), - (is_uni_linebreak, True) -] - -##### At dispatch - -def at_dispatch(space, atcode, context): - try: - function, negate = at_dispatch_table[atcode] - except IndexError: - return False - result = function(space, context) - if negate: - return not result - else: - return result + def unwrap_object(self): + # cannot unwrap in the general case + space = self.space + return space.int_w(space.len(self.w_string)) -def at_beginning(space, ctx): - return ctx.at_beginning() + def get_char_ord(self, p): + space = self.space + w_char = space.getitem(self.w_string, space.wrap(p)) + return space.int_w(space.ord(w_char)) -def at_beginning_line(space, ctx): - return ctx.at_beginning() or is_linebreak(space, ctx.peek_char(-1)) - -def at_end(space, ctx): - return ctx.at_end() or (ctx.remaining_chars() == 1 and ctx.at_linebreak()) - -def at_end_line(space, ctx): - return ctx.at_linebreak() or ctx.at_end() - -def at_end_string(space, ctx): - return ctx.at_end() - -def at_boundary(space, ctx): - return ctx.at_boundary(is_word) - -def at_loc_boundary(space, ctx): - return ctx.at_boundary(is_loc_word) - -def at_uni_boundary(space, ctx): - return ctx.at_boundary(is_uni_word) - -# Maps opcodes by indices to (function, negate) tuples. -at_dispatch_table = [ - (at_beginning, False), (at_beginning_line, False), (at_beginning, False), - (at_boundary, False), (at_boundary, True), - (at_end, False), (at_end_line, False), (at_end_string, False), - (at_loc_boundary, False), (at_loc_boundary, True), (at_uni_boundary, False), - (at_uni_boundary, True) -] - -##### Charset evaluation - -SET_OK = 1 -SET_NOT_OK = -1 -SET_NOT_FINISHED = 0 - -def check_charset(space, char_code, context): - """Checks whether a character matches set of arbitrary length. Currently - assumes the set starts at the first member of pattern_codes.""" - result = SET_NOT_FINISHED - context.set_ok = SET_OK - backup_code_position = context.code_position - while result == SET_NOT_FINISHED: - opcode = context.peek_code() - try: - function = set_dispatch_table[opcode] - except IndexError: - return False - result = function(space, context, char_code) - context.code_position = backup_code_position - return result == SET_OK - -def set_failure(space, ctx, char_code): - return -ctx.set_ok - -def set_literal(space, ctx, char_code): - # - if ctx.peek_code(1) == char_code: - return ctx.set_ok - else: - ctx.skip_code(2) - return SET_NOT_FINISHED -def set_category(space, ctx, char_code): - # - if category_dispatch(space, ctx.peek_code(1), ctx.peek_char()): - return ctx.set_ok - else: - ctx.skip_code(2) - return SET_NOT_FINISHED +def w_search(space, w_state, w_pattern_codes): + state = space.interp_w(W_State, w_state) + pattern_codes = [intmask(space.uint_w(code)) for code + in space.unpackiterable(w_pattern_codes)] + return space.newbool(state.search(pattern_codes)) -def set_charset(space, ctx, char_code): - # (16 bits per code word) - ctx.skip_code(1) # point to beginning of bitmap - if CODESIZE == 2: - if char_code < 256 and ctx.peek_code(char_code >> 4) \ - & (1 << (char_code & 15)): - return ctx.set_ok - ctx.skip_code(16) # skip bitmap - else: - if char_code < 256 and ctx.peek_code(char_code >> 5) \ - & (1 << (char_code & 31)): - return ctx.set_ok - ctx.skip_code(8) # skip bitmap - return SET_NOT_FINISHED - -def set_range(space, ctx, char_code): - # - if ctx.peek_code(1) <= char_code <= ctx.peek_code(2): - return ctx.set_ok - ctx.skip_code(3) - return SET_NOT_FINISHED - -def set_negate(space, ctx, char_code): - ctx.set_ok = -ctx.set_ok - ctx.skip_code(1) - return SET_NOT_FINISHED - -def set_bigcharset(space, ctx, char_code): - # <256 blockindices> - # XXX this function probably needs a makeover - count = ctx.peek_code(1) - ctx.skip_code(2) - if char_code < 65536: - block_index = char_code >> 8 - # NB: there are CODESIZE block indices per bytecode - a = to_byte_array(ctx.peek_code(block_index / CODESIZE)) - block = a[block_index % CODESIZE] - ctx.skip_code(256 / CODESIZE) # skip block indices - if CODESIZE == 2: - shift = 4 - else: - shift = 5 - block_value = ctx.peek_code(block * (32 / CODESIZE) - + ((char_code & 255) >> shift)) - if block_value & (1 << (char_code & ((8 * CODESIZE) - 1))): - return ctx.set_ok - else: - ctx.skip_code(256 / CODESIZE) # skip block indices - ctx.skip_code(count * (32 / CODESIZE)) # skip blocks - return SET_NOT_FINISHED - -def to_byte_array(int_value): - """Creates a list of bytes out of an integer representing data that is - CODESIZE bytes wide.""" - byte_array = [0] * CODESIZE - for i in range(CODESIZE): - byte_array[i] = int_value & 0xff - int_value = int_value >> 8 - if BIG_ENDIAN: - byte_array.reverse() - return byte_array - -set_dispatch_table = [ - set_failure, None, None, None, None, None, None, None, None, - set_category, set_charset, set_bigcharset, None, None, None, - None, None, None, None, set_literal, None, None, None, None, - None, None, set_negate, set_range -] +def w_match(space, w_state, w_pattern_codes): + state = space.interp_w(W_State, w_state) + pattern_codes = [intmask(space.uint_w(code)) for code + in space.unpackiterable(w_pattern_codes)] + return space.newbool(state.match(pattern_codes)) Added: pypy/dist/pypy/rlib/rsre/__init__.py ============================================================================== Added: pypy/dist/pypy/rlib/rsre/test/__init__.py ============================================================================== From arigo at codespeak.net Sun Feb 11 16:01:26 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 11 Feb 2007 16:01:26 +0100 (CET) Subject: [pypy-svn] r38468 - pypy/dist/pypy/module/_sre/test Message-ID: <20070211150126.177BD10089@code0.codespeak.net> Author: arigo Date: Sun Feb 11 16:01:25 2007 New Revision: 38468 Modified: pypy/dist/pypy/module/_sre/test/test_app_sre.py Log: Ou-ou-oups. Modified: pypy/dist/pypy/module/_sre/test/test_app_sre.py ============================================================================== --- pypy/dist/pypy/module/_sre/test/test_app_sre.py (original) +++ pypy/dist/pypy/module/_sre/test/test_app_sre.py Sun Feb 11 16:01:25 2007 @@ -4,7 +4,7 @@ from pypy.interpreter.gateway import app2interp_temp def init_globals_hack(space): - space.appexec([autopath.this_dir], """(this_dir): + space.appexec([space.wrap(autopath.this_dir)], """(this_dir): import __builtin__ as b import sys, os.path # Uh-oh, ugly hack From arigo at codespeak.net Sun Feb 11 16:02:51 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 11 Feb 2007 16:02:51 +0100 (CET) Subject: [pypy-svn] r38469 - pypy/dist/pypy/rlib/rsre Message-ID: <20070211150251.758C810089@code0.codespeak.net> Author: arigo Date: Sun Feb 11 16:02:50 2007 New Revision: 38469 Modified: pypy/dist/pypy/rlib/rsre/rsre_core.py Log: Reduce the amount of slicing. The first of these removed slices was invalid in RPython because its start could occasionally be beyond the end of the list. Modified: pypy/dist/pypy/rlib/rsre/rsre_core.py ============================================================================== --- pypy/dist/pypy/rlib/rsre/rsre_core.py (original) +++ pypy/dist/pypy/rlib/rsre/rsre_core.py Sun Feb 11 16:02:50 2007 @@ -181,13 +181,9 @@ assert prefix_skip >= 0 prefix = pattern_codes[7:7 + prefix_len] overlap_offset = 7 + prefix_len - 1 - overlap_stop = pattern_codes[1] + 1 assert overlap_offset >= 0 - assert overlap_stop >= 0 - overlap = pattern_codes[overlap_offset:overlap_stop] pattern_offset = pattern_codes[1] + 1 assert pattern_offset >= 0 - pattern_codes = pattern_codes[pattern_offset:] i = 0 string_position = state.string_position while string_position < state.end: @@ -197,7 +193,7 @@ if i == 0: break else: - i = overlap[i] + i = pattern_codes[overlap_offset + i] else: i += 1 if i == prefix_len: @@ -207,9 +203,10 @@ - prefix_len + prefix_skip if flags & SRE_INFO_LITERAL: return True # matched all of pure literal pattern - if match(state, pattern_codes[2 * prefix_skip:]): + start = pattern_offset + 2 * prefix_skip + if match(state, pattern_codes[start:]): return True - i = overlap[i] + i = pattern_codes[overlap_offset + i] break string_position += 1 return False From hpk at codespeak.net Sun Feb 11 17:26:43 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sun, 11 Feb 2007 17:26:43 +0100 (CET) Subject: [pypy-svn] r38475 - pypy/branch/pytrunkmerge/lib-python Message-ID: <20070211162643.C600410075@code0.codespeak.net> Author: hpk Date: Sun Feb 11 17:26:43 2007 New Revision: 38475 Modified: pypy/branch/pytrunkmerge/lib-python/conftest.py Log: proper rsync_roots for lib-python (it doesn't work though to distribute the compliance tests) Modified: pypy/branch/pytrunkmerge/lib-python/conftest.py ============================================================================== --- pypy/branch/pytrunkmerge/lib-python/conftest.py (original) +++ pypy/branch/pytrunkmerge/lib-python/conftest.py Sun Feb 11 17:26:43 2007 @@ -4,6 +4,8 @@ test suite on top of PyPy """ + +dist_rsync_roots = [".", "../pypy", "../py"] import py import sys import pypy From arigo at codespeak.net Sun Feb 11 17:33:53 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 11 Feb 2007 17:33:53 +0100 (CET) Subject: [pypy-svn] r38477 - pypy/dist/pypy/lib Message-ID: <20070211163353.1545510075@code0.codespeak.net> Author: arigo Date: Sun Feb 11 17:33:52 2007 New Revision: 38477 Modified: pypy/dist/pypy/lib/_classobj.py Log: Complain if arguments are passed to the constructor of an old-style class with no __init__. Modified: pypy/dist/pypy/lib/_classobj.py ============================================================================== --- pypy/dist/pypy/lib/_classobj.py (original) +++ pypy/dist/pypy/lib/_classobj.py Sun Feb 11 17:33:52 2007 @@ -213,6 +213,8 @@ ret = init(*args, **kwds) if ret is not None: raise TypeError("__init__() should return None") + elif args or kwds: + raise TypeError("this constructor takes no arguments") return inst # capture _name, _bases slots for usage and then hide them! From arigo at codespeak.net Sun Feb 11 17:44:13 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 11 Feb 2007 17:44:13 +0100 (CET) Subject: [pypy-svn] r38479 - pypy/dist/lib-python/modified-2.4.1/test Message-ID: <20070211164413.3E0681007B@code0.codespeak.net> Author: arigo Date: Sun Feb 11 17:44:12 2007 New Revision: 38479 Modified: pypy/dist/lib-python/modified-2.4.1/test/test_traceback.py Log: Usage of "print >> open(x, 'w')" which doesn't guarantee that any data is written until the next Boehm GC pass, and even then. Modified: pypy/dist/lib-python/modified-2.4.1/test/test_traceback.py ============================================================================== --- pypy/dist/lib-python/modified-2.4.1/test/test_traceback.py (original) +++ pypy/dist/lib-python/modified-2.4.1/test/test_traceback.py Sun Feb 11 17:44:12 2007 @@ -39,9 +39,11 @@ try: sys.path.insert(0, testdir) testfile = os.path.join(testdir, 'test_bug737473.py') - print >> open(testfile, 'w'), """ + f = open(testfile, 'w') + print >> f, """ def test(): raise ValueError""" + f.close() if 'test_bug737473' in sys.modules: del sys.modules['test_bug737473'] @@ -61,9 +63,11 @@ # three seconds are needed for this test to pass reliably :-( time.sleep(4) - print >> open(testfile, 'w'), """ + f = open(testfile, 'w') + print >> f, """ def test(): raise NotImplementedError""" + f.close() reload(test_bug737473) try: test_bug737473.test() From arigo at codespeak.net Sun Feb 11 18:01:10 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 11 Feb 2007 18:01:10 +0100 (CET) Subject: [pypy-svn] r38483 - in pypy/dist/pypy: . tool/pytest Message-ID: <20070211170110.0EB81100A4@code0.codespeak.net> Author: arigo Date: Sun Feb 11 18:01:08 2007 New Revision: 38483 Modified: pypy/dist/pypy/conftest.py pypy/dist/pypy/tool/pytest/appsupport.py Log: * Fix the code handling the failure of app-level tests (py lib API change). * Make --pdb work somewhat (instead of crashing) for app-level tests. Modified: pypy/dist/pypy/conftest.py ============================================================================== --- pypy/dist/pypy/conftest.py (original) +++ pypy/dist/pypy/conftest.py Sun Feb 11 18:01:08 2007 @@ -1,4 +1,5 @@ import py, sys +from py.__.test.outcome import Failed from pypy.interpreter.gateway import app2interp_temp from pypy.interpreter.error import OperationError from pypy.tool.pytest import appsupport @@ -218,7 +219,7 @@ raise OpErrKeyboardInterrupt, OpErrKeyboardInterrupt(), tb appexcinfo = appsupport.AppExceptionInfo(space, e) if appexcinfo.traceback: - raise self.Failed(excinfo=appsupport.AppExceptionInfo(space, e)) + raise Failed(excinfo=appsupport.AppExceptionInfo(space, e)) raise _pygame_imported = False Modified: pypy/dist/pypy/tool/pytest/appsupport.py ============================================================================== --- pypy/dist/pypy/tool/pytest/appsupport.py (original) +++ pypy/dist/pypy/tool/pytest/appsupport.py Sun Feb 11 18:01:08 2007 @@ -65,6 +65,9 @@ self.space = space self.operr = operr self.traceback = AppTraceback(space, self.operr.application_traceback) + debug_excs = getattr(operr, 'debug_excs', []) + if debug_excs: + self._excinfo = debug_excs[0] def exconly(self, tryshort=True): return '(application-level) ' + self.operr.errorstr(self.space) From arigo at codespeak.net Sun Feb 11 18:14:39 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 11 Feb 2007 18:14:39 +0100 (CET) Subject: [pypy-svn] r38487 - in pypy/dist/pypy: module/__builtin__/test objspace/std objspace/std/test Message-ID: <20070211171439.D9E731007B@code0.codespeak.net> Author: arigo Date: Sun Feb 11 18:14:37 2007 New Revision: 38487 Modified: pypy/dist/pypy/module/__builtin__/test/test_builtin.py pypy/dist/pypy/objspace/std/test/test_unicodeobject.py pypy/dist/pypy/objspace/std/unicodeobject.py Log: Fix for (u'hello' == 5). Implementing comparison with cmp__X_X() is not a great idea... Modified: pypy/dist/pypy/module/__builtin__/test/test_builtin.py ============================================================================== --- pypy/dist/pypy/module/__builtin__/test/test_builtin.py (original) +++ pypy/dist/pypy/module/__builtin__/test/test_builtin.py Sun Feb 11 18:14:37 2007 @@ -270,6 +270,8 @@ assert cmp(9,9) == 0 assert cmp(0,9) < 0 assert cmp(9,0) > 0 + assert cmp("abc", 12) != 0 + assert cmp(u"abc", 12) != 0 def test_cmp_more(self): class C: Modified: pypy/dist/pypy/objspace/std/test/test_unicodeobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/test/test_unicodeobject.py (original) +++ pypy/dist/pypy/objspace/std/test/test_unicodeobject.py Sun Feb 11 18:14:37 2007 @@ -1,16 +1,17 @@ -# test the integration of unicode and strings (even though we don't -# really implement unicode yet). - import autopath, sys - class AppTestUnicodeStringStdOnly: def test_compares(self): assert u'a' == 'a' assert 'a' == u'a' - assert not u'a' == 'b' # xxx u'a' != 'b' fails - assert not 'a' == u'b'# xxx 'a' != u'b' fails + assert not u'a' == 'b' + assert not 'a' == u'b' + assert u'a' != 'b' + assert 'a' != u'b' + assert not (u'a' == 5) + assert u'a' != 5 + assert u'a' < 5 or u'a' > 5 class AppTestUnicodeString: def test_addition(self): Modified: pypy/dist/pypy/objspace/std/unicodeobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/unicodeobject.py (original) +++ pypy/dist/pypy/objspace/std/unicodeobject.py Sun Feb 11 18:14:37 2007 @@ -65,30 +65,16 @@ def str__Unicode(space, w_uni): return space.call_method(w_uni, 'encode') -def cmp__Unicode_Unicode(space, w_left, w_right): +def eq__Unicode_Unicode(space, w_left, w_right): + return space.newbool(w_left._value == w_right._value) + +def lt__Unicode_Unicode(space, w_left, w_right): left = w_left._value right = w_right._value for i in range(min(len(left), len(right))): - test = ord(left[i]) - ord(right[i]) - if test < 0: - return space.wrap(-1) - if test > 0: - return space.wrap(1) - - test = len(left) - len(right) - if test < 0: - return space.wrap(-1) - if test > 0: - return space.wrap(1) - return space.wrap(0) - -## XXX what?? the following seems unnecessary -##def cmp__Unicode_ANY(space, w_left, w_right): -## try: -## w_right = space.call_function(space.w_unicode, w_right) -## except: -## return space.wrap(1) -## return space.cmp(w_left, w_right) + if left[i] != right[i]: + return space.newbool(left[i] < right[i]) + return space.newbool(len(left) < len(right)) def ord__Unicode(space, w_uni): if len(w_uni._value) != 1: From hpk at codespeak.net Sun Feb 11 18:16:44 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sun, 11 Feb 2007 18:16:44 +0100 (CET) Subject: [pypy-svn] r38488 - pypy/dist/pypy Message-ID: <20070211171644.D3C6F10081@code0.codespeak.net> Author: hpk Date: Sun Feb 11 18:16:43 2007 New Revision: 38488 Modified: pypy/dist/pypy/conftest.py Log: use the new per-project io-capturing facility to have appdirect tests use "sys" capturing instead of FD based. Modified: pypy/dist/pypy/conftest.py ============================================================================== --- pypy/dist/pypy/conftest.py (original) +++ pypy/dist/pypy/conftest.py Sun Feb 11 18:16:43 2007 @@ -134,6 +134,11 @@ and at interp-level (because we need to stick a space at the class) ourselves. """ + def __init__(self, *args, **kwargs): + if option.runappdirect: + option.conf_iocapture = "sys" # pypy cannot do FD-based + super(Module, self).__init__(*args, **kwargs) + def funcnamefilter(self, name): if name.startswith('test_'): return not option.runappdirect From arigo at codespeak.net Sun Feb 11 18:16:54 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 11 Feb 2007 18:16:54 +0100 (CET) Subject: [pypy-svn] r38489 - pypy/dist/pypy/objspace/std Message-ID: <20070211171654.D440D10089@code0.codespeak.net> Author: arigo Date: Sun Feb 11 18:16:53 2007 New Revision: 38489 Modified: pypy/dist/pypy/objspace/std/dictproxytype.py Log: Remove outdated comments. Modified: pypy/dist/pypy/objspace/std/dictproxytype.py ============================================================================== --- pypy/dist/pypy/objspace/std/dictproxytype.py (original) +++ pypy/dist/pypy/objspace/std/dictproxytype.py Sun Feb 11 18:16:53 2007 @@ -38,8 +38,6 @@ __contains__ = _proxymethod('__contains__'), __str__ = _proxymethod('__str__'), __iter__ = _proxymethod('__iter__'), - #__cmp__ = _proxymethod('__cmp__'), - # you cannot have it here if it is not in dict __lt__ = _compareproxymethod('lt'), __le__ = _compareproxymethod('le'), __eq__ = _compareproxymethod('eq'), From arigo at codespeak.net Sun Feb 11 18:17:08 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 11 Feb 2007 18:17:08 +0100 (CET) Subject: [pypy-svn] r38490 - pypy/dist/pypy/objspace/std/test Message-ID: <20070211171708.E4F1A10089@code0.codespeak.net> Author: arigo Date: Sun Feb 11 18:17:07 2007 New Revision: 38490 Modified: pypy/dist/pypy/objspace/std/test/test_set.py Log: Add a test showing why you explicitly need a cmp__ for sets :-( Modified: pypy/dist/pypy/objspace/std/test/test_set.py ============================================================================== --- pypy/dist/pypy/objspace/std/test/test_set.py (original) +++ pypy/dist/pypy/objspace/std/test/test_set.py Sun Feb 11 18:17:07 2007 @@ -54,3 +54,6 @@ a = subset() b = a | set('abc') assert type(b) is subset + + def test_compare(self): + raises(TypeError, cmp, set('abc'), set('abd')) From arigo at codespeak.net Sun Feb 11 18:36:19 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 11 Feb 2007 18:36:19 +0100 (CET) Subject: [pypy-svn] r38491 - pypy/dist/lib-python Message-ID: <20070211173619.0D2B810081@code0.codespeak.net> Author: arigo Date: Sun Feb 11 18:36:18 2007 New Revision: 38491 Modified: pypy/dist/lib-python/conftest.py Log: Fix a confusing comment, and pass py.test's own "-v" option to the CPython test. Modified: pypy/dist/lib-python/conftest.py ============================================================================== --- pypy/dist/lib-python/conftest.py (original) +++ pypy/dist/lib-python/conftest.py Sun Feb 11 18:36:18 2007 @@ -899,12 +899,15 @@ pypy_options.extend( ['--withmod-%s' % mod for mod in regrtest.usemodules]) sopt = " ".join(pypy_options) - # experimental: always use regrverbose script - # previously we only did it if regrtest.outputpath() was True - # the regrverbose script now does the logic that CPython - # uses in its regrtest.py + # we use the regrverbose script to run the test, but don't get + # confused: it sets verbose to True only if regrtest.outputpath() + # is True, or if we pass the -v option to py.test. It contains + # the logic that CPython uses in its regrtest.py. regrrun = str(regr_script) - regrrun_verbosity = regrtest.getoutputpath() and '0' or '1' + if regrtest.getoutputpath() or pypy_option.verbose: + regrrun_verbosity = '1' + else: + regrrun_verbosity = '0' TIMEOUT = gettimeout() if option.use_compiled: From hpk at codespeak.net Sun Feb 11 18:40:46 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sun, 11 Feb 2007 18:40:46 +0100 (CET) Subject: [pypy-svn] r38493 - in pypy/dist/pypy/objspace/cpy: . test Message-ID: <20070211174046.70ADB100A0@code0.codespeak.net> Author: hpk Date: Sun Feb 11 18:40:45 2007 New Revision: 38493 Added: pypy/dist/pypy/objspace/cpy/test/conftest.py (contents, props changed) Modified: pypy/dist/pypy/objspace/cpy/__init__.py Log: skip tests for objspace/cpy if ctypes is not importable. Modified: pypy/dist/pypy/objspace/cpy/__init__.py ============================================================================== --- pypy/dist/pypy/objspace/cpy/__init__.py (original) +++ pypy/dist/pypy/objspace/cpy/__init__.py Sun Feb 11 18:40:45 2007 @@ -1,2 +1,8 @@ -from objspace import CPyObjSpace +try: + import ctypes as _ +except ImportError: + CPyObjSpace = None +else: + from objspace import CPyObjSpace + Space = CPyObjSpace Added: pypy/dist/pypy/objspace/cpy/test/conftest.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/objspace/cpy/test/conftest.py Sun Feb 11 18:40:45 2007 @@ -0,0 +1,13 @@ + +import py + +try: + import ctypes +except ImportError: + ctypes = None + +class Directory(py.test.collect.Directory): + def run(self): + if ctypes is None: + py.test.skip("no ctypes module available") + return super(Directory, self).run() From hpk at codespeak.net Sun Feb 11 18:41:25 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sun, 11 Feb 2007 18:41:25 +0100 (CET) Subject: [pypy-svn] r38494 - pypy/dist/pypy Message-ID: <20070211174125.5C28E100A2@code0.codespeak.net> Author: hpk Date: Sun Feb 11 18:41:24 2007 New Revision: 38494 Modified: pypy/dist/pypy/conftest.py Log: use sys-capturing (instead of fd) if we are running on top of PyPy (the previous appdirect check didn't make too much sense) Modified: pypy/dist/pypy/conftest.py ============================================================================== --- pypy/dist/pypy/conftest.py (original) +++ pypy/dist/pypy/conftest.py Sun Feb 11 18:41:24 2007 @@ -135,7 +135,7 @@ at the class) ourselves. """ def __init__(self, *args, **kwargs): - if option.runappdirect: + if hasattr(sys, 'pypy_objspaceclass'): option.conf_iocapture = "sys" # pypy cannot do FD-based super(Module, self).__init__(*args, **kwargs) From arigo at codespeak.net Sun Feb 11 18:44:54 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 11 Feb 2007 18:44:54 +0100 (CET) Subject: [pypy-svn] r38495 - pypy/dist/lib-python/modified-2.4.1/test Message-ID: <20070211174454.59BAF100A0@code0.codespeak.net> Author: arigo Date: Sun Feb 11 18:44:53 2007 New Revision: 38495 Added: pypy/dist/lib-python/modified-2.4.1/test/test_marshal.py - copied, changed from r38490, pypy/dist/lib-python/2.4.1/test/test_marshal.py Log: Two fixes: * close all files after usage * some tests were dumping and reloading an object but ignoring the result by accident From arigo at codespeak.net Sun Feb 11 19:02:38 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 11 Feb 2007 19:02:38 +0100 (CET) Subject: [pypy-svn] r38497 - pypy/dist/pypy/objspace/test Message-ID: <20070211180238.AB82F1009A@code0.codespeak.net> Author: arigo Date: Sun Feb 11 19:02:37 2007 New Revision: 38497 Modified: pypy/dist/pypy/objspace/test/test_descroperation.py Log: Oups. Modified: pypy/dist/pypy/objspace/test/test_descroperation.py ============================================================================== --- pypy/dist/pypy/objspace/test/test_descroperation.py (original) +++ pypy/dist/pypy/objspace/test/test_descroperation.py Sun Feb 11 19:02:37 2007 @@ -192,7 +192,7 @@ # this behavior changed in 2.4 #assert type(s.__dict__.keys()[0]) is str # don't store S keys #assert s.abc is s - getattr(s,s) is s + assert getattr(s,s) is s def test_notimplemented(self): #import types From arigo at codespeak.net Sun Feb 11 19:03:11 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 11 Feb 2007 19:03:11 +0100 (CET) Subject: [pypy-svn] r38498 - in pypy/dist/pypy/module/__builtin__: . test Message-ID: <20070211180311.5B8D7100A2@code0.codespeak.net> Author: arigo Date: Sun Feb 11 19:03:10 2007 New Revision: 38498 Modified: pypy/dist/pypy/module/__builtin__/operation.py pypy/dist/pypy/module/__builtin__/test/test_builtin.py Log: Systematically check attribute names for being strings, and convert them from unicode if necessary. Modified: pypy/dist/pypy/module/__builtin__/operation.py ============================================================================== --- pypy/dist/pypy/module/__builtin__/operation.py (original) +++ pypy/dist/pypy/module/__builtin__/operation.py Sun Feb 11 19:03:10 2007 @@ -24,22 +24,35 @@ "len(object) -> integer\n\nReturn the number of items of a sequence or mapping." return space.len(w_obj) + +def checkattrname(space, w_name): + # This is a check to ensure that getattr/setattr/delattr only pass a + # string to the rest of the code. XXX not entirely sure if these three + # functions are the only way for non-string objects to reach + # space.{get,set,del}attr()... + # Note that if w_name is already a string (or a subclass of str), + # it must be returned unmodified (and not e.g. unwrapped-rewrapped). + name = space.str_w(w_name) # typecheck + if not space.is_true(space.isinstance(w_name, space.w_type)): + w_name = space.wrap(name) # typically, w_name was a unicode string + return w_name + def delattr(space, w_object, w_name): """Delete a named attribute on an object. delattr(x, 'y') is equivalent to ``del x.y''.""" + w_name = checkattrname(space, w_name) space.delattr(w_object, w_name) return space.w_None def getattr(space, w_object, w_name, w_defvalue=NoneNotWrapped): """Get a named attribute from an object. getattr(x, 'y') is equivalent to ``x.y''.""" - if space.is_true(space.isinstance(w_name, space.w_unicode)): # xxx collect this logic somewhere - w_name = space.call_method(w_name, 'encode') + w_name = checkattrname(space, w_name) try: return space.getattr(w_object, w_name) except OperationError, e: - if e.match(space, space.w_AttributeError): - if w_defvalue is not None: + if w_defvalue is not None: + if e.match(space, space.w_AttributeError): return w_defvalue raise @@ -183,6 +196,7 @@ def setattr(space, w_object, w_name, w_val): """Store a named attribute into an object. setattr(x, 'y', z) is equivalent to ``x.y = z''.""" + w_name = checkattrname(space, w_name) space.setattr(w_object, w_name, w_val) return space.w_None Modified: pypy/dist/pypy/module/__builtin__/test/test_builtin.py ============================================================================== --- pypy/dist/pypy/module/__builtin__/test/test_builtin.py (original) +++ pypy/dist/pypy/module/__builtin__/test/test_builtin.py Sun Feb 11 19:03:10 2007 @@ -98,6 +98,18 @@ raises(AttributeError, getattr, a, u'k') assert getattr(a, u'k', 42) == 42 + def test_getattr_typecheck(self): + class A(object): + def __getattribute__(self, name): + pass + def __setattr__(self, name, value): + pass + def __delattr__(self, name): + pass + raises(TypeError, getattr, A(), 42) + raises(TypeError, setattr, A(), 42, 'x') + raises(TypeError, delattr, A(), 42) + def test_sum(self): assert sum([]) ==0 assert sum([42]) ==42 From arigo at codespeak.net Sun Feb 11 19:06:05 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 11 Feb 2007 19:06:05 +0100 (CET) Subject: [pypy-svn] r38499 - pypy/dist/lib-python/modified-2.4.1/test Message-ID: <20070211180605.18C4110081@code0.codespeak.net> Author: arigo Date: Sun Feb 11 19:06:04 2007 New Revision: 38499 Added: pypy/dist/lib-python/modified-2.4.1/test/test_os.py - copied, changed from r38495, pypy/dist/lib-python/2.4.1/test/test_os.py Log: More of the AttributeError-vs-TypeError kind. From arigo at codespeak.net Sun Feb 11 19:15:23 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 11 Feb 2007 19:15:23 +0100 (CET) Subject: [pypy-svn] r38500 - in pypy/dist: lib-python/modified-2.4.1/test pypy/module/posix Message-ID: <20070211181523.10FFB10081@code0.codespeak.net> Author: arigo Date: Sun Feb 11 19:15:21 2007 New Revision: 38500 Modified: pypy/dist/lib-python/modified-2.4.1/test/test_os.py pypy/dist/pypy/module/posix/app_posix.py Log: Try a bit to make os.stat_result like in CPython, but give up and disable the CPython test that checks for the very obscure details (IMHO). Modified: pypy/dist/lib-python/modified-2.4.1/test/test_os.py ============================================================================== --- pypy/dist/lib-python/modified-2.4.1/test/test_os.py (original) +++ pypy/dist/lib-python/modified-2.4.1/test/test_os.py Sun Feb 11 19:15:21 2007 @@ -143,7 +143,7 @@ # Use the stat_result constructor with a too-short tuple. try: result2 = os.stat_result((10,)) - self.fail("No exception thrown") + #self.fail("No exception thrown") - XXX very much a detail IMHO except TypeError: pass Modified: pypy/dist/pypy/module/posix/app_posix.py ============================================================================== --- pypy/dist/pypy/module/posix/app_posix.py (original) +++ pypy/dist/pypy/module/posix/app_posix.py Sun Feb 11 19:15:21 2007 @@ -22,6 +22,9 @@ st_atime = tuple_item_getter(7) st_mtime = tuple_item_getter(8) st_ctime = tuple_item_getter(9) + n_sequence_fields = 10 + n_fields = 10 # no extra attributes for now + n_unnamed_fields = 0 def fdopen(fd, mode='r', buffering=-1): """fdopen(fd [, mode='r' [, buffering]]) -> file_object From pedronis at codespeak.net Sun Feb 11 19:20:06 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sun, 11 Feb 2007 19:20:06 +0100 (CET) Subject: [pypy-svn] r38501 - pypy/dist/lib-python Message-ID: <20070211182006.192A01009B@code0.codespeak.net> Author: pedronis Date: Sun Feb 11 19:20:05 2007 New Revision: 38501 Modified: pypy/dist/lib-python/conftest.py Log: be more flexible in the handling of testdir, use the old standard skip error if the default was testresultdir is used without -C and the dir is not dir, if -C is used don't care if a result dir is not specified. If a non-default one is not specified simply report it's absensce. Modified: pypy/dist/lib-python/conftest.py ============================================================================== --- pypy/dist/lib-python/conftest.py (original) +++ pypy/dist/lib-python/conftest.py Sun Feb 11 19:20:05 2007 @@ -51,8 +51,9 @@ help="fail a test module after the given timeout. " "specify in seconds or 'NUMmp' aka Mega-Pystones"), Option('--resultdir', action="store", type="string", - default=str(testresultdir), dest="resultdir", - help="directory under which to store results in USER at HOST subdirs"), + default=None, dest="resultdir", + help="directory under which to store results in USER at HOST subdirs", + ), ) def gettimeout(): @@ -840,14 +841,26 @@ def ensuretestresultdir(): - testresultdir = py.path.local(option.resultdir) - if not testresultdir.check(dir=1): - py.test.skip("""'testresult' directory not found. - To run tests in reporting mode (without -E), you first have to - check it out as follows: - svn co http://codespeak.net/svn/pypy/testresult %s""" % ( - testresultdir, )) - return testresultdir + resultdir = option.resultdir + default_place = False + if resultdir is not None: + resultdir = py.path.local(option.resultdir) + else: + if option.use_compiled: + return None + default_place = True + resultdir = testresultdir + + if not resultdir.check(dir=1): + if default_place: + py.test.skip("""'testresult' directory not found. + To run tests in reporting mode (without -E), you first have to + check it out as follows: + svn co http://codespeak.net/svn/pypy/testresult %s""" % ( + testresultdir, )) + else: + py.test.skip("'%s' test result dir not found" % resultdir) + return resultdir # # testmethod: @@ -934,26 +947,29 @@ i am afraid. """ regrtest = self.parent.regrtest - testresultdir = ensuretestresultdir() result = self.getresult(regrtest) - resultdir = testresultdir.join(result['userhost']) - assert resultdir.ensure(dir=1) - - fn = resultdir.join(regrtest.basename).new(ext='.txt') - if result.istimeout(): - if fn.check(file=1): - try: - oldresult = ResultFromMime(fn) - except TypeError: - pass - else: - if not oldresult.istimeout(): - py.test.skip("timed out, not overwriting " - "more interesting non-timeout outcome") + testresultdir = ensuretestresultdir() + if testresultdir is not None: + resultdir = testresultdir.join(result['userhost']) + assert resultdir.ensure(dir=1) + + fn = resultdir.join(regrtest.basename).new(ext='.txt') + if result.istimeout(): + if fn.check(file=1): + try: + oldresult = ResultFromMime(fn) + except TypeError: + pass + else: + if not oldresult.istimeout(): + py.test.skip("timed out, not overwriting " + "more interesting non-timeout outcome") + + fn.write(result.repr_mimemessage().as_string(unixfrom=False)) - fn.write(result.repr_mimemessage().as_string(unixfrom=False)) if result['exit-status']: time.sleep(0.5) # time for a Ctrl-C to reach us :-) + print >>sys.stdout, result.getnamedtext('stdout') print >>sys.stderr, result.getnamedtext('stderr') py.test.fail("running test failed, see stderr output below") From pedronis at codespeak.net Sun Feb 11 19:26:01 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sun, 11 Feb 2007 19:26:01 +0100 (CET) Subject: [pypy-svn] r38502 - in pypy/dist/pypy: annotation objspace/std rpython/test translator/goal Message-ID: <20070211182601.67E3310087@code0.codespeak.net> Author: pedronis Date: Sun Feb 11 19:25:53 2007 New Revision: 38502 Modified: pypy/dist/pypy/annotation/specialize.py pypy/dist/pypy/objspace/std/intobject.py pypy/dist/pypy/rpython/test/test_rpbc.py pypy/dist/pypy/translator/goal/ann_override.py Log: oops, this code was using wrap on a tuple, it could get away with it because it was the only place left but well. Modified: pypy/dist/pypy/annotation/specialize.py ============================================================================== --- pypy/dist/pypy/annotation/specialize.py (original) +++ pypy/dist/pypy/annotation/specialize.py Sun Feb 11 19:25:53 2007 @@ -373,6 +373,16 @@ ## return funcdesc.cachedgraph(s1_type, alt_name='memo_%s' % funcdesc.name, ## builder=builder) +def make_constgraphbuilder(n, v=None, factory=None): + def constgraphbuilder(translator, ignore): + args = ','.join(["arg%d" % i for i in range(n)]) + if factory is not None: + v = factory() + miniglobals = {'v': v} + exec "constf = lambda %s: v" % args in miniglobals + return translator.buildflowgraph(miniglobals['constf']) + return constgraphbuilder + def specialize_argvalue(funcdesc, args_s, *argindices): key = tuple([args_s[i].const for i in argindices]) return funcdesc.cachedgraph(key) Modified: pypy/dist/pypy/objspace/std/intobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/intobject.py (original) +++ pypy/dist/pypy/objspace/std/intobject.py Sun Feb 11 19:25:53 2007 @@ -167,7 +167,8 @@ space.wrap("integer modulo")) # no overflow possible m = x % y - return space.wrap((z,m)) + w = space.wrap + return space.newtuple([w(z), w(m)]) def div__Int_Int(space, w_int1, w_int2): return _floordiv(space, w_int1, w_int2) 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 Sun Feb 11 19:25:53 2007 @@ -3,6 +3,7 @@ from pypy.rpython.ootypesystem import ootype from pypy.rpython.test.tool import BaseRtypingTest, LLRtypeMixin, OORtypeMixin + class MyBase: def m(self, x): return self.z + x @@ -1542,7 +1543,58 @@ assert self.ll_to_string(item0) == "hello" assert item1 == 623 + def test_folding_specialize_support(self): + + class S(object): + + def w(s, x): + if isinstance(x, int): + return x + if isinstance(x, str): + return len(x) + return -1 + w._annspecialcase_ = "specialize:w" + + def _freeze_(self): + return True + + s = S() + + def f(i, n): + w = s.w + if i == 0: + return w(0) + elif i == 1: + return w("abc") + elif i == 2: + return w(3*n) + elif i == 3: + return w(str(n)) + return -1 + + class P(policy.AnnotatorPolicy): + allow_someobjects = False + + def specialize__w(pol, funcdesc, args_s): + typ = args_s[1].knowntype + if args_s[0].is_constant() and args_s[1].is_constant(): + x = args_s[1].const + v = s.w(x) + builder = specialize.make_constgraphbuilder(2, v) + return funcdesc.cachedgraph(x, builder=builder) + return funcdesc.cachedgraph(typ) + p = P() + + res = self.interpret(f, [0, 66], policy=p) + assert res == 0 + res = self.interpret(f, [1, 66], policy=p) + assert res == 3 + res = self.interpret(f, [2, 4], policy=p) + assert res == 12 + res = self.interpret(f, [3, 5555], policy=p) + assert res == 4 + class TestLLtype(BaseTestRPBC, LLRtypeMixin): pass Modified: pypy/dist/pypy/translator/goal/ann_override.py ============================================================================== --- pypy/dist/pypy/translator/goal/ann_override.py (original) +++ pypy/dist/pypy/translator/goal/ann_override.py Sun Feb 11 19:25:53 2007 @@ -8,6 +8,10 @@ from pypy.annotation import specialize from pypy.interpreter import baseobjspace +def isidentifier(s): + if not s: return False + s = s.replace('_', 'x') + return s[0].isalpha() and s.isalnum() # patch - mostly for debugging, to enfore some signatures baseobjspace.ObjSpace.newbool.im_func._annenforceargs_ = Sig(lambda s1,s2: s1, @@ -45,7 +49,14 @@ def builder(translator, func): return translator.buildflowgraph(yield_thread) return funcdesc.cachedgraph(None, builder=builder) - + + def count(self, kind): + try: + counters = self.foldedwraps + except AttributeError: + counters = self.foldedwraps = {} + counters[kind] = counters.get(kind, 0) + 1 + def specialize__wrap(pol, funcdesc, args_s): from pypy.interpreter.baseobjspace import Wrappable from pypy.annotation.classdef import ClassDef @@ -56,6 +67,19 @@ typ = Wrappable else: assert not issubclass(typ, Wrappable) + if args_s[0].is_constant() and args_s[1].is_constant(): + if typ in (str, bool, int, float): + space = args_s[0].const + x = args_s[1].const + def fold(): + if typ is str and isidentifier(x): + pol.count('identifier') + return space.new_interned_str(x) + else: + pol.count(typ) + return space.wrap(x) + builder = specialize.make_constgraphbuilder(2, factory=fold) + return funcdesc.cachedgraph(x, builder=builder) return funcdesc.cachedgraph(typ) def attach_lookup(pol, t, attr): From pedronis at codespeak.net Sun Feb 11 19:28:34 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sun, 11 Feb 2007 19:28:34 +0100 (CET) Subject: [pypy-svn] r38503 - pypy/dist/pypy/translator/goal Message-ID: <20070211182834.1CA3510087@code0.codespeak.net> Author: pedronis Date: Sun Feb 11 19:28:33 2007 New Revision: 38503 Modified: pypy/dist/pypy/translator/goal/ann_override.py Log: the previous checkin contained (oh well) logic to fold wrap for constants of simple types at annotation time. Remove some statistics logic from that. Modified: pypy/dist/pypy/translator/goal/ann_override.py ============================================================================== --- pypy/dist/pypy/translator/goal/ann_override.py (original) +++ pypy/dist/pypy/translator/goal/ann_override.py Sun Feb 11 19:28:33 2007 @@ -50,13 +50,6 @@ return translator.buildflowgraph(yield_thread) return funcdesc.cachedgraph(None, builder=builder) - def count(self, kind): - try: - counters = self.foldedwraps - except AttributeError: - counters = self.foldedwraps = {} - counters[kind] = counters.get(kind, 0) + 1 - def specialize__wrap(pol, funcdesc, args_s): from pypy.interpreter.baseobjspace import Wrappable from pypy.annotation.classdef import ClassDef @@ -73,10 +66,8 @@ x = args_s[1].const def fold(): if typ is str and isidentifier(x): - pol.count('identifier') return space.new_interned_str(x) else: - pol.count(typ) return space.wrap(x) builder = specialize.make_constgraphbuilder(2, factory=fold) return funcdesc.cachedgraph(x, builder=builder) From arigo at codespeak.net Sun Feb 11 19:52:17 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 11 Feb 2007 19:52:17 +0100 (CET) Subject: [pypy-svn] r38507 - pypy/dist/pypy/objspace/std Message-ID: <20070211185217.F0B4210081@code0.codespeak.net> Author: arigo Date: Sun Feb 11 19:52:16 2007 New Revision: 38507 Modified: pypy/dist/pypy/objspace/std/complextype.py Log: Another try at writing complex.__new__(). This one follows the logic of CPython step-by-step... Modified: pypy/dist/pypy/objspace/std/complextype.py ============================================================================== --- pypy/dist/pypy/objspace/std/complextype.py (original) +++ pypy/dist/pypy/objspace/std/complextype.py Sun Feb 11 19:52:16 2007 @@ -107,43 +107,27 @@ return realpart, imagpart -def check_second_arg(space, w_c): - """check, if second 'complex' argument is a string""" - if space.is_true(space.isinstance(w_c, space.w_str)): - raise TypeError() - return True - -def simple_arg_check(space, w_r, w_c): - """check, if there is a second argument, if first is a string""" - if space.is_true(space.isinstance(w_r, space.w_str)) or \ - space.is_true(space.isinstance(w_r, space.w_unicode)): - if not space.eq_w(w_c,space.w_None): - raise TypeError - def descr__new__(space, w_complextype, w_real=0.0, w_imag=None): - from pypy.objspace.std.complexobject import W_ComplexObject - try: - check_second_arg(space, w_imag) - except TypeError: - raise OperationError(space.w_TypeError,space.wrap("complex() second arg can't be a string")) - try: - simple_arg_check(space, w_real, w_imag) - except TypeError: - raise OperationError(space.w_TypeError, space.wrap(ERR_WRONG_SECOND)) - # if arguments can be cast to a float, do it - if space.is_w(w_complextype, space.w_complex) and \ - space.eq_w(space.type(w_real), space.w_complex) and \ - space.eq_w(w_imag, space.w_None): - # common case - return w_real + # if w_real is already a complex number and there is no second + # argument, return it. Note that we cannot return w_real if + # it is an instance of a *subclass* of complex, or if w_complextype + # is itself a subclass of complex. + noarg2 = space.is_w(w_imag, space.w_None) + if (noarg2 and space.is_w(w_complextype, space.w_complex) + and space.is_w(space.type(w_real), space.w_complex)): + return w_real if space.is_true(space.isinstance(w_real, space.w_str)) or \ space.is_true(space.isinstance(w_real, space.w_unicode)): + # a string argument + if not noarg2: + raise OperationError(space.w_TypeError, + space.wrap("complex() can't take second arg" + " if first is a string")) try: realstr, imagstr = _split_complex(space.str_w(w_real)) - except ValueError: raise OperationError(space.w_ValueError, space.wrap(ERR_MALFORMED)) try: @@ -156,64 +140,62 @@ if abs(realval) == OVERFLOWED_FLOAT or abs(imagval) == OVERFLOWED_FLOAT: raise OperationError(space.w_ValueError,space.wrap( "complex() literal too large to convert")) - if space.is_w(w_complextype, space.w_complex): - # common case - w_obj = W_ComplexObject(realval, imagval) - else: - # We are dealing with a subclass of complex - w_obj = space.allocate_instance(W_ComplexObject, w_complextype) - W_ComplexObject.__init__(w_obj,realval, imagval) - - return w_obj - # w_imag is now either float or None - # w_real is either string, complex or float - # test for '__complex__' attribute and get result of - # __complex__ method - w_complex_first = extract_complex(space, w_real) - if not space.eq_w(w_complex_first, space.w_None): - w_real = w_complex_first - - # if w_real is a complex number and there is no second - # argument, return w_real after checking the type - if space.is_true(space.isinstance(w_real, space.w_complex)): - if not space.eq_w(w_imag, space.w_None): - if not space.is_true(space.isinstance(w_imag, space.w_complex)): - w_imag = space.call_function(space.w_float, w_imag) - w_tmp = space.newcomplex(0, 1) - w_tmp = space.mul(w_tmp, w_imag) - w_real = space.add(w_real, w_tmp) - - elif not space.is_true(space.isinstance(w_real, space.w_str)): - if space.eq_w(w_imag, space.w_None): - w_imag = space.wrap(0) - w_real = space.call_function(space.w_float,w_real) - if not space.is_true(space.isinstance(w_imag, space.w_complex)): - w_imag = space.call_function(space.w_float,w_imag) - tmp = space.newcomplex(0, 1) - w_imag = space.mul(w_imag, tmp) - w_real = space.add(w_real, w_imag) - assert isinstance(w_real, W_ComplexObject) - if space.is_w(w_complextype, space.w_complex): - # common case - w_obj = W_ComplexObject(w_real.realval, w_real.imagval) - else: - # We are dealing with a subclass of complex - w_obj = space.allocate_instance(W_ComplexObject, w_complextype) - W_ComplexObject.__init__(w_obj, w_real.realval, w_real.imagval) - return w_obj - -app = gateway.applevel(r""" -def extract_complex(num): - if not hasattr(num,'__complex__'): - return None - cnum = num.__complex__() - if isinstance(cnum,complex): - return cnum + else: - return None -""", filename=__file__) + # non-string arguments + + # test for a '__complex__' method, and call it if found. + # A bit of a hack to support old-style classes: don't use + # space.lookup() (this is similar to CPython). + try: + w_method = space.getattr(w_real, space.wrap('__complex__')) + except OperationError, e: + if not e.match(space, space.w_AttributeError): + raise + else: + w_real = space.call_function(w_method) + # __complex__() could return a string, which space.float() + # could accept below... Let's catch this case. + if space.is_true(space.isinstance(w_imag, space.w_str)) or \ + space.is_true(space.isinstance(w_imag, space.w_unicode)): + raise OperationError(space.w_TypeError, + space.wrap("__complex__() cannot return" + " a string")) + + # at this point w_real can be an instance of 'complex', + # either because it is the result of __complex__() or because + # the shortcut at the beginning of the function didn't match + if space.is_true(space.isinstance(w_real, space.w_complex)): + # note that we are unwrapping the complex for the rest of + # the code. This also ensures that we eventually return + # an object of the correct subclass of complex. + realval = space.float_w(space.getattr(w_real, space.wrap('real'))) + imagval = space.float_w(space.getattr(w_real, space.wrap('imag'))) + else: + realval = space.float_w(space.float(w_real)) + imagval = 0.0 -extract_complex = app.interphook('extract_complex') + # now take w_imag into account + if not noarg2: + if space.is_true(space.isinstance(w_imag, space.w_complex)): + # complex(x, y) == x+y*j, even if 'y' is already a complex. + # say y == a+b*j: + a = space.float_w(space.getattr(w_imag, space.wrap('real'))) + b = space.float_w(space.getattr(w_imag, space.wrap('imag'))) + realval -= b + imagval += a + elif space.is_true(space.isinstance(w_imag, space.w_str)) or \ + space.is_true(space.isinstance(w_imag, space.w_unicode)): + # prevent space.float(w_imag) from succeeding + raise OperationError(space.w_TypeError, + space.wrap("complex() second arg" + " can't be a string")) + else: + imagval += space.float_w(space.float(w_imag)) + # done + w_obj = space.allocate_instance(W_ComplexObject, w_complextype) + W_ComplexObject.__init__(w_obj, realval, imagval) + return w_obj def complexwprop(name): def fget(space, w_obj): From arigo at codespeak.net Sun Feb 11 19:56:58 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 11 Feb 2007 19:56:58 +0100 (CET) Subject: [pypy-svn] r38511 - pypy/dist/lib-python/modified-2.4.1/test Message-ID: <20070211185658.664381009C@code0.codespeak.net> Author: arigo Date: Sun Feb 11 19:56:56 2007 New Revision: 38511 Added: pypy/dist/lib-python/modified-2.4.1/test/test_iter.py - copied, changed from r38501, pypy/dist/lib-python/2.4.1/test/test_iter.py Log: A probably vain attempt at improving liveness tests by plugging some gc.collect(). From arigo at codespeak.net Sun Feb 11 20:07:20 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 11 Feb 2007 20:07:20 +0100 (CET) Subject: [pypy-svn] r38512 - in pypy/dist/pypy/module/__builtin__: . test Message-ID: <20070211190720.B5A8B1008D@code0.codespeak.net> Author: arigo Date: Sun Feb 11 20:07:19 2007 New Revision: 38512 Modified: pypy/dist/pypy/module/__builtin__/__init__.py pypy/dist/pypy/module/__builtin__/app_inspect.py pypy/dist/pypy/module/__builtin__/operation.py pypy/dist/pypy/module/__builtin__/test/test_builtin.py Log: Move hasattr() to interp-level. It's not really longer (it's shorter actually :-) and it allows proper handling of the UnicodeEncodeError that we get if the attribute name is a non-ASCII unicode string... Modified: pypy/dist/pypy/module/__builtin__/__init__.py ============================================================================== --- pypy/dist/pypy/module/__builtin__/__init__.py (original) +++ pypy/dist/pypy/module/__builtin__/__init__.py Sun Feb 11 20:07:19 2007 @@ -55,7 +55,6 @@ '_install_pickle_support_for_reversed_iterator': 'app_functional._install_pickle_support_for_reversed_iterator', - 'hasattr' : 'app_inspect.hasattr', 'globals' : 'app_inspect.globals', 'locals' : 'app_inspect.locals', 'vars' : 'app_inspect.vars', @@ -117,6 +116,7 @@ 'getattr' : 'operation.getattr', 'setattr' : 'operation.setattr', 'delattr' : 'operation.delattr', + 'hasattr' : 'operation.hasattr', 'iter' : 'operation.iter', 'id' : 'operation.id', '_seqiter' : 'operation._seqiter', Modified: pypy/dist/pypy/module/__builtin__/app_inspect.py ============================================================================== --- pypy/dist/pypy/module/__builtin__/app_inspect.py (original) +++ pypy/dist/pypy/module/__builtin__/app_inspect.py Sun Feb 11 20:07:19 2007 @@ -31,23 +31,6 @@ except AttributeError: raise TypeError, "vars() argument must have __dict__ attribute" -def hasattr(obj, attr): - """Check whether the object has an attribute with the given name.""" - try: - getattr(obj, attr) - return True - except TypeError: - # if 'attr' was not a string or unicode, let the TypeError through, - # else eat it - if isinstance(attr, basestring): - return False - else: - raise - except (KeyboardInterrupt, SystemExit): - raise - except: - return False - # Replaced by the interp-level helper space.callable(): ##def callable(ob): ## import __builtin__ # XXX this is insane but required for now for geninterp Modified: pypy/dist/pypy/module/__builtin__/operation.py ============================================================================== --- pypy/dist/pypy/module/__builtin__/operation.py (original) +++ pypy/dist/pypy/module/__builtin__/operation.py Sun Feb 11 20:07:19 2007 @@ -56,6 +56,20 @@ return w_defvalue raise +def hasattr(space, w_object, w_name): + """Return whether the object has an attribute with the given name. + (This is done by calling getattr(object, name) and catching exceptions.)""" + w_name = checkattrname(space, w_name) + try: + space.getattr(w_object, w_name) + except OperationError, e: + # a PyPy extension: let SystemExit and KeyboardInterrupt go through + if (e.match(space, space.w_SystemExit) or + e.match(space, space.w_KeyboardInterrupt)): + raise + return space.w_False + return space.w_True + def hash(space, w_object): """Return a hash value for the object. Two objects which compare as equal have the same hash value. It is possible, but unlikely, for Modified: pypy/dist/pypy/module/__builtin__/test/test_builtin.py ============================================================================== --- pypy/dist/pypy/module/__builtin__/test/test_builtin.py (original) +++ pypy/dist/pypy/module/__builtin__/test/test_builtin.py Sun Feb 11 20:07:19 2007 @@ -455,13 +455,14 @@ bac = property(broken2) x = X() x.foo = 42 - assert hasattr(x, '__class__') - assert hasattr(x, 'foo') - assert not hasattr(x, 'bar') - assert not hasattr(x, 'abc') # CPython compliance - assert not hasattr(x, 'bac') # CPython compliance + assert hasattr(x, '__class__') is True + assert hasattr(x, 'foo') is True + assert hasattr(x, 'bar') is False + assert hasattr(x, 'abc') is False # CPython compliance + assert hasattr(x, 'bac') is False # CPython compliance raises(TypeError, hasattr, x, None) raises(TypeError, hasattr, x, 42) + raises(UnicodeError, hasattr, x, u'\u5678') # cannot encode attr name class AppTestBuiltinOptimized(object): def setup_class(cls): From arigo at codespeak.net Sun Feb 11 20:09:13 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 11 Feb 2007 20:09:13 +0100 (CET) Subject: [pypy-svn] r38513 - pypy/dist/pypy/objspace/std Message-ID: <20070211190913.219401008D@code0.codespeak.net> Author: arigo Date: Sun Feb 11 20:09:12 2007 New Revision: 38513 Modified: pypy/dist/pypy/objspace/std/unicodeobject.py Log: Fix translation: 'unichar < unichar' is not RPython. Modified: pypy/dist/pypy/objspace/std/unicodeobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/unicodeobject.py (original) +++ pypy/dist/pypy/objspace/std/unicodeobject.py Sun Feb 11 20:09:12 2007 @@ -73,7 +73,8 @@ right = w_right._value for i in range(min(len(left), len(right))): if left[i] != right[i]: - return space.newbool(left[i] < right[i]) + return space.newbool(ord(left[i]) < ord(right[i])) + # NB. 'unichar < unichar' is not RPython at the moment return space.newbool(len(left) < len(right)) def ord__Unicode(space, w_uni): From arigo at codespeak.net Sun Feb 11 20:37:17 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 11 Feb 2007 20:37:17 +0100 (CET) Subject: [pypy-svn] r38515 - in pypy/dist/pypy/interpreter: . test Message-ID: <20070211193717.3F05010089@code0.codespeak.net> Author: arigo Date: Sun Feb 11 20:37:15 2007 New Revision: 38515 Modified: pypy/dist/pypy/interpreter/baseobjspace.py pypy/dist/pypy/interpreter/test/test_function.py Log: (pedronis, arigo) Fix the shortcut paths: for unbound methods, it was bypassing the check that the 1st argument is of the correct class. Modified: pypy/dist/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/dist/pypy/interpreter/baseobjspace.py (original) +++ pypy/dist/pypy/interpreter/baseobjspace.py Sun Feb 11 20:37:15 2007 @@ -578,7 +578,8 @@ func = w_func.w_function if isinstance(func, Function): return func.funccall(w_inst, *args_w) - else: + elif args_w and self.is_true( + self.abstract_isinstance(args_w[0], w_func.w_class)): w_func = w_func.w_function if isinstance(w_func, Function): @@ -597,7 +598,9 @@ func = w_func.w_function if isinstance(func, Function): return func.funccall_obj_valuestack(w_inst, nargs, frame) - else: + elif nargs > 0 and self.is_true( + self.abstract_isinstance(frame.peekvalue(nargs-1), # :-( + w_func.w_class)): w_func = w_func.w_function if isinstance(w_func, Function): 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 Feb 11 20:37:15 2007 @@ -254,6 +254,29 @@ im = new.instancemethod(A(), 3) assert map(im, [4]) == [7] + def test_unbound_typecheck(self): + class A(object): + def foo(self, *args): + return args + class B(A): + pass + class C(A): + pass + + assert A.foo(A(), 42) == (42,) + assert A.foo(B(), 42) == (42,) + raises(TypeError, A.foo, 5) + raises(TypeError, B.foo, C()) + try: + class Fun: + __metaclass__ = A.foo + assert 0 # should have raised + except TypeError: + pass + class Fun: + __metaclass__ = A().foo + assert Fun[:2] == ('Fun', ()) + class TestMethod: def setup_method(self, method): From arigo at codespeak.net Sun Feb 11 20:54:10 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 11 Feb 2007 20:54:10 +0100 (CET) Subject: [pypy-svn] r38517 - pypy/dist/pypy/translator Message-ID: <20070211195410.CE7401008D@code0.codespeak.net> Author: arigo Date: Sun Feb 11 20:54:09 2007 New Revision: 38517 Modified: pypy/dist/pypy/translator/geninterplevel.py Log: Use the official e.match() way of checking for exceptions. The issubtype() version doesn't work with e.g. old-style exception classes. Modified: pypy/dist/pypy/translator/geninterplevel.py ============================================================================== --- pypy/dist/pypy/translator/geninterplevel.py (original) +++ pypy/dist/pypy/translator/geninterplevel.py Sun Feb 11 20:54:09 2007 @@ -72,7 +72,7 @@ log = py.log.Producer("geninterp") py.log.setconsumer("geninterp", ansi_log) -GI_VERSION = '1.1.19' # bump this for substantial changes +GI_VERSION = '1.1.20' # bump this for substantial changes # ____________________________________________________________ try: @@ -1346,12 +1346,11 @@ # which goes to the last err%d_%d label written above. # Since we only have OperationError, we need to select: yield "except %s, e:" % (self.nameof(OperationError),) - yield " e.normalize_exception(space)" q = "if" for link in block.exits[1:]: assert issubclass(link.exitcase, py.builtin.BaseException) # Exeption classes come unwrapped in link.exitcase - yield " %s space.is_true(space.issubtype(e.w_type, %s)):" % (q, + yield " %s e.match(space, %s):" % (q, self.nameof(link.exitcase)) q = "elif" for op in self.gen_link(link, localscope, blocknum, block, { From arigo at codespeak.net Sun Feb 11 21:07:32 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 11 Feb 2007 21:07:32 +0100 (CET) Subject: [pypy-svn] r38521 - in pypy/dist/pypy/module/rctime: . test Message-ID: <20070211200732.925FC1009A@code0.codespeak.net> Author: arigo Date: Sun Feb 11 21:07:28 2007 New Revision: 38521 Modified: pypy/dist/pypy/module/rctime/interp_time.py pypy/dist/pypy/module/rctime/test/test_rctime.py Log: Details in rctime to make it pass the CPython test. Modified: pypy/dist/pypy/module/rctime/interp_time.py ============================================================================== --- pypy/dist/pypy/module/rctime/interp_time.py (original) +++ pypy/dist/pypy/module/rctime/interp_time.py Sun Feb 11 21:07:28 2007 @@ -199,14 +199,18 @@ w_module = space.getbuiltinmodule('time') space.setattr(w_module, space.wrap(obj_name), w_obj_value) -def _get_floattime(space, w_seconds): +def _get_inttime(space, w_seconds): # w_seconds can be a wrapped None (it will be automatically wrapped # in the callers, so we never get a real None here). if space.is_w(w_seconds, space.w_None): seconds = _floattime() else: seconds = space.float_w(w_seconds) - return seconds + try: + return ovfcheck_float_to_int(seconds) + except OverflowError: + raise OperationError(space.w_ValueError, + space.wrap("time argument too large")) def _tm_to_tuple(space, t): time_tuple = [] @@ -326,8 +330,8 @@ This is equivalent to asctime(localtime(seconds)). When the time tuple is not present, current time as returned by localtime() is used.""" - seconds = _get_floattime(space, w_seconds) - tt = time_t(int(seconds)) + seconds = _get_inttime(space, w_seconds) + tt = time_t(seconds) p = libc.ctime(byref(tt)) if not p: @@ -364,8 +368,8 @@ # rpython does not support that a variable has two incompatible builtins # as value so we have to duplicate the code. NOT GOOD! see localtime() too - seconds = _get_floattime(space, w_seconds) - whent = time_t(int(seconds)) + seconds = _get_inttime(space, w_seconds) + whent = time_t(seconds) p = libc.gmtime(byref(whent)) if not p: @@ -380,8 +384,8 @@ Convert seconds since the Epoch to a time tuple expressing local time. When 'seconds' is not passed in, convert the current time instead.""" - seconds = _get_floattime(space, w_seconds) - whent = time_t(int(seconds)) + seconds = _get_inttime(space, w_seconds) + whent = time_t(seconds) p = libc.localtime(byref(whent)) if not p: @@ -424,7 +428,7 @@ _set_module_object(space, "timezone", space.wrap(timezone)) _set_module_object(space, 'daylight', space.wrap(daylight)) tzname_w = [space.wrap(tzname[0]), space.wrap(tzname[1])] - _set_module_object(space, 'tzname', space.newlist(tzname_w)) + _set_module_object(space, 'tzname', space.newtuple(tzname_w)) _set_module_object(space, 'altzone', space.wrap(altzone)) tzset.unwrap_spec = [ObjSpace] Modified: pypy/dist/pypy/module/rctime/test/test_rctime.py ============================================================================== --- pypy/dist/pypy/module/rctime/test/test_rctime.py (original) +++ pypy/dist/pypy/module/rctime/test/test_rctime.py Sun Feb 11 21:07:28 2007 @@ -43,6 +43,7 @@ res = rctime.ctime(0) assert isinstance(res, str) rctime.ctime(rctime.time()) + raises(ValueError, rctime.ctime, 1E200) def test_gmtime(self): import time as rctime @@ -171,7 +172,7 @@ os.environ['TZ'] = eastern rctime.tzset() assert rctime.gmtime(xmas2002) != rctime.localtime(xmas2002) - assert rctime.tzname == ['EST', 'EDT'] + assert rctime.tzname == ('EST', 'EDT') assert len(rctime.tzname) == 2 assert rctime.daylight == 1 assert rctime.timezone == 18000 From arigo at codespeak.net Sun Feb 11 21:30:49 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 11 Feb 2007 21:30:49 +0100 (CET) Subject: [pypy-svn] r38522 - pypy/dist/pypy/translator Message-ID: <20070211203049.5E15B10089@code0.codespeak.net> Author: arigo Date: Sun Feb 11 21:30:47 2007 New Revision: 38522 Modified: pypy/dist/pypy/translator/geninterplevel.py Log: Oups, the normalizeexception() is needed. Modified: pypy/dist/pypy/translator/geninterplevel.py ============================================================================== --- pypy/dist/pypy/translator/geninterplevel.py (original) +++ pypy/dist/pypy/translator/geninterplevel.py Sun Feb 11 21:30:47 2007 @@ -72,7 +72,7 @@ log = py.log.Producer("geninterp") py.log.setconsumer("geninterp", ansi_log) -GI_VERSION = '1.1.20' # bump this for substantial changes +GI_VERSION = '1.1.21' # bump this for substantial changes # ____________________________________________________________ try: @@ -1346,6 +1346,7 @@ # which goes to the last err%d_%d label written above. # Since we only have OperationError, we need to select: yield "except %s, e:" % (self.nameof(OperationError),) + yield " e.normalize_exception(space)" q = "if" for link in block.exits[1:]: assert issubclass(link.exitcase, py.builtin.BaseException) From arigo at codespeak.net Sun Feb 11 22:05:42 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 11 Feb 2007 22:05:42 +0100 (CET) Subject: [pypy-svn] r38523 - pypy/dist/pypy/interpreter/astcompiler Message-ID: <20070211210542.4DC5C10098@code0.codespeak.net> Author: arigo Date: Sun Feb 11 22:05:41 2007 New Revision: 38523 Modified: pypy/dist/pypy/interpreter/astcompiler/pycodegen.py pypy/dist/pypy/interpreter/astcompiler/symbols.py Log: Try harder to generate the correct SyntaxError in case of 'return arg' and 'yield arg' in the same function. Modified: pypy/dist/pypy/interpreter/astcompiler/pycodegen.py ============================================================================== --- pypy/dist/pypy/interpreter/astcompiler/pycodegen.py (original) +++ pypy/dist/pypy/interpreter/astcompiler/pycodegen.py Sun Feb 11 22:05:41 2007 @@ -1096,8 +1096,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.value.accept( self ) self.emit('RETURN_VALUE') @@ -1407,6 +1405,10 @@ self.graph.setCellVars(self.scope.get_cell_vars()) if self.scope.generator: self.graph.setFlag(CO_GENERATOR) + if self.scope.return_with_arg is not None: + node = self.scope.return_with_arg + raise SyntaxError("'return' with argument inside generator", + node.lineno) class GenExprCodeGenerator(AbstractFunctionCode): Modified: pypy/dist/pypy/interpreter/astcompiler/symbols.py ============================================================================== --- pypy/dist/pypy/interpreter/astcompiler/symbols.py (original) +++ pypy/dist/pypy/interpreter/astcompiler/symbols.py Sun Feb 11 22:05:41 2007 @@ -64,7 +64,7 @@ self.varroles[name] = ROLE_GLOBAL return prevrole - def add_return(self): + def add_return(self, node): raise SyntaxError("'return' outside function") def add_yield(self): @@ -217,6 +217,7 @@ class FunctionScope(Scope): generator = False + return_with_arg = None # or the node def add_param(self, name): name = self.mangle(name) @@ -225,8 +226,11 @@ raise SyntaxError(msg) self.varroles[name] = ROLE_PARAM - def add_return(self): - pass + def add_return(self, node): + if node.value is not None: + # record the first 'return expr' that we see, for error checking + if self.return_with_arg is None: + self.return_with_arg = node def add_yield(self): self.generator = True @@ -563,7 +567,7 @@ def visitReturn(self, node): scope = self.cur_scope() - scope.add_return() + scope.add_return(node) if node.value is not None: node.value.accept(self) From pedronis at codespeak.net Mon Feb 12 12:22:00 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Mon, 12 Feb 2007 12:22:00 +0100 (CET) Subject: [pypy-svn] r38544 - in pypy/dist/pypy: annotation rpython/test Message-ID: <20070212112200.5F3B2100A4@code0.codespeak.net> Author: pedronis Date: Mon Feb 12 12:21:58 2007 New Revision: 38544 Modified: pypy/dist/pypy/annotation/specialize.py pypy/dist/pypy/rpython/test/test_rpbc.py Log: sense++ (trying at least) Modified: pypy/dist/pypy/annotation/specialize.py ============================================================================== --- pypy/dist/pypy/annotation/specialize.py (original) +++ pypy/dist/pypy/annotation/specialize.py Mon Feb 12 12:21:58 2007 @@ -377,8 +377,10 @@ def constgraphbuilder(translator, ignore): args = ','.join(["arg%d" % i for i in range(n)]) if factory is not None: - v = factory() - miniglobals = {'v': v} + computed_v = factory() + else: + computed_v = v + miniglobals = {'v': computed_v} exec "constf = lambda %s: v" % args in miniglobals return translator.buildflowgraph(miniglobals['constf']) return constgraphbuilder 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 Mon Feb 12 12:21:58 2007 @@ -2,7 +2,7 @@ from pypy.rpython.rtyper import RPythonTyper from pypy.rpython.ootypesystem import ootype from pypy.rpython.test.tool import BaseRtypingTest, LLRtypeMixin, OORtypeMixin - +from pypy.annotation import policy, specialize class MyBase: def m(self, x): From auc at codespeak.net Mon Feb 12 12:33:09 2007 From: auc at codespeak.net (auc at codespeak.net) Date: Mon, 12 Feb 2007 12:33:09 +0100 (CET) Subject: [pypy-svn] r38545 - pypy/dist/pypy/doc Message-ID: <20070212113309.09196100A4@code0.codespeak.net> Author: auc Date: Mon Feb 12 12:33:08 2007 New Revision: 38545 Modified: pypy/dist/pypy/doc/objspace-proxies.txt Log: remove refs to obsolete docs Modified: pypy/dist/pypy/doc/objspace-proxies.txt ============================================================================== --- pypy/dist/pypy/doc/objspace-proxies.txt (original) +++ pypy/dist/pypy/doc/objspace-proxies.txt Mon Feb 12 12:33:08 2007 @@ -127,23 +127,12 @@ eventually put a value into the object. In practice, this works well with microthreads instead of real threads (see `Stackless features`_). -Two somewhat outdated documents describe the Logic Object Space in more -details: +The `EU Interim Report`_ (PDF) describes the Logic Object Space in +more details. -* `How to use the Logic Object space features of PyPy 0.9`_; -* `EU Interim Report`_ (PDF). - -The following document is a draft: - -* `Ideas about syntactic and algorithmic aspects of Constraint and Logic - Programming in Python`_ - -.. _`Ideas about syntactic and algorithmic aspects of Constraint and Logic Programming in Python`: constraints-and-logic.html -.. _`How to use the Logic Object space features of PyPy 0.9`: howto-logicobjspace-0.9.html .. _`EU Interim Report`: http://codespeak.net/pypy/extradoc/eu-report/D09.1_Constraint_Solving_and_Semantic_Web-interim-2006-07-28.pdf .. _`Stackless features`: stackless.html - .. _taint: The Taint Object Space From pedronis at codespeak.net Mon Feb 12 12:52:28 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Mon, 12 Feb 2007 12:52:28 +0100 (CET) Subject: [pypy-svn] r38547 - pypy/dist/pypy/translator/goal Message-ID: <20070212115228.1A7C1100A4@code0.codespeak.net> Author: pedronis Date: Mon Feb 12 12:52:27 2007 New Revision: 38547 Modified: pypy/dist/pypy/translator/goal/ann_override.py Log: python equality alone is not going to do us any good here. Modified: pypy/dist/pypy/translator/goal/ann_override.py ============================================================================== --- pypy/dist/pypy/translator/goal/ann_override.py (original) +++ pypy/dist/pypy/translator/goal/ann_override.py Mon Feb 12 12:52:27 2007 @@ -70,7 +70,7 @@ else: return space.wrap(x) builder = specialize.make_constgraphbuilder(2, factory=fold) - return funcdesc.cachedgraph(x, builder=builder) + return funcdesc.cachedgraph((typ, x), builder=builder) return funcdesc.cachedgraph(typ) def attach_lookup(pol, t, attr): From arigo at codespeak.net Mon Feb 12 13:38:17 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 12 Feb 2007 13:38:17 +0100 (CET) Subject: [pypy-svn] r38551 - pypy/dist/lib-python Message-ID: <20070212123817.47B4D100A3@code0.codespeak.net> Author: arigo Date: Mon Feb 12 13:38:16 2007 New Revision: 38551 Modified: pypy/dist/lib-python/conftest.py Log: Got the logic wrong: verbose mode must be *disabled* for output tests, not enabled. Modified: pypy/dist/lib-python/conftest.py ============================================================================== --- pypy/dist/lib-python/conftest.py (original) +++ pypy/dist/lib-python/conftest.py Mon Feb 12 13:38:16 2007 @@ -913,11 +913,13 @@ ['--withmod-%s' % mod for mod in regrtest.usemodules]) sopt = " ".join(pypy_options) # we use the regrverbose script to run the test, but don't get - # confused: it sets verbose to True only if regrtest.outputpath() - # is True, or if we pass the -v option to py.test. It contains - # the logic that CPython uses in its regrtest.py. + # confused: it still doesn't set verbose to True by default if + # regrtest.outputpath() is true, because output tests get confused + # in verbose mode. You can always force verbose mode by passing + # the -v option to py.test. The regrverbose script contains the + # logic that CPython uses in its regrtest.py. regrrun = str(regr_script) - if regrtest.getoutputpath() or pypy_option.verbose: + if not regrtest.getoutputpath() or pypy_option.verbose: regrrun_verbosity = '1' else: regrrun_verbosity = '0' From arigo at codespeak.net Mon Feb 12 13:38:30 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 12 Feb 2007 13:38:30 +0100 (CET) Subject: [pypy-svn] r38552 - pypy/dist/lib-python/modified-2.4.1/test Message-ID: <20070212123830.91055100AD@code0.codespeak.net> Author: arigo Date: Mon Feb 12 13:38:28 2007 New Revision: 38552 Modified: pypy/dist/lib-python/modified-2.4.1/test/test_builtin.py Log: Don't check this detail of CPython. Modified: pypy/dist/lib-python/modified-2.4.1/test/test_builtin.py ============================================================================== --- pypy/dist/lib-python/modified-2.4.1/test/test_builtin.py (original) +++ pypy/dist/lib-python/modified-2.4.1/test/test_builtin.py Mon Feb 12 13:38:28 2007 @@ -284,7 +284,9 @@ self.assertEqual(eval('dir()', g, m), list('xyz')) self.assertEqual(eval('globals()', g, m), g) self.assertEqual(eval('locals()', g, m), m) - self.assertRaises(TypeError, eval, 'a', m) + # the following line checks a detail of CPython: the globals() of + # any frame must be a real dictionary + #self.assertRaises(TypeError, eval, 'a', m) class A: "Non-mapping" pass From alix at codespeak.net Mon Feb 12 14:01:26 2007 From: alix at codespeak.net (alix at codespeak.net) Date: Mon, 12 Feb 2007 14:01:26 +0100 (CET) Subject: [pypy-svn] r38556 - pypy/extradoc/sprintinfo/trillke-2007 Message-ID: <20070212130126.0C7CB100AD@code0.codespeak.net> Author: alix Date: Mon Feb 12 14:01:12 2007 New Revision: 38556 Modified: pypy/extradoc/sprintinfo/trillke-2007/people.txt Log: registered myself for the trillke-sprint full time. Modified: pypy/extradoc/sprintinfo/trillke-2007/people.txt ============================================================================== --- pypy/extradoc/sprintinfo/trillke-2007/people.txt (original) +++ pypy/extradoc/sprintinfo/trillke-2007/people.txt Mon Feb 12 14:01:12 2007 @@ -21,6 +21,7 @@ Samuele Pedroni 25th-5th TBD Anders Chrigstr?m 25th-5th TBD Christian Tismer 28th-5th Klocke +Alix Einfeldt 25th-5th private ==================== ============== ===================== People on the following list were present at previous sprints: From pedronis at codespeak.net Mon Feb 12 14:09:27 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Mon, 12 Feb 2007 14:09:27 +0100 (CET) Subject: [pypy-svn] r38557 - pypy/dist/pypy/rpython/ootypesystem/test Message-ID: <20070212130927.BA812100A3@code0.codespeak.net> Author: pedronis Date: Mon Feb 12 14:09:26 2007 New Revision: 38557 Modified: pypy/dist/pypy/rpython/ootypesystem/test/test_bltann.py Log: skip this "wish" test for now Modified: pypy/dist/pypy/rpython/ootypesystem/test/test_bltann.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/test/test_bltann.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/test/test_bltann.py Mon Feb 12 14:09:26 2007 @@ -142,6 +142,8 @@ assert a.translator._graphof(callback) def test_callback_field_bound_method(): + py.test.skip("needs an rtyping hack to help the js backend " + "or generalized bound methods support in many places") class A: def x(self, i): return float(i) From mwh at codespeak.net Mon Feb 12 14:11:01 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Mon, 12 Feb 2007 14:11:01 +0100 (CET) Subject: [pypy-svn] r38558 - pypy/dist/pypy/module/posix Message-ID: <20070212131101.2DC85100B0@code0.codespeak.net> Author: mwh Date: Mon Feb 12 14:11:00 2007 New Revision: 38558 Modified: pypy/dist/pypy/module/posix/__init__.py Log: remove os.execv if building with llvm at least this lets pypy-llvm build again... Modified: pypy/dist/pypy/module/posix/__init__.py ============================================================================== --- pypy/dist/pypy/module/posix/__init__.py (original) +++ pypy/dist/pypy/module/posix/__init__.py Mon Feb 12 14:11:00 2007 @@ -87,6 +87,8 @@ # YYY nor does it anywhere else #if config.translating and config.translation.type_system != "lltype": # space.delattr(self, space.wrap("execve")) + if config.translating and config.translation.backend == "llvm": + space.delattr(self, space.wrap("execv")) for constant in dir(os): value = getattr(os, constant) From ac at codespeak.net Mon Feb 12 14:34:30 2007 From: ac at codespeak.net (ac at codespeak.net) Date: Mon, 12 Feb 2007 14:34:30 +0100 (CET) Subject: [pypy-svn] r38561 - pypy/dist/lib-python/modified-2.4.1/test Message-ID: <20070212133430.34F91100AB@code0.codespeak.net> Author: ac Date: Mon Feb 12 14:34:29 2007 New Revision: 38561 Modified: pypy/dist/lib-python/modified-2.4.1/test/test_file.py Log: More garbage collection. Modified: pypy/dist/lib-python/modified-2.4.1/test/test_file.py ============================================================================== --- pypy/dist/lib-python/modified-2.4.1/test/test_file.py (original) +++ pypy/dist/lib-python/modified-2.4.1/test/test_file.py Mon Feb 12 14:34:29 2007 @@ -15,6 +15,7 @@ f.close() f = None gc.collect() +gc.collect() try: p.tell() except ReferenceError: From arigo at codespeak.net Mon Feb 12 15:00:23 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 12 Feb 2007 15:00:23 +0100 (CET) Subject: [pypy-svn] r38562 - in pypy/dist/pypy/lib: . app_test Message-ID: <20070212140023.07ADA100AF@code0.codespeak.net> Author: arigo Date: Mon Feb 12 15:00:21 2007 New Revision: 38562 Added: pypy/dist/pypy/lib/_structseq.py (contents, props changed) pypy/dist/pypy/lib/app_test/test_structseq.py (contents, props changed) Log: A structseqtype metaclass that can be used at app-level to build these 'structseq'-like quasi-tuple things that CPython returns for os.stat() or time.localtime(). Added: pypy/dist/pypy/lib/_structseq.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/lib/_structseq.py Mon Feb 12 15:00:21 2007 @@ -0,0 +1,101 @@ +""" +Implementation helper: a struct that looks like a tuple. See timemodule +and posixmodule for example uses. +""" + +class structseqfield(object): + """Definition of field of a structseq. The 'index' is for positional + tuple-like indexing. Fields whose index is after a gap in the numbers + cannot be accessed like this, but only by name. + """ + def __init__(self, index, doc=None, default=lambda self: None): + self.__name__ = '?' + self.index = index # patched to None if not positional + self._index = index + self.__doc__ = doc + self._default = default + + def __repr__(self): + return '' % (self.__name__, + self.__doc__ or 'undocumented') + + def __get__(self, obj, typ=None): + if obj is None: + return self + if self.index is None: + return obj.__dict__[self.__name__] + else: + return obj[self.index] + + def __set__(self, obj, value): + raise TypeError("readonly attribute") + + +class structseqtype(type): + + def __new__(metacls, classname, bases, dict): + assert not bases + fields_by_index = {} + for name, field in dict.items(): + if isinstance(field, structseqfield): + assert field._index not in fields_by_index + fields_by_index[field._index] = field + field.__name__ = name + dict['n_fields'] = len(fields_by_index) + + extra_fields = fields_by_index.items() + extra_fields.sort() + n_sequence_fields = 0 + while extra_fields and extra_fields[0][0] == n_sequence_fields: + extra_fields.pop(0) + n_sequence_fields += 1 + dict['n_sequence_fields'] = n_sequence_fields + + extra_fields = [field for index, field in extra_fields] + for field in extra_fields: + field.index = None # no longer relevant + + assert '__new__' not in dict + dict['_extra_fields'] = tuple(extra_fields) + dict['__new__'] = structseq_new + dict['__reduce__'] = structseq_reduce + return type.__new__(metacls, classname, (tuple,), dict) + + +builtin_dict = dict + +def structseq_new(cls, sequence, dict={}): + sequence = tuple(sequence) + dict = builtin_dict(dict) + N = cls.n_sequence_fields + if len(sequence) < N: + if N < cls.n_fields: + msg = "at least" + else: + msg = "exactly" + raise TypeError("expected a sequence with %s %d items" % ( + msg, N)) + if len(sequence) > N: + if len(sequence) > cls.n_fields: + if N < cls.n_fields: + msg = "at most" + else: + msg = "exactly" + raise TypeError("expected a sequence with %s %d items" % ( + msg, cls.n_fields)) + for field, value in zip(cls._extra_fields, sequence[N:]): + name = field.__name__ + if name in dict: + raise TypeError("duplicate value for %r" % (name,)) + dict[name] = value + sequence = sequence[:N] + result = tuple.__new__(cls, sequence) + result.__dict__ = dict + for field in cls._extra_fields: + name = field.__name__ + if name not in dict: + dict[name] = field._default(result) + return result + +def structseq_reduce(self): + return type(self), (tuple(self), self.__dict__) Added: pypy/dist/pypy/lib/app_test/test_structseq.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/lib/app_test/test_structseq.py Mon Feb 12 15:00:21 2007 @@ -0,0 +1,74 @@ +import py +from pypy.lib._structseq import * + + +class mydata: + __metaclass__ = structseqtype + + st_mode = structseqfield(0, "protection bits") + st_ino = structseqfield(1) + st_dev = structseqfield(2) + st_nlink = structseqfield(3) + st_uid = structseqfield(4) + st_gid = structseqfield(5) + st_size = structseqfield(6) + _st_atime_as_int = structseqfield(7) + _st_mtime_as_int = structseqfield(8) + _st_ctime_as_int = structseqfield(9) + # skip to higher numbers for fields not part of the sequence. + # the numbers are only used to ordering + st_rdev = structseqfield(50, "device type (if inode device)") + st_atime = structseqfield(57, default=lambda self: self._st_atime_as_int) + st_mtime = structseqfield(58, default=lambda self: self._st_mtime_as_int) + st_ctime = structseqfield(59, default=lambda self: self._st_ctime_as_int) + + +def test_class(): + assert mydata.st_mode.__doc__ == "protection bits" + assert mydata.n_fields == 14 + assert mydata.n_sequence_fields == 10 + +def test_mydata(): + x = mydata(range(100, 111)) + assert x.n_sequence_fields == type(x).n_sequence_fields == 10 + assert x.n_fields == type(x).n_fields == 14 + assert x.st_mode == 100 + assert x.st_size == 106 + assert x.st_ctime == 109 # copied by the default=lambda... + assert x.st_rdev == 110 + assert len(x) == 10 + assert list(x) == range(100, 110) + assert x + (5,) == tuple(range(100, 110)) + (5,) + assert x[4:12:2] == (104, 106, 108) + assert 104 in x + assert 110 not in x + +def test_default_None(): + x = mydata(range(100, 110)) + assert x.st_rdev is None + +def test_constructor(): + x = mydata(range(100, 111), {'st_mtime': 12.25}) + assert x[8] == 108 + assert x.st_mtime == 12.25 + +def test_compare_like_tuple(): + x = mydata(range(100, 111)) + y = mydata(range(100, 110) + [555]) + assert x == tuple(range(100, 110)) + assert x == y # blame CPython + assert hash(x) == hash(y) == hash(tuple(range(100, 110))) + +def test_pickle(): + import pickle + x = mydata(range(100, 111)) + s = pickle.dumps(x) + y = pickle.loads(s) + assert x == y + assert x.st_rdev == y.st_rdev == 110 + +def test_readonly(): + x = mydata(range(100, 113)) + py.test.raises((TypeError, AttributeError), "x.st_mode = 1") + py.test.raises((TypeError, AttributeError), "x.st_mtime = 1") + py.test.raises((TypeError, AttributeError), "x.st_rdev = 1") From pedronis at codespeak.net Mon Feb 12 15:07:45 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Mon, 12 Feb 2007 15:07:45 +0100 (CET) Subject: [pypy-svn] r38563 - pypy/dist/pypy/module/thread/rpython/test Message-ID: <20070212140745.0CC4B100A6@code0.codespeak.net> Author: pedronis Date: Mon Feb 12 15:07:44 2007 New Revision: 38563 Modified: pypy/dist/pypy/module/thread/rpython/test/test_ll_thread.py Log: import py to have skipping work for real Modified: pypy/dist/pypy/module/thread/rpython/test/test_ll_thread.py ============================================================================== --- pypy/dist/pypy/module/thread/rpython/test/test_ll_thread.py (original) +++ pypy/dist/pypy/module/thread/rpython/test/test_ll_thread.py Mon Feb 12 15:07:44 2007 @@ -1,3 +1,5 @@ +import py + try: import thread except ImportError: From arigo at codespeak.net Mon Feb 12 15:30:06 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 12 Feb 2007 15:30:06 +0100 (CET) Subject: [pypy-svn] r38564 - pypy/dist/pypy/module/posix/test Message-ID: <20070212143006.62AAA100A8@code0.codespeak.net> Author: arigo Date: Mon Feb 12 15:30:05 2007 New Revision: 38564 Modified: pypy/dist/pypy/module/posix/test/test_posix2.py Log: Workaround for inspect.getsource(). 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 Mon Feb 12 15:30:05 2007 @@ -111,6 +111,7 @@ pid1, status1 = os.waitpid(pid, 0) assert pid1 == pid # XXX check status1 + pass # <- please, inspect.getsource(), don't crash if hasattr(__import__(os.name), "execv"): # and fork def test_execv(self): @@ -135,6 +136,7 @@ os.waitpid(pid, 0) assert open("onefile").read() == "xxx" os.unlink("onefile") + pass # <- please, inspect.getsource(), don't crash if hasattr(__import__(os.name), 'popen'): def test_popen(self): From arigo at codespeak.net Mon Feb 12 15:48:00 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 12 Feb 2007 15:48:00 +0100 (CET) Subject: [pypy-svn] r38565 - pypy/dist/pypy/objspace/cpy Message-ID: <20070212144800.4C1541009B@code0.codespeak.net> Author: arigo Date: Mon Feb 12 15:47:59 2007 New Revision: 38565 Modified: pypy/dist/pypy/objspace/cpy/objspace.py Log: Add a dummy implementation to make test_complete happy. Modified: pypy/dist/pypy/objspace/cpy/objspace.py ============================================================================== --- pypy/dist/pypy/objspace/cpy/objspace.py (original) +++ pypy/dist/pypy/objspace/cpy/objspace.py Mon Feb 12 15:47:59 2007 @@ -179,6 +179,9 @@ buf[i] = p[i] return buf.raw + def unichars_w(self, w_obj): + not_implemented_sorry + def call_function(self, w_callable, *args_w): args_w += (None,) return PyObject_CallFunctionObjArgs(w_callable, *args_w) From ac at codespeak.net Mon Feb 12 15:48:50 2007 From: ac at codespeak.net (ac at codespeak.net) Date: Mon, 12 Feb 2007 15:48:50 +0100 (CET) Subject: [pypy-svn] r38566 - pypy/dist/lib-python/modified-2.4.1/test Message-ID: <20070212144850.CDB0E100AB@code0.codespeak.net> Author: ac Date: Mon Feb 12 15:48:50 2007 New Revision: 38566 Modified: pypy/dist/lib-python/modified-2.4.1/test/test_weakref.py Log: Collect more garbage! Modified: pypy/dist/lib-python/modified-2.4.1/test/test_weakref.py ============================================================================== --- pypy/dist/lib-python/modified-2.4.1/test/test_weakref.py (original) +++ pypy/dist/lib-python/modified-2.4.1/test/test_weakref.py Mon Feb 12 15:48:50 2007 @@ -68,6 +68,8 @@ ref2 = weakref.ref(o, self.callback) del o gc.collect() + gc.collect() + gc.collect() self.assert_(ref1() is None, "expected reference to be invalidated") self.assert_(ref2() is None, @@ -127,6 +129,8 @@ ref = weakref.ref(o, self.callback) del o gc.collect() + gc.collect() + gc.collect() self.assert_(self.cbcalled == 1, "callback did not properly set 'cbcalled'") self.assert_(ref() is None, @@ -314,6 +318,8 @@ ref2 = weakref.ref(o, self.callback) del ref2 gc.collect() + gc.collect() + gc.collect() self.assert_(weakref.getweakrefs(o) == [ref1], "list of refs does not match") @@ -749,6 +755,8 @@ "deleting object did not cause dictionary update") del objects, o gc.collect() + gc.collect() + gc.collect() self.assert_(len(dict) == 0, "deleting the values did not clear the dictionary") # regression on SF bug #447152: @@ -756,6 +764,8 @@ self.assertRaises(KeyError, dict.__getitem__, 1) dict[2] = C() gc.collect() + gc.collect() + gc.collect() self.assertRaises(KeyError, dict.__getitem__, 2) def test_weak_keys(self): @@ -776,6 +786,8 @@ "cloning of weak-keyed dictionary did not work!") del items1, items2 gc.collect() + gc.collect() + gc.collect() self.assert_(len(dict) == self.COUNT) del objects[0] gc.collect() From arigo at codespeak.net Mon Feb 12 15:49:54 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 12 Feb 2007 15:49:54 +0100 (CET) Subject: [pypy-svn] r38567 - in pypy/dist/pypy: interpreter module/posix module/posix/test module/rctime module/rctime/test Message-ID: <20070212144954.80171100AB@code0.codespeak.net> Author: arigo Date: Mon Feb 12 15:49:52 2007 New Revision: 38567 Modified: pypy/dist/pypy/interpreter/mixedmodule.py pypy/dist/pypy/module/posix/app_posix.py pypy/dist/pypy/module/posix/test/test_posix2.py pypy/dist/pypy/module/rctime/app_time.py pypy/dist/pypy/module/rctime/test/test_rctime.py Log: Use _structseq for stat_result and struct_time. Add pickling tests. Remove the interp-level import of the app_* files that mixedmodule is doing for a reason that is no longer obvious (and which fails if the app_* file is trying to import something that implicitly comes from pypy/lib/). Modified: pypy/dist/pypy/interpreter/mixedmodule.py ============================================================================== --- pypy/dist/pypy/interpreter/mixedmodule.py (original) +++ pypy/dist/pypy/interpreter/mixedmodule.py Mon Feb 12 15:49:52 2007 @@ -174,17 +174,20 @@ # hum, it's a bit more involved, because we usually # want the import at applevel modname, attrname = spec.split('.') - impbase = pkgroot + '.' + modname - mod = __import__(impbase, None, None, ['attrname']) + impbase = pkgroot + '.' + modname try: - app = applevelcache[mod] + app = applevelcache[impbase] except KeyError: - source = inspect.getsource(mod) - fn = mod.__file__ + import imp + pkg = __import__(pkgroot, None, None, ['__doc__']) + file, fn, (suffix, mode, typ) = imp.find_module(modname, pkg.__path__) + assert typ == imp.PY_SOURCE + source = file.read() + file.close() if fn.endswith('.pyc') or fn.endswith('.pyo'): fn = fn[:-1] app = gateway.applevel(source, filename=fn) - applevelcache[mod] = app + applevelcache[impbase] = app def afileloader(space): return app.wget(space, attrname) Modified: pypy/dist/pypy/module/posix/app_posix.py ============================================================================== --- pypy/dist/pypy/module/posix/app_posix.py (original) +++ pypy/dist/pypy/module/posix/app_posix.py Mon Feb 12 15:49:52 2007 @@ -1,30 +1,25 @@ # NOT_RPYTHON +from _structseq import structseqtype, structseqfield + error = OSError -def tuple_item_getter(n): # helper to make properties - def getter(self): - return self[n] - return property(getter) - - -class stat_result(tuple): - __slots__ = [] - - st_mode = tuple_item_getter(0) - st_ino = tuple_item_getter(1) - st_dev = tuple_item_getter(2) - st_nlink = tuple_item_getter(3) - st_uid = tuple_item_getter(4) - st_gid = tuple_item_getter(5) - st_size = tuple_item_getter(6) - st_atime = tuple_item_getter(7) - st_mtime = tuple_item_getter(8) - st_ctime = tuple_item_getter(9) - n_sequence_fields = 10 - n_fields = 10 # no extra attributes for now - n_unnamed_fields = 0 +class stat_result: + __metaclass__ = structseqtype + + st_mode = structseqfield(0, "protection bits") + st_ino = structseqfield(1, "inode") + st_dev = structseqfield(2, "device") + st_nlink = structseqfield(3, "number of hard links") + st_uid = structseqfield(4, "user ID of owner") + st_gid = structseqfield(5, "group ID of owner") + st_size = structseqfield(6, "total size, in bytes") + st_atime = structseqfield(7, "time of last access (XXX as an int)") + st_mtime = structseqfield(8, "time of last modification (XXX as an int)") + st_ctime = structseqfield(9, "time of last change (XXX as an int)") + # XXX no extra fields for now + def fdopen(fd, mode='r', buffering=-1): """fdopen(fd [, mode='r' [, buffering]]) -> file_object 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 Mon Feb 12 15:49:52 2007 @@ -40,6 +40,16 @@ posix.close(fd2) posix.close(fd) + def test_pickle(self): + import pickle, os + st = self.posix.stat(os.curdir) + print type(st).__module__ + s = pickle.dumps(st) + print repr(s) + new = pickle.loads(s) + assert new == st + assert type(new) is type(st) + def test_open_exception(self): posix = self.posix try: Modified: pypy/dist/pypy/module/rctime/app_time.py ============================================================================== --- pypy/dist/pypy/module/rctime/app_time.py (original) +++ pypy/dist/pypy/module/rctime/app_time.py Mon Feb 12 15:49:52 2007 @@ -1,41 +1,23 @@ +# NOT_RPYTHON + import os +from _structseq import structseqtype, structseqfield _POSIX = os.name == "posix" -class struct_time(object): - def __init__(self, tup): - if len(tup) != 9: - raise TypeError, "time.struct_time() takes a 9-sequence" - - self._tup = tup - self.tm_year = self._tup[0] - self.tm_mon = self._tup[1] - self.tm_mday = self._tup[2] - self.tm_hour = self._tup[3] - self.tm_min = self._tup[4] - self.tm_sec = self._tup[5] - self.tm_wday = self._tup[6] - self.tm_yday = self._tup[7] - self.tm_isdst = self._tup[8] - - def __repr__(self): - return "(%d, %d, %d, %d, %d, %d, %d, %d, %d)" %\ - (self.tm_year, self.tm_mon, self.tm_mday, self.tm_hour, - self.tm_min, self.tm_sec, self.tm_wday, self.tm_yday, - self.tm_isdst) - - def __len__(self): - return 9 - - def __getitem__(self, key): - if not isinstance(key, (int, slice)): - raise TypeError, "sequence index must be integer" - return self._tup[key] - - def __cmp__(self, other): - if isinstance(other, struct_time): - return cmp(self._tup, other._tup) - return cmp(self._tup, other) +class struct_time: + __metaclass__ = structseqtype + __module__ = 'time' + + tm_year = structseqfield(0) + tm_mon = structseqfield(1) + tm_mday = structseqfield(2) + tm_hour = structseqfield(3) + tm_min = structseqfield(4) + tm_sec = structseqfield(5) + tm_wday = structseqfield(6) + tm_yday = structseqfield(7) + tm_isdst = structseqfield(8) if _POSIX: Modified: pypy/dist/pypy/module/rctime/test/test_rctime.py ============================================================================== --- pypy/dist/pypy/module/rctime/test/test_rctime.py (original) +++ pypy/dist/pypy/module/rctime/test/test_rctime.py Mon Feb 12 15:49:52 2007 @@ -264,3 +264,11 @@ 'U', 'w', 'W', 'x', 'X', 'y', 'Y', 'Z', '%'): format = ' %' + directive rctime.strptime(rctime.strftime(format, tt), format) + + def test_pickle(self): + import pickle + import time as rctime + now = rctime.localtime() + new = pickle.loads(pickle.dumps(now)) + assert new == now + assert type(new) is type(now) From fijal at codespeak.net Mon Feb 12 16:29:43 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 12 Feb 2007 16:29:43 +0100 (CET) Subject: [pypy-svn] r38575 - pypy/dist/pypy/tool/pytest Message-ID: <20070212152943.300B21005A@code0.codespeak.net> Author: fijal Date: Mon Feb 12 16:29:42 2007 New Revision: 38575 Modified: pypy/dist/pypy/tool/pytest/appsupport.py Log: We need those two for distributed testing Modified: pypy/dist/pypy/tool/pytest/appsupport.py ============================================================================== --- pypy/dist/pypy/tool/pytest/appsupport.py (original) +++ pypy/dist/pypy/tool/pytest/appsupport.py Mon Feb 12 16:29:42 2007 @@ -12,6 +12,7 @@ def __init__(self, space, pycode): self.code = space.unwrap(space.getattr(pycode, space.wrap('co_code'))) self.w_file = space.getattr(pycode, space.wrap('co_filename')) + self.name = space.getattr(pycode, space.wrap('co_name')) self.firstlineno = space.unwrap(space.getattr(pycode, space.wrap('co_firstlineno'))) #try: # self.path = space.unwrap(space.getattr(self.w_file, space.wrap('__path__'))) @@ -64,6 +65,7 @@ def __init__(self, space, operr): self.space = space self.operr = operr + self.typename = operr.w_type.name self.traceback = AppTraceback(space, self.operr.application_traceback) debug_excs = getattr(operr, 'debug_excs', []) if debug_excs: From ac at codespeak.net Mon Feb 12 17:01:15 2007 From: ac at codespeak.net (ac at codespeak.net) Date: Mon, 12 Feb 2007 17:01:15 +0100 (CET) Subject: [pypy-svn] r38580 - in pypy/dist: lib-python/modified-2.4.1/test pypy/module/unicodedata pypy/module/unicodedata/test pypy/objspace/std pypy/rlib/rsre/test Message-ID: <20070212160115.07CDC100A4@code0.codespeak.net> Author: ac Date: Mon Feb 12 17:01:15 2007 New Revision: 38580 Added: pypy/dist/lib-python/modified-2.4.1/test/test_unicodedata.py - copied, changed from r38555, pypy/dist/lib-python/2.4.1/test/test_unicodedata.py Modified: pypy/dist/pypy/module/unicodedata/__init__.py pypy/dist/pypy/module/unicodedata/interp_ucd.py pypy/dist/pypy/module/unicodedata/test/test_unicodedata.py pypy/dist/pypy/objspace/std/unicodeobject.py pypy/dist/pypy/rlib/rsre/test/test_rsre.py Log: Use Unicode database version 3.2.0 to match Python 2.4 Fix test to account for PyPy being more correct than Python. Modified: pypy/dist/pypy/module/unicodedata/__init__.py ============================================================================== --- pypy/dist/pypy/module/unicodedata/__init__.py (original) +++ pypy/dist/pypy/module/unicodedata/__init__.py Mon Feb 12 17:01:15 2007 @@ -6,8 +6,8 @@ interpleveldefs = { 'unidata_version' : 'space.wrap(interp_ucd.ucd.version)', 'ucd_3_2_0' : 'space.wrap(interp_ucd.ucd_3_2_0)', - 'ucd_4_1_0' : 'space.wrap(interp_ucd.ucd_4_1_0)', - 'ucd_5_0_0' : 'space.wrap(interp_ucd.ucd_5_0_0)', + #'ucd_4_1_0' : 'space.wrap(interp_ucd.ucd_4_1_0)', + #'ucd_5_0_0' : 'space.wrap(interp_ucd.ucd_5_0_0)', 'ucd' : 'space.wrap(interp_ucd.ucd)', '__doc__' : "space.wrap('unicode character database')", } Modified: pypy/dist/pypy/module/unicodedata/interp_ucd.py ============================================================================== --- pypy/dist/pypy/module/unicodedata/interp_ucd.py (original) +++ pypy/dist/pypy/module/unicodedata/interp_ucd.py Mon Feb 12 17:01:15 2007 @@ -289,5 +289,5 @@ ucd_3_2_0 = UCD(unicodedb_3_2_0) ucd_4_1_0 = UCD(unicodedb_4_1_0) ucd_5_0_0 = UCD(unicodedb_5_0_0) -ucd = ucd_4_1_0 +ucd = ucd_3_2_0 Modified: pypy/dist/pypy/module/unicodedata/test/test_unicodedata.py ============================================================================== --- pypy/dist/pypy/module/unicodedata/test/test_unicodedata.py (original) +++ pypy/dist/pypy/module/unicodedata/test/test_unicodedata.py Mon Feb 12 17:01:15 2007 @@ -50,9 +50,13 @@ if sys.maxunicode < 0x10ffff: skip("requires a 'wide' python build.") import unicodedata - for first, last in ((0x3400, 0x4DB5), - (0x4E00, 0x9FBB), - (0x20000, 0x2A6D6)): + cases = ((0x3400, 0x4DB5), + (0x4E00, 0x9FA5)) + if unicodedata.unidata_version >= "4.1": + cases = ((0x3400, 0x4DB5), + (0x4E00, 0x9FBB), + (0x20000, 0x2A6D6)) + for first, last in cases: # Test at and inside the boundary for i in (first, first + 1, last - 1, last): charname = 'CJK UNIFIED IDEOGRAPH-%X'%i Modified: pypy/dist/pypy/objspace/std/unicodeobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/unicodeobject.py (original) +++ pypy/dist/pypy/objspace/std/unicodeobject.py Mon Feb 12 17:01:15 2007 @@ -4,7 +4,7 @@ from pypy.objspace.std.noneobject import W_NoneObject from pypy.objspace.std.sliceobject import W_SliceObject from pypy.rlib.rarithmetic import intmask, ovfcheck -from pypy.module.unicodedata import unicodedb_4_1_0 as unicodedb +from pypy.module.unicodedata import unicodedb_3_2_0 as unicodedb class W_UnicodeObject(W_Object): from pypy.objspace.std.unicodetype import unicode_typedef as typedef Modified: pypy/dist/pypy/rlib/rsre/test/test_rsre.py ============================================================================== --- pypy/dist/pypy/rlib/rsre/test/test_rsre.py (original) +++ pypy/dist/pypy/rlib/rsre/test/test_rsre.py Mon Feb 12 17:01:15 2007 @@ -6,8 +6,8 @@ from pypy.rlib.rsre import rsre_char isre = SimpleStringState.rsre_core -from pypy.module.unicodedata import unicodedb_4_1_0 -set_unicode_db(unicodedb_4_1_0) +from pypy.module.unicodedata import unicodedb_3_2_0 +set_unicode_db(unicodedb_3_2_0) EM_SPACE = u"\u2001" INDIAN_DIGIT = u"\u0966" From arigo at codespeak.net Mon Feb 12 17:03:27 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 12 Feb 2007 17:03:27 +0100 (CET) Subject: [pypy-svn] r38581 - pypy/dist/pypy/objspace/std Message-ID: <20070212160327.9D9C81008E@code0.codespeak.net> Author: arigo Date: Mon Feb 12 17:03:26 2007 New Revision: 38581 Modified: pypy/dist/pypy/objspace/std/typeobject.py Log: Continue the "hack more at __module__" story. Modified: pypy/dist/pypy/objspace/std/typeobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/typeobject.py (original) +++ pypy/dist/pypy/objspace/std/typeobject.py Mon Feb 12 17:03:26 2007 @@ -395,13 +395,12 @@ return w_self.dict_w['__module__'] else: # for non-heap types, CPython checks for a module.name in the - # type name. we skip that here and only provide the default - if not we_are_translated(): - # hack for faked types - if ('__module__' in w_self.dict_w and - space.is_true(space.isinstance(w_self.dict_w['__module__'], - space.w_str))): - return w_self.dict_w['__module__'] + # type name. That's a hack, so we're allowed to use a different + # hack... + if ('__module__' in w_self.dict_w and + space.is_true(space.isinstance(w_self.dict_w['__module__'], + space.w_str))): + return w_self.dict_w['__module__'] return space.wrap('__builtin__') def add_subclass(w_self, w_subclass): From ac at codespeak.net Mon Feb 12 17:12:05 2007 From: ac at codespeak.net (ac at codespeak.net) Date: Mon, 12 Feb 2007 17:12:05 +0100 (CET) Subject: [pypy-svn] r38583 - pypy/dist/lib-python/modified-2.4.1/test Message-ID: <20070212161205.B63881009C@code0.codespeak.net> Author: ac Date: Mon Feb 12 17:12:05 2007 New Revision: 38583 Modified: pypy/dist/lib-python/modified-2.4.1/test/test_descr.py Log: Call parent method correctly! 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 Mon Feb 12 17:12:05 2007 @@ -2048,7 +2048,7 @@ __slots__ = ['prec'] def __init__(self, value=0.0, prec=12): self.prec = int(prec) - float.__init__(value) + float.__init__(self, value) def __repr__(self): return "%.*g" % (self.prec, self) vereq(repr(precfloat(1.1)), "1.1") From ac at codespeak.net Mon Feb 12 17:28:05 2007 From: ac at codespeak.net (ac at codespeak.net) Date: Mon, 12 Feb 2007 17:28:05 +0100 (CET) Subject: [pypy-svn] r38587 - pypy/dist/lib-python/modified-2.4.1/test Message-ID: <20070212162805.A2A1F100A9@code0.codespeak.net> Author: ac Date: Mon Feb 12 17:28:05 2007 New Revision: 38587 Modified: pypy/dist/lib-python/modified-2.4.1/test/test_builtin.py Log: Non-mappings fail differently in PyPy. Modified: pypy/dist/lib-python/modified-2.4.1/test/test_builtin.py ============================================================================== --- pypy/dist/lib-python/modified-2.4.1/test/test_builtin.py (original) +++ pypy/dist/lib-python/modified-2.4.1/test/test_builtin.py Mon Feb 12 17:28:05 2007 @@ -291,7 +291,7 @@ "Non-mapping" pass m = A() - self.assertRaises(TypeError, eval, 'a', g, m) + self.assertRaises((TypeError, AttributeError) , eval, 'a', g, m) # Verify that dict subclasses work as well class D(dict): From fijal at codespeak.net Mon Feb 12 17:29:16 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 12 Feb 2007 17:29:16 +0100 (CET) Subject: [pypy-svn] r38589 - pypy/dist/pypy/rpython Message-ID: <20070212162916.EDCFA100A6@code0.codespeak.net> Author: fijal Date: Mon Feb 12 17:29:15 2007 New Revision: 38589 Modified: pypy/dist/pypy/rpython/rgeneric.py Log: Missing conversion Modified: pypy/dist/pypy/rpython/rgeneric.py ============================================================================== --- pypy/dist/pypy/rpython/rgeneric.py (original) +++ pypy/dist/pypy/rpython/rgeneric.py Mon Feb 12 17:29:15 2007 @@ -1,6 +1,7 @@ from pypy.annotation import model as annmodel from pypy.rpython.rmodel import Repr -from pypy.rpython.rpbc import AbstractFunctionsPBCRepr +from pypy.rpython.rpbc import AbstractFunctionsPBCRepr,\ + AbstractMethodsPBCRepr from pypy.annotation.pairtype import pairtype from pypy.rpython.lltypesystem import lltype @@ -55,3 +56,13 @@ return v return NotImplemented +class __extend__(pairtype(AbstractMethodsPBCRepr, AbstractGenericCallableRepr)): + def convert_from_to((pbcrepr, gencallrepr), v, llops): + import pdb;pdb.set_trace() + if pbcrepr.lowleveltype is lltype.Void: + r = gencallrepr.convert_const(pbcrepr.s_pbc.const) + r.setup() + return r + if pbcrepr.lowleveltype == gencallrepr.lowleveltype: + return v + return NotImplemented From arigo at codespeak.net Mon Feb 12 17:41:24 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 12 Feb 2007 17:41:24 +0100 (CET) Subject: [pypy-svn] r38593 - pypy/dist/pypy/interpreter/test Message-ID: <20070212164124.4433D10077@code0.codespeak.net> Author: arigo Date: Mon Feb 12 17:41:23 2007 New Revision: 38593 Modified: pypy/dist/pypy/interpreter/test/test_syntax.py Log: Use space.appexec(), for appdirect tests. 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 Mon Feb 12 17:41:23 2007 @@ -259,10 +259,11 @@ class Py25AppTest: def setup_class(self): space = self.space - w_globals = space.newdict([]) - space.exec_('import sys; not_25 = sys.version_info < (2,5)', - w_globals, w_globals) - not_25 = space.is_true(space.getitem(w_globals, space.wrap('not_25'))) + w_not_25 = space.appexec([], """(): + import sys + return sys.version_info < (2,5) + """) + not_25 = space.is_true(w_not_25) if not_25: py.test.skip('Needs python 2.5 grammar') From arigo at codespeak.net Mon Feb 12 17:44:27 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 12 Feb 2007 17:44:27 +0100 (CET) Subject: [pypy-svn] r38596 - in pypy/dist/pypy: . module/_stackless/test module/readline/test module/signal/test module/thread/rpython/test Message-ID: <20070212164427.4C25F100A9@code0.codespeak.net> Author: arigo Date: Mon Feb 12 17:44:24 2007 New Revision: 38596 Modified: pypy/dist/pypy/conftest.py pypy/dist/pypy/module/_stackless/test/test_interp_clonable.py pypy/dist/pypy/module/_stackless/test/test_interp_coroutine.py pypy/dist/pypy/module/readline/test/test_c_readline.py pypy/dist/pypy/module/signal/test/test_interp_signal.py pypy/dist/pypy/module/thread/rpython/test/test_ll_thread.py Log: (pedronis, arigo) Skip translation tests when running appdirect. These files don't contain any app-level test anyway, but importing them fails on pypy-c. Modified: pypy/dist/pypy/conftest.py ============================================================================== --- pypy/dist/pypy/conftest.py (original) +++ pypy/dist/pypy/conftest.py Mon Feb 12 17:44:24 2007 @@ -78,12 +78,14 @@ py.test.skip("cannot runappdirect this test on top of CPython") has = sys.pypy_translation_info.get(key, None) if has != value: - print sys.pypy_translation_info + #print sys.pypy_translation_info py.test.skip("cannot runappdirect test: space needs %s = %s, "\ "while pypy-c was built with %s" % (key, value, has)) def appexec(self, args, body): - src = py.code.Source("def anonymous" + body.lstrip()) + body = body.lstrip() + assert body.startswith('(') + src = py.code.Source("def anonymous" + body) d = {} exec src.compile() in d return d['anonymous'](*args) @@ -100,6 +102,10 @@ def newdict(self): return {} +def translation_test_so_skip_if_appdirect(): + if option.runappdirect: + py.test.skip("translation test, skipped for appdirect") + class OpErrKeyboardInterrupt(KeyboardInterrupt): pass Modified: pypy/dist/pypy/module/_stackless/test/test_interp_clonable.py ============================================================================== --- pypy/dist/pypy/module/_stackless/test/test_interp_clonable.py (original) +++ pypy/dist/pypy/module/_stackless/test/test_interp_clonable.py Mon Feb 12 17:44:24 2007 @@ -2,6 +2,7 @@ testing cloning """ +from pypy import conftest; conftest.translation_test_so_skip_if_appdirect() from pypy.translator.c import gc from pypy.rpython.memory.gctransform import stacklessframework from pypy.rpython.memory.test import test_transformed_gc Modified: pypy/dist/pypy/module/_stackless/test/test_interp_coroutine.py ============================================================================== --- pypy/dist/pypy/module/_stackless/test/test_interp_coroutine.py (original) +++ pypy/dist/pypy/module/_stackless/test/test_interp_coroutine.py Mon Feb 12 17:44:24 2007 @@ -3,6 +3,7 @@ """ import os +from pypy import conftest; conftest.translation_test_so_skip_if_appdirect() from pypy.module._stackless.interp_coroutine import syncstate, Coroutine, AbstractThunk from pypy.translator.c.test.test_stackless import StacklessTest from pypy.translator.c import gc Modified: pypy/dist/pypy/module/readline/test/test_c_readline.py ============================================================================== --- pypy/dist/pypy/module/readline/test/test_c_readline.py (original) +++ pypy/dist/pypy/module/readline/test/test_c_readline.py Mon Feb 12 17:44:24 2007 @@ -2,6 +2,7 @@ Directly test the basic ctypes wrappers. """ +from pypy import conftest; conftest.translation_test_so_skip_if_appdirect() from pypy.module.readline import c_readline Modified: pypy/dist/pypy/module/signal/test/test_interp_signal.py ============================================================================== --- pypy/dist/pypy/module/signal/test/test_interp_signal.py (original) +++ pypy/dist/pypy/module/signal/test/test_interp_signal.py Mon Feb 12 17:44:24 2007 @@ -1,4 +1,5 @@ import os, py +from pypy import conftest; conftest.translation_test_so_skip_if_appdirect() from pypy.translator.c.test.test_genc import compile from pypy.module.signal import interp_signal Modified: pypy/dist/pypy/module/thread/rpython/test/test_ll_thread.py ============================================================================== --- pypy/dist/pypy/module/thread/rpython/test/test_ll_thread.py (original) +++ pypy/dist/pypy/module/thread/rpython/test/test_ll_thread.py Mon Feb 12 17:44:24 2007 @@ -1,9 +1,5 @@ -import py - -try: - import thread -except ImportError: - py.test.skip("Threads not supported") +from pypy import conftest; conftest.translation_test_so_skip_if_appdirect() +import thread import pypy.module.thread.rpython.exttable # for declare()/declaretype() from pypy.module.thread.rpython.ll_thread import * from pypy.annotation.annrpython import RPythonAnnotator From fijal at codespeak.net Mon Feb 12 18:01:48 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 12 Feb 2007 18:01:48 +0100 (CET) Subject: [pypy-svn] r38599 - pypy/dist/pypy/rpython/ootypesystem Message-ID: <20070212170148.66B921009C@code0.codespeak.net> Author: fijal Date: Mon Feb 12 18:01:46 2007 New Revision: 38599 Modified: pypy/dist/pypy/rpython/ootypesystem/bltregistry.py Log: Minor API-wise improvement Modified: pypy/dist/pypy/rpython/ootypesystem/bltregistry.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/bltregistry.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/bltregistry.py Mon Feb 12 18:01:46 2007 @@ -50,22 +50,17 @@ return tuple([typeof(i) for i in val]) return type(val) -def load_dict_args(func, args): - code = func.func_code - if not func.func_defaults: - defs = [] - else: - defs = func.func_defaults - num_args = code.co_argcount - assert(num_args < len(defs) + len(args), "Not enough information for describing method") +def load_dict_args(varnames, defs, args): + argcount = len(varnames) + assert(argcount < len(defs) + len(args), "Not enough information for describing method") - for arg in xrange(1, code.co_argcount - len(defs)): - assert code.co_varnames[arg] in args, "Don't have type for arg %s" % code.co_varnames[arg] - + for arg in xrange(1, argcount - len(defs)): + assert varnames[arg] in args, "Don't have type for arg %s" % varnames[arg] + arg_pass = [] - start_pos = code.co_argcount - len(defs) - for arg in xrange(1, code.co_argcount): - varname = code.co_varnames[arg] + start_pos = argcount - len(defs) + for arg in xrange(1, argcount): + varname = varnames[arg] if varname in args: arg_pass.append((varname, args[varname])) else: @@ -82,7 +77,11 @@ def described(retval=None, args={}): def decorator(func): if isinstance(args, dict): - arg_pass = load_dict_args(func, args) + defs = func.func_defaults + if defs is None: + defs = () + vars = func.func_code.co_varnames[:func.func_code.co_argcount] + arg_pass = load_dict_args(vars, defs, args) else: assert isinstance(args, list) arg_pass = args From ac at codespeak.net Mon Feb 12 18:24:18 2007 From: ac at codespeak.net (ac at codespeak.net) Date: Mon, 12 Feb 2007 18:24:18 +0100 (CET) Subject: [pypy-svn] r38607 - pypy/dist/lib-python/modified-2.4.1/test Message-ID: <20070212172418.24AB1100AB@code0.codespeak.net> Author: ac Date: Mon Feb 12 18:24:17 2007 New Revision: 38607 Modified: pypy/dist/lib-python/modified-2.4.1/test/test_descr.py Log: Improve on some of the tests. 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 Mon Feb 12 18:24:17 2007 @@ -3,6 +3,7 @@ from test.test_support import verify, vereq, verbose, TestFailed, TESTFN, get_original_stdout from copy import deepcopy import warnings +import gc warnings.filterwarnings("ignore", r'complex divmod\(\), // and % are deprecated$', @@ -982,8 +983,7 @@ (EditableScrollablePane, ScrollablePane, EditablePane, Pane, ScrollingMixin, EditingMixin, object)) -mro_err_msg = """Cannot create a consistent method resolution -order (MRO) for bases """ +mro_err_msg = "cycle among base classes:" def mro_disagreement(): if verbose: print "Testing error messages for MRO disagreement..." @@ -1143,16 +1143,28 @@ x.a = Counted() x.b = Counted() x.c = Counted() + gc.collect() + gc.collect() + gc.collect() vereq(Counted.counter, 3) del x + gc.collect() + gc.collect() + gc.collect() vereq(Counted.counter, 0) class D(C): pass x = D() x.a = Counted() x.z = Counted() + gc.collect() + gc.collect() + gc.collect() vereq(Counted.counter, 2) del x + gc.collect() + gc.collect() + gc.collect() vereq(Counted.counter, 0) class E(D): __slots__ = ['e'] @@ -1160,8 +1172,14 @@ x.a = Counted() x.z = Counted() x.e = Counted() + gc.collect() + gc.collect() + gc.collect() vereq(Counted.counter, 3) del x + gc.collect() + gc.collect() + gc.collect() vereq(Counted.counter, 0) # Test cyclical leaks [SF bug 519621] @@ -1170,14 +1188,19 @@ log = [] s = F() s.a = [Counted(), s] + gc.collect() + gc.collect() + gc.collect() vereq(Counted.counter, 1) s = None import gc gc.collect() + gc.collect() + gc.collect() vereq(Counted.counter, 0) # Test lookup leaks [SF bug 572567] - import sys,gc + import sys class G(object): def __cmp__(self, other): return 0 @@ -1743,12 +1766,13 @@ else: raise TestFailed, "shouldn't allow %s.__cmp__(%r, %r)" % ( a.__class__, a, b) - unsafecmp(u"123", "123") - unsafecmp("123", u"123") - unsafecmp(1, 1.0) - unsafecmp(1.0, 1) - unsafecmp(1, 1L) - unsafecmp(1L, 1) + # unicode, int, float and long does not have a __cmp__ in PyPy + # unsafecmp(u"123", "123") + # unsafecmp("123", u"123") + # unsafecmp(1, 1.0) + # unsafecmp(1.0, 1) + # unsafecmp(1, 1L) + # unsafecmp(1L, 1) class Letter(str): def __new__(cls, letter): @@ -1782,6 +1806,9 @@ r = weakref.ref(c) verify(r() is c) del c + gc.collect() + gc.collect() + gc.collect() verify(r() is None) del r class NoWeak(object): @@ -1799,6 +1826,9 @@ r = weakref.ref(yes) verify(r() is yes) del yes + gc.collect() + gc.collect() + gc.collect() verify(r() is None) del r @@ -3019,6 +3049,9 @@ c = C() vereq(log, []) del c + gc.collect() + gc.collect() + gc.collect() vereq(log, [1]) class D(object): pass @@ -3323,12 +3356,17 @@ # The most interesting thing here is whether this blows up, due to flawed # GC tracking logic in typeobject.c's call_finalizer() (a 2.2.1 bug). del c - + gc.collect() + gc.collect() + gc.collect() # If that didn't blow up, it's also interesting to see whether clearing # the last container slot works: that will attempt to delete c again, # which will cause c to get appended back to the container again "during" # the del. del C.container[-1] + gc.collect() + gc.collect() + gc.collect() vereq(len(C.container), 1) vereq(C.container[-1].attr, 42) @@ -3357,7 +3395,8 @@ pass class C(A,B) : __slots__=() - vereq(C.__basicsize__, B.__basicsize__) + # No __basicsize__ in PyPy + # vereq(C.__basicsize__, B.__basicsize__) verify(hasattr(C, '__dict__')) verify(hasattr(C, '__weakref__')) C().x = 2 From fijal at codespeak.net Mon Feb 12 18:26:20 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 12 Feb 2007 18:26:20 +0100 (CET) Subject: [pypy-svn] r38608 - in pypy/dist/pypy/translator/js/lib: . test Message-ID: <20070212172620.C92BD100A4@code0.codespeak.net> Author: fijal Date: Mon Feb 12 18:26:19 2007 New Revision: 38608 Added: pypy/dist/pypy/translator/js/lib/support.py pypy/dist/pypy/translator/js/lib/test/test_support.py Log: Add small support script Added: pypy/dist/pypy/translator/js/lib/support.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/js/lib/support.py Mon Feb 12 18:26:19 2007 @@ -0,0 +1,25 @@ + +""" Various simple support functions +""" + +from pypy.rpython.ootypesystem.bltregistry import described, load_dict_args,\ + MethodDesc + +from pypy.rpython.extfunc import _callable + +def callback(retval=None, args={}): + """ Variant of described decorator, which flows + an additional argument with return value of decorated + function, used specifically for callbacks + """ + def decorator(func): + defs = func.func_defaults + if defs is None: + defs = () + vars = func.func_code.co_varnames[:func.func_code.co_argcount] + arg_list = load_dict_args(vars, defs, args) + arg_list.append(("callback", _callable(args=[retval]))) + func._method = (func.__name__, MethodDesc(arg_list, retval)) + return func + + return decorator Added: pypy/dist/pypy/translator/js/lib/test/test_support.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/js/lib/test/test_support.py Mon Feb 12 18:26:19 2007 @@ -0,0 +1,15 @@ + +""" Tests for support module +""" + +from pypy.translator.js.lib import support + +def test_callback(): + @support.callback(retval=int) + def f(self, a=8, b=3.2): + pass + + methdesc = f._method[1] + assert len(methdesc.args) == 3 + assert methdesc.args[2].name == 'callback' + From arigo at codespeak.net Mon Feb 12 18:28:47 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 12 Feb 2007 18:28:47 +0100 (CET) Subject: [pypy-svn] r38610 - in pypy/dist/pypy: . lib module/__builtin__ module/__builtin__/test Message-ID: <20070212172847.CEE6B100A4@code0.codespeak.net> Author: arigo Date: Mon Feb 12 18:28:45 2007 New Revision: 38610 Modified: pypy/dist/pypy/conftest.py pypy/dist/pypy/lib/stackless_new.py pypy/dist/pypy/module/__builtin__/importing.py pypy/dist/pypy/module/__builtin__/test/test_import.py Log: Run all tests in the app_test directory even with the -A option, as they are meant to be testing the lib/ directory directly. Fix a crash in the import logic if __name__ is set to a non-string object. Fix a TypeError in stackless_new.py (previously hidden by invalid shortcuts in the pypy interpreter). Modified: pypy/dist/pypy/conftest.py ============================================================================== --- pypy/dist/pypy/conftest.py (original) +++ pypy/dist/pypy/conftest.py Mon Feb 12 18:28:45 2007 @@ -145,16 +145,23 @@ option.conf_iocapture = "sys" # pypy cannot do FD-based super(Module, self).__init__(*args, **kwargs) - def funcnamefilter(self, name): + def accept_regular_test(self): + if option.runappdirect: + # only collect regular tests if we are in an 'app_test' directory + return self.fspath.dirpath().basename == 'app_test' + else: + return True + + def funcnamefilter(self, name): if name.startswith('test_'): - return not option.runappdirect + return self.accept_regular_test() if name.startswith('app_test_'): return True return False def classnamefilter(self, name): if name.startswith('Test'): - return not option.runappdirect + return self.accept_regular_test() if name.startswith('AppTest'): return True return False Modified: pypy/dist/pypy/lib/stackless_new.py ============================================================================== --- pypy/dist/pypy/lib/stackless_new.py (original) +++ pypy/dist/pypy/lib/stackless_new.py Mon Feb 12 18:28:45 2007 @@ -380,7 +380,7 @@ _main_coroutine = _main_tasklet _main_tasklet = TaskletProxy(_main_tasklet) assert _main_tasklet.is_alive and not _main_tasklet.is_zombie - tasklet._init(_main_tasklet, label='main') + tasklet._init.im_func(_main_tasklet, label='main') _squeue = deque() _scheduler_append(_main_tasklet) Modified: pypy/dist/pypy/module/__builtin__/importing.py ============================================================================== --- pypy/dist/pypy/module/__builtin__/importing.py (original) +++ pypy/dist/pypy/module/__builtin__/importing.py Mon Feb 12 18:28:45 2007 @@ -155,23 +155,29 @@ space.wrap("__import__() argument 1 must be string" + helper)) w = space.wrap + ctxt_name = None if w_globals is not None and not space.is_w(w_globals, space.w_None): ctxt_w_name = try_getitem(space, w_globals, w('__name__')) ctxt_w_path = try_getitem(space, w_globals, w('__path__')) + if ctxt_w_name is not None: + try: + ctxt_name = space.str_w(ctxt_w_name) + except OperationError, e: + if not e.match(space, space.w_TypeError): + raise else: - ctxt_w_name = None ctxt_w_path = None rel_modulename = None - if ctxt_w_name is not None: + if ctxt_name is not None: - ctxt_name_prefix_parts = space.str_w(ctxt_w_name).split('.') + ctxt_name_prefix_parts = ctxt_name.split('.') if ctxt_w_path is None: # context is a plain module ctxt_name_prefix_parts = ctxt_name_prefix_parts[:-1] if ctxt_name_prefix_parts: rel_modulename = '.'.join(ctxt_name_prefix_parts+[modulename]) else: # context is a package module - rel_modulename = space.str_w(ctxt_w_name)+'.'+modulename + rel_modulename = ctxt_name+'.'+modulename if rel_modulename is not None: w_mod = check_sys_modules(space, w(rel_modulename)) if (w_mod is None or Modified: pypy/dist/pypy/module/__builtin__/test/test_import.py ============================================================================== --- pypy/dist/pypy/module/__builtin__/test/test_import.py (original) +++ pypy/dist/pypy/module/__builtin__/test/test_import.py Mon Feb 12 18:28:45 2007 @@ -247,6 +247,12 @@ finally: os.chmod(p, 0775) + def test_invalid__name__(self): + glob = {} + exec "__name__ = None; import sys" in glob + import sys + assert glob['sys'] is sys + def _getlong(data): x = marshal.dumps(data) return x[-4:] From arigo at codespeak.net Mon Feb 12 18:33:53 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 12 Feb 2007 18:33:53 +0100 (CET) Subject: [pypy-svn] r38611 - in pypy/dist/pypy/lib: app_test test2 Message-ID: <20070212173353.93A3A1009C@code0.codespeak.net> Author: arigo Date: Mon Feb 12 18:33:51 2007 New Revision: 38611 Added: pypy/dist/pypy/lib/test2/test_string_extra.py - copied unchanged from r38610, pypy/dist/pypy/lib/app_test/test_string_extra.py Removed: pypy/dist/pypy/lib/app_test/test_string_extra.py Log: Move this test to test2/, as it's not testing something that makes sense to check on top of CPython. From fijal at codespeak.net Mon Feb 12 18:42:24 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 12 Feb 2007 18:42:24 +0100 (CET) Subject: [pypy-svn] r38613 - in pypy/dist/pypy/translator/js/lib: . test Message-ID: <20070212174224.DDDE21009C@code0.codespeak.net> Author: fijal Date: Mon Feb 12 18:42:23 2007 New Revision: 38613 Modified: pypy/dist/pypy/translator/js/lib/server.py pypy/dist/pypy/translator/js/lib/test/test_server.py Log: Fix that allows to have file telling on which port server is running Modified: pypy/dist/pypy/translator/js/lib/server.py ============================================================================== --- pypy/dist/pypy/translator/js/lib/server.py (original) +++ pypy/dist/pypy/translator/js/lib/server.py Mon Feb 12 18:42:23 2007 @@ -32,7 +32,7 @@ from pypy.translator.js.main import rpython2javascript from pypy.translator.js import commproxy -commproxy.USE_MOCHIKIT = True +commproxy.USE_MOCHIKIT = False class ExportedMethods(BasicExternal): _render_xmlhttp = True @@ -118,7 +118,7 @@ return open(self.path).read() def start_server(server_address = ('', 8000), handler=TestHandler, fork=False, - timeout=None, server=HTTPServer): + timeout=None, server=HTTPServer, port_file=None): patch_handler(handler) httpd = server(server_address, handler) if timeout: @@ -133,17 +133,16 @@ thread.start_new_thread(f, (httpd,)) httpd.last_activity = time.time() + print "Server started, listening on %s:%s" %\ + (httpd.server_address[0],httpd.server_port) + if port_file: + # this is strange hack to allow exchange of port information + py.path.local(port_file).write(str(httpd.server_port)) if fork: import thread thread.start_new_thread(httpd.serve_forever, ()) - print "Server started, listening on %s:%s" %\ - (httpd.server_address[0],httpd.server_port) - sys.stdout.flush() return httpd else: - print "Server started, listening on %s:%s" %\ - (httpd.server_address[0],httpd.server_port) - sys.stdout.flush() httpd.serve_forever() Handler = TestHandler Modified: pypy/dist/pypy/translator/js/lib/test/test_server.py ============================================================================== --- pypy/dist/pypy/translator/js/lib/test/test_server.py (original) +++ pypy/dist/pypy/translator/js/lib/test/test_server.py Mon Feb 12 18:42:23 2007 @@ -53,3 +53,10 @@ assert URLopener().open("http://127.0.0.1:21213/index").read() == \ "" +def test_port_file(): + tmpdir = py.test.ensuretemp("port_file") + server.start_server(('127.0.0.1', 21214), port_file=tmpdir.join("f"), + fork=True) + assert tmpdir.join("f").read() == "21214" + + From pedronis at codespeak.net Mon Feb 12 19:02:04 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Mon, 12 Feb 2007 19:02:04 +0100 (CET) Subject: [pypy-svn] r38623 - pypy/dist/pypy/doc Message-ID: <20070212180204.258421009A@code0.codespeak.net> Author: pedronis Date: Mon Feb 12 19:02:03 2007 New Revision: 38623 Modified: pypy/dist/pypy/doc/index.txt Log: links to the nightly pypy-c compliance test runs in status. Modified: pypy/dist/pypy/doc/index.txt ============================================================================== --- pypy/dist/pypy/doc/index.txt (original) +++ pypy/dist/pypy/doc/index.txt Mon Feb 12 19:02:03 2007 @@ -74,8 +74,10 @@ `Nightly builds and benchmarks`_ of PyPy to C, CLI and LLVM (PowerPC machine). -`compliance test status`_ shows outcomes of -recent compliance test runs against PyPy. +Nightly compliance test runs for compiled pypy-c: `all working ext-modules with threads build`_, `all working ext-modules stackless build`_. + +`compliance test status`_ shows outcomes of compliance test runs +against PyPy on top of CPython. `PyPy statistics`_ shows LOC statistics about PyPy. @@ -131,6 +133,8 @@ .. _`sprint reports`: sprint-reports.html .. _`talks and related projects`: extradoc.html .. _`license`: ../../LICENSE +.. _`all working ext-modules with threads build`: http://www2.openend.se/~pedronis/pypy-c-test/allworkingmodules/summary.html +.. _`all working ext-modules stackless build`: http://www2.openend.se/~pedronis/pypy-c-test/slp/summary.html .. _`compliance test status`: http://codespeak.net/~hpk/pypy-testresult/ .. _`PyPy statistics`: http://codespeak.net/~hpk/pypy-stat/ .. _`object spaces`: objspace.html From fijal at codespeak.net Mon Feb 12 19:02:51 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 12 Feb 2007 19:02:51 +0100 (CET) Subject: [pypy-svn] r38624 - pypy/dist/pypy/rpython Message-ID: <20070212180251.E11831009C@code0.codespeak.net> Author: fijal Date: Mon Feb 12 19:02:50 2007 New Revision: 38624 Modified: pypy/dist/pypy/rpython/rgeneric.py Log: Unsure why I've commited that in. Modified: pypy/dist/pypy/rpython/rgeneric.py ============================================================================== --- pypy/dist/pypy/rpython/rgeneric.py (original) +++ pypy/dist/pypy/rpython/rgeneric.py Mon Feb 12 19:02:50 2007 @@ -55,14 +55,3 @@ if pbcrepr.lowleveltype == gencallrepr.lowleveltype: return v return NotImplemented - -class __extend__(pairtype(AbstractMethodsPBCRepr, AbstractGenericCallableRepr)): - def convert_from_to((pbcrepr, gencallrepr), v, llops): - import pdb;pdb.set_trace() - if pbcrepr.lowleveltype is lltype.Void: - r = gencallrepr.convert_const(pbcrepr.s_pbc.const) - r.setup() - return r - if pbcrepr.lowleveltype == gencallrepr.lowleveltype: - return v - return NotImplemented From fijal at codespeak.net Mon Feb 12 19:08:01 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 12 Feb 2007 19:08:01 +0100 (CET) Subject: [pypy-svn] r38625 - in pypy/dist/pypy/translator/js/examples: . data Message-ID: <20070212180801.614091009B@code0.codespeak.net> Author: fijal Date: Mon Feb 12 19:07:59 2007 New Revision: 38625 Added: pypy/dist/pypy/translator/js/examples/data/ pypy/dist/pypy/translator/js/examples/data/index.html pypy/dist/pypy/translator/js/examples/over_client.py pypy/dist/pypy/translator/js/examples/overmind.py (contents, props changed) Modified: pypy/dist/pypy/translator/js/examples/pythonconsole.py Log: A (very preliminary) version of main script to be run on play1, this is intermediate checkin, needs further tweaks Added: pypy/dist/pypy/translator/js/examples/data/index.html ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/js/examples/data/index.html Mon Feb 12 19:07:59 2007 @@ -0,0 +1,19 @@ + + + pypy.js various demos + + + +

This site presents various demos and tutorials about pypy.js

+

Python console:

+

No more, no less + Launch one for me + Source +

+

Remote terminal:

+

Fully ANSI-complaint remote terminal session: + Launch one for me + Source +

+ + Added: pypy/dist/pypy/translator/js/examples/over_client.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/js/examples/over_client.py Mon Feb 12 19:07:59 2007 @@ -0,0 +1,12 @@ + +""" Client side of overmind.py +""" + +from pypy.translator.js.examples.overmind import exported_methods +from pypy.translator.js.modules import dom + +def callback(arg): + dom.window.location = "http://localhost:%d" % arg + +def launch_console(): + exported_methods.launch_console(callback) Added: pypy/dist/pypy/translator/js/examples/overmind.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/js/examples/overmind.py Mon Feb 12 19:07:59 2007 @@ -0,0 +1,59 @@ +#!/usr/bin/env python +""" This is script which collects all the demos and +run them when needed +""" + +from pypy.translator.js.lib import server +from pypy.translator.js.lib.support import callback +from pypy.rpython.extfunc import _callable +from pypy.rpython.ootypesystem.bltregistry import described +from pypy.translator.js.main import rpython2javascript + +import os +import py + +FUNCTION_LIST = ['launch_console'] +tempdir = py.test.ensuretemp("infos") +TIMEOUT = 100 + +def launch_console_in_new_process(): + from pypy.translator.js.examples import pythonconsole + httpd = server.start_server(server_address=('', 0), + handler=pythonconsole.RequestHandler, timeout=TIMEOUT, + port_file=tempdir.join("console_pid"), + fork=True, server=pythonconsole.Server) + pythonconsole.httpd = httpd + port = int(tempdir.join("console_pid").read()) + return port + +class ExportedMethods(server.ExportedMethods): + @callback(retval=int) + def launch_console(self): + """ Note that we rely here on threads not being invoked, + if we want to make this multiplayer, we need additional locking + XXX + """ + return launch_console_in_new_process() + +exported_methods = ExportedMethods() + +def js_source(function_list): + import over_client + return rpython2javascript(over_client, FUNCTION_LIST) + +class Handler(server.Handler): + static_dir = str(py.path.local(__file__).dirpath().join("data")) + index = server.Static() + exported_methods = exported_methods + + def source_js(self): + if hasattr(self.server, 'source'): + source = self.server.source + else: + source = js_source(FUNCTION_LIST) + self.server.source = source + return "text/javascript", source + source_js.exposed = True + +if __name__ == '__main__': + server.start_server(handler=Handler) Modified: pypy/dist/pypy/translator/js/examples/pythonconsole.py ============================================================================== --- pypy/dist/pypy/translator/js/examples/pythonconsole.py (original) +++ pypy/dist/pypy/translator/js/examples/pythonconsole.py Mon Feb 12 19:07:59 2007 @@ -18,11 +18,13 @@ from pypy.rpython.extfunc import _callable from pypy.translator.js.demo.jsdemo import support +from pypy.translator.js.lib import server commproxy.USE_MOCHIKIT = True from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer from SocketServer import ThreadingMixIn +import time HTML_PAGE = """ @@ -141,6 +143,7 @@ def run_some_callback(self, cmd=[""]): cmd = cmd[0] + self.server.last_activity = time.time() if cmd: buf = cStringIO.StringIO() out1 = sys.stdout @@ -181,8 +184,8 @@ httpd = Server(server_address, RequestHandler) print 'http://127.0.0.1:%d' % (server_address[1],) -def _main(): - build_http_server() +def _main(address=('', 8001)): + build_http_server(server_address=address) httpd.serve_forever() if __name__ == '__main__': From arigo at codespeak.net Mon Feb 12 19:28:56 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 12 Feb 2007 19:28:56 +0100 (CET) Subject: [pypy-svn] r38627 - in pypy/dist/pypy/rpython: lltypesystem ootypesystem test Message-ID: <20070212182856.2980F1009A@code0.codespeak.net> Author: arigo Date: Mon Feb 12 19:28:53 2007 New Revision: 38627 Modified: pypy/dist/pypy/rpython/lltypesystem/ll_str.py pypy/dist/pypy/rpython/ootypesystem/ll_str.py pypy/dist/pypy/rpython/test/test_rint.py Log: (arre, arigo) Special-case hex() and oct() of sys.maxint-1. Avoids segfaults of pypy-c. Modified: pypy/dist/pypy/rpython/lltypesystem/ll_str.py ============================================================================== --- pypy/dist/pypy/rpython/lltypesystem/ll_str.py (original) +++ pypy/dist/pypy/rpython/lltypesystem/ll_str.py Mon Feb 12 19:28:53 2007 @@ -49,14 +49,16 @@ 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' else: while i: - temp[len] = hex_chars[i%16] - i //= 16 + temp[len] = hex_chars[i & 0xf] + i >>= 4 len += 1 len += sign if addPrefix: @@ -88,10 +90,12 @@ sign = 0 if i < 0: sign = 1 - i = -i + i = r_uint(-i) + else: + i = r_uint(i) while i: - temp[len] = hex_chars[i%8] - i //= 8 + temp[len] = hex_chars[i & 0x7] + i >>= 3 len += 1 len += sign if addPrefix: Modified: pypy/dist/pypy/rpython/ootypesystem/ll_str.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/ll_str.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/ll_str.py Mon Feb 12 19:28:53 2007 @@ -1,4 +1,6 @@ +import sys from pypy.rpython.ootypesystem.ootype import new, oostring, StringBuilder +from pypy.rpython.ootypesystem.ootype import make_string def ll_int_str(repr, i): return ll_int2dec(i) @@ -6,12 +8,20 @@ def ll_int2dec(i): return oostring(i, 10) +SPECIAL_VALUE = -sys.maxint-1 +SPECIAL_VALUE_HEX = make_string( + '-' + hex(sys.maxint+1).replace('L', '').replace('l', '')) +SPECIAL_VALUE_OCT = make_string( + '-' + oct(sys.maxint+1).replace('L', '').replace('l', '')) + def ll_int2hex(i, addPrefix): if not addPrefix: return oostring(i, 16) buf = new(StringBuilder) if i<0: + if i == SPECIAL_VALUE: + return SPECIAL_VALUE_HEX i = -i buf.ll_append_char('-') @@ -26,6 +36,8 @@ buf = new(StringBuilder) if i<0: + if i == SPECIAL_VALUE: + return SPECIAL_VALUE_OCT i = -i buf.ll_append_char('-') 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 Mon Feb 12 19:28:53 2007 @@ -78,6 +78,10 @@ res = self.interpret(dummy, [-123]) assert self.ll_to_string(res) == '-0x7b' + res = self.interpret(dummy, [-sys.maxint-1]) + res = self.ll_to_string(res) + assert res == '-0x8' + '0' * (len(res)-4) + def test_oct_of_int(self): def dummy(i): return oct(i) @@ -91,6 +95,10 @@ res = self.interpret(dummy, [-123]) assert self.ll_to_string(res) == '-0173' + res = self.interpret(dummy, [-sys.maxint-1]) + res = self.ll_to_string(res) + assert res == '-' + oct(sys.maxint+1).replace('L', '').replace('l', '') + def test_unsigned(self): def dummy(i): i = r_uint(i) From arigo at codespeak.net Mon Feb 12 19:33:36 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 12 Feb 2007 19:33:36 +0100 (CET) Subject: [pypy-svn] r38628 - in pypy/dist/pypy/lib: . app_test Message-ID: <20070212183336.09FF31009A@code0.codespeak.net> Author: arigo Date: Mon Feb 12 19:33:33 2007 New Revision: 38628 Modified: pypy/dist/pypy/lib/app_test/test_struct_extra.py pypy/dist/pypy/lib/struct.py Log: Test and fix for struct.unpack() - broken handling of repetitions. Modified: pypy/dist/pypy/lib/app_test/test_struct_extra.py ============================================================================== --- pypy/dist/pypy/lib/app_test/test_struct_extra.py (original) +++ pypy/dist/pypy/lib/app_test/test_struct_extra.py Mon Feb 12 19:33:33 2007 @@ -5,3 +5,6 @@ assert struct.pack('= num: n = num-1 result.append(data[j+1:j+n+1]) j += num - i += 1 else: for n in range(num): result += [format['unpack'](data,j,format['size'],endianness)] j += format['size'] - i += 1 return tuple(result) From arigo at codespeak.net Mon Feb 12 19:36:51 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 12 Feb 2007 19:36:51 +0100 (CET) Subject: [pypy-svn] r38629 - pypy/dist/pypy/lib Message-ID: <20070212183651.B08F71009A@code0.codespeak.net> Author: arigo Date: Mon Feb 12 19:36:50 2007 New Revision: 38629 Modified: pypy/dist/pypy/lib/struct.py Log: Kill these lines, waiting for a more comprehensive test suite (in the fullness of time). Modified: pypy/dist/pypy/lib/struct.py ============================================================================== --- pypy/dist/pypy/lib/struct.py (original) +++ pypy/dist/pypy/lib/struct.py Mon Feb 12 19:36:50 2007 @@ -330,9 +330,3 @@ j += format['size'] return tuple(result) - -if __name__ == '__main__': - print pack_float(1.23,4,'little') - import struct - print (struct.pack('f',1.23), pack('f',1.23)) - print unpack('f',pack('f',1.23)) From arigo at codespeak.net Mon Feb 12 20:22:09 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 12 Feb 2007 20:22:09 +0100 (CET) Subject: [pypy-svn] r38630 - in pypy/dist/pypy: interpreter module/__builtin__ module/marshal objspace/std Message-ID: <20070212192209.2E4A81008D@code0.codespeak.net> Author: arigo Date: Mon Feb 12 20:22:03 2007 New Revision: 38630 Modified: pypy/dist/pypy/interpreter/argument.py pypy/dist/pypy/interpreter/baseobjspace.py pypy/dist/pypy/interpreter/error.py pypy/dist/pypy/module/__builtin__/importing.py pypy/dist/pypy/module/__builtin__/operation.py pypy/dist/pypy/module/marshal/interp_marshal.py pypy/dist/pypy/objspace/std/dictmultiobject.py pypy/dist/pypy/objspace/std/dictobject.py pypy/dist/pypy/objspace/std/dictstrobject.py pypy/dist/pypy/objspace/std/marshal_impl.py pypy/dist/pypy/objspace/std/objecttype.py pypy/dist/pypy/objspace/std/typeobject.py pypy/dist/pypy/objspace/std/unicodeobject.py Log: Removing most bare "except OperationError:" in PyPy. Added a space.findattr() helper. Modified: pypy/dist/pypy/interpreter/argument.py ============================================================================== --- pypy/dist/pypy/interpreter/argument.py (original) +++ pypy/dist/pypy/interpreter/argument.py Mon Feb 12 20:22:03 2007 @@ -390,7 +390,9 @@ for w_key in space.unpackiterable(w_starstararg): try: key = space.str_w(w_key) - except OperationError: + except OperationError, e: + if not e.match(space, space.w_TypeError): + raise raise OperationError(space.w_TypeError, space.wrap("keywords must be strings")) if key in d: Modified: pypy/dist/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/dist/pypy/interpreter/baseobjspace.py (original) +++ pypy/dist/pypy/interpreter/baseobjspace.py Mon Feb 12 20:22:03 2007 @@ -448,6 +448,15 @@ return None raise + def findattr(self, w_object, w_name): + try: + return self.getattr(w_object, w_name) + except OperationError, e: + # a PyPy extension: let SystemExit and KeyboardInterrupt go through + if e.async(self): + raise + return None + def newbool(self, b): if b: return self.w_True @@ -649,12 +658,15 @@ def abstract_issubclass(self, w_obj, w_cls, failhard=False): try: return self.issubtype(w_obj, w_cls) - except OperationError: + except OperationError, e: + if not e.match(self, self.w_TypeError): + raise try: self.getattr(w_cls, self.wrap('__bases__')) # type sanity check return self.recursive_issubclass(w_obj, w_cls) - except OperationError: - if failhard: + except OperationError, e: + if failhard or not (e.match(self, self.w_TypeError) or + e.match(self, self.w_AttributeError)): raise else: return self.w_False @@ -671,22 +683,25 @@ def abstract_isinstance(self, w_obj, w_cls): try: return self.isinstance(w_obj, w_cls) - except OperationError: + except OperationError, e: + if not e.match(self, self.w_TypeError): + raise try: w_objcls = self.getattr(w_obj, self.wrap('__class__')) return self.abstract_issubclass(w_objcls, w_cls) - except OperationError: + except OperationError, e: + if not (e.match(self, self.w_TypeError) or + e.match(self, self.w_AttributeError)): + raise return self.w_False def abstract_isclass(self, w_obj): if self.is_true(self.isinstance(w_obj, self.w_type)): return self.w_True - try: - self.getattr(w_obj, self.wrap('__bases__')) - except OperationError: - return self.w_False - else: + if self.findattr(w_obj, self.wrap('__bases__')) is not None: return self.w_True + else: + return self.w_False def abstract_getclass(self, w_obj): try: Modified: pypy/dist/pypy/interpreter/error.py ============================================================================== --- pypy/dist/pypy/interpreter/error.py (original) +++ pypy/dist/pypy/interpreter/error.py Mon Feb 12 20:22:03 2007 @@ -37,6 +37,11 @@ "Check if this application-level exception matches 'w_check_class'." return space.exception_match(self.w_type, w_check_class) + def async(self, space): + "Check if this is an exception that should better not be caught." + return (self.match(space, space.w_SystemExit) or + self.match(space, space.w_KeyboardInterrupt)) + def __str__(self): "NOT_RPYTHON: Convenience for tracebacks." return '[%s: %s]' % (self.w_type, self.w_value) @@ -186,16 +191,11 @@ # things like 'raise 1', but it is probably fine (i.e. # not ambiguous) to allow them in the explicit form # 'raise int, 1' - try: - space.getattr(w_value, space.wrap('__dict__')) - except OperationError: - try: - space.getattr(w_value, space.wrap('__slots__')) - except OperationError: - raise OperationError(space.w_TypeError, - space.wrap("raising built-in objects can " - "be ambiguous, " - "use 'raise type, value' instead")) + if (space.findattr(w_value, space.wrap('__dict__')) is None and + space.findattr(w_value, space.wrap('__slots__')) is None): + msg = ("raising built-in objects can be ambiguous, " + "use 'raise type, value' instead") + raise OperationError(space.w_TypeError, space.wrap(msg)) self.w_type = w_type self.w_value = w_value Modified: pypy/dist/pypy/module/__builtin__/importing.py ============================================================================== --- pypy/dist/pypy/module/__builtin__/importing.py (original) +++ pypy/dist/pypy/module/__builtin__/importing.py Mon Feb 12 20:22:03 2007 @@ -404,12 +404,7 @@ the header; if not, return NULL. Doesn't set an exception. """ - try: - w_marshal = space.getbuiltinmodule('marshal') - except OperationError: - #XXX debug - #print "skipped checking of", cpathname - return -1 + w_marshal = space.getbuiltinmodule('marshal') stream = streamio.open_file_as_stream(cpathname, "rb") magic = _r_long(stream) try: @@ -470,22 +465,13 @@ Errors are ignored, if a write error occurs an attempt is made to remove the file. """ - # see if marshal exists, already. - # if not, skip the writing. - try: - w_marshal = space.getbuiltinmodule('marshal') - except OperationError: - # XXX debug - #print "skipped writing of", cpathname - return - else: - pass - #XXX debug - #print "indeed writing", cpathname + w_marshal = space.getbuiltinmodule('marshal') try: w_str = space.call_method(w_marshal, 'dumps', space.wrap(co)) strbuf = space.str_w(w_str) - except OperationError: + except OperationError, e: + if e.async(self): + raise #print "Problem while marshalling %s, skipping" % cpathname return # Modified: pypy/dist/pypy/module/__builtin__/operation.py ============================================================================== --- pypy/dist/pypy/module/__builtin__/operation.py (original) +++ pypy/dist/pypy/module/__builtin__/operation.py Mon Feb 12 20:22:03 2007 @@ -60,15 +60,10 @@ """Return whether the object has an attribute with the given name. (This is done by calling getattr(object, name) and catching exceptions.)""" w_name = checkattrname(space, w_name) - try: - space.getattr(w_object, w_name) - except OperationError, e: - # a PyPy extension: let SystemExit and KeyboardInterrupt go through - if (e.match(space, space.w_SystemExit) or - e.match(space, space.w_KeyboardInterrupt)): - raise + if space.findattr(w_object, w_name) is not None: + return space.w_True + else: return space.w_False - return space.w_True def hash(space, w_object): """Return a hash value for the object. Two objects which compare as Modified: pypy/dist/pypy/module/marshal/interp_marshal.py ============================================================================== --- pypy/dist/pypy/module/marshal/interp_marshal.py (original) +++ pypy/dist/pypy/module/marshal/interp_marshal.py Mon Feb 12 20:22:03 2007 @@ -47,7 +47,9 @@ try: self.func = space.getattr(w_f, space.wrap('write')) # XXX how to check if it is callable? - except OperationError: + except OperationError, e: + if not e.match(space, space.w_AttributeError): + raise raise OperationError(space.w_TypeError, space.wrap( 'marshal.dump() 2nd arg must be file-like object')) @@ -67,7 +69,9 @@ try: self.func = space.getattr(w_f, space.wrap('read')) # XXX how to check if it is callable? - except OperationError: + except OperationError, e: + if not e.match(space, space.w_AttributeError): + raise raise OperationError(space.w_TypeError, space.wrap( 'marshal.load() arg must be file-like object')) @@ -454,7 +458,9 @@ Unmarshaller.__init__(self, space, None) try: self.bufstr = space.str_w(w_str) - except OperationError: + except OperationError, e: + if not e.match(space, space.w_TypeError): + raise raise OperationError(space.w_TypeError, space.wrap( 'marshal.loads() arg must be string')) self.bufpos = 0 Modified: pypy/dist/pypy/objspace/std/dictmultiobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/dictmultiobject.py (original) +++ pypy/dist/pypy/objspace/std/dictmultiobject.py Mon Feb 12 20:22:03 2007 @@ -1033,9 +1033,7 @@ [W_DictMultiObject(space)]) # default argument # w_dict.implementation = space.emptydictimpl # ^^^ disabled only for CPython compatibility - try: - space.getattr(w_src, space.wrap("keys")) - except OperationError: + if space.findattr(w_src, space.wrap("keys")) is None: list_of_w_pairs = space.unpackiterable(w_src) for w_pair in list_of_w_pairs: pair = space.unpackiterable(w_pair) Modified: pypy/dist/pypy/objspace/std/dictobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/dictobject.py (original) +++ pypy/dist/pypy/objspace/std/dictobject.py Mon Feb 12 20:22:03 2007 @@ -52,9 +52,7 @@ (['seq_or_map'], None, 'kwargs'), # signature [W_DictObject(space)]) # default argument # w_dict.content.clear() - disabled only for CPython compatibility - try: - space.getattr(w_src, space.wrap("keys")) - except OperationError: + if space.findattr(w_src, space.wrap("keys")) is None: list_of_w_pairs = space.unpackiterable(w_src) for w_pair in list_of_w_pairs: pair = space.unpackiterable(w_pair) Modified: pypy/dist/pypy/objspace/std/dictstrobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/dictstrobject.py (original) +++ pypy/dist/pypy/objspace/std/dictstrobject.py Mon Feb 12 20:22:03 2007 @@ -109,9 +109,7 @@ #else: - # w_dict.content.clear() - - try: - space.getattr(w_src, space.wrap("keys")) - except OperationError: + if space.findattr(w_src, space.wrap("keys")) is None: list_of_w_pairs = space.unpackiterable(w_src) for w_pair in list_of_w_pairs: pair = space.unpackiterable(w_pair) 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 Mon Feb 12 20:22:03 2007 @@ -421,8 +421,11 @@ w_obj = u.get_w_obj(False) try: return u.space.str_w(w_obj) - except OperationError: - u.raise_exc('invalid marshal data for code object') + except OperationError, e: + if e.match(u.space, u.space.w_TypeError): + u.raise_exc('invalid marshal data for code object') + else: + raise def unmarshal_strlist(u, tc): lng = u.atom_lng(tc) Modified: pypy/dist/pypy/objspace/std/objecttype.py ============================================================================== --- pypy/dist/pypy/objspace/std/objecttype.py (original) +++ pypy/dist/pypy/objspace/std/objecttype.py Mon Feb 12 20:22:03 2007 @@ -59,9 +59,8 @@ def descr__reduce_ex__(space, w_obj, proto=0): w_st_reduce = space.wrap('__reduce__') - try: w_reduce = space.getattr(w_obj, w_st_reduce) - except OperationError: pass - else: + w_reduce = space.findattr(w_obj, w_st_reduce) + if w_reduce is not None: w_cls = space.getattr(w_obj, space.wrap('__class__')) w_cls_reduce_meth = space.getattr(w_cls, w_st_reduce) w_cls_reduce = space.getattr(w_cls_reduce_meth, space.wrap('im_func')) Modified: pypy/dist/pypy/objspace/std/typeobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/typeobject.py (original) +++ pypy/dist/pypy/objspace/std/typeobject.py Mon Feb 12 20:22:03 2007 @@ -81,11 +81,8 @@ else: w_globals = caller.w_globals w_str_name = space.wrap('__name__') - try: - w_name = space.getitem(w_globals, w_str_name) - except OperationError: - pass - else: + w_name = space.finditem(w_globals, w_str_name) + if w_name is not None: dict_w['__module__'] = w_name # find the most specific typedef instancetypedef = object_typedef Modified: pypy/dist/pypy/objspace/std/unicodeobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/unicodeobject.py (original) +++ pypy/dist/pypy/objspace/std/unicodeobject.py Mon Feb 12 20:22:03 2007 @@ -502,9 +502,12 @@ def _to_unichar_w(space, w_char): try: w_unichar = unicodetype.unicode_from_object(space, w_char) - except OperationError: - # XXX don't completely eat this exception - raise OperationError(space.w_TypeError, space.wrap('The fill character cannot be converted to Unicode')) + except OperationError, e: + if e.match(space, space.w_TypeError): + msg = 'The fill character cannot be converted to Unicode' + raise OperationError(space.w_TypeError, space.wrap(msg)) + else: + raise if space.int_w(space.len(w_unichar)) != 1: raise OperationError(space.w_TypeError, space.wrap('The fill character must be exactly one character long')) From arigo at codespeak.net Mon Feb 12 20:27:31 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 12 Feb 2007 20:27:31 +0100 (CET) Subject: [pypy-svn] r38631 - pypy/dist/pypy/module/thread Message-ID: <20070212192731.C46621009A@code0.codespeak.net> Author: arigo Date: Mon Feb 12 20:27:30 2007 New Revision: 38631 Modified: pypy/dist/pypy/module/thread/__init__.py Log: Add the obsolete thread.start_new() synonym. Modified: pypy/dist/pypy/module/thread/__init__.py ============================================================================== --- pypy/dist/pypy/module/thread/__init__.py (original) +++ pypy/dist/pypy/module/thread/__init__.py Mon Feb 12 20:27:30 2007 @@ -11,6 +11,7 @@ interpleveldefs = { 'start_new_thread': 'os_thread.start_new_thread', + 'start_new': 'os_thread.start_new_thread', # obsolete syn. 'get_ident': 'os_thread.get_ident', 'allocate_lock': 'os_lock.allocate_lock', 'allocate': 'os_lock.allocate_lock', # obsolete synonym From arigo at codespeak.net Mon Feb 12 20:33:50 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 12 Feb 2007 20:33:50 +0100 (CET) Subject: [pypy-svn] r38632 - in pypy/dist/pypy/lib: . app_test Message-ID: <20070212193350.2019C1009C@code0.codespeak.net> Author: arigo Date: Mon Feb 12 20:33:49 2007 New Revision: 38632 Modified: pypy/dist/pypy/lib/_structseq.py pypy/dist/pypy/lib/app_test/test_structseq.py Log: Set n_unnamed_fields anyway, even if it's always 0 here. Modified: pypy/dist/pypy/lib/_structseq.py ============================================================================== --- pypy/dist/pypy/lib/_structseq.py (original) +++ pypy/dist/pypy/lib/_structseq.py Mon Feb 12 20:33:49 2007 @@ -50,6 +50,7 @@ extra_fields.pop(0) n_sequence_fields += 1 dict['n_sequence_fields'] = n_sequence_fields + dict['n_unnamed_fields'] = 0 # no fully anonymous fields in PyPy extra_fields = [field for index, field in extra_fields] for field in extra_fields: Modified: pypy/dist/pypy/lib/app_test/test_structseq.py ============================================================================== --- pypy/dist/pypy/lib/app_test/test_structseq.py (original) +++ pypy/dist/pypy/lib/app_test/test_structseq.py Mon Feb 12 20:33:49 2007 @@ -27,6 +27,7 @@ assert mydata.st_mode.__doc__ == "protection bits" assert mydata.n_fields == 14 assert mydata.n_sequence_fields == 10 + assert mydata.n_unnamed_fields == 0 def test_mydata(): x = mydata(range(100, 111)) From arigo at codespeak.net Mon Feb 12 20:39:15 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 12 Feb 2007 20:39:15 +0100 (CET) Subject: [pypy-svn] r38633 - pypy/dist/pypy/module/mmap Message-ID: <20070212193915.8AD741008D@code0.codespeak.net> Author: arigo Date: Mon Feb 12 20:39:13 2007 New Revision: 38633 Modified: pypy/dist/pypy/module/mmap/interp_mmap.py Log: Add the __module__ of the mmap type. Modified: pypy/dist/pypy/module/mmap/interp_mmap.py ============================================================================== --- pypy/dist/pypy/module/mmap/interp_mmap.py (original) +++ pypy/dist/pypy/module/mmap/interp_mmap.py Mon Feb 12 20:39:13 2007 @@ -590,6 +590,7 @@ flush = interp2app(W_MMap.flush), move = interp2app(W_MMap.move), resize = interp2app(W_MMap.resize), + __module__ = "mmap", __len__ = interp2app(W_MMap.__len__), __getitem__ = interp2app(W_MMap.descr_getitem), From fijal at codespeak.net Mon Feb 12 20:40:29 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 12 Feb 2007 20:40:29 +0100 (CET) Subject: [pypy-svn] r38634 - pypy/dist/pypy/translator/js/test Message-ID: <20070212194029.2F4D11008D@code0.codespeak.net> Author: fijal Date: Mon Feb 12 20:40:28 2007 New Revision: 38634 Modified: pypy/dist/pypy/translator/js/test/runtest.py Log: Provide better testing machinery for test_rpbc to pass 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 Mon Feb 12 20:40:28 2007 @@ -27,14 +27,20 @@ return True class compile_function(object): - def __init__(self, function, annotations, stackless=False, view=False, html=None, is_interactive=False, root = None, run_browser = True): + def __init__(self, function, annotations, stackless=False, view=False, html=None, is_interactive=False, root = None, run_browser = True, policy = None): if not use_browsertest and not _CLI_is_on_path(): py.test.skip('Javascript CLI (js) not found') self.html = html self.is_interactive = is_interactive t = TranslationContext() - ann = t.buildannotator() + + if policy is None: + from pypy.annotation.policy import AnnotatorPolicy + policy = AnnotatorPolicy() + policy.allow_someobjects = False + + ann = t.buildannotator(policy=policy) ann.build_types(function, annotations) if view or option.view: t.view() @@ -136,7 +142,7 @@ reinterpret = classmethod(reinterpret) class JsTest(BaseRtypingTest, OORtypeMixin): - def _compile(self, _fn, args): + def _compile(self, _fn, args, policy=None): argnames = _fn.func_code.co_varnames[:_fn.func_code.co_argcount] source = py.code.Source(""" def %s(): @@ -149,18 +155,12 @@ % (_fn.func_name, ",".join(["%s=NonConstant(%s)" % (name,i) for name, i in zip(argnames, args)]))) exec source.compile() in locals() - return compile_function(locals()[_fn.func_name], []) + return compile_function(locals()[_fn.func_name], [], policy=policy) - def interpret(self, fn, args): - #def f(args): - # fn(*args) - - f = self._compile(fn, args) + def interpret(self, fn, args, policy=None): + f = self._compile(fn, args, policy) res = f(*args) return res - #if isinstance(res, ExceptionWrapper): - # raise res - #return res def interpret_raises(self, exception, fn, args): #import exceptions # needed by eval @@ -197,7 +197,7 @@ return bool(m) def read_attr(self, obj, name): - py.test.skip('read_attr not supported on gencli tests') + py.test.skip('read_attr not supported on genjs tests') def check_source_contains(compiled_function, pattern): import re From fijal at codespeak.net Mon Feb 12 20:41:28 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 12 Feb 2007 20:41:28 +0100 (CET) Subject: [pypy-svn] r38635 - in pypy/dist/pypy/translator/js/modules: . test Message-ID: <20070212194128.14BA31009C@code0.codespeak.net> Author: fijal Date: Mon Feb 12 20:41:26 2007 New Revision: 38635 Modified: pypy/dist/pypy/translator/js/modules/dom.py pypy/dist/pypy/translator/js/modules/test/test_dom.py Log: * Kill document.location * window.location is now an object * we need to provide handling of it in python to be tests-aware Modified: pypy/dist/pypy/translator/js/modules/dom.py ============================================================================== --- pypy/dist/pypy/translator/js/modules/dom.py (original) +++ pypy/dist/pypy/translator/js/modules/dom.py Mon Feb 12 20:41:26 2007 @@ -262,6 +262,24 @@ # Window is the main environment, the root node of the JS object tree +class Location(BasicExternal): + _fields = { + 'hostname' : str, + 'href' : str, + 'hash' : str, + 'host' : str, + 'pathname' : str, + 'port' : str, + 'protocol' : str, + 'search' : str, + } + _methods = { + 'assign' : _callable([str]), + 'reload' : _callable([bool]), + 'replace' : _callable([str]), + 'toString' : _callable([], str), + } + class Window(EventTarget): def __init__(self, html=('Untitled document' ''), parent=None): @@ -458,7 +476,6 @@ 'lastModified' : str, 'linkColor' : str, 'links' : [Element], - 'location' : str, 'referrer' : str, 'title' : str, 'URL' : str, @@ -498,7 +515,7 @@ 'innerHeight' : int, 'innerWidth' : int, 'length' : int, - 'location' : str, + 'location' : Location, 'name' : str, # 'preference' : # denied in gecko 'opener' : Window, Modified: pypy/dist/pypy/translator/js/modules/test/test_dom.py ============================================================================== --- pypy/dist/pypy/translator/js/modules/test/test_dom.py (original) +++ pypy/dist/pypy/translator/js/modules/test/test_dom.py Mon Feb 12 20:41:26 2007 @@ -365,6 +365,9 @@ assert dom._serialize_html(body) == ('') +def test_document_location(): + py.test.skip("To be written") + def test_build(): py.test.skip('B?rken') global TRANSLATING From fijal at codespeak.net Mon Feb 12 20:45:55 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 12 Feb 2007 20:45:55 +0100 (CET) Subject: [pypy-svn] r38636 - pypy/dist/pypy/translator/js/modules Message-ID: <20070212194555.D5BD1100A8@code0.codespeak.net> Author: fijal Date: Mon Feb 12 20:45:52 2007 New Revision: 38636 Modified: pypy/dist/pypy/translator/js/modules/dom.py Log: Ooops, wrong level Modified: pypy/dist/pypy/translator/js/modules/dom.py ============================================================================== --- pypy/dist/pypy/translator/js/modules/dom.py (original) +++ pypy/dist/pypy/translator/js/modules/dom.py Mon Feb 12 20:45:52 2007 @@ -274,10 +274,10 @@ 'search' : str, } _methods = { - 'assign' : _callable([str]), - 'reload' : _callable([bool]), - 'replace' : _callable([str]), - 'toString' : _callable([], str), + 'assign' : MethodDesc([str]), + 'reload' : MethodDesc([bool]), + 'replace' : MethodDesc([str]), + 'toString' : MethodDesc([], str), } class Window(EventTarget): From fijal at codespeak.net Mon Feb 12 20:52:36 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 12 Feb 2007 20:52:36 +0100 (CET) Subject: [pypy-svn] r38637 - in pypy/dist/pypy/translator/js/examples: . data Message-ID: <20070212195236.4E115100AD@code0.codespeak.net> Author: fijal Date: Mon Feb 12 20:52:34 2007 New Revision: 38637 Added: pypy/dist/pypy/translator/js/examples/data/launcher.html Modified: pypy/dist/pypy/translator/js/examples/data/index.html pypy/dist/pypy/translator/js/examples/over_client.py pypy/dist/pypy/translator/js/examples/overmind.py Log: Update to overmind Modified: pypy/dist/pypy/translator/js/examples/data/index.html ============================================================================== --- pypy/dist/pypy/translator/js/examples/data/index.html (original) +++ pypy/dist/pypy/translator/js/examples/data/index.html Mon Feb 12 20:52:34 2007 @@ -7,7 +7,7 @@

This site presents various demos and tutorials about pypy.js

Python console:

No more, no less - Launch one for me + Launch one for me Source

Remote terminal:

Added: pypy/dist/pypy/translator/js/examples/data/launcher.html ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/js/examples/data/launcher.html Mon Feb 12 20:52:34 2007 @@ -0,0 +1,9 @@ + + + Python console + + + +

Console Launching, please wait...

+ + \ No newline at end of file Modified: pypy/dist/pypy/translator/js/examples/over_client.py ============================================================================== --- pypy/dist/pypy/translator/js/examples/over_client.py (original) +++ pypy/dist/pypy/translator/js/examples/over_client.py Mon Feb 12 20:52:34 2007 @@ -5,8 +5,9 @@ from pypy.translator.js.examples.overmind import exported_methods from pypy.translator.js.modules import dom -def callback(arg): - dom.window.location = "http://localhost:%d" % arg +def callback(port): + hname = dom.window.location.hostname + dom.window.location.assign("http://%s:%d" % (hname, port)) def launch_console(): exported_methods.launch_console(callback) Modified: pypy/dist/pypy/translator/js/examples/overmind.py ============================================================================== --- pypy/dist/pypy/translator/js/examples/overmind.py (original) +++ pypy/dist/pypy/translator/js/examples/overmind.py Mon Feb 12 20:52:34 2007 @@ -16,7 +16,7 @@ tempdir = py.test.ensuretemp("infos") TIMEOUT = 100 -def launch_console_in_new_process(): +def launch_console_in_new_thread(): from pypy.translator.js.examples import pythonconsole httpd = server.start_server(server_address=('', 0), handler=pythonconsole.RequestHandler, timeout=TIMEOUT, @@ -33,8 +33,8 @@ if we want to make this multiplayer, we need additional locking XXX """ - return launch_console_in_new_process() - + return launch_console_in_new_thread() + exported_methods = ExportedMethods() def js_source(function_list): @@ -44,6 +44,7 @@ class Handler(server.Handler): static_dir = str(py.path.local(__file__).dirpath().join("data")) index = server.Static() + console = server.Static(os.path.join(static_dir, "launcher.html")) exported_methods = exported_methods def source_js(self): From fijal at codespeak.net Mon Feb 12 20:54:21 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 12 Feb 2007 20:54:21 +0100 (CET) Subject: [pypy-svn] r38638 - pypy/dist/pypy/translator/js/examples Message-ID: <20070212195421.F23E8100AD@code0.codespeak.net> Author: fijal Date: Mon Feb 12 20:54:21 2007 New Revision: 38638 Modified: pypy/dist/pypy/translator/js/examples/overmind.py Log: import autopath as well Modified: pypy/dist/pypy/translator/js/examples/overmind.py ============================================================================== --- pypy/dist/pypy/translator/js/examples/overmind.py (original) +++ pypy/dist/pypy/translator/js/examples/overmind.py Mon Feb 12 20:54:21 2007 @@ -3,6 +3,8 @@ run them when needed """ +import autopath + from pypy.translator.js.lib import server from pypy.translator.js.lib.support import callback from pypy.rpython.extfunc import _callable From hpk at codespeak.net Mon Feb 12 21:02:11 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Mon, 12 Feb 2007 21:02:11 +0100 (CET) Subject: [pypy-svn] r38639 - pypy/dist/pypy/module/__builtin__ Message-ID: <20070212200211.423C610098@code0.codespeak.net> Author: hpk Date: Mon Feb 12 21:02:09 2007 New Revision: 38639 Modified: pypy/dist/pypy/module/__builtin__/importing.py Log: fix self -> space Modified: pypy/dist/pypy/module/__builtin__/importing.py ============================================================================== --- pypy/dist/pypy/module/__builtin__/importing.py (original) +++ pypy/dist/pypy/module/__builtin__/importing.py Mon Feb 12 21:02:09 2007 @@ -470,7 +470,7 @@ w_str = space.call_method(w_marshal, 'dumps', space.wrap(co)) strbuf = space.str_w(w_str) except OperationError, e: - if e.async(self): + if e.async(space): raise #print "Problem while marshalling %s, skipping" % cpathname return From arigo at codespeak.net Mon Feb 12 21:31:51 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 12 Feb 2007 21:31:51 +0100 (CET) Subject: [pypy-svn] r38641 - in pypy/dist/pypy/interpreter: astcompiler stablecompiler Message-ID: <20070212203151.A43EA1009A@code0.codespeak.net> Author: arigo Date: Mon Feb 12 21:31:48 2007 New Revision: 38641 Modified: pypy/dist/pypy/interpreter/astcompiler/pyassem.py pypy/dist/pypy/interpreter/stablecompiler/pyassem.py Log: Don't put *every* name around in co_varnames! They end up reserving fastlocal slots and make our frames bigger, producing garbage more quickly at run-time. Modified: pypy/dist/pypy/interpreter/astcompiler/pyassem.py ============================================================================== --- pypy/dist/pypy/interpreter/astcompiler/pyassem.py (original) +++ pypy/dist/pypy/interpreter/astcompiler/pyassem.py Mon Feb 12 21:31:48 2007 @@ -664,12 +664,6 @@ def _lookupName(self, name, list): """Return index of name in list, appending if necessary - - This routine uses a list instead of a dictionary, because a - dictionary can't store two different keys if the keys have the - same value but different types, e.g. 2 and 2L. The compiler - must treat these two separately, so it does an explicit type - comparison before comparing the values. """ assert isinstance(name, str) for i in range(len(list)): @@ -698,6 +692,13 @@ return False def _lookupConst(self, w_obj, list_w): + """ + This routine uses a list instead of a dictionary, because a + dictionary can't store two different keys if the keys have the + same value but different types, e.g. 2 and 2L. The compiler + must treat these two separately, so it does an explicit type + comparison before comparing the values. + """ space = self.space w_obj_type = space.type(w_obj) for i in range(len(list_w)): @@ -731,8 +732,6 @@ def _convert_NAME(self, inst): assert isinstance(inst, InstrName) arg = inst.name - if not self.klass: - self._lookupName(arg, self.varnames) index = self._lookupName(arg, self.names) return InstrInt(inst.op, index) _convert_LOAD_NAME = _convert_NAME @@ -751,7 +750,6 @@ assert isinstance(inst, InstrName) arg = inst.name self._lookupName(arg, self.names) - self._lookupName(arg, self.varnames) index = self._lookupName(arg, self.closure) return InstrInt(inst.op, index) _convert_LOAD_DEREF = _convert_DEREF @@ -760,7 +758,6 @@ def _convert_LOAD_CLOSURE(self, inst): assert isinstance(inst, InstrName) arg = inst.name - self._lookupName(arg, self.varnames) index = self._lookupName(arg, self.closure) return InstrInt(inst.op, index) Modified: pypy/dist/pypy/interpreter/stablecompiler/pyassem.py ============================================================================== --- pypy/dist/pypy/interpreter/stablecompiler/pyassem.py (original) +++ pypy/dist/pypy/interpreter/stablecompiler/pyassem.py Mon Feb 12 21:31:48 2007 @@ -557,13 +557,9 @@ _convert_DELETE_FAST = _convert_LOAD_FAST def _convert_LOAD_NAME(self, arg): - if self.klass is None: - self._lookupName(arg, self.varnames) return self._lookupName(arg, self.names) def _convert_NAME(self, arg): - if self.klass is None: - self._lookupName(arg, self.varnames) return self._lookupName(arg, self.names) _convert_STORE_NAME = _convert_NAME _convert_DELETE_NAME = _convert_NAME @@ -578,13 +574,11 @@ def _convert_DEREF(self, arg): self._lookupName(arg, self.names) - self._lookupName(arg, self.varnames) return self._lookupName(arg, self.closure) _convert_LOAD_DEREF = _convert_DEREF _convert_STORE_DEREF = _convert_DEREF def _convert_LOAD_CLOSURE(self, arg): - self._lookupName(arg, self.varnames) return self._lookupName(arg, self.closure) _cmp = list(dis.cmp_op) From arigo at codespeak.net Mon Feb 12 21:50:53 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 12 Feb 2007 21:50:53 +0100 (CET) Subject: [pypy-svn] r38642 - pypy/dist/lib-python/modified-2.4.1/test Message-ID: <20070212205053.94EFD1008E@code0.codespeak.net> Author: arigo Date: Mon Feb 12 21:50:52 2007 New Revision: 38642 Modified: pypy/dist/lib-python/modified-2.4.1/test/test_tempfile.py Log: Stop relying on the GC for the deletion of these temp files. This doesn't work if the test tries to remove the containing temp directory just after the last reference to one of these objects went away. Modified: pypy/dist/lib-python/modified-2.4.1/test/test_tempfile.py ============================================================================== --- pypy/dist/lib-python/modified-2.4.1/test/test_tempfile.py (original) +++ pypy/dist/lib-python/modified-2.4.1/test/test_tempfile.py Mon Feb 12 21:50:52 2007 @@ -222,7 +222,7 @@ def write(self, str): os.write(self.fd, str) - def __del__(self): + def close(self): self._close(self.fd) self._unlink(self.name) @@ -237,25 +237,32 @@ self.nameCheck(file.name, dir, pre, suf) return file + def create_blat(self, *args, **kwds): + f = self.do_create(*args, **kwds) + f.write("blat") + f.close() + def test_basic(self): # _mkstemp_inner can create files - self.do_create().write("blat") - self.do_create(pre="a").write("blat") - self.do_create(suf="b").write("blat") - self.do_create(pre="a", suf="b").write("blat") - self.do_create(pre="aa", suf=".txt").write("blat") + self.create_blat() + self.create_blat(pre="a") + self.create_blat(suf="b") + self.create_blat(pre="a", suf="b") + self.create_blat(pre="aa", suf=".txt") def test_basic_many(self): # _mkstemp_inner can create many files (stochastic) extant = range(TEST_FILES) for i in extant: extant[i] = self.do_create(pre="aa") + for f in extant: + f.close() def test_choose_directory(self): # _mkstemp_inner can create files in a user-selected directory dir = tempfile.mkdtemp() try: - self.do_create(dir=dir).write("blat") + self.create_blat(dir=dir) finally: os.rmdir(dir) @@ -266,6 +273,7 @@ file = self.do_create() mode = stat.S_IMODE(os.stat(file.name).st_mode) + file.close() expected = 0600 if sys.platform in ('win32', 'os2emx', 'mac'): # There's no distinction among 'user', 'group' and 'world'; @@ -308,6 +316,7 @@ decorated = sys.executable retval = os.spawnl(os.P_WAIT, sys.executable, decorated, tester, v, fd) + file.close() self.failIf(retval < 0, "child process caught fatal signal %d" % -retval) self.failIf(retval > 0, "child process reports failure") @@ -317,7 +326,7 @@ if not has_textmode: return # ugh, can't use TestSkipped. - self.do_create(bin=0).write("blat\n") + self.create_blat(bin=0) # XXX should test that the file really is a text file test_classes.append(test__mkstemp_inner) From fijal at codespeak.net Mon Feb 12 22:12:47 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 12 Feb 2007 22:12:47 +0100 (CET) Subject: [pypy-svn] r38643 - in pypy/dist/pypy/translator/js: examples lib lib/test tutorial Message-ID: <20070212211247.A81E21009C@code0.codespeak.net> Author: fijal Date: Mon Feb 12 22:12:45 2007 New Revision: 38643 Modified: pypy/dist/pypy/translator/js/examples/overmind.py pypy/dist/pypy/translator/js/lib/server.py pypy/dist/pypy/translator/js/lib/test/test_server.py pypy/dist/pypy/translator/js/tutorial/step1.py pypy/dist/pypy/translator/js/tutorial/step2.py pypy/dist/pypy/translator/js/tutorial/step3.py Log: * Some improvements to API. * Server initialisation is bit saner, but I'm not sure how well this is regarding posix--semantics Modified: pypy/dist/pypy/translator/js/examples/overmind.py ============================================================================== --- pypy/dist/pypy/translator/js/examples/overmind.py (original) +++ pypy/dist/pypy/translator/js/examples/overmind.py Mon Feb 12 22:12:45 2007 @@ -15,17 +15,22 @@ import py FUNCTION_LIST = ['launch_console'] -tempdir = py.test.ensuretemp("infos") TIMEOUT = 100 +pids = [] def launch_console_in_new_thread(): from pypy.translator.js.examples import pythonconsole - httpd = server.start_server(server_address=('', 0), + httpd = server.create_server(server_address=('', 0), handler=pythonconsole.RequestHandler, timeout=TIMEOUT, - port_file=tempdir.join("console_pid"), - fork=True, server=pythonconsole.Server) - pythonconsole.httpd = httpd - port = int(tempdir.join("console_pid").read()) + server=pythonconsole.Server) + port = httpd.server_port + pid = os.fork() + if not pid: + pythonconsole.httpd = httpd + httpd.serve_forever() + os._exit(0) + del httpd + pids.append(pid) return port class ExportedMethods(server.ExportedMethods): @@ -59,4 +64,11 @@ source_js.exposed = True if __name__ == '__main__': - server.start_server(handler=Handler) + try: + server.create_server(handler=Handler).serve_forever() + except KeyboardInterrupt: + for pid in pids: + # eventually os.kill stuff + os.kill(pid, 15) + os.waitpid(pid, 0) + Modified: pypy/dist/pypy/translator/js/lib/server.py ============================================================================== --- pypy/dist/pypy/translator/js/lib/server.py (original) +++ pypy/dist/pypy/translator/js/lib/server.py Mon Feb 12 22:12:45 2007 @@ -117,8 +117,14 @@ def __call__(self): return open(self.path).read() -def start_server(server_address = ('', 8000), handler=TestHandler, fork=False, - timeout=None, server=HTTPServer, port_file=None): +def create_server(server_address = ('', 8000), handler=TestHandler, + timeout=None, server=HTTPServer): + """ Parameters: + spawn - create new thread and return (by default it doesn't return) + fork - do a real fork + timeout - kill process after X seconds (actually doesn't work for threads) + port_file - function to be called with port number + """ patch_handler(handler) httpd = server(server_address, handler) if timeout: @@ -132,18 +138,20 @@ import thread thread.start_new_thread(f, (httpd,)) httpd.last_activity = time.time() - print "Server started, listening on %s:%s" %\ (httpd.server_address[0],httpd.server_port) - if port_file: - # this is strange hack to allow exchange of port information - py.path.local(port_file).write(str(httpd.server_port)) - if fork: - import thread - thread.start_new_thread(httpd.serve_forever, ()) - return httpd - else: - httpd.serve_forever() + return httpd + +def start_server_in_new_thread(server): + import thread + thread.start_new_thread(server.serve_forever, ()) + +def start_server_in_new_process(server): + pid = os.fork() + if not pid: + httpd.server_forever() + os._exit(0) + return pid Handler = TestHandler # deprecate TestHandler name Modified: pypy/dist/pypy/translator/js/lib/test/test_server.py ============================================================================== --- pypy/dist/pypy/translator/js/lib/test/test_server.py (original) +++ pypy/dist/pypy/translator/js/lib/test/test_server.py Mon Feb 12 22:12:45 2007 @@ -20,8 +20,9 @@ assert URLopener().open("http://127.0.0.1:21210/index").read() == "xxx" def test_own_startup(): - server.start_server(server_address=('127.0.0.1', 21211), - handler=Handler, fork=True) + httpd = server.create_server(server_address=('127.0.0.1', 21211), + handler=Handler) + server.start_server_in_new_thread(httpd) assert URLopener().open("http://127.0.0.1:21210/index").read() == "xxx" def test_static_page(): @@ -52,11 +53,5 @@ thread.start_new_thread(httpd.serve_forever, ()) assert URLopener().open("http://127.0.0.1:21213/index").read() == \ "" - -def test_port_file(): - tmpdir = py.test.ensuretemp("port_file") - server.start_server(('127.0.0.1', 21214), port_file=tmpdir.join("f"), - fork=True) - assert tmpdir.join("f").read() == "21214" Modified: pypy/dist/pypy/translator/js/tutorial/step1.py ============================================================================== --- pypy/dist/pypy/translator/js/tutorial/step1.py (original) +++ pypy/dist/pypy/translator/js/tutorial/step1.py Mon Feb 12 22:12:45 2007 @@ -24,4 +24,4 @@ # let's start our server, # this will create running server instance on port 8000 by default, # which will run until we press Control-C - server.start_server(handler=Handler) + server.create_server(handler=Handler).serve_forever() Modified: pypy/dist/pypy/translator/js/tutorial/step2.py ============================================================================== --- pypy/dist/pypy/translator/js/tutorial/step2.py (original) +++ pypy/dist/pypy/translator/js/tutorial/step2.py Mon Feb 12 22:12:45 2007 @@ -49,4 +49,4 @@ # server start, same as before if __name__ == '__main__': - server.start_server(handler=Handler) + server.create_server(handler=Handler).serve_forever() Modified: pypy/dist/pypy/translator/js/tutorial/step3.py ============================================================================== --- pypy/dist/pypy/translator/js/tutorial/step3.py (original) +++ pypy/dist/pypy/translator/js/tutorial/step3.py Mon Feb 12 22:12:45 2007 @@ -57,4 +57,4 @@ # server start, same as before if __name__ == '__main__': - server.start_server(handler=Handler) + server.create_server(handler=Handler).serve_forever() From arigo at codespeak.net Mon Feb 12 22:35:48 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 12 Feb 2007 22:35:48 +0100 (CET) Subject: [pypy-svn] r38644 - in pypy/dist/pypy: module/_sre/test rlib/rsre Message-ID: <20070212213548.36E1310098@code0.codespeak.net> Author: arigo Date: Mon Feb 12 22:35:46 2007 New Revision: 38644 Modified: pypy/dist/pypy/module/_sre/test/test_app_sre.py pypy/dist/pypy/rlib/rsre/rsre_core.py Log: Fix bug in sre: missing normalization phase done by CPython during the conversion from state->marks to match->marks. Modified: pypy/dist/pypy/module/_sre/test/test_app_sre.py ============================================================================== --- pypy/dist/pypy/module/_sre/test/test_app_sre.py (original) +++ pypy/dist/pypy/module/_sre/test/test_app_sre.py Mon Feb 12 22:35:46 2007 @@ -194,6 +194,31 @@ m = re.match('hel+', a) assert m.end() == 4 + def test_group_bug(self): + import re + r = re.compile(r""" + \&(?: + (?P\&) | + (?P[_a-z][_a-z0-9]*) | + {(?P[_a-z][_a-z0-9]*)} | + (?P) + ) + """, re.IGNORECASE | re.VERBOSE) + matches = list(r.finditer('this &gift is for &{who} &&')) + assert len(matches) == 3 + assert matches[0].groupdict() == {'escaped': None, + 'named': 'gift', + 'braced': None, + 'invalid': None} + assert matches[1].groupdict() == {'escaped': None, + 'named': None, + 'braced': 'who', + 'invalid': None} + assert matches[2].groupdict() == {'escaped': '&', + 'named': None, + 'braced': None, + 'invalid': None} + class AppTestSreScanner: Modified: pypy/dist/pypy/rlib/rsre/rsre_core.py ============================================================================== --- pypy/dist/pypy/rlib/rsre/rsre_core.py (original) +++ pypy/dist/pypy/rlib/rsre/rsre_core.py Mon Feb 12 22:35:46 2007 @@ -37,11 +37,14 @@ regs = [(self.start, self.string_position)] for group in range(group_count): mark_index = 2 * group + start = end = -1 if mark_index + 1 < len(self.marks): - regs.append((self.marks[mark_index], - self.marks[mark_index + 1])) - else: - regs.append((-1, -1)) + start1 = self.marks[mark_index] + end1 = self.marks[mark_index + 1] + if start1 >= 0 and end1 >= 0: + start = start1 + end = end1 + regs.append((start, end)) return regs def set_mark(self, mark_nr, position): From arigo at codespeak.net Mon Feb 12 22:54:57 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 12 Feb 2007 22:54:57 +0100 (CET) Subject: [pypy-svn] r38646 - pypy/dist/pypy/module/__builtin__ Message-ID: <20070212215457.A142C1009A@code0.codespeak.net> Author: arigo Date: Mon Feb 12 22:54:56 2007 New Revision: 38646 Modified: pypy/dist/pypy/module/__builtin__/operation.py Log: Oups, wrong check. It was unwrapping and re-wrapping all strings. Modified: pypy/dist/pypy/module/__builtin__/operation.py ============================================================================== --- pypy/dist/pypy/module/__builtin__/operation.py (original) +++ pypy/dist/pypy/module/__builtin__/operation.py Mon Feb 12 22:54:56 2007 @@ -32,9 +32,9 @@ # space.{get,set,del}attr()... # Note that if w_name is already a string (or a subclass of str), # it must be returned unmodified (and not e.g. unwrapped-rewrapped). - name = space.str_w(w_name) # typecheck - if not space.is_true(space.isinstance(w_name, space.w_type)): - w_name = space.wrap(name) # typically, w_name was a unicode string + if not space.is_true(space.isinstance(w_name, space.w_str)): + name = space.str_w(w_name) # typecheck + w_name = space.wrap(name) # rewrap as a real string return w_name def delattr(space, w_object, w_name): From arigo at codespeak.net Mon Feb 12 22:57:06 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 12 Feb 2007 22:57:06 +0100 (CET) Subject: [pypy-svn] r38647 - in pypy/dist/pypy/objspace: . test Message-ID: <20070212215706.AA09B1009A@code0.codespeak.net> Author: arigo Date: Mon Feb 12 22:57:05 2007 New Revision: 38647 Modified: pypy/dist/pypy/objspace/descroperation.py pypy/dist/pypy/objspace/test/test_descroperation.py Log: (pedronis, arigo) More longish templates, because string-returning special methods need to do things slightly differently than int- or float-returning ones (namely, encode unicode results). Modified: pypy/dist/pypy/objspace/descroperation.py ============================================================================== --- pypy/dist/pypy/objspace/descroperation.py (original) +++ pypy/dist/pypy/objspace/descroperation.py Mon Feb 12 22:57:05 2007 @@ -515,11 +515,7 @@ for targetname, specialname, checkerspec in [ ('int', '__int__', ("space.w_int", "space.w_long")), ('long', '__long__', ("space.w_int", "space.w_long")), - ('float', '__float__', ("space.w_float",)), - ('str', '__str__', ("space.w_str",)), - ('repr', '__repr__', ("space.w_str",)), - ('oct', '__oct__', ("space.w_str",)), - ('hex', '__hex__', ("space.w_str",))]: + ('float', '__float__', ("space.w_float",))]: l = ["space.is_true(space.isinstance(w_result, %s))" % x for x in checkerspec] @@ -544,6 +540,40 @@ \n""" % locals() exec compile2(source) +for targetname, specialname in [ + ('str', '__str__'), + ('repr', '__repr__'), + ('oct', '__oct__'), + ('hex', '__hex__')]: + + source = """if 1: + def %(targetname)s(space, w_obj): + w_impl = space.lookup(w_obj, %(specialname)r) + if w_impl is None: + raise OperationError(space.w_TypeError, + space.wrap("operand does not support unary %(targetname)s")) + w_result = space.get_and_call_function(w_impl, w_obj) + + if space.is_true(space.isinstance(w_result, space.w_str)): + return w_result + try: + result = space.str_w(w_result) + except OperationError, e: + if not e.match(space, space.w_TypeError): + raise + typename = space.str_w(space.getattr(space.type(w_result), + space.wrap('__name__'))) + msg = '%(specialname)s returned non-%(targetname)s (type %%s)' %% (typename,) + raise OperationError(space.w_TypeError, space.wrap(msg)) + else: + # re-wrap the result as a real string + return space.wrap(result) + assert not hasattr(DescrOperation, %(targetname)r) + DescrOperation.%(targetname)s = %(targetname)s + del %(targetname)s + \n""" % locals() + exec compile2(source) + # add default operation implementations for all still missing ops for _name, _symbol, _arity, _specialnames in ObjSpace.MethodTable: Modified: pypy/dist/pypy/objspace/test/test_descroperation.py ============================================================================== --- pypy/dist/pypy/objspace/test/test_descroperation.py (original) +++ pypy/dist/pypy/objspace/test/test_descroperation.py Mon Feb 12 22:57:05 2007 @@ -247,3 +247,24 @@ check(iexpr, c, a) check(iexpr, c, b) check(iexpr, c, 5) + + def test_string_results(self): + class A(object): + def __str__(self): + return answer * 2 + def __repr__(self): + return answer * 3 + def __hex__(self): + return answer * 4 + def __oct__(self): + return answer * 5 + + for operate, n in [(str, 2), (repr, 3), (hex, 4), (oct, 5)]: + answer = "hello" + assert operate(A()) == "hello" * n + if operate not in (hex, oct): + answer = u"world" + assert operate(A()) == "world" * n + assert type(operate(A())) is str + answer = 42 + raises(TypeError, operate, A()) From fijal at codespeak.net Mon Feb 12 23:43:59 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 12 Feb 2007 23:43:59 +0100 (CET) Subject: [pypy-svn] r38648 - in pypy/extradoc/talk/warsaw2006: . src Message-ID: <20070212224359.9D79A1009A@code0.codespeak.net> Author: fijal Date: Mon Feb 12 23:43:54 2007 New Revision: 38648 Modified: pypy/extradoc/talk/warsaw2006/fireworks-slides.txt pypy/extradoc/talk/warsaw2006/src/slideshow.py pypy/extradoc/talk/warsaw2006/src/web.py Log: Adhere to new interface (for no particular reason) Modified: pypy/extradoc/talk/warsaw2006/fireworks-slides.txt ============================================================================== --- pypy/extradoc/talk/warsaw2006/fireworks-slides.txt (original) +++ pypy/extradoc/talk/warsaw2006/fireworks-slides.txt Mon Feb 12 23:43:54 2007 @@ -118,9 +118,17 @@ JavaScript example one (console): ================================= +.. raw:: html + + Here + JavaScript example two (Bub'n'Bros): ==================================== +.. raw:: html + + Here + Transparent proxy: ================== Modified: pypy/extradoc/talk/warsaw2006/src/slideshow.py ============================================================================== --- pypy/extradoc/talk/warsaw2006/src/slideshow.py (original) +++ pypy/extradoc/talk/warsaw2006/src/slideshow.py Mon Feb 12 23:43:54 2007 @@ -20,7 +20,7 @@ self.show(self.counter) def delete_nodes(self): - content = dom.get_document().getElementById("contentspace") + content = dom.document.getElementById("contentspace") for child in content.childNodes[:]: content.removeChild(child) content.style.position = "absolute" @@ -28,7 +28,7 @@ content.style.left = "170px" def show(self, num): - content = dom.get_document().getElementById("contentspace") + content = dom.document.getElementById("contentspace") if len(content.childNodes) > 0: content.removeChild(content.childNodes[0]) content.appendChild(self.pages[num]) @@ -44,13 +44,13 @@ page.left() def show(): - elements = [i for i in dom.get_document().getElementsByTagName('div')\ + elements = [i for i in dom.document.getElementsByTagName('div')\ if i.getAttribute('class')=='section'] page.set_pages(elements) page.delete_nodes() page.show(0) - dom.get_document().onkeypress = keydown + dom.document.onkeypress = keydown #createLoggingPane(True) def comeback(msg): Modified: pypy/extradoc/talk/warsaw2006/src/web.py ============================================================================== --- pypy/extradoc/talk/warsaw2006/src/web.py (original) +++ pypy/extradoc/talk/warsaw2006/src/web.py Mon Feb 12 23:43:54 2007 @@ -4,12 +4,13 @@ """ import py -from pypy.translator.js.examples import server +from pypy.translator.js.lib import server from pypy.rpython.ootypesystem.bltregistry import MethodDesc, BasicExternal,\ described from pypy.translator.js import commproxy from pypy.translator.js.main import rpython2javascript +from pypy.translator.js.lib.support import callback from pypy.translator.interactive import Translation @@ -42,32 +43,32 @@ self.t2 = Translation(f) - @described(retval=None) + @callback(retval=None) def flow_basic(self): self._create_t() self.t.view() - @described(retval=None) + @callback(retval=None) def annotate_basic(self): self._create_t() self.t.annotate([int]) self.t.view() - @described(retval=None) + @callback(retval=None) def rtype_basic(self): self._create_t() self.t.annotate([int]) self.t.rtype() self.t.view() - @described(retval=None) + @callback(retval=None) def example(self): self._create_t2() self.t2.annotate() self.t2.rtype() self.t2.view() - @described(retval=None) + @callback(retval=None) def const_fold(self): self._create_t2() self.t2.backendopt() @@ -99,4 +100,4 @@ style_css.exposed = True if __name__ == '__main__': - server.start_server(server_address=('localhost', 7070), handler=Handler, start_new=False) + server.create_server(server_address=('localhost', 7071), handler=Handler).serve_forever() From pedronis at codespeak.net Tue Feb 13 00:31:52 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Tue, 13 Feb 2007 00:31:52 +0100 (CET) Subject: [pypy-svn] r38651 - pypy/extradoc/planning/1.0 Message-ID: <20070212233152.50B571007A@code0.codespeak.net> Author: pedronis Date: Tue Feb 13 00:31:51 2007 New Revision: 38651 Modified: pypy/extradoc/planning/1.0/testing.txt Log: update Modified: pypy/extradoc/planning/1.0/testing.txt ============================================================================== --- pypy/extradoc/planning/1.0/testing.txt (original) +++ pypy/extradoc/planning/1.0/testing.txt Tue Feb 13 00:31:51 2007 @@ -1,9 +1,9 @@ Testing and testing infrastructure for release 1.0 ==================================================== -compliance tests for pypy-c's: (pedronis) testing it +compliance tests for pypy-c's: (pedronis) done -pypy-c py.test -A tests: in-progress, fixing to be tested +pypy-c py.test -A tests: they run nightly => triggered fixes windows testing: antocuni, http://scottdial.com/pypytest/summary.html (?) From fijal at codespeak.net Tue Feb 13 02:36:34 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 13 Feb 2007 02:36:34 +0100 (CET) Subject: [pypy-svn] r38654 - in pypy/dist/pypy/translator/js: examples lib lib/test Message-ID: <20070213013634.864CA100A6@code0.codespeak.net> Author: fijal Date: Tue Feb 13 02:36:28 2007 New Revision: 38654 Modified: pypy/dist/pypy/translator/js/examples/overmind.py pypy/dist/pypy/translator/js/lib/server.py pypy/dist/pypy/translator/js/lib/test/test_server.py Log: Another simplification of interface Modified: pypy/dist/pypy/translator/js/examples/overmind.py ============================================================================== --- pypy/dist/pypy/translator/js/examples/overmind.py (original) +++ pypy/dist/pypy/translator/js/examples/overmind.py Tue Feb 13 02:36:28 2007 @@ -15,20 +15,17 @@ import py FUNCTION_LIST = ['launch_console'] -TIMEOUT = 100 +TIMEOUT = 10 pids = [] def launch_console_in_new_thread(): from pypy.translator.js.examples import pythonconsole httpd = server.create_server(server_address=('', 0), - handler=pythonconsole.RequestHandler, timeout=TIMEOUT, + handler=pythonconsole.RequestHandler, server=pythonconsole.Server) port = httpd.server_port - pid = os.fork() - if not pid: - pythonconsole.httpd = httpd - httpd.serve_forever() - os._exit(0) + pythonconsole.httpd = httpd + pid = server.start_server_in_new_process(httpd, timeout=TIMEOUT) del httpd pids.append(pid) return port Modified: pypy/dist/pypy/translator/js/lib/server.py ============================================================================== --- pypy/dist/pypy/translator/js/lib/server.py (original) +++ pypy/dist/pypy/translator/js/lib/server.py Tue Feb 13 02:36:28 2007 @@ -118,7 +118,7 @@ return open(self.path).read() def create_server(server_address = ('', 8000), handler=TestHandler, - timeout=None, server=HTTPServer): + server=HTTPServer): """ Parameters: spawn - create new thread and return (by default it doesn't return) fork - do a real fork @@ -127,16 +127,6 @@ """ patch_handler(handler) httpd = server(server_address, handler) - if timeout: - def f(httpd): - while 1: - time.sleep(.3) - if time.time() - httpd.last_activity > timeout: - httpd.server_close() - import os - os.kill(os.getpid(), 15) - import thread - thread.start_new_thread(f, (httpd,)) httpd.last_activity = time.time() print "Server started, listening on %s:%s" %\ (httpd.server_address[0],httpd.server_port) @@ -146,10 +136,21 @@ import thread thread.start_new_thread(server.serve_forever, ()) -def start_server_in_new_process(server): +def start_server_in_new_process(server, timeout=None): pid = os.fork() if not pid: - httpd.server_forever() + if timeout: + def f(httpd): + while 1: + time.sleep(.3) + if time.time() - httpd.last_activity > timeout: + httpd.server_close() + import os + os.kill(os.getpid(), 15) + import thread + thread.start_new_thread(f, (server,)) + + server.serve_forever() os._exit(0) return pid Modified: pypy/dist/pypy/translator/js/lib/test/test_server.py ============================================================================== --- pypy/dist/pypy/translator/js/lib/test/test_server.py (original) +++ pypy/dist/pypy/translator/js/lib/test/test_server.py Tue Feb 13 02:36:28 2007 @@ -54,4 +54,3 @@ assert URLopener().open("http://127.0.0.1:21213/index").read() == \ "" - From fijal at codespeak.net Tue Feb 13 02:36:59 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 13 Feb 2007 02:36:59 +0100 (CET) Subject: [pypy-svn] r38655 - pypy/dist/pypy/translator/js/examples Message-ID: <20070213013659.56B04100A8@code0.codespeak.net> Author: fijal Date: Tue Feb 13 02:36:55 2007 New Revision: 38655 Modified: pypy/dist/pypy/translator/js/examples/overmind.py Log: Set default timeout to 5 minutes Modified: pypy/dist/pypy/translator/js/examples/overmind.py ============================================================================== --- pypy/dist/pypy/translator/js/examples/overmind.py (original) +++ pypy/dist/pypy/translator/js/examples/overmind.py Tue Feb 13 02:36:55 2007 @@ -15,7 +15,7 @@ import py FUNCTION_LIST = ['launch_console'] -TIMEOUT = 10 +TIMEOUT = 300 pids = [] def launch_console_in_new_thread(): From fijal at codespeak.net Tue Feb 13 02:38:55 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 13 Feb 2007 02:38:55 +0100 (CET) Subject: [pypy-svn] r38656 - pypy/dist/pypy/translator/js/examples Message-ID: <20070213013855.0F090100A6@code0.codespeak.net> Author: fijal Date: Tue Feb 13 02:38:46 2007 New Revision: 38656 Modified: pypy/dist/pypy/translator/js/examples/pythonconsole.py Log: Add a note about timeout Modified: pypy/dist/pypy/translator/js/examples/pythonconsole.py ============================================================================== --- pypy/dist/pypy/translator/js/examples/pythonconsole.py (original) +++ pypy/dist/pypy/translator/js/examples/pythonconsole.py Tue Feb 13 02:38:46 2007 @@ -35,6 +35,8 @@

Console

+

Note that a default timeout for the console is 5 minutes, after that time +console just dies and stops responding


 


From tismer at codespeak.net  Tue Feb 13 05:31:00 2007
From: tismer at codespeak.net (tismer at codespeak.net)
Date: Tue, 13 Feb 2007 05:31:00 +0100 (CET)
Subject: [pypy-svn] r38657 - pypy/dist/pypy/translator/goal
Message-ID: <20070213043100.9B0C2100A6@code0.codespeak.net>

Author: tismer
Date: Tue Feb 13 05:30:57 2007
New Revision: 38657

Modified:
   pypy/dist/pypy/translator/goal/compile_stackless.bat   (contents, props changed)
Log:
corrected eolstyle

Modified: pypy/dist/pypy/translator/goal/compile_stackless.bat
==============================================================================
--- pypy/dist/pypy/translator/goal/compile_stackless.bat	(original)
+++ pypy/dist/pypy/translator/goal/compile_stackless.bat	Tue Feb 13 05:30:57 2007
@@ -1,3 +1,3 @@
-python -c "import time; print time.ctime(), 'compile start'" >> compile.log
-translate.py --batch --new-stackless
-python -c "import time; print time.ctime(), 'compile stop'" >> compile.log
+python -c "import time; print time.ctime(), 'compile start'" >> compile.log
+translate.py --batch --new-stackless
+python -c "import time; print time.ctime(), 'compile stop'" >> compile.log


From tismer at codespeak.net  Tue Feb 13 06:13:27 2007
From: tismer at codespeak.net (tismer at codespeak.net)
Date: Tue, 13 Feb 2007 06:13:27 +0100 (CET)
Subject: [pypy-svn] r38658 - pypy/dist/pypy/translator/goal
Message-ID: <20070213051327.242DB1006E@code0.codespeak.net>

Author: tismer
Date: Tue Feb 13 06:13:14 2007
New Revision: 38658

Modified:
   pypy/dist/pypy/translator/goal/compile_stackless.bat
Log:
modified the compile_stackless.bat file so it works both n windows and linux. For some reason, the build does not work any longer...

Modified: pypy/dist/pypy/translator/goal/compile_stackless.bat
==============================================================================
--- pypy/dist/pypy/translator/goal/compile_stackless.bat	(original)
+++ pypy/dist/pypy/translator/goal/compile_stackless.bat	Tue Feb 13 06:13:14 2007
@@ -1,3 +1,3 @@
 python -c "import time; print time.ctime(), 'compile start'" >> compile.log
-translate.py --batch --new-stackless
+python translate.py --batch --stackless
 python -c "import time; print time.ctime(), 'compile stop'" >> compile.log


From cfbolz at codespeak.net  Tue Feb 13 09:54:53 2007
From: cfbolz at codespeak.net (cfbolz at codespeak.net)
Date: Tue, 13 Feb 2007 09:54:53 +0100 (CET)
Subject: [pypy-svn] r38660 - pypy/dist/pypy/module/__builtin__
Message-ID: <20070213085453.50983100A8@code0.codespeak.net>

Author: cfbolz
Date: Tue Feb 13 09:54:52 2007
New Revision: 38660

Modified:
   pypy/dist/pypy/module/__builtin__/functional.py
Log:
remove another bare OperationError (an non-greppable one!). remove
code-duplication in the process.


Modified: pypy/dist/pypy/module/__builtin__/functional.py
==============================================================================
--- pypy/dist/pypy/module/__builtin__/functional.py	(original)
+++ pypy/dist/pypy/module/__builtin__/functional.py	Tue Feb 13 09:54:52 2007
@@ -68,10 +68,6 @@
 to zero) to stop - 1 by step (defaults to 1).  Use a negative step to
 get a list in decending order."""
 
-    if (space.config.objspace.name == "std" and
-        (space.config.objspace.std.withmultilist or
-         space.config.objspace.std.withrangelist)):
-        return range_withspecialized_implementation(space, w_x, w_y, w_step)
     try:
         # save duplication by redirecting every error to applevel
         x = space.int_w(w_x)
@@ -81,15 +77,24 @@
             start, stop = x, space.int_w(w_y)
         step = space.int_w(w_step)
         howmany = get_len_of_range(start, stop, step)
-    except (OperationError, ValueError, OverflowError):
+    except OperationError, e:
+        if not e.match(space.w_TypeError):
+            raise
+    except (ValueError, OverflowError):
+        pass
         return range_fallback(space, w_x, w_y, w_step)
-
-    res_w = [None] * howmany
-    v = start
-    for idx in range(howmany):
-        res_w[idx] = space.wrap(v)
-        v += step
-    return space.newlist(res_w)
+    else:
+        if (space.config.objspace.name == "std" and
+            (space.config.objspace.std.withmultilist or
+             space.config.objspace.std.withrangelist)):
+            return range_withspecialized_implementation(space, start,
+                                                        step, howmany)
+        res_w = [None] * howmany
+        v = start
+        for idx in range(howmany):
+            res_w[idx] = space.wrap(v)
+            v += step
+        return space.newlist(res_w)
 range_int = range
 range_int.unwrap_spec = [ObjSpace, W_Root, W_Root, W_Root]
 del range # don't hide the builtin one
@@ -97,18 +102,7 @@
 range_fallback = applevel(getsource(app_range), getfile(app_range)
                           ).interphook('range')
 
-def range_withspecialized_implementation(space, w_x, w_y, w_step):
-    # XXX object space dependant
-    try:
-        x = space.int_w(w_x)
-        if space.is_w(w_y, space.w_None):
-            start, stop = 0, x
-        else:
-            start, stop = x, space.int_w(w_y)
-        step = space.int_w(w_step)
-        howmany = get_len_of_range(start, stop, step)
-    except (OperationError, ValueError, OverflowError):
-        return range_fallback(space, w_x, w_y, w_step)
+def range_withspecialized_implementation(space, start, step, howmany):
     if space.config.objspace.std.withrangelist:
         from pypy.objspace.std.rangeobject import W_RangeListObject
         return W_RangeListObject(start, step, howmany)


From cfbolz at codespeak.net  Tue Feb 13 10:06:24 2007
From: cfbolz at codespeak.net (cfbolz at codespeak.net)
Date: Tue, 13 Feb 2007 10:06:24 +0100 (CET)
Subject: [pypy-svn] r38661 - in pypy/dist/pypy/module/__builtin__: . test
Message-ID: <20070213090624.A6730100A8@code0.codespeak.net>

Author: cfbolz
Date: Tue Feb 13 10:06:24 2007
New Revision: 38661

Modified:
   pypy/dist/pypy/module/__builtin__/functional.py
   pypy/dist/pypy/module/__builtin__/test/test_range.py
Log:
fix bogus exception handling and add a test that would have caught it.


Modified: pypy/dist/pypy/module/__builtin__/functional.py
==============================================================================
--- pypy/dist/pypy/module/__builtin__/functional.py	(original)
+++ pypy/dist/pypy/module/__builtin__/functional.py	Tue Feb 13 10:06:24 2007
@@ -78,11 +78,12 @@
         step = space.int_w(w_step)
         howmany = get_len_of_range(start, stop, step)
     except OperationError, e:
-        if not e.match(space.w_TypeError):
+        if not e.match(space, space.w_TypeError):
+            pass
+        else:
             raise
     except (ValueError, OverflowError):
         pass
-        return range_fallback(space, w_x, w_y, w_step)
     else:
         if (space.config.objspace.name == "std" and
             (space.config.objspace.std.withmultilist or
@@ -95,6 +96,7 @@
             res_w[idx] = space.wrap(v)
             v += step
         return space.newlist(res_w)
+    return range_fallback(space, w_x, w_y, w_step)
 range_int = range
 range_int.unwrap_spec = [ObjSpace, W_Root, W_Root, W_Root]
 del range # don't hide the builtin one

Modified: pypy/dist/pypy/module/__builtin__/test/test_range.py
==============================================================================
--- pypy/dist/pypy/module/__builtin__/test/test_range.py	(original)
+++ pypy/dist/pypy/module/__builtin__/test/test_range.py	Tue Feb 13 10:06:24 2007
@@ -52,16 +52,18 @@
        assert range (-1, -12, -3) == [-1, -4, -7, -10]
 
    def test_range_decreasing_negativelargestep(self):
-      assert range(5, -2, -3) == [5, 2, -1]
+       assert range(5, -2, -3) == [5, 2, -1]
 
    def test_range_increasing_positivelargestep(self):
-      assert range(-5, 2, 3) == [-5, -2, 1]
+       assert range(-5, 2, 3) == [-5, -2, 1]
 
    def test_range_zerostep(self):
-      raises(ValueError, range, 1, 5, 0)
+       raises(ValueError, range, 1, 5, 0)
+
+   def DONT_test_range_float(self):
+       "How CPython does it - UGLY, ignored for now."
+       assert range(0.1, 2.0, 1.1) == [0, 1]
+
+   def test_range_wrong_type(self):
+       raises(TypeError, range, "42")
 
-"""
-   def test_range_float(self):
-      "How CPython does it - UGLY, ignored for now."
-      assert range(0.1, 2.0, 1.1) == [0, 1]
-      """


From mwh at codespeak.net  Tue Feb 13 10:38:17 2007
From: mwh at codespeak.net (mwh at codespeak.net)
Date: Tue, 13 Feb 2007 10:38:17 +0100 (CET)
Subject: [pypy-svn] r38662 - pypy/dist/pypy/objspace/std
Message-ID: <20070213093817.E7F0C1009C@code0.codespeak.net>

Author: mwh
Date: Tue Feb 13 10:38:17 2007
New Revision: 38662

Modified:
   pypy/dist/pypy/objspace/std/objspace.py
Log:
add a specialized version of BINARY_ADD for smallint builds.
helps pystone a few %, no effect on other benchmarks.


Modified: pypy/dist/pypy/objspace/std/objspace.py
==============================================================================
--- pypy/dist/pypy/objspace/std/objspace.py	(original)
+++ pypy/dist/pypy/objspace/std/objspace.py	Tue Feb 13 10:38:17 2007
@@ -58,19 +58,34 @@
 
         class StdObjSpaceFrame(pyframe.PyFrame):
             if self.config.objspace.std.optimized_int_add:
-                def BINARY_ADD(f, oparg, *ignored):
-                    from pypy.objspace.std.intobject import \
-                         W_IntObject, add__Int_Int
-                    w_2 = f.popvalue()
-                    w_1 = f.popvalue()
-                    if type(w_1) is W_IntObject and type(w_2) is W_IntObject:
-                        try:
-                            w_result = add__Int_Int(f.space, w_1, w_2)
-                        except FailedToImplement:
+                if self.config.objspace.std.withsmallint:
+                    def BINARY_ADD(f, oparg, *ignored):
+                        from pypy.objspace.std.smallintobject import \
+                             W_SmallIntObject, add__SmallInt_SmallInt
+                        w_2 = f.popvalue()
+                        w_1 = f.popvalue()
+                        if type(w_1) is W_SmallIntObject and type(w_2) is W_SmallIntObject:
+                            try:
+                                w_result = add__SmallInt_SmallInt(f.space, w_1, w_2)
+                            except FailedToImplement:
+                                w_result = f.space.add(w_1, w_2)
+                        else:
                             w_result = f.space.add(w_1, w_2)
-                    else:
-                        w_result = f.space.add(w_1, w_2)
-                    f.pushvalue(w_result)
+                        f.pushvalue(w_result)
+                else:
+                    def BINARY_ADD(f, oparg, *ignored):
+                        from pypy.objspace.std.intobject import \
+                             W_IntObject, add__Int_Int
+                        w_2 = f.popvalue()
+                        w_1 = f.popvalue()
+                        if type(w_1) is W_IntObject and type(w_2) is W_IntObject:
+                            try:
+                                w_result = add__Int_Int(f.space, w_1, w_2)
+                            except FailedToImplement:
+                                w_result = f.space.add(w_1, w_2)
+                        else:
+                            w_result = f.space.add(w_1, w_2)
+                        f.pushvalue(w_result)
 
             def CALL_LIKELY_BUILTIN(f, oparg, *ignored):
                 from pypy.module.__builtin__ import OPTIMIZED_BUILTINS, Module


From mwh at codespeak.net  Tue Feb 13 10:38:44 2007
From: mwh at codespeak.net (mwh at codespeak.net)
Date: Tue, 13 Feb 2007 10:38:44 +0100 (CET)
Subject: [pypy-svn] r38663 - pypy/dist/pypy/config
Message-ID: <20070213093844.7C092100AD@code0.codespeak.net>

Author: mwh
Date: Tue Feb 13 10:38:43 2007
New Revision: 38663

Modified:
   pypy/dist/pypy/config/pypyoption.py
Log:
add a couple more optimizations to --faassen


Modified: pypy/dist/pypy/config/pypyoption.py
==============================================================================
--- pypy/dist/pypy/config/pypyoption.py	(original)
+++ pypy/dist/pypy/config/pypyoption.py	Tue Feb 13 10:38:43 2007
@@ -200,6 +200,8 @@
                              ("objspace.std.withstrslice", True),
                              ("objspace.std.withsmallint", True),
                              ("objspace.std.withrangelist", True),
+                             ("objspace.std.withmethodcache", True),
+                             ("objspace.std.withfastslice", True),
                              ("objspace.std.optimized_int_add", True),
                              ],
                    cmdline="--faassen", negation=False),


From mwh at codespeak.net  Tue Feb 13 10:46:00 2007
From: mwh at codespeak.net (mwh at codespeak.net)
Date: Tue, 13 Feb 2007 10:46:00 +0100 (CET)
Subject: [pypy-svn] r38664 - pypy/dist/pypy/translator/benchmark
Message-ID: <20070213094600.ED7A71009C@code0.codespeak.net>

Author: mwh
Date: Tue Feb 13 10:46:00 2007
New Revision: 38664

Modified:
   pypy/dist/pypy/translator/benchmark/bench-custom.py
   pypy/dist/pypy/translator/benchmark/result.py
Log:
tweaks, including actually saving the results in the nominated pickle file.


Modified: pypy/dist/pypy/translator/benchmark/bench-custom.py
==============================================================================
--- pypy/dist/pypy/translator/benchmark/bench-custom.py	(original)
+++ pypy/dist/pypy/translator/benchmark/bench-custom.py	Tue Feb 13 10:46:00 2007
@@ -35,16 +35,24 @@
 
     refs = {}
 
-    exes = full_pythons+exes
+    exes = full_pythons + exes
 
     for i in range(int(options.runcount)):
-        for exe in full_pythons+exes:
+        for exe in exes:
             for b in benchmarks:
                 benchmark_result.result(exe).run_benchmark(b, verbose=True)
 
-    stats = ['stat:st_mtime', 'exe_name', 'bench:richards', 'pypy_rev', 'bench:pystone']
+    pickle.dump(benchmark_result, open(options.picklefile, 'wb'))
+
+    stats = ['stat:st_mtime', 'exe_name', 'pypy_rev']
+    for b in benchmarks:
+        stats.append('bench:'+b.name)
+    if options.relto:
+        relto = options.relto
+    else:
+        relto = full_pythons[0]
     for row in benchmark_result.txt_summary(stats,
-                                            relto=full_pythons[0],
+                                            relto=relto,
                                             filteron=lambda r: r.exe_name in exes):
         print row
 
@@ -63,5 +71,9 @@
         '--runcount', dest='runcount',
         default='1',
         )
+    parser.add_option(
+        '--relto', dest='relto',
+        default=None,
+        )
     options, args = parser.parse_args(sys.argv[1:])
     main(options, args)

Modified: pypy/dist/pypy/translator/benchmark/result.py
==============================================================================
--- pypy/dist/pypy/translator/benchmark/result.py	(original)
+++ pypy/dist/pypy/translator/benchmark/result.py	Tue Feb 13 10:46:00 2007
@@ -84,8 +84,11 @@
         if self.run_counts.get(benchmark.name, 0) > self.max_results:
             return
         if verbose:
-            print 'running', benchmark.name, 'for', self.exe_name
+            print 'running', benchmark.name, 'for', self.exe_name,
+            sys.stdout.flush()
         new_result = benchmark.run(self.exe_name)
+        if verbose:
+            print new_result
         self.benchmarks.setdefault(benchmark.name, []).append(new_result)
         if benchmark.name in self.best_benchmarks:
             old_result = self.best_benchmarks[benchmark.name]
@@ -124,10 +127,11 @@
             return time.ctime(statvalue), -1
         elif stat == 'exe_name':
             return os.path.basename(statvalue), -1
-        elif stat == 'bench:richards':
-            return "%8.2f%s"%(statvalue, 'ms'), 1
-        elif stat == 'bench:pystone':
-            return "%8.2f"%(statvalue,), 1
+        elif stat.startswith('bench:'):
+            from pypy.translator.benchmark import benchmarks
+            statkind, statdetail = stat.split(':', 1)
+            b = benchmarks.BENCHMARKS_BY_NAME[statdetail]
+            return "%8.2f%s"%(statvalue, b.units), 1
         elif stat == 'pypy_rev':
             return str(statvalue), 1
         else:


From mwh at codespeak.net  Tue Feb 13 10:52:12 2007
From: mwh at codespeak.net (mwh at codespeak.net)
Date: Tue, 13 Feb 2007 10:52:12 +0100 (CET)
Subject: [pypy-svn] r38665 - pypy/dist/pypy/config
Message-ID: <20070213095212.9F94E100AC@code0.codespeak.net>

Author: mwh
Date: Tue Feb 13 10:52:12 2007
New Revision: 38665

Modified:
   pypy/dist/pypy/config/pypyoption.py
Log:
cfbolz says that fastslicing is too experimental


Modified: pypy/dist/pypy/config/pypyoption.py
==============================================================================
--- pypy/dist/pypy/config/pypyoption.py	(original)
+++ pypy/dist/pypy/config/pypyoption.py	Tue Feb 13 10:52:12 2007
@@ -201,7 +201,7 @@
                              ("objspace.std.withsmallint", True),
                              ("objspace.std.withrangelist", True),
                              ("objspace.std.withmethodcache", True),
-                             ("objspace.std.withfastslice", True),
+#                             ("objspace.std.withfastslice", True),
                              ("objspace.std.optimized_int_add", True),
                              ],
                    cmdline="--faassen", negation=False),


From ac at codespeak.net  Tue Feb 13 11:31:30 2007
From: ac at codespeak.net (ac at codespeak.net)
Date: Tue, 13 Feb 2007 11:31:30 +0100 (CET)
Subject: [pypy-svn] r38666 - pypy/dist/lib-python/modified-2.4.1
Message-ID: <20070213103130.23989100A9@code0.codespeak.net>

Author: ac
Date: Tue Feb 13 11:31:29 2007
New Revision: 38666

Removed:
   pypy/dist/lib-python/modified-2.4.1/stringprep.py
Log:
Not needed.


From cfbolz at codespeak.net  Tue Feb 13 11:31:58 2007
From: cfbolz at codespeak.net (cfbolz at codespeak.net)
Date: Tue, 13 Feb 2007 11:31:58 +0100 (CET)
Subject: [pypy-svn] r38667 - pypy/dist/pypy/doc
Message-ID: <20070213103158.8B450100AF@code0.codespeak.net>

Author: cfbolz
Date: Tue Feb 13 11:31:57 2007
New Revision: 38667

Modified:
   pypy/dist/pypy/doc/faq.txt
Log:
completely rewrite faq rpython faq entry.


Modified: pypy/dist/pypy/doc/faq.txt
==============================================================================
--- pypy/dist/pypy/doc/faq.txt	(original)
+++ pypy/dist/pypy/doc/faq.txt	Tue Feb 13 11:31:57 2007
@@ -129,11 +129,14 @@
 
 It seems that a lot of strange, unexplainable problems can be magically
 solved by removing all the \*.pyc files from the PyPy source tree
-(script py.cleanup from py/bin will do that for you).
-Another thing you can do is removing the pypy/_cache
+(the script `py.cleanup`_ from py/bin will do that for you).
+Another thing you can do is removing the directory pypy/_cache
 completely. If the error is persistent and still annoys you after this
 treatment please send us a bug report (or even better, a fix :-)
 
+.. _`py.cleanup`: http://codespeak.net/py/current/doc/bin.html
+
+
 PyPy translation tool chain
 ========================================================================
 
@@ -141,15 +144,25 @@
 What is this RPython language?
 ------------------------------
 
-RPython is a way of interpreting your python program, running already.
-This means that term *RPython* is about some part of your program,
-beggining from your entry point (function which you explicitely 
-specify) to whatever is called from that point, also across modules.
-
-It's a subset of Python which allows full type inference (ie. you can
-deduct at compile time what are arguments of certain function),
-which puts it a bit closer to C++ or Java. To read more about RPython
-limitations read `RPython description`_
+RPython is a restricted subset of the Python language. The restrictions are to
+ensure that type inference (and eventually translation to other languages) of
+the program is possible. These restrictions only apply after the full import
+happened, so at import time arbitrary Python code can be executed. Another
+important point is that the property of "being RPython" always applies to a full
+program, not to single functions or modules (the translation tool chain does a
+full program analysis).
+
+The restrictions that apply to programs to be RPython mostly limit the ability
+of mixing types in arbitrary ways. RPython does not allow the usage of two
+different types in the same variable. In this respect (and in some others) it
+feels a bit like Java. Other features not allowed in RPython are the usage of
+special methods (``__XXX__``) except ``__init__`` and ``__del__`` and reflection
+capabilities (e.g. ``__dict__`` and ``__class__``).
+
+Most existing standard library modules are not RPython, except for some
+functions in ``os``, ``math`` and ``time``. In general it is quite unlikely that
+an existing Python program is by chance RPython, mostly it has to be rewritten
+heavily.  To read more about RPython limitations read `RPython description`_
 
 .. _`RPython description`: coding-guide.html#restricted-python
 


From mwh at codespeak.net  Tue Feb 13 11:51:01 2007
From: mwh at codespeak.net (mwh at codespeak.net)
Date: Tue, 13 Feb 2007 11:51:01 +0100 (CET)
Subject: [pypy-svn] r38669 - pypy/dist/pypy/objspace/std/test
Message-ID: <20070213105101.05626100B4@code0.codespeak.net>

Author: mwh
Date: Tue Feb 13 11:51:01 2007
New Revision: 38669

Modified:
   pypy/dist/pypy/objspace/std/test/test_listmultiobject.py
   pypy/dist/pypy/objspace/std/test/test_listobject.py
Log:
add another setslice test, which fails with multilists and is so skipped there.


Modified: pypy/dist/pypy/objspace/std/test/test_listmultiobject.py
==============================================================================
--- pypy/dist/pypy/objspace/std/test/test_listmultiobject.py	(original)
+++ pypy/dist/pypy/objspace/std/test/test_listmultiobject.py	Tue Feb 13 11:51:01 2007
@@ -32,6 +32,8 @@
         assert l == ["a", "b", "c", "d", "e", "f"]
         assert "StrListImplementation" in pypymagic.pypy_repr(l)
 
+    def test_ass_slice(self):
+        skip("failing")
 
 class AppTestRangeImplementation(AppTestRangeListObject):
 
@@ -100,7 +102,9 @@
         l1 = l[1:-1]
         del l1[:]
         assert "EmptyListImplementation" in pypymagic.pypy_repr(l1)
-        
+
+    def test_ass_slice(self):
+        skip("failing")
 
 class TestSliceListImplementation(object):
     def setup_method(self,method):

Modified: pypy/dist/pypy/objspace/std/test/test_listobject.py
==============================================================================
--- pypy/dist/pypy/objspace/std/test/test_listobject.py	(original)
+++ pypy/dist/pypy/objspace/std/test/test_listobject.py	Tue Feb 13 11:51:01 2007
@@ -514,6 +514,9 @@
         l = []
         l[:-3] = []
         assert l == []
+        l = range(6)
+        l[:] = []
+        assert l == []
 
     def test_recursive_repr(self):
         l = []


From fijal at codespeak.net  Tue Feb 13 11:52:57 2007
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Tue, 13 Feb 2007 11:52:57 +0100 (CET)
Subject: [pypy-svn] r38670 - pypy/dist/pypy/doc
Message-ID: <20070213105257.D7ECA100B3@code0.codespeak.net>

Author: fijal
Date: Tue Feb 13 11:52:56 2007
New Revision: 38670

Modified:
   pypy/dist/pypy/doc/faq.txt
Log:
Another two questions + a start for one


Modified: pypy/dist/pypy/doc/faq.txt
==============================================================================
--- pypy/dist/pypy/doc/faq.txt	(original)
+++ pypy/dist/pypy/doc/faq.txt	Tue Feb 13 11:52:56 2007
@@ -8,6 +8,14 @@
 General
 ========================================================================
 
+-----------------------------------------
+Is PyPy a drop in replacement of CPython?
+-----------------------------------------
+
+No. It's more. For a list of new, unique, features see next questions.
+One of the example problems is limited thread support, while PyPy has
+perfectly working so called "green threads"
+
 ------------------------------------------------------
 Why a new implementation of Python?  What does it add?
 ------------------------------------------------------
@@ -18,7 +26,11 @@
 What is the status of the project?  Can it be used in practice yet?
 -------------------------------------------------------------------
 
-XXX
+PyPy is a very broad project with varying level of a completion among
+parts. For example compiler toolchain is a relatively mature part,
+which is known of running several other projects (see: XXX).
+
+XXX finish that one
 
 ------------------------------
 On what platforms does it run?
@@ -166,6 +178,18 @@
 
 .. _`RPython description`: coding-guide.html#restricted-python
 
+--------------------------------------------------------------------
+What do you mean by "being RPython always applies to a full program?
+--------------------------------------------------------------------
+
+XXX
+
+-----------------------------------------
+What does a "NOT_RPYTHON" docstring mean?
+-----------------------------------------
+
+XXX
+
 -------------------------------------------------------------------
 Couldn't we simply take a Python syntax tree and turn it into Lisp?
 -------------------------------------------------------------------


From cfbolz at codespeak.net  Tue Feb 13 11:57:14 2007
From: cfbolz at codespeak.net (cfbolz at codespeak.net)
Date: Tue, 13 Feb 2007 11:57:14 +0100 (CET)
Subject: [pypy-svn] r38671 - pypy/dist/pypy/doc
Message-ID: <20070213105714.E2810100A7@code0.codespeak.net>

Author: cfbolz
Date: Tue Feb 13 11:57:14 2007
New Revision: 38671

Modified:
   pypy/dist/pypy/doc/faq.txt
Log:
try to answer these two questions


Modified: pypy/dist/pypy/doc/faq.txt
==============================================================================
--- pypy/dist/pypy/doc/faq.txt	(original)
+++ pypy/dist/pypy/doc/faq.txt	Tue Feb 13 11:57:14 2007
@@ -178,17 +178,24 @@
 
 .. _`RPython description`: coding-guide.html#restricted-python
 
---------------------------------------------------------------------
-What do you mean by "being RPython always applies to a full program?
---------------------------------------------------------------------
 
-XXX
-
------------------------------------------
-What does a "NOT_RPYTHON" docstring mean?
------------------------------------------
+--------------------------------------------------------------------------
+What do you mean by "full program"? All the code in all the modules I use?
+--------------------------------------------------------------------------
+
+"Full program" in the context of "being RPython" is all the code reachable from
+an "entry point" function. The translation toolchain follows all calls
+recursively and discovers what belongs to the program and what not.
+
+------------------------------------------------------
+What's the ``"NOT_RPYTHON"`` I see in some docstrings?
+------------------------------------------------------
+
+If you put "NOT_RPYTHON" into the docstring of a function and that function is
+found while trying to translate an RPython program, the translation process
+stops and reports this as an error. You can therefore mark functions as
+"NOT_RPYTHON" to make sure that they are never analyzed.
 
-XXX
 
 -------------------------------------------------------------------
 Couldn't we simply take a Python syntax tree and turn it into Lisp?


From fijal at codespeak.net  Tue Feb 13 12:01:31 2007
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Tue, 13 Feb 2007 12:01:31 +0100 (CET)
Subject: [pypy-svn] r38672 - pypy/dist/pypy/doc
Message-ID: <20070213110131.2FFEB100AC@code0.codespeak.net>

Author: fijal
Date: Tue Feb 13 12:01:29 2007
New Revision: 38672

Modified:
   pypy/dist/pypy/doc/faq.txt
Log:
Add very important question


Modified: pypy/dist/pypy/doc/faq.txt
==============================================================================
--- pypy/dist/pypy/doc/faq.txt	(original)
+++ pypy/dist/pypy/doc/faq.txt	Tue Feb 13 12:01:29 2007
@@ -8,13 +8,19 @@
 General
 ========================================================================
 
+-------------
+What is PyPy?
+-------------
+
+XXX
+
 -----------------------------------------
 Is PyPy a drop in replacement of CPython?
 -----------------------------------------
 
 No. It's more. For a list of new, unique, features see next questions.
-One of the example problems is limited thread support, while PyPy has
-perfectly working so called "green threads"
+For using it as an interpreter for existing projects, one of the
+example problems is limited thread support.
 
 ------------------------------------------------------
 Why a new implementation of Python?  What does it add?


From mwh at codespeak.net  Tue Feb 13 12:14:02 2007
From: mwh at codespeak.net (mwh at codespeak.net)
Date: Tue, 13 Feb 2007 12:14:02 +0100 (CET)
Subject: [pypy-svn] r38673 - in pypy/dist/pypy/objspace/std: . test
Message-ID: <20070213111402.92981100A9@code0.codespeak.net>

Author: mwh
Date: Tue Feb 13 12:14:01 2007
New Revision: 38673

Modified:
   pypy/dist/pypy/objspace/std/listmultiobject.py
   pypy/dist/pypy/objspace/std/test/test_listmultiobject.py
Log:
fix a bug in multilist shrinking slice assignments and unskip the relavent
tests.


Modified: pypy/dist/pypy/objspace/std/listmultiobject.py
==============================================================================
--- pypy/dist/pypy/objspace/std/listmultiobject.py	(original)
+++ pypy/dist/pypy/objspace/std/listmultiobject.py	Tue Feb 13 12:14:01 2007
@@ -922,7 +922,7 @@
                 i -= 1
         else:
             # shrinking requires the careful memory management of _del_slice()
-            _del_slice(w_list, start, start-delta)
+            impl = _del_slice(w_list, start, start-delta)
     elif len2 != slicelength:  # No resize for extended slices
         raise OperationError(space.w_ValueError, space.wrap("attempt to "
               "assign sequence of size %d to extended slice of size %d" %
@@ -1015,7 +1015,8 @@
     # keep a reference to the objects to be removed,
     # preventing side effects during destruction
     recycle = impl.getitem_slice(ilow, ihigh)
-    w_list.implementation = impl.i_delitem_slice(ilow, ihigh)
+    newimpl = w_list.implementation = impl.i_delitem_slice(ilow, ihigh)
+    return newimpl
 
 
 def list_pop__ListMulti_ANY(space, w_list, w_idx=-1):

Modified: pypy/dist/pypy/objspace/std/test/test_listmultiobject.py
==============================================================================
--- pypy/dist/pypy/objspace/std/test/test_listmultiobject.py	(original)
+++ pypy/dist/pypy/objspace/std/test/test_listmultiobject.py	Tue Feb 13 12:14:01 2007
@@ -32,9 +32,6 @@
         assert l == ["a", "b", "c", "d", "e", "f"]
         assert "StrListImplementation" in pypymagic.pypy_repr(l)
 
-    def test_ass_slice(self):
-        skip("failing")
-
 class AppTestRangeImplementation(AppTestRangeListObject):
 
     def setup_class(cls):
@@ -103,9 +100,6 @@
         del l1[:]
         assert "EmptyListImplementation" in pypymagic.pypy_repr(l1)
 
-    def test_ass_slice(self):
-        skip("failing")
-
 class TestSliceListImplementation(object):
     def setup_method(self,method):
         self.space = FakeSpace()


From cfbolz at codespeak.net  Tue Feb 13 12:31:57 2007
From: cfbolz at codespeak.net (cfbolz at codespeak.net)
Date: Tue, 13 Feb 2007 12:31:57 +0100 (CET)
Subject: [pypy-svn] r38674 - pypy/dist/pypy/config
Message-ID: <20070213113157.315F8100A9@code0.codespeak.net>

Author: cfbolz
Date: Tue Feb 13 12:31:55 2007
New Revision: 38674

Modified:
   pypy/dist/pypy/config/pypyoption.py
Log:
make tagged integers require boehm. The error messages could be clearer,
though.


Modified: pypy/dist/pypy/config/pypyoption.py
==============================================================================
--- pypy/dist/pypy/config/pypyoption.py	(original)
+++ pypy/dist/pypy/config/pypyoption.py	Tue Feb 13 12:31:55 2007
@@ -103,7 +103,8 @@
                    default=False, cmdline='--with-transparent-proxy'),
 
         BoolOption("withsmallint", "use tagged integers",
-                   default=False),
+                   default=False,
+                   requires=[("translation.gc", "boehm")]),
 
         BoolOption("withprebuiltint", "prebuilt commonly used int objects",
                    default=False,


From mwh at codespeak.net  Tue Feb 13 12:33:59 2007
From: mwh at codespeak.net (mwh at codespeak.net)
Date: Tue, 13 Feb 2007 12:33:59 +0100 (CET)
Subject: [pypy-svn] r38675 - in pypy/extradoc/talk/pycon2007: . pycon07.key
	pycon07.key/thumbs
Message-ID: <20070213113359.0146F100A9@code0.codespeak.net>

Author: mwh
Date: Tue Feb 13 12:33:49 2007
New Revision: 38675

Added:
   pypy/extradoc/talk/pycon2007/pycon07.pdf   (contents, props changed)
Modified:
   pypy/extradoc/talk/pycon2007/pycon07.key/index.apxl.gz
   pypy/extradoc/talk/pycon2007/pycon07.key/thumbs/st0-1.tiff
   pypy/extradoc/talk/pycon2007/pycon07.key/thumbs/st1-1.tiff
   pypy/extradoc/talk/pycon2007/pycon07.key/thumbs/st2.tiff
Log:
some updates (mostly compression of what was there) and a pdf


Modified: pypy/extradoc/talk/pycon2007/pycon07.key/index.apxl.gz
==============================================================================
Binary files. No diff available.

Modified: pypy/extradoc/talk/pycon2007/pycon07.key/thumbs/st0-1.tiff
==============================================================================
Binary files. No diff available.

Modified: pypy/extradoc/talk/pycon2007/pycon07.key/thumbs/st1-1.tiff
==============================================================================
Binary files. No diff available.

Modified: pypy/extradoc/talk/pycon2007/pycon07.key/thumbs/st2.tiff
==============================================================================
Binary files. No diff available.

Added: pypy/extradoc/talk/pycon2007/pycon07.pdf
==============================================================================
Binary file. No diff available.


From ac at codespeak.net  Tue Feb 13 12:35:18 2007
From: ac at codespeak.net (ac at codespeak.net)
Date: Tue, 13 Feb 2007 12:35:18 +0100 (CET)
Subject: [pypy-svn] r38676 - pypy/dist/lib-python/modified-2.4.1
Message-ID: <20070213113518.272B0100AF@code0.codespeak.net>

Author: ac
Date: Tue Feb 13 12:35:17 2007
New Revision: 38676

Added:
   pypy/dist/lib-python/modified-2.4.1/decimal.py
      - copied, changed from r38672, pypy/dist/lib-python/2.4.1/decimal.py
Log:
Fix bug in decimal.

By accident it doesn't show up in CPython since 'F' >= 0 is True there.




From cfbolz at codespeak.net  Tue Feb 13 12:41:23 2007
From: cfbolz at codespeak.net (cfbolz at codespeak.net)
Date: Tue, 13 Feb 2007 12:41:23 +0100 (CET)
Subject: [pypy-svn] r38677 - pypy/dist/pypy/doc
Message-ID: <20070213114123.965DE100B2@code0.codespeak.net>

Author: cfbolz
Date: Tue Feb 13 12:41:23 2007
New Revision: 38677

Added:
   pypy/dist/pypy/doc/windows.txt
Modified:
   pypy/dist/pypy/doc/getting-started.txt
Log:
move the windows explanations to their own file


Modified: pypy/dist/pypy/doc/getting-started.txt
==============================================================================
--- pypy/dist/pypy/doc/getting-started.txt	(original)
+++ pypy/dist/pypy/doc/getting-started.txt	Tue Feb 13 12:41:23 2007
@@ -359,7 +359,7 @@
 testresult directory. Running one of the above commands tells you how to
 proceed.
 
-.. _`installed py.test`: http://codespeak.net/py/current/doc/getting-started.html
+.. _`installed py.test`: https://codespeak.net/py/current/doc/download.html
 
 Demos
 +++++
@@ -538,6 +538,11 @@
 Translating the PyPy interpreter
 --------------------------------
 
+(**Note**: for some hints on how to translate PyPy under Windows, see the 
+`windows document`_)
+
+.. _`windows document`: windows.html
+
 Not for the faint of heart nor the owner of a very old machine: you can
 translate the whole of PyPy to low level C code. This is the largest and
 ultimate example of source that our translation toolchain can process::
@@ -611,110 +616,6 @@
     python translate.py targetrpystonedalone
 
 
-Translating PyPy under Windows
-++++++++++++++++++++++++++++++
-
-PyPy can be translated also under Windows. We have tested the
-translation toolchain using Visual Studio .NET 2003. It could be
-possible that it works also with other configurations: if you succeed
-to compile PyPy with a C compiler other that Visual Studio .NET 2003,
-please report us.
-
-To build pypy-c you first need a PyPy compatible version of the Boehm
-collector for Windows and Visual Studio .NET 2003. You can either
-`build your own copy`_ or download a `pre-compiled binary package`_.
-
-.. _`build your own copy`:
-
-How to build the Boehm collector
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-First of all, download the official `Boehm collector suite`_. At
-the time of writing (2007-02-09) this contains version gc6.7.
-
-Unpack this folder somewhere, for instance to ``d:\tmp``.  Change to
-this folder and copy the file ``NT_THREADS_MAKEFILE`` to
-``Makefile``::
-
-    d:
-    cd \tmp\gc6.5
-    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. 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`` -- please change the command
-according to the location of your PyPy installation)::
-
-    python d:\pypy\dist\pypy\translator\goal\win32\gc_patch_windows.py
-
-Now, your makefile is patched a little bit. See gc_patch_windows.py_
-for more details.
-
-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.
-Please note that you will need to use Microsoft's cmd, as cygwin bash
-doesn't correctly handle the batch file in the next step.
-
-With my setup, I have to do::
-
-    c:\Program Files\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 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::
-
-    nmake CFG="gc - Win32 Release"
-
-After the build, you will find the ``gc_pypy.dll`` and ``gc_pypy.lib``
-files in the Release folder.
-
-Copy the file ``gc_pypy.dll`` to ``c:\windows\system32`` or any other
-folder that is always in your PATH variable.
-
-Also, copy ``gc_pypy.lib`` to (in my case) ``c:\Program files\Microsoft
-Visual Studio .NET 2003\Vc7\lib``.
-
-Finally, copy ``d:\tmp\gc6.7\include`` to ``c:\Program
-files\Microsoft Visual Studio .NET 2003\Vc7\include`` and rename this
-folder to ``gc``, so that ``gc/gc.h`` is valid.
-
-In case of a debug build also copy ``gc_pypy.pdb`` to your lib
-folder. This allows you to use source-level debugging.
-
-Summary transcript of the steps involved (please adjust paths)::
-
-    d:
-    cd \tmp\gc6.7
-    copy NT_THREADS_MAKEFILE Makefile
-    python d:\pypy\dist\pypy\translator\goal\win32\gc_patch_windows.py
-    "c:\Program files\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 "c:\Program files\Microsoft Visual Studio .NET 2003\Vc7\lib"
-    mkdir "c:\Program files\Microsoft Visual Studio .NET 2003\Vc7\include\gc"
-    copy include "c:\Program files\Microsoft Visual Studio .NET 2003\Vc7\include\gc"
-
-.. _`pre-compiled binary package`:
-
-Installing the pre-compiled Boehm collector
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-First, download and extract the file `gc-windows.zip`_. Then, copy the
-file ``gc_pypy.dll`` to ``c:\windows\system32`` or any other folder that is
-always in your PATH variable.
-
-Also, copy ``gc_pypy.lib`` to (in my case) ``c:\Program files\Microsoft
-Visual Studio .NET 2003\Vc7\lib``.
-
-Finally, copy the ``gc`` directory to ``c:\Program files\Microsoft
-Visual Studio .NET 2003\Vc7\include``.
-
 
 .. _`translate PyPy with the thunk object space`:
 
@@ -949,7 +850,6 @@
 .. _trace:                  http://codespeak.net/pypy/dist/pypy/objspace/trace.py
 .. _flow:                   http://codespeak.net/pypy/dist/pypy/objspace/flow/
 .. _translator.py:          http://codespeak.net/pypy/dist/pypy/translator/translator.py
-.. _gc_patch_windows.py:    http://codespeak.net/pypy/dist/pypy/translator/goal/win32/gc_patch_windows.py
 .. _mailing lists:          contact.html
 .. _documentation:          index.html 
 .. _unit tests:             coding-guide.html#test-design
@@ -957,7 +857,5 @@
 
 .. _`directory reference`: index.html#directory-reference
 .. _`Boehm-Demers-Weiser garbage collector`: http://www.hpl.hp.com/personal/Hans_Boehm/gc/
-.. _`Boehm collector suite`: http://www.hpl.hp.com/personal/Hans_Boehm/gc/gc_source/gc.tar.gz
-.. _`gc-windows.zip`: http://codespeak.net/~antocuni/gc-windows.zip
 
 .. include:: _ref.txt

Added: pypy/dist/pypy/doc/windows.txt
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/doc/windows.txt	Tue Feb 13 12:41:23 2007
@@ -0,0 +1,117 @@
+=============
+Windows Hints
+=============
+
+The following text gives some hints about how to translate the PyPy interpreter
+under Windows. In general our experience with Windows is limited, so if you
+have suggestions about how this document can be improved, please contact us.
+
+Translating PyPy under Windows
+------------------------------
+
+PyPy can be translated also under Windows. We have tested the
+translation toolchain using Visual Studio .NET 2003. It could be
+possible that it works also with other configurations: if you succeed
+to compile PyPy with a C compiler other that Visual Studio .NET 2003,
+please report us.
+
+To build pypy-c you first need a PyPy compatible version of the Boehm
+collector for Windows and Visual Studio .NET 2003. You can either
+`build your own copy`_ or download a `pre-compiled binary package`_.
+
+.. _`build your own copy`:
+
+How to build the Boehm collector
+++++++++++++++++++++++++++++++++
+
+First of all, download the official `Boehm collector suite`_. At
+the time of writing (2007-02-09) this contains version gc6.7.
+
+Unpack this folder somewhere, for instance to ``d:\tmp``.  Change to
+this folder and copy the file ``NT_THREADS_MAKEFILE`` to
+``Makefile``::
+
+    d:
+    cd \tmp\gc6.5
+    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. 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`` -- please change the command
+according to the location of your PyPy installation)::
+
+    python d:\pypy\dist\pypy\translator\goal\win32\gc_patch_windows.py
+
+Now, your makefile is patched a little bit. See gc_patch_windows.py_
+for more details.
+
+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.
+Please note that you will need to use Microsoft's cmd, as cygwin bash
+doesn't correctly handle the batch file in the next step.
+
+With my setup, I have to do::
+
+    c:\Program Files\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 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::
+
+    nmake CFG="gc - Win32 Release"
+
+After the build, you will find the ``gc_pypy.dll`` and ``gc_pypy.lib``
+files in the Release folder.
+
+Copy the file ``gc_pypy.dll`` to ``c:\windows\system32`` or any other
+folder that is always in your PATH variable.
+
+Also, copy ``gc_pypy.lib`` to (in my case) ``c:\Program files\Microsoft
+Visual Studio .NET 2003\Vc7\lib``.
+
+Finally, copy ``d:\tmp\gc6.7\include`` to ``c:\Program
+files\Microsoft Visual Studio .NET 2003\Vc7\include`` and rename this
+folder to ``gc``, so that ``gc/gc.h`` is valid.
+
+In case of a debug build also copy ``gc_pypy.pdb`` to your lib
+folder. This allows you to use source-level debugging.
+
+Summary transcript of the steps involved (please adjust paths)::
+
+    d:
+    cd \tmp\gc6.7
+    copy NT_THREADS_MAKEFILE Makefile
+    python d:\pypy\dist\pypy\translator\goal\win32\gc_patch_windows.py
+    "c:\Program files\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 "c:\Program files\Microsoft Visual Studio .NET 2003\Vc7\lib"
+    mkdir "c:\Program files\Microsoft Visual Studio .NET 2003\Vc7\include\gc"
+    copy include "c:\Program files\Microsoft Visual Studio .NET 2003\Vc7\include\gc"
+
+.. _`pre-compiled binary package`:
+
+Installing the pre-compiled Boehm collector
++++++++++++++++++++++++++++++++++++++++++++
+
+First, download and extract the file `gc-windows.zip`_. Then, copy the
+file ``gc_pypy.dll`` to ``c:\windows\system32`` or any other folder that is
+always in your PATH variable.
+
+Also, copy ``gc_pypy.lib`` to (in my case) ``c:\Program files\Microsoft
+Visual Studio .NET 2003\Vc7\lib``.
+
+Finally, copy the ``gc`` directory to ``c:\Program files\Microsoft
+Visual Studio .NET 2003\Vc7\include``.
+
+
+.. _`Boehm collector suite`: http://www.hpl.hp.com/personal/Hans_Boehm/gc/gc_source/gc.tar.gz
+.. _gc_patch_windows.py:    http://codespeak.net/pypy/dist/pypy/translator/goal/win32/gc_patch_windows.py
+
+.. _`gc-windows.zip`: http://codespeak.net/~antocuni/gc-windows.zip


From cfbolz at codespeak.net  Tue Feb 13 12:52:31 2007
From: cfbolz at codespeak.net (cfbolz at codespeak.net)
Date: Tue, 13 Feb 2007 12:52:31 +0100 (CET)
Subject: [pypy-svn] r38679 - pypy/dist/pypy/doc
Message-ID: <20070213115231.3F4E0100AF@code0.codespeak.net>

Author: cfbolz
Date: Tue Feb 13 12:52:30 2007
New Revision: 38679

Modified:
   pypy/dist/pypy/doc/faq.txt
Log:
move an faq entry around, add cross-linking


Modified: pypy/dist/pypy/doc/faq.txt
==============================================================================
--- pypy/dist/pypy/doc/faq.txt	(original)
+++ pypy/dist/pypy/doc/faq.txt	Tue Feb 13 12:52:30 2007
@@ -14,14 +14,6 @@
 
 XXX
 
------------------------------------------
-Is PyPy a drop in replacement of CPython?
------------------------------------------
-
-No. It's more. For a list of new, unique, features see next questions.
-For using it as an interpreter for existing projects, one of the
-example problems is limited thread support.
-
 ------------------------------------------------------
 Why a new implementation of Python?  What does it add?
 ------------------------------------------------------
@@ -38,6 +30,16 @@
 
 XXX finish that one
 
+-----------------------------------------
+Is PyPy a drop in replacement of CPython?
+-----------------------------------------
+
+Not completely yet. There are various areas where PyPy is lacking, such as
+threading_ and `extension modules`_. The language features (including built in
+types and functions) are very complete and well tested, though. That means that
+projects not using many extension modules can probably directly use PyPy. A
+project using extension modules might get some problems, though.
+
 ------------------------------
 On what platforms does it run?
 ------------------------------
@@ -64,6 +66,8 @@
 important reasons why nobody is working on them is that we did not promise this
 to the EU and have currently enough other tasks.
 
+.. _threading:
+
 -------------------------------------------------
 Do threads work?  What are the modules that work?
 -------------------------------------------------
@@ -92,12 +96,15 @@
 
 .. _`stackless-like microthreads`: stackless.html
 
+
+.. _`extension modules`:
+
 ------------------------------------
 Can I use CPython extension modules?
 ------------------------------------
 
-No and there are no current plans to implement so. CPython extension modules
-relies heavily on CPython's C API which contains a lot of implementation details
+No and there are no current plans to support this. CPython extension modules
+rely heavily on CPython's C API which contains a lot of implementation details
 like reference counting, exact C-level objects implementations etc.
 
 Although if your module uses ctypes rather than C-level code, there is a hope.


From mwh at codespeak.net  Tue Feb 13 13:20:21 2007
From: mwh at codespeak.net (mwh at codespeak.net)
Date: Tue, 13 Feb 2007 13:20:21 +0100 (CET)
Subject: [pypy-svn] r38681 - pypy/dist/pypy/translator/llvm/test
Message-ID: <20070213122021.7148D100A7@code0.codespeak.net>

Author: mwh
Date: Tue Feb 13 13:20:19 2007
New Revision: 38681

Modified:
   pypy/dist/pypy/translator/llvm/test/test_extfunc.py
Log:
skip a few tests that aren't going to work :/


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	Tue Feb 13 13:20:19 2007
@@ -594,6 +594,7 @@
 
 if hasattr(posix, 'execv'):
     def test_execv():
+        py.test.skip("not working yet")
         filename = str(udir.join('test_execv.txt'))
         executable = sys.executable
         def does_stuff():
@@ -613,6 +614,7 @@
         assert open(filename).read() == "1"
 
     def test_execv_raising():
+        py.test.skip("not working yet")
         def does_stuff():
             l = []
             l.append("asddsadw32eewdfwqdqwdqwd")
@@ -627,6 +629,7 @@
         assert res == 1
 
     def test_execve():
+        py.test.skip("not working yet")
         filename = str(udir.join('test_execve.txt'))
         executable = sys.executable
         def does_stuff():


From mwh at codespeak.net  Tue Feb 13 13:21:09 2007
From: mwh at codespeak.net (mwh at codespeak.net)
Date: Tue, 13 Feb 2007 13:21:09 +0100 (CET)
Subject: [pypy-svn] r38682 - pypy/dist/pypy/translator/llvm
Message-ID: <20070213122109.9BD28100AD@code0.codespeak.net>

Author: mwh
Date: Tue Feb 13 13:21:09 2007
New Revision: 38682

Modified:
   pypy/dist/pypy/translator/llvm/opwriter.py
Log:
more support in genllvm for fixedsizearrays.
no tests :( because the tests depend on versions of gcc, versions of llvm and
the phase of the moon, it seems :(


Modified: pypy/dist/pypy/translator/llvm/opwriter.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/opwriter.py	(original)
+++ pypy/dist/pypy/translator/llvm/opwriter.py	Tue Feb 13 13:21:09 2007
@@ -128,6 +128,7 @@
             meth = getattr(self, op.opname, None)
             if not meth:
                 raise Exception, "operation %s not found" % op.opname
+            self.codewriter.comment(str(op))
             meth(opr)            
     
     def _generic_pow(self, opr, onestr): 
@@ -332,34 +333,61 @@
                                    op.args[0].concretetype.TO)
             assert index != -1
             tmpvar = self._tmp()
+            STRUCTTYPE = op.args[0].concretetype.TO
+            getptr = not isinstance(STRUCTTYPE, lltype.FixedSizeArray)
+            if not getptr:
+                self.codewriter.comment("HERE HERE")
             self.codewriter.getelementptr(tmpvar, opr.argtypes[0],
-                                          opr.argrefs[0], [("uint", index)])
+                                          opr.argrefs[0], [("uint", index)], getptr=getptr)
             self.codewriter.load(opr.retref, opr.rettype, tmpvar)
         else:
             self._skipped(opr)
- 
+
+    def direct_fieldptr(self, opr):
+        self.codewriter.comment("begin argh")
+        op = opr.op
+        assert opr.rettype != "void"
+        index = getindexhelper(op.args[1].value,
+                               op.args[0].concretetype.TO)
+        assert index != -1
+        #import pdb; pdb.set_trace()
+        self.codewriter.getelementptr(opr.retref, opr.argtypes[0],
+                                      opr.argrefs[0], [("uint", index), ("int", 0)], getptr=False)
+        self.codewriter.comment("end argh")
+
     def getsubstruct(self, opr): 
         index = getindexhelper(opr.op.args[1].value,
                                opr.op.args[0].concretetype.TO)
         assert opr.rettype != "void"
-        self.codewriter.getelementptr(opr.retref, opr.argtypes[0], 
-                                      opr.argrefs[0], [("uint", index)])        
-         
+        STRUCTTYPE = opr.op.args[0].concretetype.TO
+        getptr = not isinstance(STRUCTTYPE, lltype.FixedSizeArray)
+        indices = [("uint", index)]
+        RETTYPE = opr.op.result.concretetype.TO
+        if isinstance(RETTYPE, lltype.FixedSizeArray):
+            indices.append(("int", 0))
+        #import pdb; pdb.set_trace()
+        self.codewriter.getelementptr(opr.retref, opr.argtypes[0],
+                                      opr.argrefs[0], indices, getptr=getptr)
+
     def setfield(self, opr): 
         op = opr.op
         if opr.argtypes[2] != "void":
             tmpvar = self._tmp()
             index = getindexhelper(op.args[1].value,
                                    op.args[0].concretetype.TO)
+            STRUCTTYPE = op.args[0].concretetype.TO
+            getptr = not isinstance(STRUCTTYPE, lltype.FixedSizeArray)
+            if not getptr:
+                self.codewriter.comment("HERE HERE")
             self.codewriter.getelementptr(tmpvar, opr.argtypes[0],
-                                          opr.argrefs[0], [("uint", index)])
+                                          opr.argrefs[0], [("uint", index)], getptr=getptr)
             self.codewriter.store(opr.argtypes[2], opr.argrefs[2], tmpvar)
         else:
             self._skipped(opr)
 
     bare_setfield = setfield
-            
-    def getarrayitem(self, opr):        
+
+    def getarrayitem(self, opr):
         if opr.rettype == "void":
             self._skipped(opr)
             return
@@ -369,15 +397,28 @@
         tmpvar = self._tmp()
 
         indices = arrayindices(opr.op.args[0]) + [(indextype, index)]
-        self.codewriter.getelementptr(tmpvar, arraytype, array, indices)
+        ARRAYTYPE = opr.op.args[0].concretetype.TO
+        getptr = not isinstance(ARRAYTYPE, lltype.FixedSizeArray)
+        self.codewriter.getelementptr(tmpvar, arraytype, array, indices, getptr=getptr)
         self.codewriter.load(opr.retref, opr.rettype, tmpvar)
 
+    def direct_arrayitems(self, opr):
+        array, index = opr.argrefs
+        arraytype, indextype = opr.argtypes
+        indices = arrayindices(opr.op.args[0]) + [(indextype, index)]
+        self.codewriter.getelementptr(opr.retref, arraytype, array, inices)
+
     def getarraysubstruct(self, opr):        
         array, index = opr.argrefs
         arraytype, indextype = opr.argtypes
 
         indices = arrayindices(opr.op.args[0]) + [(indextype, index)]
-        self.codewriter.getelementptr(opr.retref, arraytype, array, indices)
+        ARRAYTYPE = opr.op.args[0].concretetype.TO
+        getptr = not isinstance(ARRAYTYPE, lltype.FixedSizeArray)
+        RETTYPE = opr.op.result.concretetype.TO
+        if isinstance(RETTYPE, lltype.FixedSizeArray):
+            indices.append(("int", 0))
+        self.codewriter.getelementptr(opr.retref, arraytype, array, indices, getptr=getptr)
 
     def setarrayitem(self, opr):
         array, index, valuevar = opr.argrefs
@@ -389,10 +430,12 @@
             return
 
         indices = arrayindices(opr.op.args[0]) + [(indextype, index)]
-        self.codewriter.getelementptr(tmpvar, arraytype, array, indices)            
+        ARRAYTYPE = opr.op.args[0].concretetype.TO
+        getptr = not isinstance(ARRAYTYPE, lltype.FixedSizeArray)
+        self.codewriter.getelementptr(tmpvar, arraytype, array, indices, getptr=getptr)
         self.codewriter.store(valuetype, valuevar, tmpvar) 
     bare_setarrayitem = setarrayitem
-            
+
     def getarraysize(self, opr):
         ARRAYTYPE = opr.op.args[0].concretetype.TO
         assert isinstance(ARRAYTYPE, lltype.Array)


From cfbolz at codespeak.net  Tue Feb 13 13:46:00 2007
From: cfbolz at codespeak.net (cfbolz at codespeak.net)
Date: Tue, 13 Feb 2007 13:46:00 +0100 (CET)
Subject: [pypy-svn] r38684 - pypy/dist/pypy/doc/config
Message-ID: <20070213124600.0EC31100A7@code0.codespeak.net>

Author: cfbolz
Date: Tue Feb 13 13:45:58 2007
New Revision: 38684

Added:
   pypy/dist/pypy/doc/config/makemodules.py
Modified:
   pypy/dist/pypy/doc/config/objspace.usemodules.Numeric.txt
   pypy/dist/pypy/doc/config/objspace.usemodules.__builtin__.txt
   pypy/dist/pypy/doc/config/objspace.usemodules._codecs.txt
   pypy/dist/pypy/doc/config/objspace.usemodules._demo.txt
   pypy/dist/pypy/doc/config/objspace.usemodules._file.txt
   pypy/dist/pypy/doc/config/objspace.usemodules._pickle_support.txt
   pypy/dist/pypy/doc/config/objspace.usemodules._random.txt
   pypy/dist/pypy/doc/config/objspace.usemodules._sre.txt
   pypy/dist/pypy/doc/config/objspace.usemodules._ssl.txt
   pypy/dist/pypy/doc/config/objspace.usemodules._stackless.txt
   pypy/dist/pypy/doc/config/objspace.usemodules._weakref.txt
   pypy/dist/pypy/doc/config/objspace.usemodules.array.txt
   pypy/dist/pypy/doc/config/objspace.usemodules.bz2.txt
   pypy/dist/pypy/doc/config/objspace.usemodules.clr.txt
   pypy/dist/pypy/doc/config/objspace.usemodules.crypt.txt
   pypy/dist/pypy/doc/config/objspace.usemodules.errno.txt
   pypy/dist/pypy/doc/config/objspace.usemodules.fcntl.txt
   pypy/dist/pypy/doc/config/objspace.usemodules.gc.txt
   pypy/dist/pypy/doc/config/objspace.usemodules.marshal.txt
   pypy/dist/pypy/doc/config/objspace.usemodules.math.txt
   pypy/dist/pypy/doc/config/objspace.usemodules.mmap.txt
   pypy/dist/pypy/doc/config/objspace.usemodules.posix.txt
   pypy/dist/pypy/doc/config/objspace.usemodules.pypyjit.txt
   pypy/dist/pypy/doc/config/objspace.usemodules.pypymagic.txt
   pypy/dist/pypy/doc/config/objspace.usemodules.rctime.txt
   pypy/dist/pypy/doc/config/objspace.usemodules.readline.txt
   pypy/dist/pypy/doc/config/objspace.usemodules.recparser.txt
   pypy/dist/pypy/doc/config/objspace.usemodules.rsocket.txt
   pypy/dist/pypy/doc/config/objspace.usemodules.select.txt
   pypy/dist/pypy/doc/config/objspace.usemodules.signal.txt
   pypy/dist/pypy/doc/config/objspace.usemodules.symbol.txt
   pypy/dist/pypy/doc/config/objspace.usemodules.sys.txt
   pypy/dist/pypy/doc/config/objspace.usemodules.thread.txt
   pypy/dist/pypy/doc/config/objspace.usemodules.time.txt
   pypy/dist/pypy/doc/config/objspace.usemodules.unicodedata.txt
Log:
add basic information for all the usemodules options


Added: pypy/dist/pypy/doc/config/makemodules.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/doc/config/makemodules.py	Tue Feb 13 13:45:58 2007
@@ -0,0 +1,27 @@
+import autopath
+import py
+from pypy.config import pypyoption, translationoption, config
+
+thisdir = py.magic.autopath().dirpath()
+
+if __name__ == '__main__':
+    c = config.Config(pypyoption.pypy_optiondescription).usemodules
+    prefix = "objspace.usemodules"
+    thisdir.join(prefix + ".txt").ensure()
+    for p in c.getpaths(include_groups=True):
+        basename = prefix + "." + p + ".txt"
+        f = thisdir.join(basename)
+        if f.check() and f.size():
+            continue
+        print "making docs for", p
+        text = ["Use the '%s' module. " % (p, )]
+        if p in pypyoption.essential_modules:
+            text.append("This module is essential, included by default and should not be removed.")
+        elif p in pypyoption.default_modules:
+            text.append("This module is expected to be fully working and is included by default.")
+        elif p in pypyoption.working_modules:
+            text.append("This module is expected to be fully working.")
+        text.append("")
+        f.write("\n".join(text))
+
+

Modified: pypy/dist/pypy/doc/config/objspace.usemodules.Numeric.txt
==============================================================================
--- pypy/dist/pypy/doc/config/objspace.usemodules.Numeric.txt	(original)
+++ pypy/dist/pypy/doc/config/objspace.usemodules.Numeric.txt	Tue Feb 13 13:45:58 2007
@@ -0,0 +1 @@
+Use the 'Numeric' module. 

Modified: pypy/dist/pypy/doc/config/objspace.usemodules.__builtin__.txt
==============================================================================
--- pypy/dist/pypy/doc/config/objspace.usemodules.__builtin__.txt	(original)
+++ pypy/dist/pypy/doc/config/objspace.usemodules.__builtin__.txt	Tue Feb 13 13:45:58 2007
@@ -0,0 +1,2 @@
+Use the '__builtin__' module. 
+This module is essential, included by default and should not be removed.

Modified: pypy/dist/pypy/doc/config/objspace.usemodules._codecs.txt
==============================================================================
--- pypy/dist/pypy/doc/config/objspace.usemodules._codecs.txt	(original)
+++ pypy/dist/pypy/doc/config/objspace.usemodules._codecs.txt	Tue Feb 13 13:45:58 2007
@@ -0,0 +1,2 @@
+Use the '_codecs' module. 
+This module is expected to be fully working and is included by default.

Modified: pypy/dist/pypy/doc/config/objspace.usemodules._demo.txt
==============================================================================
--- pypy/dist/pypy/doc/config/objspace.usemodules._demo.txt	(original)
+++ pypy/dist/pypy/doc/config/objspace.usemodules._demo.txt	Tue Feb 13 13:45:58 2007
@@ -0,0 +1 @@
+Use the '_demo' module. 

Modified: pypy/dist/pypy/doc/config/objspace.usemodules._file.txt
==============================================================================
--- pypy/dist/pypy/doc/config/objspace.usemodules._file.txt	(original)
+++ pypy/dist/pypy/doc/config/objspace.usemodules._file.txt	Tue Feb 13 13:45:58 2007
@@ -0,0 +1,2 @@
+Use the '_file' module. 
+This module is essential, included by default and should not be removed.

Modified: pypy/dist/pypy/doc/config/objspace.usemodules._pickle_support.txt
==============================================================================
--- pypy/dist/pypy/doc/config/objspace.usemodules._pickle_support.txt	(original)
+++ pypy/dist/pypy/doc/config/objspace.usemodules._pickle_support.txt	Tue Feb 13 13:45:58 2007
@@ -0,0 +1,2 @@
+Use the '_pickle_support' module. 
+This module is expected to be fully working and is included by default.

Modified: pypy/dist/pypy/doc/config/objspace.usemodules._random.txt
==============================================================================
--- pypy/dist/pypy/doc/config/objspace.usemodules._random.txt	(original)
+++ pypy/dist/pypy/doc/config/objspace.usemodules._random.txt	Tue Feb 13 13:45:58 2007
@@ -0,0 +1,2 @@
+Use the '_random' module. 
+This module is expected to be fully working and is included by default.

Modified: pypy/dist/pypy/doc/config/objspace.usemodules._sre.txt
==============================================================================
--- pypy/dist/pypy/doc/config/objspace.usemodules._sre.txt	(original)
+++ pypy/dist/pypy/doc/config/objspace.usemodules._sre.txt	Tue Feb 13 13:45:58 2007
@@ -0,0 +1,2 @@
+Use the '_sre' module. 
+This module is expected to be fully working and is included by default.

Modified: pypy/dist/pypy/doc/config/objspace.usemodules._ssl.txt
==============================================================================
--- pypy/dist/pypy/doc/config/objspace.usemodules._ssl.txt	(original)
+++ pypy/dist/pypy/doc/config/objspace.usemodules._ssl.txt	Tue Feb 13 13:45:58 2007
@@ -0,0 +1 @@
+Use the '_ssl' module. 

Modified: pypy/dist/pypy/doc/config/objspace.usemodules._stackless.txt
==============================================================================
--- pypy/dist/pypy/doc/config/objspace.usemodules._stackless.txt	(original)
+++ pypy/dist/pypy/doc/config/objspace.usemodules._stackless.txt	Tue Feb 13 13:45:58 2007
@@ -0,0 +1 @@
+Use the '_stackless' module. 

Modified: pypy/dist/pypy/doc/config/objspace.usemodules._weakref.txt
==============================================================================
--- pypy/dist/pypy/doc/config/objspace.usemodules._weakref.txt	(original)
+++ pypy/dist/pypy/doc/config/objspace.usemodules._weakref.txt	Tue Feb 13 13:45:58 2007
@@ -0,0 +1,2 @@
+Use the '_weakref' module. 
+This module is expected to be fully working and is included by default.

Modified: pypy/dist/pypy/doc/config/objspace.usemodules.array.txt
==============================================================================
--- pypy/dist/pypy/doc/config/objspace.usemodules.array.txt	(original)
+++ pypy/dist/pypy/doc/config/objspace.usemodules.array.txt	Tue Feb 13 13:45:58 2007
@@ -0,0 +1,2 @@
+Use the 'array' module. 
+This module is expected to be fully working and is included by default.

Modified: pypy/dist/pypy/doc/config/objspace.usemodules.bz2.txt
==============================================================================
--- pypy/dist/pypy/doc/config/objspace.usemodules.bz2.txt	(original)
+++ pypy/dist/pypy/doc/config/objspace.usemodules.bz2.txt	Tue Feb 13 13:45:58 2007
@@ -0,0 +1,2 @@
+Use the 'bz2' module. 
+This module is expected to be fully working.

Modified: pypy/dist/pypy/doc/config/objspace.usemodules.clr.txt
==============================================================================
--- pypy/dist/pypy/doc/config/objspace.usemodules.clr.txt	(original)
+++ pypy/dist/pypy/doc/config/objspace.usemodules.clr.txt	Tue Feb 13 13:45:58 2007
@@ -0,0 +1 @@
+Use the 'clr' module. 

Modified: pypy/dist/pypy/doc/config/objspace.usemodules.crypt.txt
==============================================================================
--- pypy/dist/pypy/doc/config/objspace.usemodules.crypt.txt	(original)
+++ pypy/dist/pypy/doc/config/objspace.usemodules.crypt.txt	Tue Feb 13 13:45:58 2007
@@ -0,0 +1,2 @@
+Use the 'crypt' module. 
+This module is expected to be fully working.

Modified: pypy/dist/pypy/doc/config/objspace.usemodules.errno.txt
==============================================================================
--- pypy/dist/pypy/doc/config/objspace.usemodules.errno.txt	(original)
+++ pypy/dist/pypy/doc/config/objspace.usemodules.errno.txt	Tue Feb 13 13:45:58 2007
@@ -0,0 +1,2 @@
+Use the 'errno' module. 
+This module is expected to be fully working and is included by default.

Modified: pypy/dist/pypy/doc/config/objspace.usemodules.fcntl.txt
==============================================================================
--- pypy/dist/pypy/doc/config/objspace.usemodules.fcntl.txt	(original)
+++ pypy/dist/pypy/doc/config/objspace.usemodules.fcntl.txt	Tue Feb 13 13:45:58 2007
@@ -0,0 +1,2 @@
+Use the 'fcntl' module. 
+This module is expected to be fully working.

Modified: pypy/dist/pypy/doc/config/objspace.usemodules.gc.txt
==============================================================================
--- pypy/dist/pypy/doc/config/objspace.usemodules.gc.txt	(original)
+++ pypy/dist/pypy/doc/config/objspace.usemodules.gc.txt	Tue Feb 13 13:45:58 2007
@@ -0,0 +1,2 @@
+Use the 'gc' module. 
+This module is expected to be fully working and is included by default.

Modified: pypy/dist/pypy/doc/config/objspace.usemodules.marshal.txt
==============================================================================
--- pypy/dist/pypy/doc/config/objspace.usemodules.marshal.txt	(original)
+++ pypy/dist/pypy/doc/config/objspace.usemodules.marshal.txt	Tue Feb 13 13:45:58 2007
@@ -0,0 +1,2 @@
+Use the 'marshal' module. 
+This module is expected to be fully working and is included by default.

Modified: pypy/dist/pypy/doc/config/objspace.usemodules.math.txt
==============================================================================
--- pypy/dist/pypy/doc/config/objspace.usemodules.math.txt	(original)
+++ pypy/dist/pypy/doc/config/objspace.usemodules.math.txt	Tue Feb 13 13:45:58 2007
@@ -0,0 +1,2 @@
+Use the 'math' module. 
+This module is expected to be fully working and is included by default.

Modified: pypy/dist/pypy/doc/config/objspace.usemodules.mmap.txt
==============================================================================
--- pypy/dist/pypy/doc/config/objspace.usemodules.mmap.txt	(original)
+++ pypy/dist/pypy/doc/config/objspace.usemodules.mmap.txt	Tue Feb 13 13:45:58 2007
@@ -0,0 +1,2 @@
+Use the 'mmap' module. 
+This module is expected to be fully working.

Modified: pypy/dist/pypy/doc/config/objspace.usemodules.posix.txt
==============================================================================
--- pypy/dist/pypy/doc/config/objspace.usemodules.posix.txt	(original)
+++ pypy/dist/pypy/doc/config/objspace.usemodules.posix.txt	Tue Feb 13 13:45:58 2007
@@ -0,0 +1,2 @@
+Use the 'posix' module. 
+This module is essential, included by default and should not be removed.

Modified: pypy/dist/pypy/doc/config/objspace.usemodules.pypyjit.txt
==============================================================================
--- pypy/dist/pypy/doc/config/objspace.usemodules.pypyjit.txt	(original)
+++ pypy/dist/pypy/doc/config/objspace.usemodules.pypyjit.txt	Tue Feb 13 13:45:58 2007
@@ -0,0 +1 @@
+Use the 'pypyjit' module. 

Modified: pypy/dist/pypy/doc/config/objspace.usemodules.pypymagic.txt
==============================================================================
--- pypy/dist/pypy/doc/config/objspace.usemodules.pypymagic.txt	(original)
+++ pypy/dist/pypy/doc/config/objspace.usemodules.pypymagic.txt	Tue Feb 13 13:45:58 2007
@@ -0,0 +1,2 @@
+Use the 'pypymagic' module. 
+This module is expected to be fully working and is included by default.

Modified: pypy/dist/pypy/doc/config/objspace.usemodules.rctime.txt
==============================================================================
--- pypy/dist/pypy/doc/config/objspace.usemodules.rctime.txt	(original)
+++ pypy/dist/pypy/doc/config/objspace.usemodules.rctime.txt	Tue Feb 13 13:45:58 2007
@@ -0,0 +1,2 @@
+Use the 'rctime' module. 
+This module is expected to be fully working.

Modified: pypy/dist/pypy/doc/config/objspace.usemodules.readline.txt
==============================================================================
--- pypy/dist/pypy/doc/config/objspace.usemodules.readline.txt	(original)
+++ pypy/dist/pypy/doc/config/objspace.usemodules.readline.txt	Tue Feb 13 13:45:58 2007
@@ -0,0 +1 @@
+Use the 'readline' module. 

Modified: pypy/dist/pypy/doc/config/objspace.usemodules.recparser.txt
==============================================================================
--- pypy/dist/pypy/doc/config/objspace.usemodules.recparser.txt	(original)
+++ pypy/dist/pypy/doc/config/objspace.usemodules.recparser.txt	Tue Feb 13 13:45:58 2007
@@ -0,0 +1,2 @@
+Use the 'recparser' module. 
+This module is expected to be fully working and is included by default.

Modified: pypy/dist/pypy/doc/config/objspace.usemodules.rsocket.txt
==============================================================================
--- pypy/dist/pypy/doc/config/objspace.usemodules.rsocket.txt	(original)
+++ pypy/dist/pypy/doc/config/objspace.usemodules.rsocket.txt	Tue Feb 13 13:45:58 2007
@@ -0,0 +1,2 @@
+Use the 'rsocket' module. 
+This module is expected to be fully working.

Modified: pypy/dist/pypy/doc/config/objspace.usemodules.select.txt
==============================================================================
--- pypy/dist/pypy/doc/config/objspace.usemodules.select.txt	(original)
+++ pypy/dist/pypy/doc/config/objspace.usemodules.select.txt	Tue Feb 13 13:45:58 2007
@@ -0,0 +1,2 @@
+Use the 'select' module. 
+This module is expected to be fully working.

Modified: pypy/dist/pypy/doc/config/objspace.usemodules.signal.txt
==============================================================================
--- pypy/dist/pypy/doc/config/objspace.usemodules.signal.txt	(original)
+++ pypy/dist/pypy/doc/config/objspace.usemodules.signal.txt	Tue Feb 13 13:45:58 2007
@@ -0,0 +1,2 @@
+Use the 'signal' module. 
+This module is expected to be fully working.

Modified: pypy/dist/pypy/doc/config/objspace.usemodules.symbol.txt
==============================================================================
--- pypy/dist/pypy/doc/config/objspace.usemodules.symbol.txt	(original)
+++ pypy/dist/pypy/doc/config/objspace.usemodules.symbol.txt	Tue Feb 13 13:45:58 2007
@@ -0,0 +1,2 @@
+Use the 'symbol' module. 
+This module is expected to be fully working and is included by default.

Modified: pypy/dist/pypy/doc/config/objspace.usemodules.sys.txt
==============================================================================
--- pypy/dist/pypy/doc/config/objspace.usemodules.sys.txt	(original)
+++ pypy/dist/pypy/doc/config/objspace.usemodules.sys.txt	Tue Feb 13 13:45:58 2007
@@ -0,0 +1,2 @@
+Use the 'sys' module. 
+This module is essential, included by default and should not be removed.

Modified: pypy/dist/pypy/doc/config/objspace.usemodules.thread.txt
==============================================================================
--- pypy/dist/pypy/doc/config/objspace.usemodules.thread.txt	(original)
+++ pypy/dist/pypy/doc/config/objspace.usemodules.thread.txt	Tue Feb 13 13:45:58 2007
@@ -0,0 +1 @@
+Use the 'thread' module. 

Modified: pypy/dist/pypy/doc/config/objspace.usemodules.time.txt
==============================================================================
--- pypy/dist/pypy/doc/config/objspace.usemodules.time.txt	(original)
+++ pypy/dist/pypy/doc/config/objspace.usemodules.time.txt	Tue Feb 13 13:45:58 2007
@@ -0,0 +1 @@
+Use the 'time' module. 

Modified: pypy/dist/pypy/doc/config/objspace.usemodules.unicodedata.txt
==============================================================================
--- pypy/dist/pypy/doc/config/objspace.usemodules.unicodedata.txt	(original)
+++ pypy/dist/pypy/doc/config/objspace.usemodules.unicodedata.txt	Tue Feb 13 13:45:58 2007
@@ -0,0 +1,2 @@
+Use the 'unicodedata' module. 
+This module is expected to be fully working.


From cfbolz at codespeak.net  Tue Feb 13 14:01:39 2007
From: cfbolz at codespeak.net (cfbolz at codespeak.net)
Date: Tue, 13 Feb 2007 14:01:39 +0100 (CET)
Subject: [pypy-svn] r38686 - pypy/dist/pypy/doc
Message-ID: <20070213130139.9DD7F100B0@code0.codespeak.net>

Author: cfbolz
Date: Tue Feb 13 14:01:38 2007
New Revision: 38686

Modified:
   pypy/dist/pypy/doc/garbage_collection.txt
   pypy/dist/pypy/doc/index.txt
   pypy/dist/pypy/doc/translation.txt
Log:
try to clean up the docs about garbage collection. Unfortunately we cannot
remove garbage_collection.txt, since an EU report points to it.


Modified: pypy/dist/pypy/doc/garbage_collection.txt
==============================================================================
--- pypy/dist/pypy/doc/garbage_collection.txt	(original)
+++ pypy/dist/pypy/doc/garbage_collection.txt	Tue Feb 13 14:01:38 2007
@@ -5,13 +5,17 @@
 .. contents::
 .. sectnum::
 
+
+**Warning**: The information below is incomplete and outdated (the reason we
+leave it there is that a report references it). For a more up-to-date
+description see the `EU-report on this topic`_.
+
+.. _`EU-report on this topic`: http://codespeak.net/pypy/extradoc/eu-report/D07.1_Massive_Parallelism_and_Translation_Aspects-2006-12-15.pdf
+
+
 Current Situation and Objectives
 ================================
 
-XXX *Warning*: The information below is unfortunately incomplete. I describes
-the garbage collectors themselves, but not how they are actually used in PyPy
-(via the GC transformer)
-
 This document describes how garbage collectors are implemented in PyPy. Work on
 this began as a `Summer-of-Code-project`_ (many thanks to Google!) of Carl
 Friedrich Bolz but has since been worked on by many PyPy developers.

Modified: pypy/dist/pypy/doc/index.txt
==============================================================================
--- pypy/dist/pypy/doc/index.txt	(original)
+++ pypy/dist/pypy/doc/index.txt	Tue Feb 13 14:01:38 2007
@@ -112,9 +112,6 @@
 `parser`_ contains (outdated, unfinished) documentation about
 the parser.
 
-`garbage collection`_ contains documentation about
-garbage collection in PyPy.
-
 `rlib`_ describes some modules that can be used when implementing programs in
 RPython.
 
@@ -149,7 +146,6 @@
 .. _`theory`: theory.html
 .. _`bytecode interpreter`: interpreter.html 
 .. _`EU reports`: index-report.html
-.. _`garbage collection`: garbage_collection.html
 .. _`on Linux`: http://wyvern.cs.uni-duesseldorf.de/pypytest/summary.html
 .. _`on Windows`: http://scottdial.com/pypytest/
 .. _`on built pypy-c`: http://wyvern.cs.uni-duesseldorf.de/~fijal/pypy-c-tests/
@@ -237,7 +233,7 @@
 
 `rpython/ootypesystem/`_       the `object-oriented type system`_ for OO backends
 
-`rpython/memory/`_             experimental `garbage collector`_ construction
+`rpython/memory/`_             experimental garbage collector construction
                                framework
 
 `tool/`_                       various utilities and hacks used from various places 
@@ -310,7 +306,6 @@
 .. _`CLI backend`: cli-backend.html
 .. _`Common Lisp backend`: translation.html#gencl
 .. _`Squeak backend`: translation.html#gensqueak
-.. _`garbage collector`: garbage_collection.html
 .. _`extension compiler`: extcompiler.html
 .. _`py.py`: getting-started.html#main-entry-point
 .. _`translatorshell.py`: getting-started.html#try-out-the-translator

Modified: pypy/dist/pypy/doc/translation.txt
==============================================================================
--- pypy/dist/pypy/doc/translation.txt	(original)
+++ pypy/dist/pypy/doc/translation.txt	Tue Feb 13 14:01:38 2007
@@ -641,37 +641,10 @@
 performance of the PyPy interpreter.  That said, work so far has many focussed
 on flexibility and robustness, not performance.
 
-Reference Counting
-++++++++++++++++++
+For a quite detailed description of how memory management and garbage collection
+are performed in PyPy, see the `EU report`_ about this topic (section 4.2).
 
-`Reference counting`_ is a well-known and conceptually simple approach to
-memory management.  An integer is stored at the front of each heap object that
-counts how many references exist to the object, and this count is updated as
-references are created and disposed of.
-
-Reference counting has some well known problems: it can be slow if you make
-frequent updates to the reference count, and unless you take special steps,
-cycles of objects will leak.  We make a little effort to reduce unnecessary
-reference counts, but not a great deal, and no efforts to avoid the problems
-with cyclic reference counts.  It is the worst performing of the three options.
-
-For these reasons and others, the reference counting option doesn't seem the
-most interesting at present.  It will be maintained, but probably not
-developed further.
-
-.. _`Reference counting`: http://en.wikipedia.org/wiki/Reference_counting
-
-Using the B-D-W collector
-+++++++++++++++++++++++++
-
-C with the addition of the Boehm collector actually has a very similar memory
-management model to that of RPython, so the BoehmGCTransformer is quite
-simple.  The Boehm GC performs somewhat better than the other options currently.
-
-Using our own collector
-+++++++++++++++++++++++
-
-XXX
+.. _`EU report`: http://codespeak.net/pypy/extradoc/eu-report/D07.1_Massive_Parallelism_and_Translation_Aspects-2006-12-15.pdf
 
 Building the Low-Level Database
 -------------------------------


From arigo at codespeak.net  Tue Feb 13 14:05:24 2007
From: arigo at codespeak.net (arigo at codespeak.net)
Date: Tue, 13 Feb 2007 14:05:24 +0100 (CET)
Subject: [pypy-svn] r38687 - in pypy/dist/pypy: module/_sre/test rlib/rsre
Message-ID: <20070213130524.3D098100B5@code0.codespeak.net>

Author: arigo
Date: Tue Feb 13 14:05:22 2007
New Revision: 38687

Modified:
   pypy/dist/pypy/module/_sre/test/test_app_sre.py
   pypy/dist/pypy/rlib/rsre/rsre_core.py
Log:
Squashed another

           _________     o o
          /         \   / /
      --sre groups bug----
         / \ / \ / \ / \



Modified: pypy/dist/pypy/module/_sre/test/test_app_sre.py
==============================================================================
--- pypy/dist/pypy/module/_sre/test/test_app_sre.py	(original)
+++ pypy/dist/pypy/module/_sre/test/test_app_sre.py	Tue Feb 13 14:05:22 2007
@@ -194,7 +194,7 @@
         m = re.match('hel+', a)
         assert m.end() == 4
 
-    def test_group_bug(self):
+    def test_group_bugs(self):
         import re
         r = re.compile(r"""
             \&(?:
@@ -218,6 +218,16 @@
                                           'named': None,
                                           'braced': None,
                                           'invalid': None}
+        matches = list(r.finditer('&who likes &{what)'))   # note the ')'
+        assert len(matches) == 2
+        assert matches[0].groupdict() == {'escaped': None,
+                                          'named': 'who',
+                                          'braced': None,
+                                          'invalid': None}
+        assert matches[1].groupdict() == {'escaped': None,
+                                          'named': None,
+                                          'braced': None,
+                                          'invalid': ''}
 
 
 class AppTestSreScanner:

Modified: pypy/dist/pypy/rlib/rsre/rsre_core.py
==============================================================================
--- pypy/dist/pypy/rlib/rsre/rsre_core.py	(original)
+++ pypy/dist/pypy/rlib/rsre/rsre_core.py	Tue Feb 13 14:05:22 2007
@@ -69,7 +69,7 @@
         self.marks, self.lastindex = self.marks_stack.pop()
 
     def marks_pop_keep(self):
-        self.marks, self.lastindex = self.marks_stack[-1]
+        self.marks[:], self.lastindex = self.marks_stack[-1]
 
     def marks_pop_discard(self):
         self.marks_stack.pop()


From arigo at codespeak.net  Tue Feb 13 14:11:04 2007
From: arigo at codespeak.net (arigo at codespeak.net)
Date: Tue, 13 Feb 2007 14:11:04 +0100 (CET)
Subject: [pypy-svn] r38688 - pypy/dist/pypy/rlib/rsre
Message-ID: <20070213131104.E69CE1009B@code0.codespeak.net>

Author: arigo
Date: Tue Feb 13 14:11:02 2007
New Revision: 38688

Modified:
   pypy/dist/pypy/rlib/rsre/rsre_core.py
Log:
Oups, that was not RPython, actually.


Modified: pypy/dist/pypy/rlib/rsre/rsre_core.py
==============================================================================
--- pypy/dist/pypy/rlib/rsre/rsre_core.py	(original)
+++ pypy/dist/pypy/rlib/rsre/rsre_core.py	Tue Feb 13 14:11:02 2007
@@ -69,7 +69,8 @@
         self.marks, self.lastindex = self.marks_stack.pop()
 
     def marks_pop_keep(self):
-        self.marks[:], self.lastindex = self.marks_stack[-1]
+        marks, self.lastindex = self.marks_stack[-1]
+        self.marks = marks[:]
 
     def marks_pop_discard(self):
         self.marks_stack.pop()


From cfbolz at codespeak.net  Tue Feb 13 14:11:37 2007
From: cfbolz at codespeak.net (cfbolz at codespeak.net)
Date: Tue, 13 Feb 2007 14:11:37 +0100 (CET)
Subject: [pypy-svn] r38689 - pypy/dist/pypy/doc
Message-ID: <20070213131137.1CD51100BC@code0.codespeak.net>

Author: cfbolz
Date: Tue Feb 13 14:11:36 2007
New Revision: 38689

Modified:
   pypy/dist/pypy/doc/garbage_collection.txt
Log:
really remove the content and only point to the eu report


Modified: pypy/dist/pypy/doc/garbage_collection.txt
==============================================================================
--- pypy/dist/pypy/doc/garbage_collection.txt	(original)
+++ pypy/dist/pypy/doc/garbage_collection.txt	Tue Feb 13 14:11:36 2007
@@ -6,327 +6,11 @@
 .. sectnum::
 
 
-**Warning**: The information below is incomplete and outdated (the reason we
-leave it there is that a report references it). For a more up-to-date
-description see the `EU-report on this topic`_.
+**Warning**: The that was in this document was incomplete and outdated. A much
+more up-to-date view of garbage collection in PyPy can be found in the
+`EU-report on this topic`_.
 
 .. _`EU-report on this topic`: http://codespeak.net/pypy/extradoc/eu-report/D07.1_Massive_Parallelism_and_Translation_Aspects-2006-12-15.pdf
 
 
-Current Situation and Objectives
-================================
 
-This document describes how garbage collectors are implemented in PyPy. Work on
-this began as a `Summer-of-Code-project`_ (many thanks to Google!) of Carl
-Friedrich Bolz but has since been worked on by many PyPy developers.
-
-The central idea is of course to implement PyPy's garbage collectors in Python
-itself. RPython itself is a garbage collected language that means at one point
-garbage collection has to be inserted into the flow graphs, since the typical
-target languages (C, LLVM) need explicit memory management.
-
-At the moment it is possible to do garbage collections in different ways in
-PyPy. The easiest one (and the one that performs best at the moment) is to use
-the `Boehm-Demers-Weiser garbage collector`_. Then there is a reference
-counting implementation (which is atrociously slow). In addition the
-mark-and-sweep collector that is described below can be used.
-
-Of these three, only the mark-and-sweep collector is written in Python itself.
-How garbage collectors can be written in Python is described in the following.
-
-.. _`Summer-of-Code-project`: http://code.google.com/summerofcode.html
-.. _`Boehm-Demers-Weiser garbage collector`: http://www.hpl.hp.com/personal/Hans_Boehm/gc/
-
-
-Memory Access
-=============
-
-The garbage collector needs a way to generically access memory. For this there
-is a special ``address`` class that behaves like a pointer to a location in
-memory of unspecified type. Offsets between addresses are regular integers.
-
-Addresses
----------
-
-The ``address`` class is implemented in the file
-`pypy/rpython/memory/lladdress.py`_. There is one special ``address``
-instance, ``NULL``, which is equivalent to a null pointer.
-
-
-Manipulation of Memory
-++++++++++++++++++++++
-
-The following functions are used to directly manipulate memory:
-
-   ``raw_malloc(size) --> address``: 
-       Allocates a block of memory of ``size`` bytes. This is (apart from the
-       ``NULL`` object) a canonical way to create new addresses.
-
-   ``raw_free(addr) --> None``:
-       Frees a block of memory
-
-   ``raw_memcopy(addr_from, addr_to, size) --> None``:
-       Copies ``size`` bytes from ``addr_from`` to ``addr_to``
-
-
-
-Address arithmetic
-++++++++++++++++++
-
-Pointer arithmetic between the addresses is done via overloaded operators:
-Subtraction of two addresses gives an offset (integer), addition/subtraction
-of an offset (integer) gives another address. Furthermore addresses can be
-compared to each other.
-
-Accessing Memory
-++++++++++++++++
-
-Given an instance ``addr`` of ``address`` memory is accessed the following
-way:
-
-    ``addr.signed[index] --> signed``:
-         reads a signed integer from the point in memory that is ``index``
-         signed integers distant from the ``addr``
-        
-    ``addr.signed[index] = value``:
-         writes the signed integer ``value`` to the point in memory that is
-         ``index`` signed integers distant from the ``addr``
-
-Memory access is supported for the datatypes ''signed, unsigned, char`` and ``address``.
-
-Addresses in the Translation Toolchain
----------------------------------------
-
-Instances of the ``address`` class are annotated as ``SomeAddress``. The
-RTyper produces sensible results for operations with addresses: All the
-basic functions manipulating addresses like ``raw_malloc`` and so on are
-turned into operations in the flow graph.
-
-
-The Memory Simulator
---------------------
-
-The memory simulator (`pypy/rpython/memory/simulator.py`_) lets instances of
-the ``address`` class and related functions work in a realistic manner while
-using them in a Python program (as opposed to after translation). The
-simulator implements memory using the ``array`` module from the Python
-standard library. It checks for common memory access errors to help finding
-bugs early:
-
-   - reading from uninitialized memory
-   - reading from freed memory or the ``NULL`` address
-   - freeing a memory block twice or more
-   - freeing a memory block that was not malloced
-   - trying to free the ``NULL`` address
-   - trying to malloc more memory than the simulated RAM has
-
-
-The Object Model
-================
-
-The GC needs to gain some sort of information about the objects it works
-with. To achieve this an integer ``typeid`` is attached_ to every object the
-GC manages, which is unique to each `low-level type`_. The GC uses this
-id to find pointers that are contained in the object and to find out the size
-of the object.
-
-.. _`low-level type`: rtyper.html#low-level-type
-
-.. _above:
-
-Getting Information about Object Layout
----------------------------------------
-
-The following functions are available to the GC to get information about
-objects:
-
-    ``is_varsize(typeid) --> bool``:
-        returns whether the type is variable sized, i.e. is it an Array or a
-        struct with an inlined array
-
-    ``offsets_to_gc_pointers(typeid)`` --> list of offsets:
-        returns a list of offsets to pointers that need to be traced by the
-        garbage collection and are contained within the object
-
-    ``fixed_size(typeid)`` --> size:
-        returns the size in bytes of the fixed size part of the type. For
-        non-varsize types this is just the size of the whole object.
-
-    ``varsize_item_sizes(typeid)`` --> size:
-        returns the size of one item of the variable sized part of the type
-
-    ``varsize_offset_to_variable_part(typeid)`` --> offset:
-        returns the offset to the first element of the variable sized part of
-        the type
-
-    ``varsize_offset_to_length(typeid)`` --> offset:
-        returns the offset to the length (number of items) of the variable
-        sized type
-
-    ``varsize_offsets_to_gcpointers_in_var_part(typeid)`` --> list of offsets:
-        returns a list of offsets to pointers that need to be traced by the
-        collection in one element of the variable sized part of the type
-
-
-Garbage Collectors
-==================
-
-Explicit Memory Management
---------------------------
-
-The data structures of the GC can not be handled by the GC itself. Therefore
-it is necessary to have explicit management of memory. One possibility for
-doing this is via ``raw_malloc, raw_free``  and addresses. Another possibility
-is the following: Classes can be declared as being explicitly managed by
-attaching a attribute ``_alloc_flavor_ = "raw"`` to the class.
-
-Instance creation is done the regular way, to free an instance there is a
-special function ``free_non_gc_object`` defined in
-`pypy/rlib/objectmodel.py`_. Trying to access any attribute of the instance
-after it was freed gives an exception (which is not equivalent to the
-behaviour after translation: there it would just lead to a crash) Example::
-
-    class A(object):
-        _alloc_flavor_ = "raw"
-        def __init__(self):
-            self.x = ...
-        def method(self):
-            ...
-        ...
-
-    a = A()
-    a.x = 1
-    a.method()
-    free_non_gc_object(a)
-    a.method() #--> crash
-
-The RTyper uses for instantiations of objects with an ``_alloc_flavor_ =
-"raw"`` the space operations ``flavored_malloc`` and the operation
-``flavored_free`` for a call to ``free_non_gc_object``.
-
-Accessing the Root Set
-----------------------
-
-The garbage collector can access the current set of roots via a function
-``get_roots``:
-
-    ``get_roots()`` --> linked list of addresses:
-        returns a linked list (see `pypy/rpython/memory/support.py`_) of
-	addresses to pointers to objects that can be reached from the running
-	program at the moment
-
-The garbage collector needs to make sure that the running program can still
-access the objects in the root set after the collection -- this means that for
-a moving collector the pointers to objects need to be updated.
-
-.. _attached:
-
-Memory Layout of the Data of the Garbage Collector
---------------------------------------------------
-
-The Garbage Collector stores the data it needs to attach to an object directly
-in front of it. The program sees only pointers to the part of the object
-that contains non-GC-specific data::
-
-                        +---<- program sees only this
-                        |
-    +---------+---------+----------------------------+
-    | gc info | type id | object data                |
-    | signed  | signed  | whatever ...               |
-    +---------+---------+----------------------------+
-
-At the moment all collectors put two signed integers in front of the
-object. Directly in front of the object data the typeid of the type of the
-object is stored. In front of that is another integer which usage is dependent
-of the type of the GC (for example the refcounting GC stores the reference
-count there).
-
-Garbage Collection Hooks
-------------------------
-
-There are different methods that each GC needs to implement. These will be
-called while the main program is running (either by the LLInterpreter_ or the
-calls are inserted to appropriate places by the backend):
-
-    ``malloc(self, typeid, length=0)`` --> address:
-        returns the address of a suitably sized memory chunk for an object
-        that is supposed to be garbage collected. The GC can calculate the
-        size in bytes with the typeid and the length together with the
-        functions described above_.
-
-    ``collect(self) --> None``:
-        triggers a garbage collection
-
-    ``size_gc_header(self, typeid)`` --> size:
-        returns the size of the GC header (for all GCs implemented at the
-        moment this is a constant, though the size of the GC header might also
-        be dependent on the type of the object for more sophisticated GCs)
-
-    ``init_gc_object(self, addr, typeid) --> None``:
-        initializes the gc header of an object
-
-    ``init_gc_object_immortal(self, addr, typeid) --> None``:
-        initializes the gc header of an object that is supposed to be immortal
-        (for example a refcounting GC might set the refcount to a very big
-        value that will never reach zero).
-
-    ``write_barrier(self, addr, addr_to, addr_struct) --> None``:
-        this method is called if a pointer to an object managed by the GC is
-        written into another object on the heap. The method is supposed to
-        always write the address ``addr`` to the address ``addr_to`` plus do
-        all the things that are needed for the GC. The address ``addr_struct``
-        points to the beginning of the structure that contains
-        ``addr_to``. For example a refcounting GC will increment the refcount
-        of ``addr`` and decrement that of the object stored at the old address
-        in ``addr_to``.
-
-.. _LLInterpreter: rtyper.html#llinterpreter
-
-Description of Implemented Garbage Collectors
----------------------------------------------
-
-At the moment there are three different garbage collectors implemented. They
-are all done naively in one way or the other and are mainly there to
-demonstrate the concepts. They can be found in
-`pypy/rpython/memory/gc.py`_. For a more detailed description of the
-algorithms used see `this page`_.
-
-.. _`this page`: http://www.memorymanagement.org/articles/recycle.html
-
-Mark and Sweep
-++++++++++++++
-
-This is quite a regular mark and sweep collector. The biggest difference is
-that it keeps a linked list of all malloced objects because it has no other
-way to find malloced objects later. It uses the gc info fields as a
-ridiculously big mark bit. Collection is triggered if the size of the objects
-malloced since the last collection is as big as the current heap size.
-
-Copying Garbage Collection
-++++++++++++++++++++++++++
-
-This is a simple implementation of `Cheney's copying collector`_. The heap is
-divided in two spaces, fromspace and tospace. New objects are allocated to
-tospace. When tospace is full, the roles of the spaces are exchanged. Then,
-starting from the root objects, all reachable objects are copied to the new
-space. The special feature of Cheney's algorithm is that this is done in an
-essentially non-recursive manner.
-
-.. _`Cheney's copying collector`: http://portal.acm.org/citation.cfm?id=362798
-
-
-Deferred Reference Counting
-+++++++++++++++++++++++++++
-
-Deferred reference counting is a reference counting algorithm that tries to
-reduce the overhead of reference counting at the expense of the immediacy of a
-regular refcounting implementation. To achieve this the refcounts of an
-object only count the references from other objects on the heap, not
-references from the stack. If the refcount of an object reaches zero it can 
-not be freed immediately (since it could be reachable from the stack). Instead
-it is added to a zero-refcount-list. When collection occurs the refcounts of
-all the root objects are increased by one. All the objects of the
-zero-refcount-list that still have a refcount of zero are freed. Afterwards
-the refcounts of roots are decreased by one again.
-
-.. include:: _ref.txt


From cfbolz at codespeak.net  Tue Feb 13 14:17:44 2007
From: cfbolz at codespeak.net (cfbolz at codespeak.net)
Date: Tue, 13 Feb 2007 14:17:44 +0100 (CET)
Subject: [pypy-svn] r38690 - pypy/dist/pypy/doc
Message-ID: <20070213131744.738D2100B7@code0.codespeak.net>

Author: cfbolz
Date: Tue Feb 13 14:17:43 2007
New Revision: 38690

Modified:
   pypy/dist/pypy/doc/translation.txt
Log:
update intro to OO backends a small bit


Modified: pypy/dist/pypy/doc/translation.txt
==============================================================================
--- pypy/dist/pypy/doc/translation.txt	(original)
+++ pypy/dist/pypy/doc/translation.txt	Tue Feb 13 14:17:43 2007
@@ -733,15 +733,12 @@
 The Object-Oriented Backends
 ----------------------------
 
-All of the OO backends are less mature than the C or LLVM backends.
-None can compile all of PyPy yet, but all can compile small examples.
+The Object-Oriented backends target platforms that are less C-like and support
+classes, instance etc. If such a platform is targetted, the `OO type system` is
+used while rtyping. Of the OO backends, currently only genclr can translate the
+full PyPy, but the Java backend is getting close.
 
-As they are newer than the low-level backends, we can predict the needs of
-these backends slightly better, and this is enabling them to share significant
-amounts of code, such as the equivalent of the low-level database (XXX
-details).
-
-LoopFinder?
+.. _`oo type system`: rtyper.html#oo-type
 
 .. mention that pretty much all these backends are done by volunteers?
 


From alix at codespeak.net  Tue Feb 13 14:19:59 2007
From: alix at codespeak.net (alix at codespeak.net)
Date: Tue, 13 Feb 2007 14:19:59 +0100 (CET)
Subject: [pypy-svn] r38691 - pypy/extradoc/sprintinfo/pypy-travel
Message-ID: <20070213131959.385F8100BD@code0.codespeak.net>

Author: alix
Date: Tue Feb 13 14:19:53 2007
New Revision: 38691

Added:
   pypy/extradoc/sprintinfo/pypy-travel/
Log:
tried to structure my folders


From pedronis at codespeak.net  Tue Feb 13 14:22:42 2007
From: pedronis at codespeak.net (pedronis at codespeak.net)
Date: Tue, 13 Feb 2007 14:22:42 +0100 (CET)
Subject: [pypy-svn] r38692 - pypy/dist/pypy
Message-ID: <20070213132242.8D54B100BB@code0.codespeak.net>

Author: pedronis
Date: Tue Feb 13 14:22:40 2007
New Revision: 38692

Modified:
   pypy/dist/pypy/conftest.py
Log:
we need to be more subtle here for runappdirect. the internal names used by the options
don't match the import name, use the translation_info instead of an import to check for presence.
If translation_info is not there (CPython case) assume all modules are there, this is mostly
useful for py.test -A runs for comparison purposes, it may be wrong for some pypy specific modules.



Modified: pypy/dist/pypy/conftest.py
==============================================================================
--- pypy/dist/pypy/conftest.py	(original)
+++ pypy/dist/pypy/conftest.py	Tue Feb 13 14:22:40 2007
@@ -65,18 +65,20 @@
 class TinyObjSpace(object):
     def __init__(self, **kwds):
         import sys
+        info = getattr(sys, 'pypy_translation_info', None)
         for key, value in kwds.iteritems():
             if key == 'usemodules':
-                for modname in value:
-                    try:
-                        __import__(modname)
-                    except ImportError:
-                        py.test.skip("cannot runappdirect test: "
-                                     "module %r required" % (modname,))
+                if info is not None:
+                    for modname in value:
+                        ok = info.get('objspace.usemodules.%s' % modname,
+                                      False)
+                        if not ok:
+                            py.test.skip("cannot runappdirect test: "
+                                         "module %r required" % (modname,))
                 continue
-            if not hasattr(sys, 'pypy_translation_info'):
+            if info is None:
                 py.test.skip("cannot runappdirect this test on top of CPython")
-            has = sys.pypy_translation_info.get(key, None)
+            has = info.get(key, None)
             if has != value:
                 #print sys.pypy_translation_info
                 py.test.skip("cannot runappdirect test: space needs %s = %s, "\


From pedronis at codespeak.net  Tue Feb 13 14:26:41 2007
From: pedronis at codespeak.net (pedronis at codespeak.net)
Date: Tue, 13 Feb 2007 14:26:41 +0100 (CET)
Subject: [pypy-svn] r38693 - pypy/dist/pypy/module/rsocket/test
Message-ID: <20070213132641.46D64100A6@code0.codespeak.net>

Author: pedronis
Date: Tue Feb 13 14:26:40 2007
New Revision: 38693

Modified:
   pypy/dist/pypy/module/rsocket/test/test_sock_app.py
Log:
try to make py.test -A runs of this test work or skip cleanly.



Modified: pypy/dist/pypy/module/rsocket/test/test_sock_app.py
==============================================================================
--- pypy/dist/pypy/module/rsocket/test/test_sock_app.py	(original)
+++ pypy/dist/pypy/module/rsocket/test/test_sock_app.py	Tue Feb 13 14:26:40 2007
@@ -1,13 +1,13 @@
-from pypy.objspace.std import StdObjSpace
-from pypy.interpreter.error import OperationError
-from pypy.tool.udir import udir
 from pypy.conftest import gettestobjspace
+import sys
 import py
-import socket, sys
 
 def setup_module(mod):
     mod.space = gettestobjspace(usemodules=['rsocket'])
+    global socket
+    import socket
     mod.w_socket = space.appexec([], "(): import _socket as m; return m")
+    from pypy.tool.udir import udir
     mod.path = udir.join('fd')
     mod.path.write('fo')
     mod.raises = py.test.raises # make raises available from app-level tests


From arigo at codespeak.net  Tue Feb 13 14:27:27 2007
From: arigo at codespeak.net (arigo at codespeak.net)
Date: Tue, 13 Feb 2007 14:27:27 +0100 (CET)
Subject: [pypy-svn] r38694 - pypy/dist/lib-python/modified-2.4.1/test
Message-ID: <20070213132727.3DE7A100B2@code0.codespeak.net>

Author: arigo
Date: Tue Feb 13 14:27:26 2007
New Revision: 38694

Added:
   pypy/dist/lib-python/modified-2.4.1/test/test_random.py
      - copied, changed from r38689, pypy/dist/lib-python/2.4.1/test/test_random.py
Log:
Arbitrarily decide that it's the test and not the module implementation
that is broken.



From cfbolz at codespeak.net  Tue Feb 13 14:33:16 2007
From: cfbolz at codespeak.net (cfbolz at codespeak.net)
Date: Tue, 13 Feb 2007 14:33:16 +0100 (CET)
Subject: [pypy-svn] r38695 - pypy/extradoc/sprintinfo/pypy-travel
Message-ID: <20070213133316.4D7FC10094@code0.codespeak.net>

Author: cfbolz
Date: Tue Feb 13 14:33:14 2007
New Revision: 38695

Removed:
   pypy/extradoc/sprintinfo/pypy-travel/
Log:
remove accidentally checked in folder.



From cfbolz at codespeak.net  Tue Feb 13 14:47:23 2007
From: cfbolz at codespeak.net (cfbolz at codespeak.net)
Date: Tue, 13 Feb 2007 14:47:23 +0100 (CET)
Subject: [pypy-svn] r38696 - pypy/dist/pypy/doc/config
Message-ID: <20070213134723.B7647100A8@code0.codespeak.net>

Author: cfbolz
Date: Tue Feb 13 14:47:22 2007
New Revision: 38696

Modified:
   pypy/dist/pypy/doc/config/makemodules.py
   pypy/dist/pypy/doc/config/objspace.usemodules._codecs.txt
   pypy/dist/pypy/doc/config/objspace.usemodules._pickle_support.txt
   pypy/dist/pypy/doc/config/objspace.usemodules._random.txt
   pypy/dist/pypy/doc/config/objspace.usemodules._sre.txt
   pypy/dist/pypy/doc/config/objspace.usemodules._weakref.txt
   pypy/dist/pypy/doc/config/objspace.usemodules.array.txt
   pypy/dist/pypy/doc/config/objspace.usemodules.errno.txt
   pypy/dist/pypy/doc/config/objspace.usemodules.gc.txt
   pypy/dist/pypy/doc/config/objspace.usemodules.marshal.txt
   pypy/dist/pypy/doc/config/objspace.usemodules.math.txt
   pypy/dist/pypy/doc/config/objspace.usemodules.pypymagic.txt
   pypy/dist/pypy/doc/config/objspace.usemodules.recparser.txt
   pypy/dist/pypy/doc/config/objspace.usemodules.symbol.txt
Log:
remove the "fully" (expectation management). thanks samuele.


Modified: pypy/dist/pypy/doc/config/makemodules.py
==============================================================================
--- pypy/dist/pypy/doc/config/makemodules.py	(original)
+++ pypy/dist/pypy/doc/config/makemodules.py	Tue Feb 13 14:47:22 2007
@@ -18,7 +18,7 @@
         if p in pypyoption.essential_modules:
             text.append("This module is essential, included by default and should not be removed.")
         elif p in pypyoption.default_modules:
-            text.append("This module is expected to be fully working and is included by default.")
+            text.append("This module is expected to be working and is included by default.")
         elif p in pypyoption.working_modules:
             text.append("This module is expected to be fully working.")
         text.append("")

Modified: pypy/dist/pypy/doc/config/objspace.usemodules._codecs.txt
==============================================================================
--- pypy/dist/pypy/doc/config/objspace.usemodules._codecs.txt	(original)
+++ pypy/dist/pypy/doc/config/objspace.usemodules._codecs.txt	Tue Feb 13 14:47:22 2007
@@ -1,2 +1,2 @@
 Use the '_codecs' module. 
-This module is expected to be fully working and is included by default.
+This module is expected to be working and is included by default.

Modified: pypy/dist/pypy/doc/config/objspace.usemodules._pickle_support.txt
==============================================================================
--- pypy/dist/pypy/doc/config/objspace.usemodules._pickle_support.txt	(original)
+++ pypy/dist/pypy/doc/config/objspace.usemodules._pickle_support.txt	Tue Feb 13 14:47:22 2007
@@ -1,2 +1,2 @@
 Use the '_pickle_support' module. 
-This module is expected to be fully working and is included by default.
+This module is expected to be working and is included by default.

Modified: pypy/dist/pypy/doc/config/objspace.usemodules._random.txt
==============================================================================
--- pypy/dist/pypy/doc/config/objspace.usemodules._random.txt	(original)
+++ pypy/dist/pypy/doc/config/objspace.usemodules._random.txt	Tue Feb 13 14:47:22 2007
@@ -1,2 +1,2 @@
 Use the '_random' module. 
-This module is expected to be fully working and is included by default.
+This module is expected to be working and is included by default.

Modified: pypy/dist/pypy/doc/config/objspace.usemodules._sre.txt
==============================================================================
--- pypy/dist/pypy/doc/config/objspace.usemodules._sre.txt	(original)
+++ pypy/dist/pypy/doc/config/objspace.usemodules._sre.txt	Tue Feb 13 14:47:22 2007
@@ -1,2 +1,2 @@
 Use the '_sre' module. 
-This module is expected to be fully working and is included by default.
+This module is expected to be working and is included by default.

Modified: pypy/dist/pypy/doc/config/objspace.usemodules._weakref.txt
==============================================================================
--- pypy/dist/pypy/doc/config/objspace.usemodules._weakref.txt	(original)
+++ pypy/dist/pypy/doc/config/objspace.usemodules._weakref.txt	Tue Feb 13 14:47:22 2007
@@ -1,2 +1,2 @@
 Use the '_weakref' module. 
-This module is expected to be fully working and is included by default.
+This module is expected to be working and is included by default.

Modified: pypy/dist/pypy/doc/config/objspace.usemodules.array.txt
==============================================================================
--- pypy/dist/pypy/doc/config/objspace.usemodules.array.txt	(original)
+++ pypy/dist/pypy/doc/config/objspace.usemodules.array.txt	Tue Feb 13 14:47:22 2007
@@ -1,2 +1,2 @@
 Use the 'array' module. 
-This module is expected to be fully working and is included by default.
+This module is expected to be working and is included by default.

Modified: pypy/dist/pypy/doc/config/objspace.usemodules.errno.txt
==============================================================================
--- pypy/dist/pypy/doc/config/objspace.usemodules.errno.txt	(original)
+++ pypy/dist/pypy/doc/config/objspace.usemodules.errno.txt	Tue Feb 13 14:47:22 2007
@@ -1,2 +1,2 @@
 Use the 'errno' module. 
-This module is expected to be fully working and is included by default.
+This module is expected to be working and is included by default.

Modified: pypy/dist/pypy/doc/config/objspace.usemodules.gc.txt
==============================================================================
--- pypy/dist/pypy/doc/config/objspace.usemodules.gc.txt	(original)
+++ pypy/dist/pypy/doc/config/objspace.usemodules.gc.txt	Tue Feb 13 14:47:22 2007
@@ -1,2 +1,2 @@
 Use the 'gc' module. 
-This module is expected to be fully working and is included by default.
+This module is expected to be working and is included by default.

Modified: pypy/dist/pypy/doc/config/objspace.usemodules.marshal.txt
==============================================================================
--- pypy/dist/pypy/doc/config/objspace.usemodules.marshal.txt	(original)
+++ pypy/dist/pypy/doc/config/objspace.usemodules.marshal.txt	Tue Feb 13 14:47:22 2007
@@ -1,2 +1,2 @@
 Use the 'marshal' module. 
-This module is expected to be fully working and is included by default.
+This module is expected to be working and is included by default.

Modified: pypy/dist/pypy/doc/config/objspace.usemodules.math.txt
==============================================================================
--- pypy/dist/pypy/doc/config/objspace.usemodules.math.txt	(original)
+++ pypy/dist/pypy/doc/config/objspace.usemodules.math.txt	Tue Feb 13 14:47:22 2007
@@ -1,2 +1,2 @@
 Use the 'math' module. 
-This module is expected to be fully working and is included by default.
+This module is expected to be working and is included by default.

Modified: pypy/dist/pypy/doc/config/objspace.usemodules.pypymagic.txt
==============================================================================
--- pypy/dist/pypy/doc/config/objspace.usemodules.pypymagic.txt	(original)
+++ pypy/dist/pypy/doc/config/objspace.usemodules.pypymagic.txt	Tue Feb 13 14:47:22 2007
@@ -1,2 +1,2 @@
 Use the 'pypymagic' module. 
-This module is expected to be fully working and is included by default.
+This module is expected to be working and is included by default.

Modified: pypy/dist/pypy/doc/config/objspace.usemodules.recparser.txt
==============================================================================
--- pypy/dist/pypy/doc/config/objspace.usemodules.recparser.txt	(original)
+++ pypy/dist/pypy/doc/config/objspace.usemodules.recparser.txt	Tue Feb 13 14:47:22 2007
@@ -1,2 +1,2 @@
 Use the 'recparser' module. 
-This module is expected to be fully working and is included by default.
+This module is expected to be working and is included by default.

Modified: pypy/dist/pypy/doc/config/objspace.usemodules.symbol.txt
==============================================================================
--- pypy/dist/pypy/doc/config/objspace.usemodules.symbol.txt	(original)
+++ pypy/dist/pypy/doc/config/objspace.usemodules.symbol.txt	Tue Feb 13 14:47:22 2007
@@ -1,2 +1,2 @@
 Use the 'symbol' module. 
-This module is expected to be fully working and is included by default.
+This module is expected to be working and is included by default.


From arigo at codespeak.net  Tue Feb 13 15:03:03 2007
From: arigo at codespeak.net (arigo at codespeak.net)
Date: Tue, 13 Feb 2007 15:03:03 +0100 (CET)
Subject: [pypy-svn] r38697 - in pypy/dist/pypy/module: _sre _sre/test
	mmap/test
Message-ID: <20070213140303.75AAC100AC@code0.codespeak.net>

Author: arigo
Date: Tue Feb 13 15:03:00 2007
New Revision: 38697

Modified:
   pypy/dist/pypy/module/_sre/interp_sre.py
   pypy/dist/pypy/module/_sre/test/test_app_sre.py
   pypy/dist/pypy/module/mmap/test/test_mmap.py
Log:
Some minimal type-checking on the object that we pass to sre:
it should be a "sequence" object, at least.


Modified: pypy/dist/pypy/module/_sre/interp_sre.py
==============================================================================
--- pypy/dist/pypy/module/_sre/interp_sre.py	(original)
+++ pypy/dist/pypy/module/_sre/interp_sre.py	Tue Feb 13 15:03:00 2007
@@ -161,6 +161,11 @@
     def unwrap_object(self):
         # cannot unwrap in the general case
         space = self.space
+        # some type-checking
+        if (space.lookup(self.w_string, '__getitem__') is None or
+            space.lookup(self.w_string, 'keys') is not None):
+            msg = "string or sequence of characters expected"
+            raise OperationError(space.w_TypeError, space.wrap(msg))
         return space.int_w(space.len(self.w_string))
 
     def get_char_ord(self, p):

Modified: pypy/dist/pypy/module/_sre/test/test_app_sre.py
==============================================================================
--- pypy/dist/pypy/module/_sre/test/test_app_sre.py	(original)
+++ pypy/dist/pypy/module/_sre/test/test_app_sre.py	Tue Feb 13 15:03:00 2007
@@ -229,6 +229,11 @@
                                           'braced': None,
                                           'invalid': ''}
 
+    def test_sub_typecheck(self):
+        import re
+        KEYCRE = re.compile(r"%\(([^)]*)\)s|.")
+        raises(TypeError, KEYCRE.sub, "hello", {"%(": 1})
+
 
 class AppTestSreScanner:
 

Modified: pypy/dist/pypy/module/mmap/test/test_mmap.py
==============================================================================
--- pypy/dist/pypy/module/mmap/test/test_mmap.py	(original)
+++ pypy/dist/pypy/module/mmap/test/test_mmap.py	Tue Feb 13 15:03:00 2007
@@ -419,6 +419,17 @@
 #         m = mmap(self.f.fileno(), 6)
 #         assert m[-3:7] == "bar"
 # 
+
+    def test_sequence_type(self):
+        from mmap import mmap
+        f = open(self.tmpname + "x", "w+")
+        f.write("foobar")
+        f.flush()
+        m = mmap(f.fileno(), 6)
+        import operator
+        assert operator.isSequenceType(m)
+        assert not operator.isMappingType(m)
+
     def test_all(self):
         # this is a global test, ported from test_mmap.py
         import mmap


From cfbolz at codespeak.net  Tue Feb 13 15:23:25 2007
From: cfbolz at codespeak.net (cfbolz at codespeak.net)
Date: Tue, 13 Feb 2007 15:23:25 +0100 (CET)
Subject: [pypy-svn] r38698 - pypy/dist/pypy/doc
Message-ID: <20070213142325.9EF22100BD@code0.codespeak.net>

Author: cfbolz
Date: Tue Feb 13 15:23:23 2007
New Revision: 38698

Added:
   pypy/dist/pypy/doc/cleanup-todo.txt
Log:
add a (for now small) cleanup todo list. add things freely


Added: pypy/dist/pypy/doc/cleanup-todo.txt
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/doc/cleanup-todo.txt	Tue Feb 13 15:23:23 2007
@@ -0,0 +1,15 @@
+
+PyPy cleanup areas
+==================
+
+This is a todo list that lists various areas of PyPy that should be cleaned up
+(for whatever reason: less mess, less code duplication, etc).
+
+translation toolchain
+---------------------
+
+ - low level backends should share more code
+ - all backends should have more consistent interfaces
+ - geninterp is a hack
+ - keepalives need to die, finally
+


From pedronis at codespeak.net  Tue Feb 13 15:23:37 2007
From: pedronis at codespeak.net (pedronis at codespeak.net)
Date: Tue, 13 Feb 2007 15:23:37 +0100 (CET)
Subject: [pypy-svn] r38699 - pypy/dist/pypy/rpython/test
Message-ID: <20070213142337.DA638100C0@code0.codespeak.net>

Author: pedronis
Date: Tue Feb 13 15:23:34 2007
New Revision: 38699

Modified:
   pypy/dist/pypy/rpython/test/test_rpbc.py
Log:
guess which option I picked - the options here were change one file, change two files, change 3-4+ files and thread a policy keyword around and suffer the sight of the babel tower which our backend interfaces and backend test infrastructure is.



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 Feb 13 15:23:34 2007
@@ -1543,6 +1543,16 @@
         assert self.ll_to_string(item0) == "hello"
         assert item1 == 623
 
+class TestLLtype(BaseTestRPBC, LLRtypeMixin):
+    pass
+
+class TestOOtype(BaseTestRPBC, OORtypeMixin):
+    pass
+
+# ____________________________________________________________
+
+class BaseTestRPBCExtra(BaseRtypingTest):
+    
     def test_folding_specialize_support(self):
 
         class S(object):
@@ -1594,11 +1604,11 @@
         assert res == 12
         res = self.interpret(f, [3, 5555], policy=p)
         assert res == 4
-        
-class TestLLtype(BaseTestRPBC, LLRtypeMixin):
+            
+class TestExtraLLtype(BaseTestRPBCExtra, LLRtypeMixin):
     pass
 
-class TestOOtype(BaseTestRPBC, OORtypeMixin):
+class TestExtraOOtype(BaseTestRPBCExtra, OORtypeMixin):
     pass
 
 # ____________________________________________________________


From cfbolz at codespeak.net  Tue Feb 13 15:37:47 2007
From: cfbolz at codespeak.net (cfbolz at codespeak.net)
Date: Tue, 13 Feb 2007 15:37:47 +0100 (CET)
Subject: [pypy-svn] r38702 - pypy/dist/pypy/doc
Message-ID: <20070213143747.DB291100AC@code0.codespeak.net>

Author: cfbolz
Date: Tue Feb 13 15:37:46 2007
New Revision: 38702

Modified:
   pypy/dist/pypy/doc/faq.txt
Log:
two more faq entries, a small addition to the backends one


Modified: pypy/dist/pypy/doc/faq.txt
==============================================================================
--- pypy/dist/pypy/doc/faq.txt	(original)
+++ pypy/dist/pypy/doc/faq.txt	Tue Feb 13 15:37:46 2007
@@ -131,6 +131,22 @@
 Note that the speed heavily depends on the enabled options at compile time.
 
 
+-----------------------------------------------------------------------
+What is this talk about a JavaScript and a Prolog interpreter in PyPy?
+-----------------------------------------------------------------------
+
+Since a Python interpreter is a rather large and intricate thing, our toolsuite
+became quite advanced to support it. Therefore people had the idea of using it
+to implement interpreters for other dynamic languages than Python and get a lot
+of things for free (translation to various languages, stackless features,
+garbage collection, implementation of various things like arbitraryly long
+integers). Therefore people started to implement a `JavaScript interpreter`_
+(Leonardo Santagada as his Summer of PyPy project) and a `Prolog interpreter`_
+(Carl Friedrich Bolz as his Masters thesis). Both projects are undocumented and
+unfinished, at the moment (the Prolog interpreter being less unfinished).
+
+.. _`JavaScript interpreter`: ../../pypy/lang/js
+.. _`Prolog interpreter`: ../../pypy/lang/prolog
 
 
 Development
@@ -140,7 +156,21 @@
 How do I get into PyPy development?  Can I come to sprints?
 -----------------------------------------------------------
 
-XXX
+Sure you can come to sprints! We always welcome newcomers and try to help them
+get started in the project as much as possible (e.g. by providing tutorials and
+pairing them with experienced PyPy developers). Newcomers should have some
+Python experience and read some of the PyPy documentation before coming to a
+sprint.
+
+Coming to a sprint is usually also the best way to get into PyPy development.
+If you want to start on your own, take a look at the list of `project
+suggestions`_. If you get stuck or need advice, `contact us`_. Usually IRC is
+the most immediate mean to get feedback (at least during some parts of the day,
+many PyPy developers are in Europe) and the mailing list is better for long
+discussions.
+
+.. _`project suggestions`: project-ideas.html
+.. _`contact us`: contact.html
 
 ----------------------------------
 Why so many levels of abstraction?
@@ -242,6 +272,10 @@
 Which backends are there?
 -------------------------
 
+Backends that can actually translate all of PyPy:
+
+ * C_, LLVM_, CLI_
+
 Somewhat mature backends:
 
 * Low level backends: C_, LLVM_
@@ -251,6 +285,7 @@
 
 * Squeak_, `Common Lisp`_
 
+
 To learn more about backends take a look at the `translation document`_
 
 .. _CLI: cli-backend.html


From cfbolz at codespeak.net  Tue Feb 13 15:43:33 2007
From: cfbolz at codespeak.net (cfbolz at codespeak.net)
Date: Tue, 13 Feb 2007 15:43:33 +0100 (CET)
Subject: [pypy-svn] r38703 - pypy/dist/pypy/doc/config
Message-ID: <20070213144333.37154100AC@code0.codespeak.net>

Author: cfbolz
Date: Tue Feb 13 15:43:32 2007
New Revision: 38703

Modified:
   pypy/dist/pypy/doc/config/objspace.usemodules.gc.txt
Log:
add a note about the gc module


Modified: pypy/dist/pypy/doc/config/objspace.usemodules.gc.txt
==============================================================================
--- pypy/dist/pypy/doc/config/objspace.usemodules.gc.txt	(original)
+++ pypy/dist/pypy/doc/config/objspace.usemodules.gc.txt	Tue Feb 13 15:43:32 2007
@@ -1,2 +1,5 @@
 Use the 'gc' module. 
 This module is expected to be working and is included by default.
+Note that since the gc module is highly implementation specific, it contains
+only the ``collect`` function in PyPy, which forces a collection when compiled
+with the framework or with Boehm.


From arigo at codespeak.net  Tue Feb 13 15:49:01 2007
From: arigo at codespeak.net (arigo at codespeak.net)
Date: Tue, 13 Feb 2007 15:49:01 +0100 (CET)
Subject: [pypy-svn] r38704 - in pypy/dist/pypy/interpreter: . astcompiler
	pyparser test
Message-ID: <20070213144901.C58EF100A6@code0.codespeak.net>

Author: arigo
Date: Tue Feb 13 15:48:57 2007
New Revision: 38704

Modified:
   pypy/dist/pypy/interpreter/astcompiler/pycodegen.py
   pypy/dist/pypy/interpreter/eval.py
   pypy/dist/pypy/interpreter/function.py
   pypy/dist/pypy/interpreter/gateway.py
   pypy/dist/pypy/interpreter/pycode.py
   pypy/dist/pypy/interpreter/pyparser/astbuilder.py
   pypy/dist/pypy/interpreter/test/test_compiler.py
   pypy/dist/pypy/interpreter/test/test_function.py
   pypy/dist/pypy/interpreter/typedef.py
Log:
* Support for unicode docstrings.
* Make sure the docstring of a module is in co_consts[0].


Modified: pypy/dist/pypy/interpreter/astcompiler/pycodegen.py
==============================================================================
--- pypy/dist/pypy/interpreter/astcompiler/pycodegen.py	(original)
+++ pypy/dist/pypy/interpreter/astcompiler/pycodegen.py	Tue Feb 13 15:48:57 2007
@@ -302,6 +302,7 @@
         self.scope = node.scope
         self.emitop_int('SET_LINENO', 0)
         if not space.is_w(node.w_doc, space.w_None):
+            self.setDocstring(node.w_doc)
             self.set_lineno(node)
             self.emitop_obj('LOAD_CONST', node.w_doc)
             self.storeName('__doc__', node.lineno)

Modified: pypy/dist/pypy/interpreter/eval.py
==============================================================================
--- pypy/dist/pypy/interpreter/eval.py	(original)
+++ pypy/dist/pypy/interpreter/eval.py	Tue Feb 13 15:48:57 2007
@@ -45,8 +45,8 @@
             argcount += 1
         return argcount
 
-    def getdocstring(self):
-        return None
+    def getdocstring(self, space):
+        return space.w_None
 
     def funcrun(self, func, args):
         frame = func.space.createframe(self, func.w_func_globals,

Modified: pypy/dist/pypy/interpreter/function.py
==============================================================================
--- pypy/dist/pypy/interpreter/function.py	(original)
+++ pypy/dist/pypy/interpreter/function.py	Tue Feb 13 15:48:57 2007
@@ -19,7 +19,7 @@
     def __init__(self, space, code, w_globals=None, defs_w=[], closure=None, forcename=None):
         self.space = space
         self.name = forcename or code.co_name
-        self.w_doc = None   # lazily read and wrapped from code.getdocstring()
+        self.w_doc = None   # lazily read from code.getdocstring()
         self.code = code       # Code instance
         self.w_func_globals = w_globals  # the globals dictionary
         self.closure   = closure    # normally, list of Cell instances or None
@@ -232,7 +232,7 @@
 
     def fget_func_doc(space, self):
         if self.w_doc is None:
-            self.w_doc = space.wrap(self.code.getdocstring())
+            self.w_doc = self.code.getdocstring(space)
         return self.w_doc
 
     def fset_func_doc(space, self, w_doc):

Modified: pypy/dist/pypy/interpreter/gateway.py
==============================================================================
--- pypy/dist/pypy/interpreter/gateway.py	(original)
+++ pypy/dist/pypy/interpreter/gateway.py	Tue Feb 13 15:48:57 2007
@@ -441,8 +441,8 @@
     def signature(self):
         return self.sig
 
-    def getdocstring(self):
-        return self.docstring
+    def getdocstring(self, space):
+        return space.wrap(self.docstring)
 
     def funcrun(self, func, args):
         space = func.space

Modified: pypy/dist/pypy/interpreter/pycode.py
==============================================================================
--- pypy/dist/pypy/interpreter/pycode.py	(original)
+++ pypy/dist/pypy/interpreter/pycode.py	Tue Feb 13 15:48:57 2007
@@ -228,15 +228,11 @@
     def getvarnames(self):
         return self.co_varnames
 
-    def getdocstring(self):
+    def getdocstring(self, space):
         if self.co_consts_w:   # it is probably never empty
-            const0_w = self.co_consts_w[0]
-            if const0_w is self.space.w_None:
-                return None
-            else:
-                return self.space.str_w(const0_w)
+            return self.co_consts_w[0]
         else:
-            return None
+            return space.w_None
 
     def getjoinpoints(self):
         """Compute the bytecode positions that are potential join points

Modified: pypy/dist/pypy/interpreter/pyparser/astbuilder.py
==============================================================================
--- pypy/dist/pypy/interpreter/pyparser/astbuilder.py	(original)
+++ pypy/dist/pypy/interpreter/pyparser/astbuilder.py	Tue Feb 13 15:48:57 2007
@@ -352,7 +352,7 @@
         first_child = stmt.nodes[0]
         if isinstance(first_child, ast.Discard):
             expr = first_child.expr
-            if builder.is_string_const(expr):
+            if builder.is_basestring_const(expr):
                 # This *is* a docstring, remove it from stmt list
                 assert isinstance(expr, ast.Const)
                 del stmt.nodes[0]
@@ -1798,11 +1798,11 @@
             f = space.builtin.get('float')
             return space.call_function(f, space.wrap(value))
 
-    def is_string_const(self, expr):
+    def is_basestring_const(self, expr):
         if not isinstance(expr,ast.Const):
             return False
         space = self.space
-        return space.is_true(space.isinstance(expr.value,space.w_str))
+        return space.is_true(space.isinstance(expr.value,space.w_basestring))
 
     def wrap_string(self, obj):
         if self.space:

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	Tue Feb 13 15:48:57 2007
@@ -185,6 +185,12 @@
         ex.normalize_exception(self.space)
         assert ex.match(self.space, self.space.w_UnicodeError)
 
+    def test_unicode_docstring(self):
+        space = self.space
+        code = self.compiler.compile('u"hello"\n', '', 'exec', 0)
+        assert space.eq_w(code.co_consts_w[0], space.wrap("hello"))
+        assert space.is_w(space.type(code.co_consts_w[0]), space.w_unicode)
+
     def test_argument_handling(self):
         for expr in 'lambda a,a:0', 'lambda a,a=1:0', 'lambda a=1,a=1:0':
             e = py.test.raises(OperationError, self.eval_string, expr)

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	Tue Feb 13 15:48:57 2007
@@ -169,6 +169,12 @@
         raises(TypeError, len, s, some_unknown_keyword=s)
         raises(TypeError, len, s, s, some_unknown_keyword=s)
 
+    def test_unicode_docstring(self):
+        def f():
+            u"hi"
+        assert f.__doc__ == u"hi"
+        assert type(f.__doc__) is unicode
+
 class AppTestMethod: 
     def test_get(self):
         def func(self): return self

Modified: pypy/dist/pypy/interpreter/typedef.py
==============================================================================
--- pypy/dist/pypy/interpreter/typedef.py	(original)
+++ pypy/dist/pypy/interpreter/typedef.py	Tue Feb 13 15:48:57 2007
@@ -523,7 +523,7 @@
     return space.wrap(flags)
 
 def fget_co_consts(space, code): # unwrapping through unwrap_spec
-    w_docstring = space.wrap(code.getdocstring())
+    w_docstring = code.getdocstring(space)
     return space.newtuple([w_docstring])
 
 weakref_descr = GetSetProperty(descr_get_weakref)


From arigo at codespeak.net  Tue Feb 13 16:08:23 2007
From: arigo at codespeak.net (arigo at codespeak.net)
Date: Tue, 13 Feb 2007 16:08:23 +0100 (CET)
Subject: [pypy-svn] r38707 - pypy/dist/pypy/module/posix
Message-ID: <20070213150823.675C91008D@code0.codespeak.net>

Author: arigo
Date: Tue Feb 13 16:08:21 2007
New Revision: 38707

Modified:
   pypy/dist/pypy/module/posix/interp_posix.py
Log:
Review and add the missing wrap_oserror() around all functions that
could fail.


Modified: pypy/dist/pypy/module/posix/interp_posix.py
==============================================================================
--- pypy/dist/pypy/module/posix/interp_posix.py	(original)
+++ pypy/dist/pypy/module/posix/interp_posix.py	Tue Feb 13 16:08:21 2007
@@ -172,7 +172,12 @@
     specified access to the path.  The mode argument can be F_OK to test
     existence, or the inclusive-OR of R_OK, W_OK, and X_OK.
     """
-    return space.wrap(os.access(path, mode))
+    try:
+        ok = os.access(path, mode)
+    except OSError, e: 
+        raise wrap_oserror(space, e) 
+    else:
+        return space.wrap(ok)
 access.unwrap_spec = [ObjSpace, str, int]
 
 def system(space, cmd):
@@ -397,11 +402,17 @@
 readlink.unwrap_spec = [ObjSpace, str]
 
 def fork(space):
-    pid = os.fork()
+    try:
+        pid = os.fork()
+    except OSError, e: 
+        raise wrap_oserror(space, e) 
     return space.wrap(pid)
 
 def waitpid(space, pid, options):
-    pid, status = os.waitpid(pid, options)
+    try:
+        pid, status = os.waitpid(pid, options)
+    except OSError, e: 
+        raise wrap_oserror(space, e) 
     return space.newtuple([space.wrap(pid), space.wrap(status)])
 waitpid.unwrap_spec = [ObjSpace, int, int]
 


From cfbolz at codespeak.net  Tue Feb 13 16:43:15 2007
From: cfbolz at codespeak.net (cfbolz at codespeak.net)
Date: Tue, 13 Feb 2007 16:43:15 +0100 (CET)
Subject: [pypy-svn] r38714 - in pypy/dist/pypy/module/_file: . test
Message-ID: <20070213154315.58D7F100A7@code0.codespeak.net>

Author: cfbolz
Date: Tue Feb 13 16:43:13 2007
New Revision: 38714

Modified:
   pypy/dist/pypy/module/_file/app_file.py
   pypy/dist/pypy/module/_file/test/test_file.py
Log:
check the argument types of read and readlines of files. This makes the failing
bz2 test pass, I hope.


Modified: pypy/dist/pypy/module/_file/app_file.py
==============================================================================
--- pypy/dist/pypy/module/_file/app_file.py	(original)
+++ pypy/dist/pypy/module/_file/app_file.py	Tue Feb 13 16:43:13 2007
@@ -87,6 +87,8 @@
 may be returned, even if no size parameter was given."""
         if self._closed:
             raise ValueError('I/O operation on closed file')
+        if not isinstance(n, (int, long)):
+            raise TypeError("an integer is required")
         if n < 0:
             return self.stream.readall()
         else:
@@ -107,6 +109,8 @@
 Return an empty string at EOF."""
         if self._closed:
             raise ValueError('I/O operation on closed file')
+        if not isinstance(size, (int, long)):
+            raise TypeError("an integer is required")
         if size < 0:
             return self.stream.readline()
         else:

Modified: pypy/dist/pypy/module/_file/test/test_file.py
==============================================================================
--- pypy/dist/pypy/module/_file/test/test_file.py	(original)
+++ pypy/dist/pypy/module/_file/test/test_file.py	Tue Feb 13 16:43:13 2007
@@ -16,12 +16,30 @@
         finally:
             f.close()
         f = _file.file(self.temppath, "r")
+        raises(TypeError, f.read, None)
         try:
             s = f.read()
             assert s == "foo"
         finally:
             f.close()
 
+    def test_readline(self):
+        import _file
+        f = _file.file(self.temppath, "w")
+        try:
+            f.write("foo\nbar\n")
+        finally:
+            f.close()
+        f = _file.file(self.temppath, "r")
+        raises(TypeError, f.readline, None)
+        try:
+            s = f.readline()
+            assert s == "foo\n"
+            s = f.readline()
+            assert s == "bar\n"
+        finally:
+            f.close()
+
     def test_fdopen(self):
         import _file, os
         f = _file.file(self.temppath, "w")


From cfbolz at codespeak.net  Tue Feb 13 16:47:44 2007
From: cfbolz at codespeak.net (cfbolz at codespeak.net)
Date: Tue, 13 Feb 2007 16:47:44 +0100 (CET)
Subject: [pypy-svn] r38715 - pypy/dist/pypy/doc
Message-ID: <20070213154744.D2BBC100A7@code0.codespeak.net>

Author: cfbolz
Date: Tue Feb 13 16:47:43 2007
New Revision: 38715

Modified:
   pypy/dist/pypy/doc/cleanup-todo.txt
Log:
add an item about weakrefs


Modified: pypy/dist/pypy/doc/cleanup-todo.txt
==============================================================================
--- pypy/dist/pypy/doc/cleanup-todo.txt	(original)
+++ pypy/dist/pypy/doc/cleanup-todo.txt	Tue Feb 13 16:47:43 2007
@@ -12,4 +12,4 @@
  - all backends should have more consistent interfaces
  - geninterp is a hack
  - keepalives need to die, finally
-
+ - change weakrefs to work together with the GC


From pedronis at codespeak.net  Tue Feb 13 17:09:18 2007
From: pedronis at codespeak.net (pedronis at codespeak.net)
Date: Tue, 13 Feb 2007 17:09:18 +0100 (CET)
Subject: [pypy-svn] r38717 - pypy/dist/pypy/doc
Message-ID: <20070213160918.B53E2100AB@code0.codespeak.net>

Author: pedronis
Date: Tue Feb 13 17:09:16 2007
New Revision: 38717

Modified:
   pypy/dist/pypy/doc/geninterp.txt
Log:
update, add some more explanation, use current output in the example.



Modified: pypy/dist/pypy/doc/geninterp.txt
==============================================================================
--- pypy/dist/pypy/doc/geninterp.txt	(original)
+++ pypy/dist/pypy/doc/geninterp.txt	Tue Feb 13 17:09:16 2007
@@ -32,14 +32,18 @@
 Solution
 ++++++++
 
-This bootstrap issue is solved by invoking a new bytecode interpreter which
-runs on FlowObjspace. FlowObjspace is complete without complicated
-initialization. It is able to do abstract interpretation of any
-Rpythonic code, without actually implementing anything. It just
+This bootstrap issue is solved by invoking a new bytecode interpreter
+which runs on FlowObjspace. FlowObjspace is complete without
+complicated initialization. It is able to do abstract interpretation
+of any Rpythonic code, without actually implementing anything. It just
 records all the operations the bytecode interpreter would have done by
 building flowgraphs for all the code. What the Python backend does is
 just to produce correct Python code from these flowgraphs and return
-it as source code.
+it as source code. In the produced code Python operations recorded in
+the original flowgraphs are replaced by calls to the corresponding
+methods in the `object space`_ interface.
+
+.. _`object space`: objspace.html
 
 Example
 +++++++
@@ -67,88 +71,79 @@
 recorded every possible codepath into a flowgraph, and then rendered the
 following source code:: 
 
-    >>> print source
     #!/bin/env python
     # -*- coding: LATIN-1 -*-
 
     def initapp2interpexec(space):
       """NOT_RPYTHON"""
 
-      def g(space, __args__):
-        funcname = "g"
-        signature = ['n'], None, None
-        defaults_w = []
-        w_n_2, = __args__.parse(funcname, signature, defaults_w)
-        return fastf_g(space, w_n_2)
-
-      f_g = g
-
-      def g(space, w_n_2):
+      def g(space, w_n_1):
         goto = 3 # startblock
         while True:
 
             if goto == 1:
                 v0 = space.is_true(w_n)
                 if v0 == True:
-                    w_n_1, w_0 = w_n, w_i
                     goto = 2
                 else:
-                    assert v0 == False
-                    w_1 = w_i
                     goto = 4
 
             if goto == 2:
-                w_2 = space.add(w_0, w_n_1)
-                w_3 = space.sub(w_n_1, space.w_True)
-                w_n, w_i = w_3, w_2
+                w_1 = space.add(w_0, w_n)
+                w_2 = space.sub(w_n, gi_1)
+                w_n, w_0 = w_2, w_1
                 goto = 1
                 continue
 
             if goto == 3:
-                w_n, w_i = w_n_2, space.w_False
+                w_n, w_0 = w_n_1, gi_0
                 goto = 1
                 continue
 
             if goto == 4:
-                return w_1
+                return w_0
 
       fastf_g = g
 
-      g3dict = space.newdict([])
-      gs___name__ = space.wrap('__name__')
-      gs_app2interpexec = space.wrap('app2interpexec')
+      g3dict = space.newdict()
+      gs___name__ = space.new_interned_str('__name__')
+      gs_app2interpexec = space.new_interned_str('app2interpexec')
       space.setitem(g3dict, gs___name__, gs_app2interpexec)
-      gs_g = space.wrap('g')
+      gs_g = space.new_interned_str('g')
       from pypy.interpreter import gateway
-      gfunc_g = space.wrap(gateway.interp2app(f_g, unwrap_spec=[gateway.ObjSpace, gateway.Arguments]))
+      gfunc_g = space.wrap(gateway.interp2app(fastf_g, unwrap_spec=[gateway.ObjSpace, gateway.W_Root]))
       space.setitem(g3dict, gs_g, gfunc_g)
+      gi_1 = space.wrap(1)
+      gi_0 = space.wrap(0)
       return g3dict
 
-You see that actually a single function is produced: ``initapp2interpexec``. This is the
-function that you will call with a space as argument. It defines a few functions and then
-does a number of initialization steps, builds the global objects the function need,
-and produces the interface function ``gfunc_g`` to be called from interpreter level.
-
-The return value is ``g3dict``, which contains a module name and the function we asked for.
-
-Let's have a look at the body of this code: The first definition of ``g`` is just
-for the argument parsing and is used as ``f_g`` in the ``gateway.interp2app``.
-We look at the second definition, ``fastf_g``, which does the actual
-computation. Comparing to the flowgraph,
-you see a code block for every block in the graph.
-Since Python has no goto statement, the jumps between the blocks are implemented
-by a loop that switches over a ``goto`` variable.
+You see that actually a single function is produced:
+``initapp2interpexec``. This is the function that you will call with a
+space as argument. It defines a few functions and then does a number
+of initialization steps, builds the global objects the function need,
+and produces the PyPy function object ``gfunc_g``.
+
+The return value is ``g3dict``, which contains a module name and the
+function we asked for.
+
+Let's have a look at the body of this code: The definition of ``g`` is
+used as ``fast_g`` in the ``gateway.interp2app`` which constructs a
+PyPy function object which takes care of argument unboxing (based on
+the ``unwrap_spec``), and of invoking the original ``g``.
+
+We look at the definition of ``g`` itself which does the actual
+computation. Comparing to the flowgraph, you see a code block for
+every block in the graph.  Since Python has no goto statement, the
+jumps between the blocks are implemented by a loop that switches over
+a ``goto`` variable.
 
 ::
 
     .       if goto == 1:
                 v0 = space.is_true(w_n)
                 if v0 == True:
-                    w_n_1, w_0 = w_n, w_i
                     goto = 2
                 else:
-                    assert v0 == False
-                    w_1 = w_i
                     goto = 4
 
 This is the implementation of the "``while n:``". There is no implicit state,
@@ -160,16 +155,16 @@
 ::
 
     .       if goto == 2:
-                w_2 = space.add(w_0, w_n_1)
-                w_3 = space.sub(w_n_1, space.w_True)
-                w_n, w_i = w_3, w_2
+                w_1 = space.add(w_0, w_n)
+                w_2 = space.sub(w_n, gi_1)
+                w_n, w_0 = w_2, w_1
                 goto = 1
                 continue
 
 The "``i = i + n``" and "``n = n - 1``" instructions.
 You see how every instruction produces a new variable.
 The state is again shuffled around by assigning to the
-input variables ``w_n`` and ``w_i`` of the next target, block 1.
+input variables ``w_n`` and ``w_0`` of the next target, block 1.
 
 Note that it is possible to rewrite this by re-using variables,
 trying to produce nested blocks instead of the goto construction
@@ -200,11 +195,3 @@
 a cached code snippet clear by double-clicking it. Note also that
 the auto-generated __init__.py file wipes the whole directory
 when executed.
-
-XXX this should go into some interpreter.doc, where gateway should be explained
-
-
-How it works
-++++++++++++
-
-XXX to be added later


From fijal at codespeak.net  Tue Feb 13 17:12:22 2007
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Tue, 13 Feb 2007 17:12:22 +0100 (CET)
Subject: [pypy-svn] r38718 - in pypy/dist/pypy/translator/js/lib: . test
Message-ID: <20070213161222.58A0E100A3@code0.codespeak.net>

Author: fijal
Date: Tue Feb 13 17:12:19 2007
New Revision: 38718

Added:
   pypy/dist/pypy/translator/js/lib/test/test_url.py
   pypy/dist/pypy/translator/js/lib/url.py
Log:
Add proper URL handling


Added: pypy/dist/pypy/translator/js/lib/test/test_url.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/js/lib/test/test_url.py	Tue Feb 13 17:12:19 2007
@@ -0,0 +1,10 @@
+
+from pypy.translator.js.lib.url import parse_url
+
+def test_url():
+    assert parse_url("path") == (["path"], {})
+    assert parse_url("a/b/c/d") == (["a", "b", "c", "d"], {})
+    assert parse_url("/a/b") == (["a", "b"], {})
+    assert parse_url("/a/b/c/") == (["a", "b", "c"], {})
+    assert parse_url("a/b?q=a&c=z") == (["a","b"], {"q":"a", "c":"z"})
+

Added: pypy/dist/pypy/translator/js/lib/url.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/js/lib/url.py	Tue Feb 13 17:12:19 2007
@@ -0,0 +1,35 @@
+
+""" Some support files for mapping urls, mostly bindings
+for existing cgi stuff
+"""
+
+import cgi
+import urllib
+
+class URL(object):
+    def __init__(self, path, vars):
+        self.path = path
+        self.vars = vars
+
+    def __eq__(self, other):
+        if isinstance(other, URL):
+            return self.path == other.path and self.vars == other.vars
+        if isinstance(other, tuple):
+            if len(other) != 2:
+                return False
+            return self.path, self.vars == other
+        return False
+
+    def __ne__(self, other):
+        return not self == other
+
+def parse_url(path):
+    """ Parse a/b/c?q=a into ('a', 'b', 'c') {'q':'a'}
+    """
+    if '?' in path:
+        path, var_str = path.split("?")
+        vars = cgi.parse_qs(var_str)
+    else:
+        vars = {}
+    parts = [urllib.unquote(i) for i in path.split("/") if i]
+    return URL(parts, vars)


From cfbolz at codespeak.net  Tue Feb 13 17:18:30 2007
From: cfbolz at codespeak.net (cfbolz at codespeak.net)
Date: Tue, 13 Feb 2007 17:18:30 +0100 (CET)
Subject: [pypy-svn] r38719 - in pypy/dist/pypy/module/_file: . test
Message-ID: <20070213161830.E7143100A7@code0.codespeak.net>

Author: cfbolz
Date: Tue Feb 13 17:18:30 2007
New Revision: 38719

Modified:
   pypy/dist/pypy/module/_file/app_file.py
   pypy/dist/pypy/module/_file/test/test_file.py
Log:
another one of those


Modified: pypy/dist/pypy/module/_file/app_file.py
==============================================================================
--- pypy/dist/pypy/module/_file/app_file.py	(original)
+++ pypy/dist/pypy/module/_file/app_file.py	Tue Feb 13 17:18:30 2007
@@ -131,6 +131,8 @@
 total number of bytes in the lines returned."""
         if self._closed:
             raise ValueError('I/O operation on closed file')
+        if not isinstance(size, (int, long)):
+            raise TypeError("an integer is required")
         if size < 0:
             return list(iter(self.stream.readline, ""))
         else:

Modified: pypy/dist/pypy/module/_file/test/test_file.py
==============================================================================
--- pypy/dist/pypy/module/_file/test/test_file.py	(original)
+++ pypy/dist/pypy/module/_file/test/test_file.py	Tue Feb 13 17:18:30 2007
@@ -40,6 +40,22 @@
         finally:
             f.close()
 
+    def test_readlines(self):
+        import _file
+        f = _file.file(self.temppath, "w")
+        try:
+            f.write("foo\nbar\n")
+        finally:
+            f.close()
+        f = _file.file(self.temppath, "r")
+        raises(TypeError, f.readlines, None)
+        try:
+            s = f.readlines()
+            assert s == ["foo\n", "bar\n"]
+        finally:
+            f.close()
+
+
     def test_fdopen(self):
         import _file, os
         f = _file.file(self.temppath, "w")


From fijal at codespeak.net  Tue Feb 13 17:21:42 2007
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Tue, 13 Feb 2007 17:21:42 +0100 (CET)
Subject: [pypy-svn] r38720 - in pypy/dist/pypy/translator/js/lib: . test
Message-ID: <20070213162142.A15E3100AC@code0.codespeak.net>

Author: fijal
Date: Tue Feb 13 17:21:39 2007
New Revision: 38720

Modified:
   pypy/dist/pypy/translator/js/lib/server.py
   pypy/dist/pypy/translator/js/lib/test/test_server.py
   pypy/dist/pypy/translator/js/lib/url.py
Log:
Add a bit better handling of url to server.py


Modified: pypy/dist/pypy/translator/js/lib/server.py
==============================================================================
--- pypy/dist/pypy/translator/js/lib/server.py	(original)
+++ pypy/dist/pypy/translator/js/lib/server.py	Tue Feb 13 17:21:39 2007
@@ -24,6 +24,7 @@
 import sys
 
 import py
+from pypy.translator.js.lib.url import parse_url
 
 from pypy.translator.js import json
 
@@ -53,48 +54,31 @@
     exported_methods = exported_methods
     
     def do_GET(self):
-        path = self.path
-        if path.endswith("/"):
-            path = path[:-1]
-        if path.startswith("/"):
-            path = path[1:]
-        m = re.match('^(.*)\?(.*)$', path)
-        if m:
-            path = m.group(1)
-            getargs = m.group(2)
+        path, args = parse_url(self.path)
+        name_path = path[0].replace(".", "_")
+        if len(path) > 1:
+            rest = os.path.sep.join(path[1:])
         else:
-            getargs = ""
-        name_path = path.replace(".", "_")
-        if name_path == "":
-            name_path = "index"
+            rest = None
         method_to_call = getattr(self, name_path, None)
         if method_to_call is None or not getattr(method_to_call, 'exposed', None):
             exec_meth = getattr(self.exported_methods, name_path, None)
             if exec_meth is None:
                 self.send_error(404, "File %s not found" % path)
             else:
-                self.serve_data('text/json', json.write(exec_meth(**self.parse_args(getargs))))
+                self.serve_data('text/json', json.write(exec_meth(**args)))
         else:
-            outp = method_to_call(**self.parse_args(getargs))
+            if rest:
+                outp = method_to_call(rest, **args)
+            else:
+                outp = method_to_call(**args)
             if isinstance(outp, (str, unicode)):
                 self.serve_data('text/html', outp)
             elif isinstance(outp, tuple):
                 self.serve_data(*outp)
             else:
                 raise ValueError("Don't know how to serve %s" % (outp,))
-    
-    def parse_args(self, getargs):
-        # parse get argument list
-        if getargs == "":
-            return {}
-        
-        args = {}
-        arg_pairs = getargs.split("&")
-        for arg in arg_pairs:
-            key, value = arg.split("=")
-            args[key] = value
-        return args
-    
+
     def log_message(self, format, *args):
         # XXX just discard it
         pass
@@ -115,7 +99,16 @@
         self.path = path
 
     def __call__(self):
-        return open(self.path).read()
+        return open(str(self.path)).read()
+
+class StaticDir(object):
+    exposed = True
+
+    def __init__(self, path):
+        self.path = path
+
+    def __call__(self, path):
+        return open(os.path.join(str(self.path), str(path))).read()
 
 def create_server(server_address = ('', 8000), handler=TestHandler,
                  server=HTTPServer):

Modified: pypy/dist/pypy/translator/js/lib/test/test_server.py
==============================================================================
--- pypy/dist/pypy/translator/js/lib/test/test_server.py	(original)
+++ pypy/dist/pypy/translator/js/lib/test/test_server.py	Tue Feb 13 17:21:39 2007
@@ -54,3 +54,22 @@
     assert URLopener().open("http://127.0.0.1:21213/index").read() == \
            ""
 
+
+def test_static_directory():
+    import thread
+    tmpdir = py.test.ensuretemp("server_static_dir")
+    tmpdir.ensure("a", dir=1)
+    tmpdir.join("a").ensure("a.txt").write("aaa")
+    tmpdir.join("a").ensure("b.txt").write("bbb")
+
+    class StaticDir(server.Handler):
+        static_dir = tmpdir
+        a_dir = server.StaticDir(tmpdir.join("a"))
+
+    httpd = server.HTTPServer(('127.0.0.1', 0), StaticDir)
+    port = httpd.server_port
+    thread.start_new_thread(httpd.serve_forever, ())
+    addr = "http://127.0.0.1:%d/" % port
+    assert URLopener().open(addr + "a_dir/a.txt").read() == "aaa"
+    assert URLopener().open(addr + "a_dir/b.txt").read() == "bbb"
+

Modified: pypy/dist/pypy/translator/js/lib/url.py
==============================================================================
--- pypy/dist/pypy/translator/js/lib/url.py	(original)
+++ pypy/dist/pypy/translator/js/lib/url.py	Tue Feb 13 17:21:39 2007
@@ -23,6 +23,9 @@
     def __ne__(self, other):
         return not self == other
 
+    def __iter__(self):
+        return iter((self.path, self.vars))
+
 def parse_url(path):
     """ Parse a/b/c?q=a into ('a', 'b', 'c') {'q':'a'}
     """


From pedronis at codespeak.net  Tue Feb 13 17:22:14 2007
From: pedronis at codespeak.net (pedronis at codespeak.net)
Date: Tue, 13 Feb 2007 17:22:14 +0100 (CET)
Subject: [pypy-svn] r38721 - pypy/dist/pypy/doc
Message-ID: <20070213162214.035E0100B0@code0.codespeak.net>

Author: pedronis
Date: Tue Feb 13 17:22:13 2007
New Revision: 38721

Modified:
   pypy/dist/pypy/doc/garbage_collection.txt
Log:
I suppose there's a missing "text" here



Modified: pypy/dist/pypy/doc/garbage_collection.txt
==============================================================================
--- pypy/dist/pypy/doc/garbage_collection.txt	(original)
+++ pypy/dist/pypy/doc/garbage_collection.txt	Tue Feb 13 17:22:13 2007
@@ -6,9 +6,9 @@
 .. sectnum::
 
 
-**Warning**: The that was in this document was incomplete and outdated. A much
-more up-to-date view of garbage collection in PyPy can be found in the
-`EU-report on this topic`_.
+**Warning**: The text that was in this document was incomplete and
+outdated. A much more up-to-date view of garbage collection in PyPy
+can be found in the `EU-report on this topic`_.
 
 .. _`EU-report on this topic`: http://codespeak.net/pypy/extradoc/eu-report/D07.1_Massive_Parallelism_and_Translation_Aspects-2006-12-15.pdf
 


From fijal at codespeak.net  Tue Feb 13 17:26:39 2007
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Tue, 13 Feb 2007 17:26:39 +0100 (CET)
Subject: [pypy-svn] r38722 - in pypy/dist/pypy/translator/js/lib: . test
Message-ID: <20070213162639.C4F33100A7@code0.codespeak.net>

Author: fijal
Date: Tue Feb 13 17:26:37 2007
New Revision: 38722

Modified:
   pypy/dist/pypy/translator/js/lib/server.py
   pypy/dist/pypy/translator/js/lib/test/test_server.py
Log:
Ah, nice and not tested special-case ;-


Modified: pypy/dist/pypy/translator/js/lib/server.py
==============================================================================
--- pypy/dist/pypy/translator/js/lib/server.py	(original)
+++ pypy/dist/pypy/translator/js/lib/server.py	Tue Feb 13 17:26:37 2007
@@ -55,6 +55,8 @@
     
     def do_GET(self):
         path, args = parse_url(self.path)
+        if not path:
+            path = ["index"]
         name_path = path[0].replace(".", "_")
         if len(path) > 1:
             rest = os.path.sep.join(path[1:])

Modified: pypy/dist/pypy/translator/js/lib/test/test_server.py
==============================================================================
--- pypy/dist/pypy/translator/js/lib/test/test_server.py	(original)
+++ pypy/dist/pypy/translator/js/lib/test/test_server.py	Tue Feb 13 17:26:37 2007
@@ -18,6 +18,7 @@
     httpd = server.HTTPServer(('127.0.0.1', 21210), Handler)
     thread.start_new_thread(httpd.serve_forever, ())
     assert URLopener().open("http://127.0.0.1:21210/index").read() == "xxx"
+    assert URLopener().open("http://127.0.0.1:21210/").read() == "xxx"
 
 def test_own_startup():
     httpd = server.create_server(server_address=('127.0.0.1', 21211),


From pedronis at codespeak.net  Tue Feb 13 17:27:19 2007
From: pedronis at codespeak.net (pedronis at codespeak.net)
Date: Tue, 13 Feb 2007 17:27:19 +0100 (CET)
Subject: [pypy-svn] r38723 - pypy/dist/pypy/doc
Message-ID: <20070213162719.562E0100B6@code0.codespeak.net>

Author: pedronis
Date: Tue Feb 13 17:27:16 2007
New Revision: 38723

Modified:
   pypy/dist/pypy/doc/stackless.txt
Log:
fix XXX reference with a link to D07.1 report



Modified: pypy/dist/pypy/doc/stackless.txt
==============================================================================
--- pypy/dist/pypy/doc/stackless.txt	(original)
+++ pypy/dist/pypy/doc/stackless.txt	Tue Feb 13 17:27:16 2007
@@ -308,12 +308,14 @@
 frame objects in the heap of a process before we can resume execution of
 these newly built frames.  We must recreate a corresponding chain of
 interpreter-level frames.  To this end, we have inserted a few *named
-resume points* (see XXX) in the Python interpreter of PyPy.  This is the
+resume points* (see 3.2.4, in `D07.1 Massive Parallelism and Translation Aspects`_) in the Python interpreter of PyPy.  This is the
 motivation for implementing the interpreter-level primitives
 ``resume_state_create()`` and ``resume_state_invoke()``, the powerful
 interface that allows an RPython program to artifically rebuild a chain
 of calls in a reflective way, completely from scratch, and jump to it.
 
+.. _`D07.1 Massive Parallelism and Translation Aspects`: http://codespeak.net/pypy/extradoc/eu-report/D07.1_Massive_Parallelism_and_Translation_Aspects-2006-12-15.pdf
+
 Example
 ~~~~~~~
 


From arigo at codespeak.net  Tue Feb 13 17:29:37 2007
From: arigo at codespeak.net (arigo at codespeak.net)
Date: Tue, 13 Feb 2007 17:29:37 +0100 (CET)
Subject: [pypy-svn] r38724 - in pypy/dist/pypy/module/_file: . test
Message-ID: <20070213162937.DE0AC100A8@code0.codespeak.net>

Author: arigo
Date: Tue Feb 13 17:29:35 2007
New Revision: 38724

Modified:
   pypy/dist/pypy/module/_file/app_file.py
   pypy/dist/pypy/module/_file/test/test_file.py
Log:
Allow file.write(unicode-string), converted to str in the default encoding
as usual for 'str' in unwrap_spec gateways.  I believe that it's exactly
what CPython does too.


Modified: pypy/dist/pypy/module/_file/app_file.py
==============================================================================
--- pypy/dist/pypy/module/_file/app_file.py	(original)
+++ pypy/dist/pypy/module/_file/app_file.py	Tue Feb 13 17:29:35 2007
@@ -152,8 +152,6 @@
 the file on disk reflects the data written."""
         if self._closed:
             raise ValueError('I/O operation on closed file')
-        if not isinstance(data, str):
-            raise TypeError('write() argument must be a string (for now)')
         return self.stream.write(data)
 
     def writelines(self, sequence_of_strings):
@@ -164,9 +162,6 @@
         if self._closed:
             raise ValueError('I/O operation on closed file')
         for line in sequence_of_strings:
-            if not isinstance(line, str):
-                raise TypeError('writelines() argument must be a list '
-                                'of strings')
             self.stream.write(line)
 
     def tell(self):

Modified: pypy/dist/pypy/module/_file/test/test_file.py
==============================================================================
--- pypy/dist/pypy/module/_file/test/test_file.py	(original)
+++ pypy/dist/pypy/module/_file/test/test_file.py	Tue Feb 13 17:29:35 2007
@@ -105,3 +105,14 @@
         res = f.read()
         assert res == "\n"
         assert f.newlines == "\r\n"
+
+    def test_unicode(self):
+        import _file, os
+        f = _file.file(self.temppath, "w")
+        f.write(u"hello\n")
+        f.close()
+        f = _file.file(self.temppath, "r")
+        res = f.read()
+        assert res == "hello\n"
+        assert type(res) is str
+        f.close()


From pedronis at codespeak.net  Tue Feb 13 17:36:13 2007
From: pedronis at codespeak.net (pedronis at codespeak.net)
Date: Tue, 13 Feb 2007 17:36:13 +0100 (CET)
Subject: [pypy-svn] r38725 - pypy/dist/pypy/doc
Message-ID: <20070213163613.991E7100A8@code0.codespeak.net>

Author: pedronis
Date: Tue Feb 13 17:36:11 2007
New Revision: 38725

Modified:
   pypy/dist/pypy/doc/translation.txt
Log:
reference D07.1 for all transforms. kill some unlikely to ever be filled XXX.



Modified: pypy/dist/pypy/doc/translation.txt
==============================================================================
--- pypy/dist/pypy/doc/translation.txt	(original)
+++ pypy/dist/pypy/doc/translation.txt	Tue Feb 13 17:36:11 2007
@@ -448,7 +448,10 @@
 ============================
 
 Between RTyping and C source generation there are two optional transforms:
-the "backend optimizations" and the "stackless transform".
+the "backend optimizations" and the "stackless transform". See also
+`D07.1 Massive Parallelism and Translation Aspects`_ for further details.
+
+.. _`D07.1 Massive Parallelism and Translation Aspects`: http://codespeak.net/pypy/extradoc/eu-report/D07.1_Massive_Parallelism_and_Translation_Aspects-2006-12-15.pdf
 
 Backend Optimizations
 ---------------------
@@ -548,7 +551,7 @@
 stored into a place where they can be accessed by something outside of the
 stack of frames starting with the frame where the malloc occured.
 
-For this we choose a naive, pessimistic approach (XXX reference). The analysis
+For this we choose a naive, pessimistic approach. The analysis
 assumes that an object escapes if one of the following situation occurs:
 
   * the object is returned
@@ -577,8 +580,6 @@
 The Stackless Transform
 -----------------------
 
-(this section is very incomplete currently)
-
 The stackless transform converts functions into a form that knows how
 to save the execution point and active variables into a heap structure
 and resume execution at that point.  This is used to implement
@@ -646,11 +647,6 @@
 
 .. _`EU report`: http://codespeak.net/pypy/extradoc/eu-report/D07.1_Massive_Parallelism_and_Translation_Aspects-2006-12-15.pdf
 
-Building the Low-Level Database
--------------------------------
-
-XXX
-
 .. _C:
 .. _GenC:
 .. _`c backend`:


From cfbolz at codespeak.net  Tue Feb 13 17:52:14 2007
From: cfbolz at codespeak.net (cfbolz at codespeak.net)
Date: Tue, 13 Feb 2007 17:52:14 +0100 (CET)
Subject: [pypy-svn] r38728 - pypy/dist/pypy/doc
Message-ID: <20070213165214.D8997100AF@code0.codespeak.net>

Author: cfbolz
Date: Tue Feb 13 17:52:13 2007
New Revision: 38728

Modified:
   pypy/dist/pypy/doc/cleanup-todo.txt
Log:
add the closing files problem


Modified: pypy/dist/pypy/doc/cleanup-todo.txt
==============================================================================
--- pypy/dist/pypy/doc/cleanup-todo.txt	(original)
+++ pypy/dist/pypy/doc/cleanup-todo.txt	Tue Feb 13 17:52:13 2007
@@ -13,3 +13,4 @@
  - geninterp is a hack
  - keepalives need to die, finally
  - change weakrefs to work together with the GC
+   - if this is done, open files should be closed at shutdown


From ericvrp at codespeak.net  Tue Feb 13 18:01:44 2007
From: ericvrp at codespeak.net (ericvrp at codespeak.net)
Date: Tue, 13 Feb 2007 18:01:44 +0100 (CET)
Subject: [pypy-svn] r38731 - pypy/dist/pypy/jit/codegen/llvm
Message-ID: <20070213170144.2988C10089@code0.codespeak.net>

Author: ericvrp
Date: Tue Feb 13 18:01:42 2007
New Revision: 38731

Modified:
   pypy/dist/pypy/jit/codegen/llvm/rgenop.py
Log:
Skip test that should call a function directly


Modified: pypy/dist/pypy/jit/codegen/llvm/rgenop.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/llvm/rgenop.py	(original)
+++ pypy/dist/pypy/jit/codegen/llvm/rgenop.py	Tue Feb 13 18:01:42 2007
@@ -726,8 +726,10 @@
                 gv_fn.operand2(), inttoptr, i32, gv_fnptr.operand2(), gv_fn.type))
             funcsig = gv_fn.operand()
         else:
-            #XXX we probably need to call an address directly if we can't resolve the funcsig
-            funcsig = self.rgenop.funcsig[gv_fnptr.get_integer_value()]
+            try:
+                funcsig = self.rgenop.funcsig[gv_fnptr.get_integer_value()]
+            except KeyError:
+                py.test.skip('call an address directly not supported yet')
         args_gv2 = []
         for v in args_gv:
             if v.is_const and v.type[-1] == '*': #or use some kind of 'inline' cast (see LangRef)


From pedronis at codespeak.net  Tue Feb 13 18:12:25 2007
From: pedronis at codespeak.net (pedronis at codespeak.net)
Date: Tue, 13 Feb 2007 18:12:25 +0100 (CET)
Subject: [pypy-svn] r38734 - pypy/dist/pypy/doc
Message-ID: <20070213171225.F297010089@code0.codespeak.net>

Author: pedronis
Date: Tue Feb 13 18:12:23 2007
New Revision: 38734

Modified:
   pypy/dist/pypy/doc/faq.txt
Log:
__class__ is RPython, at least reading it.



Modified: pypy/dist/pypy/doc/faq.txt
==============================================================================
--- pypy/dist/pypy/doc/faq.txt	(original)
+++ pypy/dist/pypy/doc/faq.txt	Tue Feb 13 18:12:23 2007
@@ -212,7 +212,7 @@
 different types in the same variable. In this respect (and in some others) it
 feels a bit like Java. Other features not allowed in RPython are the usage of
 special methods (``__XXX__``) except ``__init__`` and ``__del__`` and reflection
-capabilities (e.g. ``__dict__`` and ``__class__``).
+capabilities (e.g. ``__dict__``).
 
 Most existing standard library modules are not RPython, except for some
 functions in ``os``, ``math`` and ``time``. In general it is quite unlikely that


From ac at codespeak.net  Tue Feb 13 18:17:13 2007
From: ac at codespeak.net (ac at codespeak.net)
Date: Tue, 13 Feb 2007 18:17:13 +0100 (CET)
Subject: [pypy-svn] r38735 - pypy/dist/pypy/module/unicodedata
Message-ID: <20070213171713.7E40B100AB@code0.codespeak.net>

Author: ac
Date: Tue Feb 13 18:17:12 2007
New Revision: 38735

Modified:
   pypy/dist/pypy/module/unicodedata/interp_ucd.py
Log:
Needs to accept mixed-case names.

Modified: pypy/dist/pypy/module/unicodedata/interp_ucd.py
==============================================================================
--- pypy/dist/pypy/module/unicodedata/interp_ucd.py	(original)
+++ pypy/dist/pypy/module/unicodedata/interp_ucd.py	Tue Feb 13 18:17:12 2007
@@ -50,7 +50,7 @@
         
     def lookup(self, space, name):
         try:
-            code = self._lookup(name)
+            code = self._lookup(name.upper())
         except KeyError:
             msg = space.mod(space.wrap("undefined character name '%s'"), space.wrap(name))
             raise OperationError(space.w_KeyError, msg)


From pedronis at codespeak.net  Tue Feb 13 18:18:47 2007
From: pedronis at codespeak.net (pedronis at codespeak.net)
Date: Tue, 13 Feb 2007 18:18:47 +0100 (CET)
Subject: [pypy-svn] r38736 - pypy/dist/pypy/doc
Message-ID: <20070213171847.401F7100AB@code0.codespeak.net>

Author: pedronis
Date: Tue Feb 13 18:18:42 2007
New Revision: 38736

Modified:
   pypy/dist/pypy/doc/faq.txt
Log:
clarification



Modified: pypy/dist/pypy/doc/faq.txt
==============================================================================
--- pypy/dist/pypy/doc/faq.txt	(original)
+++ pypy/dist/pypy/doc/faq.txt	Tue Feb 13 18:18:42 2007
@@ -214,10 +214,11 @@
 special methods (``__XXX__``) except ``__init__`` and ``__del__`` and reflection
 capabilities (e.g. ``__dict__``).
 
-Most existing standard library modules are not RPython, except for some
-functions in ``os``, ``math`` and ``time``. In general it is quite unlikely that
-an existing Python program is by chance RPython, mostly it has to be rewritten
-heavily.  To read more about RPython limitations read `RPython description`_
+Most existing standard library modules are not RPython, except for
+some functions in ``os``, ``math`` and ``time`` that are natively
+supported. In general it is quite unlikely that an existing Python
+program is by chance RPython, mostly it has to be rewritten heavily.
+To read more about RPython limitations read `RPython description`_
 
 .. _`RPython description`: coding-guide.html#restricted-python
 


From arigo at codespeak.net  Tue Feb 13 18:55:49 2007
From: arigo at codespeak.net (arigo at codespeak.net)
Date: Tue, 13 Feb 2007 18:55:49 +0100 (CET)
Subject: [pypy-svn] r38737 - in pypy/dist/pypy: interpreter module/_file
	module/_file/test module/sys rlib
Message-ID: <20070213175549.71E601008D@code0.codespeak.net>

Author: arigo
Date: Tue Feb 13 18:55:44 2007
New Revision: 38737

Modified:
   pypy/dist/pypy/interpreter/baseobjspace.py
   pypy/dist/pypy/interpreter/mixedmodule.py
   pypy/dist/pypy/module/_file/app_file.py
   pypy/dist/pypy/module/_file/test/test_file.py
   pypy/dist/pypy/module/_file/test/test_file_extra.py
   pypy/dist/pypy/module/sys/__init__.py
   pypy/dist/pypy/module/sys/app.py
   pypy/dist/pypy/rlib/streamio.py
Log:
Add flush-on-exit capability to all our file objects.

Done with a new internal dict sys.pypy__exithandlers__.  In
space.finish(), we pop key/value pairs from this dictionary and just
call the value, as long as the dict is not empty.  This is probably
generally useful for situations where a number of small things must be
"finished" in any order, but finishing them might possibly create more
stuff that must itself be "finished" too.  The fact that it's a
dictionary means that it's cheap to add and remove many things from it.



Modified: pypy/dist/pypy/interpreter/baseobjspace.py
==============================================================================
--- pypy/dist/pypy/interpreter/baseobjspace.py	(original)
+++ pypy/dist/pypy/interpreter/baseobjspace.py	Tue Feb 13 18:55:44 2007
@@ -201,6 +201,12 @@
         w_exitfunc = self.sys.getdictvalue_w(self, 'exitfunc')
         if w_exitfunc is not None:
             self.call_function(w_exitfunc)
+        w_exithandlers = self.sys.getdictvalue_w(self, 'pypy__exithandlers__')
+        if w_exithandlers is not None:
+            while self.is_true(w_exithandlers):
+                w_key_value = self.call_method(w_exithandlers, 'popitem')
+                w_key, w_value = self.unpacktuple(w_key_value, 2)
+                self.call_function(w_value)
         if self.config.objspace.std.withdictmeasurement:
             from pypy.objspace.std.dictmultiobject import report
             report()

Modified: pypy/dist/pypy/interpreter/mixedmodule.py
==============================================================================
--- pypy/dist/pypy/interpreter/mixedmodule.py	(original)
+++ pypy/dist/pypy/interpreter/mixedmodule.py	Tue Feb 13 18:55:44 2007
@@ -216,10 +216,10 @@
     else:
         appname = name
     mod = Module(space, space.wrap(appname))
-    moddict = space.unwrap(mod.getdict())
     res = new.module(appname)
-    res.__dict__.update(moddict)
     sys.modules[appname] = res
+    moddict = space.unwrap(mod.getdict())
+    res.__dict__.update(moddict)
     return res
 
 def compilemodule(name, interactive=False):

Modified: pypy/dist/pypy/module/_file/app_file.py
==============================================================================
--- pypy/dist/pypy/module/_file/app_file.py	(original)
+++ pypy/dist/pypy/module/_file/app_file.py	Tue Feb 13 18:55:44 2007
@@ -1,5 +1,9 @@
 """NOT_RPYTHON"""
 
+import sys
+import _file
+
+
 class file(object):
     """file(name[, mode[, buffering]]) -> file object
 
@@ -22,32 +26,29 @@
     _closed = True   # Until the file is successfully opened
 
     def __init__(self, name, mode='r', buffering=-1):
-        import _file
-        self._name = name
-        self.softspace = 0    # Required according to file object docs
-        self.encoding = None  # This is not used internally by file objects
-        self._closed = False
-        self.stream = _file.open_file_as_stream(self._name, mode, buffering)
-        self._mode = mode
-        self.fd = self.stream.try_to_find_file_descriptor()
-        assert self.fd != -1
-        
+        stream = _file.open_file_as_stream(name, mode, buffering)
+        fd = stream.try_to_find_file_descriptor()
+        assert fd != -1
+        self._fdopenstream(fd, mode, buffering, name, stream)
+
     def fdopen(cls, fd, mode='r', buffering=-1):
         f = cls.__new__(cls)
-        f._fdopen(fd, mode, buffering, '')
+        stream = _file.fdopen_as_stream(fd, mode, buffering)
+        f._fdopenstream(fd, mode, buffering, '', stream)
         return f
     fdopen = classmethod(fdopen)
 
-    def _fdopen(self, fd, mode, buffering, name):
-        import _file
+    def _fdopenstream(self, fd, mode, buffering, name, stream):
         self.fd = fd
         self._name = name
         self.softspace = 0    # Required according to file object docs
         self.encoding = None  # This is not used internally by file objects
         self._closed = False
-        self.stream = _file.fdopen_as_stream(fd, mode, buffering)
+        self.stream = stream
         self._mode = mode
-        
+        if stream.flushable():
+            sys.pypy__exithandlers__[stream] = stream.flush
+
     def getnewlines(self):
         "end-of-line convention used in this file"
 
@@ -227,6 +228,7 @@
 may return an exit status upon closing."""
         if not self._closed and hasattr(self, 'stream'):
             self._closed = True
+            sys.pypy__exithandlers__.pop(self.stream, None)
             self.stream.close()
 
     __del__ = close

Modified: pypy/dist/pypy/module/_file/test/test_file.py
==============================================================================
--- pypy/dist/pypy/module/_file/test/test_file.py	(original)
+++ pypy/dist/pypy/module/_file/test/test_file.py	Tue Feb 13 18:55:44 2007
@@ -116,3 +116,21 @@
         assert res == "hello\n"
         assert type(res) is str
         f.close()
+
+
+def test_flush_at_exit():
+    from pypy import conftest
+    from pypy.tool.option import make_config, make_objspace
+    from pypy.tool.udir import udir
+
+    tmpfile = udir.join('test_flush_at_exit')
+    config = make_config(conftest.option)
+    space = make_objspace(config)
+    space.appexec([space.wrap(str(tmpfile))], """(tmpfile):
+        f = open(tmpfile, 'w')
+        f.write('42')
+        # no flush() and no close()
+        import sys; sys._keepalivesomewhereobscure = f
+    """)
+    space.finish()
+    assert tmpfile.read() == '42'

Modified: pypy/dist/pypy/module/_file/test/test_file_extra.py
==============================================================================
--- pypy/dist/pypy/module/_file/test/test_file_extra.py	(original)
+++ pypy/dist/pypy/module/_file/test/test_file_extra.py	Tue Feb 13 18:55:44 2007
@@ -1,4 +1,4 @@
-import os, random
+import os, random, sys
 from pypy.tool.udir import udir
 import py
 from pypy.interpreter.mixedmodule import testmodule
@@ -14,6 +14,9 @@
 def setup_module(mod):
     mod._file = testmodule("_file")
     udir.join('sample').write(SAMPLE)
+    # workaround for testing _file on top of CPython
+    if not hasattr(sys, 'pypy_objspaceclass'):
+        sys.pypy__exithandlers__ = {}
 
 
 class BaseROTests:

Modified: pypy/dist/pypy/module/sys/__init__.py
==============================================================================
--- pypy/dist/pypy/module/sys/__init__.py	(original)
+++ pypy/dist/pypy/module/sys/__init__.py	Tue Feb 13 18:55:44 2007
@@ -72,6 +72,7 @@
         '__excepthook__'        : 'app.excepthook', 
         'exit'                  : 'app.exit', 
         'exitfunc'              : 'app.exitfunc',
+        'pypy__exithandlers__'  : 'app.pypy__exithandlers__',  # internal
         'getfilesystemencoding' : 'app.getfilesystemencoding', 
         'callstats'             : 'app.callstats',
         'getdefaultencoding'    : 'app.getdefaultencoding', 

Modified: pypy/dist/pypy/module/sys/app.py
==============================================================================
--- pypy/dist/pypy/module/sys/app.py	(original)
+++ pypy/dist/pypy/module/sys/app.py	Tue Feb 13 18:55:44 2007
@@ -26,6 +26,8 @@
 def exitfunc():
     """Placeholder for sys.exitfunc(), which is called when PyPy exits."""
 
+pypy__exithandlers__ = {}
+
 #import __builtin__
 
 def getfilesystemencoding():

Modified: pypy/dist/pypy/rlib/streamio.py
==============================================================================
--- pypy/dist/pypy/rlib/streamio.py	(original)
+++ pypy/dist/pypy/rlib/streamio.py	Tue Feb 13 18:55:44 2007
@@ -4,7 +4,8 @@
 
 - This module contains various stream classes which provide a subset of the
   classic Python I/O API: read(n), write(s), tell(), seek(offset, whence=0),
-  readall(), readline(), truncate(size), flush(), close(), peek().
+  readall(), readline(), truncate(size), flush(), close(), peek(),
+  flushable(), try_to_find_file_descriptor().
 
 - This is not for general usage:
   * read(n) may return less than n bytes, just like os.read().
@@ -13,6 +14,7 @@
     there is no __del__() closing the stream for you.
   * some methods may raise NotImplementedError.
   * peek() returns some (or no) characters that have already been read ahead.
+  * flushable() returns True/False if flushing that stream is useful/pointless.
 
 - A 'basis stream' provides I/O using a low-level API, like the os, mmap or
   socket modules.
@@ -197,6 +199,9 @@
     def flush(self):
         pass
 
+    def flushable(self):
+        return False
+
     def close(self):
         pass
 
@@ -338,6 +343,10 @@
     def flush(self):
         self.mm.flush()
 
+    def flushable(self):
+        import mmap
+        return self.access == mmap.ACCESS_WRITE
+
     def try_to_find_file_descriptor(self):
         return self.fd
 
@@ -352,6 +361,7 @@
     ("readline", []),
     ("truncate", [int]),
     ("flush", []),
+    ("flushable", []),
     ("close", []),
     ("peek", []),
     ("try_to_find_file_descriptor", []),
@@ -613,10 +623,10 @@
     write      = PassThrough("write",     flush_buffers=True)
     truncate   = PassThrough("truncate",  flush_buffers=True)
     flush      = PassThrough("flush",     flush_buffers=True)
+    flushable  = PassThrough("flushable", flush_buffers=False)
     close      = PassThrough("close",     flush_buffers=False)
-
-    def try_to_find_file_descriptor(self):
-        return self.base.try_to_find_file_descriptor()
+    try_to_find_file_descriptor = PassThrough("try_to_find_file_descriptor",
+                                              flush_buffers=False)
 
 
 class BufferingOutputStream(Stream):
@@ -669,9 +679,11 @@
     truncate   = PassThrough("truncate", flush_buffers=True)
     flush      = PassThrough("flush",    flush_buffers=True)
     close      = PassThrough("close",    flush_buffers=True)
+    try_to_find_file_descriptor = PassThrough("try_to_find_file_descriptor",
+                                              flush_buffers=False)
 
-    def try_to_find_file_descriptor(self):
-        return self.base.try_to_find_file_descriptor()
+    def flushable(self):
+        return True
 
 
 class LineBufferingOutputStream(BufferingOutputStream):
@@ -688,9 +700,6 @@
             self.do_write(self.buf[:p])
             self.buf = self.buf[p:]
 
-    def try_to_find_file_descriptor(self):
-        return self.base.try_to_find_file_descriptor()
-
 
 # ____________________________________________________________
 
@@ -720,10 +729,10 @@
         return data
 
     flush    = PassThrough("flush", flush_buffers=False)
+    flushable= PassThrough("flushable", flush_buffers=False)
     close    = PassThrough("close", flush_buffers=False)
-
-    def try_to_find_file_descriptor(self):
-        return self.base.try_to_find_file_descriptor()
+    try_to_find_file_descriptor = PassThrough("try_to_find_file_descriptor",
+                                              flush_buffers=False)
 
 class TextInputFilter(Stream):
 
@@ -853,10 +862,10 @@
     write      = PassThrough("write",     flush_buffers=True)
     truncate   = PassThrough("truncate",  flush_buffers=True)
     flush      = PassThrough("flush",     flush_buffers=True)
+    flushable  = PassThrough("flushable", flush_buffers=False)
     close      = PassThrough("close",     flush_buffers=False)
-
-    def try_to_find_file_descriptor(self):
-        return self.base.try_to_find_file_descriptor()
+    try_to_find_file_descriptor = PassThrough("try_to_find_file_descriptor",
+                                              flush_buffers=False)
 
 
 class TextOutputFilter(Stream):
@@ -879,10 +888,10 @@
     readline   = PassThrough("readline",  flush_buffers=False)
     truncate   = PassThrough("truncate",  flush_buffers=False)
     flush      = PassThrough("flush",     flush_buffers=False)
+    flushable  = PassThrough("flushable", flush_buffers=False)
     close      = PassThrough("close",     flush_buffers=False)
-
-    def try_to_find_file_descriptor(self):
-        return self.base.try_to_find_file_descriptor()
+    try_to_find_file_descriptor = PassThrough("try_to_find_file_descriptor",
+                                              flush_buffers=False)
 
 
 # _________________________________________________
@@ -930,10 +939,10 @@
     write      = PassThrough("write",     flush_buffers=False)
     truncate   = PassThrough("truncate",  flush_buffers=False)
     flush      = PassThrough("flush",     flush_buffers=False)
+    flushable  = PassThrough("flushable", flush_buffers=False)
     close      = PassThrough("close",     flush_buffers=False)
-
-    def try_to_find_file_descriptor(self):
-        return self.base.try_to_find_file_descriptor()
+    try_to_find_file_descriptor = PassThrough("try_to_find_file_descriptor",
+                                              flush_buffers=False)
 
 class EncodingOutputFilter(Stream):
 
@@ -958,8 +967,7 @@
     readline   = PassThrough("readline",  flush_buffers=False)
     truncate   = PassThrough("truncate",  flush_buffers=False)
     flush      = PassThrough("flush",     flush_buffers=False)
+    flushable  = PassThrough("flushable", flush_buffers=False)
     close      = PassThrough("close",     flush_buffers=False)
-
-    def try_to_find_file_descriptor(self):
-        return self.base.try_to_find_file_descriptor()
-
+    try_to_find_file_descriptor = PassThrough("try_to_find_file_descriptor",
+                                              flush_buffers=False)


From arigo at codespeak.net  Tue Feb 13 19:18:15 2007
From: arigo at codespeak.net (arigo at codespeak.net)
Date: Tue, 13 Feb 2007 19:18:15 +0100 (CET)
Subject: [pypy-svn] r38738 - pypy/dist/pypy/module/__builtin__
Message-ID: <20070213181815.A287B10094@code0.codespeak.net>

Author: arigo
Date: Tue Feb 13 19:18:12 2007
New Revision: 38738

Modified:
   pypy/dist/pypy/module/__builtin__/app_descriptor.py
Log:
This is a hopefully temporary hack to work around inspect.getmodule()
as used by doctest.  Hum.


Modified: pypy/dist/pypy/module/__builtin__/app_descriptor.py
==============================================================================
--- pypy/dist/pypy/module/__builtin__/app_descriptor.py	(original)
+++ pypy/dist/pypy/module/__builtin__/app_descriptor.py	Tue Feb 13 19:18:12 2007
@@ -30,6 +30,8 @@
     def __get__(self, obj, objtype=None):
         return self._f
 
+staticmethod.__module__ = None
+
 
 class classmethod(object):
     """classmethod(function) -> class method
@@ -63,6 +65,7 @@
 def dummy(): pass
 MethodType = type(dummy.__get__(42))
 del dummy
+classmethod.__module__ = None
 
 # It's difficult to have a class that has both a docstring and a slot called
 # '__doc__', but not impossible...
@@ -142,6 +145,7 @@
         self.fdel(obj)
 
 docstring.capture(property, 'slot__doc__')
+property.__module__ = None
 
 
 # super is a modified version from Guido's tutorial


From cfbolz at codespeak.net  Tue Feb 13 19:19:25 2007
From: cfbolz at codespeak.net (cfbolz at codespeak.net)
Date: Tue, 13 Feb 2007 19:19:25 +0100 (CET)
Subject: [pypy-svn] r38740 - pypy/dist/pypy/doc
Message-ID: <20070213181925.0A139100B0@code0.codespeak.net>

Author: cfbolz
Date: Tue Feb 13 19:19:23 2007
New Revision: 38740

Modified:
   pypy/dist/pypy/doc/cleanup-todo.txt
Log:
add reviewing of performance-critical things


Modified: pypy/dist/pypy/doc/cleanup-todo.txt
==============================================================================
--- pypy/dist/pypy/doc/cleanup-todo.txt	(original)
+++ pypy/dist/pypy/doc/cleanup-todo.txt	Tue Feb 13 19:19:23 2007
@@ -13,4 +13,9 @@
  - geninterp is a hack
  - keepalives need to die, finally
  - change weakrefs to work together with the GC
-   - if this is done, open files should be closed at shutdown
+
+interpreter
+-----------
+
+ - review the things implemented at applevel whether they are performance-
+   critical


From arigo at codespeak.net  Tue Feb 13 20:20:43 2007
From: arigo at codespeak.net (arigo at codespeak.net)
Date: Tue, 13 Feb 2007 20:20:43 +0100 (CET)
Subject: [pypy-svn] r38746 - in pypy/dist/pypy/module/select: . test
Message-ID: <20070213192043.A95431008D@code0.codespeak.net>

Author: arigo
Date: Tue Feb 13 20:20:41 2007
New Revision: 38746

Added:
   pypy/dist/pypy/module/select/test/   (props changed)
   pypy/dist/pypy/module/select/test/test_select.py   (contents, props changed)
Modified:
   pypy/dist/pypy/module/select/app_select.py
Log:
Add tests to the select module implementation.  Fix a bug that
caused "busy-loops" in typical applications.


Modified: pypy/dist/pypy/module/select/app_select.py
==============================================================================
--- pypy/dist/pypy/module/select/app_select.py	(original)
+++ pypy/dist/pypy/module/select/app_select.py	Tue Feb 13 20:20:41 2007
@@ -36,7 +36,7 @@
 *** IMPORTANT NOTICE ***
 On Windows, only sockets are supported; on Unix, all file descriptors.
 """
-    from select import poll, POLLIN, POLLOUT, POLLPRI
+    from select import poll, POLLIN, POLLOUT, POLLPRI, POLLERR, POLLHUP
     fddict = {}
     polldict = {}
     fd = 0
@@ -63,9 +63,9 @@
     else:
         ret = dict(p.poll())
 
-    iretd = [ f for f in iwtd if ret.get(fddict[id(f)], 0) & POLLIN]
+    iretd = [ f for f in iwtd if ret.get(fddict[id(f)], 0) & (POLLIN|POLLHUP)]
     oretd = [ f for f in owtd if ret.get(fddict[id(f)], 0) & POLLOUT]
-    eretd = [ f for f in ewtd if ret.get(fddict[id(f)], 0) & POLLPRI]
+    eretd = [ f for f in ewtd if ret.get(fddict[id(f)], 0) & (POLLERR|POLLPRI)]
 
     return iretd, oretd, eretd
     

Added: pypy/dist/pypy/module/select/test/test_select.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/module/select/test/test_select.py	Tue Feb 13 20:20:41 2007
@@ -0,0 +1,119 @@
+import py, sys
+from pypy.conftest import gettestobjspace
+
+class AppTestSelect:
+    def setup_class(cls):
+        if sys.platform == 'win':
+            py.test.skip("select() doesn't work with pipes, "
+                         "we would need tests using sockets")
+        space = gettestobjspace(usemodules=('select',))
+        cls.space = space
+
+    def test_sleep(self):
+        import time, select
+        start = time.time()
+        iwtd, owtd, ewtd = select.select([], [], [], 0.3)
+        end = time.time()
+        assert iwtd == owtd == ewtd == []
+        assert end - start > 0.25
+
+    def test_readable(self):
+        import os, select
+        readend, writeend = os.pipe()
+        try:
+            iwtd, owtd, ewtd = select.select([readend], [], [], 0)
+            assert iwtd == owtd == ewtd == []
+            os.write(writeend, 'X')
+            iwtd, owtd, ewtd = select.select([readend], [], [])
+            assert iwtd == [readend]
+            assert owtd == ewtd == []
+        finally:
+            os.close(writeend)
+            os.close(readend)
+
+    def test_write_read(self):
+        import os, select
+        readend, writeend = os.pipe()
+        try:
+            total_out = 0
+            while True:
+                iwtd, owtd, ewtd = select.select([], [writeend], [], 0)
+                assert iwtd == ewtd == []
+                if owtd == []:
+                    break
+                assert owtd == [writeend]
+                total_out += os.write(writeend, 'x' * 512)
+            total_in = 0
+            while True:
+                iwtd, owtd, ewtd = select.select([readend], [], [], 0)
+                assert owtd == ewtd == []
+                if iwtd == []:
+                    break
+                assert iwtd == [readend]
+                data = os.read(readend, 4096)
+                assert len(data) > 0
+                assert data == 'x' * len(data)
+                total_in += len(data)
+            assert total_in == total_out
+        finally:
+            os.close(writeend)
+            os.close(readend)
+
+    def test_close(self):
+        import os, select
+        readend, writeend = os.pipe()
+        try:
+            try:
+                total_out = os.write(writeend, 'x' * 512)
+            finally:
+                os.close(writeend)
+            assert 1 <= total_out <= 512
+            total_in = 0
+            while True:
+                iwtd, owtd, ewtd = select.select([readend], [], [])
+                assert iwtd == [readend]
+                assert owtd == ewtd == []
+                data = os.read(readend, 4096)
+                if len(data) == 0:
+                    break
+                assert data == 'x' * len(data)
+                total_in += len(data)
+            assert total_in == total_out
+        finally:
+            os.close(readend)
+
+    def test_read_many(self):
+        import os, select
+        readends = []
+        writeends = []
+        try:
+            for i in range(10):
+                fd1, fd2 = os.pipe()
+                readends.append(fd1)
+                writeends.append(fd2)
+            iwtd, owtd, ewtd = select.select(readends, [], [], 0)
+            assert iwtd == owtd == ewtd == []
+
+            for i in range(50):
+                n = (i*3) % 10
+                os.write(writeends[n], 'X')
+                iwtd, owtd, ewtd = select.select(readends, [], [])
+                assert iwtd == [readends[n]]
+                assert owtd == ewtd == []
+                data = os.read(readends[n], 1)
+                assert data == 'X'
+
+        finally:
+            for fd in readends + writeends:
+                os.close(fd)
+
+    def test_read_end_closed(self):
+        import os, select
+        readend, writeend = os.pipe()
+        os.close(readend)
+        try:
+            iwtd, owtd, ewtd = select.select([], [writeend], [])
+            assert owtd == [writeend]
+            assert iwtd == ewtd == []
+        finally:
+            os.close(writeend)


From arigo at codespeak.net  Tue Feb 13 20:24:10 2007
From: arigo at codespeak.net (arigo at codespeak.net)
Date: Tue, 13 Feb 2007 20:24:10 +0100 (CET)
Subject: [pypy-svn] r38748 - in pypy/dist: lib-python/modified-2.4.1
	pypy/module/__builtin__
Message-ID: <20070213192410.764811008D@code0.codespeak.net>

Author: arigo
Date: Tue Feb 13 20:24:09 2007
New Revision: 38748

Added:
   pypy/dist/lib-python/modified-2.4.1/doctest.py
      - copied, changed from r38738, pypy/dist/lib-python/2.4.1/doctest.py
Modified:
   pypy/dist/pypy/module/__builtin__/app_descriptor.py
Log:
Revert r38738 (it's not helping) and modify doctest.py instead.


Modified: pypy/dist/pypy/module/__builtin__/app_descriptor.py
==============================================================================
--- pypy/dist/pypy/module/__builtin__/app_descriptor.py	(original)
+++ pypy/dist/pypy/module/__builtin__/app_descriptor.py	Tue Feb 13 20:24:09 2007
@@ -30,8 +30,6 @@
     def __get__(self, obj, objtype=None):
         return self._f
 
-staticmethod.__module__ = None
-
 
 class classmethod(object):
     """classmethod(function) -> class method
@@ -65,7 +63,6 @@
 def dummy(): pass
 MethodType = type(dummy.__get__(42))
 del dummy
-classmethod.__module__ = None
 
 # It's difficult to have a class that has both a docstring and a slot called
 # '__doc__', but not impossible...
@@ -145,7 +142,6 @@
         self.fdel(obj)
 
 docstring.capture(property, 'slot__doc__')
-property.__module__ = None
 
 
 # super is a modified version from Guido's tutorial


From hpk at codespeak.net  Tue Feb 13 20:56:39 2007
From: hpk at codespeak.net (hpk at codespeak.net)
Date: Tue, 13 Feb 2007 20:56:39 +0100 (CET)
Subject: [pypy-svn] r38753 - pypy/dist/pypy
Message-ID: <20070213195639.46271100A7@code0.codespeak.net>

Author: hpk
Date: Tue Feb 13 20:56:38 2007
New Revision: 38753

Modified:
   pypy/dist/pypy/conftest.py
Log:
adapt to small py.test namespace change


Modified: pypy/dist/pypy/conftest.py
==============================================================================
--- pypy/dist/pypy/conftest.py	(original)
+++ pypy/dist/pypy/conftest.py	Tue Feb 13 20:56:38 2007
@@ -227,7 +227,7 @@
         return space
 
 
-class PyPyTestFunction(py.test.Function):
+class PyPyTestFunction(py.test.collect.Function):
     # All PyPy test items catch and display OperationErrors specially.
     #
     def execute_appex(self, space, target, *args):


From hpk at codespeak.net  Tue Feb 13 20:57:27 2007
From: hpk at codespeak.net (hpk at codespeak.net)
Date: Tue, 13 Feb 2007 20:57:27 +0100 (CET)
Subject: [pypy-svn] r38754 - pypy/dist/lib-python
Message-ID: <20070213195727.42534100AB@code0.codespeak.net>

Author: hpk
Date: Tue Feb 13 20:57:26 2007
New Revision: 38754

Modified:
   pypy/dist/lib-python/conftest.py
Log:
another small adaptation to namespace change


Modified: pypy/dist/lib-python/conftest.py
==============================================================================
--- pypy/dist/lib-python/conftest.py	(original)
+++ pypy/dist/lib-python/conftest.py	Tue Feb 13 20:57:26 2007
@@ -23,6 +23,8 @@
 from pypy.tool.pytest.result import Result, ResultFromMime
 
 pypyexecpath = pypydir.join('bin', 'pypy-c')
+
+dist_rsync_roots = ['.', '../pypy', '../py']
     
 # 
 # Interfacing/Integrating with py.test's collection process 
@@ -77,8 +79,8 @@
         if appexcinfo.traceback: 
             print "appexcinfo.traceback:"
             py.std.pprint.pprint(appexcinfo.traceback)
-            raise py.test.Item.Failed(excinfo=appexcinfo) 
-        raise py.test.Item.Failed(excinfo=ilevelinfo) 
+            raise py.test.collect.Item.Failed(excinfo=appexcinfo) 
+        raise py.test.collect.Item.Failed(excinfo=ilevelinfo) 
 
 #
 # compliance modules where we invoke test_main() usually call into 
@@ -172,7 +174,7 @@
     w_namemethods, w_doctestlist = space.unpacktuple(w_result) 
     return w_namemethods, w_doctestlist 
 
-class SimpleRunItem(py.test.Item): 
+class SimpleRunItem(py.test.collect.Item): 
     """ Run a module file and compare its output 
         to the expected output in the output/ directory. 
     """ 
@@ -263,7 +265,7 @@
         except KeyError: 
             pass
 
-class AppDocTestModule(py.test.Item): 
+class AppDocTestModule(py.test.collect.Item): 
     def __init__(self, name, parent, w_module): 
         super(AppDocTestModule, self).__init__(name, parent) 
         self.w_module = w_module 
@@ -271,7 +273,7 @@
     def run(self): 
         py.test.skip("application level doctest modules not supported yet.")
     
-class AppTestCaseMethod(py.test.Item): 
+class AppTestCaseMethod(py.test.collect.Item): 
     def __init__(self, name, parent, w_method): 
         super(AppTestCaseMethod, self).__init__(name, parent) 
         self.space = gettestobjspace() 
@@ -871,7 +873,7 @@
 import socket
 import getpass
 
-class ReallyRunFileExternal(py.test.Item): 
+class ReallyRunFileExternal(py.test.collect.Item): 
     _resultcache = None
     def haskeyword(self, keyword): 
         if keyword == 'core': 


From hpk at codespeak.net  Tue Feb 13 21:22:40 2007
From: hpk at codespeak.net (hpk at codespeak.net)
Date: Tue, 13 Feb 2007 21:22:40 +0100 (CET)
Subject: [pypy-svn] r38757 - pypy/dist/pypy/doc
Message-ID: <20070213202240.5A04C100A6@code0.codespeak.net>

Author: hpk
Date: Tue Feb 13 21:22:39 2007
New Revision: 38757

Modified:
   pypy/dist/pypy/doc/cli-backend.txt
Log:
fix external link


Modified: pypy/dist/pypy/doc/cli-backend.txt
==============================================================================
--- pypy/dist/pypy/doc/cli-backend.txt	(original)
+++ pypy/dist/pypy/doc/cli-backend.txt	Tue Feb 13 21:22:39 2007
@@ -426,6 +426,6 @@
 
 
 
-.. _`Standard Ecma 335`: http://www.ecma-international.org/\\publications/standards/Ecma-335.htm
+.. _`Standard Ecma 335`: http://www.ecma-international.org/publications/standards/Ecma-335.htm
 .. _`flow graph`: http://codespeak.net/pypy/dist/pypy/doc/translation.html#the-flow-model
 .. _`rtyper`: http://codespeak.net/pypy/dist/pypy/doc/rtyper.html


From hpk at codespeak.net  Tue Feb 13 21:31:12 2007
From: hpk at codespeak.net (hpk at codespeak.net)
Date: Tue, 13 Feb 2007 21:31:12 +0100 (CET)
Subject: [pypy-svn] r38758 - in pypy/dist/pypy: objspace/cpy/test tool/pytest
Message-ID: <20070213203112.927E9100A6@code0.codespeak.net>

Author: hpk
Date: Tue Feb 13 21:31:11 2007
New Revision: 38758

Added:
   pypy/dist/pypy/tool/pytest/modcheck.py   (contents, props changed)
Modified:
   pypy/dist/pypy/objspace/cpy/test/conftest.py
Log:
* skip cpy objspace tests if there is no ctypes
* add helper to skip/check for imports 



Modified: pypy/dist/pypy/objspace/cpy/test/conftest.py
==============================================================================
--- pypy/dist/pypy/objspace/cpy/test/conftest.py	(original)
+++ pypy/dist/pypy/objspace/cpy/test/conftest.py	Tue Feb 13 21:31:11 2007
@@ -1,13 +1,8 @@
 
 import py
-
-try:
-    import ctypes
-except ImportError:
-    ctypes = None
+from pypy.tool.pytest.modcheck import skipimporterror
 
 class Directory(py.test.collect.Directory):
     def run(self):
-        if ctypes is None:
-            py.test.skip("no ctypes module available")
+        skipimporterror("ctypes")
         return super(Directory, self).run()

Added: pypy/dist/pypy/tool/pytest/modcheck.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/tool/pytest/modcheck.py	Tue Feb 13 21:31:11 2007
@@ -0,0 +1,14 @@
+import py
+
+def skipimporterror(name):
+    if not hasimport(name):
+        __tracebackhide__ = True
+        py.test.skip("cannot import %r module" % (name,))
+
+def hasimport(name):
+    try:
+        __import__(name)
+    except ImportError:
+        return False
+    else:
+        return True


From hpk at codespeak.net  Tue Feb 13 21:36:55 2007
From: hpk at codespeak.net (hpk at codespeak.net)
Date: Tue, 13 Feb 2007 21:36:55 +0100 (CET)
Subject: [pypy-svn] r38759 - pypy/dist/pypy/rpython/module/test
Message-ID: <20070213203655.301EB100AB@code0.codespeak.net>

Author: hpk
Date: Tue Feb 13 21:36:54 2007
New Revision: 38759

Modified:
   pypy/dist/pypy/rpython/module/test/test_ll_os.py
   pypy/dist/pypy/rpython/module/test/test_ll_os_path.py
   pypy/dist/pypy/rpython/module/test/test_posix.py
Log:
more skips for ctypes not present 


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	Tue Feb 13 21:36:54 2007
@@ -1,5 +1,8 @@
 import os
 from pypy.tool.udir import udir
+from pypy.tool.pytest.modcheck import skipimporterror
+skipimporterror("ctypes")
+
 from pypy.rpython.lltypesystem.module.ll_os import Implementation as impl
 import sys
 

Modified: pypy/dist/pypy/rpython/module/test/test_ll_os_path.py
==============================================================================
--- pypy/dist/pypy/rpython/module/test/test_ll_os_path.py	(original)
+++ pypy/dist/pypy/rpython/module/test/test_ll_os_path.py	Tue Feb 13 21:36:54 2007
@@ -2,6 +2,9 @@
 
 import os
 
+from pypy.tool.pytest.modcheck import skipimporterror
+skipimporterror("ctypes")
+
 from pypy.rpython.lltypesystem.module.ll_os_path import Implementation as impl
 from pypy.rpython.module.support import ll_strcpy
 from pypy.rpython.test.test_llinterp import interpret

Modified: pypy/dist/pypy/rpython/module/test/test_posix.py
==============================================================================
--- pypy/dist/pypy/rpython/module/test/test_posix.py	(original)
+++ pypy/dist/pypy/rpython/module/test/test_posix.py	Tue Feb 13 21:36:54 2007
@@ -1,3 +1,6 @@
+from pypy.tool.pytest.modcheck import skipimporterror
+skipimporterror("ctypes")
+
 from pypy.rpython.test.tool import BaseRtypingTest, LLRtypeMixin, OORtypeMixin
 from pypy.tool.udir import udir 
 import os


From arigo at codespeak.net  Wed Feb 14 00:15:51 2007
From: arigo at codespeak.net (arigo at codespeak.net)
Date: Wed, 14 Feb 2007 00:15:51 +0100 (CET)
Subject: [pypy-svn] r38765 - pypy/dist/pypy/interpreter/pyparser/test
Message-ID: <20070213231551.53319100A3@code0.codespeak.net>

Author: arigo
Date: Wed Feb 14 00:15:50 2007
New Revision: 38765

Modified:
   pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py
   pypy/dist/pypy/interpreter/pyparser/test/test_astcompiler.py
Log:
Test fixes: forgot to update the FakeSpace, and need to skip
module-level docstring tests as the "stable" compiler (joke)
is actually where the bug that I just fixed originally came from.


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 Feb 14 00:15:50 2007
@@ -670,6 +670,7 @@
 class FakeSpace:
     w_None = None
     w_str = str
+    w_basestring = basestring
     w_int = int
     
     def wrap(self,obj):

Modified: pypy/dist/pypy/interpreter/pyparser/test/test_astcompiler.py
==============================================================================
--- pypy/dist/pypy/interpreter/pyparser/test/test_astcompiler.py	(original)
+++ pypy/dist/pypy/interpreter/pyparser/test/test_astcompiler.py	Wed Feb 14 00:15:50 2007
@@ -152,16 +152,16 @@
     return code
 
 def check_compile(expr, target='exec', quiet=False, space=None):
-    if expr == "k[v,]":
-        py.test.skip('bug of the reference "stable compiler"')
     if not quiet:
         print "Compiling:", expr
 
     if space is None:
         space = std_space
 
-    sc_code = compile_with_testcompiler(expr, target=target)
     ac_code = compile_with_astcompiler(expr, target=target, space=space)
+    if expr == "k[v,]" or expr.startswith('"'):  # module-level docstring
+        py.test.skip('comparison skipped, bug in "reference stable compiler"')
+    sc_code = compile_with_testcompiler(expr, target=target)
     compare_code(ac_code, sc_code, space=space)
 
 ## def check_compile( expr ):


From arigo at codespeak.net  Wed Feb 14 00:25:45 2007
From: arigo at codespeak.net (arigo at codespeak.net)
Date: Wed, 14 Feb 2007 00:25:45 +0100 (CET)
Subject: [pypy-svn] r38767 - pypy/dist/pypy/interpreter/stablecompiler
Message-ID: <20070213232545.79400100A3@code0.codespeak.net>

Author: arigo
Date: Wed Feb 14 00:25:44 2007
New Revision: 38767

Added:
   pypy/dist/pypy/interpreter/stablecompiler/README.txt   (contents, props changed)
Log:
Add a README.txt to warn the unsuspecting onlooker against the
stablecompiler.


Added: pypy/dist/pypy/interpreter/stablecompiler/README.txt
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/interpreter/stablecompiler/README.txt	Wed Feb 14 00:25:44 2007
@@ -0,0 +1,6 @@
+This is mostly a copy of the pure Python compiler of Python
+2.4.1.  Despite the name "stable" it is heavily buggy and only
+suitable for tasks like superficial inspection of modules.
+
+It should be removed, but for now we keep it around so that
+tests have something to compare against.


From arigo at codespeak.net  Wed Feb 14 00:31:50 2007
From: arigo at codespeak.net (arigo at codespeak.net)
Date: Wed, 14 Feb 2007 00:31:50 +0100 (CET)
Subject: [pypy-svn] r38768 - pypy/dist/pypy/interpreter/stablecompiler
Message-ID: <20070213233150.CACF9100AB@code0.codespeak.net>

Author: arigo
Date: Wed Feb 14 00:31:49 2007
New Revision: 38768

Modified:
   pypy/dist/pypy/interpreter/stablecompiler/README.txt
Log:
Duh.


Modified: pypy/dist/pypy/interpreter/stablecompiler/README.txt
==============================================================================
--- pypy/dist/pypy/interpreter/stablecompiler/README.txt	(original)
+++ pypy/dist/pypy/interpreter/stablecompiler/README.txt	Wed Feb 14 00:31:49 2007
@@ -1,6 +1,7 @@
 This is mostly a copy of the pure Python compiler of Python
 2.4.1.  Despite the name "stable" it is heavily buggy and only
 suitable for tasks like superficial inspection of modules.
+(It's still less buggy than Python 2.4.1's, sadly.)
 
 It should be removed, but for now we keep it around so that
 tests have something to compare against.


From arigo at codespeak.net  Wed Feb 14 00:34:52 2007
From: arigo at codespeak.net (arigo at codespeak.net)
Date: Wed, 14 Feb 2007 00:34:52 +0100 (CET)
Subject: [pypy-svn] r38769 - pypy/dist/pypy/doc
Message-ID: <20070213233452.C1F6A100AD@code0.codespeak.net>

Author: arigo
Date: Wed Feb 14 00:34:51 2007
New Revision: 38769

Modified:
   pypy/dist/pypy/doc/index.txt
Log:
Put a single top-level link to the nightly pypy-c compliance test runs.


Modified: pypy/dist/pypy/doc/index.txt
==============================================================================
--- pypy/dist/pypy/doc/index.txt	(original)
+++ pypy/dist/pypy/doc/index.txt	Wed Feb 14 00:34:51 2007
@@ -74,7 +74,7 @@
 
 `Nightly builds and benchmarks`_ of PyPy to C, CLI and LLVM (PowerPC machine).
 
-Nightly compliance test runs for compiled pypy-c: `all working ext-modules with threads build`_, `all working ext-modules stackless build`_.
+`Nightly compliance test runs for compiled pypy-c`_.
 
 `compliance test status`_ shows outcomes of compliance test runs
 against PyPy on top of CPython.
@@ -130,8 +130,7 @@
 .. _`sprint reports`: sprint-reports.html
 .. _`talks and related projects`: extradoc.html
 .. _`license`: ../../LICENSE
-.. _`all working ext-modules with threads build`: http://www2.openend.se/~pedronis/pypy-c-test/allworkingmodules/summary.html
-.. _`all working ext-modules stackless build`: http://www2.openend.se/~pedronis/pypy-c-test/slp/summary.html
+.. _`Nightly compliance test runs for compiled pypy-c`: http://www.strakt.com/~pedronis/pypy-c-test/
 .. _`compliance test status`: http://codespeak.net/~hpk/pypy-testresult/
 .. _`PyPy statistics`: http://codespeak.net/~hpk/pypy-stat/
 .. _`object spaces`: objspace.html 


From hpk at codespeak.net  Wed Feb 14 03:37:56 2007
From: hpk at codespeak.net (hpk at codespeak.net)
Date: Wed, 14 Feb 2007 03:37:56 +0100 (CET)
Subject: [pypy-svn] r38784 - in pypy/dist/pypy/doc: . weekly
Message-ID: <20070214023756.56087100A6@code0.codespeak.net>

Author: hpk
Date: Wed Feb 14 03:37:55 2007
New Revision: 38784

Modified:
   pypy/dist/pypy/doc/confrest.py
   pypy/dist/pypy/doc/weekly/confrest.py
Log:
fixing doc generation target 


Modified: pypy/dist/pypy/doc/confrest.py
==============================================================================
--- pypy/dist/pypy/doc/confrest.py	(original)
+++ pypy/dist/pypy/doc/confrest.py	Wed Feb 14 03:37:55 2007
@@ -1,9 +1,9 @@
+import py
 from py.__.doc.confrest import *
 
 class PyPyPage(Page): 
-    def fill(self):
-        super(PyPyPage, self).fill()
-        self.menubar[:] = html.div(
+    def fill_menubar(self):
+        self.menubar = html.div(
             html.a("news", href="news.html", class_="menu"), " ",
             html.a("getting-started", 
                    href="getting-started.html", class_="menu"), " ",
@@ -18,6 +18,8 @@
             " ", id="menubar")
 
 class Project(Project): 
+    mydir = py.magic.autopath().dirpath()
+
     title = "PyPy" 
     stylesheet = 'style.css'
     encoding = 'latin1' 
@@ -29,4 +31,5 @@
                      height=110, width=149)))
     Page = PyPyPage 
 
-
+    def get_docpath(self):
+        return self.mydir

Modified: pypy/dist/pypy/doc/weekly/confrest.py
==============================================================================
--- pypy/dist/pypy/doc/weekly/confrest.py	(original)
+++ pypy/dist/pypy/doc/weekly/confrest.py	Wed Feb 14 03:37:55 2007
@@ -1,9 +1,9 @@
+import py
 from py.__.doc.confrest import *
 
 class PyPyPage(Page): 
-    def fill(self):
-        super(PyPyPage, self).fill()
-        self.menubar[:] = html.div(
+    def fill_menubar(self):
+        self.menubar = html.div(
             html.a("news", href="../news.html", class_="menu"), " ",
             html.a("doc", href="../index.html", class_="menu"), " ",
             html.a("contact", href="../contact.html", class_="menu"), " ", 
@@ -17,6 +17,7 @@
             " ", id="menubar")
 
 class Project(Project): 
+    mydir = py.magic.autopath().dirpath()
     title = "PyPy" 
     stylesheet = 'style.css'
     encoding = 'latin1' 
@@ -28,4 +29,7 @@
                      height=110, width=149)))
     Page = PyPyPage 
 
+    def get_docpath(self):
+        return self.mydir
+
 


From fijal at codespeak.net  Wed Feb 14 10:37:07 2007
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Wed, 14 Feb 2007 10:37:07 +0100 (CET)
Subject: [pypy-svn] r38785 - in pypy/dist/pypy/translator/js/examples/data:
	. images
Message-ID: <20070214093707.C15D9100AB@code0.codespeak.net>

Author: fijal
Date: Wed Feb 14 10:37:06 2007
New Revision: 38785

Added:
   pypy/dist/pypy/translator/js/examples/data/images/   (props changed)
Modified:
   pypy/dist/pypy/translator/js/examples/data/index.html
Log:
Intermediate checkin


Modified: pypy/dist/pypy/translator/js/examples/data/index.html
==============================================================================
--- pypy/dist/pypy/translator/js/examples/data/index.html	(original)
+++ pypy/dist/pypy/translator/js/examples/data/index.html	Wed Feb 14 10:37:06 2007
@@ -2,18 +2,24 @@
 
   pypy.js various demos
   
+  
 
 
   

This site presents various demos and tutorials about pypy.js

-

Python console:

-

No more, no less - Launch one for me - Source -

+
+

Python console:

+

No more, no less + Launch one for me + Source +

+
+

Remote terminal:

Fully ANSI-complaint remote terminal session: Launch one for me Source

+
From fijal at codespeak.net Wed Feb 14 10:38:14 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 14 Feb 2007 10:38:14 +0100 (CET) Subject: [pypy-svn] r38786 - in pypy/dist/pypy/translator/js/examples/bnb: . data Message-ID: <20070214093814.03187100AF@code0.codespeak.net> Author: fijal Date: Wed Feb 14 10:38:13 2007 New Revision: 38786 Added: pypy/dist/pypy/translator/js/examples/bnb/ pypy/dist/pypy/translator/js/examples/bnb/data/ Log: Add dir structure for moves From fijal at codespeak.net Wed Feb 14 10:40:06 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 14 Feb 2007 10:40:06 +0100 (CET) Subject: [pypy-svn] r38787 - pypy/dist/pypy/translator/js/examples Message-ID: <20070214094006.EBA8B100B2@code0.codespeak.net> Author: fijal Date: Wed Feb 14 10:40:06 2007 New Revision: 38787 Modified: pypy/dist/pypy/translator/js/examples/start_bnb.py Log: Commit local changes to be able to move - minor tweaks, mostly about changing genjs interface Modified: pypy/dist/pypy/translator/js/examples/start_bnb.py ============================================================================== --- pypy/dist/pypy/translator/js/examples/start_bnb.py (original) +++ pypy/dist/pypy/translator/js/examples/start_bnb.py Wed Feb 14 10:40:06 2007 @@ -6,23 +6,17 @@ import py -from pypy.translator.js import conftest - -conftest.option.tg = True -conftest.option.browser = "default" - -from pypy.translator.js.test.runtest import compile_function +from pypy.translator.js.main import rpython2javascript from pypy.translator.js.modules.dom import document -from pypy.translator.js.modules.mochikit import log, logWarning, createLoggingPane, logDebug -from pypy.translator.js.demo.jsdemo.bnb import BnbRootInstance +from pypy.translator.js.modules.mochikit import log, logWarning,\ + createLoggingPane, logDebug +from pypy.translator.js.demo.jsdemo.bnb import exported_methods import time import os - -os.chdir("../demo/jsdemo") +import sys def logKey(msg): - #log(msg) pass class Stats(object): @@ -50,6 +44,7 @@ def __init__(self): self.id = -1 self.prev_count = 0 + self.sessionid = "" player = Player() @@ -140,14 +135,15 @@ km = KeyManager() def appendPlayfield(msg): - bgcolor = '#FFF' + bgcolor = '#000' document.body.setAttribute('bgcolor', bgcolor) div = document.createElement("div") div.setAttribute("id", "playfield") div.setAttribute('width', msg['width']) div.setAttribute('height', msg['height']) div.setAttribute('style', 'position:absolute; top:0px; left:0px') - document.body.childNodes.insert(0, div) + #document.body.childNodes.insert(0, div) + document.body.appendChild(div) def appendPlayfieldXXX(): bgcolor = '#000000' @@ -189,6 +185,10 @@ logWarning('unknown message type: ' + msg['type']) +def ignore(arg): + pass +ignore._annspecialcase_ = 'specialize:argtype(0)' + def addPlayer(player_id): name = "player no. " + str(player_id) #name = "player no. %d" % player_id @@ -197,13 +197,11 @@ # NotImplementedError: Type prev_player_id = player.id if player.id >= 0: - #log("removing " + name) - BnbRootInstance.remove_player(player.id, ignore_dispatcher) + exported_methods.remove_player(player.id, player.sessionid, ignore) player.id = -1 if player_id != prev_player_id: - #log("adding " + name) - BnbRootInstance.add_player(player_id, ignore_dispatcher) - BnbRootInstance.player_name(player_id, name, ignore_dispatcher) + exported_methods.player_name(player_id, name, player.sessionid, ignore) + exported_methods.add_player(player_id, player.sessionid, ignore) player.id = player_id @@ -231,32 +229,13 @@ else: logWarning('unknown keyup: ' + str(c)) -def ignore_dispatcher(msgs): - pass +#def ignore_dispatcher(msgs): +# pass def bnb_dispatcher(msgs): - #a = [str(i) for i in q] - #logDebug(str(a)) - BnbRootInstance.get_message(player.id, ":".join([str(i) for i in km.get_keys()]), bnb_dispatcher) - #sm_restart = int(msgs['add_data'][0]['sm_restart']) - #if sm_restart == 123: - # log("sm_restart") - # stats.__init__() - # sm.__init__() - # sm.begin_clean_sprites() - # playfield = document.getElementById("playfield") - # document.body.removeChild(playfield) - # appendPlayfieldXXX() - -## count = int(msgs['add_data'][0]['n']) -## if count != player.prev_count + 1: -## logWarning("incorrect response order, expected " + str(player.prev_count+1) + ' got ' + str(count)) -## sm.frames.append(msgs) -## player.prev_count = count -## #else: - # player.prev_count = count - # for i in sm.frames: - # render_frame(i) + s = ":".join([str(i) for i in km.get_keys()]) + exported_methods.get_message(player.sessionid, player.id, s, + bnb_dispatcher) render_frame(msgs) def render_frame(msgs): @@ -265,22 +244,25 @@ stats.register_frame() document.title = str(stats.n_sprites) + " sprites " + str(stats.fps) -def session_dispatcher(msgs): - BnbRootInstance.get_message(player.id, "", bnb_dispatcher) +def session_dispatcher(sessionid): + player.sessionid = sessionid + document.onkeydown = keydown + document.onkeyup = keyup + exported_methods.get_message(player.sessionid, player.id, "", + bnb_dispatcher) + +def bnb(): + createLoggingPane(True) + log("keys: [0-9] to select player, [wsad] to walk around") + exported_methods.initialize_session(session_dispatcher) -def run_bnb(): - def bnb(): - genjsinfo = document.getElementById("genjsinfo") - document.body.removeChild(genjsinfo) - createLoggingPane(True) - log("keys: [0-9] to select player, [wsad] to walk around") - BnbRootInstance.initialize_session(session_dispatcher) - document.onkeydown = keydown - document.onkeyup = keyup - +def run_bnb(): from pypy.translator.js.demo.jsdemo.bnb import BnbRoot - fn = compile_function(bnb, [], root = BnbRoot, run_browser = False) - fn() + from pypy.translator.js.lib import server + addr = ('', 7070) + httpd = server.create_server(handler=BnbRoot, server_address=addr) + httpd.source = rpython2javascript(sys.modules[__name__], ['bnb']) + httpd.serve_forever() if __name__ == '__main__': run_bnb() From fijal at codespeak.net Wed Feb 14 10:41:38 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 14 Feb 2007 10:41:38 +0100 (CET) Subject: [pypy-svn] r38788 - pypy/dist/pypy/translator/js/demo/jsdemo Message-ID: <20070214094138.6459E100AF@code0.codespeak.net> Author: fijal Date: Wed Feb 14 10:41:37 2007 New Revision: 38788 Modified: pypy/dist/pypy/translator/js/demo/jsdemo/bnb.py pypy/dist/pypy/translator/js/demo/jsdemo/servermessage.py Log: Move out from turbogears (it was not working anyway) Modified: pypy/dist/pypy/translator/js/demo/jsdemo/bnb.py ============================================================================== --- pypy/dist/pypy/translator/js/demo/jsdemo/bnb.py (original) +++ pypy/dist/pypy/translator/js/demo/jsdemo/bnb.py Wed Feb 14 10:41:37 2007 @@ -2,16 +2,15 @@ """ xmlhttp controllers, usefull for testing """ -import turbogears -import cherrypy -from pypy.translator.js.demo.jsdemo.controllers import Root +import py from pypy.rpython.ootypesystem.bltregistry import BasicExternal, MethodDesc from pypy.translator.js.demo.jsdemo.servermessage import log, ServerMessage,\ PMSG_INLINE_FRAME, PMSG_DEF_ICON from pypy.translator.js.demo.jsdemo.msgstruct import * -from cherrypy import session from pypy.rpython.extfunc import _callable +from pypy.translator.js.lib.support import callback +from pypy.translator.js.lib import server import re, time, sys, os, urllib, socket, copy, md5, random @@ -60,7 +59,6 @@ self.positions = copy.deepcopy(self.next_pos) self.next_pos = {} to_ret = [] - #import pdb;pdb.set_trace() for ic, i in self.last_seen - self.seen: self.sprite_sets[ic].append(i) to_ret.append(i) @@ -68,9 +66,7 @@ self.seen = set() return to_ret -# Needed double inheritance for both server job -# and semi-transparent communication proxy -class BnbRoot(Root, BasicExternal): +class ExportedMethods(server.ExportedMethods): _serverMessage = {} _spriteManagers = {} @@ -84,30 +80,18 @@ log("ERROR: Connected to BnB server but unable to detect a running game") sys.exit() port = int(port[7:-1]) - - _render_xmlhttp = True - - _methods = { - 'get_message' : MethodDesc( [('player_id', int), ('keys' , str), ('callback', _callable([{str:[{str:str}]}]))] , {str:[{str:str}]}), - 'add_player' : MethodDesc( [('player_id', int), ('callback', _callable([{str:[{str:str}]}]))] , {str:[{str:str}]}), - 'remove_player': MethodDesc( [('player_id', int), ('callback', _callable([{str:[{str:str}]}]))] , {str:[{str:str}]}), - 'player_name' : MethodDesc( [('player_id', int), ('name', str), ('callback', _callable([{str:[{str:str}]}]))] , {str:[{str:str}]}), -# 'key' : MethodDesc( [('player_id', 0), ('keynum', '0'), ('callback', (lambda : None))] , {'aa':[{'aa':'bb'}]}), - 'initialize_session' : MethodDesc( [('callback', _callable([{str:str}]))], {str:str}), - } - - def add_player(self, player_id = 0): - return dict() - - def serverMessage(self): - self._closeIdleConnections() - sessionid = session['_id'] - if sessionid not in self._serverMessage: - self._serverMessage[sessionid] = ServerMessage('static/images/') - return self._serverMessage[sessionid] - def sessionSocket(self, close=False): - sm = self.serverMessage() + #def _close(self, sessionid): + # if sessionid in self._serverMessage: + # sm = self.serverMessage() + # if sm.socket is not None: + # sm.socket.close() + # del self._serverMessage[sessionid] + def get_sprite_manager(self, sessionid): + return self._spriteManagers[sessionid] + + def sessionSocket(self, sessionid, close=False): + sm = self.serverMessage(sessionid) if sm.socket is None: player_id = 0 #XXX hardcoded for now sm.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) @@ -117,57 +101,10 @@ sm.socket.send(message(CMSG_ENABLE_MUSIC, 0)) #, has_music sm.socket.send(message(CMSG_UDP_PORT, "\\")) #, port sm.socket.send(message(CMSG_PING)) #so server starts sending data - #sm.socket.send(message(CMSG_ADD_PLAYER, player_id)) - #sm.socket.send(message(CMSG_PLAYER_NAME, player_id, 'PyPy')) - #XXX todo: session.socket.close() after a timeout return sm.socket - def get_sprite_manager(self): - sessionid = session['_id'] - return self._spriteManagers[sessionid] - - @turbogears.expose(html="jsdemo.templates.bnb") - def index(self): - return dict(now=time.ctime(), onload=self.jsname, code=self.jssource) - - @turbogears.expose(format='json') - def player_name(self, player_id, name): - log("Changing player #%s name to %s" % (player_id, name)) - self.sessionSocket().send(message(CMSG_PLAYER_NAME, int(player_id), name)) - return dict() - - @turbogears.expose(format='json') - def add_player(self, player_id): - log("Adding player " + player_id) - self.sessionSocket().send(message(CMSG_ADD_PLAYER, int(player_id))) - return dict() - - @turbogears.expose(format='json') - def remove_player(self, player_id): - log("Remove player " + player_id) - self.sessionSocket().send(message(CMSG_REMOVE_PLAYER, int(player_id))) - return dict() - -## @turbogears.expose(format='json') -## def key(self, player_id, keynum): -## self.sessionSocket().send(message(CMSG_KEY, int(player_id), int(keynum))) -## return dict() - - @turbogears.expose(format='json') - def close(self): - self._close() - return dict() - - def _close(self): - sessionid = session['_id'] - if sessionid in self._serverMessage: - sm = self.serverMessage() - if sm.socket is not None: - sm.socket.close() - del self._serverMessage[sessionid] - def _closeIdleConnections(self): - t = time.time() - 5.0 #5 seconds until considered idle + t = time.time() - 20.0 #20 seconds until considered idle for sessionid, sm in self._serverMessage.items(): if sm.last_active < t: log("Close connection with sessionid %s because it was idle for %.1f seconds" % ( @@ -176,23 +113,54 @@ sm.socket.close() del self._serverMessage[sessionid] - @turbogears.expose(format="json") + def serverMessage(self, sessionid): + self._closeIdleConnections() + if sessionid not in self._serverMessage: + self._serverMessage[sessionid] = ServerMessage('data/images') + return self._serverMessage[sessionid] + + @callback(retval=None) + def player_name(self, player_id=0, name="", sessionid=""): + log("Changing player #%s name to %s" % (player_id, name)) + socket = self.sessionSocket(sessionid) + socket.send(message(CMSG_PLAYER_NAME, int(player_id), name)) + + @callback(retval=None) + def add_player(self, player_id=0, sessionid=""): + log("Adding player " + player_id) + socket = self.sessionSocket(sessionid) + socket.send(message(CMSG_ADD_PLAYER, int(player_id))) + + @callback(retval=None) + def remove_player(self, player_id=0, sessionid=""): + log("Remove player " + player_id) + socket = self.sessionSocket(sessionid) + socket.send(message(CMSG_REMOVE_PLAYER, int(player_id))) + + @callback(retval=str) def initialize_session(self): - self._close() - #force new session id to restart a game! - session['_id'] = md5.md5(str(random.random())).hexdigest() - sessionid = session['_id'] - sm = ServerMessage('static/images/') + sessionid = md5.md5(str(random.random())).hexdigest() + self._create_session(sessionid) + return sessionid + + def _create_session(self, sessionid): + sm = ServerMessage('data/images/') self._serverMessage[sessionid] = sm self._spriteManagers[sessionid] = SpriteManager() - return dict() + return sessionid - @turbogears.expose(format="json") - def get_message(self, player_id, keys): + @callback(retval={str:[{str:str}]}) + def get_message(self, sessionid="", player_id=0, keys=""): + """ This one is long, ugly and obscure + """ #XXX hangs if not first sending CMSG_PING! - sm = self.serverMessage() + try: + sm = self.serverMessage(sessionid) + except KeyError: + self._create_session(sessionid) + sm = self.serverMessage(sessionid) data = sm.data - sock = self.sessionSocket() + sock = self.sessionSocket(sessionid) while True: try: data += sock.recv(4096, socket.MSG_DONTWAIT) @@ -216,36 +184,21 @@ else: messages.append(messageOutput) sm.data = data - #log('RECEIVED DATA REMAINING CONTAINS %d BYTES' % len(data)) len_before = len(messages) - #XXX we could do better by not generating only the last inline_frame message anyway! inline_frames = [i for i,msg in enumerate(messages) if msg['type'] == PMSG_INLINE_FRAME] for i in reversed(inline_frames[:-1]): del messages[i] - #if messages: - # log('MESSAGES:lenbefore=%d, inline_frames=%s, lenafter=%d' % ( - # len_before, inline_frames, len(messages))) to_append = [] - sprite_manager = self.get_sprite_manager() + sprite_manager = self.get_sprite_manager(sessionid) sm_restart = 0 - #if inline_frames: - # sm_restart = 1 - # sprite_manager.__init__() - # to_append.append({'type':'begin_clean_sprites'}) - # log("server sm_restart") - - -## def get_full_frame(next): -## new_sprite, s_num = sprite_manager.get_sprite(*next) -## to_append.append({'type':'show_sprite', 's':s_num, 'icon_code':str(next[0]), 'x':str(next[1]), 'y':str(next[2])}) - if player_id != -1: if keys: for i in keys.split(":"): - self.sessionSocket().send(message(CMSG_KEY, int(player_id), int(i))) + self.sessionSocket(sessionid).\ + send(message(CMSG_KEY, int(player_id), int(i))) def get_partial_frame(next, z_num): new_sprite, s_num = sprite_manager.get_sprite(*next) @@ -277,8 +230,35 @@ for i in sprite_manager.end_frame(): to_append.append({'type':'ds', 's':str(i)}) messages += to_append - #messages.append(to_append[0]) - #log(len(messages)) return dict(messages=messages, add_data=[{'n':sm.count(), 'sm_restart':sm_restart}]) -BnbRootInstance = BnbRoot() +exported_methods = ExportedMethods() + +class BnbRoot(server.Handler): + """ BnB server handler + """ + exported_methods = exported_methods + static_dir = py.path.local(__file__).dirpath().join("webdata") + + index = server.Static(static_dir.join("bnb.html")) + images = server.StaticDir("data/images", type="image/png") + + def source_js(self): + return "text/javascript", self.server.source + source_js.exposed = True + + MochiKit = server.StaticDir('MochiKit') + + #@turbogears.expose(format='json') + + #@turbogears.expose(format='json') + +## @turbogears.expose(format='json') +## def key(self, player_id, keynum): +## self.sessionSocket().send(message(CMSG_KEY, int(player_id), int(keynum))) +## return dict() + + #@turbogears.expose(format='json') + def close(self): + self._close() + return dict() Modified: pypy/dist/pypy/translator/js/demo/jsdemo/servermessage.py ============================================================================== --- pypy/dist/pypy/translator/js/demo/jsdemo/servermessage.py (original) +++ pypy/dist/pypy/translator/js/demo/jsdemo/servermessage.py Wed Feb 14 10:41:37 2007 @@ -1,5 +1,3 @@ -from turbogears import controllers, expose -from cherrypy import session from msgstruct import * import PIL.Image from zlib import decompressobj, decompress @@ -38,8 +36,8 @@ _md5_file = {} _bitmap2hexdigits={} _def_icon_queue = {} - base_gfx_dir = 'testme/static/images/' - base_gfx_url = 'static/images/' + base_gfx_dir = 'data/images/' + base_gfx_url = '/images/' gfx_extension = 'png' def __init__(self, base_gfx_dir = None): From fijal at codespeak.net Wed Feb 14 10:47:12 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 14 Feb 2007 10:47:12 +0100 (CET) Subject: [pypy-svn] r38789 - in pypy/dist/pypy/translator/js/lib: . test Message-ID: <20070214094712.5C507100AD@code0.codespeak.net> Author: fijal Date: Wed Feb 14 10:47:11 2007 New Revision: 38789 Modified: pypy/dist/pypy/translator/js/lib/server.py pypy/dist/pypy/translator/js/lib/test/test_url.py pypy/dist/pypy/translator/js/lib/url.py Log: * Minor tweaks around cgiparse problems * allow staticdir to specify content-type Modified: pypy/dist/pypy/translator/js/lib/server.py ============================================================================== --- pypy/dist/pypy/translator/js/lib/server.py (original) +++ pypy/dist/pypy/translator/js/lib/server.py Wed Feb 14 10:47:11 2007 @@ -106,11 +106,15 @@ class StaticDir(object): exposed = True - def __init__(self, path): + def __init__(self, path, type=None): self.path = path + self.type = type def __call__(self, path): - return open(os.path.join(str(self.path), str(path))).read() + data = open(os.path.join(str(self.path), str(path))).read() + if self.type: + return self.type, data + return data def create_server(server_address = ('', 8000), handler=TestHandler, server=HTTPServer): Modified: pypy/dist/pypy/translator/js/lib/test/test_url.py ============================================================================== --- pypy/dist/pypy/translator/js/lib/test/test_url.py (original) +++ pypy/dist/pypy/translator/js/lib/test/test_url.py Wed Feb 14 10:47:11 2007 @@ -7,4 +7,5 @@ assert parse_url("/a/b") == (["a", "b"], {}) assert parse_url("/a/b/c/") == (["a", "b", "c"], {}) assert parse_url("a/b?q=a&c=z") == (["a","b"], {"q":"a", "c":"z"}) - + got = parse_url('/get_message?sid=2ed&pid=-1') + assert got == (["get_message"], {'pid':'-1', 'sid':'2ed'}) Modified: pypy/dist/pypy/translator/js/lib/url.py ============================================================================== --- pypy/dist/pypy/translator/js/lib/url.py (original) +++ pypy/dist/pypy/translator/js/lib/url.py Wed Feb 14 10:47:11 2007 @@ -31,7 +31,14 @@ """ if '?' in path: path, var_str = path.split("?") - vars = cgi.parse_qs(var_str) + vars_orig = cgi.parse_qs(var_str) + # if vars has a list inside... + vars = {} + for i, v in vars_orig.items(): + if isinstance(v, list): + vars[i] = v[0] + else: + vars[i] = v else: vars = {} parts = [urllib.unquote(i) for i in path.split("/") if i] From fijal at codespeak.net Wed Feb 14 10:50:46 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 14 Feb 2007 10:50:46 +0100 (CET) Subject: [pypy-svn] r38790 - pypy/dist/pypy/translator/js/examples/bnb/data Message-ID: <20070214095046.D6390100B5@code0.codespeak.net> Author: fijal Date: Wed Feb 14 10:50:44 2007 New Revision: 38790 Added: pypy/dist/pypy/translator/js/examples/bnb/data/bnb.html Log: html for bnb Added: pypy/dist/pypy/translator/js/examples/bnb/data/bnb.html ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/js/examples/bnb/data/bnb.html Wed Feb 14 10:50:44 2007 @@ -0,0 +1,11 @@ + + + + + Bub'n'bros + + + + + + From fijal at codespeak.net Wed Feb 14 10:51:21 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 14 Feb 2007 10:51:21 +0100 (CET) Subject: [pypy-svn] r38791 - in pypy/dist/pypy/translator/js: demo/jsdemo examples examples/bnb examples/bnb/data/images examples/data/images Message-ID: <20070214095121.EF215100B8@code0.codespeak.net> Author: fijal Date: Wed Feb 14 10:51:20 2007 New Revision: 38791 Added: pypy/dist/pypy/translator/js/examples/bnb/autopath.py - copied unchanged from r38665, pypy/dist/pypy/translator/js/examples/autopath.py pypy/dist/pypy/translator/js/examples/bnb/bnb.py - copied unchanged from r38788, pypy/dist/pypy/translator/js/demo/jsdemo/bnb.py pypy/dist/pypy/translator/js/examples/bnb/data/images/ - copied from r38785, pypy/dist/pypy/translator/js/examples/data/images/ pypy/dist/pypy/translator/js/examples/bnb/servermessage.py - copied unchanged from r38788, pypy/dist/pypy/translator/js/demo/jsdemo/servermessage.py pypy/dist/pypy/translator/js/examples/bnb/start_bnb.py - copied unchanged from r38787, pypy/dist/pypy/translator/js/examples/start_bnb.py Removed: pypy/dist/pypy/translator/js/demo/jsdemo/bnb.py pypy/dist/pypy/translator/js/demo/jsdemo/servermessage.py pypy/dist/pypy/translator/js/examples/data/images/ pypy/dist/pypy/translator/js/examples/start_bnb.py Log: Move bnb to it's own dir From fijal at codespeak.net Wed Feb 14 10:53:52 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 14 Feb 2007 10:53:52 +0100 (CET) Subject: [pypy-svn] r38792 - pypy/dist/pypy/translator/js/examples/bnb Message-ID: <20070214095352.C31F1100BA@code0.codespeak.net> Author: fijal Date: Wed Feb 14 10:53:51 2007 New Revision: 38792 Added: pypy/dist/pypy/translator/js/examples/bnb/__init__.py pypy/dist/pypy/translator/js/examples/bnb/msgstruct.py - copied unchanged from r38665, pypy/dist/pypy/translator/js/demo/jsdemo/msgstruct.py Modified: pypy/dist/pypy/translator/js/examples/bnb/bnb.py pypy/dist/pypy/translator/js/examples/bnb/start_bnb.py Log: Update imports Added: pypy/dist/pypy/translator/js/examples/bnb/__init__.py ============================================================================== Modified: pypy/dist/pypy/translator/js/examples/bnb/bnb.py ============================================================================== --- pypy/dist/pypy/translator/js/examples/bnb/bnb.py (original) +++ pypy/dist/pypy/translator/js/examples/bnb/bnb.py Wed Feb 14 10:53:51 2007 @@ -5,9 +5,9 @@ import py from pypy.rpython.ootypesystem.bltregistry import BasicExternal, MethodDesc -from pypy.translator.js.demo.jsdemo.servermessage import log, ServerMessage,\ +from pypy.translator.js.examples.bnb.servermessage import log, ServerMessage,\ PMSG_INLINE_FRAME, PMSG_DEF_ICON -from pypy.translator.js.demo.jsdemo.msgstruct import * +from pypy.translator.js.examples.bnb.msgstruct import * from pypy.rpython.extfunc import _callable from pypy.translator.js.lib.support import callback from pypy.translator.js.lib import server @@ -238,7 +238,7 @@ """ BnB server handler """ exported_methods = exported_methods - static_dir = py.path.local(__file__).dirpath().join("webdata") + static_dir = py.path.local(__file__).dirpath().join("data") index = server.Static(static_dir.join("bnb.html")) images = server.StaticDir("data/images", type="image/png") Modified: pypy/dist/pypy/translator/js/examples/bnb/start_bnb.py ============================================================================== --- pypy/dist/pypy/translator/js/examples/bnb/start_bnb.py (original) +++ pypy/dist/pypy/translator/js/examples/bnb/start_bnb.py Wed Feb 14 10:53:51 2007 @@ -10,7 +10,7 @@ from pypy.translator.js.modules.dom import document from pypy.translator.js.modules.mochikit import log, logWarning,\ createLoggingPane, logDebug -from pypy.translator.js.demo.jsdemo.bnb import exported_methods +from pypy.translator.js.examples.bnb.bnb import exported_methods import time import os @@ -257,7 +257,7 @@ exported_methods.initialize_session(session_dispatcher) def run_bnb(): - from pypy.translator.js.demo.jsdemo.bnb import BnbRoot + from pypy.translator.js.examples.bnb.bnb import BnbRoot from pypy.translator.js.lib import server addr = ('', 7070) httpd = server.create_server(handler=BnbRoot, server_address=addr) From fijal at codespeak.net Wed Feb 14 10:58:12 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 14 Feb 2007 10:58:12 +0100 (CET) Subject: [pypy-svn] r38793 - pypy/dist/pypy/translator/js/examples Message-ID: <20070214095812.67F99100AB@code0.codespeak.net> Author: fijal Date: Wed Feb 14 10:58:11 2007 New Revision: 38793 Modified: pypy/dist/pypy/translator/js/examples/overmind.py Log: don't interfere with default b'n'b port Modified: pypy/dist/pypy/translator/js/examples/overmind.py ============================================================================== --- pypy/dist/pypy/translator/js/examples/overmind.py (original) +++ pypy/dist/pypy/translator/js/examples/overmind.py Wed Feb 14 10:58:11 2007 @@ -62,7 +62,9 @@ if __name__ == '__main__': try: - server.create_server(handler=Handler).serve_forever() + addr = ('', 8008) + httpd = server.create_server(server_address=addr, handler=Handler) + httpd.serve_forever() except KeyboardInterrupt: for pid in pids: # eventually os.kill stuff From ac at codespeak.net Wed Feb 14 11:34:19 2007 From: ac at codespeak.net (ac at codespeak.net) Date: Wed, 14 Feb 2007 11:34:19 +0100 (CET) Subject: [pypy-svn] r38794 - pypy/dist/pypy/module/_codecs/test Message-ID: <20070214103419.9EE2910079@code0.codespeak.net> Author: ac Date: Wed Feb 14 11:34:18 2007 New Revision: 38794 Modified: pypy/dist/pypy/module/_codecs/test/test_codecs.py Log: Mixed case unicode character names shoudl be supported. Modified: pypy/dist/pypy/module/_codecs/test/test_codecs.py ============================================================================== --- pypy/dist/pypy/module/_codecs/test/test_codecs.py (original) +++ pypy/dist/pypy/module/_codecs/test/test_codecs.py Wed Feb 14 11:34:18 2007 @@ -34,7 +34,6 @@ raises( UnicodeDecodeError, unicode,'\\NSPACE}','unicode-escape') raises( UnicodeDecodeError, unicode,'\\NSPACE','unicode-escape') raises( UnicodeDecodeError, unicode,'\\N','unicode-escape') - raises( UnicodeDecodeError, unicode,'\\N{SpaCE}','unicode-escape') assert unicode('\\N{SPACE}\\N{SPACE}','unicode-escape') == u" " assert unicode('\\N{SPACE}a\\N{SPACE}','unicode-escape') == u" a " assert "\\N{foo}xx".decode("unicode-escape", "ignore") == u"xx" From adim at codespeak.net Wed Feb 14 11:53:29 2007 From: adim at codespeak.net (adim at codespeak.net) Date: Wed, 14 Feb 2007 11:53:29 +0100 (CET) Subject: [pypy-svn] r38796 - in pypy/branch/ast-experiments/pypy: interpreter/pyparser module/recparser Message-ID: <20070214105329.CB44D1007C@code0.codespeak.net> Author: adim Date: Wed Feb 14 11:53:28 2007 New Revision: 38796 Modified: pypy/branch/ast-experiments/pypy/interpreter/pyparser/astbuilder.py pypy/branch/ast-experiments/pypy/interpreter/pyparser/pythonparse.py pypy/branch/ast-experiments/pypy/module/recparser/__init__.py pypy/branch/ast-experiments/pypy/module/recparser/pyparser.py Log: small rpython fixes Modified: pypy/branch/ast-experiments/pypy/interpreter/pyparser/astbuilder.py ============================================================================== --- pypy/branch/ast-experiments/pypy/interpreter/pyparser/astbuilder.py (original) +++ pypy/branch/ast-experiments/pypy/interpreter/pyparser/astbuilder.py Wed Feb 14 11:53:28 2007 @@ -579,8 +579,10 @@ nodes = [] # remove '@', '(' and ')' from atoms and use parse_attraccess for token in atoms[1:]: - if isinstance(token, TokenObject) and \ - token.name in (builder.parser.tokens['LPAR'], builder.parser.tokens['RPAR'], builder.parser.tokens['NEWLINE']): + if isinstance(token, TokenObject) and ( + token.name == builder.parser.tokens['LPAR'] + or token.name == builder.parser.tokens['RPAR'] + or token.name == builder.parser.tokens['NEWLINE']): # skip those ones continue else: @@ -1179,7 +1181,6 @@ def is_string_const(self, expr): if not isinstance(expr,ast.Const): return False - print 'IS STRING CONST', repr(expr.value) space = self.space return space.is_true(space.isinstance(expr.value,space.w_str)) Modified: pypy/branch/ast-experiments/pypy/interpreter/pyparser/pythonparse.py ============================================================================== --- pypy/branch/ast-experiments/pypy/interpreter/pyparser/pythonparse.py (original) +++ pypy/branch/ast-experiments/pypy/interpreter/pyparser/pythonparse.py Wed Feb 14 11:53:28 2007 @@ -196,13 +196,6 @@ # PYTHON_PARSER = make_pyparser() ## XXX BROKEN -## def grammar_rules( space ): -## w_rules = space.newdict() -## for key, value in PYTHON_PARSER.rules.iteritems(): -## space.setitem(w_rules, space.wrap(key), space.wrap(value)) -## return w_rules -## -## ## def parse_grammar(space, w_src): ## """Loads the grammar using the 'dynamic' rpython parser""" ## src = space.str_w( w_src ) @@ -210,3 +203,10 @@ ## ebnfbuilder.resolve_rules() ## grammar.build_first_sets(ebnfbuilder.all_rules) ## return space.wrap( ebnfbuilder.root_rules ) + +def grammar_rules( space ): + w_rules = space.newdict() + parser = make_pyparser() + for key, value in parser.rules.iteritems(): + space.setitem(w_rules, space.wrap(key), space.wrap(value)) + return w_rules Modified: pypy/branch/ast-experiments/pypy/module/recparser/__init__.py ============================================================================== --- pypy/branch/ast-experiments/pypy/module/recparser/__init__.py (original) +++ pypy/branch/ast-experiments/pypy/module/recparser/__init__.py Wed Feb 14 11:53:28 2007 @@ -48,7 +48,6 @@ 'decode_string_literal': 'pyparser.decode_string_literal', 'install_compiler_hook' : 'pypy.interpreter.pycompiler.install_compiler_hook', 'insert_grammar_rule' : 'pypy.interpreter.pycompiler.insert_grammar_rule', - #'rules' : 'pypy.interpreter.pyparser.pythonparse.grammar_rules', #'parse_grammar' : 'pypy.interpreter.pyparser.pythonparse.parse_grammar', } Modified: pypy/branch/ast-experiments/pypy/module/recparser/pyparser.py ============================================================================== --- pypy/branch/ast-experiments/pypy/module/recparser/pyparser.py (original) +++ pypy/branch/ast-experiments/pypy/module/recparser/pyparser.py Wed Feb 14 11:53:28 2007 @@ -51,8 +51,10 @@ if node.value is not None: val = node.value else: - if num not in ( tokens['NEWLINE'], tokens['INDENT'], - tokens['DEDENT'], tokens['ENDMARKER'] ): + if num != tokens['NEWLINE'] and \ + num != tokens['INDENT'] and \ + num != tokens['DEDENT'] and \ + num != tokens['ENDMARKER']: val = space.default_compiler.parser.tok_rvalues[num] else: val = node.value or '' From xoraxax at codespeak.net Wed Feb 14 12:21:33 2007 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Wed, 14 Feb 2007 12:21:33 +0100 (CET) Subject: [pypy-svn] r38803 - pypy/extradoc/sprintinfo/trillke-2007 Message-ID: <20070214112133.942D710086@code0.codespeak.net> Author: xoraxax Date: Wed Feb 14 12:21:31 2007 New Revision: 38803 Modified: pypy/extradoc/sprintinfo/trillke-2007/people.txt Log: Added myself to the sprint's people list. Modified: pypy/extradoc/sprintinfo/trillke-2007/people.txt ============================================================================== --- pypy/extradoc/sprintinfo/trillke-2007/people.txt (original) +++ pypy/extradoc/sprintinfo/trillke-2007/people.txt Wed Feb 14 12:21:31 2007 @@ -22,6 +22,7 @@ Anders Chrigstr?m 25th-5th TBD Christian Tismer 28th-5th Klocke Alix Einfeldt 25th-5th private +Alexander Schremmer 1st-5th no idea ==================== ============== ===================== People on the following list were present at previous sprints: @@ -32,7 +33,6 @@ Christian Tismer ? ? Anders Lehmann ? ? Niklaus Haldimann ? ? -Lene Wagner ? ? Amaury Forgeot d'Arc ? ? Valentino Volonghi ? ? Boris Feigin ? ? @@ -40,7 +40,5 @@ Bert Freudenberg ? ? Richard Emslie ? ? Johan Hahn ? ? -Stephan Diehl ? ? Niko Matsakis ? ? -Alexander Schremmer ? ? ==================== ============== ===================== From mwh at codespeak.net Wed Feb 14 12:47:49 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Wed, 14 Feb 2007 12:47:49 +0100 (CET) Subject: [pypy-svn] r38804 - pypy/dist/lib-python/modified-2.4.1/test Message-ID: <20070214114749.F401610074@code0.codespeak.net> Author: mwh Date: Wed Feb 14 12:47:49 2007 New Revision: 38804 Modified: pypy/dist/lib-python/modified-2.4.1/test/test_descr.py Log: remove function level imports of gc now it's imported at module level. 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 Wed Feb 14 12:47:49 2007 @@ -1193,7 +1193,6 @@ gc.collect() vereq(Counted.counter, 1) s = None - import gc gc.collect() gc.collect() gc.collect() @@ -2962,7 +2961,6 @@ raise TestFailed, "d.foo should be undefined now" # Test a nasty bug in recurse_down_subclasses() - import gc class A(object): pass class B(A): @@ -3895,7 +3893,7 @@ vereq(c.attr, 1) # this makes a crash more likely: - import gc; gc.collect() + gc.collect() vereq(hasattr(c, 'attr'), False) import warnings From cfbolz at codespeak.net Wed Feb 14 13:27:49 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 14 Feb 2007 13:27:49 +0100 (CET) Subject: [pypy-svn] r38814 - in pypy/dist/pypy/config: . test Message-ID: <20070214122749.0A87B10081@code0.codespeak.net> Author: cfbolz Date: Wed Feb 14 13:27:47 2007 New Revision: 38814 Modified: pypy/dist/pypy/config/makerestdoc.py pypy/dist/pypy/config/test/test_makerestdoc.py Log: add the doc lines into the tree Modified: pypy/dist/pypy/config/makerestdoc.py ============================================================================== --- pypy/dist/pypy/config/makerestdoc.py (original) +++ pypy/dist/pypy/config/makerestdoc.py Wed Feb 14 13:27:47 2007 @@ -1,6 +1,6 @@ import py from py.__.rest.rst import Rest, Paragraph, Strong, ListItem, Title, Link -from py.__.rest.rst import Directive +from py.__.rest.rst import Directive, Em from pypy.config.config import ChoiceOption, BoolOption, StrOption, IntOption from pypy.config.config import FloatOption, OptionDescription, Option, Config @@ -140,13 +140,20 @@ stack = [] prefix = fullpath curr = content - for subpath in self.getpaths(include_groups=True): - subpath = fullpath + "." + subpath + config = Config(self) + for ending in self.getpaths(include_groups=True): + subpath = fullpath + "." + ending while not (subpath.startswith(prefix) and subpath[len(prefix)] == "."): curr, prefix = stack.pop() - print subpath, fullpath, curr - new = curr.add(ListItem(Link(subpath, subpath + ".html"))) + print subpath, fullpath, ending, curr + sub, step = config._cfgimpl_get_home_by_path(ending) + doc = getattr(sub._cfgimpl_descr, step).doc + if doc: + new = curr.add(ListItem(Link(subpath + ":", subpath + ".html"), + Em(doc))) + else: + new = curr.add(ListItem(Link(subpath + ":", subpath + ".html"))) stack.append((curr, prefix)) prefix = subpath curr = new Modified: pypy/dist/pypy/config/test/test_makerestdoc.py ============================================================================== --- pypy/dist/pypy/config/test/test_makerestdoc.py (original) +++ pypy/dist/pypy/config/test/test_makerestdoc.py Wed Feb 14 13:27:47 2007 @@ -14,14 +14,16 @@ def generate_html(descr): config = Config(descr) txt = descr.make_rest_doc().text() - checkrest(txt, descr._name + ".txt") + + result = {"": checkrest(txt, descr._name + ".txt")} for path in config.getpaths(include_groups=True): subconf, step = config._cfgimpl_get_home_by_path(path) fullpath = (descr._name + "." + path) prefix = fullpath.rsplit(".", 1)[0] txt = getattr(subconf._cfgimpl_descr, step).make_rest_doc( prefix).text() - checkrest(txt, fullpath + ".txt") + result[path] = checkrest(txt, fullpath + ".txt") + return result def test_simple(): descr = OptionDescription("foo", "doc", [ @@ -60,6 +62,8 @@ requires=[("a0.bar", "c"), ("a0.B2", True)]), ChoiceOption("bar", "more doc", ["a", "b", "c"], default="a")]) - generate_html(descr) + result = generate_html(descr) + assert "more doc" in result[""] + From arigo at codespeak.net Wed Feb 14 14:04:17 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 14 Feb 2007 14:04:17 +0100 (CET) Subject: [pypy-svn] r38823 - pypy/dist/pypy/doc Message-ID: <20070214130417.7F03510081@code0.codespeak.net> Author: arigo Date: Wed Feb 14 14:04:13 2007 New Revision: 38823 Modified: pypy/dist/pypy/doc/rlib.txt Log: Explain what's the difference between the socket and rsocket APIs. Modified: pypy/dist/pypy/doc/rlib.txt ============================================================================== --- pypy/dist/pypy/doc/rlib.txt (original) +++ pypy/dist/pypy/doc/rlib.txt Wed Feb 14 14:04:13 2007 @@ -139,7 +139,11 @@ =========== The rsocket_ module contains an RPython implementation of the functionality of -the socket standard library with a slightly different interface. +the socket standard library with a slightly different interface. The +difficulty with the Python socket API is that addresses are not "well-typed" +objects: dependending on the address family they are tuples, or strings, and +so on, which is not suitable for RPython. Instead, ``rsocket`` contains +a hierarchy of Address classes, in a typical static-OO-programming style. .. _rsocket: ../../pypy/rlib/rsocket.py From cfbolz at codespeak.net Wed Feb 14 14:37:48 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 14 Feb 2007 14:37:48 +0100 (CET) Subject: [pypy-svn] r38826 - in pypy/dist/pypy/doc: . config Message-ID: <20070214133748.0BDB510082@code0.codespeak.net> Author: cfbolz Date: Wed Feb 14 14:37:46 2007 New Revision: 38826 Modified: pypy/dist/pypy/doc/config/confrest.py pypy/dist/pypy/doc/config/objspace.lowmem.txt pypy/dist/pypy/doc/config/translation.gc.txt pypy/dist/pypy/doc/conftest.py Log: - document two more options - change conftest to register a :config:`...` link role that will produce a link to a configuration description page Modified: pypy/dist/pypy/doc/config/confrest.py ============================================================================== --- pypy/dist/pypy/doc/config/confrest.py (original) +++ pypy/dist/pypy/doc/config/confrest.py Wed Feb 14 14:37:46 2007 @@ -42,6 +42,7 @@ fullpath.split(".", 1)[1]) descr = getattr(subconf._cfgimpl_descr, step) text = unicode(descr.make_rest_doc(path).text()) + text += "\nDescription\n===========" if txtpath.check(file=True): return u"%s\n\n%s" % (text, unicode(txtpath.read(), encoding)) return text Modified: pypy/dist/pypy/doc/config/objspace.lowmem.txt ============================================================================== --- pypy/dist/pypy/doc/config/objspace.lowmem.txt (original) +++ pypy/dist/pypy/doc/config/objspace.lowmem.txt Wed Feb 14 14:37:46 2007 @@ -0,0 +1,4 @@ +Try to use as little memory as possible *during translation*. Currently only +disables geninterp_ which also makes the resulting binary slower. + +.. _geninterp: objspace.geninterp.html Modified: pypy/dist/pypy/doc/config/translation.gc.txt ============================================================================== --- pypy/dist/pypy/doc/config/translation.gc.txt (original) +++ pypy/dist/pypy/doc/config/translation.gc.txt Wed Feb 14 14:37:46 2007 @@ -0,0 +1,15 @@ +Choose the Garbage Collector used by the translated program: + + - "ref": reference counting. Takes very long to translate and the result is + slow. + + - "framework": our custom mark-and-sweep collector. Takes moderately long and + is the fastest option without external dependencies. + + - "stacklessgc": same as "framework" but uses a different method to find the + garbage collection roots on the stack, by unwinding it, using stackless: + :config:`translation.stackless`. + + - "boehm": use the Boehm conservative GC + + Modified: pypy/dist/pypy/doc/conftest.py ============================================================================== --- pypy/dist/pypy/doc/conftest.py (original) +++ pypy/dist/pypy/doc/conftest.py Wed Feb 14 14:37:46 2007 @@ -1,5 +1,8 @@ import py from py.__.doc.conftest import Directory, DoctestText, ReSTChecker +from py.__.rest.directive import register_linkrole + +thisdir = py.magic.autopath().dirpath() Option = py.test.config.Option option = py.test.config.addoptions("pypy-doc options", @@ -41,3 +44,33 @@ class Directory(Directory): ReSTChecker = PyPyReSTChecker + +try: + from docutils.parsers.rst import directives, states, roles +except ImportError: + pass +else: + # enable :config: link role + def config_role(name, rawtext, text, lineno, inliner, options={}, + content=[]): + from docutils import nodes + txt = thisdir.join("config", text + ".txt") + html = thisdir.join("config", text + ".html") + assert txt.check() + assert name == "config" + sourcedir = py.path.local(inliner.document.settings._source).dirpath() + curr = sourcedir + prefix = "" + while 1: + relative = str(html.relto(curr)) + if relative: + break + curr = curr.dirpath() + prefix += "../" + target = prefix + relative + print text, target + reference_node = nodes.reference(rawtext, text, name=text, refuri=target) + return [reference_node], [] + config_role.content = True + config_role.options = {} + roles.register_canonical_role("config", config_role) From cfbolz at codespeak.net Wed Feb 14 14:54:59 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 14 Feb 2007 14:54:59 +0100 (CET) Subject: [pypy-svn] r38827 - pypy/dist/pypy/doc Message-ID: <20070214135459.9144E10082@code0.codespeak.net> Author: cfbolz Date: Wed Feb 14 14:54:58 2007 New Revision: 38827 Modified: pypy/dist/pypy/doc/faq.txt Log: faq item Modified: pypy/dist/pypy/doc/faq.txt ============================================================================== --- pypy/dist/pypy/doc/faq.txt (original) +++ pypy/dist/pypy/doc/faq.txt Wed Feb 14 14:54:58 2007 @@ -20,15 +20,26 @@ XXX -------------------------------------------------------------------- -What is the status of the project? Can it be used in practice yet? -------------------------------------------------------------------- +----------------------------------- +What is the status of the project? +----------------------------------- + +XXX status + + +-------------------------------- + Can it be used in practice yet? +-------------------------------- -PyPy is a very broad project with varying level of a completion among -parts. For example compiler toolchain is a relatively mature part, -which is known of running several other projects (see: XXX). +PyPy is a very broad project and its various parts have different levels of +maturity and of general applicability. For example our compiler toolchain is a +relatively mature part and can be used in practice already (see the faq about +`prolog and javascript`_). The Python interpreter that we have written is still +slightly `slower than CPython`_ and not yet a `drop in replacement`_. +In any case, our pygame graph viewer is *extremely* useful already! -XXX finish that one + +.. _`drop in replacement`: ----------------------------------------- Is PyPy a drop in replacement of CPython? @@ -116,6 +127,9 @@ XXX + +.. _`slower than CPython`: + ----------------- How fast is PyPy? ----------------- @@ -127,10 +141,12 @@ a factor of 2000. The first translated version was roughly 300 times slower than CPython. In later versions, we increased the speed. CPython was about 10-20 times as fast as version 0.8.0, 4-7 times as fast as version 0.9 and -2.4 - 5 times as fast as the current version (1.0). +2.4 - 5 times as fast as the current version (0.99). Note that the speed heavily depends on the enabled options at compile time. +.. _`prolog and javascript`: + ----------------------------------------------------------------------- What is this talk about a JavaScript and a Prolog interpreter in PyPy? ----------------------------------------------------------------------- From arigo at codespeak.net Wed Feb 14 15:05:10 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 14 Feb 2007 15:05:10 +0100 (CET) Subject: [pypy-svn] r38829 - in pypy: dist/pypy/doc extradoc/planning/1.0 Message-ID: <20070214140510.51BB91007C@code0.codespeak.net> Author: arigo Date: Wed Feb 14 15:05:08 2007 New Revision: 38829 Modified: pypy/dist/pypy/doc/_ref.txt pypy/dist/pypy/doc/index.txt pypy/extradoc/planning/1.0/documentation.txt Log: Reviewed the directory cross-reference. Modified: pypy/dist/pypy/doc/_ref.txt ============================================================================== --- pypy/dist/pypy/doc/_ref.txt (original) +++ pypy/dist/pypy/doc/_ref.txt Wed Feb 14 15:05:08 2007 @@ -11,6 +11,7 @@ .. _`bin/`: ../../pypy/bin .. _`config/`: ../../pypy/config .. _`doc/`: ../../pypy/doc +.. _`doc/config/`: ../../pypy/doc/config .. _`doc/discussion/`: ../../pypy/doc/discussion .. _`interpreter/`: .. _`pypy/interpreter`: ../../pypy/interpreter @@ -32,6 +33,7 @@ .. _`jit/`: ../../pypy/jit .. _`jit/codegen/`: ../../pypy/jit/codegen .. _`pypy/jit/codegen/model.py`: ../../pypy/jit/codegen/model.py +.. _`jit/goal/`: ../../pypy/jit/goal .. _`jit/hintannotator/`: ../../pypy/jit/hintannotator .. _`jit/timeshifter/`: ../../pypy/jit/timeshifter .. _`pypy/jit/timeshifter/rvalue.py`: ../../pypy/jit/timeshifter/rvalue.py @@ -41,8 +43,9 @@ .. _`lang/prolog/`: ../../pypy/lang/prolog .. _`lib/`: .. _`pypy/lib/`: ../../pypy/lib +.. _`lib/app_test/`: ../../pypy/lib/app_test +.. _`lib/distributed/`: ../../pypy/lib/distributed .. _`pypy/lib/stackless.py`: ../../pypy/lib/stackless.py -.. _`lib/test2/`: .. _`pypy/lib/test2`: ../../pypy/lib/test2 .. _`module/`: .. _`pypy/module`: @@ -56,6 +59,7 @@ .. _`pypy/module/readline`: ../../pypy/module/readline .. _`objspace/`: .. _`pypy/objspace`: ../../pypy/objspace +.. _`objspace/cpy/`: .. _`pypy/objspace/cpy`: ../../pypy/objspace/cpy .. _`objspace/dump.py`: ../../pypy/objspace/dump.py .. _`objspace/flow/`: ../../pypy/objspace/flow @@ -69,7 +73,6 @@ .. _`pypy/objspace/trace.py`: ../../pypy/objspace/trace.py .. _`pypy/rlib`: .. _`rlib/`: ../../pypy/rlib -.. _`pypy/rlib/objectmodel.py`: ../../pypy/rlib/objectmodel.py .. _`pypy/rlib/rarithmetic.py`: ../../pypy/rlib/rarithmetic.py .. _`pypy/rlib/rctypes/rctypesobject.py`: ../../pypy/rlib/rctypes/rctypesobject.py .. _`pypy/rlib/rctypes/test/test_rctypesobject.py`: ../../pypy/rlib/rctypes/test/test_rctypesobject.py @@ -83,10 +86,6 @@ .. _`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 -.. _`pypy/rpython/memory/simulator.py`: ../../pypy/rpython/memory/simulator.py -.. _`pypy/rpython/memory/support.py`: ../../pypy/rpython/memory/support.py .. _`pypy/rpython/module/`: ../../pypy/rpython/module .. _`pypy/rpython/module/ll_os.py`: ../../pypy/rpython/module/ll_os.py .. _`pypy/rpython/module/test`: ../../pypy/rpython/module/test @@ -102,7 +101,6 @@ .. _`tool/`: ../../pypy/tool .. _`tool/algo/`: ../../pypy/tool/algo .. _`tool/pytest/`: ../../pypy/tool/pytest -.. _`tool/tb_server/`: ../../pypy/tool/tb_server .. _`pypy/translator`: .. _`translator/`: ../../pypy/translator .. _`translator/backendopt/`: ../../pypy/translator/backendopt Modified: pypy/dist/pypy/doc/index.txt ============================================================================== --- pypy/dist/pypy/doc/index.txt (original) +++ pypy/dist/pypy/doc/index.txt Wed Feb 14 15:05:08 2007 @@ -170,8 +170,12 @@ `doc/`_ text versions of PyPy developer documentation +`doc/config/`_ documentation for the numerous translation options + `doc/discussion/`_ drafts of ideas and documentation +``doc/*/`` other specific documentation topics or tools + `interpreter/`_ `bytecode interpreter`_ and related objects (frames, functions, modules,...) @@ -184,6 +188,8 @@ `jit/codegen/`_ `jit backends`_ for different architectures +`jit/goal/`_ the translation targets that produce a PyPy with a JIT_ + `jit/hintannotator/`_ the `hint-annotator`_ that analyzes an interpreter `jit/timeshifter/`_ the `timeshifter`_ that turns an interpreter into a JIT compiler @@ -200,12 +206,14 @@ `lib/`_ PyPy's wholesale reimplementations of CPython modules_ and experimental new application-level modules -`lib/test2/`_ tests running at interp-level against the reimplementations +`lib/app_test/`_ tests for the reimplementations, running on top of CPython + +`lib/distributed/`_ distributed execution prototype, based on `transparent proxies`_ `module/`_ contains `mixed modules`_ implementing core modules with both application and interpreter level code. Not all are finished and working. Use the ``--withmod-xxx`` - options of `translate.py`_. + or ``--allworkingmodules`` translation options. `objspace/`_ `object space`_ implementations @@ -220,11 +228,13 @@ `objspace/logic.py`_ the `logic object space`_, providing Prolog-like logic variables +`objspace/cpy/`_ an object space supporting the `extension compiler`_ + `objspace/flow/`_ the FlowObjSpace_ implementing `abstract interpretation` `objspace/std/`_ the StdObjSpace_ implementing CPython's objects and types -`rlib/`_ a "standard library" for RPython_ programs +`rlib/`_ a `"standard library"`_ for RPython_ programs `rpython/`_ the `RPython Typer`_ @@ -232,8 +242,7 @@ `rpython/ootypesystem/`_ the `object-oriented type system`_ for OO backends -`rpython/memory/`_ experimental garbage collector construction - framework +`rpython/memory/`_ the garbage collector construction framework `tool/`_ various utilities and hacks used from various places @@ -242,17 +251,12 @@ `tool/pytest/`_ support code for our `testing methods`_ -`tool/tb_server/`_ a somewhat outdated http-server for presenting - tracebacks in a helpful manner - `translator/`_ translation_ backends and support code `translator/backendopt/`_ general optimizations that run before a backend generates code `translator/c/`_ the `GenC backend`_, producing C code from an - RPython program (generally via the RTyper) - -`translator/lisp/`_ the `Common Lisp backend`_ (incomplete) + RPython program (generally via the rtyper_) `translator/cli/`_ the `CLI backend`_ for `.NET`_ (Microsoft CLR or Mono_) @@ -262,6 +266,8 @@ `translator/jvm/`_ the Java backend (in-progress) +`translator/lisp/`_ the `Common Lisp backend`_ (incomplete) + `translator/llvm/`_ contains the `LLVM backend`_ producing LLVM assembler from fully annotated RPython programs @@ -269,7 +275,8 @@ `translator/stackless/`_ the `Stackless Transform`_ -`translator/tool/`_ helper tools for translation +`translator/tool/`_ helper tools for translation, including the Pygame + `graph viewer`_ ``*/test/`` many directories have a test subdirectory containing test modules (see `Testing in PyPy`_) @@ -291,6 +298,7 @@ .. _`taint object space`: objspace-proxies.html#taint .. _`thunk object space`: objspace-proxies.html#thunk .. _`logic object space`: objspace-proxies.html#logic +.. _`transparent proxies`: objspace-proxies.html#tproxy .. _`What PyPy can do for your objects`: objspace-proxies.html .. _`Stackless and coroutines`: stackless.html .. _StdObjSpace: objspace.html#the-standard-object-space @@ -308,6 +316,7 @@ .. _`extension compiler`: extcompiler.html .. _`py.py`: getting-started.html#main-entry-point .. _`translatorshell.py`: getting-started.html#try-out-the-translator +.. _JIT: jit.html .. _`JIT Generation in PyPy`: jit.html .. _`just-in-time compiler generator`: jit.html .. _`jit backends`: jit.html#backends @@ -321,6 +330,8 @@ .. _`translate.py`: getting-started.html#translating-the-pypy-interpreter .. _`.NET`: http://www.microsoft.com/net/ .. _Mono: http://www.mono-project.com/ +.. _`"standard library"`: rlib.html +.. _`graph viewer`: getting-started.html#try-out-the-translator .. include:: _ref.txt Modified: pypy/extradoc/planning/1.0/documentation.txt ============================================================================== --- pypy/extradoc/planning/1.0/documentation.txt (original) +++ pypy/extradoc/planning/1.0/documentation.txt Wed Feb 14 15:05:08 2007 @@ -2,7 +2,7 @@ ================================ -index.txt: review the directory cross-reference (arigo) +index.txt: review the directory cross-reference (done) config pages, for all the options. From cfbolz at codespeak.net Wed Feb 14 15:06:09 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 14 Feb 2007 15:06:09 +0100 (CET) Subject: [pypy-svn] r38830 - pypy/dist/pypy/doc Message-ID: <20070214140609.AFBDC10088@code0.codespeak.net> Author: cfbolz Date: Wed Feb 14 15:06:08 2007 New Revision: 38830 Modified: pypy/dist/pypy/doc/object-optimizations.txt Log: add a lot of config links Modified: pypy/dist/pypy/doc/object-optimizations.txt ============================================================================== --- pypy/dist/pypy/doc/object-optimizations.txt (original) +++ pypy/dist/pypy/doc/object-optimizations.txt Wed Feb 14 15:06:08 2007 @@ -31,6 +31,8 @@ perform repeated string additions in a loop without using the ``"".join(list_of_strings)`` pattern. +You can this feature enable with the :config:`objspace.std.withstrjoin` option. + string-slice objects -------------------- @@ -46,6 +48,8 @@ string. There is also a minimum number of characters below which being lazy is not saving any time over making the copy). +You can this feature enable with the :config:`objspace.std.withstrslice` option. + Integer optimizations ===================== @@ -57,6 +61,7 @@ time a new integer object is created it is checked whether the integer is small enough to be retrieved from the cache. +You can enable this feature with the :config:`objspace.std.withsmallint` option. integers as tagged pointers --------------------------- @@ -82,6 +87,8 @@ the whole information in the string-keyed dictionary is copied over into another RPython-dictionary, where arbitrary Python objects can be used as keys. +You can enable this feature with the :config:`objspace.std.withstrdict` option. + multi-dicts ----------- @@ -98,6 +105,9 @@ general representation that can store arbitrary keys). In addition there are more specialized dictionary implementations for various purposes (see below). +You can enable this feature with the :config:`objspace.std.withmultidict` +option. + sharing dicts ------------- @@ -116,6 +126,9 @@ dicts: the representation of the instance dict contains only a list of values. +You can enable this feature with the :config:`objspace.std.withsharingdict` +option. + builtin-shadowing ----------------- @@ -140,6 +153,10 @@ common case, the program didn't do any of these; the proper builtin can then be called without using any dictionary lookup at all. +You can enable this feature with the +:config:`objspace.opcodes.CALL_LIKELY_BUILTIN` option. + + List optimizations ================== @@ -155,6 +172,8 @@ created. This gives the memory and speed behaviour of ``xrange`` and the generality of use of ``range``, and makes ``xrange`` essentially useless. +You can enable this feature with the :config:`objspace.std.withrangelist` +option. multi-lists ----------- @@ -167,6 +186,9 @@ implement the same optimization is that range lists came earlier and that multi-lists are not tested that much so far). +You can enable this feature with the :config:`objspace.std.withmultilist` +option. + fast list slicing ------------------ @@ -178,6 +200,8 @@ list slice is only created lazily, that is when either the original list or the sliced list is mutated. +You can enable this feature with the :config:`objspace.std.withfastslice` +option. .. _`Neal Norwitz on pypy-dev`: http://codespeak.net/pipermail/pypy-dev/2005q4/002538.html @@ -199,6 +223,9 @@ shadowing the class attribute. If we know that there is no shadowing (since instance dict tells us that) we can save this lookup on the instance dictionary. +You can enable this feature with the :config:`objspace.std.withshadowtracking` +option. + Method caching -------------- @@ -212,3 +239,6 @@ lookup happens (this version is incremented every time the type or one of its base classes is changed). On subsequent lookups the cached version can be used, as long as the instance did not shadow any of its classes attributes. + +You can enable this feature with the :config:`objspace.std.withmethodcache` +option. From cfbolz at codespeak.net Wed Feb 14 15:38:09 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 14 Feb 2007 15:38:09 +0100 (CET) Subject: [pypy-svn] r38838 - pypy/dist/pypy/doc Message-ID: <20070214143809.7313F10089@code0.codespeak.net> Author: cfbolz Date: Wed Feb 14 15:38:08 2007 New Revision: 38838 Modified: pypy/dist/pypy/doc/objspace-proxies.txt Log: add link to config options Modified: pypy/dist/pypy/doc/objspace-proxies.txt ============================================================================== --- pypy/dist/pypy/doc/objspace-proxies.txt (original) +++ pypy/dist/pypy/doc/objspace-proxies.txt Wed Feb 14 15:38:08 2007 @@ -32,6 +32,9 @@ regular built-in objects (list objects, traceback objects, etc.), but completely under the control of the application. +Which object space to use can be chosen with :config:`objspace.name` option. + +.. _`Object Space`: objspace.html .. _thunk: @@ -451,15 +454,17 @@ Among the unique features of PyPy, there is as well the possibility of having multiple implementations of builtin types. Multiple performance -optimisations using this features are already implemented, some -hints are in the `Object Space`_ document. +optimisations using this features are already implemented, see the document +about `alternative object implementations`_. Transparent proxy are implementations of some (maybe all at some point) objects like functions, objects, lists etc. which forwards all operations performed on these object to app-level functions which have specific signatures. -.. _`Object Space`: objspace.html#object-types +To enable them, use the :config:`objspace.std.withtproxy` option. + +.. _`alternative object implementations`: object-optimizations.html Example: --------- @@ -541,8 +546,8 @@ frames. .. _`standard object space`: objspace.html#the-standard-object-space -.. _`proxy_helpers.py`: http://codespeak.net/svn/pypy/dist/pypy/objspace/std/proxy_helpers.py -.. _`proxyobject.py`: http://codespeak.net/svn/pypy/dist/pypy/objspace/std/proxyobject.py -.. _`transparent.py`: http://codespeak.net/svn/pypy/dist/pypy/objspace/std/transparent.py +.. _`proxy_helpers.py`: ../../pypy/objspace/std/proxy_helpers.py +.. _`proxyobject.py`: ../../pypy/objspace/std/proxyobject.py +.. _`transparent.py`: ../../pypy/objspace/std/transparent.py .. include:: _ref.txt From fijal at codespeak.net Wed Feb 14 15:56:55 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 14 Feb 2007 15:56:55 +0100 (CET) Subject: [pypy-svn] r38843 - in pypy/dist/pypy/translator/js/examples: . data Message-ID: <20070214145655.58D69100A3@code0.codespeak.net> Author: fijal Date: Wed Feb 14 15:56:54 2007 New Revision: 38843 Modified: pypy/dist/pypy/translator/js/examples/data/index.html pypy/dist/pypy/translator/js/examples/over_client.py pypy/dist/pypy/translator/js/examples/overmind.py Log: A link to b'n'b (need a check if it's running :) Modified: pypy/dist/pypy/translator/js/examples/data/index.html ============================================================================== --- pypy/dist/pypy/translator/js/examples/data/index.html (original) +++ pypy/dist/pypy/translator/js/examples/data/index.html Wed Feb 14 15:56:54 2007 @@ -16,9 +16,16 @@

Remote terminal:

-

Fully ANSI-complaint remote terminal session: - Launch one for me - Source +

Fully ANSI-complaint remote terminal session: + Launch one for me + Source +

+

Bub'n'Bros JavaScript version

+

+ This is a working b'n'b client. It's kind of slow (blame louse browsers), + but usable. WARNING! If you're using the firebug, please disable it, + it's a great tool, but chockes a bit on this demo
+ Demo

Modified: pypy/dist/pypy/translator/js/examples/over_client.py ============================================================================== --- pypy/dist/pypy/translator/js/examples/over_client.py (original) +++ pypy/dist/pypy/translator/js/examples/over_client.py Wed Feb 14 15:56:54 2007 @@ -11,3 +11,8 @@ def launch_console(): exported_methods.launch_console(callback) + +def bnb_redirect(): + loc = dom.window.location + new_loc = loc.protocol + "//" + loc.hostname + ":7070" + loc.assign(new_loc) Modified: pypy/dist/pypy/translator/js/examples/overmind.py ============================================================================== --- pypy/dist/pypy/translator/js/examples/overmind.py (original) +++ pypy/dist/pypy/translator/js/examples/overmind.py Wed Feb 14 15:56:54 2007 @@ -14,7 +14,7 @@ import os import py -FUNCTION_LIST = ['launch_console'] +FUNCTION_LIST = ['launch_console', 'bnb_redirect'] TIMEOUT = 300 pids = [] @@ -60,6 +60,17 @@ return "text/javascript", source source_js.exposed = True + def bnb(self): + return ''' + + + + + + + ''' + bnb.exposed = True + if __name__ == '__main__': try: addr = ('', 8008) From cfbolz at codespeak.net Wed Feb 14 16:37:15 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 14 Feb 2007 16:37:15 +0100 (CET) Subject: [pypy-svn] r38845 - pypy/dist/pypy/doc/config Message-ID: <20070214153715.E315D10094@code0.codespeak.net> Author: cfbolz Date: Wed Feb 14 16:37:14 2007 New Revision: 38845 Modified: pypy/dist/pypy/doc/config/translation.backendopt.remove_asserts.txt pypy/dist/pypy/doc/config/translation.backendopt.txt pypy/dist/pypy/doc/config/translation.cc.txt pypy/dist/pypy/doc/config/translation.debug.txt pypy/dist/pypy/doc/config/translation.fork_before.txt pypy/dist/pypy/doc/config/translation.insist.txt pypy/dist/pypy/doc/config/translation.instrument.txt pypy/dist/pypy/doc/config/translation.instrumentctl.txt pypy/dist/pypy/doc/config/translation.profopt.txt pypy/dist/pypy/doc/config/translation.vanilla.txt pypy/dist/pypy/doc/config/translation.withsmallfuncsets.txt Log: document a couple of more options Modified: pypy/dist/pypy/doc/config/translation.backendopt.remove_asserts.txt ============================================================================== --- pypy/dist/pypy/doc/config/translation.backendopt.remove_asserts.txt (original) +++ pypy/dist/pypy/doc/config/translation.backendopt.remove_asserts.txt Wed Feb 14 16:37:14 2007 @@ -0,0 +1 @@ +Remove assertion errors from the flowgraphs, which might give small speedups. Modified: pypy/dist/pypy/doc/config/translation.backendopt.txt ============================================================================== --- pypy/dist/pypy/doc/config/translation.backendopt.txt (original) +++ pypy/dist/pypy/doc/config/translation.backendopt.txt Wed Feb 14 16:37:14 2007 @@ -0,0 +1,5 @@ +This group contains options about various backend optimization passes. Most of +them are described in the `EU report about optimization`_ + +.. _`EU report about optimization`: http://codespeak.net/pypy/extradoc/eu-report/D07.1_Massive_Parallelism_and_Translation_Aspects-2006-12-15.pdf + Modified: pypy/dist/pypy/doc/config/translation.cc.txt ============================================================================== --- pypy/dist/pypy/doc/config/translation.cc.txt (original) +++ pypy/dist/pypy/doc/config/translation.cc.txt Wed Feb 14 16:37:14 2007 @@ -0,0 +1 @@ +Specify which C compiler to use. Modified: pypy/dist/pypy/doc/config/translation.debug.txt ============================================================================== --- pypy/dist/pypy/doc/config/translation.debug.txt (original) +++ pypy/dist/pypy/doc/config/translation.debug.txt Wed Feb 14 16:37:14 2007 @@ -0,0 +1,2 @@ +Record extra debugging information during annotation. This leads to slightly +less obscure error messages. Modified: pypy/dist/pypy/doc/config/translation.fork_before.txt ============================================================================== --- pypy/dist/pypy/doc/config/translation.fork_before.txt (original) +++ pypy/dist/pypy/doc/config/translation.fork_before.txt Wed Feb 14 16:37:14 2007 @@ -0,0 +1,4 @@ +This is an option mostly useful when working on the PyPy toolchain. If you use +it, translate.py will fork before the specified phase. If the translation +crashes after that fork, you can fix the bug in the toolchain, and continue +translation at the fork-point. Modified: pypy/dist/pypy/doc/config/translation.insist.txt ============================================================================== --- pypy/dist/pypy/doc/config/translation.insist.txt (original) +++ pypy/dist/pypy/doc/config/translation.insist.txt Wed Feb 14 16:37:14 2007 @@ -0,0 +1,4 @@ +Don't stop on the first `rtyping`_ error. Instead, try to rtype as much as +possible and show the collected error messages in the end. + +.. _`rtyping`: ../rtyper.html Modified: pypy/dist/pypy/doc/config/translation.instrument.txt ============================================================================== --- pypy/dist/pypy/doc/config/translation.instrument.txt (original) +++ pypy/dist/pypy/doc/config/translation.instrument.txt Wed Feb 14 16:37:14 2007 @@ -0,0 +1 @@ +internal option Modified: pypy/dist/pypy/doc/config/translation.instrumentctl.txt ============================================================================== --- pypy/dist/pypy/doc/config/translation.instrumentctl.txt (original) +++ pypy/dist/pypy/doc/config/translation.instrumentctl.txt Wed Feb 14 16:37:14 2007 @@ -0,0 +1 @@ +internal option Modified: pypy/dist/pypy/doc/config/translation.profopt.txt ============================================================================== --- pypy/dist/pypy/doc/config/translation.profopt.txt (original) +++ pypy/dist/pypy/doc/config/translation.profopt.txt Wed Feb 14 16:37:14 2007 @@ -0,0 +1,3 @@ +Use GCCs profile-guided optimizations. This option specifies the the arguments +with which to call pypy-c to gather profile data. Example: +"-c 'from richards import main;main(); from test import pystone; pystone.main()'" Modified: pypy/dist/pypy/doc/config/translation.vanilla.txt ============================================================================== --- pypy/dist/pypy/doc/config/translation.vanilla.txt (original) +++ pypy/dist/pypy/doc/config/translation.vanilla.txt Wed Feb 14 16:37:14 2007 @@ -0,0 +1,2 @@ +Try to make the resulting compiled program as portable (=moveable to another +machine) as possible. Which is not much. Modified: pypy/dist/pypy/doc/config/translation.withsmallfuncsets.txt ============================================================================== --- pypy/dist/pypy/doc/config/translation.withsmallfuncsets.txt (original) +++ pypy/dist/pypy/doc/config/translation.withsmallfuncsets.txt Wed Feb 14 16:37:14 2007 @@ -0,0 +1,3 @@ +Represent function sets smaller than this option's value as an integer instead +of a function pointer. A call is then done via a switch on that integer, which +allows inlining etc. Small numbers for this can speed up PyPy (try 5). From pedronis at codespeak.net Wed Feb 14 16:45:20 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Wed, 14 Feb 2007 16:45:20 +0100 (CET) Subject: [pypy-svn] r38847 - pypy/dist/pypy/doc Message-ID: <20070214154520.830B11008A@code0.codespeak.net> Author: pedronis Date: Wed Feb 14 16:45:18 2007 New Revision: 38847 Modified: pypy/dist/pypy/doc/translation.txt Log: a disclamair about the described approach to external functions. Modified: pypy/dist/pypy/doc/translation.txt ============================================================================== --- pypy/dist/pypy/doc/translation.txt (original) +++ pypy/dist/pypy/doc/translation.txt Wed Feb 14 16:45:18 2007 @@ -848,6 +848,13 @@ External Function Calls ======================= +*Warning* This approach while is still used at the moment by PyPy to +expose native operations (like ``os.read``, ``os.write``) is going to be +phased out. It has shown to be to cumbersome in practice. An approach +based on `rctypes`_ should replace it. + +.. _rctypes: rctypes.html + There are some functions that we don't want to implement in Python for various reasons (e.g. if they need to make calls into the OS). These can be implemented by writing backend code by hand that either implements the From pedronis at codespeak.net Wed Feb 14 16:53:30 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Wed, 14 Feb 2007 16:53:30 +0100 (CET) Subject: [pypy-svn] r38848 - pypy/dist/pypy/doc Message-ID: <20070214155330.764FB10068@code0.codespeak.net> Author: pedronis Date: Wed Feb 14 16:53:29 2007 New Revision: 38848 Modified: pypy/dist/pypy/doc/translation.txt Log: oops typo Modified: pypy/dist/pypy/doc/translation.txt ============================================================================== --- pypy/dist/pypy/doc/translation.txt (original) +++ pypy/dist/pypy/doc/translation.txt Wed Feb 14 16:53:29 2007 @@ -850,7 +850,7 @@ *Warning* This approach while is still used at the moment by PyPy to expose native operations (like ``os.read``, ``os.write``) is going to be -phased out. It has shown to be to cumbersome in practice. An approach +phased out. It has shown to be too cumbersome in practice. An approach based on `rctypes`_ should replace it. .. _rctypes: rctypes.html From hpk at codespeak.net Wed Feb 14 16:55:14 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Wed, 14 Feb 2007 16:55:14 +0100 (CET) Subject: [pypy-svn] r38849 - pypy/dist/pypy Message-ID: <20070214155514.4882610068@code0.codespeak.net> Author: hpk Date: Wed Feb 14 16:55:13 2007 New Revision: 38849 Modified: pypy/dist/pypy/conftest.py Log: add doc line (to check commit time) Modified: pypy/dist/pypy/conftest.py ============================================================================== --- pypy/dist/pypy/conftest.py (original) +++ pypy/dist/pypy/conftest.py Wed Feb 14 16:55:13 2007 @@ -8,6 +8,7 @@ rootdir = py.magic.autopath().dirpath() +# distributed testing settings dist_rsync_roots = ['.', '../lib-python', '../py', '../demo'] dist_rsync_ignore = ['_cache'] From guido at codespeak.net Wed Feb 14 16:57:38 2007 From: guido at codespeak.net (guido at codespeak.net) Date: Wed, 14 Feb 2007 16:57:38 +0100 (CET) Subject: [pypy-svn] r38850 - pypy/dist/pypy/translator/js/examples Message-ID: <20070214155738.7B7761009B@code0.codespeak.net> Author: guido Date: Wed Feb 14 16:57:37 2007 New Revision: 38850 Added: pypy/dist/pypy/translator/js/examples/guestbook.py pypy/dist/pypy/translator/js/examples/guestbook_client.py Log: Stupid guestbook example for the 'webapps_with_pypy.txt' doc. Added: pypy/dist/pypy/translator/js/examples/guestbook.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/js/examples/guestbook.py Wed Feb 14 16:57:37 2007 @@ -0,0 +1,95 @@ +#!/usr/bin/env python + +""" the mandatory guestbook example + + accompanies the pypyp/doc/js/webapps_with_pypy.txt document, serves as + a simple example to show how to go about writing a pypy web application +""" + +import autopath + +from pypy.translator.js.lib import server +from pypy.translator.js.lib.support import callback +from pypy.translator.js.main import rpython2javascript + +import py +import shelve + +class ExportedMethods(server.ExportedMethods): + """ this provides the methods that are exposed to the client ('AJAX' stuff) + """ + def __init__(self): + super(ExportedMethods, self).__init__() + self._db = shelve.open('messages') + self._db.setdefault('messages', []) + + # callback makes that a method gets exposed, it can get 2 arguments, + # 'ret' for specifying the return value, and 'args' for specifying the + # argument types + @callback(retval=[str]) + def get_messages(self): + return self._db['messages'] + + @callback(retval=str) + def add_message(self, name='', message=''): + text = '%s says: %s' % (name, message) + m = self._db['messages'] + m.append(text) + self._db['messages'] = m + return text + +exported_methods = ExportedMethods() + +FUNCTION_LIST = ['init_guestbook', 'add_message'] +def guestbook_client(): + """ compile the rpython guestbook_client code to js + """ + import guestbook_client + return rpython2javascript(guestbook_client, FUNCTION_LIST) + +class Handler(server.Handler): + """ a BaseHTTPRequestHandler subclass providing the HTTP methods + """ + # provide the exported methods + exported_methods = exported_methods + + # a simple html page + def index(self): + html = """ + + + Guestbook + + + +

Guestbook

+
+ +
+
+ name:
+ message:
+
+ +
+ + + """ + return 'text/html', html + index.exposed = True + + # the (generated) javascript + def guestbook_js(self): + if hasattr(self.server, 'source'): + source = self.server.source + else: + source = guestbook_client() + self.server.source = source + return "text/javascript", source + guestbook_js.exposed = True + +if __name__ == '__main__': + addr = ('', 8008) + httpd = server.create_server(server_address=addr, handler=Handler) + httpd.serve_forever() Added: pypy/dist/pypy/translator/js/examples/guestbook_client.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/js/examples/guestbook_client.py Wed Feb 14 16:57:37 2007 @@ -0,0 +1,35 @@ +""" rpython guestbook client-side code + + this code can be tested in CPython, but will also be converted to + JavaScript to provide the client-side functionality for the guestbook + example +""" + +from pypy.translator.js.modules import dom +from pypy.translator.js.examples.guestbook import exported_methods + +def add_html_message(text=''): + doc = dom.window.document + div = doc.getElementById('messages') + msgdiv = doc.createElement('div') + msgdiv.style.border = '1px solid black' + msgdiv.style.margin = '1em' + msgdiv.appendChild(doc.createTextNode(text)) + div.appendChild(msgdiv) + +def _init_callback(messages): + for message in messages: + add_html_message(message) + +def init_guestbook(): + exported_methods.get_messages(_init_callback) + +def _add_message_callback(message): + add_html_message(message) + +def add_message(): + doc = dom.window.document + name = doc.getElementById('name').value + message = doc.getElementById('message').value + exported_methods.add_message(name, message, _add_message_callback) + From pedronis at codespeak.net Wed Feb 14 16:59:15 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Wed, 14 Feb 2007 16:59:15 +0100 (CET) Subject: [pypy-svn] r38851 - pypy/dist/pypy Message-ID: <20070214155915.33B15100AB@code0.codespeak.net> Author: pedronis Date: Wed Feb 14 16:59:14 2007 New Revision: 38851 Modified: pypy/dist/pypy/conftest.py Log: testing Modified: pypy/dist/pypy/conftest.py ============================================================================== --- pypy/dist/pypy/conftest.py (original) +++ pypy/dist/pypy/conftest.py Wed Feb 14 16:59:14 2007 @@ -12,7 +12,7 @@ dist_rsync_roots = ['.', '../lib-python', '../py', '../demo'] dist_rsync_ignore = ['_cache'] -# +# # PyPy's command line extra options (these are added # to py.test's standard options) # From fijal at codespeak.net Wed Feb 14 17:27:38 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 14 Feb 2007 17:27:38 +0100 (CET) Subject: [pypy-svn] r38853 - pypy/dist/pypy/doc/js Message-ID: <20070214162738.7764210094@code0.codespeak.net> Author: fijal Date: Wed Feb 14 17:27:37 2007 New Revision: 38853 Added: pypy/dist/pypy/doc/js/testing.txt Modified: pypy/dist/pypy/doc/js/whatis.txt Log: * Added testing file (empty) * Make doc a bit more up-to-date Added: pypy/dist/pypy/doc/js/testing.txt ============================================================================== Modified: pypy/dist/pypy/doc/js/whatis.txt ============================================================================== --- pypy/dist/pypy/doc/js/whatis.txt (original) +++ pypy/dist/pypy/doc/js/whatis.txt Wed Feb 14 17:27:37 2007 @@ -15,45 +15,34 @@ What is it? ----------- -Pypy.js is mostly RPython to javascript converter. Nothing more, nothing -less. By `using`_ it you can write down RPython code (static enough subset -of python) which get translated into JavaScript and then run it in a browser. -As an addon you can get access to semi-transparent rendering of AJAX calls. - -This means that you might expect python semantics: ie. when trying to get -non-existing key from dictionary, you'll get KeyError, not undefined element. -If you prefer JavaScript semantics there is no point in using pypy.js, if -you instead prefer Python semantics this is a good point. Some of the -errors might appear at compile time (such as wrong number of arguments +Pypy.web is RPython to javascript converter and a set of tools which +evolved during pypy developement. By `using`_ it you can write down RPython +code (static enough subset of python) which get translated into JavaScript +and then run it in a browser. As an addon you can get access to +semi-transparent rendering of AJAX calls. + +This means that you might expect python semantics: ie. when you're trying to get +non-existing key from a dictionary, you'll get a KeyError, not an undefined element. +If you prefer JavaScript semantics there is no point in using pypy.web, if +you instead prefer Python semantics this is a good point. Some of +errors might appear at a compile time (such as wrong number of arguments to function, non-existing global variable, non-existing method call). -This also means that you will get python features - such as multi-inheritance, -exception handling etc. But you'll not get python dynamic features - modifying -dict access etc. +This also means that you will get some python features - such as exception handling +, list comprehensions etc. But you'll not get python dynamic features - overloading +operators, dynamic modifications of \_\_dict\_\_ and such. This also means that it is much easier to write code in pypy.js than in -JavaScript itself. The whole b'n'b demo is just about 250 lines of code, with +JavaScript itself. The whole `b'n'b demo`_ is just about 250 lines of code, with many AJAX calls. Imagine writing it in JavaScript. -We can say that pypy.js extends Mochikit's motto ("Makes JavaScript suck -less"), by "Makes JavaScript suck less, by not using it". +There are also facilities for testing your python code (about to be translated +to a JavaScript) on top of Python. For further details see `testing`_ .. _`using`: using.html +.. _`b'n'b demo`: http://play1.codespeak.net:7070 +.. _`testing`: testing.html What is it not? --------------- -Pypy.js is definitely not a browser-abstract library (with exceptions to -the semi-transparent AJAX calls, which are trying to be browser-independent). -Pypy.js is trying to expose the browser API as it comes, with all shortcomings. -If you need something like that you can expose any existing JS library -(there is an example with a few mochikit calls in modules). But it seems evident -that writing such a library on top of pypy.js sounds more interesting. - -Pypy.js is not a browser for python. Right now you cannot run your DOM-dependent -code on top of CPython (and this is unlikely to change in a future, because -we don't want to have just-another-browser-problem, do we?). Altough because -RPython is just subset of python, nothing stops you from separating code -DOM-dependent from other and running other part on top of CPython. Or, if you -really want to, from writing DOM library in CPython itself (just a library, no -mangling with compiler at all) which will allow you to run that code. From mwh at codespeak.net Wed Feb 14 17:39:00 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Wed, 14 Feb 2007 17:39:00 +0100 (CET) Subject: [pypy-svn] r38855 - pypy/dist/pypy/doc Message-ID: <20070214163900.8521510088@code0.codespeak.net> Author: mwh Date: Wed Feb 14 17:38:58 2007 New Revision: 38855 Modified: pypy/dist/pypy/doc/extcompiler.txt pypy/dist/pypy/doc/extradoc.txt pypy/dist/pypy/doc/objspace-proxies.txt pypy/dist/pypy/doc/rctypes.txt Log: fix a few instances of a classic arigo-typo Modified: pypy/dist/pypy/doc/extcompiler.txt ============================================================================== --- pypy/dist/pypy/doc/extcompiler.txt (original) +++ pypy/dist/pypy/doc/extcompiler.txt Wed Feb 14 17:38:58 2007 @@ -179,7 +179,7 @@ This does not work, however, if you need special data attached to the instances of your class. For this case, you need the second solution: -write the class entierely at interp-level. Such a class must inherit +write the class entirely at interp-level. Such a class must inherit from ``pypy.interpreter.baseobjspace.Wrappable``. You can manipulate instances of such a class freely at interp-level. Instances of subclasses of ``Wrappable`` are *not* wrapped; they are merely Modified: pypy/dist/pypy/doc/extradoc.txt ============================================================================== --- pypy/dist/pypy/doc/extradoc.txt (original) +++ pypy/dist/pypy/doc/extradoc.txt Wed Feb 14 17:38:58 2007 @@ -133,7 +133,7 @@ * `GNU lightning`_ generates assembly language at runtime. -* Tunes_ is not entierely unrelated. (See also the `review of +* Tunes_ is not entirely unrelated. (See also the `review of programming languages`_.) .. _`CLR under the hood`: http://download.microsoft.com/download/2/4/d/24dfac0e-fec7-4252-91b9-fb2310603f14/CLRUnderTheHood.BradA.ppt Modified: pypy/dist/pypy/doc/objspace-proxies.txt ============================================================================== --- pypy/dist/pypy/doc/objspace-proxies.txt (original) +++ pypy/dist/pypy/doc/objspace-proxies.txt Wed Feb 14 17:38:58 2007 @@ -123,7 +123,7 @@ with no initial value at all. It is possible to put a value into this object once, and only once, at any point in time. -This is not entierely unrelated to a lazily-computed object, except that +This is not entireely unrelated to a lazily-computed object, except that the object has no built-in knowledge about how it should compute itself. Trying to use such an object before it got a value results in a lock: the current thread is suspended, in the hope that another thread will @@ -160,7 +160,7 @@ other places merely pass it around, or do entirely unrelated things. Nevertheless, if a large application needs to be reviewed for security, -it must be entierely carefully checked, because it is possible that a +it must be entirely carefully checked, because it is possible that a bug at some apparently unrelated place could lead to a leak of sensitive information in a way that an external attacker could exploit. For example, if any part of the application provides web services, an Modified: pypy/dist/pypy/doc/rctypes.txt ============================================================================== --- pypy/dist/pypy/doc/rctypes.txt (original) +++ pypy/dist/pypy/doc/rctypes.txt Wed Feb 14 17:38:58 2007 @@ -414,7 +414,7 @@ * ``getitem()`` and ``setitem()`` - called when the RPython program uses the ``[ ]`` notation to index the full Python object -If necessary, the controller can also choose to entierely override the +If necessary, the controller can also choose to entirely override the default annotating and rtyping behavior and insert its own. This is useful for cases where the method cannot be implemented in RPython, e.g. in the presence of a polymorphic operation that would cause the From mwh at codespeak.net Wed Feb 14 17:57:05 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Wed, 14 Feb 2007 17:57:05 +0100 (CET) Subject: [pypy-svn] r38858 - pypy/dist/pypy/doc Message-ID: <20070214165705.CA95A10086@code0.codespeak.net> Author: mwh Date: Wed Feb 14 17:57:04 2007 New Revision: 38858 Modified: pypy/dist/pypy/doc/objspace-proxies.txt Log: oops Modified: pypy/dist/pypy/doc/objspace-proxies.txt ============================================================================== --- pypy/dist/pypy/doc/objspace-proxies.txt (original) +++ pypy/dist/pypy/doc/objspace-proxies.txt Wed Feb 14 17:57:04 2007 @@ -123,7 +123,7 @@ with no initial value at all. It is possible to put a value into this object once, and only once, at any point in time. -This is not entireely unrelated to a lazily-computed object, except that +This is not entirely unrelated to a lazily-computed object, except that the object has no built-in knowledge about how it should compute itself. Trying to use such an object before it got a value results in a lock: the current thread is suspended, in the hope that another thread will From arigo at codespeak.net Wed Feb 14 18:04:03 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 14 Feb 2007 18:04:03 +0100 (CET) Subject: [pypy-svn] r38859 - pypy/dist/pypy/doc Message-ID: <20070214170403.E86131008D@code0.codespeak.net> Author: arigo Date: Wed Feb 14 18:04:02 2007 New Revision: 38859 Modified: pypy/dist/pypy/doc/index.txt pypy/dist/pypy/doc/translation.txt Log: * Meta-Documentation => Project Documentation * EU report => Technical report (when the change makes sense) * strakt.com => openend.se Modified: pypy/dist/pypy/doc/index.txt ============================================================================== --- pypy/dist/pypy/doc/index.txt (original) +++ pypy/dist/pypy/doc/index.txt Wed Feb 14 18:04:02 2007 @@ -30,9 +30,11 @@ Status_ of the project. -Meta-Documentation +Project Documentation ===================================== +architecture_ gives a complete view of PyPy's basic design. + `coding guide`_ helps you to write code for PyPy (especially also describes coding in RPython a bit). @@ -50,7 +52,7 @@ `PyPy video documentation`_ is a page linking to the videos (e.g. of talks and introductions) that are available. -`EU reports`_ is a page that contains links to the +`Technical reports`_ is a page that contains links to the reports that we submitted to the European Union. `license`_ contains licensing details (basically a straight MIT-license). @@ -85,8 +87,6 @@ Source Code Documentation =============================================== -architecture_ gives a complete view of PyPy's basic design. - `object spaces`_ discusses the object space interface and several implementations. @@ -130,7 +130,7 @@ .. _`sprint reports`: sprint-reports.html .. _`talks and related projects`: extradoc.html .. _`license`: ../../LICENSE -.. _`Nightly compliance test runs for compiled pypy-c`: http://www.strakt.com/~pedronis/pypy-c-test/ +.. _`Nightly compliance test runs for compiled pypy-c`: http://www2.openend.se/~pedronis/pypy-c-test/ .. _`compliance test status`: http://codespeak.net/~hpk/pypy-testresult/ .. _`PyPy statistics`: http://codespeak.net/~hpk/pypy-stat/ .. _`object spaces`: objspace.html @@ -145,6 +145,7 @@ .. _`theory`: theory.html .. _`bytecode interpreter`: interpreter.html .. _`EU reports`: index-report.html +.. _`Technical reports`: index-report.html .. _`on Linux`: http://wyvern.cs.uni-duesseldorf.de/pypytest/summary.html .. _`on Windows`: http://scottdial.com/pypytest/ .. _`on built pypy-c`: http://wyvern.cs.uni-duesseldorf.de/~fijal/pypy-c-tests/ Modified: pypy/dist/pypy/doc/translation.txt ============================================================================== --- pypy/dist/pypy/doc/translation.txt (original) +++ pypy/dist/pypy/doc/translation.txt Wed Feb 14 18:04:02 2007 @@ -643,9 +643,9 @@ on flexibility and robustness, not performance. For a quite detailed description of how memory management and garbage collection -are performed in PyPy, see the `EU report`_ about this topic (section 4.2). +are performed in PyPy, see the `Technical report`_ about this topic (section 4.2). -.. _`EU report`: http://codespeak.net/pypy/extradoc/eu-report/D07.1_Massive_Parallelism_and_Translation_Aspects-2006-12-15.pdf +.. _`Technical report`: http://codespeak.net/pypy/extradoc/eu-report/D07.1_Massive_Parallelism_and_Translation_Aspects-2006-12-15.pdf .. _C: .. _GenC: From arigo at codespeak.net Wed Feb 14 18:17:53 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 14 Feb 2007 18:17:53 +0100 (CET) Subject: [pypy-svn] r38860 - pypy/dist/pypy/doc Message-ID: <20070214171753.D9C621008D@code0.codespeak.net> Author: arigo Date: Wed Feb 14 18:17:52 2007 New Revision: 38860 Modified: pypy/dist/pypy/doc/architecture.txt Log: (screen session) Updated the Architecture document. Note that we killed the Status section because the rest already talks a bit about it, and also because this is now present in index.txt. Modified: pypy/dist/pypy/doc/architecture.txt ============================================================================== --- pypy/dist/pypy/doc/architecture.txt (original) +++ pypy/dist/pypy/doc/architecture.txt Wed Feb 14 18:17:52 2007 @@ -20,6 +20,10 @@ Eventually, dynamic optimization techniques - implemented as another translation aspect - should become robust against language changes. +As part of this process, we ended up developing a general +framework for implementing dynamic languages and generating +virtual machines for them `[VMC]_`. As proof of concepts, we +have a Prolog and an in-progress JavaScript interpreter. PyPy - an implementation of Python in Python ============================================ @@ -70,19 +74,28 @@ details. (Because of the nature of Python, this is already a complicated task, although not as much as writing it in - say - C.) Then we use this as a "language specification" and manipulate it to -produce the more traditional interpreters that we want. In the above -sense, we are generating the concrete "mappings" of Python into -lower-level target platforms. - -So far (autumn 2005), we have already succeeded in turning this "language -specification" into reasonably efficient C-level code that performs -basically the same job as CPython. Memory management is inserted during -this *translation* process. It can be configured to use reference -counting or not; thus we have already achieved two very different -mappings of application Python code over C/Posix. We have -successfully also translated our Python interpreter into LLVM_ code, -and we are working on targeting higher-level environments like -Java and Squeak. +produce the more traditional interpreters that we want. In other words, +we are generating concrete interpreters, all able to execute normal +Python code, but themselves running on a variety of lower-level +target platforms. + +So far (early 2007), we have already succeeded in turning this +"language specification" into reasonably efficient C-level +code that performs basically the same job as CPython (either +by generating C source, or via LLVM_). We can also generate a +Python interpreter for .NET, and a Java (JVM) version is on +its way. + +In addition to the platform diversity, we can generate very +diverse interpreters for each platform. Some of these +differences come from the inclusion of optional language +features or optimizations; but more fundamentally, and +particularly when targetting C-level environments, many +low-level details are inserted during this *translation* +process - for example, memory management: the generated code +can use the Boehm garbage collector, our custom collectors, or +a simple reference counting scheme. These are all different +concrete realisations of our "language specification". In some senses, PyPy project's central component is not its interpreter implementation, but its configurable translator. @@ -180,11 +193,13 @@ target platform; - the *code generator* which translates the resulting flow graph into - another language, currently C, LLVM_, Javascript (experimental). + another language, currently C, LLVM_, .NET, Javascript (in-progress) + or Java (JVM - in-progress). -A more complete description of the phases of this process is out of the -scope of the present introduction. We will only give in the sequel a -short overview. +A more complete description of the phases of this process is +out of the scope of the present introduction. For more +details, see the `translation document`_. We will only give a +short overview in the sequel. .. _`initialization time`: @@ -241,45 +256,25 @@ .. image:: image/translation-greyscale-small.png -The complete translation process is described in more details in the -`translation document`_. You might also be interested in reading the -more theoretically-oriented paper `Compiling dynamic language -implementations`_. - -Status of the implementation (June 2006) -========================================== - -The work leading up to the pypy-0.9.0 release has concentrated on the -features of the translation. - -We can now produce a pypy-c that `has the majority of the features`_ -of `Stackless Python`_. We have integrated the mark and sweep garbage -collector written in RPython by Carl Friedrich as part of Google's -Summer of Code 2005 with the translation machinery, and can produce a -pypy-c that uses it for memory management. - -.. _`has the majority of the features`: stackless.html -.. _`Stackless Python`: http://www.stackless.com/ - -The self-contained PyPy version (single-threaded and using the -`Boehm-Demers-Weiser garbage collector`_) now runs around 4-5 times -slower than CPython, i.e. around 3 times faster than 0.8.0. - -We have improved our CPython compatibility still further, and now pass -around 95% of CPython's core tests, the main improvement over 0.8.0 -being the implementation of the _weakref module. - -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 230,000 -lines of code including 62,000 lines of tests. Refer to -the `statistics web page`_ for more detailed information. + +Further reading +=============== + +* `[VMC]`_ PyPy's approach to virtual machine construction + (Dynamic Languages Symposium 2006). + +* The `translation document`_ describes our translation process in detail. + You might also be interested in reading the more + theoretically-oriented paper `Compiling dynamic language + implementations`_. + +* All our `Technical reports`_. + +* `Getting started`_ with PyPy. + .. _`statistics web page`: http://codespeak.net/~hpk/pypy-stat/ -.. _`very compliant`: http://codespeak.net/~hpk/pypy-testresult/ +.. _`very compliant`: http://www2.openend.se/~pedronis/pypy-c-test/allworkingmodules/summary.html .. _`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 @@ -288,6 +283,8 @@ .. _LLVM: http://llvm.org/ .. _`PDF color version`: image/translation.pdf .. _`getting started`: getting-started.html +.. _`[VMC]`: http://codespeak.net/svn/pypy/extradoc/talk/dls2006/pypy-vm-construction.pdf +.. _`Technical reports`: index-report.html .. include:: _ref.txt From pedronis at codespeak.net Wed Feb 14 18:21:29 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Wed, 14 Feb 2007 18:21:29 +0100 (CET) Subject: [pypy-svn] r38861 - pypy/dist/pypy/doc Message-ID: <20070214172129.145F51008D@code0.codespeak.net> Author: pedronis Date: Wed Feb 14 18:21:28 2007 New Revision: 38861 Added: pypy/dist/pypy/doc/release-0.99.0.txt (contents, props changed) Log: create release announcement file: to be filled ... Added: pypy/dist/pypy/doc/release-0.99.0.txt ============================================================================== --- (empty file) +++ pypy/dist/pypy/doc/release-0.99.0.txt Wed Feb 14 18:21:28 2007 @@ -0,0 +1,2 @@ +pypy-0.99.0: ... +================================ From antocuni at codespeak.net Wed Feb 14 19:01:28 2007 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Wed, 14 Feb 2007 19:01:28 +0100 (CET) Subject: [pypy-svn] r38862 - pypy/dist/pypy/doc Message-ID: <20070214180128.A40071007C@code0.codespeak.net> Author: antocuni Date: Wed Feb 14 19:01:27 2007 New Revision: 38862 Modified: pypy/dist/pypy/doc/getting-started.txt pypy/dist/pypy/doc/translation.txt Log: the clr module is buggy when translated :-( Modified: pypy/dist/pypy/doc/getting-started.txt ============================================================================== --- pypy/dist/pypy/doc/getting-started.txt (original) +++ pypy/dist/pypy/doc/getting-started.txt Wed Feb 14 19:01:27 2007 @@ -676,35 +676,6 @@ fine. Once assembled, you can run the produced executable with the Microsoft Runtime. -You can also try the still very experimental ``clr`` module that -enables integration with the surrounding .NET environment. First, you -have to tell translate.py to include the ``clr`` module:: - - ./translate.py --text --batch --backend=cli targetpypystandalone.py --withmod-clr - -Then, you can dynamically load .NET classes using the -``clr.load_cli_classe`` method. After a class has been loaded, you can -instantiate and use it as it were a normal Python class. Special -methods such as indexers and properties are supported using the usual -Python syntax: - - >>>> import clr - >>>> ArrayList = clr.load_cli_class('System.Collections', 'ArrayList') - >>>> obj.Add(1) - 0 - >>>> obj.Add(2) - 1 - >>>> obj.Add("foo") - 2 - >>>> print obj[0], obj[1], obj[2] - 1 2 foo - >>>> print obj.Count - 3 - -At the moment the only way to load a .NET class is to explicitly use -``clr.load_cli_class``; in the future they will be automatically -loaded when accessing .NET namespaces as they were Python modules, as -IronPython does. .. _`start reading sources`: Modified: pypy/dist/pypy/doc/translation.txt ============================================================================== --- pypy/dist/pypy/doc/translation.txt (original) +++ pypy/dist/pypy/doc/translation.txt Wed Feb 14 19:01:27 2007 @@ -731,7 +731,7 @@ The Object-Oriented backends target platforms that are less C-like and support classes, instance etc. If such a platform is targetted, the `OO type system` is -used while rtyping. Of the OO backends, currently only genclr can translate the +used while rtyping. Of the OO backends, currently only gencli can translate the full PyPy, but the Java backend is getting close. .. _`oo type system`: rtyper.html#oo-type From rxe at codespeak.net Wed Feb 14 21:46:41 2007 From: rxe at codespeak.net (rxe at codespeak.net) Date: Wed, 14 Feb 2007 21:46:41 +0100 (CET) Subject: [pypy-svn] r38863 - pypy/dist/pypy/rpython/lltypesystem Message-ID: <20070214204641.AF68810088@code0.codespeak.net> Author: rxe Date: Wed Feb 14 21:46:40 2007 New Revision: 38863 Modified: pypy/dist/pypy/rpython/lltypesystem/lltype.py Log: support long constants Modified: pypy/dist/pypy/rpython/lltypesystem/lltype.py ============================================================================== --- pypy/dist/pypy/rpython/lltypesystem/lltype.py (original) +++ pypy/dist/pypy/rpython/lltypesystem/lltype.py Wed Feb 14 21:46:40 2007 @@ -643,6 +643,11 @@ return Void # maybe if tp is int: return Signed + if tp is long: + if -maxint-1 <= val <= maxint: + return Signed + else: + return SignedLongLong if tp is bool: return Bool if issubclass(tp, base_int): From guido at codespeak.net Wed Feb 14 22:14:41 2007 From: guido at codespeak.net (guido at codespeak.net) Date: Wed, 14 Feb 2007 22:14:41 +0100 (CET) Subject: [pypy-svn] r38865 - in pypy/dist/pypy: doc/js translator/js/examples Message-ID: <20070214211441.6173110087@code0.codespeak.net> Author: guido Date: Wed Feb 14 22:14:40 2007 New Revision: 38865 Modified: pypy/dist/pypy/doc/js/webapps_with_pypy.txt pypy/dist/pypy/translator/js/examples/guestbook_client.py Log: Some small cleanups in the guestbook code, added description of the elements of the guestbook to webapps_with_pypy.txt. Modified: pypy/dist/pypy/doc/js/webapps_with_pypy.txt ============================================================================== --- pypy/dist/pypy/doc/js/webapps_with_pypy.txt (original) +++ pypy/dist/pypy/doc/js/webapps_with_pypy.txt Wed Feb 14 22:14:40 2007 @@ -18,6 +18,9 @@ too much of anything in the (rather daunting) PyPy codebase besides the useful bits for web application development. +Note that this document describes APIs that are not mature and will change in +the near future. + PyPy features for web developers --------------------------------- @@ -30,12 +33,12 @@ This particulary means that when a program is in RPython, you can run it on top of Python interpreter with the same results as translated to JS version. -However, mostly for demonstration purposes, some other interesting code is -available in the PyPy code package that may help developing web apps. The most -interesting of these I think is a library that transparently makes server-side -functionality available to client-side code, using XMLHttpRequest. This code -lives in a module in pypy/translator/js/examples that's called 'server.py', and -uses a library in pypy/translator/js called 'commproxy.py'. +However, there is some other interesting code available in the PyPy package +that may help developing web apps. The most interesting of these I think is a +library that transparently makes server-side functionality available to +client-side code, using XMLHttpRequest. This code lives in a module in +pypy/translator/js/examples that's called 'server.py', and uses a library in +pypy/translator/js called 'commproxy.py'. Note that the 'server.py' library currently is usable, but not complete: I assume there will be quite some development and refinement later. This may mean @@ -87,6 +90,155 @@ Writing a simple application ----------------------------- -XXX hands-on guide to writing guestbook or something +To explain what needs to be done to write an application using all this, I +decided to add the (almost mandatory) classic guestbook example. To show off +the transparent XMLHttpRequest stuff, I chose to do one that stays on-screen +when adding a message, so there's no screen refresh, but apart from that it's +a very basic, simple guestbook. Of course the script is still too much code to +fit in this document nicely, so I placed it in some nice files: on for +`the server-side code` and one for `the client-side`. Let's examine the +server side first. + +guestbook.py +++++++++++++ + +If you examine the code, you will see 2 classes, one function and some code +in the usual "if __name__ == '__main__'" block. The latter bit starts the +webserver, passing one of the classes (Handler) as a handler to a +BaseHTTPServer, which in turn uses the function (guestbook_client) to produce +JavaScript, and the class (ExportedMethods) to serve 'AJAX' methods from. + +This will be what a general PyPy web application (using commproxy) will look +like: a set of HTTP methods (web pages and scripts) on a Handler class, a set +of 'RPC' methods on an ExportedMethods class, a main loop and perhaps some +helper functionality (e.g. to convert RPython to JS). Let's examine the two +classes in more detail. + +Handler +~~~~~~~ + +The Handler class is a normal BaseHTTPRequestHandler subclass, but with some +pre-defined HTTP handlers (do_GET et al) that dispatch actual content +generation to user-defined methods. If a '/' path is requested from the server, +a method called 'index' is called, else the path is split on slashes, and the +first bit, with dots replaced by underscores, is used to find a method, the +other parts passed to that method as arguments. So calling '/foo.bar/baz' will +result in the method 'foo_bar' getting called with argument 'baz'. + +Note that a method needs to have an attribute 'exposed' set to True to actually +expose the method, if this attribute is not set requesting the path will result +in a 404 error. Methods that aren't exposed can be used for internal purposes. + +There is some helper functionality, such as the Static class to serve static +files and directories, in the pypy/translator/js/lib/server.py. + +(Note that even though currently BaseHTTPServer is used to deal with HTTP, +this will likely change in the future, in favour of something like CherryPy.) + +ExportedMethods +~~~~~~~~~~~~~~~ + +The ExportedMethods class contains methods that are (through some magic) +exposed to the client side, in an RPC-like fashion. This is implemented using +XMLHttpRequest and JSON: when from the client-side a method is called here, +the arguments to the method will be serialized and sent to the server, the +method is called, the return value is serialized again and sent to the client, +where a callback (registered on calling the method) is called with the return +value as argument. Methods on ExportedMethods contain normal, unrestricted +Python code, but do need to have the arguments and return value described in +order for the proxy mechanism to deal with them. + +Let's take a look at the 'get_messages' method. The 'callback' decorator that +wraps it is used to tell the proxy mechanism what arguments and return value +is used (arguments can also be determined by examining the function signature, +so only have to be provided when the function signature doesn't describe +default values), using that decorator will mark the method for exposure. This +particular method does not have arguments passed to it from the client, but +does have a return value: a list of strings. + +The second message on this class, 'add_message', does have a set of arguments, +which both have a string value, both of which are described in the function +arguments (as default values). + +guestbook_client +~~~~~~~~~~~~~~~~ + +This function imports a Python (or RPython, actually) module and commands +PyPy to convert a set of functions in it to JavaScript. This is all you need +to do to get a conversion done, the function returns a string of directly +executable JavaScript with the functions made available under their original +name. + +guestbook_client.py ++++++++++++++++++++ + +This contains the client-side code. It contains a couple of functions to +display messages and add messages to the guestbook, all relatively simple, +but there are a couple of things that need explanation. + +First thing to notice is of course that the code is RPython. This allows PyPy +to translate it to JavaScript (and a lot of other things :), but does mean +there are some restrictions: RPython is less dynamic than normal Python. For +instance, you need to make sure that PyPy knows in advance of what types +variables are, so changing a variable type, or writing functions that allow +different types of variables (Python's 'duck typing') is not allowed. + +Another odd thing are the imports: these are ignored on the client. They +are only there to satisfy the RPython to JavaScript translator, and to allow +running the code as 'normal' Python, for instance when testing. Both the 'dom' +object, and 'exported_methods' are made available on the client by some +commproxy magic. + +In the functions, there are some other things to note. The 'exported_methods' +variable is a reference to the exported_methods instance in guestbook.py, but +because there's the commproxy between the client and server, the methods are +wrapped, and the signatures are changed. The methods all need an additional +argument, 'callback', when called from the client side, and rather than +returning the return value directly, this callback is called with the return +value as argument. + +Finishing up +++++++++++++ + +The previously described components together already make up a working web +application. If you run the 'guestbook.py' script, the main loop bit on the +bottom will be triggered, passing the Handler class to some BaseHTTPRequest +server, which will start waiting for a request. + +If a browser is pointed to http://localhost:8008/ (the root of the +application), the 'index' method will be called, which presents the HTML page +with the form. A script tag will make that the JavaScript is retrieved from the +server, which is built on-the-fly (if required) from the RPython +'guestbook_client.py' file. An 'onload' handler on the tag will trigger +the 'init_guestbook()' function in this JS, which in turn calls the server's +'exported_methods.get_messages()' function that provides the initial page +content. + +If the form is filled in and the 'submit' button pressed, the 'add_message()' +function is called, which gets the data from the form and calls the server's +'exported_methods.add_message()' function. This then returns a string version +of the message back to the client (to the '_add_message_callback' function) +where it is presented. + +All this code is written without having to care about XMLHttpRequest and +serialization, with a simple server-side interface, and in a testable manner. + +Conclusion +---------- + +Even though RPython is somewhat hard to debug sometimes, and the tools are +still a little rough around the edges sometimes, PyPy can already be a valuable +tool for web developers, with RPython to make code easier to write and test, +and the commproxy to help dealing with asynchronous server calls and +serialization. Do not expect that PyPy does not try to 'magically' make all web +development problems go away: you will still need to manually write +client-side code, and still need to take care for dealing with browsers and +such, except not in JavaScript but in RPython, and with the 'AJAX' stuff +nicely tucked away. There may be future developments that will provide +higher-level layers, and client-side widgets and such, but currently it's +still 'work as usual', but with somewhat nicer (we hope ;) tools. .. _`RPython`: ../coding-guide.html#restricted-python +.. _`the server-side code`: ../../translator/js/examples/guestbook.py +.. _`the client-side`: ../../translator/js/examples/guestbook_client.py + Modified: pypy/dist/pypy/translator/js/examples/guestbook_client.py ============================================================================== --- pypy/dist/pypy/translator/js/examples/guestbook_client.py (original) +++ pypy/dist/pypy/translator/js/examples/guestbook_client.py Wed Feb 14 22:14:40 2007 @@ -8,21 +8,12 @@ from pypy.translator.js.modules import dom from pypy.translator.js.examples.guestbook import exported_methods -def add_html_message(text=''): - doc = dom.window.document - div = doc.getElementById('messages') - msgdiv = doc.createElement('div') - msgdiv.style.border = '1px solid black' - msgdiv.style.margin = '1em' - msgdiv.appendChild(doc.createTextNode(text)) - div.appendChild(msgdiv) - -def _init_callback(messages): +def _get_messages_callback(messages): for message in messages: add_html_message(message) def init_guestbook(): - exported_methods.get_messages(_init_callback) + exported_methods.get_messages(_get_messages_callback) def _add_message_callback(message): add_html_message(message) @@ -33,3 +24,12 @@ message = doc.getElementById('message').value exported_methods.add_message(name, message, _add_message_callback) +def add_html_message(text=''): + doc = dom.window.document + div = doc.getElementById('messages') + msgdiv = doc.createElement('div') + msgdiv.style.border = '1px solid black' + msgdiv.style.margin = '1em' + msgdiv.appendChild(doc.createTextNode(text)) + div.appendChild(msgdiv) + From guido at codespeak.net Wed Feb 14 22:39:38 2007 From: guido at codespeak.net (guido at codespeak.net) Date: Wed, 14 Feb 2007 22:39:38 +0100 (CET) Subject: [pypy-svn] r38866 - pypy/dist/pypy/doc/js Message-ID: <20070214213938.4075310081@code0.codespeak.net> Author: guido Date: Wed Feb 14 22:39:37 2007 New Revision: 38866 Modified: pypy/dist/pypy/doc/js/whatis.txt Log: Improved document structure, fixed some typos and re-arranged the text a bit to make it sound better (less, well, chaotic ;). Modified: pypy/dist/pypy/doc/js/whatis.txt ============================================================================== --- pypy/dist/pypy/doc/js/whatis.txt (original) +++ pypy/dist/pypy/doc/js/whatis.txt Wed Feb 14 22:39:37 2007 @@ -15,34 +15,44 @@ What is it? ----------- -Pypy.web is RPython to javascript converter and a set of tools which -evolved during pypy developement. By `using`_ it you can write down RPython -code (static enough subset of python) which get translated into JavaScript -and then run it in a browser. As an addon you can get access to -semi-transparent rendering of AJAX calls. - -This means that you might expect python semantics: ie. when you're trying to get -non-existing key from a dictionary, you'll get a KeyError, not an undefined element. -If you prefer JavaScript semantics there is no point in using pypy.web, if -you instead prefer Python semantics this is a good point. Some of -errors might appear at a compile time (such as wrong number of arguments -to function, non-existing global variable, non-existing method call). - -This also means that you will get some python features - such as exception handling -, list comprehensions etc. But you'll not get python dynamic features - overloading -operators, dynamic modifications of \_\_dict\_\_ and such. - -This also means that it is much easier to write code in pypy.js than in -JavaScript itself. The whole `b'n'b demo`_ is just about 250 lines of code, with -many AJAX calls. Imagine writing it in JavaScript. +Pypy.web is an RPython to JavaScript converter and a set of tools which +evolved during PyPy developement. By `using`_ it you can write RPython +code (a subset of Python static enough to compile), translate it into +JavaScript and then run it in a browser. As an add-on you can +semi-transparently make 'AJAX' (JavaScript to server) calls. + +RPython to JavaScript +--------------------- + +When writing RPython you can expect full Python semantics from code you write: +ie. when you're trying to get a non-existing key from a dictionary, you'll get +a KeyError, not an undefined element. Also things like Python's +object-orientation are fully supported. This in contrast to other efforts of +getting Python converted to JavaScript, which usually provide only a very small +subset of Python, and with JavaScript semantics. + +This means that you will get some Python features - such as exception handling, +list comprehensions, etc., but do understand that you will _not_ get some of +the more 'dynamic' features of Python - overloading operators, dynamic +modifications of \_\_dict\_\_ and such, because that will break RPython. + +Additional features +------------------- + +It is much easier to write code in pypy.js than in JavaScript itself. The whole +`b'n'b demo`_ is just about 250 lines of code, with many AJAX calls. Imagine +writing it in JavaScript, it would easily exceed the number of lines, even with +a nice library to handle the AJAX, and would almost certainly be less elegant +and readable. + +Errors may appear already at compile time (such as providing the wrong number +of arguments to a function, using a non-existing global variable, calling a +non-existing method). -There are also facilities for testing your python code (about to be translated +There are some facilities for testing your Python code (about to be translated to a JavaScript) on top of Python. For further details see `testing`_ .. _`using`: using.html .. _`b'n'b demo`: http://play1.codespeak.net:7070 .. _`testing`: testing.html -What is it not? ---------------- - From guido at codespeak.net Wed Feb 14 22:46:24 2007 From: guido at codespeak.net (guido at codespeak.net) Date: Wed, 14 Feb 2007 22:46:24 +0100 (CET) Subject: [pypy-svn] r38867 - pypy/extradoc/sprintinfo/trillke-2007 Message-ID: <20070214214624.1D4F11007B@code0.codespeak.net> Author: guido Date: Wed Feb 14 22:46:22 2007 New Revision: 38867 Modified: pypy/extradoc/sprintinfo/trillke-2007/people.txt Log: Added my name to the list of sprinters (not sure about the start date anymore, may change it later). Modified: pypy/extradoc/sprintinfo/trillke-2007/people.txt ============================================================================== --- pypy/extradoc/sprintinfo/trillke-2007/people.txt (original) +++ pypy/extradoc/sprintinfo/trillke-2007/people.txt Wed Feb 14 22:46:22 2007 @@ -23,6 +23,7 @@ Christian Tismer 28th-5th Klocke Alix Einfeldt 25th-5th private Alexander Schremmer 1st-5th no idea +Guido Wesdorp 26th-5th ? ==================== ============== ===================== People on the following list were present at previous sprints: From guido at codespeak.net Wed Feb 14 23:05:14 2007 From: guido at codespeak.net (guido at codespeak.net) Date: Wed, 14 Feb 2007 23:05:14 +0100 (CET) Subject: [pypy-svn] r38868 - pypy/dist/pypy/translator/js Message-ID: <20070214220514.A8F5310082@code0.codespeak.net> Author: guido Date: Wed Feb 14 23:05:13 2007 New Revision: 38868 Modified: pypy/dist/pypy/translator/js/commproxy.py Log: Added missing escape() calls (for URL-encoding the GET and POST bodies). Modified: pypy/dist/pypy/translator/js/commproxy.py ============================================================================== --- pypy/dist/pypy/translator/js/commproxy.py (original) +++ pypy/dist/pypy/translator/js/commproxy.py Wed Feb 14 23:05:13 2007 @@ -19,7 +19,7 @@ } else { str += "&"; } - str += i + "=" + data[i].toString(); + str += escape(i) + "=" + escape(data[i].toString()); } } //logDebug('%(call)s'+str); @@ -45,7 +45,7 @@ } else { str += "&"; } - str += i + "=" + data[i].toString(); + str += escape(i) + "=" + escape(data[i].toString()); } } //logDebug('%(call)s'+str); From guido at codespeak.net Wed Feb 14 23:10:29 2007 From: guido at codespeak.net (guido at codespeak.net) Date: Wed, 14 Feb 2007 23:10:29 +0100 (CET) Subject: [pypy-svn] r38869 - pypy/dist/pypy/translator/js/examples Message-ID: <20070214221029.723A210082@code0.codespeak.net> Author: guido Date: Wed Feb 14 23:10:28 2007 New Revision: 38869 Modified: pypy/dist/pypy/translator/js/examples/guestbook.py (props changed) Log: Set svn:executable to ON. From pedronis at codespeak.net Thu Feb 15 00:50:14 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Thu, 15 Feb 2007 00:50:14 +0100 (CET) Subject: [pypy-svn] r38870 - pypy/extradoc/planning/1.0 Message-ID: <20070214235014.90B7610086@code0.codespeak.net> Author: pedronis Date: Thu Feb 15 00:50:13 2007 New Revision: 38870 Modified: pypy/extradoc/planning/1.0/documentation.txt Log: update, reduce down tasks... Modified: pypy/extradoc/planning/1.0/documentation.txt ============================================================================== --- pypy/extradoc/planning/1.0/documentation.txt (original) +++ pypy/extradoc/planning/1.0/documentation.txt Thu Feb 15 00:50:13 2007 @@ -1,39 +1,47 @@ Documentation for release 1.0 ================================ +release announcement! -index.txt: review the directory cross-reference (done) +improve getting-started (cfbolz, partially) + XXX put the windows things into their own file? + XXX add optional tools needed +important cross-check that things still works, update links... -config pages, for all the options. -Link to the other pages as much as possible. - +contributor.txt: needs to be updated -pypy.net - also update translation.txt (antocuni, done) +faq.txt: write answers (arigo, fijal, cfbolz) complete! +config pages, for all the options. +Link to the other pages as much as possible. js backend - is there something to update in translation.txt? BasicExternal approach, external functions? (fijal) +consult, improve *how-to-release.txt* -jit.txt: add examples of nice colors - postponed +Leave as is? + * dynamic-language-translation.txt (old report, leave as it is? or remove and + point to the report?) -faq.txt: write answers (arigo, fijal, cfbolz) + * low-level-encapsulation.txt (old report, leave as it is? or remove and + point to the report?) +Done, postponed +===================== -improve getting-started (cfbolz, partially) - XXX put the windows things into their own file? - XXX add optional tools needed +index.txt: review the directory cross-reference (done) + +pypy.net - also update translation.txt (antocuni, done) + +jit.txt: add examples of nice colors - postponed short how to compile on windows (based on docstring of goal/win32/gc_patch_windows.py) (antocuni, done) -release announcement - -architecture.txt: should grow a bit and have an updated "status" section. - -contributor.txt: needs to be updated +architecture.txt: killed status, updated theory.txt: add specialization @@ -46,21 +54,17 @@ * constraints-and-logic.txt * contact.txt * dev_method.txt - * dynamic-language-translation.txt (old report, leave as it is? or remove and - point to the report?) - * extcompiler.txt * extradoc.txt - * garbage_collection.txt (out of date) - * geninterp.txt (incomplete) + * garbage_collection.txt (transformed into a reference) + * geninterp.txt (made it good enough, pedronis) * glossary.txt (add terms) - * how-to-release.txt + * howto-logicobjspace-0.9.txt * index-report.txt (shouldn't be changed, I guess) * interpreter.txt - * low-level-encapsulation.txt (old report, leave as it is? or remove and - point to the report?) + * objspace.txt * parser.txt (horribly incomplete) * project-ideas.txt @@ -73,5 +77,4 @@ * standalone-howto.txt (remove/or update) * svn-help.txt * translation-aspects.txt - * translation.txt (contains long standing XXXd sections, kill them - or put something in them) + * translation.txt (made up-to-date, partially) From mwh at codespeak.net Thu Feb 15 10:32:36 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Thu, 15 Feb 2007 10:32:36 +0100 (CET) Subject: [pypy-svn] r38872 - pypy/dist/pypy/doc Message-ID: <20070215093236.3DB5510078@code0.codespeak.net> Author: mwh Date: Thu Feb 15 10:32:34 2007 New Revision: 38872 Modified: pypy/dist/pypy/doc/glossary.txt Log: remove glossary entry on l3interp Modified: pypy/dist/pypy/doc/glossary.txt ============================================================================== --- pypy/dist/pypy/doc/glossary.txt (original) +++ pypy/dist/pypy/doc/glossary.txt Thu Feb 15 10:32:34 2007 @@ -45,7 +45,7 @@ **external function** Functions that we don't want to implement in Python for various - reasons (e.g. if they need to make calls into the OS) and whose + reasons (e.g. they need to make calls into the OS) and whose implementation will be provided by the backend. .. _`garbage collection framework`: @@ -68,12 +68,6 @@ `just in time compiler`_. Our jit now has `some draft documentation `__. -.. _`l3interpreter`: - -**l3interpreter** - Piece of code that is able to interpret L3 flow graphs. This code - is unfinished and its future is unclear. - .. _llinterpreter: **llinterpreter** From fijal at codespeak.net Thu Feb 15 12:30:11 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 15 Feb 2007 12:30:11 +0100 (CET) Subject: [pypy-svn] r38873 - pypy/dist/pypy/doc/js Message-ID: <20070215113011.62F171007C@code0.codespeak.net> Author: fijal Date: Thu Feb 15 12:30:10 2007 New Revision: 38873 Added: pypy/dist/pypy/doc/js/confrest.py - copied, changed from r38668, pypy/dist/pypy/doc/confrest.py Log: Add confrest which resembles links better From fijal at codespeak.net Thu Feb 15 13:30:37 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 15 Feb 2007 13:30:37 +0100 (CET) Subject: [pypy-svn] r38874 - pypy/dist/pypy/doc/js Message-ID: <20070215123037.DB32310078@code0.codespeak.net> Author: fijal Date: Thu Feb 15 13:30:36 2007 New Revision: 38874 Removed: pypy/dist/pypy/doc/js/confrest.py Log: Delete file which makes py.test choke From fijal at codespeak.net Thu Feb 15 13:48:27 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 15 Feb 2007 13:48:27 +0100 (CET) Subject: [pypy-svn] r38875 - pypy/dist/pypy/doc/js Message-ID: <20070215124827.E3D921007A@code0.codespeak.net> Author: fijal Date: Thu Feb 15 13:48:26 2007 New Revision: 38875 Modified: pypy/dist/pypy/doc/js/using.txt pypy/dist/pypy/doc/js/webapps_with_pypy.txt pypy/dist/pypy/doc/js/whatis.txt Log: Fix links, minor rewording Modified: pypy/dist/pypy/doc/js/using.txt ============================================================================== --- pypy/dist/pypy/doc/js/using.txt (original) +++ pypy/dist/pypy/doc/js/using.txt Thu Feb 15 13:48:26 2007 @@ -170,6 +170,6 @@ working copy on-line right now, sorry) and a simple example of JS a `console`_. There is also a simple `django ping example`_. -.. _`here`: http://codespeak.net/svn/pypy/dist/pypy/translator/js/examples/start_bnb.py +.. _`here`: http://codespeak.net/svn/pypy/dist/pypy/translator/js/examples/bnb/start_bnb.py .. _`console`: http://codespeak.net/svn/pypy/dist/pypy/translator/js/examples/console.py .. _`django ping example`: http://codespeak.net/svn/pypy/dist/pypy/translator/js/demo/jsdemo/djangoping Modified: pypy/dist/pypy/doc/js/webapps_with_pypy.txt ============================================================================== --- pypy/dist/pypy/doc/js/webapps_with_pypy.txt (original) +++ pypy/dist/pypy/doc/js/webapps_with_pypy.txt Thu Feb 15 13:48:26 2007 @@ -25,7 +25,7 @@ --------------------------------- Of course the 'killer feature' of PyPy for web application developers is the -ability to convert somewhat restricted Python code (aka RPython) into +ability to convert somewhat restricted Python code (aka `RPython`_) into JavaScript code. Unlike other libraries that perform similar functionality, PyPy really interprets the code, and produces 'lower level' JavaScript code, so it implements Python core language features like list comprehensions, and @@ -40,9 +40,10 @@ pypy/translator/js/examples that's called 'server.py', and uses a library in pypy/translator/js called 'commproxy.py'. -Note that the 'server.py' library currently is usable, but not complete: I -assume there will be quite some development and refinement later. This may mean -that certain things in this document are outdated. +Note that the 'server.py' library currently is usable, but not complete nor +stable: I assume there will be quite some development and refinement later. +This may mean that certain things in this document are outdated. There +might be even a strong API rewrite at some point. Layers ------- @@ -75,7 +76,7 @@ exposed functions only support common datatypes (ints, strings, lists of ints, etc.) for arguments and return values, and have to have those - arguments and return values 'described' so that the rtyper system can + arguments and return values 'described' so that the annotator system can discover how they should be exposed, and so that the (transparently used) XMLHttpRequest handler and JSON serializer know how they should be treated @@ -96,7 +97,7 @@ when adding a message, so there's no screen refresh, but apart from that it's a very basic, simple guestbook. Of course the script is still too much code to fit in this document nicely, so I placed it in some nice files: on for -`the server-side code` and one for `the client-side`. Let's examine the +`the server-side code`_ and one for `the client-side`_. Let's examine the server side first. guestbook.py @@ -239,6 +240,6 @@ still 'work as usual', but with somewhat nicer (we hope ;) tools. .. _`RPython`: ../coding-guide.html#restricted-python -.. _`the server-side code`: ../../translator/js/examples/guestbook.py -.. _`the client-side`: ../../translator/js/examples/guestbook_client.py +.. _`the server-side code`: http://codespeak.net/svn/pypy/dist/pypy/translator/js/examples/guestbook.py +.. _`the client-side`: http://codespeak.net/svn/pypy/dist/pypy/translator/js/examples/guestbook_client.py Modified: pypy/dist/pypy/doc/js/whatis.txt ============================================================================== --- pypy/dist/pypy/doc/js/whatis.txt (original) +++ pypy/dist/pypy/doc/js/whatis.txt Thu Feb 15 13:48:26 2007 @@ -1,6 +1,6 @@ -============================================ -What is pypy.js (JavaScript backend of pypy) -============================================ +============================================= +What is pypy.web (JavaScript backend of pypy) +============================================= Author: ======= @@ -10,7 +10,7 @@ Purpose: ======== -This document explains what pypy.js is and (just as important) what it is not. +This document explains what pypy.web is and (just as important) what it is not. What is it? ----------- @@ -39,7 +39,7 @@ Additional features ------------------- -It is much easier to write code in pypy.js than in JavaScript itself. The whole +It is much easier to write code in pypy.web than in JavaScript itself. The whole `b'n'b demo`_ is just about 250 lines of code, with many AJAX calls. Imagine writing it in JavaScript, it would easily exceed the number of lines, even with a nice library to handle the AJAX, and would almost certainly be less elegant From hpk at codespeak.net Thu Feb 15 14:06:58 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Thu, 15 Feb 2007 14:06:58 +0100 (CET) Subject: [pypy-svn] r38876 - pypy/dist/lib-python Message-ID: <20070215130658.076F110079@code0.codespeak.net> Author: hpk Date: Thu Feb 15 14:06:58 2007 New Revision: 38876 Modified: pypy/dist/lib-python/conftest.py Log: hum, a missing fix for a changed method Modified: pypy/dist/lib-python/conftest.py ============================================================================== --- pypy/dist/lib-python/conftest.py (original) +++ pypy/dist/lib-python/conftest.py Thu Feb 15 14:06:58 2007 @@ -875,7 +875,7 @@ class ReallyRunFileExternal(py.test.collect.Item): _resultcache = None - def haskeyword(self, keyword): + def _haskeyword(self, keyword): if keyword == 'core': return self.parent.regrtest.core if keyword not in ('error', 'ok', 'timeout'): From adim at codespeak.net Thu Feb 15 14:13:50 2007 From: adim at codespeak.net (adim at codespeak.net) Date: Thu, 15 Feb 2007 14:13:50 +0100 (CET) Subject: [pypy-svn] r38877 - in pypy/branch/ast-experiments/pypy: config interpreter interpreter/pyparser module/dyngram module/recparser Message-ID: <20070215131350.C6F2B10083@code0.codespeak.net> Author: adim Date: Thu Feb 15 14:13:49 2007 New Revision: 38877 Added: pypy/branch/ast-experiments/pypy/module/dyngram/ (props changed) pypy/branch/ast-experiments/pypy/module/dyngram/__init__.py (contents, props changed) Modified: pypy/branch/ast-experiments/pypy/config/pypyoption.py pypy/branch/ast-experiments/pypy/interpreter/pycompiler.py pypy/branch/ast-experiments/pypy/interpreter/pyparser/pythonparse.py pypy/branch/ast-experiments/pypy/module/recparser/__init__.py Log: - made a special "dyngram" module that exports the runtime grammar modifications ability Modified: pypy/branch/ast-experiments/pypy/config/pypyoption.py ============================================================================== --- pypy/branch/ast-experiments/pypy/config/pypyoption.py (original) +++ pypy/branch/ast-experiments/pypy/config/pypyoption.py Thu Feb 15 14:13:49 2007 @@ -24,7 +24,7 @@ working_modules = default_modules.copy() working_modules.update(dict.fromkeys( ["rsocket", "unicodedata", "mmap", "fcntl", "rctime", "select", "bz2", - "crypt", "signal", + "crypt", "signal", "dyngram", ] )) Modified: pypy/branch/ast-experiments/pypy/interpreter/pycompiler.py ============================================================================== --- pypy/branch/ast-experiments/pypy/interpreter/pycompiler.py (original) +++ pypy/branch/ast-experiments/pypy/interpreter/pycompiler.py Thu Feb 15 14:13:49 2007 @@ -200,11 +200,10 @@ the whole source after having only added a new '\n') """ def __init__(self, space): - from pyparser.pythonparse import make_pyparser + from pyparser.pythonparse import PYTHON_PARSER PyCodeCompiler.__init__(self, space) - self.parser = make_pyparser() + self.parser = PYTHON_PARSER self.additional_rules = {} - def compile(self, source, filename, mode, flags): Modified: pypy/branch/ast-experiments/pypy/interpreter/pyparser/pythonparse.py ============================================================================== --- pypy/branch/ast-experiments/pypy/interpreter/pyparser/pythonparse.py (original) +++ pypy/branch/ast-experiments/pypy/interpreter/pyparser/pythonparse.py Thu Feb 15 14:13:49 2007 @@ -168,12 +168,12 @@ # recompute first sets self.build_first_sets() - - def make_pyparser(version="2.4"): parser = PythonParser() return build_parser_for_version(version, parser=parser) +PYTHON_PARSER = make_pyparser() + def translation_target(grammardef): parser = PythonParser() # predefined_symbols=symbol.sym_name) source = GrammarSource(GRAMMAR_GRAMMAR, grammardef) @@ -185,7 +185,6 @@ return 0 - ## XXX BROKEN ## def parse_grammar(space, w_src): ## """Loads the grammar using the 'dynamic' rpython parser""" Added: pypy/branch/ast-experiments/pypy/module/dyngram/__init__.py ============================================================================== --- (empty file) +++ pypy/branch/ast-experiments/pypy/module/dyngram/__init__.py Thu Feb 15 14:13:49 2007 @@ -0,0 +1,12 @@ +"""Mixed module for dynamic grammar modification""" + +from pypy.interpreter.mixedmodule import MixedModule + +class Module(MixedModule): + """dyngram module definition""" + + name = 'dyngram' + appleveldefs = {} + interpleveldefs = { + 'insert_grammar_rule' : 'pypy.interpreter.pycompiler.insert_grammar_rule', + } Modified: pypy/branch/ast-experiments/pypy/module/recparser/__init__.py ============================================================================== --- pypy/branch/ast-experiments/pypy/module/recparser/__init__.py (original) +++ pypy/branch/ast-experiments/pypy/module/recparser/__init__.py Thu Feb 15 14:13:49 2007 @@ -47,8 +47,6 @@ 'source2ast' : "pyparser.source2ast", 'decode_string_literal': 'pyparser.decode_string_literal', 'install_compiler_hook' : 'pypy.interpreter.pycompiler.install_compiler_hook', - 'insert_grammar_rule' : 'pypy.interpreter.pycompiler.insert_grammar_rule', - #'parse_grammar' : 'pypy.interpreter.pyparser.pythonparse.parse_grammar', } # Automatically exports each AST class From fijal at codespeak.net Thu Feb 15 14:19:08 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 15 Feb 2007 14:19:08 +0100 (CET) Subject: [pypy-svn] r38878 - pypy/dist/pypy/translator/js/examples/data Message-ID: <20070215131908.9B05F10083@code0.codespeak.net> Author: fijal Date: Thu Feb 15 14:19:07 2007 New Revision: 38878 Modified: pypy/dist/pypy/translator/js/examples/data/index.html Log: Kill source links Modified: pypy/dist/pypy/translator/js/examples/data/index.html ============================================================================== --- pypy/dist/pypy/translator/js/examples/data/index.html (original) +++ pypy/dist/pypy/translator/js/examples/data/index.html Thu Feb 15 14:19:07 2007 @@ -11,14 +11,12 @@

Python console:

No more, no less Launch one for me - Source

Remote terminal:

Fully ANSI-complaint remote terminal session: - Launch one for me - Source + Launch one for me

Bub'n'Bros JavaScript version

From adim at codespeak.net Thu Feb 15 14:26:14 2007 From: adim at codespeak.net (adim at codespeak.net) Date: Thu, 15 Feb 2007 14:26:14 +0100 (CET) Subject: [pypy-svn] r38879 - pypy/branch/ast-experiments/pypy/doc/config Message-ID: <20070215132614.9DA5610086@code0.codespeak.net> Author: adim Date: Thu Feb 15 14:26:12 2007 New Revision: 38879 Added: pypy/branch/ast-experiments/pypy/doc/config/objspace.usemodules.dyngram.txt (contents, props changed) Log: small doc for the --withmod-dyngram option Added: pypy/branch/ast-experiments/pypy/doc/config/objspace.usemodules.dyngram.txt ============================================================================== --- (empty file) +++ pypy/branch/ast-experiments/pypy/doc/config/objspace.usemodules.dyngram.txt Thu Feb 15 14:26:12 2007 @@ -0,0 +1,7 @@ +Use the 'dyngram' module. + +The 'dyngram' module exports the 'insert_grammar_rule' function to +application-level code. This function allows to modify dynamically +the python the grammar. + + From fijal at codespeak.net Thu Feb 15 14:27:10 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 15 Feb 2007 14:27:10 +0100 (CET) Subject: [pypy-svn] r38880 - pypy/dist/pypy/doc/js Message-ID: <20070215132710.878EE10083@code0.codespeak.net> Author: fijal Date: Thu Feb 15 14:27:09 2007 New Revision: 38880 Modified: pypy/dist/pypy/doc/js/using.txt Log: Minor API changes Modified: pypy/dist/pypy/doc/js/using.txt ============================================================================== --- pypy/dist/pypy/doc/js/using.txt (original) +++ pypy/dist/pypy/doc/js/using.txt Thu Feb 15 14:27:09 2007 @@ -94,10 +94,12 @@ tell the JS backend to render it using xmlhttp communication. Because the web server code does not need to be rpython, you have to supply some way of telling PyPy what types can be returned out of it. This is done -using the decorator `@described(retval = )` from +using the decorator `@callback(retval = )` from `bltregistry`_. For example you may provide:: - @described(retval = {str:str}) + from pypy.translator.js.lib.support import callback + + @callback(retval = {str:str}) def some_fun(self, some_arg = 3): .... @@ -121,12 +123,13 @@ On the server side:: - from pypy.rpython.ootypesystem.bltregistry import BasicExternal, described + from pypy.rpython.ootypesystem.bltregistry import BasicExternal + from pypy.translator.js.lib.support import callback class PingHandler(BasicExternal): _render_xmlhttp = True - @described(retval={str:str}) + @callback(retval={str:str}) def ping(self, ping_str="aa"): return dict(response="PONG: %s" % ping_str) From pedronis at codespeak.net Thu Feb 15 14:36:31 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Thu, 15 Feb 2007 14:36:31 +0100 (CET) Subject: [pypy-svn] r38881 - in pypy/extradoc/planning: 0.99 1.0 Message-ID: <20070215133631.2E3F61007A@code0.codespeak.net> Author: pedronis Date: Thu Feb 15 14:36:30 2007 New Revision: 38881 Added: pypy/extradoc/planning/0.99/ - copied from r38880, pypy/extradoc/planning/1.0/ Removed: pypy/extradoc/planning/1.0/ Log: 1.0 -> 0.99 for now From fijal at codespeak.net Thu Feb 15 14:48:19 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 15 Feb 2007 14:48:19 +0100 (CET) Subject: [pypy-svn] r38882 - in pypy/dist/pypy/translator/js/demo/jsdemo/djangoping: . templates Message-ID: <20070215134819.A8A2010087@code0.codespeak.net> Author: fijal Date: Thu Feb 15 14:48:18 2007 New Revision: 38882 Modified: pypy/dist/pypy/translator/js/demo/jsdemo/djangoping/client.py pypy/dist/pypy/translator/js/demo/jsdemo/djangoping/templates/index.html Log: * Fix djangoping example * Reference external MochiKit for now Modified: pypy/dist/pypy/translator/js/demo/jsdemo/djangoping/client.py ============================================================================== --- pypy/dist/pypy/translator/js/demo/jsdemo/djangoping/client.py (original) +++ pypy/dist/pypy/translator/js/demo/jsdemo/djangoping/client.py Thu Feb 15 14:48:18 2007 @@ -1,6 +1,7 @@ """rpython javascript code""" -from pypy.rpython.ootypesystem.bltregistry import BasicExternal, MethodDesc, described +from pypy.rpython.ootypesystem.bltregistry import BasicExternal, MethodDesc +from pypy.translator.js.lib.support import callback from pypy.translator.js.modules import mochikit from pypy.translator.js.modules import dom @@ -9,7 +10,7 @@ """Server side code which handles javascript calls""" _render_xmlhttp = True - @described(retval={"aa":"aa"}) + @callback(retval={str:str}) def ping(self, ping_str="aa"): """Simply returns the string prefixed with a PONG""" return dict(response="PONG: %s" % ping_str) Modified: pypy/dist/pypy/translator/js/demo/jsdemo/djangoping/templates/index.html ============================================================================== --- pypy/dist/pypy/translator/js/demo/jsdemo/djangoping/templates/index.html (original) +++ pypy/dist/pypy/translator/js/demo/jsdemo/djangoping/templates/index.html Thu Feb 15 14:48:18 2007 @@ -3,7 +3,7 @@ Python pinger - - + Modified: pypy/dist/pypy/translator/js/examples/overmind.py ============================================================================== --- pypy/dist/pypy/translator/js/examples/overmind.py (original) +++ pypy/dist/pypy/translator/js/examples/overmind.py Thu Feb 15 14:55:45 2007 @@ -49,6 +49,7 @@ static_dir = str(py.path.local(__file__).dirpath().join("data")) index = server.Static() console = server.Static(os.path.join(static_dir, "launcher.html")) + terminal = server.Static(os.path.join(static_dir, "terminal.html")) exported_methods = exported_methods def source_js(self): Modified: pypy/dist/pypy/translator/js/examples/pythonconsole.py ============================================================================== --- pypy/dist/pypy/translator/js/examples/pythonconsole.py (original) +++ pypy/dist/pypy/translator/js/examples/pythonconsole.py Thu Feb 15 14:55:45 2007 @@ -31,7 +31,7 @@ Example +

Console

From afayolle at codespeak.net Fri Feb 16 09:07:17 2007 From: afayolle at codespeak.net (afayolle at codespeak.net) Date: Fri, 16 Feb 2007 09:07:17 +0100 (CET) Subject: [pypy-svn] r38995 - pypy/dist/pypy/doc Message-ID: <20070216080717.F17FA1007C@code0.codespeak.net> Author: afayolle Date: Fri Feb 16 09:07:16 2007 New Revision: 38995 Modified: pypy/dist/pypy/doc/release-0.99.0.txt Log: small improvement on the WP09 and WP10 related features Modified: pypy/dist/pypy/doc/release-0.99.0.txt ============================================================================== --- pypy/dist/pypy/doc/release-0.99.0.txt (original) +++ pypy/dist/pypy/doc/release-0.99.0.txt Fri Feb 16 09:07:16 2007 @@ -106,9 +106,13 @@ that we set for ourselves (and which many blogs and people out there have chosen as a main criterium for looking at PyPy). -* we are to integrate new Syntax and Aspect-Oriented - extension capabilities and refine the Logic object - space (provides Logic Variables within Python). +* the extension enabling runtime changes of the Python grammar is not + yet integrated. This will be used to provide Aspect-Oriented + Programming extensions and Design by Contract facilities in PyPy. + +* the Logic object space, which provides Logic Variables in PyPy, + needs to undergo a bit more testing. A constraint problem solver + extension module is ready, and needs to be integrated in the codebase. * we'd like to package and improve configurations and and testing, and actually ask for your help From fijal at codespeak.net Fri Feb 16 10:46:33 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 16 Feb 2007 10:46:33 +0100 (CET) Subject: [pypy-svn] r38997 - pypy/dist/pypy/doc Message-ID: <20070216094633.386B710088@code0.codespeak.net> Author: fijal Date: Fri Feb 16 10:46:31 2007 New Revision: 38997 Modified: pypy/dist/pypy/doc/release-0.99.0.txt Log: A note about transparent proxy Modified: pypy/dist/pypy/doc/release-0.99.0.txt ============================================================================== --- pypy/dist/pypy/doc/release-0.99.0.txt (original) +++ pypy/dist/pypy/doc/release-0.99.0.txt Fri Feb 16 10:46:31 2007 @@ -74,7 +74,11 @@ objects are "declassified" in order to send information across IO barriers. - - TProxy: Transparent distribution: XXX + - TProxy: An object space hack, which allows you to create + objects of any type, with custom behavior, defined by your own + function. For details see + http://codespeak.net/pypy/dist/pypy/doc/proxy.html + XXX Move link to the bottom? * optimizations: - XXX From cfbolz at codespeak.net Fri Feb 16 13:04:00 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 16 Feb 2007 13:04:00 +0100 (CET) Subject: [pypy-svn] r39001 - pypy/dist/pypy/doc Message-ID: <20070216120400.A7A3210094@code0.codespeak.net> Author: cfbolz Date: Fri Feb 16 13:03:58 2007 New Revision: 39001 Modified: pypy/dist/pypy/doc/release-0.99.0.txt Log: - add short sentence about wp6 - the taint space is bigger now Modified: pypy/dist/pypy/doc/release-0.99.0.txt ============================================================================== --- pypy/dist/pypy/doc/release-0.99.0.txt (original) +++ pypy/dist/pypy/doc/release-0.99.0.txt Fri Feb 16 13:03:58 2007 @@ -65,7 +65,7 @@ ===================== * new object spaces: - - Tainting: a 150-line proxy object space tracking + - Tainting: a 270-line proxy object space tracking and boxing sensitive information within an application. A tainted object is completely barred from crossing an IO barrier, such as writing to files, databases @@ -81,7 +81,8 @@ XXX Move link to the bottom? * optimizations: - - XXX + - experimental new optimized implementations for various built in Python + types (strings, dicts, lists) - speed up of 5-7 compared to 0.9, overall 2-3 slower than CPython From mwh at codespeak.net Fri Feb 16 13:41:06 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 16 Feb 2007 13:41:06 +0100 (CET) Subject: [pypy-svn] r39002 - pypy/dist/pypy/doc/config Message-ID: <20070216124106.44B6D10091@code0.codespeak.net> Author: mwh Date: Fri Feb 16 13:41:03 2007 New Revision: 39002 Modified: pypy/dist/pypy/doc/config/objspace.std.methodcachesize.txt Log: typo Modified: pypy/dist/pypy/doc/config/objspace.std.methodcachesize.txt ============================================================================== --- pypy/dist/pypy/doc/config/objspace.std.methodcachesize.txt (original) +++ pypy/dist/pypy/doc/config/objspace.std.methodcachesize.txt Fri Feb 16 13:41:03 2007 @@ -1 +1 @@ -Set the cache size (number of entries) for config:`objspace.std.withmethodcache`. +Set the cache size (number of entries) for :config:`objspace.std.withmethodcache`. From mwh at codespeak.net Fri Feb 16 13:44:02 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 16 Feb 2007 13:44:02 +0100 (CET) Subject: [pypy-svn] r39003 - pypy/dist/pypy/doc/config Message-ID: <20070216124402.763A31009D@code0.codespeak.net> Author: mwh Date: Fri Feb 16 13:43:59 2007 New Revision: 39003 Modified: pypy/dist/pypy/doc/config/objspace.std.prebuiltintfrom.txt pypy/dist/pypy/doc/config/objspace.std.prebuiltintto.txt pypy/dist/pypy/doc/config/objspace.std.withmethodcachecounter.txt pypy/dist/pypy/doc/config/objspace.std.withstrdict.txt pypy/dist/pypy/doc/config/objspace.usemodules._stackless.txt pypy/dist/pypy/doc/config/objspace.usemodules.rctime.txt pypy/dist/pypy/doc/config/translation.backendopt.clever_malloc_removal.txt pypy/dist/pypy/doc/config/translation.backendopt.clever_malloc_removal_heuristic.txt pypy/dist/pypy/doc/config/translation.backendopt.clever_malloc_removal_threshold.txt pypy/dist/pypy/doc/config/translation.backendopt.inline_heuristic.txt pypy/dist/pypy/doc/config/translation.backendopt.inline_threshold.txt pypy/dist/pypy/doc/config/translation.backendopt.profile_based_inline_heuristic.txt pypy/dist/pypy/doc/config/translation.backendopt.profile_based_inline_threshold.txt Log: wow, someone didn't know how text roles in rest work! Modified: pypy/dist/pypy/doc/config/objspace.std.prebuiltintfrom.txt ============================================================================== --- pypy/dist/pypy/doc/config/objspace.std.prebuiltintfrom.txt (original) +++ pypy/dist/pypy/doc/config/objspace.std.prebuiltintfrom.txt Fri Feb 16 13:43:59 2007 @@ -1 +1 @@ -see config:`objspace.std.withprebuiltint`. +see :config:`objspace.std.withprebuiltint`. Modified: pypy/dist/pypy/doc/config/objspace.std.prebuiltintto.txt ============================================================================== --- pypy/dist/pypy/doc/config/objspace.std.prebuiltintto.txt (original) +++ pypy/dist/pypy/doc/config/objspace.std.prebuiltintto.txt Fri Feb 16 13:43:59 2007 @@ -1 +1 @@ -See config:`objspace.std.withprebuiltint`. +See :config:`objspace.std.withprebuiltint`. Modified: pypy/dist/pypy/doc/config/objspace.std.withmethodcachecounter.txt ============================================================================== --- pypy/dist/pypy/doc/config/objspace.std.withmethodcachecounter.txt (original) +++ pypy/dist/pypy/doc/config/objspace.std.withmethodcachecounter.txt Fri Feb 16 13:43:59 2007 @@ -1 +1 @@ -Testing/debug option for config:`objspace.std.withmethodcache`. +Testing/debug option for :config:`objspace.std.withmethodcache`. Modified: pypy/dist/pypy/doc/config/objspace.std.withstrdict.txt ============================================================================== --- pypy/dist/pypy/doc/config/objspace.std.withstrdict.txt (original) +++ pypy/dist/pypy/doc/config/objspace.std.withstrdict.txt Fri Feb 16 13:43:59 2007 @@ -1 +1 @@ -Obsolete. See config:`objspace.std.withmultidict` instead. \ No newline at end of file +Obsolete. See :config:`objspace.std.withmultidict` instead. Modified: pypy/dist/pypy/doc/config/objspace.usemodules._stackless.txt ============================================================================== --- pypy/dist/pypy/doc/config/objspace.usemodules._stackless.txt (original) +++ pypy/dist/pypy/doc/config/objspace.usemodules._stackless.txt Fri Feb 16 13:43:59 2007 @@ -1,6 +1,6 @@ Use the '_stackless' module. Exposes the `stackless` primitives, and also implies a stackless build. -See also config:`translation.stackless`. +See also :config:`translation.stackless`. .. _`stackless`: ../stackless.html Modified: pypy/dist/pypy/doc/config/objspace.usemodules.rctime.txt ============================================================================== --- pypy/dist/pypy/doc/config/objspace.usemodules.rctime.txt (original) +++ pypy/dist/pypy/doc/config/objspace.usemodules.rctime.txt Fri Feb 16 13:43:59 2007 @@ -1,7 +1,7 @@ Use the 'rctime' module. 'rctime' is our `rctypes`_ based implementation of the builtin 'time' module. -It supersedes the less complete config:`objspace.usemodules.time`, +It supersedes the less complete :config:`objspace.usemodules.time`, at least for C-like targets (the C and LLVM backends). .. _`rctypes`: ../rctypes.html Modified: pypy/dist/pypy/doc/config/translation.backendopt.clever_malloc_removal.txt ============================================================================== --- pypy/dist/pypy/doc/config/translation.backendopt.clever_malloc_removal.txt (original) +++ pypy/dist/pypy/doc/config/translation.backendopt.clever_malloc_removal.txt Fri Feb 16 13:43:59 2007 @@ -1,5 +1,5 @@ Try to inline flowgraphs based on whether doing so would enable malloc -removal (config:`translation.backendopt.mallocs`.) by eliminating +removal (:config:`translation.backendopt.mallocs`.) by eliminating calls that result in escaping. This is an experimental optimisation, also right now some eager inlining is necessary for helpers doing malloc itself to be inlined first for this to be effective. Modified: pypy/dist/pypy/doc/config/translation.backendopt.clever_malloc_removal_heuristic.txt ============================================================================== --- pypy/dist/pypy/doc/config/translation.backendopt.clever_malloc_removal_heuristic.txt (original) +++ pypy/dist/pypy/doc/config/translation.backendopt.clever_malloc_removal_heuristic.txt Fri Feb 16 13:43:59 2007 @@ -1,2 +1,2 @@ Internal option. Switch to a different weight heuristic for inlining. -This is for clever malloc removal (config:`translation.backendopt.clever_malloc_removal`). +This is for clever malloc removal (:config:`translation.backendopt.clever_malloc_removal`). Modified: pypy/dist/pypy/doc/config/translation.backendopt.clever_malloc_removal_threshold.txt ============================================================================== --- pypy/dist/pypy/doc/config/translation.backendopt.clever_malloc_removal_threshold.txt (original) +++ pypy/dist/pypy/doc/config/translation.backendopt.clever_malloc_removal_threshold.txt Fri Feb 16 13:43:59 2007 @@ -1,2 +1,2 @@ Weight threshold used to decide whether to inline flowgraphs. -This is for clever malloc removal (config:`translation.backendopt.clever_malloc_removal`). +This is for clever malloc removal (:config:`translation.backendopt.clever_malloc_removal`). Modified: pypy/dist/pypy/doc/config/translation.backendopt.inline_heuristic.txt ============================================================================== --- pypy/dist/pypy/doc/config/translation.backendopt.inline_heuristic.txt (original) +++ pypy/dist/pypy/doc/config/translation.backendopt.inline_heuristic.txt Fri Feb 16 13:43:59 2007 @@ -1,2 +1,2 @@ Internal option. Switch to a different weight heuristic for inlining. -This is for basic inlining (config:`translation.backendopt.inline`). +This is for basic inlining (:config:`translation.backendopt.inline`). Modified: pypy/dist/pypy/doc/config/translation.backendopt.inline_threshold.txt ============================================================================== --- pypy/dist/pypy/doc/config/translation.backendopt.inline_threshold.txt (original) +++ pypy/dist/pypy/doc/config/translation.backendopt.inline_threshold.txt Fri Feb 16 13:43:59 2007 @@ -1,2 +1,2 @@ Weight threshold used to decide whether to inline flowgraphs. -This is for basic inlining (config:`translation.backendopt.inline`). \ No newline at end of file +This is for basic inlining (:config:`translation.backendopt.inline`). Modified: pypy/dist/pypy/doc/config/translation.backendopt.profile_based_inline_heuristic.txt ============================================================================== --- pypy/dist/pypy/doc/config/translation.backendopt.profile_based_inline_heuristic.txt (original) +++ pypy/dist/pypy/doc/config/translation.backendopt.profile_based_inline_heuristic.txt Fri Feb 16 13:43:59 2007 @@ -1,2 +1,2 @@ Internal option. Switch to a different weight heuristic for inlining. -This is for profile-based inlining (config:`translation.backendopt.profile_based_inline`). +This is for profile-based inlining (:config:`translation.backendopt.profile_based_inline`). Modified: pypy/dist/pypy/doc/config/translation.backendopt.profile_based_inline_threshold.txt ============================================================================== --- pypy/dist/pypy/doc/config/translation.backendopt.profile_based_inline_threshold.txt (original) +++ pypy/dist/pypy/doc/config/translation.backendopt.profile_based_inline_threshold.txt Fri Feb 16 13:43:59 2007 @@ -1,2 +1,2 @@ Weight threshold used to decide whether to inline flowgraphs. -This is for profile-based inlining (config:`translation.backendopt.profile_based_inline`). \ No newline at end of file +This is for profile-based inlining (:config:`translation.backendopt.profile_based_inline`). From mwh at codespeak.net Fri Feb 16 14:09:55 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 16 Feb 2007 14:09:55 +0100 (CET) Subject: [pypy-svn] r39004 - pypy/dist/pypy/doc/config Message-ID: <20070216130955.CF669100A6@code0.codespeak.net> Author: mwh Date: Fri Feb 16 14:09:53 2007 New Revision: 39004 Modified: pypy/dist/pypy/doc/config/translation.no__thread.txt Log: missed one Modified: pypy/dist/pypy/doc/config/translation.no__thread.txt ============================================================================== --- pypy/dist/pypy/doc/config/translation.no__thread.txt (original) +++ pypy/dist/pypy/doc/config/translation.no__thread.txt Fri Feb 16 14:09:53 2007 @@ -1,4 +1,4 @@ Don't use gcc __thread attribute for fast thread local storage implementation . Increases the chance that moving the resulting executable to another same processor Linux machine will work. (see -config:`translation.vanilla`). +:config:`translation.vanilla`). From mwh at codespeak.net Fri Feb 16 14:11:21 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 16 Feb 2007 14:11:21 +0100 (CET) Subject: [pypy-svn] r39005 - pypy/dist/pypy/doc Message-ID: <20070216131121.0E5CC100AC@code0.codespeak.net> Author: mwh Date: Fri Feb 16 14:11:15 2007 New Revision: 39005 Modified: pypy/dist/pypy/doc/conftest.py Log: make the text for the link produced :config:`some option` be --some-option, not some.option (if that made any sense). Modified: pypy/dist/pypy/doc/conftest.py ============================================================================== --- pypy/dist/pypy/doc/conftest.py (original) +++ pypy/dist/pypy/doc/conftest.py Fri Feb 16 14:11:15 2007 @@ -54,6 +54,8 @@ def config_role(name, rawtext, text, lineno, inliner, options={}, content=[]): from docutils import nodes + from pypy.config.pypyoption import get_pypy_config + from pypy.config.makerestdoc import get_cmdline txt = thisdir.join("config", text + ".txt") html = thisdir.join("config", text + ".html") assert txt.check() @@ -67,6 +69,17 @@ break curr = curr.dirpath() prefix += "../" + config = get_pypy_config() + # begin horror + h, n = config._cfgimpl_get_home_by_path('objspace.std.withmethodcache'); + opt = getattr(h._cfgimpl_descr, n) + # end horror + cmdline = get_cmdline(opt.cmdline, text) + shortest_long_option = 'X'*1000 + for cmd in cmdline.split(): + if cmd.startswith('--') and len(cmd) < len(shortest_long_option): + shortest_long_option = cmd + text = shortest_long_option target = prefix + relative print text, target reference_node = nodes.reference(rawtext, text, name=text, refuri=target) From mwh at codespeak.net Fri Feb 16 14:12:17 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 16 Feb 2007 14:12:17 +0100 (CET) Subject: [pypy-svn] r39006 - pypy/dist/pypy/doc Message-ID: <20070216131217.9F089100B0@code0.codespeak.net> Author: mwh Date: Fri Feb 16 14:12:13 2007 New Revision: 39006 Modified: pypy/dist/pypy/doc/conftest.py Log: hahaoops Modified: pypy/dist/pypy/doc/conftest.py ============================================================================== --- pypy/dist/pypy/doc/conftest.py (original) +++ pypy/dist/pypy/doc/conftest.py Fri Feb 16 14:12:13 2007 @@ -71,7 +71,7 @@ prefix += "../" config = get_pypy_config() # begin horror - h, n = config._cfgimpl_get_home_by_path('objspace.std.withmethodcache'); + h, n = config._cfgimpl_get_home_by_path(text); opt = getattr(h._cfgimpl_descr, n) # end horror cmdline = get_cmdline(opt.cmdline, text) From mwh at codespeak.net Fri Feb 16 14:18:30 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 16 Feb 2007 14:18:30 +0100 (CET) Subject: [pypy-svn] r39007 - pypy/dist/pypy/doc Message-ID: <20070216131830.EA02C100B3@code0.codespeak.net> Author: mwh Date: Fri Feb 16 14:18:29 2007 New Revision: 39007 Modified: pypy/dist/pypy/doc/conftest.py Log: protect against get_cmdline returning None. Modified: pypy/dist/pypy/doc/conftest.py ============================================================================== --- pypy/dist/pypy/doc/conftest.py (original) +++ pypy/dist/pypy/doc/conftest.py Fri Feb 16 14:18:29 2007 @@ -75,11 +75,12 @@ opt = getattr(h._cfgimpl_descr, n) # end horror cmdline = get_cmdline(opt.cmdline, text) - shortest_long_option = 'X'*1000 - for cmd in cmdline.split(): - if cmd.startswith('--') and len(cmd) < len(shortest_long_option): - shortest_long_option = cmd - text = shortest_long_option + if cmdline is not None: + shortest_long_option = 'X'*1000 + for cmd in cmdline.split(): + if cmd.startswith('--') and len(cmd) < len(shortest_long_option): + shortest_long_option = cmd + text = shortest_long_option target = prefix + relative print text, target reference_node = nodes.reference(rawtext, text, name=text, refuri=target) From pedronis at codespeak.net Fri Feb 16 14:32:51 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Fri, 16 Feb 2007 14:32:51 +0100 (CET) Subject: [pypy-svn] r39008 - pypy/dist Message-ID: <20070216133251.2F50D100B5@code0.codespeak.net> Author: pedronis Date: Fri Feb 16 14:32:50 2007 New Revision: 39008 Modified: pypy/dist/README Log: update generic README Modified: pypy/dist/README ============================================================================== --- pypy/dist/README (original) +++ pypy/dist/README Fri Feb 16 14:32:50 2007 @@ -1,5 +1,5 @@ ======================================================= -PyPy: Python in Python implementation / Version 0.9.0 +PyPy: Python in Python implementation / Version 0.99.0 ======================================================= PyPy is an implementation of the Python programming language, written @@ -23,8 +23,8 @@ For information in what's new in this release, please read the release announcement: - pypy/doc/release-0.9.0.txt - http://codespeak.net/pypy/dist/pypy/doc/release-0.9.0.html + pypy/doc/release-0.99.0.txt + http://codespeak.net/pypy/dist/pypy/doc/release-0.99.0.html Since December 2004, the development of PyPy has been funded by the European Union's research programme. For more information on this From pedronis at codespeak.net Fri Feb 16 14:33:13 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Fri, 16 Feb 2007 14:33:13 +0100 (CET) Subject: [pypy-svn] r39009 - pypy/dist Message-ID: <20070216133313.9A3E7100B7@code0.codespeak.net> Author: pedronis Date: Fri Feb 16 14:33:13 2007 New Revision: 39009 Modified: pypy/dist/LICENSE Log: copyright includes 2007 Modified: pypy/dist/LICENSE ============================================================================== --- pypy/dist/LICENSE (original) +++ pypy/dist/LICENSE Fri Feb 16 14:33:13 2007 @@ -27,7 +27,7 @@ DEALINGS IN THE SOFTWARE. -PyPy Copyright holders 2003-2006 +PyPy Copyright holders 2003-2007 ----------------------------------- Except when otherwise stated (look for LICENSE files or information at From ac at codespeak.net Fri Feb 16 14:38:10 2007 From: ac at codespeak.net (ac at codespeak.net) Date: Fri, 16 Feb 2007 14:38:10 +0100 (CET) Subject: [pypy-svn] r39010 - in pypy/dist: . pypy/doc pypy/doc/tool Message-ID: <20070216133810.88C4A100B2@code0.codespeak.net> Author: ac Date: Fri Feb 16 14:38:08 2007 New Revision: 39010 Modified: pypy/dist/LICENSE pypy/dist/pypy/doc/contributor.txt pypy/dist/pypy/doc/tool/makecontributor.py Log: Update the lists of authors and hack at makecontributor script to make this easier in the future. Modified: pypy/dist/LICENSE ============================================================================== --- pypy/dist/LICENSE (original) +++ pypy/dist/LICENSE Fri Feb 16 14:38:08 2007 @@ -34,39 +34,63 @@ the beginning of each file) the files in the 'pypy' directory are each copyrighted by one or more of the following people and organizations: - Armin Rigo - Samuele Pedroni - Holger Krekel - Christian Tismer - Michael Hudson - Carl Friedrich Bolz - Eric van Riet Paap - Richard Emslie - Anders Chrigstrom - Niklaus Haldimann - Antonio Cuni - Maciek Fijalkowski - Aur?lien Camp?as - Seo Sanghyeon - Alex Martelli - Anders Lehmann - Stephan Diehl - Patrick Maupin - Ludovic Aubry - Bob Ippolito - Adrien Di Mascio - Jacob Hallen - Laura Creighton - Marius Gedminas - Amaury Forgeot d Arc - Boris Feigin - Valentino Volonghi - Bert Freudenberg - Andrew Thompson - Jonathan David Riehl - Amaury Forgeot D Arc - Alexandre Fayolle - Guido van Rossum + Armin Rigo + Samuele Pedroni + Michael Hudson + Carl Friedrich Bolz + Christian Tismer + Holger Krekel + Eric van Riet Paap + Antonio Cuni + Anders Chrigstrom + Maciek Fijalkowski + Richard Emslie + Aurelien Campeas + Anders Lehmann + Niklaus Haldimann + Seo Sanghyeon + Lawrence Oluyede + Alex Martelli + Ludovic Aubry + Adrien Di Mascio + Stephan Diehl + Guido Wesdorp + Stefan Schwarzer + Tomek Meka + Patrick Maupin + Leonardo Santagada + Bob Ippolito + Laura Creighton + Jacob Hallen + Marius Gedminas + Niko Matsakis + Amaury Forgeot d Arc + Guido van Rossum + Valentino Volonghi + Alexander Schremmer + Alexandre Fayolle + Wanja Saatkamp + Gerald Klix + Eugene Oden + Dinu Gherman + Guenter Jantzen + Ben Young + Nicolas Chauvat + Michael Twomey + Rocco Moretti + Simon Burton + Boris Feigin + Olivier Dormond + Gintautas Miliauskas + Stuart Williams + Jens-Uwe Mager + Brian Dorsey + Jonathan David Riehl + Anders Qvist + Beatrice During + Andreas Friedge + Alan McIntyre + Bert Freudenberg Heinrich-Heine University, Germany AB Strakt, Sweden Modified: pypy/dist/pypy/doc/contributor.txt ============================================================================== --- pypy/dist/pypy/doc/contributor.txt (original) +++ pypy/dist/pypy/doc/contributor.txt Fri Feb 16 14:38:08 2007 @@ -6,48 +6,73 @@ code base, ordered by number of commits (which is certainly not a very appropriate measure but it's something):: - Armin Rigo + Armin Rigo Samuele Pedroni - Christian Tismer - Holger Krekel Michael Hudson Carl Friedrich Bolz + Christian Tismer + Holger Krekel Eric van Riet Paap + Antonio Cuni Anders Chrigstrom + Maciek Fijalkowski Richard Emslie - Anders Lehmann + Aurelien Campeas + Anders Lehmann + Niklaus Haldimann Seo Sanghyeon + Lawrence Oluyede Alex Martelli Ludovic Aubry Adrien Di Mascio + Stephan Diehl + Guido Wesdorp Stefan Schwarzer - Tomek Meka + Tomek Meka Patrick Maupin + Leonardo Santagada Bob Ippolito - Jacob Hallen Laura Creighton - Marius Gedminas - Niklaus Haldimann + Jacob Hallen + Marius Gedminas + Niko Matsakis Amaury Forgeot d Arc Guido van Rossum - Stephan Diehl + Valentino Volonghi + Alexander Schremmer + Alexandre Fayolle + Wanja Saatkamp + Gerald Klix + Eugene Oden Dinu Gherman Guenter Jantzen - Rocco Moretti - Boris Feigin + Ben Young + Nicolas Chauvat + Michael Twomey + Rocco Moretti + Simon Burton + Boris Feigin Olivier Dormond - Valentino Volonghi + Gintautas Miliauskas + Stuart Williams + Jens-Uwe Mager Brian Dorsey Jonathan David Riehl + Anders Qvist + Beatrice During Andreas Friedge - Jens-Uwe Mager - Bert Freudenberg Alan McIntyre - Anders Qvist + Bert Freudenberg + Pieter Zieschang + Jean-Paul Calderone + Jacob Oscarson + Ignas Mikalajunas Lutz Paelike - Jacek Generowicz + Christopher Armstrong + Yusei Tahara Andrew Thompson - Ben Young - Alexander Schremmer + Jacek Generowicz + Joshua Gilbert + Anna Ravencroft + Martin Blais Michael Chermside - Modified: pypy/dist/pypy/doc/tool/makecontributor.py ============================================================================== --- pypy/dist/pypy/doc/tool/makecontributor.py (original) +++ pypy/dist/pypy/doc/tool/makecontributor.py Fri Feb 16 14:38:08 2007 @@ -25,9 +25,15 @@ import uconf # http://codespeak.net/svn/uconf/dist/uconf +# Authors that don't want to be listed +excluded = set("anna gintas ignas".split()) +cutoff = 5 # cutoff for authors in the LICENS file +mark = False for author, count in items: - #user = uconf.system.User(author) - #realname = user.realname - #print "%5d" % count, " ", realname, "<%s>" % email - print count, " ", author - + user = uconf.system.User(author) + realname = user.realname.strip() + if not mark and count < cutoff: + mark = True + print '-'*60 + print " ", realname + #print count, " ", author From ac at codespeak.net Fri Feb 16 14:40:21 2007 From: ac at codespeak.net (ac at codespeak.net) Date: Fri, 16 Feb 2007 14:40:21 +0100 (CET) Subject: [pypy-svn] r39011 - pypy/dist/pypy/doc/tool Message-ID: <20070216134021.D07C5100B8@code0.codespeak.net> Author: ac Date: Fri Feb 16 14:40:19 2007 New Revision: 39011 Modified: pypy/dist/pypy/doc/tool/makecontributor.py Log: Typo Modified: pypy/dist/pypy/doc/tool/makecontributor.py ============================================================================== --- pypy/dist/pypy/doc/tool/makecontributor.py (original) +++ pypy/dist/pypy/doc/tool/makecontributor.py Fri Feb 16 14:40:19 2007 @@ -27,7 +27,7 @@ # Authors that don't want to be listed excluded = set("anna gintas ignas".split()) -cutoff = 5 # cutoff for authors in the LICENS file +cutoff = 5 # cutoff for authors in the LICENSE file mark = False for author, count in items: user = uconf.system.User(author) From santagada at codespeak.net Fri Feb 16 14:50:17 2007 From: santagada at codespeak.net (santagada at codespeak.net) Date: Fri, 16 Feb 2007 14:50:17 +0100 (CET) Subject: [pypy-svn] r39012 - pypy/dist/pypy/translator/goal Message-ID: <20070216135017.1A2A1100BD@code0.codespeak.net> Author: santagada Date: Fri Feb 16 14:50:16 2007 New Revision: 39012 Modified: pypy/dist/pypy/translator/goal/targetjsstandalone.py Log: small bugfix Modified: pypy/dist/pypy/translator/goal/targetjsstandalone.py ============================================================================== --- pypy/dist/pypy/translator/goal/targetjsstandalone.py (original) +++ pypy/dist/pypy/translator/goal/targetjsstandalone.py Fri Feb 16 14:50:16 2007 @@ -4,7 +4,6 @@ import sys from pypy.rlib.streamio import open_file_as_stream -from pypy.lang.js.interpreter import Interpreter from pypy.lang.js.interpreter import * from pypy.lang.js.jsobj import ExecutionReturned From pedronis at codespeak.net Fri Feb 16 14:50:46 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Fri, 16 Feb 2007 14:50:46 +0100 (CET) Subject: [pypy-svn] r39013 - pypy/extradoc/planning/0.99 Message-ID: <20070216135046.CB0F9100C0@code0.codespeak.net> Author: pedronis Date: Fri Feb 16 14:50:45 2007 New Revision: 39013 Modified: pypy/extradoc/planning/0.99/documentation.txt Log: update Modified: pypy/extradoc/planning/0.99/documentation.txt ============================================================================== --- pypy/extradoc/planning/0.99/documentation.txt (original) +++ pypy/extradoc/planning/0.99/documentation.txt Fri Feb 16 14:50:45 2007 @@ -9,17 +9,16 @@ important cross-check that things still works, update links... -contributor.txt: needs to be updated -README and LICENSE too - consult, improve *how-to-release.txt* Done, postponed ===================== -faq.txt: done for now. +contributor.txt: needs to be updated +EADME and LICENSE too: done +faq.txt: done for now. index.txt: review the directory cross-reference (done) From pedronis at codespeak.net Fri Feb 16 14:55:09 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Fri, 16 Feb 2007 14:55:09 +0100 (CET) Subject: [pypy-svn] r39014 - pypy/extradoc/planning/0.99 Message-ID: <20070216135509.B38D3100C0@code0.codespeak.net> Author: pedronis Date: Fri Feb 16 14:55:08 2007 New Revision: 39014 Modified: pypy/extradoc/planning/0.99/documentation.txt Log: better Modified: pypy/extradoc/planning/0.99/documentation.txt ============================================================================== --- pypy/extradoc/planning/0.99/documentation.txt (original) +++ pypy/extradoc/planning/0.99/documentation.txt Fri Feb 16 14:55:08 2007 @@ -15,8 +15,7 @@ Done, postponed ===================== -contributor.txt: needs to be updated -EADME and LICENSE too: done +contributor.txt, README and LICENSE: done faq.txt: done for now. From cfbolz at codespeak.net Fri Feb 16 15:15:32 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 16 Feb 2007 15:15:32 +0100 (CET) Subject: [pypy-svn] r39015 - pypy/dist/pypy/doc/config Message-ID: <20070216141532.A6433100CA@code0.codespeak.net> Author: cfbolz Date: Fri Feb 16 15:15:31 2007 New Revision: 39015 Modified: pypy/dist/pypy/doc/config/objspace.logbytecodes.txt Log: experimentally add the external comment to one of the doc files. Modified: pypy/dist/pypy/doc/config/objspace.logbytecodes.txt ============================================================================== --- pypy/dist/pypy/doc/config/objspace.logbytecodes.txt (original) +++ pypy/dist/pypy/doc/config/objspace.logbytecodes.txt Fri Feb 16 15:15:31 2007 @@ -1 +1,2 @@ Internal option. +.. internal From pedronis at codespeak.net Fri Feb 16 15:16:50 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Fri, 16 Feb 2007 15:16:50 +0100 (CET) Subject: [pypy-svn] r39016 - pypy/dist/pypy/doc Message-ID: <20070216141650.8B877100CE@code0.codespeak.net> Author: pedronis Date: Fri Feb 16 15:16:46 2007 New Revision: 39016 Modified: pypy/dist/pypy/doc/_ref.txt pypy/dist/pypy/doc/faq.txt Log: expand the last faq a bit. Modified: pypy/dist/pypy/doc/_ref.txt ============================================================================== --- pypy/dist/pypy/doc/_ref.txt (original) +++ pypy/dist/pypy/doc/_ref.txt Fri Feb 16 15:16:46 2007 @@ -112,6 +112,7 @@ .. _`translator/cli/`: ../../pypy/translator/cli .. _`translator/goal/`: ../../pypy/translator/goal .. _`pypy/translator/goal/targetnopstandalone.py`: ../../pypy/translator/goal/targetnopstandalone.py +.. _`pypy/translator/goal/targetprologstandalone.py`: ../../pypy/translator/goal/targetprologstandalone.py .. _`translator/js/`: ../../pypy/translator/js .. _`translator/jvm/`: ../../pypy/translator/jvm .. _`translator/lisp/`: ../../pypy/translator/lisp Modified: pypy/dist/pypy/doc/faq.txt ============================================================================== --- pypy/dist/pypy/doc/faq.txt (original) +++ pypy/dist/pypy/doc/faq.txt Fri Feb 16 15:16:46 2007 @@ -331,8 +331,11 @@ You can have a look at intermediate C source code, which is (at the moment) put in ``/tmp/usession-*/testing_1/testing_1.c``. Of course, -all the functions and stuff used directly and indirectly by your ``entry_point()`` -function has to be RPython_. +all the functions and stuff used directly and indirectly by your +``entry_point()`` function has to be RPython_. Another example you may +want to look at is `pypy/translator/goal/targetprologstandalone.py`_, +the target for the in-progress Prolog implementation; this target for +example enables a stackless build programmatically. .. _`RPython`: coding-guide.html#rpython From cfbolz at codespeak.net Fri Feb 16 15:20:27 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 16 Feb 2007 15:20:27 +0100 (CET) Subject: [pypy-svn] r39017 - pypy/dist/pypy/config Message-ID: <20070216142027.61683100D2@code0.codespeak.net> Author: cfbolz Date: Fri Feb 16 15:20:25 2007 New Revision: 39017 Modified: pypy/dist/pypy/config/makerestdoc.py Log: slightly hackish way to mark options as internal and have them get their own section. Modified: pypy/dist/pypy/config/makerestdoc.py ============================================================================== --- pypy/dist/pypy/config/makerestdoc.py (original) +++ pypy/dist/pypy/config/makerestdoc.py Fri Feb 16 15:20:25 2007 @@ -7,6 +7,8 @@ from pypy.config.config import ArbitraryOption, DEFAULT_OPTION_NAME from pypy.config.config import _getnegation +configdocdir = py.magic.autopath().dirpath().dirpath().join("doc", "config") + def get_fullpath(opt, path): if path: return "%s.%s" % (path, opt._name) @@ -163,6 +165,19 @@ return content +def _get_section_header(cmdline, fullpath, subdescr): + # XXX: pypy specific hack + txtfile = configdocdir.join(fullpath + ".txt") + print txtfile, + if not txtfile.check(): + print "not found" + return "" + print "found" + content = txtfile.read() + if ".. internal" in content: + return "Internal Options" + return "" + def make_cmdline_overview(descr): content = Rest( Title("Overwiew of Command Line Options for '%s'" % (descr._name, ), @@ -176,11 +191,18 @@ subdescr = getattr(subconf._cfgimpl_descr, step) cmdline = get_cmdline(subdescr.cmdline, fullpath) if cmdline is not None: - cmdlines.append((cmdline, fullpath, subdescr)) - cmdlines.sort(key=lambda t: t[0].strip("-")) - for cmdline, fullpath, subdescr in cmdlines: - content.add(ListItem(Link(cmdline + ":", fullpath + ".html"), - Text(subdescr.doc))) + header = _get_section_header(cmdline, fullpath, subdescr) + cmdlines.append((header, cmdline, fullpath, subdescr)) + cmdlines.sort(key=lambda x: (x[0], x[1].strip("-"))) + currheader = "" + curr = content + for header, cmdline, fullpath, subdescr in cmdlines: + if header != currheader: + content.add(Title(header, abovechar="", belowchar="=")) + curr = content.add(Paragraph()) + currheader = header + curr.add(ListItem(Link(cmdline + ":", fullpath + ".html"), + Text(subdescr.doc))) return content From mwh at codespeak.net Fri Feb 16 15:37:52 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 16 Feb 2007 15:37:52 +0100 (CET) Subject: [pypy-svn] r39018 - pypy/dist/pypy/doc/config Message-ID: <20070216143752.329C9100D7@code0.codespeak.net> Author: mwh Date: Fri Feb 16 15:37:50 2007 New Revision: 39018 Modified: pypy/dist/pypy/doc/config/confrest.py Log: redo the navigation bar links Modified: pypy/dist/pypy/doc/config/confrest.py ============================================================================== --- pypy/dist/pypy/doc/config/confrest.py (original) +++ pypy/dist/pypy/doc/config/confrest.py Fri Feb 16 15:37:50 2007 @@ -16,10 +16,10 @@ self.menubar[:] = html.div( html.a("general documentation", href="../index.html", class_="menu"), " ", - html.a("translation options", href="translation.html", - class_="menu"), - html.a("standard interpreter options", href="objspace.html", - class_="menu"), + html.a("config index", href="index.html", + class_="menu"), " ", + html.a("command-line overview", href="commandline.html", + class_="menu"), " ", " ", id="menubar") class Project(Project): From pedronis at codespeak.net Fri Feb 16 15:43:01 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Fri, 16 Feb 2007 15:43:01 +0100 (CET) Subject: [pypy-svn] r39019 - pypy/dist/pypy/doc/config Message-ID: <20070216144301.5F25C100D5@code0.codespeak.net> Author: pedronis Date: Fri Feb 16 15:42:55 2007 New Revision: 39019 Modified: pypy/dist/pypy/doc/config/objspace.compiler.txt pypy/dist/pypy/doc/config/objspace.parser.txt pypy/dist/pypy/doc/config/objspace.std.withdictmeasurement.txt pypy/dist/pypy/doc/config/objspace.std.withtypeversion.txt pypy/dist/pypy/doc/config/objspace.usemodules._file.txt pypy/dist/pypy/doc/config/objspace.usemodules._pickle_support.txt Log: mark internal option for objspace Modified: pypy/dist/pypy/doc/config/objspace.compiler.txt ============================================================================== --- pypy/dist/pypy/doc/config/objspace.compiler.txt (original) +++ pypy/dist/pypy/doc/config/objspace.compiler.txt Fri Feb 16 15:42:55 2007 @@ -1,2 +1,2 @@ Internal option. - +.. internal Modified: pypy/dist/pypy/doc/config/objspace.parser.txt ============================================================================== --- pypy/dist/pypy/doc/config/objspace.parser.txt (original) +++ pypy/dist/pypy/doc/config/objspace.parser.txt Fri Feb 16 15:42:55 2007 @@ -1 +1,2 @@ Internal option. +.. internal Modified: pypy/dist/pypy/doc/config/objspace.std.withdictmeasurement.txt ============================================================================== --- pypy/dist/pypy/doc/config/objspace.std.withdictmeasurement.txt (original) +++ pypy/dist/pypy/doc/config/objspace.std.withdictmeasurement.txt Fri Feb 16 15:42:55 2007 @@ -1 +1,2 @@ Internal option. +.. internal Modified: pypy/dist/pypy/doc/config/objspace.std.withtypeversion.txt ============================================================================== --- pypy/dist/pypy/doc/config/objspace.std.withtypeversion.txt (original) +++ pypy/dist/pypy/doc/config/objspace.std.withtypeversion.txt Fri Feb 16 15:42:55 2007 @@ -2,3 +2,4 @@ (only internally visible) version that is updated when the type's dict is changed. This is e.g. used for invalidating caches. It does not make sense to enable this option alone. +.. internal Modified: pypy/dist/pypy/doc/config/objspace.usemodules._file.txt ============================================================================== --- pypy/dist/pypy/doc/config/objspace.usemodules._file.txt (original) +++ pypy/dist/pypy/doc/config/objspace.usemodules._file.txt Fri Feb 16 15:42:55 2007 @@ -1,2 +1,3 @@ Use the '_file' module. It is an internal module that contains helper functionality for the builtin ``file`` type. +.. internal Modified: pypy/dist/pypy/doc/config/objspace.usemodules._pickle_support.txt ============================================================================== --- pypy/dist/pypy/doc/config/objspace.usemodules._pickle_support.txt (original) +++ pypy/dist/pypy/doc/config/objspace.usemodules._pickle_support.txt Fri Feb 16 15:42:55 2007 @@ -1,5 +1,5 @@ Use the '_pickle_support' module. Internal helpers for pickling runtime builtin types (frames, cells, etc) for `stackless`_ tasklet pickling support. - .. _`stackless`: ../stackless.html +.. internal From cfbolz at codespeak.net Fri Feb 16 15:50:37 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 16 Feb 2007 15:50:37 +0100 (CET) Subject: [pypy-svn] r39020 - pypy/dist/pypy/doc/config Message-ID: <20070216145037.47489100D3@code0.codespeak.net> Author: cfbolz Date: Fri Feb 16 15:50:36 2007 New Revision: 39020 Modified: pypy/dist/pypy/doc/config/objspace.compiler.txt pypy/dist/pypy/doc/config/objspace.logbytecodes.txt pypy/dist/pypy/doc/config/objspace.parser.txt pypy/dist/pypy/doc/config/objspace.std.withdictmeasurement.txt pypy/dist/pypy/doc/config/objspace.std.withtypeversion.txt pypy/dist/pypy/doc/config/objspace.usemodules._file.txt pypy/dist/pypy/doc/config/objspace.usemodules._pickle_support.txt pypy/dist/pypy/doc/config/translation.backendopt.clever_malloc_removal_heuristic.txt pypy/dist/pypy/doc/config/translation.backendopt.inline_heuristic.txt pypy/dist/pypy/doc/config/translation.backendopt.profile_based_inline_heuristic.txt pypy/dist/pypy/doc/config/translation.backendopt.raisingop2direct_call.txt pypy/dist/pypy/doc/config/translation.builtins_can_raise_exceptions.txt pypy/dist/pypy/doc/config/translation.cli.trace_calls.txt pypy/dist/pypy/doc/config/translation.countmallocs.txt pypy/dist/pypy/doc/config/translation.instrument.txt pypy/dist/pypy/doc/config/translation.instrumentctl.txt pypy/dist/pypy/doc/config/translation.simplifying.txt Log: more .. internal Modified: pypy/dist/pypy/doc/config/objspace.compiler.txt ============================================================================== --- pypy/dist/pypy/doc/config/objspace.compiler.txt (original) +++ pypy/dist/pypy/doc/config/objspace.compiler.txt Fri Feb 16 15:50:36 2007 @@ -1,2 +1,3 @@ Internal option. + .. internal Modified: pypy/dist/pypy/doc/config/objspace.logbytecodes.txt ============================================================================== --- pypy/dist/pypy/doc/config/objspace.logbytecodes.txt (original) +++ pypy/dist/pypy/doc/config/objspace.logbytecodes.txt Fri Feb 16 15:50:36 2007 @@ -1,2 +1,3 @@ Internal option. + .. internal Modified: pypy/dist/pypy/doc/config/objspace.parser.txt ============================================================================== --- pypy/dist/pypy/doc/config/objspace.parser.txt (original) +++ pypy/dist/pypy/doc/config/objspace.parser.txt Fri Feb 16 15:50:36 2007 @@ -1,2 +1,3 @@ Internal option. + .. internal Modified: pypy/dist/pypy/doc/config/objspace.std.withdictmeasurement.txt ============================================================================== --- pypy/dist/pypy/doc/config/objspace.std.withdictmeasurement.txt (original) +++ pypy/dist/pypy/doc/config/objspace.std.withdictmeasurement.txt Fri Feb 16 15:50:36 2007 @@ -1,2 +1,3 @@ Internal option. + .. internal Modified: pypy/dist/pypy/doc/config/objspace.std.withtypeversion.txt ============================================================================== --- pypy/dist/pypy/doc/config/objspace.std.withtypeversion.txt (original) +++ pypy/dist/pypy/doc/config/objspace.std.withtypeversion.txt Fri Feb 16 15:50:36 2007 @@ -2,4 +2,5 @@ (only internally visible) version that is updated when the type's dict is changed. This is e.g. used for invalidating caches. It does not make sense to enable this option alone. + .. internal Modified: pypy/dist/pypy/doc/config/objspace.usemodules._file.txt ============================================================================== --- pypy/dist/pypy/doc/config/objspace.usemodules._file.txt (original) +++ pypy/dist/pypy/doc/config/objspace.usemodules._file.txt Fri Feb 16 15:50:36 2007 @@ -1,3 +1,4 @@ Use the '_file' module. It is an internal module that contains helper functionality for the builtin ``file`` type. + .. internal Modified: pypy/dist/pypy/doc/config/objspace.usemodules._pickle_support.txt ============================================================================== --- pypy/dist/pypy/doc/config/objspace.usemodules._pickle_support.txt (original) +++ pypy/dist/pypy/doc/config/objspace.usemodules._pickle_support.txt Fri Feb 16 15:50:36 2007 @@ -2,4 +2,5 @@ Internal helpers for pickling runtime builtin types (frames, cells, etc) for `stackless`_ tasklet pickling support. .. _`stackless`: ../stackless.html + .. internal Modified: pypy/dist/pypy/doc/config/translation.backendopt.clever_malloc_removal_heuristic.txt ============================================================================== --- pypy/dist/pypy/doc/config/translation.backendopt.clever_malloc_removal_heuristic.txt (original) +++ pypy/dist/pypy/doc/config/translation.backendopt.clever_malloc_removal_heuristic.txt Fri Feb 16 15:50:36 2007 @@ -1,2 +1,4 @@ Internal option. Switch to a different weight heuristic for inlining. This is for clever malloc removal (:config:`translation.backendopt.clever_malloc_removal`). + +.. internal Modified: pypy/dist/pypy/doc/config/translation.backendopt.inline_heuristic.txt ============================================================================== --- pypy/dist/pypy/doc/config/translation.backendopt.inline_heuristic.txt (original) +++ pypy/dist/pypy/doc/config/translation.backendopt.inline_heuristic.txt Fri Feb 16 15:50:36 2007 @@ -1,2 +1,4 @@ Internal option. Switch to a different weight heuristic for inlining. This is for basic inlining (:config:`translation.backendopt.inline`). + +.. internal Modified: pypy/dist/pypy/doc/config/translation.backendopt.profile_based_inline_heuristic.txt ============================================================================== --- pypy/dist/pypy/doc/config/translation.backendopt.profile_based_inline_heuristic.txt (original) +++ pypy/dist/pypy/doc/config/translation.backendopt.profile_based_inline_heuristic.txt Fri Feb 16 15:50:36 2007 @@ -1,2 +1,4 @@ Internal option. Switch to a different weight heuristic for inlining. This is for profile-based inlining (:config:`translation.backendopt.profile_based_inline`). + +.. internal Modified: pypy/dist/pypy/doc/config/translation.backendopt.raisingop2direct_call.txt ============================================================================== --- pypy/dist/pypy/doc/config/translation.backendopt.raisingop2direct_call.txt (original) +++ pypy/dist/pypy/doc/config/translation.backendopt.raisingop2direct_call.txt Fri Feb 16 15:50:36 2007 @@ -1,2 +1,3 @@ Internal option. Transformation required by the LLVM backend. +.. internal Modified: pypy/dist/pypy/doc/config/translation.builtins_can_raise_exceptions.txt ============================================================================== --- pypy/dist/pypy/doc/config/translation.builtins_can_raise_exceptions.txt (original) +++ pypy/dist/pypy/doc/config/translation.builtins_can_raise_exceptions.txt Fri Feb 16 15:50:36 2007 @@ -1 +1,3 @@ -Internal option. \ No newline at end of file +Internal option. + +.. internal Modified: pypy/dist/pypy/doc/config/translation.cli.trace_calls.txt ============================================================================== --- pypy/dist/pypy/doc/config/translation.cli.trace_calls.txt (original) +++ pypy/dist/pypy/doc/config/translation.cli.trace_calls.txt Fri Feb 16 15:50:36 2007 @@ -1 +1,3 @@ Internal. Debugging aid for the CLI backend. + +.. internal Modified: pypy/dist/pypy/doc/config/translation.countmallocs.txt ============================================================================== --- pypy/dist/pypy/doc/config/translation.countmallocs.txt (original) +++ pypy/dist/pypy/doc/config/translation.countmallocs.txt Fri Feb 16 15:50:36 2007 @@ -1,2 +1,4 @@ Internal; used by some of the C backend tests to check that the number of allocations matches the number of frees. + +.. internal Modified: pypy/dist/pypy/doc/config/translation.instrument.txt ============================================================================== --- pypy/dist/pypy/doc/config/translation.instrument.txt (original) +++ pypy/dist/pypy/doc/config/translation.instrument.txt Fri Feb 16 15:50:36 2007 @@ -1 +1,3 @@ -Internal option. \ No newline at end of file +Internal option. + +.. internal Modified: pypy/dist/pypy/doc/config/translation.instrumentctl.txt ============================================================================== --- pypy/dist/pypy/doc/config/translation.instrumentctl.txt (original) +++ pypy/dist/pypy/doc/config/translation.instrumentctl.txt Fri Feb 16 15:50:36 2007 @@ -1 +1,3 @@ Internal option. + +.. internal Modified: pypy/dist/pypy/doc/config/translation.simplifying.txt ============================================================================== --- pypy/dist/pypy/doc/config/translation.simplifying.txt (original) +++ pypy/dist/pypy/doc/config/translation.simplifying.txt Fri Feb 16 15:50:36 2007 @@ -1 +1,3 @@ -Internal option. \ No newline at end of file +Internal option. + +.. internal From cfbolz at codespeak.net Fri Feb 16 15:59:56 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 16 Feb 2007 15:59:56 +0100 (CET) Subject: [pypy-svn] r39021 - pypy/dist/pypy/doc/config Message-ID: <20070216145956.A62E4100D9@code0.codespeak.net> Author: cfbolz Date: Fri Feb 16 15:59:56 2007 New Revision: 39021 Modified: pypy/dist/pypy/doc/config/index.txt Log: link to the documentation! Modified: pypy/dist/pypy/doc/config/index.txt ============================================================================== --- pypy/dist/pypy/doc/config/index.txt (original) +++ pypy/dist/pypy/doc/config/index.txt Fri Feb 16 15:59:56 2007 @@ -40,9 +40,9 @@ do for your objects`_. .. _`configuration`: ../configuration.html -.. _`object space`: objspace.html +.. _`object space`: ../objspace.html .. _`objspace options`: objspace.html -.. _`translation`: translation.html +.. _`translation`: ../translation.html .. _`translation options`: translation.html .. _`overview`: commandline.html .. _`Alternative object implementations in the PyPy standard interpreter`: ../object-optimizations.html From cfbolz at codespeak.net Fri Feb 16 16:14:50 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 16 Feb 2007 16:14:50 +0100 (CET) Subject: [pypy-svn] r39022 - pypy/dist/pypy/doc/config Message-ID: <20070216151450.7AD59100D9@code0.codespeak.net> Author: cfbolz Date: Fri Feb 16 16:14:49 2007 New Revision: 39022 Modified: pypy/dist/pypy/doc/config/commandline.txt pypy/dist/pypy/doc/config/index.txt Log: adjust links. hack a bit to fool py.test into believing that they are there Modified: pypy/dist/pypy/doc/config/commandline.txt ============================================================================== --- pypy/dist/pypy/doc/config/commandline.txt (original) +++ pypy/dist/pypy/doc/config/commandline.txt Fri Feb 16 16:14:49 2007 @@ -1 +1,4 @@ -.. intentionally empty +.. intentionally empty, but contains the following comment to fool py.test: + overwiew of command line options for objspace + overwiew of command line options for translation + Modified: pypy/dist/pypy/doc/config/index.txt ============================================================================== --- pypy/dist/pypy/doc/config/index.txt (original) +++ pypy/dist/pypy/doc/config/index.txt Fri Feb 16 16:14:49 2007 @@ -4,8 +4,8 @@ This directory contains documentation for the many `configuration`_ options that can be used to affect PyPy's behaviour. There are two -main classes of option, `object space`_ options and `translation`_ -options. +main classes of option, `object space options`_ and `translation +options`_. There are two main entry points that accept options: ``py.py``, which implements Python on top of another Python interpreter and accepts all @@ -40,10 +40,9 @@ do for your objects`_. .. _`configuration`: ../configuration.html -.. _`object space`: ../objspace.html -.. _`objspace options`: objspace.html -.. _`translation`: ../translation.html -.. _`translation options`: translation.html +.. _`objspace options`: commandline.html#overwiew-of-command-line-options-for-objspace +.. _`object space`: commandline.html#overwiew-of-command-line-options-for-objspace +.. _`translation options`: commandline.html#overwiew-of-command-line-options-for-translation .. _`overview`: commandline.html .. _`Alternative object implementations in the PyPy standard interpreter`: ../object-optimizations.html .. _`What PyPy can do for your objects`: ../objspace-proxies.html From pedronis at codespeak.net Fri Feb 16 16:24:29 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Fri, 16 Feb 2007 16:24:29 +0100 (CET) Subject: [pypy-svn] r39023 - pypy/dist/pypy/doc/config Message-ID: <20070216152429.BAC4F100D7@code0.codespeak.net> Author: pedronis Date: Fri Feb 16 16:24:28 2007 New Revision: 39023 Modified: pypy/dist/pypy/doc/config/index.txt Log: last fixes Modified: pypy/dist/pypy/doc/config/index.txt ============================================================================== --- pypy/dist/pypy/doc/config/index.txt (original) +++ pypy/dist/pypy/doc/config/index.txt Fri Feb 16 16:24:28 2007 @@ -9,7 +9,7 @@ There are two main entry points that accept options: ``py.py``, which implements Python on top of another Python interpreter and accepts all -the `object space`_ options: +the `object space options`_: .. parsed-literal:: @@ -23,7 +23,7 @@ ./translate.py <`translation options`_> For the common case of ```` being ``targetpypystandalone.py``, -you can then pass the `object space`_ options after +you can then pass the `object space options`_ after ``targetpypystandalone.py``, i.e. like this: .. parsed-literal:: @@ -41,7 +41,7 @@ .. _`configuration`: ../configuration.html .. _`objspace options`: commandline.html#overwiew-of-command-line-options-for-objspace -.. _`object space`: commandline.html#overwiew-of-command-line-options-for-objspace +.. _`object space options`: commandline.html#overwiew-of-command-line-options-for-objspace .. _`translation options`: commandline.html#overwiew-of-command-line-options-for-translation .. _`overview`: commandline.html .. _`Alternative object implementations in the PyPy standard interpreter`: ../object-optimizations.html From pedronis at codespeak.net Fri Feb 16 16:28:46 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Fri, 16 Feb 2007 16:28:46 +0100 (CET) Subject: [pypy-svn] r39024 - pypy/release/0.99.x Message-ID: <20070216152846.18185100E2@code0.codespeak.net> Author: pedronis Date: Fri Feb 16 16:28:44 2007 New Revision: 39024 Added: pypy/release/0.99.x/ - copied from r39023, pypy/dist/ Log: release branch for 0.99 From pedronis at codespeak.net Fri Feb 16 16:45:50 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Fri, 16 Feb 2007 16:45:50 +0100 (CET) Subject: [pypy-svn] r39025 - in pypy/release/0.99.x/pypy: config doc/config module/Numeric Message-ID: <20070216154550.A582B100DF@code0.codespeak.net> Author: pedronis Date: Fri Feb 16 16:45:49 2007 New Revision: 39025 Removed: pypy/release/0.99.x/pypy/doc/config/objspace.usemodules.Numeric.txt pypy/release/0.99.x/pypy/doc/config/objspace.usemodules.readline.txt pypy/release/0.99.x/pypy/module/Numeric/ Modified: pypy/release/0.99.x/pypy/config/pypyoption.py Log: - hide readline module from the command line - remove Numeric from 0.99 Modified: pypy/release/0.99.x/pypy/config/pypyoption.py ============================================================================== --- pypy/release/0.99.x/pypy/config/pypyoption.py (original) +++ pypy/release/0.99.x/pypy/config/pypyoption.py Fri Feb 16 16:45:49 2007 @@ -5,10 +5,12 @@ from pypy.config.config import OptionDescription, BoolOption, IntOption, ArbitraryOption from pypy.config.config import ChoiceOption, StrOption, to_optparse, Config +exclude = ['readline'] + modulepath = py.magic.autopath().dirpath().dirpath().join("module") all_modules = [p.basename for p in modulepath.listdir() if p.check(dir=True, dotfile=False) - and p.join('__init__.py').check()] + and p.join('__init__.py').check() and p.basename not in exclude] essential_modules = dict.fromkeys( ["exceptions", "_file", "sys", "__builtin__", "posix"] From pedronis at codespeak.net Fri Feb 16 16:57:48 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Fri, 16 Feb 2007 16:57:48 +0100 (CET) Subject: [pypy-svn] r39026 - in pypy/release/0.99.x/pypy: doc doc/config jit jit/codegen jit/goal jit/hintannotator jit/timeshifter jit/tl module/pypyjit Message-ID: <20070216155748.ED0FB100E6@code0.codespeak.net> Author: pedronis Date: Fri Feb 16 16:57:47 2007 New Revision: 39026 Removed: pypy/release/0.99.x/pypy/doc/config/objspace.usemodules.pypyjit.txt pypy/release/0.99.x/pypy/jit/TODO.txt pypy/release/0.99.x/pypy/jit/__init__.py pypy/release/0.99.x/pypy/jit/codegen/ pypy/release/0.99.x/pypy/jit/conftest.py pypy/release/0.99.x/pypy/jit/goal/ pypy/release/0.99.x/pypy/jit/hintannotator/ pypy/release/0.99.x/pypy/jit/timeshifter/ pypy/release/0.99.x/pypy/jit/tl/ pypy/release/0.99.x/pypy/module/pypyjit/ Modified: pypy/release/0.99.x/pypy/doc/index.txt Log: - removing pypyjit module - emptying the jit directory - removing some references from doc/index.txt, annotating some others with a non-inclusion comment Modified: pypy/release/0.99.x/pypy/doc/index.txt ============================================================================== --- pypy/release/0.99.x/pypy/doc/index.txt (original) +++ pypy/release/0.99.x/pypy/doc/index.txt Fri Feb 16 16:57:47 2007 @@ -124,7 +124,7 @@ `CLI backend`_ describes the details of the .NET backend. `JIT Generation in PyPy`_ describes how we produce the Python Just-in-time Compiler -from our Python interpreter. +from our Python interpreter (Code not included in 0.99). @@ -193,18 +193,7 @@ `interpreter/astcompiler/`_ interpreter-level bytecode compiler, via an AST representation -`jit/`_ the `just-in-time compiler generator`_ - -`jit/codegen/`_ `jit backends`_ for different architectures - -`jit/goal/`_ the translation targets that produce a PyPy with a JIT_ - -`jit/hintannotator/`_ the `hint-annotator`_ that analyzes an interpreter - -`jit/timeshifter/`_ the `timeshifter`_ that turns an interpreter into a JIT compiler - -`jit/tl/`_ interpreters for toy languages, with which we test the - JIT generator +`jit/`_ the `just-in-time compiler generator`_ (not in 0.99) `lang/`_ interpreters for non-Python languages, written in RPython_ From guido at codespeak.net Fri Feb 16 16:58:42 2007 From: guido at codespeak.net (guido at codespeak.net) Date: Fri, 16 Feb 2007 16:58:42 +0100 (CET) Subject: [pypy-svn] r39027 - pypy/branch/guido-buildtool-web Message-ID: <20070216155842.E5F2C100E9@code0.codespeak.net> Author: guido Date: Fri Feb 16 16:58:41 2007 New Revision: 39027 Added: pypy/branch/guido-buildtool-web/ - copied from r39026, pypy/dist/ Log: Creating branch to not interfere with the release work. From pedronis at codespeak.net Fri Feb 16 17:07:05 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Fri, 16 Feb 2007 17:07:05 +0100 (CET) Subject: [pypy-svn] r39029 - pypy/release/0.99.x/pypy/tool Message-ID: <20070216160705.F16F6100EE@code0.codespeak.net> Author: pedronis Date: Fri Feb 16 17:07:04 2007 New Revision: 39029 Modified: pypy/release/0.99.x/pypy/tool/makerelease.py Log: change makerelease for 0.99 Modified: pypy/release/0.99.x/pypy/tool/makerelease.py ============================================================================== --- pypy/release/0.99.x/pypy/tool/makerelease.py (original) +++ pypy/release/0.99.x/pypy/tool/makerelease.py Fri Feb 16 17:07:04 2007 @@ -5,7 +5,7 @@ log = py.log.Producer("log") logexec = py.log.Producer("exec") -BASEURL = "file:///svn/pypy/release/0.9.x" +BASEURL = "file:///svn/pypy/release/0.99.x" DDIR = py.path.local('/www/codespeak.net/htdocs/download/pypy') def usage(): From guido at codespeak.net Fri Feb 16 17:23:35 2007 From: guido at codespeak.net (guido at codespeak.net) Date: Fri, 16 Feb 2007 17:23:35 +0100 (CET) Subject: [pypy-svn] r39030 - in pypy/branch/guido-buildtool-web/pypy/tool/build: . templates test Message-ID: <20070216162335.C9E6A100F2@code0.codespeak.net> Author: guido Date: Fri Feb 16 17:23:34 2007 New Revision: 39030 Added: pypy/branch/guido-buildtool-web/pypy/tool/build/templates/builderinfo.html pypy/branch/guido-buildtool-web/pypy/tool/build/templates/buildersinfo.html pypy/branch/guido-buildtool-web/pypy/tool/build/test/test_webapp.py Modified: pypy/branch/guido-buildtool-web/pypy/tool/build/build.py pypy/branch/guido-buildtool-web/pypy/tool/build/config.py pypy/branch/guido-buildtool-web/pypy/tool/build/conftest.py pypy/branch/guido-buildtool-web/pypy/tool/build/metaserver.py pypy/branch/guido-buildtool-web/pypy/tool/build/templates/index.html pypy/branch/guido-buildtool-web/pypy/tool/build/templates/serverstatus.html pypy/branch/guido-buildtool-web/pypy/tool/build/test/fake.py pypy/branch/guido-buildtool-web/pypy/tool/build/test/test_build.py pypy/branch/guido-buildtool-web/pypy/tool/build/test/test_metaserver.py pypy/branch/guido-buildtool-web/pypy/tool/build/webapp.py pypy/branch/guido-buildtool-web/pypy/tool/build/webserver.py Log: Added some more pages and some more information on the BuildRequest objects to display. Some pages don't yet display anything, though, and not all the information that we're interested in is available yet. Also small cleanups of the tests, and added some 'missing tests'. Modified: pypy/branch/guido-buildtool-web/pypy/tool/build/build.py ============================================================================== --- pypy/branch/guido-buildtool-web/pypy/tool/build/build.py (original) +++ pypy/branch/guido-buildtool-web/pypy/tool/build/build.py Fri Feb 16 17:23:34 2007 @@ -110,6 +110,9 @@ self.svnurl = svnurl self.svnrev = svnrev self.revrange = revrange + self.request_time = py.std.time.time() + self.build_start_time = None + self.build_end_time = None def __str__(self): return '' % (self.svnurl, self.normalized_rev) @@ -119,7 +122,8 @@ """ return 'build.BuildRequest(%r, %r, %r, %r, %r, %r)' % ( self.email, self.sysinfo, self.compileinfo, self.svnurl, - self.svnrev, self.revrange) + self.svnrev, self.revrange, self.request_time, + self.build_start_time, self.build_end_time) def serialize(self): data = {'normalized_rev': self.normalized_rev} # it's a property @@ -132,6 +136,9 @@ svnrev: %(svnrev)s revrange: %(revrange)s normalized_rev: %(normalized_rev)s +request_time: %(request_time)s +build_start_time: %(build_start_time)s +build_end_time: %(build_end_time)s """ % data def _fromstring(cls, s): @@ -146,6 +153,9 @@ eval(data['compileinfo']), data['svnurl'], data['svnrev'], int(data['revrange'])) ret._nr = int(data['normalized_rev']) + ret.request_time = eval(data['request_time']) + ret.build_start_time = eval(data['build_start_time']) + ret.build_end_time = eval(data['build_end_time']) return ret fromstring = classmethod(_fromstring) Modified: pypy/branch/guido-buildtool-web/pypy/tool/build/config.py ============================================================================== --- pypy/branch/guido-buildtool-web/pypy/tool/build/config.py (original) +++ pypy/branch/guido-buildtool-web/pypy/tool/build/config.py Fri Feb 16 17:23:34 2007 @@ -3,7 +3,7 @@ packageparent = py.magic.autopath().dirpath().dirpath().dirpath().dirpath() # general settings, used by both server and client -server = 'codespeak.net' +server = 'localhost' port = 12321 testport = 32123 path = [str(packageparent)] Modified: pypy/branch/guido-buildtool-web/pypy/tool/build/conftest.py ============================================================================== --- pypy/branch/guido-buildtool-web/pypy/tool/build/conftest.py (original) +++ pypy/branch/guido-buildtool-web/pypy/tool/build/conftest.py Fri Feb 16 17:23:34 2007 @@ -9,6 +9,11 @@ action="store_true", dest="functional", default=False, help="run pypybuilder functional tests" ), + Option('', '--webcheck', + action="store_true", dest="webcheck", default=False, + help=("run (X)HTML validity tests (using " + "http://www.w3c.org/validator)") + ), ) class Directory(Dir): Modified: pypy/branch/guido-buildtool-web/pypy/tool/build/metaserver.py ============================================================================== --- pypy/branch/guido-buildtool-web/pypy/tool/build/metaserver.py (original) +++ pypy/branch/guido-buildtool-web/pypy/tool/build/metaserver.py Fri Feb 16 17:23:34 2007 @@ -25,6 +25,9 @@ return False return True +def make_id(build): + """ generate a unique, but predictable id for a build """ + class MetaServer(object): """ the build meta-server @@ -171,12 +174,28 @@ def status(self): # XXX temporary - in_progress = len([b for b in self._builders if b.busy_on]) - return {'in_progress': in_progress, + running = len([b for b in self._builders if b.busy_on]) + return {'builders': len(self._builders), + 'running': running, 'queued': len(self._queued), - 'waiting': len(self._waiting), + 'waiting': len(self._waiting) + running, 'done': len(self._done)} + def buildersinfo(self): + ret = [] + for b in self._builders: + print 'busy_on:', b.busy_on + print 'resolved:', b.busy_on and b.busy_on.compileinfo or None + ret.append({ + 'hostname': b.hostname, + 'sysinfo': b.sysinfo, + 'busy_on': b.busy_on and b.busy_on.compileinfo or None, + }) + return ret + + def buildids(self): + pass + def _cleanup_builders(self): self._queuelock.acquire() try: Added: pypy/branch/guido-buildtool-web/pypy/tool/build/templates/builderinfo.html ============================================================================== --- (empty file) +++ pypy/branch/guido-buildtool-web/pypy/tool/build/templates/builderinfo.html Fri Feb 16 17:23:34 2007 @@ -0,0 +1,8 @@ +
+

%(hostname)s

+
+
sysinfo: %(sysinfo)s
+
busy on: %(busy_on)s
+
+
+ Added: pypy/branch/guido-buildtool-web/pypy/tool/build/templates/buildersinfo.html ============================================================================== --- (empty file) +++ pypy/branch/guido-buildtool-web/pypy/tool/build/templates/buildersinfo.html Fri Feb 16 17:23:34 2007 @@ -0,0 +1,13 @@ + + + + Build meta server builders page + + +

Connected build servers

+
+%(builders)s +
+ + + Modified: pypy/branch/guido-buildtool-web/pypy/tool/build/templates/index.html ============================================================================== --- pypy/branch/guido-buildtool-web/pypy/tool/build/templates/index.html (original) +++ pypy/branch/guido-buildtool-web/pypy/tool/build/templates/index.html Fri Feb 16 17:23:34 2007 @@ -1,9 +1,13 @@ + Build meta server web interface (temp index page) - server status + Modified: pypy/branch/guido-buildtool-web/pypy/tool/build/templates/serverstatus.html ============================================================================== --- pypy/branch/guido-buildtool-web/pypy/tool/build/templates/serverstatus.html (original) +++ pypy/branch/guido-buildtool-web/pypy/tool/build/templates/serverstatus.html Fri Feb 16 17:23:34 2007 @@ -1,3 +1,4 @@ + Build meta server status page @@ -5,10 +6,10 @@

Server status

    -
  • Currently in progress: %(in_progress)s
  • +
  • Connected build servers: %(builders)s
  • +
  • Currently running builds: %(running)s
  • Builds done: %(done)s
  • -
  • Waiting (clients for which a suitable build is in progress already): - %(waiting)s
  • +
  • Clients waiting for a build: %(waiting)s
  • Builds for which no suitable server is available: %(queued)s
Modified: pypy/branch/guido-buildtool-web/pypy/tool/build/test/fake.py ============================================================================== --- pypy/branch/guido-buildtool-web/pypy/tool/build/test/fake.py (original) +++ pypy/branch/guido-buildtool-web/pypy/tool/build/test/fake.py Fri Feb 16 17:23:34 2007 @@ -17,9 +17,10 @@ pass class FakeBuildserver(object): - def __init__(self, info): + def __init__(self, info, compile_info=None): self.channel = FakeChannel() self.sysinfo = info + self.compileinfo = compile_info or {} self.busy_on = None self.refused = [] self.hostname = "fake" Modified: pypy/branch/guido-buildtool-web/pypy/tool/build/test/test_build.py ============================================================================== --- pypy/branch/guido-buildtool-web/pypy/tool/build/test/test_build.py (original) +++ pypy/branch/guido-buildtool-web/pypy/tool/build/test/test_build.py Fri Feb 16 17:23:34 2007 @@ -93,7 +93,10 @@ svnrev: HEAD revrange: 0 normalized_rev: 1 -""" +request_time: %s +build_start_time: None +build_end_time: None +""" % (br.request_time,) assert build.BuildRequest.fromstring(ser).serialize() == ser py.test.raises(SyntaxError, 'build.BuildRequest.fromstring("foo")') Modified: pypy/branch/guido-buildtool-web/pypy/tool/build/test/test_metaserver.py ============================================================================== --- pypy/branch/guido-buildtool-web/pypy/tool/build/test/test_metaserver.py (original) +++ pypy/branch/guido-buildtool-web/pypy/tool/build/test/test_metaserver.py Fri Feb 16 17:23:34 2007 @@ -13,10 +13,11 @@ mailhost=None) mod.svr = metaserver.MetaServer(config, FakeChannel()) - mod.c1 = FakeBuildserver({'foo': 1, 'bar': [1,2]}) + mod.c1 = FakeBuildserver({'foo': 1, 'bar': [1,2]}, {'spam': ['spam', + 'eggs']}) mod.svr.register(mod.c1) - mod.c2 = FakeBuildserver({'foo': 2, 'bar': [2,3]}) + mod.c2 = FakeBuildserver({'foo': 2, 'bar': [2,3]}, {'spam': 'eggs'}) mod.svr.register(mod.c2) def test_server_issubdict(): @@ -39,6 +40,7 @@ assert svr._builders[0] == c1 assert svr._builders[1] == c2 + py.test.raises(IndexError, "c1.channel.receive()") assert svr._channel.receive().find('registered') > -1 @@ -158,7 +160,6 @@ assert bp2.check() def test_status(): - return temppath = py.test.ensuretemp('test_status') config = Container(projectname='test', buildpath=temppath) svr = metaserver.MetaServer(config, FakeChannel()) @@ -170,10 +171,24 @@ bs = FakeBuildserver({}) bs.busy_on = 'foo' svr._builders.append(bs) + print svr.status() assert svr.status() == { 'done': 2, 'queued': 3, - 'waiting': 0, - 'in_progress': 1, + 'waiting': 1, + 'running': 1, + 'builders': 1, } +def test_buildersinfo(): + bi = svr.buildersinfo() + assert len(bi) == 2 + assert bi[0]['sysinfo'] == {'foo': 1, 'bar': [1,2]} + assert bi[0]['busy_on'] == None + assert bi[1]['sysinfo'] == {'foo': 2, 'bar': [2,3]} + svr._builders[0].busy_on = c1 + bi = svr.buildersinfo() + assert bi[0]['busy_on'] + # for now, later more info should be made available + assert bi[0]['busy_on'] == c1.compileinfo + Added: pypy/branch/guido-buildtool-web/pypy/tool/build/test/test_webapp.py ============================================================================== --- (empty file) +++ pypy/branch/guido-buildtool-web/pypy/tool/build/test/test_webapp.py Fri Feb 16 17:23:34 2007 @@ -0,0 +1,148 @@ +import py +from py.__.test.web.webcheck import check_html +from pypy.tool.build.webapp import * +from pypy.tool.build.conftest import option +from pypy.tool.build.test import fake +from pypy.tool.build import config as build_config + +TESTPORT = build_config.testport + +here = py.magic.autopath().dirpath() +pypyparent = here.dirpath().dirpath().dirpath().dirpath() + +def html_validate(html): + if not option.webcheck: + py.test.skip('Skipping XHTML validation (rest of the test passed)') + check_html(html) + +class TestTemplate(object): + def test_render(self): + # XXX stupid test ;) but perhaps we're going to add features later or + # something... + s = py.std.StringIO.StringIO('%(foo)s') + s.seek(0) + t = Template(s) + assert t.render({'foo': 'bar'}) == 'bar' + +class FakeMetaServer(object): + def __init__(self): + self._status = {} + self._builders = [] + + def status(self): + return self._status + + def buildersinfo(self): + return self._builders + +_metaserver_init = """ + import sys + sys.path += %r + + from pypy.tool.build.test.test_webapp import FakeMetaServer + from pypy.tool import build + build.metaserver_instance = s = FakeMetaServer() + try: + while 1: + command = channel.receive() + if command == 'quit': + break + command, data = command + if command == 'set_status': + s._status = data + elif command == 'set_buildersinfo': + s._builders = data + finally: + channel.close() +""" + +def init_fake_metaserver(port, path): + gw = py.execnet.PopenGateway() + conference = execnetconference.conference(gw, port, True) + channel = conference.remote_exec(_metaserver_init % (path,)) + return channel + +def setup_module(mod): + mod.path = path = pypyparent.strpath + mod.server_channel = init_fake_metaserver(TESTPORT, path) + mod.config = fake.Container(port=TESTPORT, path=path) + mod.gateway = py.execnet.PopenGateway() + +def teardown_module(mod): + mod.server_channel.send('quit') + mod.gateway.exit() + +class TestIndexPage(object): + def test_handle(self): + p = IndexPage() + headers, html = p.handle(None, '/', '') + assert headers == {'Content-Type': 'text/html; charset=UTF-8'} + assert html.strip().startswith('') + html_validate(html) + +class TestServerStatusPage(object): + def test_get_status(self): + p = ServerStatusPage(config, gateway) + assert p.get_status() == {} + server_channel.send(('set_status', {'foo': 'bar'})) + assert p.get_status() == {'foo': 'bar'} + + def test_handle(self): + server_channel.send(('set_status', {'builders': 3, 'running': 2, + 'done': 7, 'waiting': 5, + 'queued': 2})) + p = ServerStatusPage(config, gateway) + headers, html = p.handle(None, '/serverstatus', '') + assert headers == {'Content-Type': 'text/html; charset=UTF-8'} + assert html.strip().startswith('') + html_validate(html) + +class TestBuilderInfoPage(object): + def test_get_builderinfo(self): + p = BuildersInfoPage(config, gateway) + assert p.get_buildersinfo() == [] + server_channel.send(('set_buildersinfo', [{'foo': 'bar'}])) + assert p.get_buildersinfo() == [{'foo': 'bar'}] + + def test_handle(self): + server_channel.send(('set_buildersinfo', [{'hostname': 'host1', + 'sysinfo': {'foo': 'bar'}, + 'busy_on': None}, + {'hostname': 'host2', + 'sysinfo': {'foo': 'baz'}, + 'busy_on': {'spam': 'eggs'}, + }])) + p = BuildersInfoPage(config, gateway) + headers, html = p.handle(None, '/buildersinfo', '') + assert headers == {'Content-Type': 'text/html; charset=UTF-8'} + assert html.strip().startswith('') + html_validate(html) + +class TestBuildPage(object): + def test_handle(self): + pass + +class TestBuildCollectionIndexPage(object): + def test_get_builds(self): + pass + + def test_handle(self): + p = BuildCollectionIndexPage(config, gateway) + headers, html = p.handle(None, '/builds/', '') + assert headers == {'Content-Type': 'text/html; charset=UTF-8'} + assert html.strip().startswith('') + html_validate(html) + +class TestBuildCollection(object): + def test_traverse(self): + p = BuildCollection(config, gateway) + assert p.traverse(['index'], '/builds/index') is p.index + assert p.traverse([''], '/builds/') is p.index + assert isinstance(p.traverse(['foo'], '/builds/foo'), BuildPage) + py.test.raises(HTTPError, + "p.traverse(['foo', 'bar'], '/builds/foo/bar')") + Modified: pypy/branch/guido-buildtool-web/pypy/tool/build/webapp.py ============================================================================== --- pypy/branch/guido-buildtool-web/pypy/tool/build/webapp.py (original) +++ pypy/branch/guido-buildtool-web/pypy/tool/build/webapp.py Fri Feb 16 17:23:34 2007 @@ -10,6 +10,11 @@ mypath = py.magic.autopath().dirpath() class Template(object): + """ very stupid template class + + does nothing more than string interpolation, no loop constructs or + other fancyness: you will have to do that yourself + """ def __init__(self, path): self.template = path.read() @@ -20,55 +25,131 @@ """ the index page """ def handle(self, handler, path, query): template = Template(mypath.join('templates/index.html')) - return {'Content-Type': 'text/html'}, template.render({}) + return ({'Content-Type': 'text/html; charset=UTF-8'}, + template.render({})) -class ServerStatus(Resource): - """ a page displaying overall meta server statistics """ +class ServerPage(Resource): + """ base class for pages that communicate with the server + """ + + def __init__(self, config, gateway=None): + self.config = config + self.gateway = gateway or self.init_gateway() remote_code = """ import sys sys.path += %r - try: - from pypy.tool.build import metaserver_instance - ret = metaserver_instance.status() - channel.send(ret) - channel.close() - except: - import sys, traceback - exc, e, tb = sys.exc_info() - channel.send(str(exc) + ' - ' + str(e)) - for line in traceback.format_tb(tb): - channel.send(line[:-1]) - del tb + from pypy.tool.build import metaserver_instance + ret = metaserver_instance.%s(%s) + channel.send(ret) + channel.close() """ + def call_method(self, methodname, args=''): + """ calls a method on the server + + methodname is the name of the method to call, args is a string + which is _interpolated_ into the method call (so if you want to + pass the integers 1 and 2 as arguments, 'args' will become '1, 2') + """ + conference = execnetconference.conference(self.gateway, + self.config.port, False) + channel = conference.remote_exec(self.remote_code % (self.config.path, + methodname, + args)) + ret = channel.receive() + channel.close() + return ret + + def init_gateway(self): + if self.config.server in ['localhost', '127.0.0.1']: + gw = py.execnet.PopenGateway() + else: + gw = py.execnet.SshGateway(self.config.server) + return gw + +class ServerStatusPage(ServerPage): + """ a page displaying overall meta server statistics """ + def handle(self, handler, path, query): template = Template(mypath.join('templates/serverstatus.html')) return ({'Content-Type': 'text/html; charset=UTF-8'}, template.render(self.get_status())) def get_status(self): - if config.server in ['localhost', '127.0.0.1']: - gw = py.execnet.PopenGateway() - else: - gw = py.execnet.SshGateway(config.server) + return self.call_method('status') - conference = execnetconference.conference(gw, config.port, False) - channel = conference.remote_exec(self.remote_code % (config.path,)) - ret = channel.receive() - channel.close() - return ret +class BuildersInfoPage(ServerPage): + def handle(self, handler, path, query): + template = Template(mypath.join('templates/buildersinfo.html')) + context = { + 'builders': '\n'.join([self.get_builder_html(b) + for b in self.get_buildersinfo()]) + } + return ({'Content-Type': 'text/html; charset=UTF-8'}, + template.render(context)) + + def get_buildersinfo(self): + return self.call_method('buildersinfo') + + def get_builder_html(self, buildinfo): + template = Template(mypath.join('templates/builderinfo.html')) + return template.render(buildinfo) + +class BuildPage(ServerPage): + """ display information for one build """ + + def __init__(self, buildid, config, gateway=None): + super(BuildPage, self).__init__(config, gateway) + self._buildid = buildid + + def handle(self, handler, path, query): + pass + +class BuildCollectionIndexPage(ServerPage): + """ display the list of available builds """ + + def handle(self, handler, path, query): + template = Template(mypath.join('templates/builds.html')) + context = {'builds': '\n'.join([self.get_build_html(b) for b in + self.get_builds()])} + return ({'Content-Type': 'text/html; charset=UTF-8'}, + template.render(context)) + + def get_builds(self): + return [] + +class BuildCollection(Collection): + """ container for BuildCollectionIndexPage and BuildPage """ + + def __init__(self, config, gateway=None): + self.index = BuildCollectionIndexPage(config, gateway) + self.config = config + self.gateway = gateway + + def traverse(self, path, orgpath): + """ generate a BuildPage on the fly """ + # next element of the path is the id of the build '//' + name = path.pop() + if name in ['', 'index']: + return self.index + if len(path): + # no Collection type children here... + raise HTTPError(404) + # we have a name for a build, let's build a page for it (if it can't + # be found, this page will raise an exception) + return BuildPage(name, self.config, self.gateway) class Application(Collection): """ the application root """ index = IndexPage() - serverstatus = ServerStatus() - foo = Collection() - foo.index = IndexPage() + serverstatus = ServerStatusPage(config) + buildersinfo = BuildersInfoPage(config) + builds = BuildCollection(config) class AppHandler(Handler): - application = Application() # shared by all instances! + application = Application() if __name__ == '__main__': from pypy.tool.build.webserver import run_server Modified: pypy/branch/guido-buildtool-web/pypy/tool/build/webserver.py ============================================================================== --- pypy/branch/guido-buildtool-web/pypy/tool/build/webserver.py (original) +++ pypy/branch/guido-buildtool-web/pypy/tool/build/webserver.py Fri Feb 16 17:23:34 2007 @@ -96,6 +96,9 @@ return resource class Handler(BaseHTTPRequestHandler): + """ BaseHTTPRequestHandler that does object publishing + """ + application = None # attach web root (Collection object) here!! bufsize = 1024 @@ -143,6 +146,8 @@ return self.application.traverse(chunks, path) def process_http_error(self, e): + """ create the response body and headers for errors + """ headers = {'Content-Type': 'text/plain'} # XXX need more headers here? if e.status in [301, 302]: headers['Location'] = e.data @@ -152,6 +157,8 @@ return headers, body def response(self, status, headers, body): + """ generate the HTTP response and send it to the client + """ self.send_response(status) if (isinstance(body, str) and not 'content-length' in [k.lower() for k in headers]): @@ -171,6 +178,8 @@ raise ValueError('body is not a plain string or file-like object') def run_server(address, handler): + """ run a BaseHTTPServer instance + """ server = HTTPServer(address, handler) server.serve_forever() From guido at codespeak.net Fri Feb 16 17:24:04 2007 From: guido at codespeak.net (guido at codespeak.net) Date: Fri, 16 Feb 2007 17:24:04 +0100 (CET) Subject: [pypy-svn] r39031 - pypy/branch/guido-buildtool-web/pypy/tool/build/templates Message-ID: <20070216162404.44B1410070@code0.codespeak.net> Author: guido Date: Fri Feb 16 17:24:03 2007 New Revision: 39031 Added: pypy/branch/guido-buildtool-web/pypy/tool/build/templates/builds.html Log: Missed this template. Added: pypy/branch/guido-buildtool-web/pypy/tool/build/templates/builds.html ============================================================================== --- (empty file) +++ pypy/branch/guido-buildtool-web/pypy/tool/build/templates/builds.html Fri Feb 16 17:24:03 2007 @@ -0,0 +1,18 @@ + + + + Build meta server builds page + + +

Overview of builds

+

+ Here you see an overview of all builds, both completed (and available + for download) and waiting or in-progress ones, ordered by date. Click + on the build to get more information. +

+
+%(builds)s +
+ + + From guido at codespeak.net Fri Feb 16 17:39:40 2007 From: guido at codespeak.net (guido at codespeak.net) Date: Fri, 16 Feb 2007 17:39:40 +0100 (CET) Subject: [pypy-svn] r39032 - in pypy/branch/guido-buildtool-web/pypy/tool/build: . templates test web web/templates web/test Message-ID: <20070216163940.25697100F2@code0.codespeak.net> Author: guido Date: Fri Feb 16 17:39:40 2007 New Revision: 39032 Added: pypy/branch/guido-buildtool-web/pypy/tool/build/web/ (props changed) pypy/branch/guido-buildtool-web/pypy/tool/build/web/__init__.py pypy/branch/guido-buildtool-web/pypy/tool/build/web/conftest.py pypy/branch/guido-buildtool-web/pypy/tool/build/web/templates/ - copied from r39027, pypy/branch/guido-buildtool-web/pypy/tool/build/templates/ pypy/branch/guido-buildtool-web/pypy/tool/build/web/templates/builderinfo.html - copied unchanged from r39031, pypy/branch/guido-buildtool-web/pypy/tool/build/templates/builderinfo.html pypy/branch/guido-buildtool-web/pypy/tool/build/web/templates/buildersinfo.html - copied unchanged from r39031, pypy/branch/guido-buildtool-web/pypy/tool/build/templates/buildersinfo.html pypy/branch/guido-buildtool-web/pypy/tool/build/web/templates/builds.html - copied unchanged from r39031, pypy/branch/guido-buildtool-web/pypy/tool/build/templates/builds.html pypy/branch/guido-buildtool-web/pypy/tool/build/web/templates/index.html - copied unchanged from r39031, pypy/branch/guido-buildtool-web/pypy/tool/build/templates/index.html pypy/branch/guido-buildtool-web/pypy/tool/build/web/templates/serverstatus.html - copied unchanged from r39031, pypy/branch/guido-buildtool-web/pypy/tool/build/templates/serverstatus.html pypy/branch/guido-buildtool-web/pypy/tool/build/web/test/ (props changed) pypy/branch/guido-buildtool-web/pypy/tool/build/web/test/__init__.py pypy/branch/guido-buildtool-web/pypy/tool/build/web/test/test_webapp.py (contents, props changed) - copied, changed from r39030, pypy/branch/guido-buildtool-web/pypy/tool/build/test/test_webapp.py pypy/branch/guido-buildtool-web/pypy/tool/build/web/test/test_webserver.py (contents, props changed) - copied, changed from r39031, pypy/branch/guido-buildtool-web/pypy/tool/build/test/test_webserver.py pypy/branch/guido-buildtool-web/pypy/tool/build/web/webapp.py (contents, props changed) - copied, changed from r39030, pypy/branch/guido-buildtool-web/pypy/tool/build/webapp.py pypy/branch/guido-buildtool-web/pypy/tool/build/web/webserver.py (props changed) - copied unchanged from r39030, pypy/branch/guido-buildtool-web/pypy/tool/build/webserver.py Removed: pypy/branch/guido-buildtool-web/pypy/tool/build/templates/ pypy/branch/guido-buildtool-web/pypy/tool/build/test/test_webapp.py pypy/branch/guido-buildtool-web/pypy/tool/build/test/test_webserver.py pypy/branch/guido-buildtool-web/pypy/tool/build/webapp.py pypy/branch/guido-buildtool-web/pypy/tool/build/webserver.py Modified: pypy/branch/guido-buildtool-web/pypy/tool/build/build.py pypy/branch/guido-buildtool-web/pypy/tool/build/conftest.py pypy/branch/guido-buildtool-web/pypy/tool/build/test/__init__.py (props changed) Log: Moved web-related stuff to a seperate dir, fixed a problem with BuildRequest's __repr__ (interpolation bug). Modified: pypy/branch/guido-buildtool-web/pypy/tool/build/build.py ============================================================================== --- pypy/branch/guido-buildtool-web/pypy/tool/build/build.py (original) +++ pypy/branch/guido-buildtool-web/pypy/tool/build/build.py Fri Feb 16 17:39:40 2007 @@ -103,16 +103,18 @@ holds information about a build request, and some functionality to serialize and unserialize itself """ - def __init__(self, email, sysinfo, compileinfo, svnurl, svnrev, revrange): + def __init__(self, email, sysinfo, compileinfo, svnurl, svnrev, revrange, + request_time=None, build_start_time=None, + build_end_time=None): self.email = email self.sysinfo = sysinfo self.compileinfo = compileinfo self.svnurl = svnurl self.svnrev = svnrev self.revrange = revrange - self.request_time = py.std.time.time() - self.build_start_time = None - self.build_end_time = None + self.request_time = request_time or py.std.time.time() + self.build_start_time = build_start_time + self.build_end_time = build_end_time def __str__(self): return '' % (self.svnurl, self.normalized_rev) @@ -120,7 +122,7 @@ def __repr__(self): """ the result of this method can be exec-ed when build.py is imported """ - return 'build.BuildRequest(%r, %r, %r, %r, %r, %r)' % ( + return 'build.BuildRequest(%r, %r, %r, %r, %r, %r, %s, %s, %s)' % ( self.email, self.sysinfo, self.compileinfo, self.svnurl, self.svnrev, self.revrange, self.request_time, self.build_start_time, self.build_end_time) Modified: pypy/branch/guido-buildtool-web/pypy/tool/build/conftest.py ============================================================================== --- pypy/branch/guido-buildtool-web/pypy/tool/build/conftest.py (original) +++ pypy/branch/guido-buildtool-web/pypy/tool/build/conftest.py Fri Feb 16 17:39:40 2007 @@ -9,15 +9,11 @@ action="store_true", dest="functional", default=False, help="run pypybuilder functional tests" ), - Option('', '--webcheck', - action="store_true", dest="webcheck", default=False, - help=("run (X)HTML validity tests (using " - "http://www.w3c.org/validator)") - ), ) class Directory(Dir): def run(self): if self.fspath == mypath: - return ['test'] + return ['test', 'web'] return super(Directory, self).run() + Added: pypy/branch/guido-buildtool-web/pypy/tool/build/web/__init__.py ============================================================================== --- (empty file) +++ pypy/branch/guido-buildtool-web/pypy/tool/build/web/__init__.py Fri Feb 16 17:39:40 2007 @@ -0,0 +1 @@ +# Added: pypy/branch/guido-buildtool-web/pypy/tool/build/web/conftest.py ============================================================================== --- (empty file) +++ pypy/branch/guido-buildtool-web/pypy/tool/build/web/conftest.py Fri Feb 16 17:39:40 2007 @@ -0,0 +1,12 @@ +import py +from py.__.doc.conftest import Directory as Dir, DoctestText, \ + ReSTChecker +Option = py.test.config.Option +option = py.test.config.addoptions("pypybuilder test options", + Option('', '--webcheck', + action="store_true", dest="webcheck", default=False, + help=("run (X)HTML validity tests (using " + "http://www.w3c.org/validator)") + ), +) + Added: pypy/branch/guido-buildtool-web/pypy/tool/build/web/test/__init__.py ============================================================================== --- (empty file) +++ pypy/branch/guido-buildtool-web/pypy/tool/build/web/test/__init__.py Fri Feb 16 17:39:40 2007 @@ -0,0 +1 @@ +# From cfbolz at codespeak.net Fri Feb 16 18:14:52 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 16 Feb 2007 18:14:52 +0100 (CET) Subject: [pypy-svn] r39033 - pypy/release/0.99.x/pypy/translator/tool Message-ID: <20070216171452.B6AE5100ED@code0.codespeak.net> Author: cfbolz Date: Fri Feb 16 18:14:51 2007 New Revision: 39033 Modified: pypy/release/0.99.x/pypy/translator/tool/graphpage.py Log: the jit is not there Modified: pypy/release/0.99.x/pypy/translator/tool/graphpage.py ============================================================================== --- pypy/release/0.99.x/pypy/translator/tool/graphpage.py (original) +++ pypy/release/0.99.x/pypy/translator/tool/graphpage.py Fri Feb 16 18:14:51 2007 @@ -148,9 +148,12 @@ self.annotator.binding_cause_history.get(var, [])) self.binding_history[var.name] = zip(history, cause_history) - from pypy.jit.hintannotator.annotator import HintAnnotator - if isinstance(self.annotator, HintAnnotator): - return + try: + from pypy.jit.hintannotator.annotator import HintAnnotator + if isinstance(self.annotator, HintAnnotator): + return + except ImportError: # jit not included e.g. in 0.99 + pass vars = {} for graph in graphs: From cfbolz at codespeak.net Fri Feb 16 18:15:28 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 16 Feb 2007 18:15:28 +0100 (CET) Subject: [pypy-svn] r39034 - pypy/release/0.99.x/pypy/doc Message-ID: <20070216171528.CA095100F7@code0.codespeak.net> Author: cfbolz Date: Fri Feb 16 18:15:27 2007 New Revision: 39034 Modified: pypy/release/0.99.x/pypy/doc/getting-started.txt Log: fix links to 0.99 thunk has grown __pytrace__ output is different now Modified: pypy/release/0.99.x/pypy/doc/getting-started.txt ============================================================================== --- pypy/release/0.99.x/pypy/doc/getting-started.txt (original) +++ pypy/release/0.99.x/pypy/doc/getting-started.txt Fri Feb 16 18:15:27 2007 @@ -27,26 +27,26 @@ .. _gettingpypy: -Downloading & running the PyPy 0.9 release -------------------------------------------- +Downloading & running the PyPy 0.99 release +-------------------------------------------- Download one of the following release files and unpack it: -*pypy-0.9* +*pypy-0.99* * download one of - * `pypy-0.9.0.tar.bz2`_ (unix line endings) or - * `pypy-0.9.0.tar.gz`_ (unix line endings) or - * `pypy-0.9.0.zip`_ (windows line-endings) and unpack it + * `pypy-0.99.0.tar.bz2`_ (unix line endings) or + * `pypy-0.99.0.tar.gz`_ (unix line endings) or + * `pypy-0.99.0.zip`_ (windows line-endings) and unpack it * alternatively run - * ``svn co http://codespeak.net/svn/pypy/release/0.9.x pypy-0.9.x`` - (the 0.9 maintenance branch) + * ``svn co http://codespeak.net/svn/pypy/release/0.99.x pypy-0.99.x`` + (the 0.99 maintenance branch) -to get it from the subversion repository then change to the -``pypy-0.9.0`` or ``pypy-0.9.x`` directory and execute the following +to get it from the subversion repository. Then change to the +``pypy-0.99.0`` or ``pypy-0.99.x`` directory and execute the following command line:: python pypy/bin/py.py @@ -62,9 +62,9 @@ dependant on CPython anymore and becomes faster. .. _`95% of CPythons core language regression tests`: http://codespeak.net/~hpk/pypy-testresult/ -.. _`pypy-0.9.0.tar.bz2`: http://codespeak.net/download/pypy/pypy-0.9.0.tar.bz2 -.. _`pypy-0.9.0.zip`: http://codespeak.net/download/pypy/pypy-0.9.0.zip -.. _`pypy-0.9.0.tar.gz`: http://codespeak.net/download/pypy/pypy-0.9.0.tar.gz +.. _`pypy-0.99.0.tar.bz2`: http://codespeak.net/download/pypy/pypy-0.99.0.tar.bz2 +.. _`pypy-0.99.0.zip`: http://codespeak.net/download/pypy/pypy-0.99.0.zip +.. _`pypy-0.99.0.tar.gz`: http://codespeak.net/download/pypy/pypy-0.99.0.tar.gz Svn-check out & run the latest PyPy as a two-liner -------------------------------------------------- @@ -242,9 +242,8 @@ |- 6 BINARY_ADD |- add(W_IntObject(1), W_IntObject(2)) -> W_IntObject(3) |- 7 STORE_NAME 0 (a) - |- setitem(W_DictObject([ + |- hash(W_StringObject('a')) -> W_IntObject(-468864544) + |- int_w(W_IntObject(-468864544)) -> -468864544 |-10 LOAD_CONST 2 () |-13 RETURN_VALUE |- <<<< leave a = 1 + 2 @ 1 >>>> @@ -288,7 +287,7 @@ It is interesting to note that this lazy-computing Python extension is solely implemented in a small `objspace/thunk.py`_ file consisting -of around 100 lines of code. Since the 0.8.0 release it is even possible +of around 200 lines of code. Since the 0.8.0 release it is even possible to `translate PyPy with the thunk object space`_. Logic programming From ac at codespeak.net Fri Feb 16 18:55:38 2007 From: ac at codespeak.net (ac at codespeak.net) Date: Fri, 16 Feb 2007 18:55:38 +0100 (CET) Subject: [pypy-svn] r39039 - pypy/release/0.99.x/pypy/tool Message-ID: <20070216175538.445E5100F3@code0.codespeak.net> Author: ac Date: Fri Feb 16 18:55:37 2007 New Revision: 39039 Modified: pypy/release/0.99.x/pypy/tool/makerelease.py Log: Add code for generating html files. Modified: pypy/release/0.99.x/pypy/tool/makerelease.py ============================================================================== --- pypy/release/0.99.x/pypy/tool/makerelease.py (original) +++ pypy/release/0.99.x/pypy/tool/makerelease.py Fri Feb 16 18:55:37 2007 @@ -70,6 +70,18 @@ %(lineend, BASEURL, target)) assert target.check(dir=1) +def build_html(target): + docdir = target.join('pypy').join('doc') + old = docdir.chdir() + try: + # Generate the html files. + out = cexec("python2.4 ../test_all.py") + # Remove any .pyc files created in the process + target.chdir() + out = cexec("find . -name '*.pyc' -print0 | xargs -0 -r rm") + finally: + old.chdir() + if __name__ == '__main__': argc = len(py.std.sys.argv) if argc <= 1: @@ -80,6 +92,7 @@ target = tmpdir.join(ver) forced_export(BASEURL, target, lineend="LF") + build_html(target) target_targz = maketargz(target) assert target_targz.check(file=1) copydownload(target_targz) @@ -89,6 +102,7 @@ copydownload(target_tarbzip) forced_export(BASEURL, target, lineend="CRLF") + build_html(target) target_zip = makezip(target) assert target_zip.check(file=1) copydownload(target_zip) From cfbolz at codespeak.net Fri Feb 16 19:01:18 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 16 Feb 2007 19:01:18 +0100 (CET) Subject: [pypy-svn] r39040 - pypy/release/0.99.x/pypy/doc Message-ID: <20070216180118.B07E1100F8@code0.codespeak.net> Author: cfbolz Date: Fri Feb 16 19:01:16 2007 New Revision: 39040 Modified: pypy/release/0.99.x/pypy/doc/getting-started.txt Log: some more fixes + small additions to getting started Modified: pypy/release/0.99.x/pypy/doc/getting-started.txt ============================================================================== --- pypy/release/0.99.x/pypy/doc/getting-started.txt (original) +++ pypy/release/0.99.x/pypy/doc/getting-started.txt Fri Feb 16 19:01:16 2007 @@ -510,7 +510,7 @@ executable directly from the shell; you can find the executable in one of the ``/tmp/usession-*`` directories:: - anto at anto anto$ mono /tmp/usession-anto/main.exe 4 5 + $ mono /tmp/usession-/main.exe 4 5 9 To translate and run for CLI you must have the SDK installed: Windows @@ -549,7 +549,7 @@ ultimate example of source that our translation toolchain can process:: cd pypy/translator/goal - python translate.py --run + python translate.py --run targetpypystandalone.py By default the translation process will try to use the `Boehm-Demers-Weiser garbage collector`_ for the translated PyPy (Use @@ -560,7 +560,11 @@ This whole process will take some time and quite a lot of memory. To reduce the memory footprint of the translation process you can use the -option ``--lowmem`` With this option the whole process should be +option ``--lowmem``:: + + python translate.py --run targetpypystandalone.py --lowmem + +With this option the whole process should be runnable on a machine with 512Mb of RAM. If the translation is finished running and after you closed the graph you will be greeted (because of ``--run`` option) by the friendly prompt of a PyPy @@ -581,7 +585,7 @@ With the default options, you can find the produced executable under the name ``pypy-c``. Type ``pypy-c --help`` to see the options it supports -- -mainly the same basic options of CPython. In addition, ``pypy-c --info`` +mainly the same basic options as CPython. In addition, ``pypy-c --info`` prints the translation options that where used to produce this particular executable. This executable contains a lot of things that are hard-coded for your particular system (including paths), so it's not really meant to @@ -619,6 +623,7 @@ cd pypy/translator/goal python translate.py targetrpystonedalone +This will produce the executable "targetrpystonedalone-c". .. _`configuration sections`: config/ From cfbolz at codespeak.net Fri Feb 16 19:29:54 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 16 Feb 2007 19:29:54 +0100 (CET) Subject: [pypy-svn] r39041 - pypy/release/0.99.x/pypy/doc Message-ID: <20070216182954.EC745100FC@code0.codespeak.net> Author: cfbolz Date: Fri Feb 16 19:29:53 2007 New Revision: 39041 Modified: pypy/release/0.99.x/pypy/doc/release-0.99.0.txt Log: small improvements to the release doc Modified: pypy/release/0.99.x/pypy/doc/release-0.99.0.txt ============================================================================== --- pypy/release/0.99.x/pypy/doc/release-0.99.0.txt (original) +++ pypy/release/0.99.x/pypy/doc/release-0.99.0.txt Fri Feb 16 19:29:53 2007 @@ -74,23 +74,24 @@ objects are "declassified" in order to send information across IO barriers. - - TProxy: An object space hack, which allows you to create - objects of any type, with custom behavior, defined by your own - function. For details see + - Transparent proxies: An addition to the standard object space, which allows + you to create objects of builtin types with completely customised + behaviour. For details see http://codespeak.net/pypy/dist/pypy/doc/proxy.html XXX Move link to the bottom? * optimizations: - experimental new optimized implementations for various built in Python types (strings, dicts, lists) - - speed up of 5-7 compared to 0.9, overall 2-3 slower than - CPython + - twice the of the 0.9 release, overall 2-3 slower than CPython * Demonstrations of Javascript-Backend / AJAX experiments: XXX play1 pointer? * new configuration system: - XXX + There is a new comprehensive configuration system that allows the + fine-grained configuration of the PyPy standard interpreter and the + translation process. * improved documentation: XXX point to main new docs @@ -117,7 +118,7 @@ * the Logic object space, which provides Logic Variables in PyPy, needs to undergo a bit more testing. A constraint problem solver - extension module is ready, and needs to be integrated in the codebase. + extension module is ready, and needs to be integrated with the codebase. * we'd like to package and improve configurations and and testing, and actually ask for your help @@ -125,7 +126,7 @@ base for further developments IOW, PyPy 0.99 is the start for getting to 1.0 end of March 2007, -which we intend to become a base for a longer (and more relaxed:) +which we intend to become a base for a longer (and more relaxed :) time to come. From auc at codespeak.net Fri Feb 16 19:33:38 2007 From: auc at codespeak.net (auc at codespeak.net) Date: Fri, 16 Feb 2007 19:33:38 +0100 (CET) Subject: [pypy-svn] r39042 - in pypy/dist/pypy: lib/cslib lib/cslib/doc lib/cslib/examples lib/cslib/test module/_cslib rlib/cslib Message-ID: <20070216183338.D6B22100FF@code0.codespeak.net> Author: auc Date: Fri Feb 16 19:33:37 2007 New Revision: 39042 Added: pypy/dist/pypy/lib/cslib/ pypy/dist/pypy/lib/cslib/__init__.py (contents, props changed) pypy/dist/pypy/lib/cslib/app_distributors.py (contents, props changed) pypy/dist/pypy/lib/cslib/app_fd.py (contents, props changed) pypy/dist/pypy/lib/cslib/app_propagation.py (contents, props changed) pypy/dist/pypy/lib/cslib/distributors.py (contents, props changed) pypy/dist/pypy/lib/cslib/doc/ pypy/dist/pypy/lib/cslib/examples/ pypy/dist/pypy/lib/cslib/fd.py (contents, props changed) pypy/dist/pypy/lib/cslib/fi.py (contents, props changed) pypy/dist/pypy/lib/cslib/propagation.py (contents, props changed) pypy/dist/pypy/lib/cslib/test/ pypy/dist/pypy/module/_cslib/ pypy/dist/pypy/module/_cslib/__init__.py (contents, props changed) pypy/dist/pypy/module/_cslib/constraint.py (contents, props changed) pypy/dist/pypy/module/_cslib/fd.py (contents, props changed) pypy/dist/pypy/module/_cslib/propagation.py (contents, props changed) pypy/dist/pypy/rlib/cslib/ pypy/dist/pypy/rlib/cslib/__init__.py (contents, props changed) pypy/dist/pypy/rlib/cslib/btree.py (contents, props changed) pypy/dist/pypy/rlib/cslib/rconstraint.py (contents, props changed) pypy/dist/pypy/rlib/cslib/rdistributor.py (contents, props changed) pypy/dist/pypy/rlib/cslib/rdomain.py (contents, props changed) pypy/dist/pypy/rlib/cslib/rpropagation.py (contents, props changed) Log: (alf, auc, ludal) provide constraint solver with logilab.constraint interface, apropriately stuffed into lib, module, rlib Added: pypy/dist/pypy/lib/cslib/__init__.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/lib/cslib/__init__.py Fri Feb 16 19:33:37 2007 @@ -0,0 +1,7 @@ +"Constraint Solver in Python." + +from propagation import Repository, Solver +#from distributors import DefaultDistributor +import fd +#import fi +__all__ = ['Repository', 'Solver', 'fd'] Added: pypy/dist/pypy/lib/cslib/app_distributors.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/lib/cslib/app_distributors.py Fri Feb 16 19:33:37 2007 @@ -0,0 +1,154 @@ +""" +distributors - part of constraint satisfaction solver. +""" + +import math, random + +def make_new_domains(domains): + """return a shallow copy of dict of domains passed in argument""" + domain = {} + for key, value in domains.items(): + domain[key] = value.copy() + return domain + +class AbstractDistributor(object): + """Implements DistributorInterface but abstract because + _distribute is left unimplemented.""" + + def __init__(self, nb_subspaces=2): + self.nb_subspaces = nb_subspaces + self.verbose = 0 + + def findSmallestDomain(self, domains): + """returns the variable having the smallest domain. + (or one of such varibles if there is a tie) + """ + domlist = [(dom.size(), variable ) for variable, dom in domains.items() + if dom.size() > 1] + domlist.sort() + return domlist[0][1] + + def findLargestDomain(self, domains): + """returns the variable having the largest domain. + (or one of such variables if there is a tie) + """ + domlist = [(dom.size(), variable) for variable, dom in domains.items() + if dom.size() > 1] + domlist.sort() + return domlist[-1][1] + + def nb_subdomains(self, domains): + """return number of sub domains to explore""" + return self.nb_subspaces + + def distribute(self, domains, verbose=0): + """do the minimal job and let concrete class distribute variables + """ + self.verbose = verbose + replicas = [] + for i in range(self.nb_subdomains(domains)): + replicas.append(make_new_domains(domains)) + modified_domains = self._distribute(*replicas) + for domain in modified_domains: + domain.clear_change() + return replicas + + def _distribute(self, *args): + """ method to implement in concrete class + + take self.nb_subspaces copy of the original domains as argument + distribute the domains and return each modified domain + """ + raise NotImplementedError("Use a concrete implementation of " + "the Distributor interface") + +class NaiveDistributor(AbstractDistributor): + """distributes domains by splitting the smallest domain in 2 new domains + The first new domain has a size of one, + and the second has all the other values""" + + def __init__(self): + AbstractDistributor.__init__(self) + + def _distribute(self, dom1, dom2): + """See AbstractDistributor""" + variable = self.findSmallestDomain(dom1) + values = dom1[variable].get_values() + if self.verbose: + print 'Distributing domain for variable', variable, \ + 'at value', values[0] + dom1[variable].remove_values(values[1:]) + dom2[variable].removeValue(values[0]) + return (dom1[variable], dom2[variable]) + + +class RandomizingDistributor(AbstractDistributor): + """distributes domains as the NaiveDistrutor, except that the unique + value of the first domain is picked at random.""" + + def __init__(self): + AbstractDistributor.__init__(self) + + def _distribute(self, dom1, dom2): + """See AbstractDistributor""" + variable = self.findSmallestDomain(dom1) + values = dom1[variable].get_values() + distval = random.choice(values) + values.remove(distval) + if self.verbose: + print 'Distributing domain for variable', variable, \ + 'at value', distval + dom1[variable].remove_values(values) + dom2[variable].removeValue(distval) + return (dom1[variable], dom2[variable]) + + +class SplitDistributor(AbstractDistributor): + """distributes domains by splitting the smallest domain in + nb_subspaces equal parts or as equal as possible. + If nb_subspaces is 0, then the smallest domain is split in + domains of size 1""" + + def __init__(self, nb_subspaces=3): + AbstractDistributor.__init__(self, nb_subspaces) + self.__to_split = None + def nb_subdomains(self, domains): + """See AbstractDistributor""" + self.__to_split = self.findSmallestDomain(domains) + if self.nb_subspaces: + return min(self.nb_subspaces, domains[self.__to_split].size()) + else: + return domains[self.__to_split].size() + + def _distribute(self, *args): + """See AbstractDistributor""" + variable = self.__to_split + nb_subspaces = len(args) + values = args[0][variable].get_values() + nb_elts = max(1, len(values)*1./nb_subspaces) + slices = [(int(math.floor(index * nb_elts)), + int(math.floor((index + 1) * nb_elts))) + for index in range(nb_subspaces)] + if self.verbose: + print 'Distributing domain for variable', variable + modified = [] + for (dom, (end, start)) in zip(args, slices) : + dom[variable].remove_values(values[:end]) + dom[variable].remove_values(values[start:]) + modified.append(dom[variable]) + return modified + +class DichotomyDistributor(SplitDistributor): + """distributes domains by splitting the smallest domain in + two equal parts or as equal as possible""" + def __init__(self): + SplitDistributor.__init__(self, 2) + + +class EnumeratorDistributor(SplitDistributor): + """distributes domains by splitting the smallest domain + in domains of size 1.""" + def __init__(self): + SplitDistributor.__init__(self, 0) + +DefaultDistributor = DichotomyDistributor Added: pypy/dist/pypy/lib/cslib/app_fd.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/lib/cslib/app_fd.py Fri Feb 16 19:33:37 2007 @@ -0,0 +1,351 @@ +"""Tools to work with finite domain variables and constraints + +This module provides the following usable classes: + * FiniteDomain: a class for storing FiniteDomains + * Expression: a constraint represented as an expression + * BinaryExpression: a binary constraint represented as an expression + * various BasicConstraint classes + +The Expression and BinaryExpression classes can be constructed using the +make_expression factory function. """ + +import operator + +from propagation import AbstractDomain, BasicConstraint, \ + ConsistencyFailure, AbstractConstraint + + +class FiniteDomain(AbstractDomain): + """ + Variable Domain with a finite set of possible values + """ + + _copy_count = 0 + _write_count = 0 + + def __init__(self, values): + """values is a list of values in the domain + This class uses a dictionnary to make sure that there are + no duplicate values""" + AbstractDomain.__init__(self) + if isinstance(values, FiniteDomain): + # do a copy on write + self._cow = True + values._cow = True + FiniteDomain._copy_count += 1 + self._values = values._values + else: + assert len(values) > 0 + self.setValues(values) + + ##self.getValues = self._values.keys + + def setValues(self, values): + self._cow = False + FiniteDomain._write_count += 1 + self._values = {} + for val in values: + self._values[val] = 0 + + def removeValue(self, value): + """Remove value of domain and check for consistency""" +## print "removing", value, "from", self._values.keys() + if self._cow: + self.setValues(self._values) + del self._values[value] + self._valueRemoved() + + def removeValues(self, values): + """Remove values of domain and check for consistency""" + if self._cow: + self.setValues(self._values) + if values: +## print "removing", values, "from", self._values.keys() + for val in values : + del self._values[val] + self._valueRemoved() + __delitem__ = removeValue + + def size(self): + """computes the size of a finite domain""" + return len(self._values) + __len__ = size + + def getValues(self): + """return all the values in the domain""" + return self._values.keys() + + def __iter__(self): + return iter(self._values) + + def copy(self): + """clone the domain""" + return FiniteDomain(self) + + def __repr__(self): + return '' % str(self.getValues()) + +## +## Constraints +## +class AllDistinct(AbstractConstraint): + """Contraint: all values must be distinct""" + + def __init__(self, variables): + assert len(variables)>1 + AbstractConstraint.__init__(self, variables) + # worst case complexity + self.__cost = len(variables) * (len(variables) - 1) / 2 + + def __repr__(self): + return '' % str(self._variables) + + def estimateCost(self, domains): + """return cost""" + return self.__cost + + def narrow(self, domains): + """narrowing algorithm for the constraint""" + variables = [(domains[variable].size(), variable, domains[variable]) + for variable in self._variables] + + variables.sort() + # if a domain has a size of 1, + # then the value must be removed from the other domains + for size, var, dom in variables: + if dom.size() == 1: + for _siz, _var, _dom in variables: + if _var != var: + try: + _dom.removeValue(dom.getValues()[0]) + except KeyError: + # we ignore errors caused by the removal of + # non existing values + pass + + # if there are less values than variables, the constraint fails + values = {} + for size, var, dom in variables: + for val in dom: + values[val] = 0 + if len(values) < len(variables): + raise ConsistencyFailure() + + # the constraint is entailed if all domains have a size of 1 + for variable in variables: + if variable[2].size() != 1: + return 0 + return 1 + + + + +class Expression(AbstractConstraint): + """A constraint represented as a python expression.""" + _FILTER_CACHE = {} + + def __init__(self, variables, formula, type='fd.Expression'): + """variables is a list of variables which appear in the formula + formula is a python expression that will be evaluated as a boolean""" + AbstractConstraint.__init__(self, variables) + self.formula = formula + self.type = type + try: + self.filterFunc = Expression._FILTER_CACHE[formula] + except KeyError: + self.filterFunc = eval('lambda %s: %s' % \ + (','.join(variables), formula), {}, {}) + Expression._FILTER_CACHE[formula] = self.filterFunc + + def _init_result_cache(self): + """key = (variable,value), value = [has_success,has_failure]""" + result_cache = {} + for var_name in self._variables: + result_cache[var_name] = {} + return result_cache + + + def _assign_values(self, domains): + variables = [] + kwargs = {} + for variable in self._variables: + domain = domains[variable] + values = domain.get_values() + variables.append((domain.size(), [variable, values, 0, len(values)])) + kwargs[variable] = values[0] + # sort variables to instanciate those with fewer possible values first + variables.sort() + + go_on = 1 + while go_on: + yield kwargs + # try to instanciate the next variable + for size, curr in variables: + if (curr[2] + 1) < curr[-1]: + curr[2] += 1 + kwargs[curr[0]] = curr[1][curr[2]] + break + else: + curr[2] = 0 + kwargs[curr[0]] = curr[1][0] + else: + # it's over + go_on = 0 + + + def narrow(self, domains): + """generic narrowing algorithm for n-ary expressions""" + maybe_entailed = 1 + ffunc = self.filterFunc + result_cache = self._init_result_cache() + for kwargs in self._assign_values(domains): + if maybe_entailed: + for var, val in kwargs.iteritems(): + if val not in result_cache[var]: + break + else: + continue + if ffunc(**kwargs): + for var, val in kwargs.items(): + result_cache[var][val] = 1 + else: + maybe_entailed = 0 + + try: + for var, keep in result_cache.iteritems(): + domain = domains[var] + domain.remove_values([val for val in domain.get_values() + if val not in keep]) + except ConsistencyFailure: + raise ConsistencyFailure('Inconsistency while applying %s' % \ + repr(self)) + except KeyError: + # There are no more value in result_cache + pass + + return maybe_entailed + + def __repr__(self): + return '<%s "%s">' % (self.type, self.formula) + +class BinaryExpression(Expression): + """A binary constraint represented as a python expression + + This implementation uses a narrowing algorithm optimized for + binary constraints.""" + + def __init__(self, variables, formula, type = 'fd.BinaryExpression'): + assert len(variables) == 2 + Expression.__init__(self, variables, formula, type) + + def narrow(self, domains): + """specialized narrowing algorithm for binary expressions + Runs much faster than the generic version""" + maybe_entailed = 1 + var1 = self._variables[0] + dom1 = domains[var1] + values1 = dom1.get_values() + var2 = self._variables[1] + dom2 = domains[var2] + values2 = dom2.get_values() + ffunc = self.filterFunc + if dom2.size() < dom1.size(): + var1, var2 = var2, var1 + dom1, dom2 = dom2, dom1 + values1, values2 = values2, values1 + + kwargs = {} + keep1 = {} + keep2 = {} + maybe_entailed = 1 + try: + # iterate for all values + for val1 in values1: + kwargs[var1] = val1 + for val2 in values2: + kwargs[var2] = val2 + if val1 in keep1 and val2 in keep2 and maybe_entailed == 0: + continue + if ffunc(**kwargs): + keep1[val1] = 1 + keep2[val2] = 1 + else: + maybe_entailed = 0 + + dom1.remove_values([val for val in values1 if val not in keep1]) + dom2.remove_values([val for val in values2 if val not in keep2]) + + except ConsistencyFailure: + raise ConsistencyFailure('Inconsistency while applying %s' % \ + repr(self)) + except Exception: + print self, kwargs + raise + return maybe_entailed + + +def make_expression(variables, formula, constraint_type=None): + """create a new constraint of type Expression or BinaryExpression + The chosen class depends on the number of variables in the constraint""" + # encode unicode + vars = [] + for var in variables: + if type(var) == type(u''): + vars.append(var.encode()) + else: + vars.append(var) + if len(vars) == 2: + if constraint_type is not None: + return BinaryExpression(vars, formula, constraint_type) + else: + return BinaryExpression(vars, formula) + + else: + if constraint_type is not None: + return Expression(vars, formula, constraint_type) + else: + return Expression(vars, formula) + + +class Equals(BasicConstraint): + """A basic constraint variable == constant value""" + def __init__(self, variable, reference): + BasicConstraint.__init__(self, variable, reference, operator.eq) + +class NotEquals(BasicConstraint): + """A basic constraint variable != constant value""" + def __init__(self, variable, reference): + BasicConstraint.__init__(self, variable, reference, operator.ne) + +class LesserThan(BasicConstraint): + """A basic constraint variable < constant value""" + def __init__(self, variable, reference): + BasicConstraint.__init__(self, variable, reference, operator.lt) + +class LesserOrEqual(BasicConstraint): + """A basic constraint variable <= constant value""" + def __init__(self, variable, reference): + BasicConstraint.__init__(self, variable, reference, operator.le) + +class GreaterThan(BasicConstraint): + """A basic constraint variable > constant value""" + def __init__(self, variable, reference): + BasicConstraint.__init__(self, variable, reference, operator.gt) + +class GreaterOrEqual(BasicConstraint): + """A basic constraint variable >= constant value""" + def __init__(self, variable, reference): + BasicConstraint.__init__(self, variable, reference, operator.ge) + +def _in(v, set): + """test presence of v in set""" + return v in set + +class InSet(BasicConstraint): + """A basic contraint variable in set value""" + def __init__(self, variable, set): + BasicConstraint.__init__(self, variable, set, _in ) + + + + Added: pypy/dist/pypy/lib/cslib/app_propagation.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/lib/cslib/app_propagation.py Fri Feb 16 19:33:37 2007 @@ -0,0 +1,283 @@ +"""The code of the constraint propagation algorithms""" + +import operator +#from time import strftime + +class ConsistencyFailure(Exception): + """The repository is not in a consistent state""" + pass + +class Repository(object): + """Stores variables, domains and constraints + Propagates domain changes to constraints + Manages the constraint evaluation queue""" + + def __init__(self, variables, domains, constraints = None): + # encode unicode + for i, var in enumerate(variables): + if type(var) == type(u''): + variables[i] = var.encode() + + self._variables = variables # list of variable names + self._domains = domains # maps variable name to domain object + self._constraints = [] # list of constraint objects +# self._queue = [] # queue of constraints waiting to be processed + self._variableListeners = {} + for var in self._variables: + self._variableListeners[var] = [] + assert self._domains.has_key(var) + for constr in constraints or (): + self.addConstraint(constr) + + def __repr__(self): + return '' % \ + (len(self._constraints), self._domains) + + def addConstraint(self, constraint): + if isinstance(constraint, BasicConstraint): + # Basic constraints are processed just once + # because they are straight away entailed + var = constraint.getVariable() + constraint.narrow({var: self._domains[var]}) + else: + self._constraints.append(constraint) + for var in constraint.affectedVariables(): + self._variableListeners[var].append(constraint) + + def _removeConstraint(self, constraint): + self._constraints.remove(constraint) + for var in constraint.affectedVariables(): + try: + self._variableListeners[var].remove(constraint) + except ValueError: + raise ValueError('Error removing constraint from listener', + var, + self._variableListeners[var], + constraint) + + def getDomains(self): + return self._domains + + def distribute(self, distributor, verbose=0): + """Create new repository using the distributor and self """ + for domains in distributor.distribute(self._domains, verbose): + yield Repository(self._variables, domains, self._constraints) + + def revise(self, verbose=0): + """Prunes the domains of the variables + This method calls constraint.narrow() and queues constraints + that are affected by recent changes in the domains. + Returns True if a solution was found""" + if verbose: + print '** Consistency **' + + _queue = [ (constr.estimateCost(self._domains), + constr) for constr in self._constraints ] + _queue.sort() + _affected_constraints = {} + while True: + if not _queue: + # refill the queue if some constraints have been affected + _queue = [(constr.estimateCost(self._domains), + constr) for constr in _affected_constraints] + if not _queue: + break + _queue.sort() + _affected_constraints.clear() + if verbose > 2: + print 'Queue', _queue + cost, constraint = _queue.pop(0) + if verbose > 1: + print 'Trying to entail constraint', + print constraint, '[cost:%d]' % cost + entailed = constraint.narrow(self._domains) + for var in constraint.affectedVariables(): + # affected constraints are listeners of + # affected variables of this constraint + dom = self._domains[var] + if not dom.has_changed(): + continue + if verbose > 1 : + print ' -> New domain for variable', var, 'is', dom + for constr in self._variableListeners[var]: + if constr is not constraint: + _affected_constraints[constr] = True + dom.clear_change() + if entailed: + if verbose: + print "--> Entailed constraint", constraint + self._removeConstraint(constraint) + if constraint in _affected_constraints: + del _affected_constraints[constraint] + + for domain in self._domains.itervalues(): + if domain.size() != 1: + return 0 + return 1 + +class Solver(object): + """Top-level object used to manage the search""" + + def __init__(self, distributor=None): + """if no distributer given, will use the default one""" + if distributor is None: + from distributors import DefaultDistributor + distributor = DefaultDistributor() + self._distributor = distributor + self.verbose = 1 + self.max_depth = 0 + + def solve_one(self, repository, verbose=0): + """Generates only one solution""" + self.verbose = verbose + self.max_depth = 0 + try: + return self._solve(repository).next() + except StopIteration: + return + + def solve_best(self, repository, cost_func, verbose=0): + """Generates solution with an improving cost""" + self.verbose = verbose + self.max_depth = 0 + best_cost = None + for solution in self._solve(repository): + cost = cost_func(**solution) + if best_cost is None or cost <= best_cost: + best_cost = cost + yield solution, cost + + def solve_all(self, repository, verbose=0): + """Generates all solutions""" + self.verbose = verbose + self.max_depth = 0 + for solution in self._solve(repository): + yield solution + + def solve(self, repository, verbose=0): + """return list of all solutions""" + self.max_depth = 0 + solutions = [] + for solution in self.solve_all(repository, verbose): + solutions.append(solution) + return solutions + + def _solve(self, repository, recursion_level=0): + """main generator""" + solve = self._solve + verbose = self.verbose + if recursion_level > self.max_depth: + self.max_depth = recursion_level + if verbose: + print '*** [%d] Solve called with repository' % recursion_level, + print repository + try: + foundSolution = repository.revise(verbose) + except ConsistencyFailure, exc: + if verbose: + print exc + pass + else: + if foundSolution: + solution = {} + for variable, domain in repository.getDomains().items(): + solution[variable] = domain.get_values()[0] + if verbose: + print '### Found Solution', solution + print '-'*80 + yield solution + else: + for repo in repository.distribute(self._distributor, + verbose): + for solution in solve(repo, recursion_level+1): + if solution is not None: + yield solution + + if recursion_level == 0 and self.verbose: + print 'Finished search' + print 'Maximum recursion depth = ', self.max_depth + + + + + + +class BasicConstraint(object): + """A BasicConstraint, which is never queued by the Repository + A BasicConstraint affects only one variable, and will be entailed + on the first call to narrow()""" + + def __init__(self, variable, reference, operator): + """variables is a list of variables on which + the constraint is applied""" + self._variable = variable + self._reference = reference + self._operator = operator + + def __repr__(self): + return '<%s %s %s>'% (self.__class__, self._variable, self._reference) + + def isVariableRelevant(self, variable): + return variable == self._variable + + def estimateCost(self, domains): + return 0 # get in the first place in the queue + + def affectedVariables(self): + return [self._variable] + + def getVariable(self): + return self._variable + + def narrow(self, domains): + domain = domains[self._variable] + operator = self._operator + ref = self._reference + try: + for val in domain.getValues() : + if not operator(val, ref) : + domain.removeValue(val) + except ConsistencyFailure: + raise ConsistencyFailure('inconsistency while applying %s' % \ + repr(self)) + return 1 + + +class AbstractDomain(object): + """Implements the functionnality related to the changed flag. + Can be used as a starting point for concrete domains""" + + def __init__(self): + self.__changed = 0 + + def resetFlags(self): + self.__changed = 0 + + def hasChanged(self): + return self.__changed + + def _valueRemoved(self): + """The implementation of removeValue should call this method""" + self.__changed = 1 + if self.size() == 0: + raise ConsistencyFailure() + +class AbstractConstraint(object): + + def __init__(self, variables): + """variables is a list of variables which appear in the formula""" + self._variables = variables + + def affectedVariables(self): + """ Return a list of all variables affected by this constraint """ + return self._variables + + def isVariableRelevant(self, variable): + return variable in self._variables + + def estimateCost(self, domains): + """Return an estimate of the cost of the narrowing of the constraint""" + return reduce(operator.mul, + [domains[var].size() for var in self._variables]) + + Added: pypy/dist/pypy/lib/cslib/distributors.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/lib/cslib/distributors.py Fri Feb 16 19:33:37 2007 @@ -0,0 +1,2 @@ +from _cslib import DefaultDistributor + Added: pypy/dist/pypy/lib/cslib/fd.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/lib/cslib/fd.py Fri Feb 16 19:33:37 2007 @@ -0,0 +1,7 @@ +from _cslib import FiniteDomain, _make_expression, AllDistinct + + +def make_expression(variables, formula): + func = 'lambda %s:%s' % (','.join(variables), + formula) + return _make_expression(variables, formula, eval(func)) Added: pypy/dist/pypy/lib/cslib/fi.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/lib/cslib/fi.py Fri Feb 16 19:33:37 2007 @@ -0,0 +1,326 @@ +"""Tools to work with finite interval domain interval and constraints +""" + +from propagation import AbstractDomain, BasicConstraint, \ + ConsistencyFailure, AbstractConstraint + +from distributors import AbstractDistributor + +class Interval: + """representation of an interval + This class is used to give back results from a FiniteIntervalDomain + """ + def __init__(self, start, end): + self._start = start + self._end = end + + def __repr__(self): + return "" % (self._start, self._end) + + def __eq__(self, other): + return self._start == other._start and \ + self._end == other._end + +class FiniteIntervalDomain(AbstractDomain): + """ + Domain for a variable with interval values. + """ + + def __init__(self, lowestMin, highestMax, + min_length, max_length=None, resolution=1): + """ + lowestMin is the lowest value of a low boundary for a variable (inclusive). + highestMax is the highest value of a high boundary for a variable (exclusive). + min_length is the minimum width of the interval. + max_length is the maximum width of the interval. + Use None to have max = min. + resolution is the precision to use for constraint satisfaction. Defaults to 1 + """ + assert highestMax >= lowestMin + if max_length is None: + max_length = min_length + assert 0 <= min_length <= max_length + assert min_length <= highestMax - lowestMin + assert resolution > 0 + AbstractDomain.__init__(self) + self.lowestMin = lowestMin + self.highestMax = highestMax + self._min_length = min_length + max_length = min(max_length, highestMax - lowestMin) + self._max_length = max_length + self._resolution = resolution + + def __eq__(self, other): + + return self.lowestMin == other.lowestMin and \ + self.highestMax == other.highestMax and \ + self._min_length == other._min_length and \ + self._max_length == other._max_length and \ + self._resolution == other._resolution + + def getValues(self): + return list(self.iter_values()) + + def iter_values(self): + length = self._min_length + while length <= self._max_length: + start = self.lowestMin + while start + length <= self.highestMax: + yield Interval(start, start+length) + start += self._resolution + length += self._resolution + + + def size(self): + """computes the size of a finite interval""" + size = 0 + length = self._min_length + while length <= self._max_length : + size += ((self.highestMax - length) - self.lowestMin) / self._resolution + 1 + length += self._resolution + return size + + def _highestMin(self): + return self.highestMax - self._min_length + + def _lowestMax(self): + return self.lowestMin + self._min_length + + lowestMax = property(_lowestMax, None, None, "") + + highestMin = property(_highestMin, None, None, "") + + def copy(self): + """clone the domain""" + return FiniteIntervalDomain(self.lowestMin, self.highestMax, + self._min_length, self._max_length, + self._resolution) + + def setLowestMin(self, new_lowestMin): + self.lowestMin = new_lowestMin + self._valueRemoved() + + def setHighestMax(self, new_highestMax): + self.highestMax = new_highestMax + self._valueRemoved() + + def setMinLength(self, new_min): + self._min_length = new_min + self._valueRemoved() + + def setMaxLength(self, new_max): + self._max_length = new_max + self._valueRemoved() + + def overlap(self, other): + return other.highestMax > self.lowestMin and \ + other.lowestMin < self.highestMax + + def no_overlap_impossible(self, other): + return self.lowestMax > other.highestMin and \ + other.lowestMax > self.highestMin + + def hasSingleLength(self): + return self._max_length == self._min_length + + def _valueRemoved(self): + if self.lowestMin >= self.highestMax: + raise ConsistencyFailure("earliest start [%.2f] higher than latest end [%.2f]" % + (self.lowestMin, self.highestMax)) + if self._min_length > self._max_length: + raise ConsistencyFailure("min length [%.2f] greater than max length [%.2f]" % + (self._min_length, self._max_length)) + + self._max_length = min(self._max_length, self.highestMax - self.lowestMin) + + if self.size() == 0: + raise ConsistencyFailure('size is 0') + + + + def __repr__(self): + return '' % (self.lowestMin, + self.lowestMax, + self.highestMin, + self.highestMax) + +## +## Distributors +## + +class FiniteIntervalDistributor(AbstractDistributor): + """Distributes a set of FiniteIntervalDomain + The distribution strategy is the following: + - the smallest domain of size > 1 is picked + - if its max_length is greater than its min_length, a subdomain if size + min_length is distributed, with the same boundaries + - otherwise, a subdomain [lowestMin, lowestMax[ is distributed + """ + def __init__(self): + AbstractDistributor.__init__(self) + + def _split_values(self, copy1, copy2): + if copy1.hasSingleLength(): + copy1.highestMax = copy1.lowestMin + copy1._min_length + copy2.lowestMin += copy2._resolution + else: + copy1._max_length = copy1._min_length + copy2._min_length += copy2._resolution + + + def _distribute(self, dom1, dom2): + variable = self.findSmallestDomain(dom1) + if self.verbose: + print 'Distributing domain for variable', variable + splitted = dom1[variable] + cpy1 = splitted.copy() + cpy2 = splitted.copy() + + self._split_values(cpy1, cpy2) + + dom1[variable] = cpy1 + dom2[variable] = cpy2 + + return cpy1, cpy2 + + + +## +## Constraints +## + +class AbstractFIConstraint(AbstractConstraint): + def __init__(self, var1, var2): + AbstractConstraint.__init__(self, (var1, var2)) + + def estimateCost(self, domains): + return 1 + + def __repr__(self): + return '<%s %s>' % (self.__class__.__name__, str(self._variables)) + + def __eq__(self, other): + return repr(self) == repr(other) + + def __hash__(self): + # FIXME: to be able to add constraints in Sets (and compare them) + # FIXME: improve implementation + variables = tuple(sorted(self._variables)) + return hash((self.__class__.__name__, variables)) + + def narrow(self, domains): + """narrowing algorithm for the constraint""" + dom1 = domains[self._variables[0]] + dom2 = domains[self._variables[1]] + + return self._doNarrow(dom1, dom2) + + def _doNarrow(self, dom1, dom2): + """virtual method which does the real work""" + raise NotImplementedError + + + +# FIXME: deal with more than 2 domains at once ? +class NoOverlap(AbstractFIConstraint): + + def __eq__(self, other): + return isinstance(other, NoOverlap) and \ + set(self._variables) == set(other._variables) + + def _doNarrow(self, dom1, dom2): + if not dom1.overlap(dom2): + return 1 + elif dom1.no_overlap_impossible(dom2) : + raise ConsistencyFailure + elif dom1.lowestMax == dom2.highestMin and dom2.lowestMax > dom1.highestMin : + dom1.setHighestMax(dom2.highestMin) + dom2.setLowestMin(dom1.lowestMax) + return 1 + elif dom1.lowestMax > dom2.highestMin and dom2.lowestMax == dom1.highestMin : + dom2.setHighestMax(dom1.highestMin) + dom1.setLowestMin(dom2.lowestMax) + return 1 + return 0 + +class StartsBeforeStart(AbstractFIConstraint): + + def _doNarrow(self, dom1, dom2): + + if dom1.lowestMin > dom2.highestMin: + raise ConsistencyFailure + if dom1.highestMin < dom2.lowestMin: + return 1 + return 0 + +class StartsBeforeEnd(AbstractFIConstraint): + + def _doNarrow(self, dom1, dom2): + if dom1.lowestMin > dom2.highestMax: + raise ConsistencyFailure + if dom1.highestMin < dom2.lowestMax: + return 1 + return 0 + +class EndsBeforeStart(AbstractFIConstraint): + + def _doNarrow(self, dom1, dom2): + if dom1.lowestMax > dom2.highestMin: + raise ConsistencyFailure + if dom1.highestMax < dom2.lowestMin: + return 1 + if dom1.highestMax > dom2.highestMin: + dom1.setHighestMax(dom2.highestMin) + return 0 + +class EndsBeforeEnd(AbstractFIConstraint): + + def _doNarrow(self, dom1, dom2): + if dom1.lowestMax > dom2.highestMax: + raise ConsistencyFailure + if dom1.highestMax < dom2.lowestMax: + return 1 + if dom1.highestMax > dom2.highestMax: + dom1.setHighestMax(dom2.highestMax) + return 0 + +class StartsAfterStart(AbstractFIConstraint): + + def _doNarrow(self, dom1, dom2): + if dom1.highestMin < dom2.lowestMin: + raise ConsistencyFailure + if dom1.lowestMin > dom2.highestMin: + return 1 + if dom1.lowestMin < dom2.lowestMin: + dom1.setLowestMin(dom2.lowestMin) + return 0 + +class StartsAfterEnd(AbstractFIConstraint): + + def _doNarrow(self, dom1, dom2): + if dom1.highestMin < dom2.lowestMax: + raise ConsistencyFailure + if dom1.lowestMin > dom2.highestMax: + return 1 + if dom1.lowestMin < dom2.lowestMax: + dom1.setLowestMin(dom2.lowestMax) + return 0 + +class EndsAfterStart(AbstractFIConstraint): + + def _doNarrow(self, dom1, dom2): + if dom1.highestMax < dom2.lowestMin: + raise ConsistencyFailure + if dom1.lowestMax > dom2.highestMin: + return 1 + return 0 + +class EndsAfterEnd(AbstractFIConstraint): + + def _doNarrow(self, dom1, dom2): + if dom1.highestMax < dom2.lowestMax: + raise ConsistencyFailure + if dom1.lowestMax > dom2.highestMax: + return 1 + return 0 + Added: pypy/dist/pypy/lib/cslib/propagation.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/lib/cslib/propagation.py Fri Feb 16 19:33:37 2007 @@ -0,0 +1 @@ +from _cslib import Repository, Solver Added: pypy/dist/pypy/module/_cslib/__init__.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/_cslib/__init__.py Fri Feb 16 19:33:37 2007 @@ -0,0 +1,16 @@ +# Package initialisation +from pypy.interpreter.mixedmodule import MixedModule + +#print '_csp module' + +class Module(MixedModule): + appleveldefs = { + } + + interpleveldefs = { + 'FiniteDomain' : 'fd.make_fd', + 'AllDistinct' : 'constraint.make_alldistinct', + '_make_expression': 'constraint.interp_make_expression', + 'Repository' : 'propagation.make_repo', + 'Solver' : 'propagation.make_solver' + } Added: pypy/dist/pypy/module/_cslib/constraint.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/_cslib/constraint.py Fri Feb 16 19:33:37 2007 @@ -0,0 +1,185 @@ +from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter import baseobjspace, typedef, gateway +from pypy.interpreter.gateway import interp2app +from pypy.interpreter.function import Function +from pypy.interpreter.error import OperationError + +from pypy.objspace.std.listobject import W_ListObject +from pypy.objspace.std.tupleobject import W_TupleObject +from pypy.objspace.std.stringobject import W_StringObject +from pypy.objspace.std.dictobject import W_DictObject + +from pypy.module._cslib.fd import _FiniteDomain +from pypy.rlib import rconstraint as rc + +class W_AbstractConstraint(baseobjspace.Wrappable): + + def __init__(self, space, constraint): + """variables is a list of variables which appear in the formula""" + self.space = space + assert isinstance( constraint, rc.AbstractConstraint ) + self.constraint = constraint + + def w_affected_variables(self): + """ Return a list of all variables affected by this constraint """ + return self.space.wrap(self._variables) + + def affected_variables(self): + return self._variables + + def w_revise(self, w_domains): + assert isinstance(w_domains, W_DictObject) + doms = {} + spc = self.space + for var, dom in w_domains.content.items(): + doms[spc.str_w(var)] = dom + return self.space.newbool(self.revise(doms)) + + def w_estimate_cost(self, w_domains): + assert isinstance(w_domains, W_DictObject) + cost = 1 + doms = w_domains.content + for var in self._variables: + dom = doms[self.space.wrap(var)] + assert isinstance(dom, W_AbstractDomain) + cost = cost * dom.size() + return self.space.newint(cost) + +W_AbstractConstraint.typedef = typedef.TypeDef( + "W_AbstractConstraint") + + + +class _Expression(rc.Expression): + """A constraint represented as a python expression.""" + + def __init__(self, space, w_variables, w_formula, w_filter_func): + """variables is a list of variables which appear in the formula + formula is a python expression that will be evaluated as a boolean""" + self.space = space + variables = [] + for w_var in space.unpackiterable( w_variables ): + variables.append( space.str_w(w_var) ) + if len(variables)==0: + raise OperationError( space.w_ValueError, + space.wrap("need at least one variable") ) + rc.Expression.__init__(self, variables ) + self.formula = self.space.str_w(w_formula) + # self.filter_func is a function taking keyword arguments and returning a boolean + self.w_filter_func = w_filter_func + + def filter_func(self, kwargs): + space = self.space + w_kwargs = space.newdict() + for var, value in kwargs.items(): + dom = self.doms[var] + assert isinstance( dom, _FiniteDomain ) + #print '!!!!', dom.w_values, value + w_val = space.getitem( dom.w_values, space.wrap(value) ) + w_kwargs.content[space.wrap(var)] = w_val + return space.is_true(space.call(self.w_filter_func, + space.newlist([]), + w_kwargs)) + + + def __repr__(self): + return '<%s>' % self.formula + + +class _BinaryExpression(rc.BinaryExpression): + """A constraint represented as a python expression.""" + + def __init__(self, space, w_variables, w_formula, w_filter_func): + """variables is a list of variables which appear in the formula + formula is a python expression that will be evaluated as a boolean""" + self.space = space + variables = [] + for w_var in space.unpackiterable( w_variables ): + variables.append( space.str_w(w_var) ) + if len(variables)==0: + raise OperationError( space.w_ValueError, + space.wrap("need at least one variable") ) + rc.BinaryExpression.__init__(self, variables ) + self.formula = self.space.str_w(w_formula) + # self.filter_func is a function taking keyword arguments and returning a boolean + self.w_filter_func = w_filter_func + self.kwcache = {} + + def filter_func(self, kwargs): + space = self.space + var1 = self._variables[0] + var2 = self._variables[1] + arg1 = kwargs[var1] + arg2 = kwargs[var2] + t = (arg1,arg2) + if t in self.kwcache: + return self.kwcache[t] + w_kwargs = space.newdict() + + dom = self.doms[var1] + w_val = space.getitem( dom.w_values, space.wrap(arg1) ) + w_kwargs.content[space.wrap(var1)] = w_val + + dom = self.doms[var2] + w_val = space.getitem( dom.w_values, space.wrap(arg2) ) + w_kwargs.content[space.wrap(var2)] = w_val + + res = space.is_true(space.call(self.w_filter_func, + space.newlist([]), + w_kwargs)) + self.kwcache[t] = res + return res + + +class W_Expression(W_AbstractConstraint): + + def __init__(self, space, w_variables, w_formula, w_filter_func): + if space.int_w(space.len(w_variables)) == 2: + constraint = _BinaryExpression(space, w_variables, w_formula, w_filter_func) + else: + constraint = _Expression(space, w_variables, w_formula, w_filter_func) + W_AbstractConstraint.__init__(self, space, constraint) + + +W_Expression.typedef = typedef.TypeDef("W_Expression", + W_AbstractConstraint.typedef) + + +def interp_make_expression(space, w_variables, w_formula, w_callable): + """create a new constraint of type Expression or BinaryExpression + The chosen class depends on the number of variables in the constraint""" + if not isinstance(w_formula, W_StringObject): + raise OperationError(space.w_TypeError, + space.wrap('formula must be a string.')) + return W_Expression(space, w_variables, w_formula, w_callable) + + +#--- Alldistinct + +class _AllDistinct(rc.AllDistinct): + """Contraint: all values must be distinct""" + + def __init__(self, space, w_variables): + variables = [] + for w_var in space.unpackiterable( w_variables ): + variables.append( space.str_w(w_var) ) + if len(variables)==0: + raise OperationError( space.w_ValueError, + space.wrap("need at least one variable") ) + rc.AllDistinct.__init__(self, variables) + + +class W_AllDistinct(W_AbstractConstraint): + + def __init__(self, space, w_variables): + constraint = _AllDistinct(space, w_variables) + W_AbstractConstraint.__init__(self, space, constraint) + + +W_AllDistinct.typedef = typedef.TypeDef( + "W_AllDistinct", W_AbstractConstraint.typedef) + +#function bolted into the space to serve as constructor +def make_alldistinct(space, w_variables): + return space.wrap(W_AllDistinct(space, w_variables)) + Added: pypy/dist/pypy/module/_cslib/fd.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/_cslib/fd.py Fri Feb 16 19:33:37 2007 @@ -0,0 +1,50 @@ +from pypy.interpreter.error import OperationError + +from pypy.interpreter import typedef, gateway, baseobjspace +from pypy.interpreter.gateway import interp2app + +from pypy.objspace.std.listobject import W_ListObject, W_TupleObject +from pypy.objspace.std.intobject import W_IntObject + +from pypy.rlib import rdomain as rd + +class _FiniteDomain(rd.BaseFiniteDomain): + """ + Variable Domain with a finite set of possible values + """ + + def __init__(self, w_values, values): + """values is a list of values in the domain + This class uses a dictionnary to make sure that there are + no duplicate values""" + + assert isinstance(w_values, W_ListObject) + self.w_values = w_values + self._values = {} + + if values is None: + for k in range(len(w_values.wrappeditems)): + self._values[k] = True + else: + self._values = values.copy() + + self._changed = False + + def copy(self): + return _FiniteDomain(self.w_values, self._values) + +class W_FiniteDomain(baseobjspace.Wrappable): + def __init__(self, w_values, values): + assert isinstance(w_values, W_ListObject) + self.domain = _FiniteDomain( w_values, values ) + +def make_fd(space, w_values): + if not isinstance(w_values, W_ListObject): + if not isinstance(w_values, W_TupleObject): + raise OperationError(space.w_TypeError, + space.wrap('first argument must be a list.')) + return W_FiniteDomain(w_values, None) + +W_FiniteDomain.typedef = typedef.TypeDef( + "W_FiniteDomain") + Added: pypy/dist/pypy/module/_cslib/propagation.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/_cslib/propagation.py Fri Feb 16 19:33:37 2007 @@ -0,0 +1,86 @@ +from pypy.rlib.rpropagation import Repository, Solver +import pypy.rlib.rdistributor as rd +from pypy.module._cslib import fd +from pypy.module._cslib.constraint import W_AbstractConstraint + +from pypy.interpreter.error import OperationError + +from pypy.interpreter import typedef, gateway, baseobjspace +from pypy.interpreter.gateway import interp2app + +#from pypy.objspace.std.listobject import W_ListObject, W_TupleObject +from pypy.objspace.std.intobject import W_IntObject +from pypy.objspace.std.listobject import W_ListObject +from pypy.objspace.std.tupleobject import W_TupleObject +from pypy.objspace.std.stringobject import W_StringObject +from pypy.objspace.std.dictobject import W_DictObject + + +class _Repository(Repository): + + def __init__(self, space, w_variables, w_domains, w_constraints): + # let's just give everything unwrapped to our parent + doms = {} + for var, dom in w_domains.content.items(): + assert isinstance( dom, fd.W_FiniteDomain ) + assert isinstance( var, W_StringObject ) + doms[space.str_w(var)] = dom.domain + constraints = [] + for w_constraint in space.unpackiterable( w_constraints ): + if not isinstance( w_constraint, W_AbstractConstraint ): + raise OperationError( space.w_TypeError, + space.wrap("constraints needs to be a sequence of constraints" ) ) + constraints.append( w_constraint.constraint ) + Repository.__init__(self, doms, constraints) + + +class W_Repository(baseobjspace.Wrappable): + + def __init__(self, space, w_variables, w_domains, w_constraints): + self.repo = _Repository(space, w_variables, w_domains, w_constraints) + + +W_Repository.typedef = typedef.TypeDef("W_Repository") + +def make_repo(space, w_variables, w_domains, w_constraints): + if not isinstance(w_domains,W_DictObject): + raise OperationError(space.w_TypeError, + space.wrap('domains must be a dictionary')) + return W_Repository(space, w_variables, w_domains, w_constraints) + + +class W_Solver(baseobjspace.Wrappable): + + def __init__(self, space): + self.space = space + self.solver = Solver(rd.DefaultDistributor()) + + def w_solve(self, w_repo, w_verbosity): + space = self.space + if not isinstance(w_repo, W_Repository): + raise OperationError(space.w_TypeError, + space.wrap('first argument must be a repository.')) + if not isinstance(w_verbosity, W_IntObject): + raise OperationError(space.w_TypeError, + space.wrap('second argument must be an int.')) + self._verb = w_verbosity.intval + sols = self.solver.solve_all(w_repo.repo) + sols_w = [] + for sol in sols: + w_dict = space.newdict() + for var,value in sol.items(): + domain = w_repo.repo._domains[var] + assert isinstance( domain, fd._FiniteDomain ) + w_var = space.wrap(var) + w_value = space.getitem( domain.w_values, space.wrap(value) ) + space.setitem( w_dict, w_var, w_value ) + sols_w.append( w_dict ) + return space.newlist(sols_w) + +W_Solver.typedef = typedef.TypeDef( + 'W_Solver', + solve = interp2app(W_Solver.w_solve)) + + +def make_solver(space): + return W_Solver(space) Added: pypy/dist/pypy/rlib/cslib/__init__.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/rlib/cslib/__init__.py Fri Feb 16 19:33:37 2007 @@ -0,0 +1 @@ +# Added: pypy/dist/pypy/rlib/cslib/btree.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/rlib/cslib/btree.py Fri Feb 16 19:33:37 2007 @@ -0,0 +1,43 @@ +""" +A minimalist binary tree implementation +whose values are (descendants of) BTreeNodes. +This alleviates some typing difficulties when +using TimSort on lists of the form [(key, Thing), ...] +""" + +class BTreeNode: + + def __init__(self, key): + self.key = key + self.left = None + self.right = None + + def add(self, val): + key = val.key + assert isinstance(key, int) + assert isinstance(val, BTreeNode) + + if key > self.key: + if self.right: + self.right.add(val) + else: + self.right = val + else: + if self.left: + self.left.add(val) + else: + self.left = val + + + def _values(self, dest): + if self.left: + self.left._values(dest) + dest.append(self) + if self.right: + self.right._values(dest) + + def get_values(self): + dest = [] + self._values( dest ) + return dest + Added: pypy/dist/pypy/rlib/cslib/rconstraint.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/rlib/cslib/rconstraint.py Fri Feb 16 19:33:37 2007 @@ -0,0 +1,262 @@ +from pypy.rlib.btree import BTreeNode +from pypy.rlib.rdomain import BaseFiniteDomain, ConsistencyError + + +class AbstractConstraint: + + def __init__(self, variables): + """variables is a list of variables which appear in the formula""" + assert isinstance(variables, list) + + self._variables = variables + + def revise(self, domains): + "domains : {'var':Domain}" + return False + + def estimate_cost(self, domains): + cost = 1 + for var in self._variables: + dom = domains[var] + assert isinstance(dom, BaseFiniteDomain) + cost = cost * dom.size() + return cost + + +class Quadruple(BTreeNode): + def __init__(self, key, varname, values, index): + BTreeNode.__init__( self, key ) + self.var = varname + self.values = values + self.index = index + +class Expression(AbstractConstraint): + """A constraint represented as a functional expression.""" + + def __init__(self, variables): + AbstractConstraint.__init__(self, variables) + self.doms = {} + + def filter_func(self, kwargs): + return False + + def _init_result_cache(self): + """key = (variable,value), value = [has_success,has_failure]""" + result_cache = {} + for var in self._variables: + result_cache[var] = {} + return result_cache + + def _assign_values(self, doms): + kwargs = {} + sorted_vars = None + for variable in self._variables: + domain = doms[variable] + assert isinstance(domain, BaseFiniteDomain) + values = domain.get_values() + node = Quadruple(domain.size(), + variable, + values, + 0) + if sorted_vars is None: + sorted_vars = node + else: + sorted_vars.add( node ) + kwargs[variable] = values[0] + + # get sorted variables to instanciate those with fewer possible values first + assert sorted_vars is not None + self._assign_values_state = sorted_vars.get_values() + return kwargs + + def _next_value(self, kwargs): + + # try to instanciate the next variable + variables = self._assign_values_state + + for curr in variables: + if curr.index < curr.key: + kwargs[curr.var] = curr.values[curr.index] + curr.index += 1 + break + else: + curr.index = 0 + kwargs[curr.var] = curr.values[0] + else: + # it's over + return None + return kwargs + + def revise(self, doms): + """generic propagation algorithm for n-ary expressions""" + self.doms = doms + maybe_entailed = True + result_cache = self._init_result_cache() + + kwargs = self._assign_values(doms) + + while 1: + kwargs = self._next_value(kwargs) + if kwargs is None: + break + + if maybe_entailed: + for varname, val in kwargs.iteritems(): + val_dict = result_cache[varname] + if val not in val_dict: + break + else: + continue + if self.filter_func(kwargs): + for var, val in kwargs.items(): + var_dict = result_cache[var] + var_dict[val] = True + else: + maybe_entailed = False + + try: # XXX domains in rlib, too + for varname, keep in result_cache.items(): + domain = doms[varname] + assert isinstance(domain, BaseFiniteDomain) + domain.remove_values([val + for val in domain.get_values() + if val not in keep]) + except KeyError: + # There are no more value in result_cache + pass + + return maybe_entailed + + + def __repr__(self): + return '<%s>' % self.formula + + +#--- Alldistinct + +class VarDom(BTreeNode): + def __init__(self, key, var, dom): + BTreeNode.__init__(self, key) + self.var = var + self.dom = dom + +class AllDistinct(AbstractConstraint): + """Contraint: all values must be distinct""" + + def __init__(self, variables): + AbstractConstraint.__init__(self, variables) + # worst case complexity + self._cost = len(self._variables) * (len(self._variables) - 1) / 2 + + def estimate_cost(self, domains): + return self._cost + + def revise(self, doms): + + sorted_vars = None + for var in self._variables: + dom = doms[var] + assert isinstance(dom, BaseFiniteDomain) + node = VarDom(dom.size(), var, dom) + if sorted_vars is None: + sorted_vars = node + else: + sorted_vars.add(node) + + assert sorted_vars is not None + variables = sorted_vars.get_values() + + # if a domain has a size of 1, + # then the value must be removed from the other domains + for var_dom in variables: + if var_dom.dom.size() == 1: + #print "AllDistinct removes values" + for var_dom2 in variables: + if var_dom2.var != var_dom.var: + try: + var_dom2.dom.remove_value(var_dom.dom.get_values()[0]) + except KeyError, e: + # we ignore errors caused by the removal of + # non existing values + pass + + # if there are less values than variables, the constraint fails + values = {} + for var_dom in variables: + for val in var_dom.dom.get_values(): + values[val] = 0 + + if len(values) < len(variables): + #print "AllDistinct failed" + raise ConsistencyError + + # the constraint is entailed if all domains have a size of 1 + for var_dom in variables: + if not var_dom.dom.size() == 1: + return False + + #print "All distinct entailed" + return True + + + +#--- Binary expressions + +class BinaryExpression(Expression): + """A binary constraint represented as a python expression + + This implementation uses a narrowing algorithm optimized for + binary constraints.""" + + def __init__(self, variables): + assert len(variables) == 2 + Expression.__init__(self, variables) + + def revise(self, domains): + """specialized pruning algorithm for binary expressions + Runs much faster than the generic version""" + self.doms = domains + maybe_entailed = True + var1 = self._variables[0] + dom1 = domains[var1] + values1 = dom1.get_values() + var2 = self._variables[1] + dom2 = domains[var2] + values2 = dom2.get_values() + if dom2.size() < dom1.size(): + var1, var2 = var2, var1 + dom1, dom2 = dom2, dom1 + values1, values2 = values2, values1 + + kwargs = {} + keep1 = {} + keep2 = {} + maybe_entailed = True + # iterate for all values + for val1 in values1: + kwargs[var1] = val1 + for val2 in values2: + kwargs[var2] = val2 + if val1 in keep1 and val2 in keep2 and not maybe_entailed: + continue + if self.filter_func(kwargs): + keep1[val1] = 1 + keep2[val2] = 1 + else: + maybe_entailed = False + + dom1.remove_values([val for val in values1 if val not in keep1]) + dom2.remove_values([val for val in values2 if val not in keep2]) + + return maybe_entailed + + +class BinEq(BinaryExpression): + def filter_func(self, kwargs): + values = kwargs.values() + return values[0]==values[1] + +class BinLt(BinaryExpression): + def filter_func(self, kwargs): + values = kwargs.values() + return values[0] < values[1] Added: pypy/dist/pypy/rlib/cslib/rdistributor.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/rlib/cslib/rdistributor.py Fri Feb 16 19:33:37 2007 @@ -0,0 +1,77 @@ +""" +distributors - part of constraint satisfaction solver. +""" + +def make_new_domains(domains): + """return a shallow copy of dict of domains passed in argument""" + new_domains = {} + for key, domain in domains.items(): + new_domains[key] = domain.copy() + return new_domains + +class AbstractDistributor: + """Implements DistributorInterface but abstract because + _distribute is left unimplemented.""" + + def find_smallest_domain(self, domains): + """returns the variable having the smallest domain. + (or one of such varibles if there is a tie) + """ + k = 0 + doms = domains.items() + while k1: + min_size = sz + min_var = var + break + k += 1 + else: + raise RuntimeError, "should not be here" + while k two variants of the same modified domain + do the minimal job and let concrete class distribute variables + """ + doms1 = make_new_domains(domains) + doms2 = make_new_domains(domains) + for modified_domain in self._distribute(doms1,doms2): + modified_domain._changed = False + return [doms1,doms2] + +class AllOrNothingDistributor(AbstractDistributor): + """distributes domains by splitting the smallest domain in 2 new domains + The first new domain has a size of one, + and the second has all the other values""" + + def _distribute(self, doms1, doms2): + """See AbstractDistributor""" + variable = self.find_smallest_domain(doms1) + values = doms1[variable].get_values() + doms1[variable].remove_values(values[1:]) + doms2[variable].remove_value(values[0]) + return [doms1[variable], doms2[variable]] + +class DichotomyDistributor(AbstractDistributor): + """distributes domains by splitting the smallest domain in + two equal parts or as equal as possible.""" + + def _distribute(self, doms1, doms2): + """See AbstractDistributor""" + variable = self.find_smallest_domain(doms1) + values = doms1[variable].get_values() + middle = len(values)/2 + doms1[variable].remove_values(values[:middle]) + doms2[variable].remove_values(values[middle:]) + return [doms1[variable], doms2[variable]] + +DefaultDistributor = DichotomyDistributor Added: pypy/dist/pypy/rlib/cslib/rdomain.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/rlib/cslib/rdomain.py Fri Feb 16 19:33:37 2007 @@ -0,0 +1,93 @@ + +class ConsistencyError(Exception): + pass + +class BaseFiniteDomain: + """ + Variable Domain with a finite set of int values + """ + + def __init__(self, values): + """values is a list of values in the domain + This class uses a dictionnary to make sure that there are + no duplicate values""" + #assert isinstance(values, dict) + self._values = values.copy() + self._changed = False + + def copy(self): + return BaseFiniteDomain(self._values) + + def _value_removed(self): + "The implementation of remove_value should call this method" + if self.size() == 0: + raise ConsistencyError, "tried to make a domain empty" + + def remove_value(self, value): + """Remove value of domain and check for consistency""" + del self._values[value] + self._value_removed() + self._changed = True + + def remove_values(self, values): + assert isinstance(values, list) + if len(values) > 0: + for val in values: + del self._values[val] + self._value_removed() + self._changed = True + + def size(self): + """computes the size of a finite domain""" + return len(self._values) + + def get_values(self): + return self._values.keys() + + + def __repr__(self): + return "" % self._values.keys() + +# XXX finish this +class TodoBaseFiniteDomain: + """ + Variable Domain with a finite set of int values + """ + + def __init__(self, values): + """values is a list of values in the domain + This class uses a dictionnary to make sure that there are + no duplicate values""" + assert isinstance(values, int) + self._values = [True] * values + + def copy(self): + dom = BaseFiniteDomain(len(self._values)) + for i, v in enumerate(self._values): + dom._values[i] = v + + def _value_removed(self): + "The implementation of remove_value should call this method" + if self.size() == 0: + raise ConsistencyError, "tried to make a domain empty" + + def remove_value(self, value): + """Remove value of domain and check for consistency""" + assert isinstance(value, int) + del self._values[value] + self._value_removed() + + def remove_values(self, values): + assert isinstance(values, list) + if len(values) > 0: + for val in values: + del self._values[val] + self._value_removed() + + def size(self): + """computes the size of a finite domain""" + return len(self._values) + + def get_values(self): + return self._values.keys() + Added: pypy/dist/pypy/rlib/cslib/rpropagation.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/rlib/cslib/rpropagation.py Fri Feb 16 19:33:37 2007 @@ -0,0 +1,151 @@ +"""The code of the constraint propagation algorithms""" +from pypy.rlib.rconstraint import AbstractConstraint, ConsistencyError + +class Repository: + """Stores variables, domains and constraints + Propagates domain changes to constraints + Manages the constraint evaluation queue""" + + def __init__(self, domains, constraints): + self._variables = domains.keys() # list of variable names + self._domains = domains # maps variable name to domain object + self._constraints = [] # list of constraint objects + self._variableListeners = {} + for var in self._variables: + self._variableListeners[var] = [] + for constr in constraints: + self.add_constraint( constr ) + + def __repr__(self): + return '' % \ + (len(self._constraints), self._domains) + + def add_constraint(self, constraint): + assert isinstance( constraint, AbstractConstraint ) + if 0: # isinstance(constraint, BasicConstraint): + # Basic constraints are processed just once + # because they are straight away entailed + var = constraint.getVariable() + constraint.revise({var: self._domains[var]}) + else: + self._constraints.append(constraint) + for var in constraint._variables: + self._variableListeners[var].append(constraint) + + def _remove_constraint(self, constraint): + self._constraints.remove(constraint) + for var in constraint._variables: + try: + self._variableListeners[var].remove(constraint) + except ValueError: + raise ValueError('Error removing constraint from listener', + var, + self._variableListeners[var], + constraint) + + def get_domains(self): + return self._domains + + def distribute(self, distributor): + """ + create new repository using the distributor and self + using changed domains + """ + d1, d2 = distributor.distribute(self._domains) + return [Repository(d1, self._constraints), + Repository(d2, self._constraints)] + + def propagate(self): + """Prunes the domains of the variables + This method calls constraint.narrow() and queues constraints + that are affected by recent changes in the domains. + Returns True if a solution was found""" + + _queue = [(constr.estimate_cost(self._domains), constr) + for constr in self._constraints ] + # XXX : _queue.sort() + _affected_constraints = {} + while True: + if not _queue: + # refill the queue if some constraints have been affected + _queue = [(constr.estimate_cost(self._domains), constr) + for constr in _affected_constraints] + if not _queue: + break + # XXX _queue.sort() + _affected_constraints.clear() + cost, constraint = _queue.pop(0) + entailed = constraint.revise(self._domains) + for var in constraint._variables: + # affected constraints are listeners of + # affected variables of this constraint + dom = self._domains[var] + if not dom._changed: # XXX + continue + for constr in self._variableListeners[var]: + if constr is not constraint: + _affected_constraints[constr] = True + dom._changed = False + if entailed: + self._remove_constraint(constraint) + if constraint in _affected_constraints: + del _affected_constraints[constraint] + + for domain in self._domains.values(): + if domain.size() != 1: + return 0 + return 1 + + + def solve_all(self, distributor): + solver = Solver(distributor) + return solver.solve_all(self) + + +import os + +class Solver: + """Top-level object used to manage the search""" + + def __init__(self, distributor): + """if no distributer given, will use the default one""" + self._verb = 0 + self._distributor = distributor + self.todo = [] + + def solve_one(self, repository): + self.todo = [repository] + return self.next_sol() + + def solve_all(self, repository): + self.todo = [repository] + solutions = [] + while True: + sol = self.next_sol() + if sol is not None: + solutions.append( sol ) + if self._verb: + os.write(1, 'found solution : %s\n' % sol) + else: + break + return solutions + + def next_sol(self): + found_solution = False + todo = self.todo + while todo: + repo = todo.pop() + try: + found_solution = repo.propagate() + except ConsistencyError: + continue + if found_solution: + solution = {} + for variable, domain in repo.get_domains().items(): + solution[variable] = domain.get_values()[0] + return solution + else: + for rep in repo.distribute(self._distributor): + todo.append( rep ) + return None + From guido at codespeak.net Fri Feb 16 20:29:49 2007 From: guido at codespeak.net (guido at codespeak.net) Date: Fri, 16 Feb 2007 20:29:49 +0100 (CET) Subject: [pypy-svn] r39043 - in pypy/branch/guido-buildtool-web/pypy/tool/build/web: . test Message-ID: <20070216192949.78CBF100FA@code0.codespeak.net> Author: guido Date: Fri Feb 16 20:29:48 2007 New Revision: 39043 Added: pypy/branch/guido-buildtool-web/pypy/tool/build/web/app.py - copied, changed from r39032, pypy/branch/guido-buildtool-web/pypy/tool/build/web/webapp.py pypy/branch/guido-buildtool-web/pypy/tool/build/web/server.py - copied unchanged from r39032, pypy/branch/guido-buildtool-web/pypy/tool/build/web/webserver.py pypy/branch/guido-buildtool-web/pypy/tool/build/web/test/test_app.py - copied, changed from r39032, pypy/branch/guido-buildtool-web/pypy/tool/build/web/test/test_webapp.py pypy/branch/guido-buildtool-web/pypy/tool/build/web/test/test_server.py - copied, changed from r39032, pypy/branch/guido-buildtool-web/pypy/tool/build/web/test/test_webserver.py Removed: pypy/branch/guido-buildtool-web/pypy/tool/build/web/test/test_webapp.py pypy/branch/guido-buildtool-web/pypy/tool/build/web/test/test_webserver.py pypy/branch/guido-buildtool-web/pypy/tool/build/web/webapp.py pypy/branch/guido-buildtool-web/pypy/tool/build/web/webserver.py Log: Renamed 'webapp' to 'app', 'webserver' to 'server' and 'BuildCollection' to 'Builds. From hpk at codespeak.net Fri Feb 16 20:42:53 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Fri, 16 Feb 2007 20:42:53 +0100 (CET) Subject: [pypy-svn] r39044 - pypy/release/0.99.x/pypy/doc Message-ID: <20070216194253.A108A100FE@code0.codespeak.net> Author: hpk Date: Fri Feb 16 20:42:52 2007 New Revision: 39044 Modified: pypy/release/0.99.x/pypy/doc/release-0.99.0.txt Log: trying to finalise the release announcement: * streamlined various sections (particularly "what is pypy") * added references * added funding organisations (including EU) * XXX i think the main missing piece is an inspired go through the 0.99 features Modified: pypy/release/0.99.x/pypy/doc/release-0.99.0.txt ============================================================================== --- pypy/release/0.99.x/pypy/doc/release-0.99.0.txt (original) +++ pypy/release/0.99.x/pypy/doc/release-0.99.0.txt Fri Feb 16 20:42:52 2007 @@ -6,59 +6,47 @@ and milestone of the last 8 months of work and contributions since PyPy-0.9.0 came out in June 2006! -Main entry points: +Main entry point for getting-started/download and documentation: - XXX getting-started - XXX downloads - XXX index - -Further below you'll find notes on our current -project view, a list of 0.99.0 highlights, and -plans for PyPy 1.0 and beyond. + http://codespeak.net/pypy/dist/pypy/doc/index.html + +Further below you'll find some notes about PyPy, +the 0.99.0 highlights and our aims for PyPy 1.0. have fun, - - XXX the release team + the pypy team, + XXX insert release participants + + and many others: + http://codespeak.net/pypy/dist/pypy/doc/contributor.html -What and where is PyPy? -========================== + +What is PyPy? +================================ Technically, PyPy is both a Python Interpreter implementation and an advanced Compiler, actually a framework for implementing dynamic languages and generating virtual machines for them. - -The Python Standard interpreter provides compliant CPython -semantics with a high flexibility for extending and -amending it. We believe that the main issue keeping it from -being usable as a productive alternative is the -lack of extension module support. This will likely be -an ongoing topic for 2007, as it is less of a research -topic and has thus been of less priority to the core -people involved with the European Union project. - -The Compiler Framework allows for alternative frontends and -for alternative backends, currently C, LLVM, and .NET. For -our main target "C", the Compiler can "mix in" different Garbage -Collectors and threading models, including micro-threads, aka +The Framework allows for alternative frontends and +for alternative backends, currently C, LLVM and .NET. +For our main target "C", we can can "mix in" different Garbage +Collectors and threading models, including micro-threads aka "Stackless". The inherent complexity that arises from this -ambitious approach is mostly kept away from our Python -interpreter implementation (our main frontend). +ambitious approach is mostly kept away from the Python +interpreter implementation, our main frontend. -(If you want to compare PyPy-the-Compiler with something -else, please pick a compiler that shares these goals and -don't forget to tell us about what you find out :) - -Socially, PyPy is a collaborative effort of many individuals, -companies and universities, working together in a distributed -and sprint-driven way since 2003. - -Formally, many of us are involved as partners in an EU -contract with the goal of exploring and researching new -approaches to Language/Compiler development and +Socially, PyPy is a collaborative effort of many individuals +working together in a distributed and sprint-driven way since +2003. PyPy would not have gotten as far without the coding, +feedback and general support from numerous people. + +Formally, many of the current developers are involved in +executing an EU contract with the goal of exploring and +researching new approaches to Language/Compiler development and software engineering. This contract's duration is about to end March 2007 and we are working and preparing the according -"final review" which is scheduled for May 2007. +final review which is scheduled for May 2007. Key 0.99.0 Features @@ -89,7 +77,7 @@ XXX play1 pointer? * new configuration system: - There is a new comprehensive configuration system that allows the + There is a new comprehensive configuration system that allows fine-grained configuration of the PyPy standard interpreter and the translation process. @@ -100,17 +88,17 @@ What about 1.0? ====================== -In the last days leading up to the release, we decided -to go for naming the release 0.99.0, mainly because -we still have some efforts pending to integrate and complete +In the last week leading up to the release, we decided +to go for tagging the release as 0.99.0, mainly because +we have some efforts pending to integrate and complete research and coding work: * the JIT Compiler Generator is ready, but not fully integrated with the PyPy interpreter. As a result, the JIT does not give actual speed improvements yet, so we chose to leave it out of the 0.99 release: the result doesn't meet yet the speed expectations - that we set for ourselves (and which many blogs and people out - there have chosen as a main criterium for looking at PyPy). + that we set for ourselves - and which some blogs and people + have chosen as the main criterium for looking at PyPy. * the extension enabling runtime changes of the Python grammar is not yet integrated. This will be used to provide Aspect-Oriented @@ -120,13 +108,22 @@ needs to undergo a bit more testing. A constraint problem solver extension module is ready, and needs to be integrated with the codebase. -* we'd like to package and improve configurations and - and testing, and actually ask for your help - on getting PyPy to become a sustained and interesting - base for further developments - -IOW, PyPy 0.99 is the start for getting to 1.0 end of March 2007, +PyPy 0.99 is the start for getting to 1.0 end of March 2007, which we intend to become a base for a longer (and more relaxed :) time to come. + +Funding partners and organisations +===================================================== + +PyPy development and activities happen as an open source project +and with the support of a consortium partially funded by a 28 months +European Union IST research grant. The full partners of that +consortium are: + + Heinrich-Heine University (Germany), Openend (Sweden) + merlinux GmbH (Germany), tismerysoft GmbH (Germany) + Logilab Paris (France), DFKI GmbH (Germany) + ChangeMaker (Sweden), Impara (Germany) + From cfbolz at codespeak.net Fri Feb 16 20:50:53 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 16 Feb 2007 20:50:53 +0100 (CET) Subject: [pypy-svn] r39045 - pypy/release/0.99.x/pypy/doc Message-ID: <20070216195053.D94A410100@code0.codespeak.net> Author: cfbolz Date: Fri Feb 16 20:50:50 2007 New Revision: 39045 Modified: pypy/release/0.99.x/pypy/doc/release-0.99.0.txt Log: add list of release-helping people. fix typo Modified: pypy/release/0.99.x/pypy/doc/release-0.99.0.txt ============================================================================== --- pypy/release/0.99.x/pypy/doc/release-0.99.0.txt (original) +++ pypy/release/0.99.x/pypy/doc/release-0.99.0.txt Fri Feb 16 20:50:50 2007 @@ -15,8 +15,10 @@ have fun, - the pypy team, - XXX insert release participants + the PyPy team, + Samuele Pedroni, Carl Friedrich Bolz, Armin Rigo, Michael Hudson, + Maciej Fijalkowski, Anders Chrigstroem, Holger Krekel, + Guido Wesdorp and many others: http://codespeak.net/pypy/dist/pypy/doc/contributor.html @@ -71,7 +73,7 @@ * optimizations: - experimental new optimized implementations for various built in Python types (strings, dicts, lists) - - twice the of the 0.9 release, overall 2-3 slower than CPython + - twice the speed of the 0.9 release, overall 2-3 slower than CPython * Demonstrations of Javascript-Backend / AJAX experiments: XXX play1 pointer? From cfbolz at codespeak.net Fri Feb 16 20:57:55 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 16 Feb 2007 20:57:55 +0100 (CET) Subject: [pypy-svn] r39046 - pypy/release/0.99.x/pypy/doc Message-ID: <20070216195755.E927A10103@code0.codespeak.net> Author: cfbolz Date: Fri Feb 16 20:57:54 2007 New Revision: 39046 Modified: pypy/release/0.99.x/pypy/doc/release-0.99.0.txt Log: add note about added modules Modified: pypy/release/0.99.x/pypy/doc/release-0.99.0.txt ============================================================================== --- pypy/release/0.99.x/pypy/doc/release-0.99.0.txt (original) +++ pypy/release/0.99.x/pypy/doc/release-0.99.0.txt Fri Feb 16 20:57:54 2007 @@ -83,6 +83,10 @@ fine-grained configuration of the PyPy standard interpreter and the translation process. +* new modules: Since the last release, the signal, mmap, bz2 and fcntl standard + library modules have been implemented for PyPy. In addition we added a the + pypymagic module that contains PyPy-specific functionality. + * improved documentation: XXX point to main new docs From guido at codespeak.net Fri Feb 16 21:03:12 2007 From: guido at codespeak.net (guido at codespeak.net) Date: Fri, 16 Feb 2007 21:03:12 +0100 (CET) Subject: [pypy-svn] r39047 - in pypy/branch/guido-buildtool-web/pypy/tool/build/web: . templates test Message-ID: <20070216200312.C7CDE10105@code0.codespeak.net> Author: guido Date: Fri Feb 16 21:03:11 2007 New Revision: 39047 Added: pypy/branch/guido-buildtool-web/pypy/tool/build/web/README.txt Modified: pypy/branch/guido-buildtool-web/pypy/tool/build/web/app.py pypy/branch/guido-buildtool-web/pypy/tool/build/web/templates/builderinfo.html pypy/branch/guido-buildtool-web/pypy/tool/build/web/templates/buildersinfo.html pypy/branch/guido-buildtool-web/pypy/tool/build/web/templates/builds.html pypy/branch/guido-buildtool-web/pypy/tool/build/web/templates/index.html pypy/branch/guido-buildtool-web/pypy/tool/build/web/templates/serverstatus.html pypy/branch/guido-buildtool-web/pypy/tool/build/web/test/test_app.py Log: Switched to using 'Templess' instead of the stupid Templates for HTML templating (and added README for details). Added: pypy/branch/guido-buildtool-web/pypy/tool/build/web/README.txt ============================================================================== --- (empty file) +++ pypy/branch/guido-buildtool-web/pypy/tool/build/web/README.txt Fri Feb 16 21:03:11 2007 @@ -0,0 +1,49 @@ +py.tool.build.web +================= + +What is this? +------------- + +This is a web front-end for the PyPy build tool, which builds an ad-hoc network +of 'build-servers', all connected to a main 'meta server' to allow connecting +'compile clients' to compile on them. This allows the compile clients to use +a build of PyPy even if they do not have the resources to build it themselves. + +The web front-end provides some status information about the server: what +build servers are connected to the network, how many builds are in progress, +details per build, etc. and also allows downloading a build if it's done. + +How do I use it? +---------------- + +NOTE: Using the server only makes sense if you run a pypy.tool.build meta +server and want to allow clients to view status information! + +Using it is relatively simple, just (XXX temporary solution!) run:: + + $ PYTHONPATH=path/to/pypy/parentdir python app.py + +and you will have a server running. 'path/to/pypy/parentdir' is an absolute +path to the _parent_ of the pypy package (to make 'import pypy' work), and +'app.py' is the script 'app.py' found in this directory. + +Requirements +------------ + +The dependencies for this package are a reasonably new Python (tested on 2.4), +a recent PyPy checkout or release (which you have, else you wouldn't be reading +this ;) and the Templess templating library, which can be checked out from +Subversion using the following command:: + + $ svn co http://johnnydebris.net/templess/trunk templess + +or downloaded from the following location:: + + http://johnnydebris.net/templess_package + +Minimal version required is 0.2. + +Questions, remarks, etc. +------------------------ + +For questions, remarks, etc. about this product, mail guido at merlinux.de. Modified: pypy/branch/guido-buildtool-web/pypy/tool/build/web/app.py ============================================================================== --- pypy/branch/guido-buildtool-web/pypy/tool/build/web/app.py (original) +++ pypy/branch/guido-buildtool-web/pypy/tool/build/web/app.py Fri Feb 16 21:03:11 2007 @@ -7,26 +7,22 @@ from pypy.tool.build import execnetconference from pypy.tool.build.web.server import HTTPError, Resource, Collection, Handler +from templess import templess + mypath = py.magic.autopath().dirpath() -class Template(object): - """ very stupid template class - - does nothing more than string interpolation, no loop constructs or - other fancyness: you will have to do that yourself - """ - def __init__(self, path): - self.template = path.read() - - def render(self, context): - return self.template % context +def fix_html(html): + return ('\n%s' % ( + html.strip().encode('UTF-8'),)) class IndexPage(Resource): """ the index page """ def handle(self, handler, path, query): - template = Template(mypath.join('templates/index.html')) + template = templess.template( + mypath.join('templates/index.html').read()) return ({'Content-Type': 'text/html; charset=UTF-8'}, - template.render({})) + fix_html(template.unicode({}))) class ServerPage(Resource): """ base class for pages that communicate with the server @@ -73,30 +69,25 @@ """ a page displaying overall meta server statistics """ def handle(self, handler, path, query): - template = Template(mypath.join('templates/serverstatus.html')) + template = templess.template( + mypath.join('templates/serverstatus.html').read()) return ({'Content-Type': 'text/html; charset=UTF-8'}, - template.render(self.get_status())) + fix_html(template.unicode(self.get_status()))) def get_status(self): return self.call_method('status') class BuildersInfoPage(ServerPage): def handle(self, handler, path, query): - template = Template(mypath.join('templates/buildersinfo.html')) - context = { - 'builders': '\n'.join([self.get_builder_html(b) - for b in self.get_buildersinfo()]) - } + template = templess.template( + mypath.join('templates/buildersinfo.html').read()) return ({'Content-Type': 'text/html; charset=UTF-8'}, - template.render(context)) + fix_html(template.unicode({'builders': + self.get_buildersinfo()}))) def get_buildersinfo(self): return self.call_method('buildersinfo') - def get_builder_html(self, buildinfo): - template = Template(mypath.join('templates/builderinfo.html')) - return template.render(buildinfo) - class BuildPage(ServerPage): """ display information for one build """ @@ -111,11 +102,10 @@ """ display the list of available builds """ def handle(self, handler, path, query): - template = Template(mypath.join('templates/builds.html')) - context = {'builds': '\n'.join([self.get_build_html(b) for b in - self.get_builds()])} + template = templess.template( + mypath.join('templates/builds.html').read()) return ({'Content-Type': 'text/html; charset=UTF-8'}, - template.render(context)) + fix_html(template.unicode({'builds': self.get_builds()}))) def get_builds(self): return [] Modified: pypy/branch/guido-buildtool-web/pypy/tool/build/web/templates/builderinfo.html ============================================================================== --- pypy/branch/guido-buildtool-web/pypy/tool/build/web/templates/builderinfo.html (original) +++ pypy/branch/guido-buildtool-web/pypy/tool/build/web/templates/builderinfo.html Fri Feb 16 21:03:11 2007 @@ -1,8 +1 @@ -
-

%(hostname)s

-
-
sysinfo: %(sysinfo)s
-
busy on: %(busy_on)s
-
-
Modified: pypy/branch/guido-buildtool-web/pypy/tool/build/web/templates/buildersinfo.html ============================================================================== --- pypy/branch/guido-buildtool-web/pypy/tool/build/web/templates/buildersinfo.html (original) +++ pypy/branch/guido-buildtool-web/pypy/tool/build/web/templates/buildersinfo.html Fri Feb 16 21:03:11 2007 @@ -1,12 +1,17 @@ - - + Build meta server builders page

Connected build servers

-%(builders)s +
+

+
+
sysinfo:
+
busy on:
+
+

Modified: pypy/branch/guido-buildtool-web/pypy/tool/build/web/templates/builds.html ============================================================================== --- pypy/branch/guido-buildtool-web/pypy/tool/build/web/templates/builds.html (original) +++ pypy/branch/guido-buildtool-web/pypy/tool/build/web/templates/builds.html Fri Feb 16 21:03:11 2007 @@ -1,5 +1,4 @@ - - + Build meta server builds page @@ -11,7 +10,7 @@ on the build to get more information.

-%(builds)s +
Modified: pypy/branch/guido-buildtool-web/pypy/tool/build/web/templates/index.html ============================================================================== --- pypy/branch/guido-buildtool-web/pypy/tool/build/web/templates/index.html (original) +++ pypy/branch/guido-buildtool-web/pypy/tool/build/web/templates/index.html Fri Feb 16 21:03:11 2007 @@ -1,4 +1,3 @@ - Build meta server web interface (temp index page) @@ -6,7 +5,7 @@ Modified: pypy/branch/guido-buildtool-web/pypy/tool/build/web/templates/serverstatus.html ============================================================================== --- pypy/branch/guido-buildtool-web/pypy/tool/build/web/templates/serverstatus.html (original) +++ pypy/branch/guido-buildtool-web/pypy/tool/build/web/templates/serverstatus.html Fri Feb 16 21:03:11 2007 @@ -1,16 +1,15 @@ - - + Build meta server status page

Server status

    -
  • Connected build servers: %(builders)s
  • -
  • Currently running builds: %(running)s
  • -
  • Builds done: %(done)s
  • -
  • Clients waiting for a build: %(waiting)s
  • -
  • Builds for which no suitable server is available: %(queued)s
  • +
  • Connected build servers:
  • +
  • Currently running builds:
  • +
  • Builds done:
  • +
  • Clients waiting for a build:
  • +
  • Builds for which no suitable server is available:
Modified: pypy/branch/guido-buildtool-web/pypy/tool/build/web/test/test_app.py ============================================================================== --- pypy/branch/guido-buildtool-web/pypy/tool/build/web/test/test_app.py (original) +++ pypy/branch/guido-buildtool-web/pypy/tool/build/web/test/test_app.py Fri Feb 16 21:03:11 2007 @@ -15,15 +15,6 @@ py.test.skip('Skipping XHTML validation (rest of the test passed)') check_html(html) -class TestTemplate(object): - def test_render(self): - # XXX stupid test ;) but perhaps we're going to add features later or - # something... - s = py.std.StringIO.StringIO('%(foo)s') - s.seek(0) - t = Template(s) - assert t.render({'foo': 'bar'}) == 'bar' - class FakeMetaServer(object): def __init__(self): self._status = {} @@ -108,7 +99,7 @@ def test_handle(self): server_channel.send(('set_buildersinfo', [{'hostname': 'host1', - 'sysinfo': {'foo': 'bar'}, + 'sysinfo': str({'foo': 'bar'}), 'busy_on': None}, {'hostname': 'host2', 'sysinfo': {'foo': 'baz'}, From cfbolz at codespeak.net Fri Feb 16 21:54:17 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 16 Feb 2007 21:54:17 +0100 (CET) Subject: [pypy-svn] r39048 - pypy/release/0.99.x/pypy/doc Message-ID: <20070216205417.D196C10105@code0.codespeak.net> Author: cfbolz Date: Fri Feb 16 21:54:16 2007 New Revision: 39048 Modified: pypy/release/0.99.x/pypy/doc/release-0.99.0.txt Log: mention .net compilatino Modified: pypy/release/0.99.x/pypy/doc/release-0.99.0.txt ============================================================================== --- pypy/release/0.99.x/pypy/doc/release-0.99.0.txt (original) +++ pypy/release/0.99.x/pypy/doc/release-0.99.0.txt Fri Feb 16 21:54:16 2007 @@ -75,8 +75,14 @@ types (strings, dicts, lists) - twice the speed of the 0.9 release, overall 2-3 slower than CPython -* Demonstrations of Javascript-Backend / AJAX experiments: - XXX play1 pointer? +* High level backends: + - It is now possible to translate the PyPy interpreter to run on the .NET + platform, which gives a very compliant (but somewhat slow) Python + interpreter. + - the JavaScript backend has evolved to a point where it can be used to write + AJAX web applications with it. This is still an experimental technique, + though. For demo applications see: + XXX play1 pointer? * new configuration system: There is a new comprehensive configuration system that allows From cfbolz at codespeak.net Fri Feb 16 22:08:01 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 16 Feb 2007 22:08:01 +0100 (CET) Subject: [pypy-svn] r39049 - pypy/release/0.99.x/pypy/doc Message-ID: <20070216210801.7B35410109@code0.codespeak.net> Author: cfbolz Date: Fri Feb 16 22:08:00 2007 New Revision: 39049 Modified: pypy/release/0.99.x/pypy/doc/release-0.99.0.txt Log: mention CALL_LIKELY_BUILTIN and the work on rlib Modified: pypy/release/0.99.x/pypy/doc/release-0.99.0.txt ============================================================================== --- pypy/release/0.99.x/pypy/doc/release-0.99.0.txt (original) +++ pypy/release/0.99.x/pypy/doc/release-0.99.0.txt Fri Feb 16 22:08:00 2007 @@ -71,8 +71,10 @@ XXX Move link to the bottom? * optimizations: - - experimental new optimized implementations for various built in Python + - Experimental new optimized implementations for various built in Python types (strings, dicts, lists) + - Optimized builtin lookups to not require any dictionary lookups if the + builtin is not shadowed by a name in the global dictionary. - twice the speed of the 0.9 release, overall 2-3 slower than CPython * High level backends: @@ -93,6 +95,11 @@ library modules have been implemented for PyPy. In addition we added a the pypymagic module that contains PyPy-specific functionality. +* RPython library: The release contains our emerging RPython library that tries + to make programming in RPython more pleasant. It contains an experimental + parser generator framework. For more details see: + http://codespeak.net/pypy/dist/pypy/doc/rlib.html + * improved documentation: XXX point to main new docs From cfbolz at codespeak.net Fri Feb 16 22:24:59 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 16 Feb 2007 22:24:59 +0100 (CET) Subject: [pypy-svn] r39050 - pypy/release/0.99.x/pypy/doc Message-ID: <20070216212459.8907810108@code0.codespeak.net> Author: cfbolz Date: Fri Feb 16 22:24:58 2007 New Revision: 39050 Modified: pypy/release/0.99.x/pypy/doc/release-0.99.0.txt Log: add more points to docs, cannot think of nice formulatinos Modified: pypy/release/0.99.x/pypy/doc/release-0.99.0.txt ============================================================================== --- pypy/release/0.99.x/pypy/doc/release-0.99.0.txt (original) +++ pypy/release/0.99.x/pypy/doc/release-0.99.0.txt Fri Feb 16 22:24:58 2007 @@ -100,7 +100,10 @@ parser generator framework. For more details see: http://codespeak.net/pypy/dist/pypy/doc/rlib.html -* improved documentation: +* improved documentation: + * XXX video + * reports + * point to vm-construction? XXX point to main new docs From hpk at codespeak.net Fri Feb 16 22:29:44 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Fri, 16 Feb 2007 22:29:44 +0100 (CET) Subject: [pypy-svn] r39051 - pypy/release/0.99.x/pypy/tool Message-ID: <20070216212944.8C7611010B@code0.codespeak.net> Author: hpk Date: Fri Feb 16 22:29:43 2007 New Revision: 39051 Modified: pypy/release/0.99.x/pypy/tool/makerelease.py Log: subst TAB with spaces Modified: pypy/release/0.99.x/pypy/tool/makerelease.py ============================================================================== --- pypy/release/0.99.x/pypy/tool/makerelease.py (original) +++ pypy/release/0.99.x/pypy/tool/makerelease.py Fri Feb 16 22:29:43 2007 @@ -77,7 +77,7 @@ # Generate the html files. out = cexec("python2.4 ../test_all.py") # Remove any .pyc files created in the process - target.chdir() + target.chdir() out = cexec("find . -name '*.pyc' -print0 | xargs -0 -r rm") finally: old.chdir() From hpk at codespeak.net Fri Feb 16 22:31:22 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Fri, 16 Feb 2007 22:31:22 +0100 (CET) Subject: [pypy-svn] r39052 - pypy/release/0.99.x/pypy/tool Message-ID: <20070216213122.83A0E1010D@code0.codespeak.net> Author: hpk Date: Fri Feb 16 22:31:21 2007 New Revision: 39052 Modified: pypy/release/0.99.x/pypy/tool/makerelease.py Log: let's use our version of the py lib, not some random one being installed Modified: pypy/release/0.99.x/pypy/tool/makerelease.py ============================================================================== --- pypy/release/0.99.x/pypy/tool/makerelease.py (original) +++ pypy/release/0.99.x/pypy/tool/makerelease.py Fri Feb 16 22:31:21 2007 @@ -1,5 +1,5 @@ - +import autopath import py log = py.log.Producer("log") From guido at codespeak.net Fri Feb 16 22:37:29 2007 From: guido at codespeak.net (guido at codespeak.net) Date: Fri, 16 Feb 2007 22:37:29 +0100 (CET) Subject: [pypy-svn] r39053 - in pypy/branch/guido-buildtool-web/pypy/tool/build: . test web web/templates web/test web/theme Message-ID: <20070216213729.5693A1010F@code0.codespeak.net> Author: guido Date: Fri Feb 16 22:37:26 2007 New Revision: 39053 Added: pypy/branch/guido-buildtool-web/pypy/tool/build/web/theme/ pypy/branch/guido-buildtool-web/pypy/tool/build/web/theme/style.css Removed: pypy/branch/guido-buildtool-web/pypy/tool/build/web/templates/builderinfo.html Modified: pypy/branch/guido-buildtool-web/pypy/tool/build/build.py pypy/branch/guido-buildtool-web/pypy/tool/build/config.py pypy/branch/guido-buildtool-web/pypy/tool/build/metaserver.py pypy/branch/guido-buildtool-web/pypy/tool/build/test/test_metaserver.py pypy/branch/guido-buildtool-web/pypy/tool/build/web/ (props changed) pypy/branch/guido-buildtool-web/pypy/tool/build/web/app.py pypy/branch/guido-buildtool-web/pypy/tool/build/web/server.py pypy/branch/guido-buildtool-web/pypy/tool/build/web/templates/buildersinfo.html pypy/branch/guido-buildtool-web/pypy/tool/build/web/test/test_app.py pypy/branch/guido-buildtool-web/pypy/tool/build/web/test/test_server.py Log: Showing more interesting information on the builders info page now, added stylesheet (and FsFile Resource subclass to support it), rolling back change in config.py I shouldn't have checked in, removed unused template. Modified: pypy/branch/guido-buildtool-web/pypy/tool/build/build.py ============================================================================== --- pypy/branch/guido-buildtool-web/pypy/tool/build/build.py (original) +++ pypy/branch/guido-buildtool-web/pypy/tool/build/build.py Fri Feb 16 22:37:26 2007 @@ -127,9 +127,13 @@ self.svnrev, self.revrange, self.request_time, self.build_start_time, self.build_end_time) - def serialize(self): + def todict(self): data = {'normalized_rev': self.normalized_rev} # it's a property data.update(self.__dict__) + data.pop('_nr', 0) + return data + + def serialize(self): return """\ email: %(email)s sysinfo: %(sysinfo)r @@ -141,7 +145,7 @@ request_time: %(request_time)s build_start_time: %(build_start_time)s build_end_time: %(build_end_time)s -""" % data +""" % self.todict() def _fromstring(cls, s): data = {} Modified: pypy/branch/guido-buildtool-web/pypy/tool/build/config.py ============================================================================== --- pypy/branch/guido-buildtool-web/pypy/tool/build/config.py (original) +++ pypy/branch/guido-buildtool-web/pypy/tool/build/config.py Fri Feb 16 22:37:26 2007 @@ -3,7 +3,7 @@ packageparent = py.magic.autopath().dirpath().dirpath().dirpath().dirpath() # general settings, used by both server and client -server = 'localhost' +server = 'codespeak.net' port = 12321 testport = 32123 path = [str(packageparent)] Modified: pypy/branch/guido-buildtool-web/pypy/tool/build/metaserver.py ============================================================================== --- pypy/branch/guido-buildtool-web/pypy/tool/build/metaserver.py (original) +++ pypy/branch/guido-buildtool-web/pypy/tool/build/metaserver.py Fri Feb 16 22:37:26 2007 @@ -184,12 +184,10 @@ def buildersinfo(self): ret = [] for b in self._builders: - print 'busy_on:', b.busy_on - print 'resolved:', b.busy_on and b.busy_on.compileinfo or None ret.append({ 'hostname': b.hostname, 'sysinfo': b.sysinfo, - 'busy_on': b.busy_on and b.busy_on.compileinfo or None, + 'busy_on': b.busy_on and b.busy_on.serialize() or None, }) return ret Modified: pypy/branch/guido-buildtool-web/pypy/tool/build/test/test_metaserver.py ============================================================================== --- pypy/branch/guido-buildtool-web/pypy/tool/build/test/test_metaserver.py (original) +++ pypy/branch/guido-buildtool-web/pypy/tool/build/test/test_metaserver.py Fri Feb 16 22:37:26 2007 @@ -186,9 +186,12 @@ assert bi[0]['sysinfo'] == {'foo': 1, 'bar': [1,2]} assert bi[0]['busy_on'] == None assert bi[1]['sysinfo'] == {'foo': 2, 'bar': [2,3]} - svr._builders[0].busy_on = c1 + req = build.BuildRequest('foo at bar.com', {}, {}, 'file:///tmp/repo', '10', + '10') + req._nr = '10' # normalized revision + svr._builders[0].busy_on = req bi = svr.buildersinfo() assert bi[0]['busy_on'] # for now, later more info should be made available - assert bi[0]['busy_on'] == c1.compileinfo + assert bi[0]['busy_on'] == req.serialize() Modified: pypy/branch/guido-buildtool-web/pypy/tool/build/web/app.py ============================================================================== --- pypy/branch/guido-buildtool-web/pypy/tool/build/web/app.py (original) +++ pypy/branch/guido-buildtool-web/pypy/tool/build/web/app.py Fri Feb 16 22:37:26 2007 @@ -3,9 +3,12 @@ """ a web server that displays status info of the meta server and builds """ import py +import time from pypy.tool.build import config from pypy.tool.build import execnetconference -from pypy.tool.build.web.server import HTTPError, Resource, Collection, Handler +from pypy.tool.build.build import BuildRequest +from pypy.tool.build.web.server import HTTPError, Resource, Collection, \ + Handler, FsFile from templess import templess @@ -86,7 +89,24 @@ self.get_buildersinfo()}))) def get_buildersinfo(self): - return self.call_method('buildersinfo') + infos = self.call_method('buildersinfo') + # some massaging of the data for Templess + for binfo in infos: + binfo['sysinfo'] = [binfo['sysinfo']] + if binfo['busy_on']: + b = binfo['busy_on'] + d = BuildRequest.fromstring(binfo['busy_on']).todict() + d.pop('sysinfo', None) # same as builder + d.pop('build_end_time', None) # it's still busy ;) + # templess doesn't understand dicts this way... + d['compileinfo'] = [{'key': k, 'value': v} for (k, v) in + d['compileinfo'].items()] + for key in ['request_time', 'build_start_time']: + if d[key]: + d[key] = time.strftime('%Y/%m/%d %H:%M:%S', + time.gmtime(d[key])) + binfo['busy_on'] = [d] + return infos class BuildPage(ServerPage): """ display information for one build """ @@ -134,6 +154,7 @@ class Application(Collection): """ the application root """ index = IndexPage() + style = FsFile(mypath.join('theme/style.css'), 'text/css') serverstatus = ServerStatusPage(config) buildersinfo = BuildersInfoPage(config) builds = Builds(config) Modified: pypy/branch/guido-buildtool-web/pypy/tool/build/web/server.py ============================================================================== --- pypy/branch/guido-buildtool-web/pypy/tool/build/web/server.py (original) +++ pypy/branch/guido-buildtool-web/pypy/tool/build/web/server.py Fri Feb 16 22:37:26 2007 @@ -183,4 +183,16 @@ server = HTTPServer(address, handler) server.serve_forever() +# ready-to-use Collection and Resource implementations +class FsFile(Resource): + debug = False + def __init__(self, path, content_type): + self._path = path + self._content_type = content_type + + _data = None + def handle(self, handler, path, query): + if self._data is None or self.debug: + self._data = self._path.read() + return ({'Content-Type': self._content_type}, self._data) Modified: pypy/branch/guido-buildtool-web/pypy/tool/build/web/templates/buildersinfo.html ============================================================================== --- pypy/branch/guido-buildtool-web/pypy/tool/build/web/templates/buildersinfo.html (original) +++ pypy/branch/guido-buildtool-web/pypy/tool/build/web/templates/buildersinfo.html Fri Feb 16 22:37:26 2007 @@ -1,6 +1,7 @@ Build meta server builders page +

Connected build servers

@@ -8,8 +9,56 @@

-
sysinfo:
-
busy on:
+
+
sysinfo:
+
+
+ os: + +
+
+ maxint: + +
+
+ byteorder: + +
+
+
+
+
busy on build:
+
nothing
+
+
+ request time: + +
+
+ build start time: + +
+
+ svn url: + +
+
+ svn revision: + +
+ +
+

Modified: pypy/branch/guido-buildtool-web/pypy/tool/build/web/test/test_app.py ============================================================================== --- pypy/branch/guido-buildtool-web/pypy/tool/build/web/test/test_app.py (original) +++ pypy/branch/guido-buildtool-web/pypy/tool/build/web/test/test_app.py Fri Feb 16 22:37:26 2007 @@ -4,6 +4,7 @@ from pypy.tool.build.web.conftest import option from pypy.tool.build.test import fake from pypy.tool.build import config as build_config +from pypy.tool.build import build TESTPORT = build_config.testport @@ -94,16 +95,28 @@ def test_get_builderinfo(self): p = BuildersInfoPage(config, gateway) assert p.get_buildersinfo() == [] - server_channel.send(('set_buildersinfo', [{'foo': 'bar'}])) - assert p.get_buildersinfo() == [{'foo': 'bar'}] + server_channel.send(('set_buildersinfo', [{'sysinfo': 'foo', + 'busy_on': None}])) + assert p.get_buildersinfo() == [{'sysinfo': ['foo'], 'busy_on': None}] def test_handle(self): + b = build.BuildRequest('foo at bar.com', {}, {'foo': 'bar'}, + 'http://codespeak.net/svn/pypy/dist', 10, 2, + 123456789) + busy_on = b.serialize() server_channel.send(('set_buildersinfo', [{'hostname': 'host1', - 'sysinfo': str({'foo': 'bar'}), + 'sysinfo': { + 'os': 'linux2', + 'maxint': + 9223372036854775807, + 'byteorder': 'little'}, 'busy_on': None}, {'hostname': 'host2', - 'sysinfo': {'foo': 'baz'}, - 'busy_on': {'spam': 'eggs'}, + 'sysinfo': { + 'os': 'zx81', + 'maxint': 255, + 'byteorder': 'little'}, + 'busy_on': busy_on, }])) p = BuildersInfoPage(config, gateway) headers, html = p.handle(None, '/buildersinfo', '') Modified: pypy/branch/guido-buildtool-web/pypy/tool/build/web/test/test_server.py ============================================================================== --- pypy/branch/guido-buildtool-web/pypy/tool/build/web/test/test_server.py (original) +++ pypy/branch/guido-buildtool-web/pypy/tool/build/web/test/test_server.py Fri Feb 16 22:37:26 2007 @@ -1,5 +1,5 @@ import py -from pypy.tool.build.web.server import Handler, Resource, Collection, HTTPError +from pypy.tool.build.web.server import * class NonInitHandler(Handler): request_version = '1.0' @@ -100,3 +100,14 @@ def test_get_response_wrong_body(self): py.test.raises(ValueError, "self.handler.response(200, {}, u'xxx')") +class TestFsFile(object): + def test_handle(self): + temp = py.test.ensuretemp('TestStaticResource.test_handle') + foo = temp.ensure('foo.txt') + foo.write('foo') + r = FsFile(foo, 'text/plain') + ret = r.handle(None, '/bar/foo.txt', '') + assert ret[0] == {'Content-Type': 'text/plain'} + assert ret[1] == 'foo' + + Added: pypy/branch/guido-buildtool-web/pypy/tool/build/web/theme/style.css ============================================================================== --- (empty file) +++ pypy/branch/guido-buildtool-web/pypy/tool/build/web/theme/style.css Fri Feb 16 22:37:26 2007 @@ -0,0 +1,19 @@ +body { + background-color: white; + color: black; + font: Times New Roman; +} + +.infoblock { + margin-bottom: 1em; +} + +.title { + font-weight: bold; +} + +.sub div { + margin-left: 1em; + font-size: 0.8em; +} + From pedronis at codespeak.net Fri Feb 16 22:41:36 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Fri, 16 Feb 2007 22:41:36 +0100 (CET) Subject: [pypy-svn] r39054 - pypy/release/0.99.x/pypy/tool Message-ID: <20070216214136.6995D10113@code0.codespeak.net> Author: pedronis Date: Fri Feb 16 22:41:35 2007 New Revision: 39054 Modified: pypy/release/0.99.x/pypy/tool/makerelease.py Log: try to be more chatty Modified: pypy/release/0.99.x/pypy/tool/makerelease.py ============================================================================== --- pypy/release/0.99.x/pypy/tool/makerelease.py (original) +++ pypy/release/0.99.x/pypy/tool/makerelease.py Fri Feb 16 22:41:35 2007 @@ -5,6 +5,8 @@ log = py.log.Producer("log") logexec = py.log.Producer("exec") +import os + BASEURL = "file:///svn/pypy/release/0.99.x" DDIR = py.path.local('/www/codespeak.net/htdocs/download/pypy') @@ -75,7 +77,11 @@ old = docdir.chdir() try: # Generate the html files. - out = cexec("python2.4 ../test_all.py") + cmd = "python2.4 ../test_all.py" + logexec(cmd) + r = os.system(cmd) + if r: + raise SystemExit, -1 # Remove any .pyc files created in the process target.chdir() out = cexec("find . -name '*.pyc' -print0 | xargs -0 -r rm") From pedronis at codespeak.net Fri Feb 16 22:51:01 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Fri, 16 Feb 2007 22:51:01 +0100 (CET) Subject: [pypy-svn] r39055 - pypy/release/0.99.x/pypy/doc Message-ID: <20070216215101.6B37810115@code0.codespeak.net> Author: pedronis Date: Fri Feb 16 22:51:00 2007 New Revision: 39055 Modified: pypy/release/0.99.x/pypy/doc/_ref.txt Log: update _ref.txt Modified: pypy/release/0.99.x/pypy/doc/_ref.txt ============================================================================== --- pypy/release/0.99.x/pypy/doc/_ref.txt (original) +++ pypy/release/0.99.x/pypy/doc/_ref.txt Fri Feb 16 22:51:00 2007 @@ -31,13 +31,6 @@ .. _`pypy/interpreter/pyparser`: ../../pypy/interpreter/pyparser .. _`pypy/interpreter/typedef.py`: ../../pypy/interpreter/typedef.py .. _`jit/`: ../../pypy/jit -.. _`jit/codegen/`: ../../pypy/jit/codegen -.. _`pypy/jit/codegen/model.py`: ../../pypy/jit/codegen/model.py -.. _`jit/goal/`: ../../pypy/jit/goal -.. _`jit/hintannotator/`: ../../pypy/jit/hintannotator -.. _`jit/timeshifter/`: ../../pypy/jit/timeshifter -.. _`pypy/jit/timeshifter/rvalue.py`: ../../pypy/jit/timeshifter/rvalue.py -.. _`jit/tl/`: ../../pypy/jit/tl .. _`lang/`: ../../pypy/lang .. _`lang/js/`: ../../pypy/lang/js .. _`lang/prolog/`: ../../pypy/lang/prolog From cfbolz at codespeak.net Fri Feb 16 22:58:05 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 16 Feb 2007 22:58:05 +0100 (CET) Subject: [pypy-svn] r39056 - pypy/release/0.99.x/pypy/doc Message-ID: <20070216215805.5235E10111@code0.codespeak.net> Author: cfbolz Date: Fri Feb 16 22:58:03 2007 New Revision: 39056 Modified: pypy/release/0.99.x/pypy/doc/release-0.99.0.txt Log: fix rest. add point about files. add sre and socket Modified: pypy/release/0.99.x/pypy/doc/release-0.99.0.txt ============================================================================== --- pypy/release/0.99.x/pypy/doc/release-0.99.0.txt (original) +++ pypy/release/0.99.x/pypy/doc/release-0.99.0.txt Fri Feb 16 22:58:03 2007 @@ -55,6 +55,7 @@ ===================== * new object spaces: + - Tainting: a 270-line proxy object space tracking and boxing sensitive information within an application. A tainted object is completely barred from crossing @@ -71,16 +72,21 @@ XXX Move link to the bottom? * optimizations: + - Experimental new optimized implementations for various built in Python types (strings, dicts, lists) + - Optimized builtin lookups to not require any dictionary lookups if the builtin is not shadowed by a name in the global dictionary. + - twice the speed of the 0.9 release, overall 2-3 slower than CPython * High level backends: + - It is now possible to translate the PyPy interpreter to run on the .NET platform, which gives a very compliant (but somewhat slow) Python interpreter. + - the JavaScript backend has evolved to a point where it can be used to write AJAX web applications with it. This is still an experimental technique, though. For demo applications see: @@ -91,10 +97,14 @@ fine-grained configuration of the PyPy standard interpreter and the translation process. -* new modules: Since the last release, the signal, mmap, bz2 and fcntl standard - library modules have been implemented for PyPy. In addition we added a the +* new and improved modules: Since the last release, the signal, mmap, bz2 + and fcntl standard library modules have been implemented for PyPy. The socket + and _sre modules have been greatly improved. In addition we added a the pypymagic module that contains PyPy-specific functionality. +* improved file implementation: Our file implementation was ported to RPython + and is therefore somewhat faster. + * RPython library: The release contains our emerging RPython library that tries to make programming in RPython more pleasant. It contains an experimental parser generator framework. For more details see: @@ -102,9 +112,9 @@ * improved documentation: * XXX video - * reports + * reports? * point to vm-construction? - XXX point to main new docs + * XXX point to main new docs What about 1.0? From hpk at codespeak.net Fri Feb 16 23:00:40 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Fri, 16 Feb 2007 23:00:40 +0100 (CET) Subject: [pypy-svn] r39057 - pypy/release/0.99.x/pypy/doc Message-ID: <20070216220040.CC3D810118@code0.codespeak.net> Author: hpk Date: Fri Feb 16 23:00:38 2007 New Revision: 39057 Modified: pypy/release/0.99.x/pypy/doc/release-0.99.0.txt Log: as far as i can see, stackless support improved quite a bit Modified: pypy/release/0.99.x/pypy/doc/release-0.99.0.txt ============================================================================== --- pypy/release/0.99.x/pypy/doc/release-0.99.0.txt (original) +++ pypy/release/0.99.x/pypy/doc/release-0.99.0.txt Fri Feb 16 23:00:38 2007 @@ -103,7 +103,9 @@ pypymagic module that contains PyPy-specific functionality. * improved file implementation: Our file implementation was ported to RPython - and is therefore somewhat faster. + and is therefore faster (and not based on libc). + +* more stable stackless support * RPython library: The release contains our emerging RPython library that tries to make programming in RPython more pleasant. It contains an experimental From cfbolz at codespeak.net Fri Feb 16 23:08:00 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 16 Feb 2007 23:08:00 +0100 (CET) Subject: [pypy-svn] r39058 - pypy/release/0.99.x/pypy/doc Message-ID: <20070216220800.07AC81011A@code0.codespeak.net> Author: cfbolz Date: Fri Feb 16 23:07:59 2007 New Revision: 39058 Modified: pypy/release/0.99.x/pypy/doc/release-0.99.0.txt Log: add link, reformulate stackless entry, fix typos Modified: pypy/release/0.99.x/pypy/doc/release-0.99.0.txt ============================================================================== --- pypy/release/0.99.x/pypy/doc/release-0.99.0.txt (original) +++ pypy/release/0.99.x/pypy/doc/release-0.99.0.txt Fri Feb 16 23:07:59 2007 @@ -59,11 +59,11 @@ - Tainting: a 270-line proxy object space tracking and boxing sensitive information within an application. A tainted object is completely barred from crossing - an IO barrier, such as writing to files, databases - or sockets. This allows to to significantly reduce the + an I/O barrier, such as writing to files, databases + or sockets. This allows to significantly reduce the effort of e.g. security reviews to the few places where objects are "declassified" in order to send information - across IO barriers. + across I/O barriers. - Transparent proxies: An addition to the standard object space, which allows you to create objects of builtin types with completely customised @@ -105,7 +105,8 @@ * improved file implementation: Our file implementation was ported to RPython and is therefore faster (and not based on libc). -* more stable stackless support +* The stability of stackless features was greatly improved. For more details + see: http://codespeak.net/pypy/dist/pypy/doc/stackless.html * RPython library: The release contains our emerging RPython library that tries to make programming in RPython more pleasant. It contains an experimental From ac at codespeak.net Fri Feb 16 23:30:26 2007 From: ac at codespeak.net (ac at codespeak.net) Date: Fri, 16 Feb 2007 23:30:26 +0100 (CET) Subject: [pypy-svn] r39061 - pypy/release/0.99.x Message-ID: <20070216223026.92D3010121@code0.codespeak.net> Author: ac Date: Fri Feb 16 23:30:25 2007 New Revision: 39061 Modified: pypy/release/0.99.x/LICENSE Log: We have changed name. Modified: pypy/release/0.99.x/LICENSE ============================================================================== --- pypy/release/0.99.x/LICENSE (original) +++ pypy/release/0.99.x/LICENSE Fri Feb 16 23:30:25 2007 @@ -93,7 +93,7 @@ Bert Freudenberg Heinrich-Heine University, Germany - AB Strakt, Sweden + Open End AB, Sweden merlinux GmbH, Germany tismerysoft GmbH, Germany Logilab Paris, France From ac at codespeak.net Fri Feb 16 23:31:51 2007 From: ac at codespeak.net (ac at codespeak.net) Date: Fri, 16 Feb 2007 23:31:51 +0100 (CET) Subject: [pypy-svn] r39062 - pypy/release/0.99.x Message-ID: <20070216223151.044CD10121@code0.codespeak.net> Author: ac Date: Fri Feb 16 23:31:51 2007 New Revision: 39062 Modified: pypy/release/0.99.x/LICENSE Log: Oops, too quick at checking in. Modified: pypy/release/0.99.x/LICENSE ============================================================================== --- pypy/release/0.99.x/LICENSE (original) +++ pypy/release/0.99.x/LICENSE Fri Feb 16 23:31:51 2007 @@ -93,7 +93,7 @@ Bert Freudenberg Heinrich-Heine University, Germany - Open End AB, Sweden + Open End AB (formerly AB Strakt), Sweden merlinux GmbH, Germany tismerysoft GmbH, Germany Logilab Paris, France From cfbolz at codespeak.net Fri Feb 16 23:32:04 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 16 Feb 2007 23:32:04 +0100 (CET) Subject: [pypy-svn] r39063 - pypy/release/0.99.x Message-ID: <20070216223204.70F6F10125@code0.codespeak.net> Author: cfbolz Date: Fri Feb 16 23:32:02 2007 New Revision: 39063 Modified: pypy/release/0.99.x/README Log: point to the html files as well Modified: pypy/release/0.99.x/README ============================================================================== --- pypy/release/0.99.x/README (original) +++ pypy/release/0.99.x/README Fri Feb 16 23:32:02 2007 @@ -11,7 +11,8 @@ For more, we invite you to head over to our getting-started document: - pypy/doc/getting-started.txt + pypy/doc/getting-started.txt or + pypy/doc/getting-started.html (local if you got a tarball or svn checkout) http://codespeak.net/pypy/dist/pypy/doc/getting-started.html @@ -23,7 +24,8 @@ For information in what's new in this release, please read the release announcement: - pypy/doc/release-0.99.0.txt + pypy/doc/release-0.99.0.txt or + pypy/doc/release-0.99.0.html http://codespeak.net/pypy/dist/pypy/doc/release-0.99.0.html Since December 2004, the development of PyPy has been funded by the From pedronis at codespeak.net Fri Feb 16 23:42:14 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Fri, 16 Feb 2007 23:42:14 +0100 (CET) Subject: [pypy-svn] r39064 - pypy/release/0.99.x Message-ID: <20070216224214.B26A810123@code0.codespeak.net> Author: pedronis Date: Fri Feb 16 23:42:13 2007 New Revision: 39064 Modified: pypy/release/0.99.x/README Log: change order here Modified: pypy/release/0.99.x/README ============================================================================== --- pypy/release/0.99.x/README (original) +++ pypy/release/0.99.x/README Fri Feb 16 23:42:13 2007 @@ -11,8 +11,8 @@ For more, we invite you to head over to our getting-started document: - pypy/doc/getting-started.txt or - pypy/doc/getting-started.html + pypy/doc/getting-started.html or + pypy/doc/getting-started.txt (local if you got a tarball or svn checkout) http://codespeak.net/pypy/dist/pypy/doc/getting-started.html From cfbolz at codespeak.net Fri Feb 16 23:49:47 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 16 Feb 2007 23:49:47 +0100 (CET) Subject: [pypy-svn] r39066 - pypy/release/0.99.x/pypy/doc Message-ID: <20070216224947.ADEAA10129@code0.codespeak.net> Author: cfbolz Date: Fri Feb 16 23:49:46 2007 New Revision: 39066 Modified: pypy/release/0.99.x/pypy/doc/release-0.99.0.txt Log: resolve last XXX Modified: pypy/release/0.99.x/pypy/doc/release-0.99.0.txt ============================================================================== --- pypy/release/0.99.x/pypy/doc/release-0.99.0.txt (original) +++ pypy/release/0.99.x/pypy/doc/release-0.99.0.txt Fri Feb 16 23:49:46 2007 @@ -114,10 +114,19 @@ http://codespeak.net/pypy/dist/pypy/doc/rlib.html * improved documentation: - * XXX video - * reports? - * point to vm-construction? - * XXX point to main new docs + + - extended documentation about stackless features: + http://codespeak.net/pypy/dist/pypy/doc/stackless.html + + - PyPy video documentation: eight hours of talks, interviews and features: + http://codespeak.net/pypy/dist/pypy/doc/video-index.html + + - technical reports about various aspects of PyPy: + http://codespeak.net/pypy/dist/pypy/doc/index-report.html + + The entry point to all our documentation is: + http://codespeak.net/pypy/dist/pypy/doc/index.html + What about 1.0? From hpk at codespeak.net Fri Feb 16 23:58:30 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Fri, 16 Feb 2007 23:58:30 +0100 (CET) Subject: [pypy-svn] r39067 - pypy/release/0.99.x/pypy/doc Message-ID: <20070216225830.114DF1012A@code0.codespeak.net> Author: hpk Date: Fri Feb 16 23:58:29 2007 New Revision: 39067 Modified: pypy/release/0.99.x/pypy/doc/release-0.99.0.txt Log: os also received quites some improvement (reading the diff) Modified: pypy/release/0.99.x/pypy/doc/release-0.99.0.txt ============================================================================== --- pypy/release/0.99.x/pypy/doc/release-0.99.0.txt (original) +++ pypy/release/0.99.x/pypy/doc/release-0.99.0.txt Fri Feb 16 23:58:29 2007 @@ -98,8 +98,8 @@ translation process. * new and improved modules: Since the last release, the signal, mmap, bz2 - and fcntl standard library modules have been implemented for PyPy. The socket - and _sre modules have been greatly improved. In addition we added a the + and fcntl standard library modules have been implemented for PyPy. The socket, + _sre and os modules have been greatly improved. In addition we added a the pypymagic module that contains PyPy-specific functionality. * improved file implementation: Our file implementation was ported to RPython From pedronis at codespeak.net Sat Feb 17 00:36:58 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 17 Feb 2007 00:36:58 +0100 (CET) Subject: [pypy-svn] r39068 - pypy/dist/pypy/module/sys Message-ID: <20070216233658.6692710126@code0.codespeak.net> Author: pedronis Date: Sat Feb 17 00:36:56 2007 New Revision: 39068 Modified: pypy/dist/pypy/module/sys/version.py (contents, props changed) Log: try to use the svn:keyword mechanism Modified: pypy/dist/pypy/module/sys/version.py ============================================================================== --- pypy/dist/pypy/module/sys/version.py (original) +++ pypy/dist/pypy/module/sys/version.py Sat Feb 17 00:36:56 2007 @@ -11,7 +11,9 @@ PYPY_VERSION = (0, 9, 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] +SVN_URL = "$HeadURL$"[10:-28] + +REV = "$LastChangedRevision$" # ____________________________________________________________ From pedronis at codespeak.net Sat Feb 17 00:42:47 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 17 Feb 2007 00:42:47 +0100 (CET) Subject: [pypy-svn] r39069 - pypy/dist/pypy/module/sys Message-ID: <20070216234247.9F6451011C@code0.codespeak.net> Author: pedronis Date: Sat Feb 17 00:42:46 2007 New Revision: 39069 Modified: pypy/dist/pypy/module/sys/version.py Log: use LastChangedRevision if we are in a working copy. Modified: pypy/dist/pypy/module/sys/version.py ============================================================================== --- pypy/dist/pypy/module/sys/version.py (original) +++ pypy/dist/pypy/module/sys/version.py Sat Feb 17 00:42:46 2007 @@ -13,7 +13,7 @@ SVN_URL = "$HeadURL$"[10:-28] -REV = "$LastChangedRevision$" +REV = "$LastChangedRevision$"[22:-2] # ____________________________________________________________ @@ -64,7 +64,7 @@ "Return the last-changed svn revision number." # NB. we hack the number directly out of the .svn directory to avoid # to depend on an external 'svn' executable in the path. - rev = 0 + rev = int(REV) try: f = open(os.path.join(autopath.pypydir, '.svn', 'format'), 'r') format = int(f.readline().strip()) From pedronis at codespeak.net Sat Feb 17 00:46:10 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 17 Feb 2007 00:46:10 +0100 (CET) Subject: [pypy-svn] r39070 - pypy/dist/pypy/module/sys Message-ID: <20070216234610.4998E1012D@code0.codespeak.net> Author: pedronis Date: Sat Feb 17 00:46:08 2007 New Revision: 39070 Modified: pypy/dist/pypy/module/sys/version.py Log: bump to 0.99 Modified: pypy/dist/pypy/module/sys/version.py ============================================================================== --- pypy/dist/pypy/module/sys/version.py (original) +++ pypy/dist/pypy/module/sys/version.py Sat Feb 17 00:46:08 2007 @@ -8,7 +8,7 @@ CPYTHON_VERSION = (2, 4, 1, "alpha", 42) CPYTHON_API_VERSION = 1012 -PYPY_VERSION = (0, 9, 0, "alpha", '?') +PYPY_VERSION = (0, 99, 0, "alpha", '?') # the last item is replaced by the svn revision ^^^ SVN_URL = "$HeadURL$"[10:-28] From pedronis at codespeak.net Sat Feb 17 00:47:06 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 17 Feb 2007 00:47:06 +0100 (CET) Subject: [pypy-svn] r39071 - pypy/release/0.99.x/pypy/module/sys Message-ID: <20070216234706.8BE7810130@code0.codespeak.net> Author: pedronis Date: Sat Feb 17 00:47:05 2007 New Revision: 39071 Removed: pypy/release/0.99.x/pypy/module/sys/version.py Log: merge by copy from trunk From pedronis at codespeak.net Sat Feb 17 00:48:03 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 17 Feb 2007 00:48:03 +0100 (CET) Subject: [pypy-svn] r39072 - pypy/release/0.99.x/pypy/module/sys Message-ID: <20070216234803.1266910132@code0.codespeak.net> Author: pedronis Date: Sat Feb 17 00:48:03 2007 New Revision: 39072 Added: pypy/release/0.99.x/pypy/module/sys/version.py - copied unchanged from r39071, pypy/dist/pypy/module/sys/version.py Log: finish merge by copy from trunk From pedronis at codespeak.net Sat Feb 17 00:57:18 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 17 Feb 2007 00:57:18 +0100 (CET) Subject: [pypy-svn] r39073 - pypy/dist/pypy/doc Message-ID: <20070216235718.E2B2710134@code0.codespeak.net> Author: pedronis Date: Sat Feb 17 00:57:16 2007 New Revision: 39073 Modified: pypy/dist/pypy/doc/how-to-release.txt Log: update: remember to bump version in sys/version.py Modified: pypy/dist/pypy/doc/how-to-release.txt ============================================================================== --- pypy/dist/pypy/doc/how-to-release.txt (original) +++ pypy/dist/pypy/doc/how-to-release.txt Sat Feb 17 00:57:16 2007 @@ -16,7 +16,9 @@ Release Steps ---------------- -* at code freeze make a release branch under http://codepeak.net/svn/pypy/release/x.y(.z) , +* at code freeze make a release branch under http://codepeak.net/svn/pypy/release/x.y(.z). IMPORTANT: bump the pypy version number in module/sys/version.py, + notice that the branch will capture the revision number of this change + for the release; some of the next updates may be done before or after branching; make sure things are ported back to the trunk and to the branch as necessary * update dist/pypy/doc/contributor.txt (and possibly dist/LICENSE) @@ -24,8 +26,9 @@ * write release announcement dist/pypy/doc/release-x.y(.z).txt * update dist/pypy/doc/getting-started.txt links at the top and release number references, make sure it is generally up-to-date -* use, after the necessary updates, dist/pypy/tool/makerealase.py to make the tarballs - on codespeak (XXX what about tagging the release?) +* use, after the necessary updates, dist/pypy/tool/makerelease.py to make the tarballs + on codespeak; this generates html doc for the tarballs too. + (XXX what about tagging?) * nowadays we have an extensive set of nightly builds and test runs. Is probably good to do some minimal testing of the tarballs, especially to check that things work even outside a working copy or if some stuff is missing. From pedronis at codespeak.net Sat Feb 17 01:15:03 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 17 Feb 2007 01:15:03 +0100 (CET) Subject: [pypy-svn] r39074 - pypy/dist/pypy/doc Message-ID: <20070217001503.A479410131@code0.codespeak.net> Author: pedronis Date: Sat Feb 17 01:15:00 2007 New Revision: 39074 Modified: pypy/dist/pypy/doc/confrest.py pypy/dist/pypy/doc/how-to-release.txt Log: formatting Modified: pypy/dist/pypy/doc/confrest.py ============================================================================== --- pypy/dist/pypy/doc/confrest.py (original) +++ pypy/dist/pypy/doc/confrest.py Sat Feb 17 01:15:00 2007 @@ -1,6 +1,9 @@ import py from py.__.doc.confrest import * +#import docage + + class PyPyPage(Page): def fill_menubar(self): self.menubar = html.div( Modified: pypy/dist/pypy/doc/how-to-release.txt ============================================================================== --- pypy/dist/pypy/doc/how-to-release.txt (original) +++ pypy/dist/pypy/doc/how-to-release.txt Sat Feb 17 01:15:00 2007 @@ -16,21 +16,25 @@ Release Steps ---------------- -* at code freeze make a release branch under http://codepeak.net/svn/pypy/release/x.y(.z). IMPORTANT: bump the pypy version number in module/sys/version.py, - notice that the branch will capture the revision number of this change - for the release; - some of the next updates may be done before or after branching; - make sure things are ported back to the trunk and to the branch as necessary +* at code freeze make a release branch under + http://codepeak.net/svn/pypy/release/x.y(.z). IMPORTANT: bump the + pypy version number in module/sys/version.py, notice that the branch + will capture the revision number of this change for the release; + some of the next updates may be done before or after branching; make + sure things are ported back to the trunk and to the branch as + necessary * update dist/pypy/doc/contributor.txt (and possibly dist/LICENSE) * update dist/README * write release announcement dist/pypy/doc/release-x.y(.z).txt * update dist/pypy/doc/getting-started.txt links at the top and release number references, make sure it is generally up-to-date -* use, after the necessary updates, dist/pypy/tool/makerelease.py to make the tarballs - on codespeak; this generates html doc for the tarballs too. - (XXX what about tagging?) -* nowadays we have an extensive set of nightly builds and test runs. Is probably - good to do some minimal testing of the tarballs, especially to check that things - work even outside a working copy or if some stuff is missing. +* use, after the necessary updates, dist/pypy/tool/makerelease.py to + make the tarballs on codespeak; this generates html doc for the + tarballs too. (XXX what about tagging?) +* nowadays we have an extensive set of nightly builds and test + runs. Is probably good to do some minimal testing of the tarballs, + especially to check that things work even outside a working copy or + if some stuff is missing. * write a news item for the release in dist/pypy/doc/news.txt -* send announcements to pypy-dev, pypy-funding, python-list, python-announce, python-dev ... +* send announcements to pypy-dev, pypy-funding, python-list, + python-announce, python-dev ... From pedronis at codespeak.net Sat Feb 17 09:07:20 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 17 Feb 2007 09:07:20 +0100 (CET) Subject: [pypy-svn] r39075 - pypy/dist/pypy/doc/tool Message-ID: <20070217080720.D8EC710139@code0.codespeak.net> Author: pedronis Date: Sat Feb 17 09:07:19 2007 New Revision: 39075 Modified: pypy/dist/pypy/doc/tool/makecontributor.py Log: squash tab Modified: pypy/dist/pypy/doc/tool/makecontributor.py ============================================================================== --- pypy/dist/pypy/doc/tool/makecontributor.py (original) +++ pypy/dist/pypy/doc/tool/makecontributor.py Sat Feb 17 09:07:19 2007 @@ -34,6 +34,6 @@ realname = user.realname.strip() if not mark and count < cutoff: mark = True - print '-'*60 + print '-'*60 print " ", realname #print count, " ", author From pedronis at codespeak.net Sat Feb 17 09:09:46 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 17 Feb 2007 09:09:46 +0100 (CET) Subject: [pypy-svn] r39076 - pypy/release/0.99.x/pypy/doc/tool Message-ID: <20070217080946.C7CD91013B@code0.codespeak.net> Author: pedronis Date: Sat Feb 17 09:09:45 2007 New Revision: 39076 Modified: pypy/release/0.99.x/pypy/doc/tool/makecontributor.py Log: merge tab squashing Modified: pypy/release/0.99.x/pypy/doc/tool/makecontributor.py ============================================================================== --- pypy/release/0.99.x/pypy/doc/tool/makecontributor.py (original) +++ pypy/release/0.99.x/pypy/doc/tool/makecontributor.py Sat Feb 17 09:09:45 2007 @@ -34,6 +34,6 @@ realname = user.realname.strip() if not mark and count < cutoff: mark = True - print '-'*60 + print '-'*60 print " ", realname #print count, " ", author From pedronis at codespeak.net Sat Feb 17 09:13:46 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 17 Feb 2007 09:13:46 +0100 (CET) Subject: [pypy-svn] r39077 - pypy/dist/pypy/lang/automata/test Message-ID: <20070217081346.366421013E@code0.codespeak.net> Author: pedronis Date: Sat Feb 17 09:13:45 2007 New Revision: 39077 Modified: pypy/dist/pypy/lang/automata/test/test_dfa.py Log: remove unused imports Modified: pypy/dist/pypy/lang/automata/test/test_dfa.py ============================================================================== --- pypy/dist/pypy/lang/automata/test/test_dfa.py (original) +++ pypy/dist/pypy/lang/automata/test/test_dfa.py Sat Feb 17 09:13:45 2007 @@ -2,13 +2,6 @@ from pypy import conftest from pypy.rpython.test.test_llinterp import interpret -from pypy.translator.translator import graphof -from pypy.jit.timeshifter.test.test_timeshift import hannotate -from pypy.jit.timeshifter.hrtyper import HintRTyper -from pypy.jit.timeshifter.test.test_timeshift import P_NOVIRTUAL -from pypy.rpython.llinterp import LLInterpreter -from pypy.objspace.flow.model import checkgraph -from pypy.rlib.objectmodel import hint from pypy.lang.automata.dfa import * From pedronis at codespeak.net Sat Feb 17 09:15:14 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 17 Feb 2007 09:15:14 +0100 (CET) Subject: [pypy-svn] r39078 - pypy/release/0.99.x/pypy/lang/automata/test Message-ID: <20070217081514.627E910140@code0.codespeak.net> Author: pedronis Date: Sat Feb 17 09:15:12 2007 New Revision: 39078 Modified: pypy/release/0.99.x/pypy/lang/automata/test/test_dfa.py Log: merge removal of unused jit imports Modified: pypy/release/0.99.x/pypy/lang/automata/test/test_dfa.py ============================================================================== --- pypy/release/0.99.x/pypy/lang/automata/test/test_dfa.py (original) +++ pypy/release/0.99.x/pypy/lang/automata/test/test_dfa.py Sat Feb 17 09:15:12 2007 @@ -2,13 +2,6 @@ from pypy import conftest from pypy.rpython.test.test_llinterp import interpret -from pypy.translator.translator import graphof -from pypy.jit.timeshifter.test.test_timeshift import hannotate -from pypy.jit.timeshifter.hrtyper import HintRTyper -from pypy.jit.timeshifter.test.test_timeshift import P_NOVIRTUAL -from pypy.rpython.llinterp import LLInterpreter -from pypy.objspace.flow.model import checkgraph -from pypy.rlib.objectmodel import hint from pypy.lang.automata.dfa import * From pedronis at codespeak.net Sat Feb 17 09:16:22 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 17 Feb 2007 09:16:22 +0100 (CET) Subject: [pypy-svn] r39079 - in pypy/dist/pypy/translator/js/examples: djangoping/test test Message-ID: <20070217081622.42B7E10144@code0.codespeak.net> Author: pedronis Date: Sat Feb 17 09:16:21 2007 New Revision: 39079 Modified: pypy/dist/pypy/translator/js/examples/djangoping/test/ (props changed) pypy/dist/pypy/translator/js/examples/djangoping/test/test_build.py (props changed) pypy/dist/pypy/translator/js/examples/test/test_examples.py (props changed) Log: fixeol From pedronis at codespeak.net Sat Feb 17 09:17:41 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 17 Feb 2007 09:17:41 +0100 (CET) Subject: [pypy-svn] r39080 - in pypy/release/0.99.x/pypy/translator/js/examples: djangoping/test test Message-ID: <20070217081741.E9CB210146@code0.codespeak.net> Author: pedronis Date: Sat Feb 17 09:17:40 2007 New Revision: 39080 Modified: pypy/release/0.99.x/pypy/translator/js/examples/djangoping/test/ (props changed) pypy/release/0.99.x/pypy/translator/js/examples/djangoping/test/test_build.py (props changed) pypy/release/0.99.x/pypy/translator/js/examples/test/test_examples.py (props changed) Log: merge fixeol From pedronis at codespeak.net Sat Feb 17 09:28:30 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 17 Feb 2007 09:28:30 +0100 (CET) Subject: [pypy-svn] r39081 - pypy/dist/pypy/translator/cli/test Message-ID: <20070217082830.7790C10148@code0.codespeak.net> Author: pedronis Date: Sat Feb 17 09:28:29 2007 New Revision: 39081 Modified: pypy/dist/pypy/translator/cli/test/runtest.py Log: fix skipping logic vs caching of previous compilation. Modified: pypy/dist/pypy/translator/cli/test/runtest.py ============================================================================== --- pypy/dist/pypy/translator/cli/test/runtest.py (original) +++ pypy/dist/pypy/translator/cli/test/runtest.py Sat Feb 17 09:28:29 2007 @@ -251,9 +251,9 @@ if self._func is fn and self._ann == ann: return self._cli_func else: + self._cli_func = compile_function(fn, ann) self._func = fn self._ann = ann - self._cli_func = compile_function(fn, ann) return self._cli_func def _skip_win(self, reason): From pedronis at codespeak.net Sat Feb 17 09:33:06 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 17 Feb 2007 09:33:06 +0100 (CET) Subject: [pypy-svn] r39082 - pypy/release/0.99.x/pypy/translator/cli/test Message-ID: <20070217083306.7ADF11014A@code0.codespeak.net> Author: pedronis Date: Sat Feb 17 09:33:05 2007 New Revision: 39082 Modified: pypy/release/0.99.x/pypy/translator/cli/test/runtest.py Log: merging r39081 - fix skipping logic vs caching of previous compilation. Modified: pypy/release/0.99.x/pypy/translator/cli/test/runtest.py ============================================================================== --- pypy/release/0.99.x/pypy/translator/cli/test/runtest.py (original) +++ pypy/release/0.99.x/pypy/translator/cli/test/runtest.py Sat Feb 17 09:33:05 2007 @@ -251,9 +251,9 @@ if self._func is fn and self._ann == ann: return self._cli_func else: + self._cli_func = compile_function(fn, ann) self._func = fn self._ann = ann - self._cli_func = compile_function(fn, ann) return self._cli_func def _skip_win(self, reason): From pedronis at codespeak.net Sat Feb 17 10:26:03 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 17 Feb 2007 10:26:03 +0100 (CET) Subject: [pypy-svn] r39083 - pypy/release/0.99.x/pypy/module/readline/test Message-ID: <20070217092603.21FD210138@code0.codespeak.net> Author: pedronis Date: Sat Feb 17 10:26:01 2007 New Revision: 39083 Modified: pypy/release/0.99.x/pypy/module/readline/test/test_with_pypy.py Log: skip test in 0.99 Modified: pypy/release/0.99.x/pypy/module/readline/test/test_with_pypy.py ============================================================================== --- pypy/release/0.99.x/pypy/module/readline/test/test_with_pypy.py (original) +++ pypy/release/0.99.x/pypy/module/readline/test/test_with_pypy.py Sat Feb 17 10:26:01 2007 @@ -10,6 +10,8 @@ def setup_class(cls): # enable usage of the readline mixedmodule + import py + py.test.skip("no readline option in 0.99") space = gettestobjspace(usemodules=('readline',)) cls.space = space From pedronis at codespeak.net Sat Feb 17 10:32:27 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 17 Feb 2007 10:32:27 +0100 (CET) Subject: [pypy-svn] r39084 - in pypy/dist/pypy/translator/llvm: . module test Message-ID: <20070217093227.9556A10140@code0.codespeak.net> Author: pedronis Date: Sat Feb 17 10:32:26 2007 New Revision: 39084 Modified: pypy/dist/pypy/translator/llvm/buildllvm.py pypy/dist/pypy/translator/llvm/externs2ll.py pypy/dist/pypy/translator/llvm/gc.py pypy/dist/pypy/translator/llvm/genllvm.py pypy/dist/pypy/translator/llvm/module/support.py pypy/dist/pypy/translator/llvm/test/runtest.py Log: attempt at fixing skip logic. Modified: pypy/dist/pypy/translator/llvm/buildllvm.py ============================================================================== --- pypy/dist/pypy/translator/llvm/buildllvm.py (original) +++ pypy/dist/pypy/translator/llvm/buildllvm.py Sat Feb 17 10:32:26 2007 @@ -15,13 +15,23 @@ return False return True -def _exe_version(exe): - v = os.popen(exe + ' -version 2>&1').read() - v = ''.join([c for c in v if c.isdigit()]) - v = int(v) / 10.0 +def _exe_version(exe, cache={}): + try: + v = cache[exe] + except KeyError: + v = os.popen(exe + ' -version 2>&1').read() + v = ''.join([c for c in v if c.isdigit()]) + v = int(v) / 10.0 + cache[exe] = v return v -llvm_version = _exe_version('llvm-as') +llvm_version = lambda: _exe_version('llvm-as') + +def postfix(): + if llvm_version() >= 2.0: + return '.i32' + else: + return '' def _exe_version2(exe): v = os.popen(exe + ' --version 2>&1').read() @@ -31,8 +41,8 @@ v = float(major) + float(minor) / 10.0 return v -gcc_version = _exe_version2('gcc') -llvm_gcc_version = _exe_version2('llvm-gcc') +gcc_version = lambda: _exe_version2('gcc') +llvm_gcc_version = lambda: _exe_version2('llvm-gcc') def optimizations(simple, use_gcc): @@ -86,7 +96,7 @@ # run llvm assembler and optimizer simple_optimizations = not optimize opts = optimizations(simple_optimizations, use_gcc) - if llvm_version < 2.0: + if llvm_version() < 2.0: cmds = ["llvm-as < %s.ll | opt %s -f -o %s.bc" % (b, opts, b)] else: #we generate 1.x .ll files, so upgrade these first cmds = ["llvm-upgrade < %s.ll | llvm-as | opt %s -f -o %s.bc" % (b, opts, b)] Modified: pypy/dist/pypy/translator/llvm/externs2ll.py ============================================================================== --- pypy/dist/pypy/translator/llvm/externs2ll.py (original) +++ pypy/dist/pypy/translator/llvm/externs2ll.py Sat Feb 17 10:32:26 2007 @@ -11,8 +11,6 @@ from pypy.tool.udir import udir -_llvm_gcc_version = None - support_functions = [ "%raisePyExc_IOError", "%raisePyExc_ValueError", @@ -40,7 +38,7 @@ plain = filename[:-2] includes = get_incdirs() - if llvm_gcc_version < 4.0: + if llvm_gcc_version() < 4.0: emit_llvm = '' else: emit_llvm = '-emit-llvm -O3' Modified: pypy/dist/pypy/translator/llvm/gc.py ============================================================================== --- pypy/dist/pypy/translator/llvm/gc.py (original) +++ pypy/dist/pypy/translator/llvm/gc.py Sat Feb 17 10:32:26 2007 @@ -5,11 +5,7 @@ from pypy.translator.llvm.log import log log = log.gc -from pypy.translator.llvm.buildllvm import llvm_version -if llvm_version >= 2.0: - postfix = '.i32' -else: - postfix = '' +from pypy.translator.llvm.buildllvm import postfix def have_boehm(): import distutils.sysconfig @@ -157,7 +153,7 @@ # malloc_size is unsigned right now codewriter.malloc(targetvar, "sbyte", size) - codewriter.call(None, 'void', '%llvm.memset' + postfix, + codewriter.call(None, 'void', '%llvm.memset' + postfix(), ['sbyte*', 'ubyte', uword, uword], [targetvar, 0, size, boundary_size], cconv='ccc') @@ -210,7 +206,7 @@ codewriter.call(targetvar, 'sbyte*', fnname, [word], [sizei]) if atomic: - codewriter.call(None, 'void', '%llvm.memset' + postfix, + codewriter.call(None, 'void', '%llvm.memset' + postfix(), ['sbyte*', 'ubyte', uword, uword], [targetvar, 0, size, boundary_size], cconv='ccc') Modified: pypy/dist/pypy/translator/llvm/genllvm.py ============================================================================== --- pypy/dist/pypy/translator/llvm/genllvm.py (original) +++ pypy/dist/pypy/translator/llvm/genllvm.py Sat Feb 17 10:32:26 2007 @@ -18,7 +18,7 @@ from pypy.translator.llvm.gc import GcPolicy from pypy.translator.llvm.log import log from pypy import conftest -from pypy.translator.llvm.buildllvm import llvm_is_on_path +from pypy.translator.llvm.buildllvm import llvm_is_on_path, postfix class GenLLVM(object): # see create_codewriter() below @@ -119,6 +119,7 @@ def _set_wordsize(self, s): s = s.replace('UWORD', self.db.get_machine_uword()) s = s.replace( 'WORD', self.db.get_machine_word()) + s = s.replace('POSTFIX', postfix()) return s def write_headers(self, codewriter): 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 Sat Feb 17 10:32:26 2007 @@ -1,8 +1,3 @@ -from pypy.translator.llvm.buildllvm import llvm_version -if llvm_version >= 2.0: - postfix = '.i32' -else: - postfix = '' extdeclarations = """ %last_exception_type = internal global %RPYTHON_EXCEPTION_VTABLE* null @@ -12,7 +7,6 @@ declare ccc void %llvm.memsetPOSTFIX(sbyte*, ubyte, UWORD, UWORD) declare ccc void %llvm.memcpyPOSTFIX(sbyte*, sbyte*, UWORD, UWORD) """ -extdeclarations = extdeclarations.replace('POSTFIX', postfix) extfunctions = """ internal fastcc sbyte* %RPyString_AsString(%RPyString* %structstring) { @@ -84,7 +78,6 @@ } """ -extfunctions = extfunctions.replace('POSTFIX', postfix) from sys import maxint if maxint != 2**31-1: Modified: pypy/dist/pypy/translator/llvm/test/runtest.py ============================================================================== --- pypy/dist/pypy/translator/llvm/test/runtest.py (original) +++ pypy/dist/pypy/translator/llvm/test/runtest.py Sat Feb 17 10:32:26 2007 @@ -32,15 +32,17 @@ if not llvm_is_on_path(): py.test.skip("could not find one of llvm-as or llvm-gcc") return False - if llvm_version < MINIMUM_LLVM_VERSION: + llvm_ver = llvm_version() + if llvm_ver < MINIMUM_LLVM_VERSION: py.test.skip("llvm version not up-to-date (found " - "%.1f, should be >= %.1f)" % (llvm_version, MINIMUM_LLVM_VERSION)) + "%.1f, should be >= %.1f)" % (llvm_ver, MINIMUM_LLVM_VERSION)) return False return True def gcc3_test(): - if int(gcc_version) != 3: - py.test.skip("test required gcc version 3 (found version %.1f)" % gcc_version) + gcc_ver = gcc_version() + if int(gcc_ver) != 3: + py.test.skip("test required gcc version 3 (found version %.1f)" % gcc_ver) return False return True From pedronis at codespeak.net Sat Feb 17 10:34:41 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 17 Feb 2007 10:34:41 +0100 (CET) Subject: [pypy-svn] r39085 - in pypy/release/0.99.x/pypy/translator/llvm: . module test Message-ID: <20070217093441.738EA10144@code0.codespeak.net> Author: pedronis Date: Sat Feb 17 10:34:40 2007 New Revision: 39085 Modified: pypy/release/0.99.x/pypy/translator/llvm/buildllvm.py pypy/release/0.99.x/pypy/translator/llvm/externs2ll.py pypy/release/0.99.x/pypy/translator/llvm/gc.py pypy/release/0.99.x/pypy/translator/llvm/genllvm.py pypy/release/0.99.x/pypy/translator/llvm/module/support.py pypy/release/0.99.x/pypy/translator/llvm/test/runtest.py Log: merge r39084, fix for skip logic Modified: pypy/release/0.99.x/pypy/translator/llvm/buildllvm.py ============================================================================== --- pypy/release/0.99.x/pypy/translator/llvm/buildllvm.py (original) +++ pypy/release/0.99.x/pypy/translator/llvm/buildllvm.py Sat Feb 17 10:34:40 2007 @@ -15,13 +15,23 @@ return False return True -def _exe_version(exe): - v = os.popen(exe + ' -version 2>&1').read() - v = ''.join([c for c in v if c.isdigit()]) - v = int(v) / 10.0 +def _exe_version(exe, cache={}): + try: + v = cache[exe] + except KeyError: + v = os.popen(exe + ' -version 2>&1').read() + v = ''.join([c for c in v if c.isdigit()]) + v = int(v) / 10.0 + cache[exe] = v return v -llvm_version = _exe_version('llvm-as') +llvm_version = lambda: _exe_version('llvm-as') + +def postfix(): + if llvm_version() >= 2.0: + return '.i32' + else: + return '' def _exe_version2(exe): v = os.popen(exe + ' --version 2>&1').read() @@ -31,8 +41,8 @@ v = float(major) + float(minor) / 10.0 return v -gcc_version = _exe_version2('gcc') -llvm_gcc_version = _exe_version2('llvm-gcc') +gcc_version = lambda: _exe_version2('gcc') +llvm_gcc_version = lambda: _exe_version2('llvm-gcc') def optimizations(simple, use_gcc): @@ -86,7 +96,7 @@ # run llvm assembler and optimizer simple_optimizations = not optimize opts = optimizations(simple_optimizations, use_gcc) - if llvm_version < 2.0: + if llvm_version() < 2.0: cmds = ["llvm-as < %s.ll | opt %s -f -o %s.bc" % (b, opts, b)] else: #we generate 1.x .ll files, so upgrade these first cmds = ["llvm-upgrade < %s.ll | llvm-as | opt %s -f -o %s.bc" % (b, opts, b)] Modified: pypy/release/0.99.x/pypy/translator/llvm/externs2ll.py ============================================================================== --- pypy/release/0.99.x/pypy/translator/llvm/externs2ll.py (original) +++ pypy/release/0.99.x/pypy/translator/llvm/externs2ll.py Sat Feb 17 10:34:40 2007 @@ -11,8 +11,6 @@ from pypy.tool.udir import udir -_llvm_gcc_version = None - support_functions = [ "%raisePyExc_IOError", "%raisePyExc_ValueError", @@ -40,7 +38,7 @@ plain = filename[:-2] includes = get_incdirs() - if llvm_gcc_version < 4.0: + if llvm_gcc_version() < 4.0: emit_llvm = '' else: emit_llvm = '-emit-llvm -O3' Modified: pypy/release/0.99.x/pypy/translator/llvm/gc.py ============================================================================== --- pypy/release/0.99.x/pypy/translator/llvm/gc.py (original) +++ pypy/release/0.99.x/pypy/translator/llvm/gc.py Sat Feb 17 10:34:40 2007 @@ -5,11 +5,7 @@ from pypy.translator.llvm.log import log log = log.gc -from pypy.translator.llvm.buildllvm import llvm_version -if llvm_version >= 2.0: - postfix = '.i32' -else: - postfix = '' +from pypy.translator.llvm.buildllvm import postfix def have_boehm(): import distutils.sysconfig @@ -157,7 +153,7 @@ # malloc_size is unsigned right now codewriter.malloc(targetvar, "sbyte", size) - codewriter.call(None, 'void', '%llvm.memset' + postfix, + codewriter.call(None, 'void', '%llvm.memset' + postfix(), ['sbyte*', 'ubyte', uword, uword], [targetvar, 0, size, boundary_size], cconv='ccc') @@ -210,7 +206,7 @@ codewriter.call(targetvar, 'sbyte*', fnname, [word], [sizei]) if atomic: - codewriter.call(None, 'void', '%llvm.memset' + postfix, + codewriter.call(None, 'void', '%llvm.memset' + postfix(), ['sbyte*', 'ubyte', uword, uword], [targetvar, 0, size, boundary_size], cconv='ccc') Modified: pypy/release/0.99.x/pypy/translator/llvm/genllvm.py ============================================================================== --- pypy/release/0.99.x/pypy/translator/llvm/genllvm.py (original) +++ pypy/release/0.99.x/pypy/translator/llvm/genllvm.py Sat Feb 17 10:34:40 2007 @@ -18,7 +18,7 @@ from pypy.translator.llvm.gc import GcPolicy from pypy.translator.llvm.log import log from pypy import conftest -from pypy.translator.llvm.buildllvm import llvm_is_on_path +from pypy.translator.llvm.buildllvm import llvm_is_on_path, postfix class GenLLVM(object): # see create_codewriter() below @@ -119,6 +119,7 @@ def _set_wordsize(self, s): s = s.replace('UWORD', self.db.get_machine_uword()) s = s.replace( 'WORD', self.db.get_machine_word()) + s = s.replace('POSTFIX', postfix()) return s def write_headers(self, codewriter): Modified: pypy/release/0.99.x/pypy/translator/llvm/module/support.py ============================================================================== --- pypy/release/0.99.x/pypy/translator/llvm/module/support.py (original) +++ pypy/release/0.99.x/pypy/translator/llvm/module/support.py Sat Feb 17 10:34:40 2007 @@ -1,8 +1,3 @@ -from pypy.translator.llvm.buildllvm import llvm_version -if llvm_version >= 2.0: - postfix = '.i32' -else: - postfix = '' extdeclarations = """ %last_exception_type = internal global %RPYTHON_EXCEPTION_VTABLE* null @@ -12,7 +7,6 @@ declare ccc void %llvm.memsetPOSTFIX(sbyte*, ubyte, UWORD, UWORD) declare ccc void %llvm.memcpyPOSTFIX(sbyte*, sbyte*, UWORD, UWORD) """ -extdeclarations = extdeclarations.replace('POSTFIX', postfix) extfunctions = """ internal fastcc sbyte* %RPyString_AsString(%RPyString* %structstring) { @@ -84,7 +78,6 @@ } """ -extfunctions = extfunctions.replace('POSTFIX', postfix) from sys import maxint if maxint != 2**31-1: Modified: pypy/release/0.99.x/pypy/translator/llvm/test/runtest.py ============================================================================== --- pypy/release/0.99.x/pypy/translator/llvm/test/runtest.py (original) +++ pypy/release/0.99.x/pypy/translator/llvm/test/runtest.py Sat Feb 17 10:34:40 2007 @@ -32,15 +32,17 @@ if not llvm_is_on_path(): py.test.skip("could not find one of llvm-as or llvm-gcc") return False - if llvm_version < MINIMUM_LLVM_VERSION: + llvm_ver = llvm_version() + if llvm_ver < MINIMUM_LLVM_VERSION: py.test.skip("llvm version not up-to-date (found " - "%.1f, should be >= %.1f)" % (llvm_version, MINIMUM_LLVM_VERSION)) + "%.1f, should be >= %.1f)" % (llvm_ver, MINIMUM_LLVM_VERSION)) return False return True def gcc3_test(): - if int(gcc_version) != 3: - py.test.skip("test required gcc version 3 (found version %.1f)" % gcc_version) + gcc_ver = gcc_version() + if int(gcc_ver) != 3: + py.test.skip("test required gcc version 3 (found version %.1f)" % gcc_ver) return False return True From cfbolz at codespeak.net Sat Feb 17 10:49:20 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sat, 17 Feb 2007 10:49:20 +0100 (CET) Subject: [pypy-svn] r39086 - pypy/release/0.99.x/pypy/jit Message-ID: <20070217094920.832541014C@code0.codespeak.net> Author: cfbolz Date: Sat Feb 17 10:49:18 2007 New Revision: 39086 Added: pypy/release/0.99.x/pypy/jit/README Log: short note saying that the jit is not included. Added: pypy/release/0.99.x/pypy/jit/README ============================================================================== --- (empty file) +++ pypy/release/0.99.x/pypy/jit/README Sat Feb 17 10:49:18 2007 @@ -0,0 +1,2 @@ +The jit is not included in the 0.99 release since it is not ready. See the +release announcement (doc/release-0.99.0-txt) for details. From fijal at codespeak.net Sat Feb 17 11:06:58 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 17 Feb 2007 11:06:58 +0100 (CET) Subject: [pypy-svn] r39087 - pypy/release/0.99.x/pypy/doc Message-ID: <20070217100658.E5F2E1014E@code0.codespeak.net> Author: fijal Date: Sat Feb 17 11:06:55 2007 New Revision: 39087 Modified: pypy/release/0.99.x/pypy/doc/release-0.99.0.txt Log: Add play1 pointer Modified: pypy/release/0.99.x/pypy/doc/release-0.99.0.txt ============================================================================== --- pypy/release/0.99.x/pypy/doc/release-0.99.0.txt (original) +++ pypy/release/0.99.x/pypy/doc/release-0.99.0.txt Sat Feb 17 11:06:55 2007 @@ -90,7 +90,7 @@ - the JavaScript backend has evolved to a point where it can be used to write AJAX web applications with it. This is still an experimental technique, though. For demo applications see: - XXX play1 pointer? + http://play1.codespeak.net:8008/ * new configuration system: There is a new comprehensive configuration system that allows From pedronis at codespeak.net Sat Feb 17 11:12:54 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 17 Feb 2007 11:12:54 +0100 (CET) Subject: [pypy-svn] r39088 - pypy/release/0.99.x/pypy/doc Message-ID: <20070217101254.D663A100A2@code0.codespeak.net> Author: pedronis Date: Sat Feb 17 11:12:52 2007 New Revision: 39088 Removed: pypy/release/0.99.x/pypy/doc/jit.txt Log: substitute this. From pedronis at codespeak.net Sat Feb 17 11:16:26 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 17 Feb 2007 11:16:26 +0100 (CET) Subject: [pypy-svn] r39089 - pypy/release/0.99.x/pypy/doc Message-ID: <20070217101626.381FD1012C@code0.codespeak.net> Author: pedronis Date: Sat Feb 17 11:16:24 2007 New Revision: 39089 Added: pypy/release/0.99.x/pypy/doc/jit.txt - copied, changed from r39087, pypy/release/0.99.x/pypy/jit/README Log: minimal stub for now. until we know where to point for the original version. From pedronis at codespeak.net Sat Feb 17 11:28:33 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 17 Feb 2007 11:28:33 +0100 (CET) Subject: [pypy-svn] r39090 - pypy/dist/pypy/doc Message-ID: <20070217102833.50A9D10141@code0.codespeak.net> Author: pedronis Date: Sat Feb 17 11:28:31 2007 New Revision: 39090 Modified: pypy/dist/pypy/doc/confrest.py Log: oops this should not be here Modified: pypy/dist/pypy/doc/confrest.py ============================================================================== --- pypy/dist/pypy/doc/confrest.py (original) +++ pypy/dist/pypy/doc/confrest.py Sat Feb 17 11:28:31 2007 @@ -1,7 +1,6 @@ import py from py.__.doc.confrest import * -#import docage class PyPyPage(Page): From pedronis at codespeak.net Sat Feb 17 11:30:42 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 17 Feb 2007 11:30:42 +0100 (CET) Subject: [pypy-svn] r39091 - pypy/dist/pypy/doc Message-ID: <20070217103042.1A7EA1014E@code0.codespeak.net> Author: pedronis Date: Sat Feb 17 11:30:39 2007 New Revision: 39091 Modified: pypy/dist/pypy/doc/confrest.py Log: kill the blank lines too Modified: pypy/dist/pypy/doc/confrest.py ============================================================================== --- pypy/dist/pypy/doc/confrest.py (original) +++ pypy/dist/pypy/doc/confrest.py Sat Feb 17 11:30:39 2007 @@ -1,8 +1,6 @@ import py from py.__.doc.confrest import * - - class PyPyPage(Page): def fill_menubar(self): self.menubar = html.div( From pedronis at codespeak.net Sat Feb 17 11:33:38 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 17 Feb 2007 11:33:38 +0100 (CET) Subject: [pypy-svn] r39092 - pypy/release/0.99.x/pypy/doc Message-ID: <20070217103338.1708210151@code0.codespeak.net> Author: pedronis Date: Sat Feb 17 11:33:31 2007 New Revision: 39092 Removed: pypy/release/0.99.x/pypy/doc/how-to-release.txt Log: replace from dist From pedronis at codespeak.net Sat Feb 17 11:34:37 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 17 Feb 2007 11:34:37 +0100 (CET) Subject: [pypy-svn] r39093 - pypy/release/0.99.x/pypy/doc Message-ID: <20070217103437.509A310153@code0.codespeak.net> Author: pedronis Date: Sat Feb 17 11:34:34 2007 New Revision: 39093 Added: pypy/release/0.99.x/pypy/doc/how-to-release.txt - copied unchanged from r39092, pypy/dist/pypy/doc/how-to-release.txt Log: from dist. From pedronis at codespeak.net Sat Feb 17 11:37:09 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 17 Feb 2007 11:37:09 +0100 (CET) Subject: [pypy-svn] r39094 - pypy/release/0.99.x/pypy/jit Message-ID: <20070217103709.5FD4910155@code0.codespeak.net> Author: pedronis Date: Sat Feb 17 11:37:04 2007 New Revision: 39094 Modified: pypy/release/0.99.x/pypy/jit/README Log: slight change Modified: pypy/release/0.99.x/pypy/jit/README ============================================================================== --- pypy/release/0.99.x/pypy/jit/README (original) +++ pypy/release/0.99.x/pypy/jit/README Sat Feb 17 11:37:04 2007 @@ -1,2 +1,2 @@ -The jit is not included in the 0.99 release since it is not ready. See the +The JIT is not included in the 0.99 release. See the release announcement (doc/release-0.99.0-txt) for details. From pedronis at codespeak.net Sat Feb 17 11:37:25 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 17 Feb 2007 11:37:25 +0100 (CET) Subject: [pypy-svn] r39095 - pypy/release/0.99.x/pypy/doc Message-ID: <20070217103725.234CD10159@code0.codespeak.net> Author: pedronis Date: Sat Feb 17 11:37:22 2007 New Revision: 39095 Modified: pypy/release/0.99.x/pypy/doc/release-0.99.0.txt Log: fixing the spelling before I forget Modified: pypy/release/0.99.x/pypy/doc/release-0.99.0.txt ============================================================================== --- pypy/release/0.99.x/pypy/doc/release-0.99.0.txt (original) +++ pypy/release/0.99.x/pypy/doc/release-0.99.0.txt Sat Feb 17 11:37:22 2007 @@ -166,7 +166,7 @@ European Union IST research grant. The full partners of that consortium are: - Heinrich-Heine University (Germany), Openend (Sweden) + Heinrich-Heine University (Germany), Open End (Sweden) merlinux GmbH (Germany), tismerysoft GmbH (Germany) Logilab Paris (France), DFKI GmbH (Germany) ChangeMaker (Sweden), Impara (Germany) From pedronis at codespeak.net Sat Feb 17 11:38:02 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 17 Feb 2007 11:38:02 +0100 (CET) Subject: [pypy-svn] r39096 - pypy/release/0.99.x/pypy/tool Message-ID: <20070217103802.B307610157@code0.codespeak.net> Author: pedronis Date: Sat Feb 17 11:38:00 2007 New Revision: 39096 Modified: pypy/release/0.99.x/pypy/tool/makerelease.py Log: tagging support Modified: pypy/release/0.99.x/pypy/tool/makerelease.py ============================================================================== --- pypy/release/0.99.x/pypy/tool/makerelease.py (original) +++ pypy/release/0.99.x/pypy/tool/makerelease.py Sat Feb 17 11:38:00 2007 @@ -11,7 +11,7 @@ DDIR = py.path.local('/www/codespeak.net/htdocs/download/pypy') def usage(): - print "usage: %s versionbasename" %(py.std.sys.argv[0]) + print "usage: %s [-tag .] versionbasename" %(py.std.sys.argv[0]) raise SystemExit, 1 def cexec(cmd): @@ -92,7 +92,17 @@ argc = len(py.std.sys.argv) if argc <= 1: usage() - ver = py.std.sys.argv[1] + + j = 1 + if py.std.sys.argv[1] == '-tag': + micro = py.std.sys.argv[2] + assert micro.startswith('.') + NEWURL = BASEURL.replace('.x', micro) + cexec('svn cp %s %s' % (BASEURL, NEWURL)) + BASEURL = NEWURL + j = 3 + + ver = py.std.sys.argv[j] tmpdir = py.path.local("/tmp/pypy-release") target = tmpdir.join(ver) From pedronis at codespeak.net Sat Feb 17 11:49:54 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 17 Feb 2007 11:49:54 +0100 (CET) Subject: [pypy-svn] r39097 - pypy/release/0.99.x/pypy/doc Message-ID: <20070217104954.919841015A@code0.codespeak.net> Author: pedronis Date: Sat Feb 17 11:49:53 2007 New Revision: 39097 Modified: pypy/release/0.99.x/pypy/doc/index.txt Log: remove dangling refs Modified: pypy/release/0.99.x/pypy/doc/index.txt ============================================================================== --- pypy/release/0.99.x/pypy/doc/index.txt (original) +++ pypy/release/0.99.x/pypy/doc/index.txt Sat Feb 17 11:49:53 2007 @@ -317,9 +317,6 @@ .. _JIT: jit.html .. _`JIT Generation in PyPy`: jit.html .. _`just-in-time compiler generator`: jit.html -.. _`jit backends`: jit.html#backends -.. _`hint-annotator`: jit.html#hint-annotator -.. _`timeshifter`: jit.html#timeshifter .. _rtyper: rtyper.html .. _`low-level type system`: rtyper.html#low-level-type .. _`object-oriented type system`: rtyper.html#oo-type From pedronis at codespeak.net Sat Feb 17 12:01:52 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 17 Feb 2007 12:01:52 +0100 (CET) Subject: [pypy-svn] r39098 - pypy/release/0.99.x/pypy/tool Message-ID: <20070217110152.DC39610160@code0.codespeak.net> Author: pedronis Date: Sat Feb 17 12:01:50 2007 New Revision: 39098 Modified: pypy/release/0.99.x/pypy/tool/makerelease.py Log: sanity check. this has bitten me a bunch times. Modified: pypy/release/0.99.x/pypy/tool/makerelease.py ============================================================================== --- pypy/release/0.99.x/pypy/tool/makerelease.py (original) +++ pypy/release/0.99.x/pypy/tool/makerelease.py Sat Feb 17 12:01:50 2007 @@ -103,6 +103,7 @@ j = 3 ver = py.std.sys.argv[j] + assert ver.startswith('pypy-') tmpdir = py.path.local("/tmp/pypy-release") target = tmpdir.join(ver) From cfbolz at codespeak.net Sat Feb 17 13:19:04 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sat, 17 Feb 2007 13:19:04 +0100 (CET) Subject: [pypy-svn] r39099 - pypy/release/0.99.x/pypy/doc Message-ID: <20070217121904.5014E1015A@code0.codespeak.net> Author: cfbolz Date: Sat Feb 17 13:19:02 2007 New Revision: 39099 Modified: pypy/release/0.99.x/pypy/doc/_ref.txt pypy/release/0.99.x/pypy/doc/index.txt Log: make the link to doc/config work locally Modified: pypy/release/0.99.x/pypy/doc/_ref.txt ============================================================================== --- pypy/release/0.99.x/pypy/doc/_ref.txt (original) +++ pypy/release/0.99.x/pypy/doc/_ref.txt Sat Feb 17 13:19:02 2007 @@ -11,7 +11,6 @@ .. _`bin/`: ../../pypy/bin .. _`config/`: ../../pypy/config .. _`doc/`: ../../pypy/doc -.. _`doc/config/`: ../../pypy/doc/config .. _`doc/discussion/`: ../../pypy/doc/discussion .. _`interpreter/`: .. _`pypy/interpreter`: ../../pypy/interpreter @@ -112,4 +111,4 @@ .. _`translator/llvm/`: ../../pypy/translator/llvm .. _`translator/squeak/`: ../../pypy/translator/squeak .. _`translator/stackless/`: ../../pypy/translator/stackless -.. _`translator/tool/`: ../../pypy/translator/tool \ No newline at end of file +.. _`translator/tool/`: ../../pypy/translator/tool Modified: pypy/release/0.99.x/pypy/doc/index.txt ============================================================================== --- pypy/release/0.99.x/pypy/doc/index.txt (original) +++ pypy/release/0.99.x/pypy/doc/index.txt Sat Feb 17 13:19:02 2007 @@ -330,3 +330,4 @@ .. include:: _ref.txt +.. _`doc/config/`: config/index.html From cfbolz at codespeak.net Sat Feb 17 13:21:19 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sat, 17 Feb 2007 13:21:19 +0100 (CET) Subject: [pypy-svn] r39100 - pypy/release/0.99.x/pypy/doc Message-ID: <20070217122119.9EF081015B@code0.codespeak.net> Author: cfbolz Date: Sat Feb 17 13:21:18 2007 New Revision: 39100 Modified: pypy/release/0.99.x/pypy/doc/getting-started.txt Log: fix link to py-lib installation page Modified: pypy/release/0.99.x/pypy/doc/getting-started.txt ============================================================================== --- pypy/release/0.99.x/pypy/doc/getting-started.txt (original) +++ pypy/release/0.99.x/pypy/doc/getting-started.txt Sat Feb 17 13:21:18 2007 @@ -782,9 +782,7 @@ but if you want to have the ``py.test`` tool generally in your path, you might like to visit: - http://codespeak.net/py/current/doc/getting-started.html - - + http://codespeak.net/py/dist/download.html Getting involved ================================== From cfbolz at codespeak.net Sat Feb 17 13:49:34 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sat, 17 Feb 2007 13:49:34 +0100 (CET) Subject: [pypy-svn] r39101 - pypy/dist/pypy/doc Message-ID: <20070217124934.3173310161@code0.codespeak.net> Author: cfbolz Date: Sat Feb 17 13:49:31 2007 New Revision: 39101 Modified: pypy/dist/pypy/doc/cli-backend.txt pypy/dist/pypy/doc/contact.txt pypy/dist/pypy/doc/dev_method.txt pypy/dist/pypy/doc/eventhistory.txt pypy/dist/pypy/doc/extradoc.txt pypy/dist/pypy/doc/geninterp.txt pypy/dist/pypy/doc/getting-started.txt pypy/dist/pypy/doc/news.txt pypy/dist/pypy/doc/translation.txt pypy/dist/pypy/doc/windows.txt Log: replace links to codespeak by local links as much as possible Modified: pypy/dist/pypy/doc/cli-backend.txt ============================================================================== --- pypy/dist/pypy/doc/cli-backend.txt (original) +++ pypy/dist/pypy/doc/cli-backend.txt Sat Feb 17 13:49:31 2007 @@ -427,5 +427,5 @@ .. _`Standard Ecma 335`: http://www.ecma-international.org/publications/standards/Ecma-335.htm -.. _`flow graph`: http://codespeak.net/pypy/dist/pypy/doc/translation.html#the-flow-model -.. _`rtyper`: http://codespeak.net/pypy/dist/pypy/doc/rtyper.html +.. _`flow graph`: translation.html#the-flow-model +.. _`rtyper`: rtyper.html Modified: pypy/dist/pypy/doc/contact.txt ============================================================================== --- pypy/dist/pypy/doc/contact.txt (original) +++ pypy/dist/pypy/doc/contact.txt Sat Feb 17 13:49:31 2007 @@ -39,7 +39,7 @@ conferences all year round. They will be happy to meet in person with anyone interested in the project. Here is the list of planned events_. -.. _events: http://codespeak.net/pypy/dist/pypy/doc/events.html +.. _events: http://codespeak.net/pypy/dist/pypy/doc/news.html PyPy calendar ============= Modified: pypy/dist/pypy/doc/dev_method.txt ============================================================================== --- pypy/dist/pypy/doc/dev_method.txt (original) +++ pypy/dist/pypy/doc/dev_method.txt Sat Feb 17 13:49:31 2007 @@ -224,7 +224,7 @@ some middle ground - thus increases the importance of feedback. -.. _documentation: http://codespeak.net/pypy/dist/pypy/doc/getting-started.html +.. _documentation: getting-started.html Can I join in? ++++++++++++++ Modified: pypy/dist/pypy/doc/eventhistory.txt ============================================================================== --- pypy/dist/pypy/doc/eventhistory.txt (original) +++ pypy/dist/pypy/doc/eventhistory.txt Sat Feb 17 13:49:31 2007 @@ -140,7 +140,7 @@ all these documents are not approved by the European Union and therefore only preliminary. *(01/06/2006)* -.. _`reports for the EU`: http://codespeak.net/pypy/dist/pypy/doc/index-report.html +.. _`reports for the EU`: index-report.html PyPy Sprint in G?teborg 7th - 11th December 2005 @@ -168,7 +168,7 @@ the `getting started`_ document for instructions about downloading it and trying it out. There is also a short FAQ_. *(11/03/2005)* -.. _`release 0.8 announcement`: http://codespeak.net/pypy/dist/pypy/doc/release-0.8.0.html +.. _`release 0.8 announcement`: release-0.8.0.html PyPy Sprint in Paris 10th-16th October 2005 ======================================================== @@ -203,9 +203,9 @@ trying it out. We also have the beginning of a FAQ_. *(08/28/2005)* .. _`pypy-0.7.0`: -.. _`release announcement`: http://codespeak.net/pypy/dist/pypy/doc/release-0.7.0.html -.. _`getting started`: http://codespeak.net/pypy/dist/pypy/doc/getting-started.html -.. _FAQ: http://codespeak.net/pypy/dist/pypy/doc/faq.html +.. _`release announcement`: release-0.7.0.html +.. _`getting started`: getting-started.html +.. _FAQ: faq.html PyPy Sprint in Heidelberg 22nd-29th August 2005 ========================================================== @@ -268,7 +268,7 @@ .. _`pypy-dev`: http://codespeak.net/mailman/listinfo/pypy-dev .. _EuroPython: http://europython.org -.. _`translation`: http://codespeak.net/pypy/dist/pypy/doc/translation.html +.. _`translation`: translation.html .. _`sprint announcement`: http://codespeak.net/pypy/extradoc/sprintinfo/EP2005-announcement.html .. _`list of people coming`: http://codespeak.net/pypy/extradoc/sprintinfo/EP2005-people.html Modified: pypy/dist/pypy/doc/extradoc.txt ============================================================================== --- pypy/dist/pypy/doc/extradoc.txt (original) +++ pypy/dist/pypy/doc/extradoc.txt Sat Feb 17 13:49:31 2007 @@ -144,7 +144,7 @@ .. _`Croquet`: http://www.opencroquet.org/ .. _`transparent dynamic optimization`: http://www.hpl.hp.com/techreports/1999/HPL-1999-77.pdf .. _Dynamo: http://www.hpl.hp.com/techreports/1999/HPL-1999-78.pdf -.. _testdesign: http://codespeak.net/pypy/dist/pypy/doc/coding-guide.html#test-design +.. _testdesign: coding-guide.html#test-design .. _feasible: http://codespeak.net/pipermail/pypy-dev/2004q2/001289.html .. _rock: http://codespeak.net/pipermail/pypy-dev/2004q1/001255.html .. _`GNU lightning`: http://www.gnu.org/software/lightning/lightning.html Modified: pypy/dist/pypy/doc/geninterp.txt ============================================================================== --- pypy/dist/pypy/doc/geninterp.txt (original) +++ pypy/dist/pypy/doc/geninterp.txt Sat Feb 17 13:49:31 2007 @@ -18,8 +18,8 @@ any longer to execute this code. .. _`application-level`: coding-guide.html#app-preferable -.. _exceptions: http://codespeak.net/pypy/dist/pypy/lib/_exceptions.py -.. _oldstyle: http://codespeak.net/pypy/dist/pypy/lib/_classobj.py +.. _exceptions: ../../pypy/lib/_exceptions.py +.. _oldstyle: ../../pypy/lib/_classobj.py Examples are exceptions_ and oldstyle_ classes. They are needed in a very early phase of bootstrapping StdObjspace, but @@ -48,7 +48,7 @@ Example +++++++ -.. _implementation: http://codespeak.net/pypy/dist/pypy/translator/geninterplevel.py +.. _implementation: ../../pypy/translator/geninterplevel.py Let's try a little example. You might want to look at the flowgraph that it produces. Here, we directly run the Python translation and look at the @@ -177,8 +177,8 @@ Interplevel Snippets in the Sources +++++++++++++++++++++++++++++++++++ -.. _`_exceptions.py`: http://codespeak.net/pypy/dist/pypy/lib/_exceptions.py -.. _`_classobj.py`: http://codespeak.net/pypy/dist/pypy/lib/_classobj.py +.. _`_exceptions.py`: ../../pypy/lib/_exceptions.py +.. _`_classobj.py`: ../../pypy/lib/_classobj.py Code written in application space can consist of complete files to be translated (`_exceptions.py`_, `_classobj.py`_), or they Modified: pypy/dist/pypy/doc/getting-started.txt ============================================================================== --- pypy/dist/pypy/doc/getting-started.txt (original) +++ pypy/dist/pypy/doc/getting-started.txt Sat Feb 17 13:49:31 2007 @@ -20,7 +20,7 @@ translation aspect - should become robust against language changes. `more...`_ .. _Python: http://docs.python.org/ref -.. _`more...`: http://codespeak.net/pypy/dist/pypy/doc/architecture.html +.. _`more...`: architecture.html Just the facts ============== @@ -792,7 +792,7 @@ as EuroPython or Pycon. Take a look at the list of upcoming events_ to plan where to meet with us. -.. _events: http://codespeak.net/pypy/dist/pypy/doc/events.html +.. _events: news.html .. _`pypy-dev mailing list`: http://codespeak.net/mailman/listinfo/pypy-dev .. _`contact possibilities`: contact.html @@ -822,11 +822,11 @@ .. _mixedmodule.py: http://codespeak.net/svn/pypy/dist/pypy/interpreter/mixedmodule.py .. _typedef.py: http://codespeak.net/svn/pypy/dist/pypy/interpreter/typedef.py .. _Standard object space: objspace.html#the-standard-object-space -.. _objspace.py: http://codespeak.net/pypy/dist/pypy/objspace/std/objspace.py -.. _thunk: http://codespeak.net/pypy/dist/pypy/objspace/thunk.py -.. _trace: http://codespeak.net/pypy/dist/pypy/objspace/trace.py -.. _flow: http://codespeak.net/pypy/dist/pypy/objspace/flow/ -.. _translator.py: http://codespeak.net/pypy/dist/pypy/translator/translator.py +.. _objspace.py: ../../pypy/objspace/std/objspace.py +.. _thunk: ../../pypy/objspace/thunk.py +.. _trace: ../../pypy/objspace/trace.py +.. _flow: ../../pypy/objspace/flow/ +.. _translator.py: ../../pypy/translator/translator.py .. _mailing lists: contact.html .. _documentation: index.html .. _unit tests: coding-guide.html#test-design Modified: pypy/dist/pypy/doc/news.txt ============================================================================== --- pypy/dist/pypy/doc/news.txt (original) +++ pypy/dist/pypy/doc/news.txt Sat Feb 17 13:49:31 2007 @@ -5,7 +5,7 @@ nonsense, isn't it? `more...`_ .. _Python: http://www.python.org/doc/current/ref/ref.html -.. _`more...`: http://codespeak.net/pypy/dist/pypy/doc/architecture.html#mission-statement +.. _`more...`: architecture.html#mission-statement The following is a list of planned PyPy events, most of which Modified: pypy/dist/pypy/doc/translation.txt ============================================================================== --- pypy/dist/pypy/doc/translation.txt (original) +++ pypy/dist/pypy/doc/translation.txt Sat Feb 17 13:49:31 2007 @@ -91,18 +91,18 @@ stages. .. _`SSA`: http://en.wikipedia.org/wiki/Static_single_assignment_form -.. _`translator.py`: http://codespeak.net/pypy/dist/pypy/translator/translator.py +.. _`translator.py`: ../../pypy/translator/translator.py .. _`play around`: getting-started.html#trying-out-the-translator .. _`Flow Object Space`: objspace.html#the-flow-object-space .. _`control flow graph`: objspace.html#the-flow-model -.. _`Common Lisp`: http://codespeak.net/pypy/dist/pypy/translator/lisp/ -.. _Pyrex: http://codespeak.net/pypy/dist/pypy/translator/pyrex/ -.. _JavaScript: http://codespeak.net/pypy/dist/pypy/translator/js/ -.. _Squeak: http://codespeak.net/pypy/dist/pypy/translator/squeak/ -.. _CLI: http://codespeak.net/pypy/dist/pypy/translator/cli/ +.. _`Common Lisp`: ../../pypy/translator/lisp/ +.. _Pyrex: ../../pypy/translator/pyrex/ +.. _JavaScript: ../../pypy/translator/js/ +.. _Squeak: ../../pypy/translator/squeak/ +.. _CLI: ../../pypy/translator/cli/ .. _graph: image/translation.pdf .. _`interactive interface`: getting-started.html#try-out-the-translator -.. _`translatorshell.py`: http://codespeak.net/pypy/dist/pypy/bin/translatorshell.py +.. _`translatorshell.py`: ../../pypy/bin/translatorshell.py .. _`flow model`: Modified: pypy/dist/pypy/doc/windows.txt ============================================================================== --- pypy/dist/pypy/doc/windows.txt (original) +++ pypy/dist/pypy/doc/windows.txt Sat Feb 17 13:49:31 2007 @@ -112,6 +112,6 @@ .. _`Boehm collector suite`: http://www.hpl.hp.com/personal/Hans_Boehm/gc/gc_source/gc.tar.gz -.. _gc_patch_windows.py: http://codespeak.net/pypy/dist/pypy/translator/goal/win32/gc_patch_windows.py +.. _gc_patch_windows.py: ../../pypy/translator/goal/win32/gc_patch_windows.py .. _`gc-windows.zip`: http://codespeak.net/~antocuni/gc-windows.zip From pedronis at codespeak.net Sat Feb 17 14:33:44 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 17 Feb 2007 14:33:44 +0100 (CET) Subject: [pypy-svn] r39102 - pypy/release/0.99.x/pypy/doc Message-ID: <20070217133344.B727510164@code0.codespeak.net> Author: pedronis Date: Sat Feb 17 14:33:43 2007 New Revision: 39102 Modified: pypy/release/0.99.x/pypy/doc/_ref.txt pypy/release/0.99.x/pypy/doc/getting-started.txt pypy/release/0.99.x/pypy/doc/index.txt Log: fix 39099 confusion Modified: pypy/release/0.99.x/pypy/doc/_ref.txt ============================================================================== --- pypy/release/0.99.x/pypy/doc/_ref.txt (original) +++ pypy/release/0.99.x/pypy/doc/_ref.txt Sat Feb 17 14:33:43 2007 @@ -11,6 +11,7 @@ .. _`bin/`: ../../pypy/bin .. _`config/`: ../../pypy/config .. _`doc/`: ../../pypy/doc +.. _`doc/config/`: ../../pypy/doc/config .. _`doc/discussion/`: ../../pypy/doc/discussion .. _`interpreter/`: .. _`pypy/interpreter`: ../../pypy/interpreter @@ -111,4 +112,4 @@ .. _`translator/llvm/`: ../../pypy/translator/llvm .. _`translator/squeak/`: ../../pypy/translator/squeak .. _`translator/stackless/`: ../../pypy/translator/stackless -.. _`translator/tool/`: ../../pypy/translator/tool +.. _`translator/tool/`: ../../pypy/translator/tool \ No newline at end of file Modified: pypy/release/0.99.x/pypy/doc/getting-started.txt ============================================================================== --- pypy/release/0.99.x/pypy/doc/getting-started.txt (original) +++ pypy/release/0.99.x/pypy/doc/getting-started.txt Sat Feb 17 14:33:43 2007 @@ -625,7 +625,7 @@ This will produce the executable "targetrpystonedalone-c". -.. _`configuration sections`: config/ +.. _`configuration sections`: config/index.html .. _`translate PyPy with the thunk object space`: Modified: pypy/release/0.99.x/pypy/doc/index.txt ============================================================================== --- pypy/release/0.99.x/pypy/doc/index.txt (original) +++ pypy/release/0.99.x/pypy/doc/index.txt Sat Feb 17 14:33:43 2007 @@ -330,4 +330,3 @@ .. include:: _ref.txt -.. _`doc/config/`: config/index.html From hpk at codespeak.net Sat Feb 17 14:38:24 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sat, 17 Feb 2007 14:38:24 +0100 (CET) Subject: [pypy-svn] r39103 - pypy/release/0.99.x/pypy/doc Message-ID: <20070217133824.C4A0210168@code0.codespeak.net> Author: hpk Date: Sat Feb 17 14:38:23 2007 New Revision: 39103 Modified: pypy/release/0.99.x/pypy/doc/getting-started.txt Log: just state translatability Modified: pypy/release/0.99.x/pypy/doc/getting-started.txt ============================================================================== --- pypy/release/0.99.x/pypy/doc/getting-started.txt (original) +++ pypy/release/0.99.x/pypy/doc/getting-started.txt Sat Feb 17 14:38:23 2007 @@ -287,8 +287,8 @@ It is interesting to note that this lazy-computing Python extension is solely implemented in a small `objspace/thunk.py`_ file consisting -of around 200 lines of code. Since the 0.8.0 release it is even possible -to `translate PyPy with the thunk object space`_. +of around 200 lines of code. Since the 0.8.0 release you +can `translate PyPy with the thunk object space`_. Logic programming +++++++++++++++++ From hpk at codespeak.net Sat Feb 17 14:49:18 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sat, 17 Feb 2007 14:49:18 +0100 (CET) Subject: [pypy-svn] r39104 - pypy/release/0.99.x/pypy/doc Message-ID: <20070217134918.8A0961016A@code0.codespeak.net> Author: hpk Date: Sat Feb 17 14:49:17 2007 New Revision: 39104 Modified: pypy/release/0.99.x/pypy/doc/getting-started.txt Log: i think it flows better to generally "cd pypy" instead of sometimes "cd pypy" and sometimes "cd pypy/bin" Modified: pypy/release/0.99.x/pypy/doc/getting-started.txt ============================================================================== --- pypy/release/0.99.x/pypy/doc/getting-started.txt (original) +++ pypy/release/0.99.x/pypy/doc/getting-started.txt Sat Feb 17 14:49:17 2007 @@ -155,8 +155,8 @@ To start interpreting Python with PyPy, use Python 2.3 or greater:: - cd pypy/bin - python py.py + cd pypy + python bin/py.py After a few seconds (remember: this is running on top of CPython), you should be at the PyPy prompt, which is the same as the Python @@ -180,8 +180,8 @@ To list the PyPy interpreter command line options, type:: - cd pypy/bin - python py.py --help + cd pypy + python bin/py.py --help py.py supports most of the options that CPython supports too (in addition to a large amount of options that can be used to customize py.py). @@ -258,8 +258,8 @@ object space, providing lazily-computed objects in a fully transparent manner:: - cd pypy/bin - python py.py -o thunk + cd pypy + python bin/py.py -o thunk >>>> from pypymagic import thunk >>>> def longcomputation(lst): @@ -301,8 +301,8 @@ Try it out:: - cd pypy/bin - python py.py -o logic + cd pypy + python bin/py.py -o logic >>>> X = newvar() # a logic variable >>>> bind(X, 42) # give it a value @@ -388,8 +388,8 @@ To start the interactive translator shell do:: - cd pypy/bin - python translatorshell.py + cd pypy + python bin/translatorshell.py Test snippets of translatable code are provided in the file ``pypy/translator/test/snippet.py``, which is imported under the name From hpk at codespeak.net Sat Feb 17 15:15:01 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sat, 17 Feb 2007 15:15:01 +0100 (CET) Subject: [pypy-svn] r39107 - pypy/release/0.99.x Message-ID: <20070217141501.F262E10169@code0.codespeak.net> Author: hpk Date: Sat Feb 17 15:15:00 2007 New Revision: 39107 Modified: pypy/release/0.99.x/README Log: slight refinements/updates to the README intro part Modified: pypy/release/0.99.x/README ============================================================================== --- pypy/release/0.99.x/README (original) +++ pypy/release/0.99.x/README Sat Feb 17 15:15:00 2007 @@ -2,14 +2,14 @@ PyPy: Python in Python implementation / Version 0.99.0 ======================================================= -PyPy is an implementation of the Python programming language, written -in Python. +Welcome to PyPy! -PyPy is very much a work in progress, but can already build a -self-contained Python implementation that is completely independent of -Python. +PyPy is both an implementation of the Python programming language, +and an extensive compiler framework for dynamic languages. +You can build self-contained Python implementations +which execute independently from CPython. -For more, we invite you to head over to our getting-started document: +We invite you to head over to our detailed getting-started document: pypy/doc/getting-started.html or pypy/doc/getting-started.txt From pedronis at codespeak.net Sat Feb 17 15:15:24 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 17 Feb 2007 15:15:24 +0100 (CET) Subject: [pypy-svn] r39108 - pypy/release/0.99.x/pypy/doc Message-ID: <20070217141524.01DBB10170@code0.codespeak.net> Author: pedronis Date: Sat Feb 17 15:15:22 2007 New Revision: 39108 Modified: pypy/release/0.99.x/pypy/doc/cli-backend.txt pypy/release/0.99.x/pypy/doc/contact.txt pypy/release/0.99.x/pypy/doc/dev_method.txt pypy/release/0.99.x/pypy/doc/eventhistory.txt pypy/release/0.99.x/pypy/doc/extradoc.txt pypy/release/0.99.x/pypy/doc/geninterp.txt pypy/release/0.99.x/pypy/doc/getting-started.txt pypy/release/0.99.x/pypy/doc/news.txt pypy/release/0.99.x/pypy/doc/release-0.99.0.txt pypy/release/0.99.x/pypy/doc/translation.txt pypy/release/0.99.x/pypy/doc/windows.txt Log: mergine 39101, plus fix in getting started Modified: pypy/release/0.99.x/pypy/doc/cli-backend.txt ============================================================================== --- pypy/release/0.99.x/pypy/doc/cli-backend.txt (original) +++ pypy/release/0.99.x/pypy/doc/cli-backend.txt Sat Feb 17 15:15:22 2007 @@ -427,5 +427,5 @@ .. _`Standard Ecma 335`: http://www.ecma-international.org/publications/standards/Ecma-335.htm -.. _`flow graph`: http://codespeak.net/pypy/dist/pypy/doc/translation.html#the-flow-model -.. _`rtyper`: http://codespeak.net/pypy/dist/pypy/doc/rtyper.html +.. _`flow graph`: translation.html#the-flow-model +.. _`rtyper`: rtyper.html Modified: pypy/release/0.99.x/pypy/doc/contact.txt ============================================================================== --- pypy/release/0.99.x/pypy/doc/contact.txt (original) +++ pypy/release/0.99.x/pypy/doc/contact.txt Sat Feb 17 15:15:22 2007 @@ -39,7 +39,7 @@ conferences all year round. They will be happy to meet in person with anyone interested in the project. Here is the list of planned events_. -.. _events: http://codespeak.net/pypy/dist/pypy/doc/events.html +.. _events: http://codespeak.net/pypy/dist/pypy/doc/news.html PyPy calendar ============= Modified: pypy/release/0.99.x/pypy/doc/dev_method.txt ============================================================================== --- pypy/release/0.99.x/pypy/doc/dev_method.txt (original) +++ pypy/release/0.99.x/pypy/doc/dev_method.txt Sat Feb 17 15:15:22 2007 @@ -224,7 +224,7 @@ some middle ground - thus increases the importance of feedback. -.. _documentation: http://codespeak.net/pypy/dist/pypy/doc/getting-started.html +.. _documentation: getting-started.html Can I join in? ++++++++++++++ Modified: pypy/release/0.99.x/pypy/doc/eventhistory.txt ============================================================================== --- pypy/release/0.99.x/pypy/doc/eventhistory.txt (original) +++ pypy/release/0.99.x/pypy/doc/eventhistory.txt Sat Feb 17 15:15:22 2007 @@ -140,7 +140,7 @@ all these documents are not approved by the European Union and therefore only preliminary. *(01/06/2006)* -.. _`reports for the EU`: http://codespeak.net/pypy/dist/pypy/doc/index-report.html +.. _`reports for the EU`: index-report.html PyPy Sprint in G?teborg 7th - 11th December 2005 @@ -168,7 +168,7 @@ the `getting started`_ document for instructions about downloading it and trying it out. There is also a short FAQ_. *(11/03/2005)* -.. _`release 0.8 announcement`: http://codespeak.net/pypy/dist/pypy/doc/release-0.8.0.html +.. _`release 0.8 announcement`: release-0.8.0.html PyPy Sprint in Paris 10th-16th October 2005 ======================================================== @@ -203,9 +203,9 @@ trying it out. We also have the beginning of a FAQ_. *(08/28/2005)* .. _`pypy-0.7.0`: -.. _`release announcement`: http://codespeak.net/pypy/dist/pypy/doc/release-0.7.0.html -.. _`getting started`: http://codespeak.net/pypy/dist/pypy/doc/getting-started.html -.. _FAQ: http://codespeak.net/pypy/dist/pypy/doc/faq.html +.. _`release announcement`: release-0.7.0.html +.. _`getting started`: getting-started.html +.. _FAQ: faq.html PyPy Sprint in Heidelberg 22nd-29th August 2005 ========================================================== @@ -268,7 +268,7 @@ .. _`pypy-dev`: http://codespeak.net/mailman/listinfo/pypy-dev .. _EuroPython: http://europython.org -.. _`translation`: http://codespeak.net/pypy/dist/pypy/doc/translation.html +.. _`translation`: translation.html .. _`sprint announcement`: http://codespeak.net/pypy/extradoc/sprintinfo/EP2005-announcement.html .. _`list of people coming`: http://codespeak.net/pypy/extradoc/sprintinfo/EP2005-people.html Modified: pypy/release/0.99.x/pypy/doc/extradoc.txt ============================================================================== --- pypy/release/0.99.x/pypy/doc/extradoc.txt (original) +++ pypy/release/0.99.x/pypy/doc/extradoc.txt Sat Feb 17 15:15:22 2007 @@ -144,7 +144,7 @@ .. _`Croquet`: http://www.opencroquet.org/ .. _`transparent dynamic optimization`: http://www.hpl.hp.com/techreports/1999/HPL-1999-77.pdf .. _Dynamo: http://www.hpl.hp.com/techreports/1999/HPL-1999-78.pdf -.. _testdesign: http://codespeak.net/pypy/dist/pypy/doc/coding-guide.html#test-design +.. _testdesign: coding-guide.html#test-design .. _feasible: http://codespeak.net/pipermail/pypy-dev/2004q2/001289.html .. _rock: http://codespeak.net/pipermail/pypy-dev/2004q1/001255.html .. _`GNU lightning`: http://www.gnu.org/software/lightning/lightning.html Modified: pypy/release/0.99.x/pypy/doc/geninterp.txt ============================================================================== --- pypy/release/0.99.x/pypy/doc/geninterp.txt (original) +++ pypy/release/0.99.x/pypy/doc/geninterp.txt Sat Feb 17 15:15:22 2007 @@ -18,8 +18,8 @@ any longer to execute this code. .. _`application-level`: coding-guide.html#app-preferable -.. _exceptions: http://codespeak.net/pypy/dist/pypy/lib/_exceptions.py -.. _oldstyle: http://codespeak.net/pypy/dist/pypy/lib/_classobj.py +.. _exceptions: ../../pypy/lib/_exceptions.py +.. _oldstyle: ../../pypy/lib/_classobj.py Examples are exceptions_ and oldstyle_ classes. They are needed in a very early phase of bootstrapping StdObjspace, but @@ -48,7 +48,7 @@ Example +++++++ -.. _implementation: http://codespeak.net/pypy/dist/pypy/translator/geninterplevel.py +.. _implementation: ../../pypy/translator/geninterplevel.py Let's try a little example. You might want to look at the flowgraph that it produces. Here, we directly run the Python translation and look at the @@ -177,8 +177,8 @@ Interplevel Snippets in the Sources +++++++++++++++++++++++++++++++++++ -.. _`_exceptions.py`: http://codespeak.net/pypy/dist/pypy/lib/_exceptions.py -.. _`_classobj.py`: http://codespeak.net/pypy/dist/pypy/lib/_classobj.py +.. _`_exceptions.py`: ../../pypy/lib/_exceptions.py +.. _`_classobj.py`: ../../pypy/lib/_classobj.py Code written in application space can consist of complete files to be translated (`_exceptions.py`_, `_classobj.py`_), or they Modified: pypy/release/0.99.x/pypy/doc/getting-started.txt ============================================================================== --- pypy/release/0.99.x/pypy/doc/getting-started.txt (original) +++ pypy/release/0.99.x/pypy/doc/getting-started.txt Sat Feb 17 15:15:22 2007 @@ -20,7 +20,7 @@ translation aspect - should become robust against language changes. `more...`_ .. _Python: http://docs.python.org/ref -.. _`more...`: http://codespeak.net/pypy/dist/pypy/doc/architecture.html +.. _`more...`: architecture.html Just the facts ============== @@ -794,7 +794,7 @@ as EuroPython or Pycon. Take a look at the list of upcoming events_ to plan where to meet with us. -.. _events: http://codespeak.net/pypy/dist/pypy/doc/events.html +.. _events: http://codespeak.net/pypy/dist/pypy/doc/news.html .. _`pypy-dev mailing list`: http://codespeak.net/mailman/listinfo/pypy-dev .. _`contact possibilities`: contact.html @@ -824,11 +824,11 @@ .. _mixedmodule.py: http://codespeak.net/svn/pypy/dist/pypy/interpreter/mixedmodule.py .. _typedef.py: http://codespeak.net/svn/pypy/dist/pypy/interpreter/typedef.py .. _Standard object space: objspace.html#the-standard-object-space -.. _objspace.py: http://codespeak.net/pypy/dist/pypy/objspace/std/objspace.py -.. _thunk: http://codespeak.net/pypy/dist/pypy/objspace/thunk.py -.. _trace: http://codespeak.net/pypy/dist/pypy/objspace/trace.py -.. _flow: http://codespeak.net/pypy/dist/pypy/objspace/flow/ -.. _translator.py: http://codespeak.net/pypy/dist/pypy/translator/translator.py +.. _objspace.py: ../../pypy/objspace/std/objspace.py +.. _thunk: ../../pypy/objspace/thunk.py +.. _trace: ../../pypy/objspace/trace.py +.. _flow: ../../pypy/objspace/flow/ +.. _translator.py: ../../pypy/translator/translator.py .. _mailing lists: contact.html .. _documentation: index.html .. _unit tests: coding-guide.html#test-design Modified: pypy/release/0.99.x/pypy/doc/news.txt ============================================================================== --- pypy/release/0.99.x/pypy/doc/news.txt (original) +++ pypy/release/0.99.x/pypy/doc/news.txt Sat Feb 17 15:15:22 2007 @@ -5,7 +5,7 @@ nonsense, isn't it? `more...`_ .. _Python: http://www.python.org/doc/current/ref/ref.html -.. _`more...`: http://codespeak.net/pypy/dist/pypy/doc/architecture.html#mission-statement +.. _`more...`: architecture.html#mission-statement The following is a list of planned PyPy events, most of which Modified: pypy/release/0.99.x/pypy/doc/release-0.99.0.txt ============================================================================== --- pypy/release/0.99.x/pypy/doc/release-0.99.0.txt (original) +++ pypy/release/0.99.x/pypy/doc/release-0.99.0.txt Sat Feb 17 15:15:22 2007 @@ -69,7 +69,6 @@ you to create objects of builtin types with completely customised behaviour. For details see http://codespeak.net/pypy/dist/pypy/doc/proxy.html - XXX Move link to the bottom? * optimizations: Modified: pypy/release/0.99.x/pypy/doc/translation.txt ============================================================================== --- pypy/release/0.99.x/pypy/doc/translation.txt (original) +++ pypy/release/0.99.x/pypy/doc/translation.txt Sat Feb 17 15:15:22 2007 @@ -91,18 +91,18 @@ stages. .. _`SSA`: http://en.wikipedia.org/wiki/Static_single_assignment_form -.. _`translator.py`: http://codespeak.net/pypy/dist/pypy/translator/translator.py +.. _`translator.py`: ../../pypy/translator/translator.py .. _`play around`: getting-started.html#trying-out-the-translator .. _`Flow Object Space`: objspace.html#the-flow-object-space .. _`control flow graph`: objspace.html#the-flow-model -.. _`Common Lisp`: http://codespeak.net/pypy/dist/pypy/translator/lisp/ -.. _Pyrex: http://codespeak.net/pypy/dist/pypy/translator/pyrex/ -.. _JavaScript: http://codespeak.net/pypy/dist/pypy/translator/js/ -.. _Squeak: http://codespeak.net/pypy/dist/pypy/translator/squeak/ -.. _CLI: http://codespeak.net/pypy/dist/pypy/translator/cli/ +.. _`Common Lisp`: ../../pypy/translator/lisp/ +.. _Pyrex: ../../pypy/translator/pyrex/ +.. _JavaScript: ../../pypy/translator/js/ +.. _Squeak: ../../pypy/translator/squeak/ +.. _CLI: ../../pypy/translator/cli/ .. _graph: image/translation.pdf .. _`interactive interface`: getting-started.html#try-out-the-translator -.. _`translatorshell.py`: http://codespeak.net/pypy/dist/pypy/bin/translatorshell.py +.. _`translatorshell.py`: ../../pypy/bin/translatorshell.py .. _`flow model`: Modified: pypy/release/0.99.x/pypy/doc/windows.txt ============================================================================== --- pypy/release/0.99.x/pypy/doc/windows.txt (original) +++ pypy/release/0.99.x/pypy/doc/windows.txt Sat Feb 17 15:15:22 2007 @@ -112,6 +112,6 @@ .. _`Boehm collector suite`: http://www.hpl.hp.com/personal/Hans_Boehm/gc/gc_source/gc.tar.gz -.. _gc_patch_windows.py: http://codespeak.net/pypy/dist/pypy/translator/goal/win32/gc_patch_windows.py +.. _gc_patch_windows.py: ../../pypy/translator/goal/win32/gc_patch_windows.py .. _`gc-windows.zip`: http://codespeak.net/~antocuni/gc-windows.zip From hpk at codespeak.net Sat Feb 17 15:29:36 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sat, 17 Feb 2007 15:29:36 +0100 (CET) Subject: [pypy-svn] r39110 - pypy/release/0.99.x/pypy/doc Message-ID: <20070217142936.7ACD410170@code0.codespeak.net> Author: hpk Date: Sat Feb 17 15:29:35 2007 New Revision: 39110 Modified: pypy/release/0.99.x/pypy/doc/release-0.99.0.txt Log: try to be clearer with tproxy mentioning Modified: pypy/release/0.99.x/pypy/doc/release-0.99.0.txt ============================================================================== --- pypy/release/0.99.x/pypy/doc/release-0.99.0.txt (original) +++ pypy/release/0.99.x/pypy/doc/release-0.99.0.txt Sat Feb 17 15:29:35 2007 @@ -65,9 +65,9 @@ objects are "declassified" in order to send information across I/O barriers. - - Transparent proxies: An addition to the standard object space, which allows - you to create objects of builtin types with completely customised - behaviour. For details see + - Transparent proxies: allow to customize both application and + builtin objects from application level code. Works as an addition + to the Standard Object Space (and is translatable). For details see http://codespeak.net/pypy/dist/pypy/doc/proxy.html * optimizations: From pedronis at codespeak.net Sat Feb 17 15:30:07 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 17 Feb 2007 15:30:07 +0100 (CET) Subject: [pypy-svn] r39111 - pypy/release/0.99.x Message-ID: <20070217143007.48A5210171@code0.codespeak.net> Author: pedronis Date: Sat Feb 17 15:30:04 2007 New Revision: 39111 Modified: pypy/release/0.99.x/README Log: detail Modified: pypy/release/0.99.x/README ============================================================================== --- pypy/release/0.99.x/README (original) +++ pypy/release/0.99.x/README Sat Feb 17 15:30:04 2007 @@ -4,10 +4,10 @@ Welcome to PyPy! -PyPy is both an implementation of the Python programming language, -and an extensive compiler framework for dynamic languages. -You can build self-contained Python implementations -which execute independently from CPython. +PyPy is both an implementation of the Python programming language, and +an extensive compiler framework for dynamic language implementations. +You can build self-contained Python implementations which execute +independently from CPython. We invite you to head over to our detailed getting-started document: From cfbolz at codespeak.net Sat Feb 17 15:46:57 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sat, 17 Feb 2007 15:46:57 +0100 (CET) Subject: [pypy-svn] r39112 - pypy/release/0.99.x/pypy/doc Message-ID: <20070217144657.09AA110171@code0.codespeak.net> Author: cfbolz Date: Sat Feb 17 15:46:56 2007 New Revision: 39112 Modified: pypy/release/0.99.x/pypy/doc/getting-started.txt Log: add ctypes to requirements Modified: pypy/release/0.99.x/pypy/doc/getting-started.txt ============================================================================== --- pypy/release/0.99.x/pypy/doc/getting-started.txt (original) +++ pypy/release/0.99.x/pypy/doc/getting-started.txt Sat Feb 17 15:46:56 2007 @@ -760,6 +760,16 @@ pygame: http://www.pygame.org/download.shtml +CTypes (highly recommended) +++++++++++++++++++++++++++++ + +`ctypes`_ (version 0.9.9.6 or later) is required if you want to translate PyPy +to C. See the `download page of ctypes`_. + +.. _`download page of ctypes`: http://sourceforge.net/project/showfiles.php?group_id=71702 +.. _`ctypes`: http://starship.python.net/crew/theller/ctypes/ + + CLISP +++++++ From hpk at codespeak.net Sat Feb 17 16:17:44 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sat, 17 Feb 2007 16:17:44 +0100 (CET) Subject: [pypy-svn] r39116 - pypy/release/0.99.x/pypy/doc Message-ID: <20070217151744.5600F10180@code0.codespeak.net> Author: hpk Date: Sat Feb 17 16:17:43 2007 New Revision: 39116 Modified: pypy/release/0.99.x/pypy/doc/release-0.99.0.txt Log: added another optimization news after reading 0.9->0.99 diff and brief discussion with cfbolz Modified: pypy/release/0.99.x/pypy/doc/release-0.99.0.txt ============================================================================== --- pypy/release/0.99.x/pypy/doc/release-0.99.0.txt (original) +++ pypy/release/0.99.x/pypy/doc/release-0.99.0.txt Sat Feb 17 16:17:43 2007 @@ -78,6 +78,9 @@ - Optimized builtin lookups to not require any dictionary lookups if the builtin is not shadowed by a name in the global dictionary. + - Improved inlining (now also working for higher level + backends) and malloc removal. + - twice the speed of the 0.9 release, overall 2-3 slower than CPython * High level backends: From cfbolz at codespeak.net Sat Feb 17 16:30:45 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sat, 17 Feb 2007 16:30:45 +0100 (CET) Subject: [pypy-svn] r39117 - pypy/release/0.99.x/pypy/doc Message-ID: <20070217153045.5CD6B10182@code0.codespeak.net> Author: cfbolz Date: Sat Feb 17 16:30:44 2007 New Revision: 39117 Modified: pypy/release/0.99.x/pypy/doc/getting-started.txt Log: point to 1.9 instead of 1.7 Modified: pypy/release/0.99.x/pypy/doc/getting-started.txt ============================================================================== --- pypy/release/0.99.x/pypy/doc/getting-started.txt (original) +++ pypy/release/0.99.x/pypy/doc/getting-started.txt Sat Feb 17 16:30:44 2007 @@ -437,7 +437,7 @@ +++++++++++++++++++++++++++++++++++++++ To translate for LLVM (`low level virtual machine`_) you must first have `LLVM -installed with version 1.7`_ - the `how to install LLVM`_ provides some helpful +installed with version 1.9`_ - the `how to install LLVM`_ provides some helpful hints. Please note that you do not need the CFrontend to compile, make tools-only. @@ -813,7 +813,7 @@ .. _`low level virtual machine`: http://llvm.org/ .. _`how to install LLVM`: http://llvm.org/docs/GettingStarted.html .. _`LLVM mailing list`: http://mail.cs.uiuc.edu/mailman/listinfo/llvmdev -.. _`LLVM installed with version 1.7`: http://llvm.org/releases +.. _`LLVM installed with version 1.9`: http://llvm.org/releases .. _`Spidermonkey`: http://www.mozilla.org/js/spidermonkey/ .. _`Google summer of code`: http://code.google.com/soc From cfbolz at codespeak.net Sat Feb 17 16:31:04 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sat, 17 Feb 2007 16:31:04 +0100 (CET) Subject: [pypy-svn] r39118 - pypy/release/0.99.x/pypy/doc Message-ID: <20070217153104.D6DF910187@code0.codespeak.net> Author: cfbolz Date: Sat Feb 17 16:31:03 2007 New Revision: 39118 Modified: pypy/release/0.99.x/pypy/doc/confrest.py Log: news should point to the webpage Modified: pypy/release/0.99.x/pypy/doc/confrest.py ============================================================================== --- pypy/release/0.99.x/pypy/doc/confrest.py (original) +++ pypy/release/0.99.x/pypy/doc/confrest.py Sat Feb 17 16:31:03 2007 @@ -4,7 +4,8 @@ class PyPyPage(Page): def fill_menubar(self): self.menubar = html.div( - html.a("news", href=self.get_doclink("news.html"), + html.a("news", + href="http://codespeak.net/pypy/dist/pypy/doc/news.html", class_="menu"), " ", html.a("getting-started", href=self.get_doclink("getting-started.html"), From pedronis at codespeak.net Sat Feb 17 16:40:06 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 17 Feb 2007 16:40:06 +0100 (CET) Subject: [pypy-svn] r39119 - pypy/release/0.99.x/pypy/doc Message-ID: <20070217154006.C7BA410188@code0.codespeak.net> Author: pedronis Date: Sat Feb 17 16:40:05 2007 New Revision: 39119 Modified: pypy/release/0.99.x/pypy/doc/how-to-release.txt Log: Some notes about -tag option to makerelease, and tarball-testing. Modified: pypy/release/0.99.x/pypy/doc/how-to-release.txt ============================================================================== --- pypy/release/0.99.x/pypy/doc/how-to-release.txt (original) +++ pypy/release/0.99.x/pypy/doc/how-to-release.txt Sat Feb 17 16:40:05 2007 @@ -30,11 +30,18 @@ and release number references, make sure it is generally up-to-date * use, after the necessary updates, dist/pypy/tool/makerelease.py to make the tarballs on codespeak; this generates html doc for the - tarballs too. (XXX what about tagging?) + tarballs too. Use:: + + makerelease -tag .z pypy-x.y.z + + to tag and produce final tarballs. Without the '-tag' this can + be used to make pre-release testing tarballs. * nowadays we have an extensive set of nightly builds and test runs. Is probably good to do some minimal testing of the tarballs, especially to check that things work even outside a working copy or - if some stuff is missing. + if some stuff is missing. We have some support for running part of + our nightly tests on tarballs (see + http://codespeak.net/svn/user/pedronis/tarball-testing). * write a news item for the release in dist/pypy/doc/news.txt * send announcements to pypy-dev, pypy-funding, python-list, python-announce, python-dev ... From cfbolz at codespeak.net Sat Feb 17 16:50:54 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sat, 17 Feb 2007 16:50:54 +0100 (CET) Subject: [pypy-svn] r39120 - pypy/dist/pypy/doc Message-ID: <20070217155054.A1C4B1018A@code0.codespeak.net> Author: cfbolz Date: Sat Feb 17 16:50:53 2007 New Revision: 39120 Modified: pypy/dist/pypy/doc/news.txt Log: add news item for release Modified: pypy/dist/pypy/doc/news.txt ============================================================================== --- pypy/dist/pypy/doc/news.txt (original) +++ pypy/dist/pypy/doc/news.txt Sat Feb 17 16:50:53 2007 @@ -15,6 +15,18 @@ .. _`iCalendar format`: webcal://pypycal.sabi.net///calendars/PyPy.ics .. _eventhistory: eventhistory.html +PyPy 0.99.0 +================================================================== + +We are proud to release PyPy 0.99.0, our fifth public release. See +the `release announcement `__ to read about the +many new features in this release. See also our detailed instructions on +how to `get started`_. *(February 17th, 2007)* + +.. _`get started`: getting-started.html + + + PyPy Trillke Sprints upcoming, 25-28th Feb and 1-5th March 2007 ================================================================== From hpk at codespeak.net Sat Feb 17 16:58:11 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sat, 17 Feb 2007 16:58:11 +0100 (CET) Subject: [pypy-svn] r39121 - pypy/dist/pypy/doc Message-ID: <20070217155811.E577F1018C@code0.codespeak.net> Author: hpk Date: Sat Feb 17 16:58:11 2007 New Revision: 39121 Modified: pypy/dist/pypy/doc/news.txt Log: * add more to the pypy-release title * add a news item for py lib release Modified: pypy/dist/pypy/doc/news.txt ============================================================================== --- pypy/dist/pypy/doc/news.txt (original) +++ pypy/dist/pypy/doc/news.txt Sat Feb 17 16:58:11 2007 @@ -15,7 +15,7 @@ .. _`iCalendar format`: webcal://pypycal.sabi.net///calendars/PyPy.ics .. _eventhistory: eventhistory.html -PyPy 0.99.0 +PyPy 0.99.0: optimizations, backends, new object spaces and more ================================================================== We are proud to release PyPy 0.99.0, our fifth public release. See @@ -26,6 +26,14 @@ .. _`get started`: getting-started.html +py lib 0.9.0: py.test, distributed execution, greenlets and more +================================================================== + +Our development support and testing library was publically released, see the +`0.9 release announcement `__ +and its extensive `online documentation `__. +(February 15th, 2007) + PyPy Trillke Sprints upcoming, 25-28th Feb and 1-5th March 2007 ================================================================== From pedronis at codespeak.net Sat Feb 17 17:07:18 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 17 Feb 2007 17:07:18 +0100 (CET) Subject: [pypy-svn] r39123 - pypy/release/0.99.x/pypy/doc Message-ID: <20070217160718.1670C10187@code0.codespeak.net> Author: pedronis Date: Sat Feb 17 17:07:16 2007 New Revision: 39123 Modified: pypy/release/0.99.x/pypy/doc/news.txt Log: merging 0.99 news from 39120, 39121 Modified: pypy/release/0.99.x/pypy/doc/news.txt ============================================================================== --- pypy/release/0.99.x/pypy/doc/news.txt (original) +++ pypy/release/0.99.x/pypy/doc/news.txt Sat Feb 17 17:07:16 2007 @@ -15,6 +15,26 @@ .. _`iCalendar format`: webcal://pypycal.sabi.net///calendars/PyPy.ics .. _eventhistory: eventhistory.html +PyPy 0.99.0: optimizations, backends, new object spaces and more +================================================================== + +We are proud to release PyPy 0.99.0, our fifth public release. See +the `release announcement `__ to read about the +many new features in this release. See also our detailed instructions on +how to `get started`_. *(February 17th, 2007)* + +.. _`get started`: getting-started.html + + +py lib 0.9.0: py.test, distributed execution, greenlets and more +================================================================== + +Our development support and testing library was publically released, see the +`0.9 release announcement `__ +and its extensive `online documentation `__. +(February 15th, 2007) + + PyPy Trillke Sprints upcoming, 25-28th Feb and 1-5th March 2007 ================================================================== From pedronis at codespeak.net Sat Feb 17 17:13:08 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 17 Feb 2007 17:13:08 +0100 (CET) Subject: [pypy-svn] r39125 - pypy/dist Message-ID: <20070217161308.0EAFD1018D@code0.codespeak.net> Author: pedronis Date: Sat Feb 17 17:13:08 2007 New Revision: 39125 Removed: pypy/dist/LICENSE pypy/dist/README Log: copy from 0.99 From pedronis at codespeak.net Sat Feb 17 17:14:58 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 17 Feb 2007 17:14:58 +0100 (CET) Subject: [pypy-svn] r39126 - pypy/dist Message-ID: <20070217161458.6CB3610191@code0.codespeak.net> Author: pedronis Date: Sat Feb 17 17:14:57 2007 New Revision: 39126 Added: pypy/dist/LICENSE - copied unchanged from r39125, pypy/release/0.99.x/LICENSE pypy/dist/README - copied unchanged from r39125, pypy/release/0.99.x/README Log: finish copy from 0.99 From pedronis at codespeak.net Sat Feb 17 17:21:46 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 17 Feb 2007 17:21:46 +0100 (CET) Subject: [pypy-svn] r39127 - pypy/dist/pypy/doc Message-ID: <20070217162146.68D3810192@code0.codespeak.net> Author: pedronis Date: Sat Feb 17 17:21:44 2007 New Revision: 39127 Removed: pypy/dist/pypy/doc/getting-started.txt pypy/dist/pypy/doc/release-0.99.0.txt Log: copy from 0.99 From pedronis at codespeak.net Sat Feb 17 17:22:49 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 17 Feb 2007 17:22:49 +0100 (CET) Subject: [pypy-svn] r39128 - pypy/dist/pypy/doc Message-ID: <20070217162249.73FB910196@code0.codespeak.net> Author: pedronis Date: Sat Feb 17 17:22:48 2007 New Revision: 39128 Added: pypy/dist/pypy/doc/getting-started.txt - copied unchanged from r39127, pypy/release/0.99.x/pypy/doc/getting-started.txt pypy/dist/pypy/doc/release-0.99.0.txt - copied unchanged from r39127, pypy/release/0.99.x/pypy/doc/release-0.99.0.txt Log: finish copy from 0.99 From pedronis at codespeak.net Sat Feb 17 17:25:40 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 17 Feb 2007 17:25:40 +0100 (CET) Subject: [pypy-svn] r39129 - pypy/dist/pypy/doc Message-ID: <20070217162540.2C43710198@code0.codespeak.net> Author: pedronis Date: Sat Feb 17 17:25:39 2007 New Revision: 39129 Modified: pypy/dist/pypy/doc/confrest.py Log: merge 39118, absolute link to news from 0.99.x Modified: pypy/dist/pypy/doc/confrest.py ============================================================================== --- pypy/dist/pypy/doc/confrest.py (original) +++ pypy/dist/pypy/doc/confrest.py Sat Feb 17 17:25:39 2007 @@ -4,7 +4,8 @@ class PyPyPage(Page): def fill_menubar(self): self.menubar = html.div( - html.a("news", href=self.get_doclink("news.html"), + html.a("news", + href="http://codespeak.net/pypy/dist/pypy/doc/news.html", class_="menu"), " ", html.a("getting-started", href=self.get_doclink("getting-started.html"), From pedronis at codespeak.net Sat Feb 17 17:39:27 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 17 Feb 2007 17:39:27 +0100 (CET) Subject: [pypy-svn] r39130 - pypy/release/0.99.x/pypy/doc Message-ID: <20070217163927.6C8D0101A1@code0.codespeak.net> Author: pedronis Date: Sat Feb 17 17:39:25 2007 New Revision: 39130 Modified: pypy/release/0.99.x/pypy/doc/jit.txt Log: pointer to the in-progress doc. Modified: pypy/release/0.99.x/pypy/doc/jit.txt ============================================================================== --- pypy/release/0.99.x/pypy/doc/jit.txt (original) +++ pypy/release/0.99.x/pypy/doc/jit.txt Sat Feb 17 17:39:25 2007 @@ -1,4 +1,7 @@ -The JIT is not included in the 0.99 release. See the +The JIT (and its generator) are not included in the 0.99 release. See the `release announcement (doc/release-0.99.0-txt)`_ for details. +The work-in-progress documentation about the JIT generator lives +at http://codespeak.net/pypy/dist/pypy/doc/jit.html. + .. _`release announcement (doc/release-0.99.0-txt)`: release-0.99.0.html From pedronis at codespeak.net Sat Feb 17 17:49:29 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 17 Feb 2007 17:49:29 +0100 (CET) Subject: [pypy-svn] r39131 - pypy/release/0.99.x/pypy/tool Message-ID: <20070217164929.BE3A2101A3@code0.codespeak.net> Author: pedronis Date: Sat Feb 17 17:49:27 2007 New Revision: 39131 Modified: pypy/release/0.99.x/pypy/tool/makerelease.py Log: fix Modified: pypy/release/0.99.x/pypy/tool/makerelease.py ============================================================================== --- pypy/release/0.99.x/pypy/tool/makerelease.py (original) +++ pypy/release/0.99.x/pypy/tool/makerelease.py Sat Feb 17 17:49:27 2007 @@ -98,7 +98,7 @@ micro = py.std.sys.argv[2] assert micro.startswith('.') NEWURL = BASEURL.replace('.x', micro) - cexec('svn cp %s %s' % (BASEURL, NEWURL)) + os.system("svn cp %s %s" % (BASEURL, NEWURL)) BASEURL = NEWURL j = 3 From pedronis at codespeak.net Sat Feb 17 17:49:53 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 17 Feb 2007 17:49:53 +0100 (CET) Subject: [pypy-svn] r39132 - pypy/release/0.99.0 Message-ID: <20070217164953.D55C5101A9@code0.codespeak.net> Author: pedronis Date: Sat Feb 17 17:49:52 2007 New Revision: 39132 Added: pypy/release/0.99.0/ - copied from r39131, pypy/release/0.99.x/ Log: tagging 0.99.0 From pedronis at codespeak.net Sat Feb 17 18:29:35 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 17 Feb 2007 18:29:35 +0100 (CET) Subject: [pypy-svn] r39135 - in pypy/dist/pypy: doc tool Message-ID: <20070217172935.8FCD5101AC@code0.codespeak.net> Author: pedronis Date: Sat Feb 17 18:29:33 2007 New Revision: 39135 Removed: pypy/dist/pypy/doc/how-to-release.txt pypy/dist/pypy/tool/makerelease.py Log: copy latest version of the release how-to and tool to the trunk. From pedronis at codespeak.net Sat Feb 17 18:31:04 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 17 Feb 2007 18:31:04 +0100 (CET) Subject: [pypy-svn] r39136 - in pypy/dist/pypy: doc tool Message-ID: <20070217173104.3B345101AF@code0.codespeak.net> Author: pedronis Date: Sat Feb 17 18:31:03 2007 New Revision: 39136 Added: pypy/dist/pypy/doc/how-to-release.txt - copied unchanged from r39135, pypy/release/0.99.x/pypy/doc/how-to-release.txt pypy/dist/pypy/tool/makerelease.py - copied unchanged from r39135, pypy/release/0.99.x/pypy/tool/makerelease.py Log: finish copy form 0.99.x of latest version of release helps. From pedronis at codespeak.net Sat Feb 17 20:28:07 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 17 Feb 2007 20:28:07 +0100 (CET) Subject: [pypy-svn] r39138 - pypy/dist/pypy/tool Message-ID: <20070217192807.0ABEE101BC@code0.codespeak.net> Author: pedronis Date: Sat Feb 17 20:28:06 2007 New Revision: 39138 Modified: pypy/dist/pypy/tool/makerelease.py Log: error checking before I forget. Modified: pypy/dist/pypy/tool/makerelease.py ============================================================================== --- pypy/dist/pypy/tool/makerelease.py (original) +++ pypy/dist/pypy/tool/makerelease.py Sat Feb 17 20:28:06 2007 @@ -98,7 +98,9 @@ micro = py.std.sys.argv[2] assert micro.startswith('.') NEWURL = BASEURL.replace('.x', micro) - os.system("svn cp %s %s" % (BASEURL, NEWURL)) + r = os.system("svn cp %s %s" % (BASEURL, NEWURL)) + if r: + raise SystemExit, -1 BASEURL = NEWURL j = 3 From fijal at codespeak.net Sat Feb 17 21:22:44 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 17 Feb 2007 21:22:44 +0100 (CET) Subject: [pypy-svn] r39139 - pypy/dist/pypy/translator/js/examples/data Message-ID: <20070217202244.8D591101B9@code0.codespeak.net> Author: fijal Date: Sat Feb 17 21:22:43 2007 New Revision: 39139 Modified: pypy/dist/pypy/translator/js/examples/data/index.html Log: wording Modified: pypy/dist/pypy/translator/js/examples/data/index.html ============================================================================== --- pypy/dist/pypy/translator/js/examples/data/index.html (original) +++ pypy/dist/pypy/translator/js/examples/data/index.html Sat Feb 17 21:22:43 2007 @@ -6,6 +6,9 @@ +

Note: this demos are set up on the replicable xen instance, but + please do not vandalise the machine, otherwise we would be forced to + take it down

This site presents various demos and tutorials about pypy.js

Python console:

@@ -20,7 +23,7 @@

Bub'n'Bros JavaScript version

- This is a working b'n'b client. It's kind of slow (blame louse browsers), + This is a working b'n'b client. It's kind of slow (blame lousy browsers), but usable. WARNING! If you're using the firebug, please disable it, it's a great tool, but chockes a bit on this demo
Demo From fijal at codespeak.net Sun Feb 18 00:41:20 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 18 Feb 2007 00:41:20 +0100 (CET) Subject: [pypy-svn] r39145 - pypy/dist/pypy/doc/js Message-ID: <20070217234120.84ED8101C8@code0.codespeak.net> Author: fijal Date: Sun Feb 18 00:41:20 2007 New Revision: 39145 Modified: pypy/dist/pypy/doc/js/todo.txt Log: Fix rest a bit Modified: pypy/dist/pypy/doc/js/todo.txt ============================================================================== --- pypy/dist/pypy/doc/js/todo.txt (original) +++ pypy/dist/pypy/doc/js/todo.txt Sun Feb 18 00:41:20 2007 @@ -19,8 +19,6 @@ * Support bound methods as arguments for callbacks. - Idea is to provide following: - - if you pass a bound method to a callback, this method is called with previously bound self - if you provide an unbound method for a callback, this is an error, From fijal at codespeak.net Sun Feb 18 00:43:08 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 18 Feb 2007 00:43:08 +0100 (CET) Subject: [pypy-svn] r39146 - pypy/dist/pypy/doc/js Message-ID: <20070217234308.462E1101CC@code0.codespeak.net> Author: fijal Date: Sun Feb 18 00:43:06 2007 New Revision: 39146 Modified: pypy/dist/pypy/doc/js/todo.txt Log: Rest? Modified: pypy/dist/pypy/doc/js/todo.txt ============================================================================== --- pypy/dist/pypy/doc/js/todo.txt (original) +++ pypy/dist/pypy/doc/js/todo.txt Sun Feb 18 00:43:06 2007 @@ -19,15 +19,15 @@ * Support bound methods as arguments for callbacks. - - if you pass a bound method to a callback, this method is called + - if you pass a bound method to a callback, this method is called with previously bound self - - if you provide an unbound method for a callback, this is an error, - unless class is proper to the callback object (or high level class - apropriate for that DOM object), in which case a bound method is - called with apropriate self. + - if you provide an unbound method for a callback, this is an error, + unless class is proper to the callback object (or high level class + apropriate for that DOM object), in which case a bound method is + called with apropriate self. - I'm quite sure this can be done using RPython, but I'm totally unsure - how much effort this will require :-) (as usuall) + - I'm quite sure this can be done using RPython, but I'm totally unsure + how much effort this will require :-) (as usuall) * Cleanup of parent namespace (put all builtin functions into it's own namespace?) From fijal at codespeak.net Sun Feb 18 00:47:23 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 18 Feb 2007 00:47:23 +0100 (CET) Subject: [pypy-svn] r39147 - pypy/dist/pypy/doc/js Message-ID: <20070217234723.EE8161006F@code0.codespeak.net> Author: fijal Date: Sun Feb 18 00:47:22 2007 New Revision: 39147 Modified: pypy/dist/pypy/doc/js/todo.txt Log: another attempt Modified: pypy/dist/pypy/doc/js/todo.txt ============================================================================== --- pypy/dist/pypy/doc/js/todo.txt (original) +++ pypy/dist/pypy/doc/js/todo.txt Sun Feb 18 00:47:22 2007 @@ -20,7 +20,8 @@ * Support bound methods as arguments for callbacks. - if you pass a bound method to a callback, this method is called - with previously bound self + with previously bound self + - if you provide an unbound method for a callback, this is an error, unless class is proper to the callback object (or high level class apropriate for that DOM object), in which case a bound method is From hpk at codespeak.net Sun Feb 18 09:54:23 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sun, 18 Feb 2007 09:54:23 +0100 (CET) Subject: [pypy-svn] r39151 - pypy/dist/pypy/doc Message-ID: <20070218085423.340C3101D3@code0.codespeak.net> Author: hpk Date: Sun Feb 18 09:54:22 2007 New Revision: 39151 Modified: pypy/dist/pypy/doc/getting-started.txt Log: insert one hook that one should use python2.4 for translation tools. Modified: pypy/dist/pypy/doc/getting-started.txt ============================================================================== --- pypy/dist/pypy/doc/getting-started.txt (original) +++ pypy/dist/pypy/doc/getting-started.txt Sun Feb 18 09:54:22 2007 @@ -386,6 +386,9 @@ `Dot Graphviz`_ that does not crash. This is only needed if you want to look at the flowgraphs. + * Use Python-2.4 for using translation tools because python2.5 + is (as of revision 39130) not fully supported. + To start the interactive translator shell do:: cd pypy From fijal at codespeak.net Sun Feb 18 14:05:46 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 18 Feb 2007 14:05:46 +0100 (CET) Subject: [pypy-svn] r39153 - pypy/extradoc/sprintinfo/trillke-2007 Message-ID: <20070218130546.7A991101DD@code0.codespeak.net> Author: fijal Date: Sun Feb 18 14:05:43 2007 New Revision: 39153 Modified: pypy/extradoc/sprintinfo/trillke-2007/people.txt Log: my dates Modified: pypy/extradoc/sprintinfo/trillke-2007/people.txt ============================================================================== --- pypy/extradoc/sprintinfo/trillke-2007/people.txt (original) +++ pypy/extradoc/sprintinfo/trillke-2007/people.txt Sun Feb 18 14:05:43 2007 @@ -15,7 +15,7 @@ Carl Friedrich Bolz 25th-5th ? Lene Wagner 25th-5th private Michael Hudson 27th-5th no idea -Maciej Fijalkowski ?-5th no idea +Maciej Fijalkowski 28th-? private Stephan Diehl 2nd-4th no idea Antonio Cuni 25th-5th no idea Samuele Pedroni 25th-5th TBD From cfbolz at codespeak.net Sun Feb 18 14:45:17 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sun, 18 Feb 2007 14:45:17 +0100 (CET) Subject: [pypy-svn] r39154 - pypy/dist/pypy/objspace/std Message-ID: <20070218134517.0A3BF101E9@code0.codespeak.net> Author: cfbolz Date: Sun Feb 18 14:45:16 2007 New Revision: 39154 Modified: pypy/dist/pypy/objspace/std/stringobject.py Log: kill unused var Modified: pypy/dist/pypy/objspace/std/stringobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/stringobject.py (original) +++ pypy/dist/pypy/objspace/std/stringobject.py Sun Feb 18 14:45:16 2007 @@ -647,7 +647,6 @@ # cannot return w_self, in case it is a subclass of str return space.wrap(input) - result = [] buf = [' '] * width if len(input) > 0 and (input[0] == '+' or input[0] == '-'): buf[0] = input[0] From santagada at codespeak.net Sun Feb 18 14:57:32 2007 From: santagada at codespeak.net (santagada at codespeak.net) Date: Sun, 18 Feb 2007 14:57:32 +0100 (CET) Subject: [pypy-svn] r39155 - in pypy/dist/pypy/lang/js: . test/ecma Message-ID: <20070218135732.541D3101DC@code0.codespeak.net> Author: santagada Date: Sun Feb 18 14:57:31 2007 New Revision: 39155 Added: pypy/dist/pypy/lang/js/conftest.py pypy/dist/pypy/lang/js/test/ecma/conftest.py Modified: pypy/dist/pypy/lang/js/jsobj.py pypy/dist/pypy/lang/js/test/ecma/shell.js Log: new mozilla test suite integration with py.test Added: pypy/dist/pypy/lang/js/conftest.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/lang/js/conftest.py Sun Feb 18 14:57:31 2007 @@ -0,0 +1,9 @@ +import py + +Option = py.test.config.Option +option = py.test.config.addoptions("ecma compatibility tests", + Option('', '--ecma', + action="store_true", dest="ecma", default=False, + help="run js interpreter ecma tests" + ), +) Modified: pypy/dist/pypy/lang/js/jsobj.py ============================================================================== --- pypy/dist/pypy/lang/js/jsobj.py (original) +++ pypy/dist/pypy/lang/js/jsobj.py Sun Feb 18 14:57:31 2007 @@ -286,7 +286,6 @@ self.array = [] self.set_builtin_call(arraycallbi) - def Put(self, P, V): try: x = int(P) Added: pypy/dist/pypy/lang/js/test/ecma/conftest.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/lang/js/test/ecma/conftest.py Sun Feb 18 14:57:31 2007 @@ -0,0 +1,66 @@ +import py +from pypy.lang.js.interpreter import * +from pypy.lang.js.jsobj import W_Array +from pypy.lang.js.conftest import option + +rootdir = py.magic.autopath().dirpath() +exclusionlist = ['shell.js', 'browser.js'] + +class JSDirectory(py.test.collect.Directory): + + def filefilter(self, path): + if path.check(file=1): + return (path.basename not in exclusionlist) and (path.ext == '.js') + + def join(self, name): + if not name.endswith('.js'): + return super(Directory, self).join(name) + p = self.fspath.join(name) + if p.check(file=1): + return JSTestFile(p, parent=self) + + + +class JSTestFile(py.test.collect.Collector): + def __init__(self, filepath, parent=None): + super(JSTestFile, self).__init__(filepath, parent) + self.name = filepath.purebasename + " JSFILE" + self.filepath = filepath + + def run(self): + #actually run the file :) + t = load_source(self.filepath.read()) + try: + t.execute(interp.global_context) + except: + py.test.fail("Could not load js file") + testcases = interp.global_context.resolve_identifier('testcases') + values = testcases.GetValue().array + testcases.PutValue(W_Array(), interp.global_context) + return values + + def join(self, name): + return JSTestItem(name, parent = self) + +class JSTestItem(py.__.test.item.Item): + def __init__(self, name, parent=None): + #super(JSTestItem, self).__init__(filepath, parent) + self.name = name + + def run(): + ctx = interp.global_context + r3 = ctx.resolve_identifier('run_test').GetValue() + result = r3.Call(ctx=ctx, args=[name,]).ToNumber() + if result == 0: + py.test.fail() + elif result == -1: + py.test.skip() + +if option.ecma: + global interp + interp = Interpreter() + ctx = interp.global_context + shellpath = rootdir/'shell.js' + t = load_source(shellpath.read()) + t.execute(ctx) + Directory = JSDirectory \ No newline at end of file Modified: pypy/dist/pypy/lang/js/test/ecma/shell.js ============================================================================== --- pypy/dist/pypy/lang/js/test/ecma/shell.js (original) +++ pypy/dist/pypy/lang/js/test/ecma/shell.js Sun Feb 18 14:57:31 2007 @@ -124,23 +124,23 @@ } function test() { - for ( tc=0; tc < testcases.length; tc++ ) { - // temporary hack to work around some unknown issue in 1.7 - try - { - testcases[tc].passed = writeTestCaseResult( - testcases[tc].expect, - testcases[tc].actual, - testcases[tc].description +" = "+ testcases[tc].actual ); - testcases[tc].reason += ( testcases[tc].passed ) ? "" : "wrong value "; - } - catch(e) - { - print('test(): empty testcase for tc = ' + tc + ' ' + e); - } - } - stopTest(); - return ( testcases ); + // for ( tc=0; tc < testcases.length; tc++ ) { + // // temporary hack to work around some unknown issue in 1.7 + // try + // { + // testcases[tc].passed = writeTestCaseResult( + // testcases[tc].expect, + // testcases[tc].actual, + // testcases[tc].description +" = "+ testcases[tc].actual ); + // testcases[tc].reason += ( testcases[tc].passed ) ? "" : "wrong value "; + // } + // catch(e) + // { + // print('test(): empty testcase for tc = ' + tc + ' ' + e); + // } + // } + // stopTest(); + return ( testcases ); } /* @@ -193,6 +193,18 @@ * document.write. */ +function run_test(testnr) { + try + { + getTestCaseResult(testcases[tc].expect, testcases[tc].actual) + testcases[tc].reason += ( testcases[tc].passed ) ? "" : "wrong value "; + return testcases[tc].passed? 1:0; + } + catch(e) + { + return -1 + } +} function writeTestCaseResult( expect, actual, string ) { var passed = getTestCaseResult( expect, actual ); writeFormattedResult( expect, actual, string, passed ); From santagada at codespeak.net Sun Feb 18 18:25:58 2007 From: santagada at codespeak.net (santagada at codespeak.net) Date: Sun, 18 Feb 2007 18:25:58 +0100 (CET) Subject: [pypy-svn] r39166 - in pypy/dist/pypy/lang/js: . test Message-ID: <20070218172558.DA0F4101F1@code0.codespeak.net> Author: santagada Date: Sun Feb 18 18:25:57 2007 New Revision: 39166 Modified: pypy/dist/pypy/lang/js/interpreter.py pypy/dist/pypy/lang/js/jsobj.py pypy/dist/pypy/lang/js/test/test_interp.py Log: delete operator Modified: pypy/dist/pypy/lang/js/interpreter.py ============================================================================== --- pypy/dist/pypy/lang/js/interpreter.py (original) +++ pypy/dist/pypy/lang/js/interpreter.py Sun Feb 18 18:25:57 2007 @@ -511,6 +511,17 @@ name = op1.ToString() return W_Boolean(op2.HasProperty(name)) +class Delete(UnaryOp): + opcode = 'DELETE' + + def eval(self, ctx): + r1 = self.expr.eval(ctx) + if not isinstance(r1, W_Reference): + return W_Boolean(True) + r3 = r1.GetBase() + r4 = r1.GetPropertyName() + return r3.Delete(r4) + class Increment(UnaryOp): opcode = 'INCREMENT' Modified: pypy/dist/pypy/lang/js/jsobj.py ============================================================================== --- pypy/dist/pypy/lang/js/jsobj.py (original) +++ pypy/dist/pypy/lang/js/jsobj.py Sun Feb 18 18:25:57 2007 @@ -189,7 +189,7 @@ if self.Prototype is None: return False return self.Prototype.HasProperty(P) - def Delete(P): + def Delete(self, P): if P in self.propdict: if self.propdict[P].dd: return False del self.propdict[P] Modified: pypy/dist/pypy/lang/js/test/test_interp.py ============================================================================== --- pypy/dist/pypy/lang/js/test/test_interp.py (original) +++ pypy/dist/pypy/lang/js/test/test_interp.py Sun Feb 18 18:25:57 2007 @@ -454,3 +454,11 @@ def test_unary_plus(self): self.assert_prints("print(+1)", ['1']) + + def test_delete(self): + self.assert_prints(""" + var x = {} + x.y = 1; + delete x.y + print(x.y) + """, ['undefined']) From fijal at codespeak.net Sun Feb 18 19:01:35 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 18 Feb 2007 19:01:35 +0100 (CET) Subject: [pypy-svn] r39167 - pypy/dist/pypy/lang/js Message-ID: <20070218180135.BB6DF101F3@code0.codespeak.net> Author: fijal Date: Sun Feb 18 19:01:34 2007 New Revision: 39167 Modified: pypy/dist/pypy/lang/js/js_interactive.py Log: Quick hack to get rid of problems with options for ebnfparse. I would rather go and fix it at some point Modified: pypy/dist/pypy/lang/js/js_interactive.py ============================================================================== --- pypy/dist/pypy/lang/js/js_interactive.py (original) +++ pypy/dist/pypy/lang/js/js_interactive.py Sun Feb 18 19:01:34 2007 @@ -156,4 +156,6 @@ print res if __name__ == "__main__": + import py + py.test.config.parse(sys.argv) sys.exit(main()) From fijal at codespeak.net Sun Feb 18 19:09:42 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 18 Feb 2007 19:09:42 +0100 (CET) Subject: [pypy-svn] r39168 - pypy/dist/pypy/lang/js/test/ecma Message-ID: <20070218180942.58C1B101F7@code0.codespeak.net> Author: fijal Date: Sun Feb 18 19:09:38 2007 New Revision: 39168 Modified: pypy/dist/pypy/lang/js/test/ecma/conftest.py Log: At least --collectonly works. Breaks tests a bit (error reporting) but it's still better. This is intermediate checkin Modified: pypy/dist/pypy/lang/js/test/ecma/conftest.py ============================================================================== --- pypy/dist/pypy/lang/js/test/ecma/conftest.py (original) +++ pypy/dist/pypy/lang/js/test/ecma/conftest.py Sun Feb 18 19:09:38 2007 @@ -22,33 +22,43 @@ class JSTestFile(py.test.collect.Collector): + def init_interp(cls): + cls.interp = Interpreter() + ctx = cls.interp.global_context + shellpath = rootdir/'shell.js' + t = load_source(shellpath.read()) + t.execute(ctx) + init_interp = classmethod(init_interp) + def __init__(self, filepath, parent=None): super(JSTestFile, self).__init__(filepath, parent) self.name = filepath.purebasename + " JSFILE" self.filepath = filepath def run(self): + if not option.ecma: + py.test.skip("ECMA tests disabled, run with --ecma") #actually run the file :) t = load_source(self.filepath.read()) try: - t.execute(interp.global_context) + t.execute(self.interp.global_context) except: py.test.fail("Could not load js file") - testcases = interp.global_context.resolve_identifier('testcases') + testcases = self.interp.global_context.resolve_identifier('testcases') values = testcases.GetValue().array - testcases.PutValue(W_Array(), interp.global_context) + testcases.PutValue(W_Array(), self.interp.global_context) return values def join(self, name): return JSTestItem(name, parent = self) -class JSTestItem(py.__.test.item.Item): +class JSTestItem(py.test.collect.Item): def __init__(self, name, parent=None): #super(JSTestItem, self).__init__(filepath, parent) self.name = name def run(): - ctx = interp.global_context + ctx = JSTestFile.interp.global_context r3 = ctx.resolve_identifier('run_test').GetValue() result = r3.Call(ctx=ctx, args=[name,]).ToNumber() if result == 0: @@ -56,11 +66,4 @@ elif result == -1: py.test.skip() -if option.ecma: - global interp - interp = Interpreter() - ctx = interp.global_context - shellpath = rootdir/'shell.js' - t = load_source(shellpath.read()) - t.execute(ctx) - Directory = JSDirectory \ No newline at end of file +Directory = JSDirectory From fijal at codespeak.net Sun Feb 18 19:16:11 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 18 Feb 2007 19:16:11 +0100 (CET) Subject: [pypy-svn] r39170 - pypy/dist/pypy/lang/js Message-ID: <20070218181611.434AF101F8@code0.codespeak.net> Author: fijal Date: Sun Feb 18 19:16:09 2007 New Revision: 39170 Modified: pypy/dist/pypy/lang/js/js_interactive.py Log: Don't use py.test options Modified: pypy/dist/pypy/lang/js/js_interactive.py ============================================================================== --- pypy/dist/pypy/lang/js/js_interactive.py (original) +++ pypy/dist/pypy/lang/js/js_interactive.py Sun Feb 18 19:16:09 2007 @@ -157,5 +157,5 @@ if __name__ == "__main__": import py - py.test.config.parse(sys.argv) + py.test.config.parse([]) sys.exit(main()) From fijal at codespeak.net Sun Feb 18 19:19:33 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 18 Feb 2007 19:19:33 +0100 (CET) Subject: [pypy-svn] r39171 - pypy/dist/pypy/lang/js/test/ecma Message-ID: <20070218181933.7E66C101FC@code0.codespeak.net> Author: fijal Date: Sun Feb 18 19:19:32 2007 New Revision: 39171 Modified: pypy/dist/pypy/lang/js/test/ecma/conftest.py Log: Fix conftest a bit. Now it fails on module level Modified: pypy/dist/pypy/lang/js/test/ecma/conftest.py ============================================================================== --- pypy/dist/pypy/lang/js/test/ecma/conftest.py (original) +++ pypy/dist/pypy/lang/js/test/ecma/conftest.py Sun Feb 18 19:19:32 2007 @@ -21,7 +21,7 @@ -class JSTestFile(py.test.collect.Collector): +class JSTestFile(py.test.collect.Module): def init_interp(cls): cls.interp = Interpreter() ctx = cls.interp.global_context @@ -38,6 +38,8 @@ def run(self): if not option.ecma: py.test.skip("ECMA tests disabled, run with --ecma") + if option.collectonly: + return #actually run the file :) t = load_source(self.filepath.read()) try: From fijal at codespeak.net Sun Feb 18 19:27:46 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 18 Feb 2007 19:27:46 +0100 (CET) Subject: [pypy-svn] r39173 - pypy/dist/pypy/lang/js/test/ecma Message-ID: <20070218182746.1E6D6101F3@code0.codespeak.net> Author: fijal Date: Sun Feb 18 19:27:45 2007 New Revision: 39173 Modified: pypy/dist/pypy/lang/js/test/ecma/conftest.py Log: Make tests actually run Modified: pypy/dist/pypy/lang/js/test/ecma/conftest.py ============================================================================== --- pypy/dist/pypy/lang/js/test/ecma/conftest.py (original) +++ pypy/dist/pypy/lang/js/test/ecma/conftest.py Sun Feb 18 19:27:45 2007 @@ -23,6 +23,8 @@ class JSTestFile(py.test.collect.Module): def init_interp(cls): + if hasattr(cls, 'interp'): + return cls.interp = Interpreter() ctx = cls.interp.global_context shellpath = rootdir/'shell.js' @@ -40,6 +42,7 @@ py.test.skip("ECMA tests disabled, run with --ecma") if option.collectonly: return + self.init_interp() #actually run the file :) t = load_source(self.filepath.read()) try: @@ -54,7 +57,7 @@ def join(self, name): return JSTestItem(name, parent = self) -class JSTestItem(py.test.collect.Item): +class JSTestItem(py.test.collect.Function): def __init__(self, name, parent=None): #super(JSTestItem, self).__init__(filepath, parent) self.name = name From santagada at codespeak.net Sun Feb 18 19:44:43 2007 From: santagada at codespeak.net (santagada at codespeak.net) Date: Sun, 18 Feb 2007 19:44:43 +0100 (CET) Subject: [pypy-svn] r39174 - pypy/dist/pypy/lang/js/test/ecma Message-ID: <20070218184443.27482101FA@code0.codespeak.net> Author: santagada Date: Sun Feb 18 19:44:42 2007 New Revision: 39174 Modified: pypy/dist/pypy/lang/js/test/ecma/conftest.py Log: not reading options Modified: pypy/dist/pypy/lang/js/test/ecma/conftest.py ============================================================================== --- pypy/dist/pypy/lang/js/test/ecma/conftest.py (original) +++ pypy/dist/pypy/lang/js/test/ecma/conftest.py Sun Feb 18 19:44:42 2007 @@ -1,7 +1,6 @@ import py from pypy.lang.js.interpreter import * from pypy.lang.js.jsobj import W_Array -from pypy.lang.js.conftest import option rootdir = py.magic.autopath().dirpath() exclusionlist = ['shell.js', 'browser.js'] From santagada at codespeak.net Sun Feb 18 19:49:57 2007 From: santagada at codespeak.net (santagada at codespeak.net) Date: Sun, 18 Feb 2007 19:49:57 +0100 (CET) Subject: [pypy-svn] r39175 - pypy/dist/pypy/lang/js/test/ecma Message-ID: <20070218184957.898CA101FE@code0.codespeak.net> Author: santagada Date: Sun Feb 18 19:49:56 2007 New Revision: 39175 Modified: pypy/dist/pypy/lang/js/test/ecma/conftest.py Log: almost working Modified: pypy/dist/pypy/lang/js/test/ecma/conftest.py ============================================================================== --- pypy/dist/pypy/lang/js/test/ecma/conftest.py (original) +++ pypy/dist/pypy/lang/js/test/ecma/conftest.py Sun Feb 18 19:49:56 2007 @@ -1,6 +1,7 @@ import py from pypy.lang.js.interpreter import * -from pypy.lang.js.jsobj import W_Array +from pypy.lang.js.jsobj import W_Array, JsBaseExcept +from pypy.lang.js.jsparser import JsSyntaxError rootdir = py.magic.autopath().dirpath() exclusionlist = ['shell.js', 'browser.js'] @@ -37,16 +38,16 @@ self.filepath = filepath def run(self): - if not option.ecma: + if not py.test.config.option.ecma: py.test.skip("ECMA tests disabled, run with --ecma") - if option.collectonly: + if py.test.config.option.collectonly: return self.init_interp() #actually run the file :) t = load_source(self.filepath.read()) try: t.execute(self.interp.global_context) - except: + except JsBaseExcept, JsSyntaxError: py.test.fail("Could not load js file") testcases = self.interp.global_context.resolve_identifier('testcases') values = testcases.GetValue().array From fijal at codespeak.net Sun Feb 18 19:51:35 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 18 Feb 2007 19:51:35 +0100 (CET) Subject: [pypy-svn] r39176 - pypy/dist/pypy/lang/js/test/ecma Message-ID: <20070218185135.91BBD10201@code0.codespeak.net> Author: fijal Date: Sun Feb 18 19:51:34 2007 New Revision: 39176 Modified: pypy/dist/pypy/lang/js/test/ecma/conftest.py Log: Common typo Modified: pypy/dist/pypy/lang/js/test/ecma/conftest.py ============================================================================== --- pypy/dist/pypy/lang/js/test/ecma/conftest.py (original) +++ pypy/dist/pypy/lang/js/test/ecma/conftest.py Sun Feb 18 19:51:34 2007 @@ -47,7 +47,7 @@ t = load_source(self.filepath.read()) try: t.execute(self.interp.global_context) - except JsBaseExcept, JsSyntaxError: + except (JsBaseExcept, JsSyntaxError): py.test.fail("Could not load js file") testcases = self.interp.global_context.resolve_identifier('testcases') values = testcases.GetValue().array From hpk at codespeak.net Sun Feb 18 19:56:43 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sun, 18 Feb 2007 19:56:43 +0100 (CET) Subject: [pypy-svn] r39177 - pypy/extradoc/sprintinfo/trillke-2007 Message-ID: <20070218185643.E572510205@code0.codespeak.net> Author: hpk Date: Sun Feb 18 19:56:42 2007 New Revision: 39177 Modified: pypy/extradoc/sprintinfo/trillke-2007/people.txt Log: updated people.txt according to accomodation clarifications, and local sort outs. please check that everything is correct (seperate mail on pypy-sprint follows) Modified: pypy/extradoc/sprintinfo/trillke-2007/people.txt ============================================================================== --- pypy/extradoc/sprintinfo/trillke-2007/people.txt (original) +++ pypy/extradoc/sprintinfo/trillke-2007/people.txt Sun Feb 18 19:56:42 2007 @@ -9,21 +9,24 @@ ==================== ============== ===================== Name Arrive/Depart Accomodation ==================== ============== ===================== -Holger Krekel 25th-5th private -Armin Rigo 26th-? ? Beatrice Duering 25th-3rd Klocke -Carl Friedrich Bolz 25th-5th ? -Lene Wagner 25th-5th private -Michael Hudson 27th-5th no idea -Maciej Fijalkowski 28th-? private -Stephan Diehl 2nd-4th no idea -Antonio Cuni 25th-5th no idea -Samuele Pedroni 25th-5th TBD -Anders Chrigstr?m 25th-5th TBD +Samuele Pedroni 25th-5th Klocke +Anders Chrigstr?m 25th-5th Klocke Christian Tismer 28th-5th Klocke -Alix Einfeldt 25th-5th private -Alexander Schremmer 1st-5th no idea -Guido Wesdorp 26th-5th ? +Anders Sigfridsson 2-4th klocke +Michael Hudson 27th-5th klocke +Antonio Cuni 25th-5th klocke +TAV? 1-4th? undetermined +Stephan Diehl 2nd-4th private/shared alex +Alexander Schremmer 1st-5th private/shared stephan +Maciej Fijalkowski 28-6th+X private +Guido Wesdorp 26th-5th private +Carl Friedrich Bolz 25th-6th private +Armin Rigo 26th-6+X private +Jens-Uwe Mager 1-4th?? private +Holger Krekel 25th-8th private +Alix Einfeldt 25th-8th private +Lene Wagner 25th-8th private ==================== ============== ===================== People on the following list were present at previous sprints: From fijal at codespeak.net Sun Feb 18 19:57:09 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 18 Feb 2007 19:57:09 +0100 (CET) Subject: [pypy-svn] r39178 - pypy/dist/pypy/lang/js/test/ecma Message-ID: <20070218185709.8785D10204@code0.codespeak.net> Author: fijal Date: Sun Feb 18 19:57:07 2007 New Revision: 39178 Modified: pypy/dist/pypy/lang/js/test/ecma/conftest.py Log: Give a bit more detailed info Modified: pypy/dist/pypy/lang/js/test/ecma/conftest.py ============================================================================== --- pypy/dist/pypy/lang/js/test/ecma/conftest.py (original) +++ pypy/dist/pypy/lang/js/test/ecma/conftest.py Sun Feb 18 19:57:07 2007 @@ -1,6 +1,6 @@ import py from pypy.lang.js.interpreter import * -from pypy.lang.js.jsobj import W_Array, JsBaseExcept +from pypy.lang.js.jsobj import W_Array, JsTypeError from pypy.lang.js.jsparser import JsSyntaxError rootdir = py.magic.autopath().dirpath() @@ -47,8 +47,8 @@ t = load_source(self.filepath.read()) try: t.execute(self.interp.global_context) - except (JsBaseExcept, JsSyntaxError): - py.test.fail("Could not load js file") + except (JsTypeError, JsSyntaxError): + raise Failed(excinfo=py.code.ExceptionInfo()) testcases = self.interp.global_context.resolve_identifier('testcases') values = testcases.GetValue().array testcases.PutValue(W_Array(), self.interp.global_context) From santagada at codespeak.net Sun Feb 18 20:02:53 2007 From: santagada at codespeak.net (santagada at codespeak.net) Date: Sun, 18 Feb 2007 20:02:53 +0100 (CET) Subject: [pypy-svn] r39179 - in pypy/dist/pypy/lang/js: . test/ecma Message-ID: <20070218190253.1B04110213@code0.codespeak.net> Author: santagada Date: Sun Feb 18 20:02:51 2007 New Revision: 39179 Modified: pypy/dist/pypy/lang/js/jsobj.py pypy/dist/pypy/lang/js/test/ecma/conftest.py Log: trying to get it to work Modified: pypy/dist/pypy/lang/js/jsobj.py ============================================================================== --- pypy/dist/pypy/lang/js/jsobj.py (original) +++ pypy/dist/pypy/lang/js/jsobj.py Sun Feb 18 20:02:51 2007 @@ -5,18 +5,20 @@ class SeePage(NotImplementedError): pass -class ExecutionReturned(Exception): +class JsBaseExcept(Exception): pass + +class ExecutionReturned(JsBaseExcept): def __init__(self, type='normal', value=None, identifier=None): self.type = type self.value = value self.identifier = identifier -class ThrowException(Exception): +class ThrowException(JsBaseExcept): def __init__(self, exception): self.exception = exception self.args = self.exception -class JsTypeError(Exception): +class JsTypeError(JsBaseExcept): pass Infinity = 1e300 * 1e300 Modified: pypy/dist/pypy/lang/js/test/ecma/conftest.py ============================================================================== --- pypy/dist/pypy/lang/js/test/ecma/conftest.py (original) +++ pypy/dist/pypy/lang/js/test/ecma/conftest.py Sun Feb 18 20:02:51 2007 @@ -61,7 +61,11 @@ def __init__(self, name, parent=None): #super(JSTestItem, self).__init__(filepath, parent) self.name = name - + self.parent = parent + + def startcapture(self): pass + def stopcapture(self): pass + def run(): ctx = JSTestFile.interp.global_context r3 = ctx.resolve_identifier('run_test').GetValue() From santagada at codespeak.net Sun Feb 18 20:05:18 2007 From: santagada at codespeak.net (santagada at codespeak.net) Date: Sun, 18 Feb 2007 20:05:18 +0100 (CET) Subject: [pypy-svn] r39180 - pypy/dist/pypy/lang/js/test/ecma Message-ID: <20070218190518.1404F10217@code0.codespeak.net> Author: santagada Date: Sun Feb 18 20:05:11 2007 New Revision: 39180 Modified: pypy/dist/pypy/lang/js/test/ecma/conftest.py Log: almost working Modified: pypy/dist/pypy/lang/js/test/ecma/conftest.py ============================================================================== --- pypy/dist/pypy/lang/js/test/ecma/conftest.py (original) +++ pypy/dist/pypy/lang/js/test/ecma/conftest.py Sun Feb 18 20:05:11 2007 @@ -59,9 +59,8 @@ class JSTestItem(py.test.collect.Function): def __init__(self, name, parent=None): - #super(JSTestItem, self).__init__(filepath, parent) + super(JSTestItem, self).__init__(name, parent) self.name = name - self.parent = parent def startcapture(self): pass def stopcapture(self): pass From fijal at codespeak.net Sun Feb 18 20:08:43 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 18 Feb 2007 20:08:43 +0100 (CET) Subject: [pypy-svn] r39181 - pypy/dist/pypy/lang/js/test/ecma Message-ID: <20070218190843.18DDB1021A@code0.codespeak.net> Author: fijal Date: Sun Feb 18 20:08:41 2007 New Revision: 39181 Modified: pypy/dist/pypy/lang/js/test/ecma/conftest.py Log: * Use JsBaseExcept * import failed Modified: pypy/dist/pypy/lang/js/test/ecma/conftest.py ============================================================================== --- pypy/dist/pypy/lang/js/test/ecma/conftest.py (original) +++ pypy/dist/pypy/lang/js/test/ecma/conftest.py Sun Feb 18 20:08:41 2007 @@ -1,7 +1,8 @@ import py from pypy.lang.js.interpreter import * -from pypy.lang.js.jsobj import W_Array, JsTypeError +from pypy.lang.js.jsobj import W_Array, JsBaseExcept from pypy.lang.js.jsparser import JsSyntaxError +from py.__.test.outcome import Failed rootdir = py.magic.autopath().dirpath() exclusionlist = ['shell.js', 'browser.js'] @@ -47,7 +48,7 @@ t = load_source(self.filepath.read()) try: t.execute(self.interp.global_context) - except (JsTypeError, JsSyntaxError): + except (JsBaseExcept, JsSyntaxError): raise Failed(excinfo=py.code.ExceptionInfo()) testcases = self.interp.global_context.resolve_identifier('testcases') values = testcases.GetValue().array From rxe at codespeak.net Sun Feb 18 21:42:37 2007 From: rxe at codespeak.net (rxe at codespeak.net) Date: Sun, 18 Feb 2007 21:42:37 +0100 (CET) Subject: [pypy-svn] r39186 - pypy/extradoc/sprintinfo/trillke-2007 Message-ID: <20070218204237.B5D3010211@code0.codespeak.net> Author: rxe Date: Sun Feb 18 21:42:36 2007 New Revision: 39186 Modified: pypy/extradoc/sprintinfo/trillke-2007/people.txt Log: my details - dates/accomodation not finalized yet Modified: pypy/extradoc/sprintinfo/trillke-2007/people.txt ============================================================================== --- pypy/extradoc/sprintinfo/trillke-2007/people.txt (original) +++ pypy/extradoc/sprintinfo/trillke-2007/people.txt Sun Feb 18 21:42:36 2007 @@ -27,6 +27,7 @@ Holger Krekel 25th-8th private Alix Einfeldt 25th-8th private Lene Wagner 25th-8th private +Richard Emslie ?-5th ? ==================== ============== ===================== People on the following list were present at previous sprints: @@ -42,7 +43,6 @@ Boris Feigin ? ? Andrew Thompson ? ? Bert Freudenberg ? ? -Richard Emslie ? ? Johan Hahn ? ? Niko Matsakis ? ? ==================== ============== ===================== From auc at codespeak.net Mon Feb 19 11:42:31 2007 From: auc at codespeak.net (auc at codespeak.net) Date: Mon, 19 Feb 2007 11:42:31 +0100 (CET) Subject: [pypy-svn] r39197 - pypy/dist/pypy/rlib/cslib/test Message-ID: <20070219104231.67BAF10213@code0.codespeak.net> Author: auc Date: Mon Feb 19 11:42:30 2007 New Revision: 39197 Added: pypy/dist/pypy/rlib/cslib/test/ pypy/dist/pypy/rlib/cslib/test/test_cslib.py (contents, props changed) Log: some testing bits Added: pypy/dist/pypy/rlib/cslib/test/test_cslib.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/rlib/cslib/test/test_cslib.py Mon Feb 19 11:42:30 2007 @@ -0,0 +1,95 @@ +import os + +from pypy.rlib import rconstraint as rc, rdomain as rd +from pypy.rlib import rpropagation as rp, rdistributor as rdist + + +def debug(msg): + os.write(2, "debug: " + msg + '\n') + +N = 32 + +def _disp_sols(sols): + for s in sols: + os.write(1, "solution\n") + for var, val in s.items(): + os.write(1, ' %s = %d\n' % (var, val)) + + +def test_binlt(): + "binary exprs and alldistinctness test" + dom = {} + for i in range(N): + dom[i] = True + D1 = rd.BaseFiniteDomain( dom ) + D2 = rd.BaseFiniteDomain( dom ) + vars = ["a", "b"] + constraints = [] + constr = rc.BinLt( vars ) + constr.revise( {"a":D1,"b":D2} ) + constraints.append( constr ) + rep = rp.Repository({"a":D1,"b":D2}, constraints) + sols = rep.solve_all(rdist.DichotomyDistributor()) + + assert len(sols) == N * (N - 1) / 2 + + for s in sols: + a = s['a'] + b = s['b'] + assert a < b + + return 0 + + +def test_alldistinct(): + dom = {} + for i in range(N): + dom[i] = True + D1 = rd.BaseFiniteDomain( dom ) + D2 = rd.BaseFiniteDomain( dom ) + vars = ["a", "b"] + constraints = [] + constr = rc.AllDistinct( vars ) + constr.revise( {"a":D1,"b":D2} ) + constraints.append(constr) + rep = rp.Repository({"a":D1,"b":D2}, constraints) + sols = rep.solve_all(rdist.DichotomyDistributor()) + + assert len(sols) == N * (N - 1) + for s in sols: + a = s['a'] + b = s['b'] + assert a != b + + return 0 + + +class FooConstraint(rc.Expression): + + def filter_func(self, kwargs): + a, b, c = kwargs.values() + return a == b + c + +def test_nary_expr(): + dom = {} + for i in range(N): + dom[i] = True + D1 = rd.BaseFiniteDomain( dom ) + D2 = rd.BaseFiniteDomain( dom ) + D3 = rd.BaseFiniteDomain( dom ) + vars = ["a", "b", "c"] + constraints = [] + constr = FooConstraint( vars ) + constr.revise( {"a":D1,"b":D2, "c":D3} ) + constraints.append(constr) + rep = rp.Repository({"a":D1,"b":D2, "c":D3}, constraints) + sols = rep.solve_all(rdist.DichotomyDistributor()) + + assert len(sols) == N * (N + 1) / 2 + for s in sols: + a = s['a'] + b = s['b'] + c = s['c'] + assert a == b + c + + return 0 From santagada at codespeak.net Mon Feb 19 12:28:42 2007 From: santagada at codespeak.net (santagada at codespeak.net) Date: Mon, 19 Feb 2007 12:28:42 +0100 (CET) Subject: [pypy-svn] r39199 - pypy/dist/pypy/lang/js/test/ecma Message-ID: <20070219112842.1973710223@code0.codespeak.net> Author: santagada Date: Mon Feb 19 12:28:41 2007 New Revision: 39199 Modified: pypy/dist/pypy/lang/js/test/ecma/conftest.py pypy/dist/pypy/lang/js/test/ecma/shell.js Log: tests running Modified: pypy/dist/pypy/lang/js/test/ecma/conftest.py ============================================================================== --- pypy/dist/pypy/lang/js/test/ecma/conftest.py (original) +++ pypy/dist/pypy/lang/js/test/ecma/conftest.py Mon Feb 19 12:28:41 2007 @@ -33,10 +33,10 @@ t.execute(ctx) init_interp = classmethod(init_interp) - def __init__(self, filepath, parent=None): - super(JSTestFile, self).__init__(filepath, parent) - self.name = filepath.purebasename + " JSFILE" - self.filepath = filepath + def __init__(self, fspath, parent=None): + super(JSTestFile, self).__init__(fspath, parent) + self.name = fspath.purebasename + " JSFILE" + self.fspath = fspath def run(self): if not py.test.config.option.ecma: @@ -45,34 +45,40 @@ return self.init_interp() #actually run the file :) - t = load_source(self.filepath.read()) + t = load_source(self.fspath.read()) try: t.execute(self.interp.global_context) except (JsBaseExcept, JsSyntaxError): raise Failed(excinfo=py.code.ExceptionInfo()) testcases = self.interp.global_context.resolve_identifier('testcases') values = testcases.GetValue().array - testcases.PutValue(W_Array(), self.interp.global_context) - return values + self.testcases = testcases + result = [str(i) for i in range(len(values))] + return result def join(self, name): return JSTestItem(name, parent = self) -class JSTestItem(py.test.collect.Function): + def teardown(self): + self.testcases.PutValue(W_Array(), self.interp.global_context) + +class JSTestItem(py.test.collect.Item): def __init__(self, name, parent=None): super(JSTestItem, self).__init__(name, parent) self.name = name - - def startcapture(self): pass - def stopcapture(self): pass - - def run(): + + def run(self): ctx = JSTestFile.interp.global_context r3 = ctx.resolve_identifier('run_test').GetValue() - result = r3.Call(ctx=ctx, args=[name,]).ToNumber() + result = r3.Call(ctx=ctx, args=[W_Number(int(self.name)),]).ToNumber() if result == 0: py.test.fail() elif result == -1: py.test.skip() + _handling_traceback = False + def _getpathlineno(self): + return self.parent.parent.fspath, 0 + + Directory = JSDirectory Modified: pypy/dist/pypy/lang/js/test/ecma/shell.js ============================================================================== --- pypy/dist/pypy/lang/js/test/ecma/shell.js (original) +++ pypy/dist/pypy/lang/js/test/ecma/shell.js Mon Feb 19 12:28:41 2007 @@ -193,17 +193,18 @@ * document.write. */ -function run_test(testnr) { - try - { +function run_test(tc) { + // try + // { + print(tc) getTestCaseResult(testcases[tc].expect, testcases[tc].actual) testcases[tc].reason += ( testcases[tc].passed ) ? "" : "wrong value "; return testcases[tc].passed? 1:0; - } - catch(e) - { - return -1 - } + // } + // catch(e) + // { + // return -1 + // } } function writeTestCaseResult( expect, actual, string ) { var passed = getTestCaseResult( expect, actual ); From ac at codespeak.net Mon Feb 19 12:35:54 2007 From: ac at codespeak.net (ac at codespeak.net) Date: Mon, 19 Feb 2007 12:35:54 +0100 (CET) Subject: [pypy-svn] r39201 - pypy/extradoc/sprintinfo/trillke-2007 Message-ID: <20070219113554.E433610237@code0.codespeak.net> Author: ac Date: Mon Feb 19 12:35:53 2007 New Revision: 39201 Modified: pypy/extradoc/sprintinfo/trillke-2007/people.txt Log: Correct the accomodation for me and Samuele. Modified: pypy/extradoc/sprintinfo/trillke-2007/people.txt ============================================================================== --- pypy/extradoc/sprintinfo/trillke-2007/people.txt (original) +++ pypy/extradoc/sprintinfo/trillke-2007/people.txt Mon Feb 19 12:35:53 2007 @@ -10,8 +10,8 @@ Name Arrive/Depart Accomodation ==================== ============== ===================== Beatrice Duering 25th-3rd Klocke -Samuele Pedroni 25th-5th Klocke -Anders Chrigstr?m 25th-5th Klocke +Samuele Pedroni 25th-5th Parkhotel Bergh?lzchen +Anders Chrigstr?m 25th-5th Parkhotel Bergh?lzchen Christian Tismer 28th-5th Klocke Anders Sigfridsson 2-4th klocke Michael Hudson 27th-5th klocke From auc at codespeak.net Mon Feb 19 15:07:01 2007 From: auc at codespeak.net (auc at codespeak.net) Date: Mon, 19 Feb 2007 15:07:01 +0100 (CET) Subject: [pypy-svn] r39205 - pypy/dist/pypy/lib/pyontology/test Message-ID: <20070219140701.6790510256@code0.codespeak.net> Author: auc Date: Mon Feb 19 15:06:59 2007 New Revision: 39205 Modified: pypy/dist/pypy/lib/pyontology/test/test_ontology.py Log: make this use cslib Modified: pypy/dist/pypy/lib/pyontology/test/test_ontology.py ============================================================================== --- pypy/dist/pypy/lib/pyontology/test/test_ontology.py (original) +++ pypy/dist/pypy/lib/pyontology/test/test_ontology.py Mon Feb 19 15:06:59 2007 @@ -1,747 +1,803 @@ # tests for the Ontology class +import autopath import py +from pypy.conftest import gettestobjspace try: - import logilab.constraint + #import logilab.constraint import rdflib except ImportError: import py - py.test.skip("Logilab.constraint and/or rdflib not installed") + py.test.skip("rdflib not installed") -from pypy.lib.pyontology.pyontology import * # Ontology, ClassDomain, SubClassConstraint +#from pypy.lib.pyontology.pyontology import * # Ontology, ClassDomain, SubClassConstraint from rdflib import Graph, URIRef, BNode UR = URIRef -def rdf_list(ont, name, data): - owllist = URIRef(name) - obj = URIRef(namespaces['rdf']+'#List') - ont.type(owllist, obj) - own =owllist - for i,dat in enumerate(data[:-1]): - next = BNode( name + str(i)) - next,i,dat,own - ont.first(own, dat) - ont.type(next, obj) - ont.rest(own, next) - own = next - ont.first(own, data[-1]) - ont.rest(own, URIRef(namespaces['rdf']+'#nil')) - return owllist - -def test_equivalentProperty_inconst(): - O = Ontology() - O.add_file("testinconst.rdf") - O.attach_fd() - raises(ConsistencyFailure, O.consistency) - -def test_XMLSchema_string(): - O = Ontology() - a = URIRef(u'A') - p = URIRef(u'P') - prop = URIRef(namespaces['rdf']+'#Property') - xml_string_uri = URIRef(namespaces['xmlschema']+"#string") - O.type(p, prop) - O.consider_triple((a, p, rdflib_literal("ddd", datatype=xml_string_uri))) - O.range(p, xml_string_uri) - O.consistency() - -def test_XMLSchema_string_fail(): -# py.test.skip("WIP") - O = Ontology() - a = URIRef(u'A') - p = URIRef(u'P') - prop = URIRef(namespaces['rdf']+'#Property') - xml_string_uri = URIRef(namespaces['xmlschema']+"#string") - xml_int_uri= URIRef(namespaces['xmlschema']+"#integer") - O.type(p, prop) - O.consider_triple((a, p, rdflib_literal(2, datatype = xml_int_uri))) - O.range(p, xml_string_uri) - raises(ConsistencyFailure, O.consistency) - -def test_makevar(): - O = Ontology() - var = URIRef(u'http://www.w3.org/2002/03owlt/unionOf/premises004#A-and-B') - name = O.make_var(ClassDomain, var) - cod = name+' = 1' - exec cod - assert O.make_var(None, var) in locals() - assert isinstance(O.variables[name], ClassDomain) - -def test_subClassof(): - O = Ontology() - a = URIRef(u'A') - b = URIRef(u'B') - c = URIRef(u'C') - O.subClassOf(b, a) - O.subClassOf(c, b) - obj = URIRef(namespaces['owl']+'#Class') - O.type(a,obj) - O.consistency() - O.subClassOf(c, a) - O.consistency() - -def test_subClassof2(): - O = Ontology() - a = URIRef(u'A') - b = URIRef(u'B') - c = URIRef(u'C') - d = URIRef(u'D') - O.subClassOf(b, a) - O.subClassOf(c, b) - obj = URIRef(namespaces['owl']+'#Class') - O.type(a,obj) - O.type(d,c) - O.consistency() - d_indi = O.mangle_name(d) - assert Individual(d_indi, d) in O.variables[O.mangle_name(a)].getValues() - O.subClassOf(c, a) - O.consistency() - -def test_addvalue(): - O = Ontology() - a = O.make_var(Property, URIRef('a')) - O.variables[a].addValue('key', 42) - assert ('key', 42) in O.variables[a] - O.variables[a].addValue('key', 43) - assert list(O.variables[a].getValues()) == [('key', 42), ('key', 43)] - -def no_test_ClassDomain(): - a = ClassDomain() - cls = 1 - b = ClassDomain('B',[],[a]) - assert b in b - assert a in b - -def test_subClassconstraint(): - a = ClassDomain('A') - b = ClassDomain('B') - c = ClassDomain('C') - con = SubClassConstraint('b','a') - con2 = SubClassConstraint('c','b') - indi = URIRef('indi') - c.setValues([Individual('indi_',indi)]) - con.narrow({'a': a, 'b': b, 'c': c}) - con2.narrow({'a': a, 'b': b, 'c': c}) - con.narrow({'a': a, 'b': b, 'c': c}) - assert Individual('indi_', indi) in a - -def test_subClassconstraintMulti(): - a = ClassDomain('A') - b = ClassDomain('B') - c = ClassDomain('C') - indi = URIRef('indi') - c.setValues([Individual('indi_',indi)]) - con = SubClassConstraint('c','a') - con2 = SubClassConstraint('c','b') - con.narrow({'a': a, 'b': b, 'c': c}) - con2.narrow({'a': a, 'b': b, 'c': c}) - assert Individual('indi_', indi) in a - assert Individual('indi_', indi) in b - -def test_subClassconstraintMulti2(): - a = ClassDomain('A') - b = ClassDomain('B') - c = ClassDomain('C') - indi = URIRef('indi') - c.setValues([Individual('indi_',indi)]) - con = SubClassConstraint('c','a') - con2 = SubClassConstraint('c','b') - con3 = SubClassConstraint('a','c') - con.narrow({'a': a, 'b': b, 'c': c}) - con2.narrow({'a': a, 'b': b, 'c': c}) - con3.narrow({'a': a, 'b': b, 'c': c}) - assert Individual('indi_', indi) in a - assert Individual('indi_', indi) in b - assert Individual('indi_', indi) in c - -def test_equivalentClass(): - O = Ontology() - a = O.make_var(ClassDomain,URIRef('A')) - b = O.make_var(ClassDomain,URIRef('B')) - c = O.make_var(ClassDomain,URIRef('C')) - O.equivalentClass(c, a) - O.equivalentClass(c, b) - A = O.make_var(ClassDomain, a) - B = O.make_var(ClassDomain, b) - assert O.variables[A].values == O.variables[B].values - -def test_type(): - sub = URIRef('a') - pred = URIRef('type') - obj = URIRef('o') - O = Ontology() - O.make_var(ClassDomain, obj) - O.type(sub, obj) - O.type(obj, namespaces['owl']+"#Class") - - assert list(O.variables[O.make_var(None, obj)].getValues())[0].__class__ == Individual - -# test for multiple types -# test for type hierarchy - -def test_ObjectProperty(): - sub = URIRef('a') - obj = URIRef(namespaces['owl']+'#ObjectProperty') - O = Ontology() - O.type(sub, obj) - assert O.variables[O.make_var(None, sub)].__class__ == ObjectProperty - -def test_range(): - O = Ontology() - sub = URIRef('a') - obj = URIRef('b') - O.variables['b_'] = ClassDomain(values=[1,2,3,4]) - O.range(sub, obj) - sub = URIRef('a') - pred = URIRef('type') - obj = URIRef(namespaces['owl']+'#ObjectProperty') - O.type(sub, obj) - #assert len(O.constraints) == 1 - O.constraints[0].narrow(O.variables) - -def test_merge(): - O = Ontology() - sub = URIRef('a') - obj = URIRef('b') - O.variables['b_'] = ClassDomain(values=[1,2,3,4]) - O.range(sub, obj) - obj = URIRef('c') - O.variables['c_'] = ClassDomain(values=[3,4,5,6]) - O.range(sub, obj) - sub = URIRef('a') - pred = URIRef('type') - obj = URIRef(namespaces['owl']+'#ObjectProperty') - O.type(sub, obj) - #assert len(O.constraints) == 2 - O.consistency() - -def test_domain(): - O = Ontology() - sub = URIRef('a') - obj = URIRef('b') - O.variables['b_'] = ClassDomain('b') - O.domain(sub, obj) - sub = URIRef('a') - pred = URIRef('type') - obj = URIRef(namespaces['owl']+'#ObjectProperty') - O.type(sub, obj) - #assert len(O.constraints) == 1 - O.constraints[0].narrow(O.variables) - -def test_domain_merge(): - O = Ontology() - sub = URIRef('a') - obj = URIRef('b') - O.variables['b_'] = ClassDomain('b') - O.domain(sub, obj) - obj = URIRef('c') - O.variables['c_'] = ClassDomain('c') - O.domain(sub, obj) - obj = URIRef(namespaces['owl']+'#ObjectProperty') - O.type(sub, obj) - - #assert len(O.constraints) == 2 - for con in O.constraints: - con.narrow(O.variables) - assert O.variables['a_'].size() == 0 - -def test_subproperty(): - O = Ontology() - sub = URIRef('a') - obj = URIRef(namespaces['owl']+'#ObjectProperty') - O.type(sub, obj) - b = URIRef('b') - O.type(b, obj) - O.variables['a_'].setValues([('individ_',42)]) - O.subPropertyOf(sub, b) - O.consistency() - for val in O.variables['a_'].getValues(): - assert val in O.variables['b_'] - -def test_functionalproperty(): - - O = Ontology() - #Make functional property - sub = URIRef('p') - obj = URIRef(namespaces['owl']+'#FunctionalProperty') - O.type(sub, obj) - #Make class - sub = URIRef('c') - obj = URIRef(namespaces['owl']+'#Class') - O.type(sub, obj) - #Make individual with a value of the property - sub = URIRef('individ') - obj = URIRef('c') - O.type(sub, obj) - O.variables['p_'].setValues([('individ',42)]) - #add another valueof the property - O.variables['p_'].addValue('individ',43) - py.test.raises(ConsistencyFailure, O.consistency ) - #check that consistency raises - -def test_inversefunctionalproperty(): - - O = Ontology() - #Make functional property - sub = URIRef('p') - obj = URIRef(namespaces['owl']+'#InverseFunctionalProperty') - O.type(sub, obj) - #Make class - sub = URIRef('c') - obj = URIRef(namespaces['owl']+'#Class') - O.type(sub, obj) - #Make individual with a value of the property - sub = URIRef('individ') - obj = URIRef('c') - O.type(sub, obj) - O.variables['p_'].setValues([('individ_',42)]) - #assert len(O.constraints) == 2 - #add another individual with the same value for the property - sub = URIRef('individ2') - obj = URIRef('c') - O.type(sub, obj) - py.test.raises(ConsistencyFailure, O.variables['p_'].setValues, [('individ_',42),('individ2_',42)]) - -def test_Transitiveproperty(): - O = Ontology() - #Make functional property - subreg = URIRef('subRegionOf') - obj = URIRef(namespaces['owl']+'#TransitiveProperty') - O.type(subreg, obj) - #Make class - sub = URIRef('c') - obj = URIRef(namespaces['owl']+'#Class') - O.type(sub, obj) - #Make individual with a value of the property - it = URIRef('Italy') - obj = URIRef('c') - O.type(it, obj) - tus = URIRef('Tuscanny') - O.type(tus, obj) - chi = URIRef('Chianti') - O.type(chi, obj) -# O.variables['subRegionOf_'].setValues([('Italy_','Tuscanny_'),('Tuscanny_','Chianti_')]) - O.consider_triple((tus, subreg, it)) - O.consider_triple((chi, subreg, tus)) - O.consistency() - assert Individual('Italy_', it) in O.variables['subRegionOf_'].getValuesPrKey(Individual('Chianti',chi)) - -def test_symmetricproperty(): - O = Ontology() - #Make functional property - sub = URIRef('friend') - obj = URIRef(namespaces['owl']+'#SymmetricProperty') - O.type(sub, obj) - assert O.variables[O.make_var(None, sub)].__class__.__name__=='SymmetricProperty' - #Make class - sub = URIRef('c') - obj = URIRef(namespaces['owl']+'#Class') - O.type(sub, obj) - #Make individual with a value of the property - sub = URIRef('Bob') - obj = URIRef('c') - O.type(sub, obj) - sub = URIRef('Alice') - O.type(sub, obj) - O.variables['friend_'].setValues([('Bob_','Alice_')]) - O.consistency() - assert ('Alice_', 'Bob_') in O.variables['friend_'] - -def test_inverseof(): - O = Ontology() - own = URIRef('owner') - obj = URIRef(namespaces['owl']+'#ObjectProperty') - O.type(own, obj) - owned = URIRef('ownedby') - obj = URIRef(namespaces['owl']+'#ObjectProperty') - O.type(owned, obj) - #Make class - sub = URIRef('c') - obj = URIRef(namespaces['owl']+'#Class') - O.type(sub, obj) - #Make individual with a property value - sub = URIRef('Bob') - obj = URIRef('c') - O.type(sub, obj) - sub = URIRef('Fiat') - obj = URIRef('car') - O.type(sub, obj) - O.variables['owner_'].setValues([('Bob_','Fiat_')]) - O.inverseOf(own, owned) - O.consistency() - assert ('Fiat_','Bob_') in O.variables['ownedby_'] - -def test_hasvalue(): - # py.test.skip("") - O = Ontology() - cls = URIRef('class') - obj = URIRef(namespaces['owl']+'#Thing') - O.type(cls, obj) - restrict = BNode('anon1') - obj = URIRef(namespaces['owl']+'#Restriction') - O.type(restrict, obj) - p = URIRef('p') - obj = URIRef(namespaces['owl']+'#ObjectProperty') - O.type(p, obj) - O.consider_triple((cls, p, 2)) - O.onProperty(restrict,p) - O.consider_triple((cls, p, 1)) - O.hasValue(restrict, 2) -# O.type(2, URIRef(namespaces['owl']+'#Thing')) -# O.type(1, URIRef(namespaces['owl']+'#Thing')) - - cls2 = URIRef('class2') - obj = URIRef(namespaces['owl']+'#Thing') - O.type(cls2, obj) - O.subClassOf(cls2,restrict) - O.variables[O.make_var(None, cls2)].finish(O.variables, O.constraints) - O.consistency() - assert cls in O.variables[O.make_var(None, cls2)] -# py.test.raises(ConsistencyFailure, O.consistency) - -def test_List(): - py.test.skip("Need to be rewritten using RDF-XML") - O = Ontology() - own = URIRef('favlist') - obj = URIRef(namespaces['rdf']+'#List') - O.type(own, obj) - O.first(own, 0) - O.rest(own, URIRef('1')) - O.first( URIRef('1'), 1) - O.rest( URIRef('1'), URIRef('2')) - O.first( URIRef('2'), 2) - O.rest( URIRef('2'), URIRef(namespaces['rdf']+'#nil')) - O.flatten_rdf_list(own) - O.consistency() - assert list(O.rep._domains['favlist_'].getValues()) == [0,1,2] - -def test_oneofclassenumeration(): - O = Ontology() - restrict = BNode('anon') - own = [UR('first'), UR('second'), UR('third')] - O.oneOf(restrict, own) - O.type(restrict, UR(namespaces['owl']+'#Class')) - O.consistency() - assert O.rep._domains[restrict].size()== 3 - assert set(O.rep._domains[restrict].getValues()) == set(own) - -def test_unification_of_two_oneofclassenumeration(): - O = Ontology() - restrict = BNode('anon') - own = [UR('first'), UR('second'), UR('third')] - for i in own: - O.type(i,UR(namespaces['owl']+'#Thing')) - O.oneOf(restrict, own) - restrict1 = BNode('anon1') - own = [UR('second'), UR('third'), UR('first')] - O.oneOf(restrict1, own) - O.type(UR('test'), UR(namespaces['owl']+'#Thing')) - O.type(UR('test'), restrict) - O.type(UR('test'), restrict1) - O.consistency() - assert O.rep._domains[restrict].size() == 3 - assert set(O.rep._domains[restrict].getValues()) == set(own) - - -def test_oneofdatarange(): - O = Ontology() - restrict = BNode('anon') - own = ['1','2','3'] - O.oneOf(restrict, own) - O.type(restrict, UR(namespaces['owl']+'#DataRange')) - O.consistency() - assert O.rep._domains[restrict].size() == 3 - assert set(O.rep._domains[restrict].getValues()) == set(own) - -def test_somevaluesfrom_datarange(): - py.test.skip("reconsider if the test is correct - make it simpler") - O = Ontology() - datarange = BNode('anon') - own = ['1','2','3'] - O.oneOf(datarange, own) - O.type(datarange, namespaces['owl']+'#DataRange') - restrict = BNode('anon1') - obj = URIRef(namespaces['owl']+'#Restriction') - O.type(restrict, obj) - p = URIRef('p') - obj = URIRef(namespaces['owl']+'#ObjectProperty') - O.type(p, obj) - cls = URIRef('class') - obj = URIRef(namespaces['owl']+'#Class') - O.type(cls, obj) - O.variables['p_'].setValues([(cls,'1')]) - O.onProperty(restrict,p) - O.someValuesFrom(restrict, datarange) - O.subClassOf(cls,restrict) - O.consistency() - assert cls in O.variables[O.make_var(None, cls)] - -def test_allvaluesfrom_datarange(): - py.test.skip("") - O = Ontology() - datarange = BNode('anon') - own = ['1','2','3'] - O.oneOf(datarange, own) - O.type(datarange, namespaces['owl']+'#DataRange') - restrict = BNode('anon1') - obj = URIRef(namespaces['owl']+'#Restriction') - O.type(restrict, obj) - p = URIRef('p') - obj = URIRef(namespaces['owl']+'#ObjectProperty') - O.type(p, obj) - cls = URIRef('class') - O.variables['p_'].setValues([(cls,'1'),(cls,'2'),(cls,'3')]) - obj = URIRef(namespaces['owl']+'#Class') - O.type(cls, obj) - O.onProperty(restrict,p) - O.allValuesFrom(restrict, datarange) - O.subClassOf(cls,restrict) - assert cls in O.variables[O.make_var(None, cls)] - -def test_unionof(): - #py.test.skip("Rewrite the test") - O = Ontology() - cls = BNode('anon') - own1 = BNode('liist1') - own2 = BNode('liist2') - list1 = ['1', '2', '3'] - list2 = ['3', '4', '5'] - own = [own1, own2] - O.oneOf( own1, list1) - O.oneOf( own2, list2) - O.unionOf(cls, own) - O.type(cls, namespaces['owl']+'#Class') - O.consistency() - res = list(O.rep._domains[cls].getValues()) - res.sort() - assert set(res) == set([Individual(x,x) for x in ['1', '2', '3', '4', '5']]) - -def test_intersectionof(): - py.test.skip("Rewrite the test") - O = Ontology() - cls = BNode('anon') - O.intersectionOf(cls, [['1','2','3'],['3','4','5']]) - O.type(cls, namespaces['owl']+'#Class') - O.consistency() - assert list(O.rep._domains[cls].getValues()) == ['3'] - -def test_differentfrom(): - O = Ontology() - cls = BNode('anon') - own1 = BNode('liist1') - own2 = BNode('liist2') - O.differentFrom(cls, own1) - O.differentFrom(own1, own2) - O.differentFrom(cls, own2) - O.differentFrom(own2,cls) - O.type(cls, UR(namespaces['owl']+'#Thing')) - O.type(own1, UR(namespaces['owl']+'#Thing')) - O.type(own2, UR(namespaces['owl']+'#Thing')) - O.consistency() - #assert len(O.rep._constraints) == 4 - -def test_differentfromconsistency(): - O = Ontology() - cls = BNode('anon') - O.differentFrom(cls, cls) - O.type(cls, UR(namespaces['owl']+'#Thing')) - py.test.raises(ConsistencyFailure, O.consistency) - -def test_sameas(): - O = Ontology() - cls = BNode('anon') - own1 = BNode('liist1') - own2 = BNode('liist2') - O.sameAs(cls, own1) - O.sameAs(own1, own2) - O.sameAs(cls, own2) - O.type(cls, UR(namespaces['owl']+'#Thing')) - O.type(own1, UR(namespaces['owl']+'#Thing')) - O.type(own2, UR(namespaces['owl']+'#Thing')) - sub = URIRef('a') - obj = URIRef(namespaces['owl']+'#ObjectProperty') - O.type(sub, obj) - O.variables[O.make_var(None,sub)].setValues([(cls,'1')]) - O.consistency() - assert ('liist1','1') in O.rep._domains[O.make_var(None,sub)] - -def test_sameasconsistency(): - O = Ontology() - cls = BNode('anon') - own1 = BNode('liist1') - O.sameAs(cls, own1) - O.type(cls, UR(namespaces['owl']+'#Thing')) - O.type(own1, UR(namespaces['owl']+'#Thing')) - sub = URIRef('a') - obj = URIRef(namespaces['owl']+'#ObjectProperty') - O.type(sub, obj) - O.variables[O.make_var(None,sub)].setValues([(cls,'1'), (own1,'2')]) - py.test.raises(ConsistencyFailure, O.consistency) - - -def test_terminology_cardinality(): - # Modeled after one of the standard tests (approved/maxCardinality) - # 'cls' by subclassing two maxCardinality restrictions becomes the set of - # individuals satisfying both restriction, ie having exactly 2 values of - # predicate p - cls = URIRef('cls') - O = Ontology() - O.add((cls, UR(namespaces['rdf']+'#type'), UR(namespaces['owl']+'#Class'))) - p = O.make_var(Property,URIRef('p')) - p = URIRef('p') - O.add((p, UR(namespaces['rdf']+'#type'), UR(namespaces['owl']+'#ObjectProperty'))) - - restr = BNode('anon') - O.add((restr, UR(namespaces['rdf']+'#type'), UR(namespaces['owl']+'#Restriction') )) - O.add((restr, UR(namespaces['owl']+'#onProperty'), p )) - O.add((cls, UR(namespaces['rdfs']+'#subClassOf'),restr )) - O.add((restr, UR(namespaces['owl']+'#maxCardinality'), 2 )) - - restr2 = BNode('anon2') - O.add((restr2, UR(namespaces['rdf']+'#type'), UR(namespaces['owl']+'#Restriction') )) - O.add((restr2, UR(namespaces['owl']+'#onProperty'), p )) - O.add((cls, UR(namespaces['rdfs']+'#subClassOf'),restr2 )) - O.add((restr2, UR(namespaces['owl']+'#minCardinality'), 3 )) - O.attach_fd() - for var in O.variables.values(): - var.finish(O.variables, O.constraints) - py.test.raises(ConsistencyFailure, O.consistency) - -def test_terminology_subclassof_cardinality(): - cls = URIRef('cls') - cls2 = URIRef('cls2') - O = Ontology() - O.add((cls, UR(namespaces['rdfs']+'#type'), UR(namespaces['owl']+'#Class'))) - O.add((cls2, UR(namespaces['rdfs']+'#type'), UR(namespaces['owl']+'#Class'))) - p = O.make_var(Property,URIRef('p')) - p = URIRef('p') - O.add((p, UR(namespaces['rdfs']+'#type'), UR(namespaces['owl']+'#ObjectProperty'))) - - restr = BNode('anon') - O.add((restr, UR(namespaces['rdfs']+'#type'), UR(namespaces['owl']+'#Restriction'))) - O.add((restr, UR(namespaces['rdfs']+'#onProperty'), p )) - O.add((cls, UR(namespaces['rdfs']+'#subClassOf'),restr )) - O.add((restr, UR(namespaces['rdfs']+'#maxCardinality'), 2 )) - - restr2 = BNode('anon2') - O.add((restr2, UR(namespaces['rdfs']+'#type'), UR(namespaces['owl']+'#Restriction'))) - O.add((restr2, UR(namespaces['rdfs']+'#onProperty'), p )) - O.add((cls, UR(namespaces['rdfs']+'#subClassOf'),restr2 )) - O.add((restr2, UR(namespaces['rdfs']+'#minCardinality'), 3 )) - O.add((cls2, UR(namespaces['rdfs']+'#subClassOf'), cls )) - O.attach_fd() - for var in O.variables.values(): - var.finish(O.variables, O.constraints) - py.test.raises(ConsistencyFailure, O.consistency) - -def test_add_file(): - O = Ontology() - O.add_file('premises001.rdf') - trip = list(O.graph.triples((None,)*3)) -# O.attach_fd() - ll = len(O.variables) - l = len(trip) - O.add_file('conclusions001.rdf') - O.attach_fd() - lll = len(O.variables) - assert len(list(O.graph.triples((None,)*3))) > l - -def test_more_cardinality(): - O = Ontology() - O.add_file('premises003.rdf') - trip = list(O.graph.triples((None,)*3)) - # O.attach_fd() - ll = len(O.variables) - l = len(trip) - O.add_file('conclusions003.rdf') - O.attach_fd() - O.consistency() - lll = len(O.variables) - assert len(list(O.graph.triples((None,)*3))) > l - -def test_import(): - O = Ontology() - s = URIRef('s') - O.imports(s,URIRef('http://www.w3.org/2002/03owlt/imports/support001-A')) - -def test_complementof(): - O = Ontology() - a_cls = URIRef('a') - b_cls = URIRef('b') - O.type(a_cls, URIRef(namespaces['owl']+'#Class')) - O.type(b_cls, URIRef(namespaces['owl']+'#Class')) - O.oneOf(a_cls, [URIRef('i1'), URIRef('i2'), URIRef('i3'), URIRef('i4')]) - for i in ['i1', 'i2', 'i3', 'i4']: - O.type(URIRef(i), URIRef(namespaces['owl']+'#Thing')) - O.type(URIRef('i5'), URIRef(namespaces['owl']+'#Thing')) - O.complementOf(b_cls, a_cls) - O.consistency() - assert list(O.variables[O.make_var(None, b_cls)].getValues()) == ['i5'] - -def test_complementof_raise(): - O = Ontology() - a_cls = URIRef('a') - b_cls = URIRef('b') - O.type(a_cls, URIRef(namespaces['owl']+'#Class')) - O.type(b_cls, URIRef(namespaces['owl']+'#Class')) - O.oneOf(a_cls, [URIRef('i1'), URIRef('i2'), URIRef('i3'), URIRef('i4')]) - for i in ['i1', 'i2', 'i3', 'i4']: - O.type(URIRef(i), URIRef(namespaces['owl']+'#Thing')) - O.type(URIRef('i5'), URIRef(namespaces['owl']+'#Thing')) - O.type(URIRef('i4'), b_cls) - O.type(URIRef('i4'), a_cls) - O.complementOf(b_cls, a_cls) - # The above ontology states that 'b' is complement of 'a'. But that leads - # to an inconsistency as 'i4' is of type 'a' and 'b' - raises(ConsistencyFailure, O.consistency) - -def test_class_promotion(): - O = Ontology() - a_cls = URIRef('a') - O.type(a_cls, URIRef(namespaces['owl']+'#Class')) - - assert isinstance(O.variables['a_'], ClassDomain) - O.type(a_cls, URIRef(namespaces['owl']+'#Restriction')) - assert isinstance(O.variables['a_'], Restriction) - -def test_class_demotion(): - O = Ontology() - a_cls = URIRef('a') - O.type(a_cls, URIRef(namespaces['owl']+'#Restriction')) - O.variables[O.make_var(None, a_cls)].property = "SomeProp" - assert isinstance(O.variables['a_'], Restriction) - - O.type(a_cls, URIRef(namespaces['owl']+'#Class')) - - assert isinstance(O.variables['a_'], Restriction) - assert O.variables[O.make_var(None, a_cls)].property == "SomeProp" - -def test_property_to_objectproperty(): - O = Ontology() - a_cls = URIRef('a') - O.type(a_cls, URIRef(namespaces['rdf']+'#Property')) - assert isinstance(O.variables['a_'], Property) - O.type(a_cls, URIRef(namespaces['owl']+'#ObjectProperty')) - assert isinstance(O.variables['a_'], Property) - - O.type(a_cls, URIRef(namespaces['rdf']+'#Property')) - - assert isinstance(O.variables['a_'], ObjectProperty) - -def test_individual(): - # test comparison (unknown, equal, different) - O = Ontology() - first = URIRef('first') - second = URIRef('second') - O.type(first, URIRef(namespaces['owl']+'#Thing')) - assert isinstance(list(O.variables['owl_Thing'].getValues())[0], Individual) - -def test_recording_of_properties(): - O = Ontology() - first = URIRef('first') - second = URIRef('second') -# O.type(first, URIRef(namespaces['owl']+'#SymmetricProperty')) - O.consider_triple((first, URIRef(namespaces['rdf']+'#type'), URIRef(namespaces['owl']+'#SymmetricProperty'))) - assert isinstance(O.variables['first_'], SymmetricProperty) - assert 'first_' in O.variables['owl_ObjectProperty'] #.getValues() - assert 'first_' in O.variables['rdf_Property'] # .getValues() + +class TestAppOntology: + + def setup_class(cls): + space = gettestobjspace(usemodules=('_cslib',)) + cls.space = space + + def rdf_list(self, ont, name, data): + owllist = URIRef(name) + obj = URIRef(namespaces['rdf']+'#List') + ont.type(owllist, obj) + own =owllist + for i,dat in enumerate(data[:-1]): + next = BNode( name + str(i)) + next,i,dat,own + ont.first(own, dat) + ont.type(next, obj) + ont.rest(own, next) + own = next + ont.first(own, data[-1]) + ont.rest(own, URIRef(namespaces['rdf']+'#nil')) + return owllist + + def test_equivalentProperty_inconst(self): + from pypy.lib.pyontology.pyontology import * + O = Ontology() + O.add_file("testinconst.rdf") + O.attach_fd() + raises(ConsistencyFailure, O.consistency) + + def test_XMLSchema_string(self): + from pypy.lib.pyontology.pyontology import * + O = Ontology() + a = URIRef(u'A') + p = URIRef(u'P') + prop = URIRef(namespaces['rdf']+'#Property') + xml_string_uri = URIRef(namespaces['xmlschema']+"#string") + O.type(p, prop) + O.consider_triple((a, p, rdflib_literal("ddd", datatype=xml_string_uri))) + O.range(p, xml_string_uri) + O.consistency() + + def test_XMLSchema_string_fail(self): + # py.test.skip("WIP") + from pypy.lib.pyontology.pyontology import * + O = Ontology() + a = URIRef(u'A') + p = URIRef(u'P') + prop = URIRef(namespaces['rdf']+'#Property') + xml_string_uri = URIRef(namespaces['xmlschema']+"#string") + xml_int_uri= URIRef(namespaces['xmlschema']+"#integer") + O.type(p, prop) + O.consider_triple((a, p, rdflib_literal(2, datatype = xml_int_uri))) + O.range(p, xml_string_uri) + raises(ConsistencyFailure, O.consistency) + + def test_makevar(self): + from pypy.lib.pyontology.pyontology import * + O = Ontology() + var = URIRef(u'http://www.w3.org/2002/03owlt/unionOf/premises004#A-and-B') + name = O.make_var(ClassDomain, var) + cod = name+' = 1' + exec cod + assert O.make_var(None, var) in locals() + assert isinstance(O.variables[name], ClassDomain) + + def test_subClassof(self): + from pypy.lib.pyontology.pyontology import * + O = Ontology() + a = URIRef(u'A') + b = URIRef(u'B') + c = URIRef(u'C') + O.subClassOf(b, a) + O.subClassOf(c, b) + obj = URIRef(namespaces['owl']+'#Class') + O.type(a,obj) + O.consistency() + O.subClassOf(c, a) + O.consistency() + + def test_subClassof2(self): + from pypy.lib.pyontology.pyontology import * + O = Ontology() + a = URIRef(u'A') + b = URIRef(u'B') + c = URIRef(u'C') + d = URIRef(u'D') + O.subClassOf(b, a) + O.subClassOf(c, b) + obj = URIRef(namespaces['owl']+'#Class') + O.type(a,obj) + O.type(d,c) + O.consistency() + d_indi = O.mangle_name(d) + assert Individual(d_indi, d) in O.variables[O.mangle_name(a)].getValues() + O.subClassOf(c, a) + O.consistency() + + def test_addvalue(self): + from pypy.lib.pyontology.pyontology import * + O = Ontology() + a = O.make_var(Property, URIRef('a')) + O.variables[a].addValue('key', 42) + assert ('key', 42) in O.variables[a] + O.variables[a].addValue('key', 43) + assert list(O.variables[a].getValues()) == [('key', 42), ('key', 43)] + + def no_test_ClassDomain(self): + from pypy.lib.pyontology.pyontology import * + a = ClassDomain() + cls = 1 + b = ClassDomain('B',[],[a]) + assert b in b + assert a in b + + def test_subClassconstraint(self): + from pypy.lib.pyontology.pyontology import * + a = ClassDomain('A') + b = ClassDomain('B') + c = ClassDomain('C') + con = SubClassConstraint('b','a') + con2 = SubClassConstraint('c','b') + indi = URIRef('indi') + c.setValues([Individual('indi_',indi)]) + con.narrow({'a': a, 'b': b, 'c': c}) + con2.narrow({'a': a, 'b': b, 'c': c}) + con.narrow({'a': a, 'b': b, 'c': c}) + assert Individual('indi_', indi) in a + + def test_subClassconstraintMulti(self): + from pypy.lib.pyontology.pyontology import * + a = ClassDomain('A') + b = ClassDomain('B') + c = ClassDomain('C') + indi = URIRef('indi') + c.setValues([Individual('indi_',indi)]) + con = SubClassConstraint('c','a') + con2 = SubClassConstraint('c','b') + con.narrow({'a': a, 'b': b, 'c': c}) + con2.narrow({'a': a, 'b': b, 'c': c}) + assert Individual('indi_', indi) in a + assert Individual('indi_', indi) in b + + def test_subClassconstraintMulti2(self): + from pypy.lib.pyontology.pyontology import * + a = ClassDomain('A') + b = ClassDomain('B') + c = ClassDomain('C') + indi = URIRef('indi') + c.setValues([Individual('indi_',indi)]) + con = SubClassConstraint('c','a') + con2 = SubClassConstraint('c','b') + con3 = SubClassConstraint('a','c') + con.narrow({'a': a, 'b': b, 'c': c}) + con2.narrow({'a': a, 'b': b, 'c': c}) + con3.narrow({'a': a, 'b': b, 'c': c}) + assert Individual('indi_', indi) in a + assert Individual('indi_', indi) in b + assert Individual('indi_', indi) in c + + def test_equivalentClass(self): + from pypy.lib.pyontology.pyontology import * + O = Ontology() + a = O.make_var(ClassDomain,URIRef('A')) + b = O.make_var(ClassDomain,URIRef('B')) + c = O.make_var(ClassDomain,URIRef('C')) + O.equivalentClass(c, a) + O.equivalentClass(c, b) + A = O.make_var(ClassDomain, a) + B = O.make_var(ClassDomain, b) + assert O.variables[A].values == O.variables[B].values + + def test_type(self): + from pypy.lib.pyontology.pyontology import * + sub = URIRef('a') + pred = URIRef('type') + obj = URIRef('o') + O = Ontology() + O.make_var(ClassDomain, obj) + O.type(sub, obj) + O.type(obj, namespaces['owl']+"#Class") + + assert list(O.variables[O.make_var(None, obj)].getValues())[0].__class__ == Individual + + # test for multiple types + # test for type hierarchy + + def test_ObjectProperty(self): + from pypy.lib.pyontology.pyontology import * + sub = URIRef('a') + obj = URIRef(namespaces['owl']+'#ObjectProperty') + O = Ontology() + O.type(sub, obj) + assert O.variables[O.make_var(None, sub)].__class__ == ObjectProperty + + def test_range(self): + from pypy.lib.pyontology.pyontology import * + O = Ontology() + sub = URIRef('a') + obj = URIRef('b') + O.variables['b_'] = ClassDomain(values=[1,2,3,4]) + O.range(sub, obj) + sub = URIRef('a') + pred = URIRef('type') + obj = URIRef(namespaces['owl']+'#ObjectProperty') + O.type(sub, obj) + #assert len(O.constraints) == 1 + O.constraints[0].narrow(O.variables) + + def test_merge(self): + from pypy.lib.pyontology.pyontology import * + O = Ontology() + sub = URIRef('a') + obj = URIRef('b') + O.variables['b_'] = ClassDomain(values=[1,2,3,4]) + O.range(sub, obj) + obj = URIRef('c') + O.variables['c_'] = ClassDomain(values=[3,4,5,6]) + O.range(sub, obj) + sub = URIRef('a') + pred = URIRef('type') + obj = URIRef(namespaces['owl']+'#ObjectProperty') + O.type(sub, obj) + #assert len(O.constraints) == 2 + O.consistency() + + def test_domain(self): + from pypy.lib.pyontology.pyontology import * + O = Ontology() + sub = URIRef('a') + obj = URIRef('b') + O.variables['b_'] = ClassDomain('b') + O.domain(sub, obj) + sub = URIRef('a') + pred = URIRef('type') + obj = URIRef(namespaces['owl']+'#ObjectProperty') + O.type(sub, obj) + #assert len(O.constraints) == 1 + O.constraints[0].narrow(O.variables) + + def test_domain_merge(self): + from pypy.lib.pyontology.pyontology import * + O = Ontology() + sub = URIRef('a') + obj = URIRef('b') + O.variables['b_'] = ClassDomain('b') + O.domain(sub, obj) + obj = URIRef('c') + O.variables['c_'] = ClassDomain('c') + O.domain(sub, obj) + obj = URIRef(namespaces['owl']+'#ObjectProperty') + O.type(sub, obj) + + #assert len(O.constraints) == 2 + for con in O.constraints: + con.narrow(O.variables) + assert O.variables['a_'].size() == 0 + + def test_subproperty(self): + from pypy.lib.pyontology.pyontology import * + O = Ontology() + sub = URIRef('a') + obj = URIRef(namespaces['owl']+'#ObjectProperty') + O.type(sub, obj) + b = URIRef('b') + O.type(b, obj) + O.variables['a_'].setValues([('individ_',42)]) + O.subPropertyOf(sub, b) + O.consistency() + for val in O.variables['a_'].getValues(): + assert val in O.variables['b_'] + + def test_functionalproperty(self): + from pypy.lib.pyontology.pyontology import * + O = Ontology() + #Make functional property + sub = URIRef('p') + obj = URIRef(namespaces['owl']+'#FunctionalProperty') + O.type(sub, obj) + #Make class + sub = URIRef('c') + obj = URIRef(namespaces['owl']+'#Class') + O.type(sub, obj) + #Make individual with a value of the property + sub = URIRef('individ') + obj = URIRef('c') + O.type(sub, obj) + O.variables['p_'].setValues([('individ',42)]) + #add another valueof the property + O.variables['p_'].addValue('individ',43) + py.test.raises(ConsistencyFailure, O.consistency ) + #check that consistency raises + + def test_inversefunctionalproperty(self): + from pypy.lib.pyontology.pyontology import * + O = Ontology() + #Make functional property + sub = URIRef('p') + obj = URIRef(namespaces['owl']+'#InverseFunctionalProperty') + O.type(sub, obj) + #Make class + sub = URIRef('c') + obj = URIRef(namespaces['owl']+'#Class') + O.type(sub, obj) + #Make individual with a value of the property + sub = URIRef('individ') + obj = URIRef('c') + O.type(sub, obj) + O.variables['p_'].setValues([('individ_',42)]) + #assert len(O.constraints) == 2 + #add another individual with the same value for the property + sub = URIRef('individ2') + obj = URIRef('c') + O.type(sub, obj) + py.test.raises(ConsistencyFailure, O.variables['p_'].setValues, [('individ_',42),('individ2_',42)]) + + def test_Transitiveproperty(self): + from pypy.lib.pyontology.pyontology import * + O = Ontology() + #Make functional property + subreg = URIRef('subRegionOf') + obj = URIRef(namespaces['owl']+'#TransitiveProperty') + O.type(subreg, obj) + #Make class + sub = URIRef('c') + obj = URIRef(namespaces['owl']+'#Class') + O.type(sub, obj) + #Make individual with a value of the property + it = URIRef('Italy') + obj = URIRef('c') + O.type(it, obj) + tus = URIRef('Tuscanny') + O.type(tus, obj) + chi = URIRef('Chianti') + O.type(chi, obj) + # O.variables['subRegionOf_'].setValues([('Italy_','Tuscanny_'),('Tuscanny_','Chianti_')]) + O.consider_triple((tus, subreg, it)) + O.consider_triple((chi, subreg, tus)) + O.consistency() + assert Individual('Italy_', it) in O.variables['subRegionOf_'].getValuesPrKey(Individual('Chianti',chi)) + + def test_symmetricproperty(self): + from pypy.lib.pyontology.pyontology import * + O = Ontology() + #Make functional property + sub = URIRef('friend') + obj = URIRef(namespaces['owl']+'#SymmetricProperty') + O.type(sub, obj) + assert O.variables[O.make_var(None, sub)].__class__.__name__=='SymmetricProperty' + #Make class + sub = URIRef('c') + obj = URIRef(namespaces['owl']+'#Class') + O.type(sub, obj) + #Make individual with a value of the property + sub = URIRef('Bob') + obj = URIRef('c') + O.type(sub, obj) + sub = URIRef('Alice') + O.type(sub, obj) + O.variables['friend_'].setValues([('Bob_','Alice_')]) + O.consistency() + assert ('Alice_', 'Bob_') in O.variables['friend_'] + + def test_inverseof(self): + from pypy.lib.pyontology.pyontology import * + O = Ontology() + own = URIRef('owner') + obj = URIRef(namespaces['owl']+'#ObjectProperty') + O.type(own, obj) + owned = URIRef('ownedby') + obj = URIRef(namespaces['owl']+'#ObjectProperty') + O.type(owned, obj) + #Make class + sub = URIRef('c') + obj = URIRef(namespaces['owl']+'#Class') + O.type(sub, obj) + #Make individual with a property value + sub = URIRef('Bob') + obj = URIRef('c') + O.type(sub, obj) + sub = URIRef('Fiat') + obj = URIRef('car') + O.type(sub, obj) + O.variables['owner_'].setValues([('Bob_','Fiat_')]) + O.inverseOf(own, owned) + O.consistency() + assert ('Fiat_','Bob_') in O.variables['ownedby_'] + + def test_hasvalue(self): + # py.test.skip("") + from pypy.lib.pyontology.pyontology import * + O = Ontology() + cls = URIRef('class') + obj = URIRef(namespaces['owl']+'#Thing') + O.type(cls, obj) + restrict = BNode('anon1') + obj = URIRef(namespaces['owl']+'#Restriction') + O.type(restrict, obj) + p = URIRef('p') + obj = URIRef(namespaces['owl']+'#ObjectProperty') + O.type(p, obj) + O.consider_triple((cls, p, 2)) + O.onProperty(restrict,p) + O.consider_triple((cls, p, 1)) + O.hasValue(restrict, 2) + # O.type(2, URIRef(namespaces['owl']+'#Thing')) + # O.type(1, URIRef(namespaces['owl']+'#Thing')) + + cls2 = URIRef('class2') + obj = URIRef(namespaces['owl']+'#Thing') + O.type(cls2, obj) + O.subClassOf(cls2,restrict) + O.variables[O.make_var(None, cls2)].finish(O.variables, O.constraints) + O.consistency() + assert cls in O.variables[O.make_var(None, cls2)] + # py.test.raises(ConsistencyFailure, O.consistency) + + def test_List(self): + py.test.skip("Need to be rewritten using RDF-XML") + from pypy.lib.pyontology.pyontology import * + O = Ontology() + own = URIRef('favlist') + obj = URIRef(namespaces['rdf']+'#List') + O.type(own, obj) + O.first(own, 0) + O.rest(own, URIRef('1')) + O.first( URIRef('1'), 1) + O.rest( URIRef('1'), URIRef('2')) + O.first( URIRef('2'), 2) + O.rest( URIRef('2'), URIRef(namespaces['rdf']+'#nil')) + O.flatten_rdf_list(own) + O.consistency() + assert list(O.rep._domains['favlist_'].getValues()) == [0,1,2] + + def test_oneofclassenumeration(self): + from pypy.lib.pyontology.pyontology import * + O = Ontology() + restrict = BNode('anon') + own = [UR('first'), UR('second'), UR('third')] + O.oneOf(restrict, own) + O.type(restrict, UR(namespaces['owl']+'#Class')) + O.consistency() + assert O.rep._domains[restrict].size()== 3 + assert set(O.rep._domains[restrict].getValues()) == set(own) + + def test_unification_of_two_oneofclassenumeration(self): + from pypy.lib.pyontology.pyontology import * + O = Ontology() + restrict = BNode('anon') + own = [UR('first'), UR('second'), UR('third')] + for i in own: + O.type(i,UR(namespaces['owl']+'#Thing')) + O.oneOf(restrict, own) + restrict1 = BNode('anon1') + own = [UR('second'), UR('third'), UR('first')] + O.oneOf(restrict1, own) + O.type(UR('test'), UR(namespaces['owl']+'#Thing')) + O.type(UR('test'), restrict) + O.type(UR('test'), restrict1) + O.consistency() + assert O.rep._domains[restrict].size() == 3 + assert set(O.rep._domains[restrict].getValues()) == set(own) + + + def test_oneofdatarange(self): + from pypy.lib.pyontology.pyontology import * + O = Ontology() + restrict = BNode('anon') + own = ['1','2','3'] + O.oneOf(restrict, own) + O.type(restrict, UR(namespaces['owl']+'#DataRange')) + O.consistency() + assert O.rep._domains[restrict].size() == 3 + assert set(O.rep._domains[restrict].getValues()) == set(own) + + def test_somevaluesfrom_datarange(self): + py.test.skip("reconsider if the test is correct - make it simpler") + from pypy.lib.pyontology.pyontology import * + O = Ontology() + datarange = BNode('anon') + own = ['1','2','3'] + O.oneOf(datarange, own) + O.type(datarange, namespaces['owl']+'#DataRange') + restrict = BNode('anon1') + obj = URIRef(namespaces['owl']+'#Restriction') + O.type(restrict, obj) + p = URIRef('p') + obj = URIRef(namespaces['owl']+'#ObjectProperty') + O.type(p, obj) + cls = URIRef('class') + obj = URIRef(namespaces['owl']+'#Class') + O.type(cls, obj) + O.variables['p_'].setValues([(cls,'1')]) + O.onProperty(restrict,p) + O.someValuesFrom(restrict, datarange) + O.subClassOf(cls,restrict) + O.consistency() + assert cls in O.variables[O.make_var(None, cls)] + + def test_allvaluesfrom_datarange(self): + py.test.skip("") + from pypy.lib.pyontology.pyontology import * + O = Ontology() + datarange = BNode('anon') + own = ['1','2','3'] + O.oneOf(datarange, own) + O.type(datarange, namespaces['owl']+'#DataRange') + restrict = BNode('anon1') + obj = URIRef(namespaces['owl']+'#Restriction') + O.type(restrict, obj) + p = URIRef('p') + obj = URIRef(namespaces['owl']+'#ObjectProperty') + O.type(p, obj) + cls = URIRef('class') + O.variables['p_'].setValues([(cls,'1'),(cls,'2'),(cls,'3')]) + obj = URIRef(namespaces['owl']+'#Class') + O.type(cls, obj) + O.onProperty(restrict,p) + O.allValuesFrom(restrict, datarange) + O.subClassOf(cls,restrict) + assert cls in O.variables[O.make_var(None, cls)] + + def test_unionof(self): + #py.test.skip("Rewrite the test") + from pypy.lib.pyontology.pyontology import * + O = Ontology() + cls = BNode('anon') + own1 = BNode('liist1') + own2 = BNode('liist2') + list1 = ['1', '2', '3'] + list2 = ['3', '4', '5'] + own = [own1, own2] + O.oneOf( own1, list1) + O.oneOf( own2, list2) + O.unionOf(cls, own) + O.type(cls, namespaces['owl']+'#Class') + O.consistency() + res = list(O.rep._domains[cls].getValues()) + res.sort() + assert set(res) == set([Individual(x,x) for x in ['1', '2', '3', '4', '5']]) + + def test_intersectionof(self): + py.test.skip("Rewrite the test") + from pypy.lib.pyontology.pyontology import * + O = Ontology() + cls = BNode('anon') + O.intersectionOf(cls, [['1','2','3'],['3','4','5']]) + O.type(cls, namespaces['owl']+'#Class') + O.consistency() + assert list(O.rep._domains[cls].getValues()) == ['3'] + + def test_differentfrom(self): + from pypy.lib.pyontology.pyontology import * + O = Ontology() + cls = BNode('anon') + own1 = BNode('liist1') + own2 = BNode('liist2') + O.differentFrom(cls, own1) + O.differentFrom(own1, own2) + O.differentFrom(cls, own2) + O.differentFrom(own2,cls) + O.type(cls, UR(namespaces['owl']+'#Thing')) + O.type(own1, UR(namespaces['owl']+'#Thing')) + O.type(own2, UR(namespaces['owl']+'#Thing')) + O.consistency() + #assert len(O.rep._constraints) == 4 + + def test_differentfromconsistency(self): + from pypy.lib.pyontology.pyontology import * + O = Ontology() + cls = BNode('anon') + O.differentFrom(cls, cls) + O.type(cls, UR(namespaces['owl']+'#Thing')) + py.test.raises(ConsistencyFailure, O.consistency) + + def test_sameas(self): + from pypy.lib.pyontology.pyontology import * + O = Ontology() + cls = BNode('anon') + own1 = BNode('liist1') + own2 = BNode('liist2') + O.sameAs(cls, own1) + O.sameAs(own1, own2) + O.sameAs(cls, own2) + O.type(cls, UR(namespaces['owl']+'#Thing')) + O.type(own1, UR(namespaces['owl']+'#Thing')) + O.type(own2, UR(namespaces['owl']+'#Thing')) + sub = URIRef('a') + obj = URIRef(namespaces['owl']+'#ObjectProperty') + O.type(sub, obj) + O.variables[O.make_var(None,sub)].setValues([(cls,'1')]) + O.consistency() + assert ('liist1','1') in O.rep._domains[O.make_var(None,sub)] + + def test_sameasconsistency(self): + from pypy.lib.pyontology.pyontology import * + O = Ontology() + cls = BNode('anon') + own1 = BNode('liist1') + O.sameAs(cls, own1) + O.type(cls, UR(namespaces['owl']+'#Thing')) + O.type(own1, UR(namespaces['owl']+'#Thing')) + sub = URIRef('a') + obj = URIRef(namespaces['owl']+'#ObjectProperty') + O.type(sub, obj) + O.variables[O.make_var(None,sub)].setValues([(cls,'1'), (own1,'2')]) + py.test.raises(ConsistencyFailure, O.consistency) + + + def test_terminology_cardinality(self): + # Modeled after one of the standard tests (approved/maxCardinality) + # 'cls' by subclassing two maxCardinality restrictions becomes the set of + # individuals satisfying both restriction, ie having exactly 2 values of + # predicate p + from pypy.lib.pyontology.pyontology import * + cls = URIRef('cls') + O = Ontology() + O.add((cls, UR(namespaces['rdf']+'#type'), UR(namespaces['owl']+'#Class'))) + p = O.make_var(Property,URIRef('p')) + p = URIRef('p') + O.add((p, UR(namespaces['rdf']+'#type'), UR(namespaces['owl']+'#ObjectProperty'))) + + restr = BNode('anon') + O.add((restr, UR(namespaces['rdf']+'#type'), UR(namespaces['owl']+'#Restriction') )) + O.add((restr, UR(namespaces['owl']+'#onProperty'), p )) + O.add((cls, UR(namespaces['rdfs']+'#subClassOf'),restr )) + O.add((restr, UR(namespaces['owl']+'#maxCardinality'), 2 )) + + restr2 = BNode('anon2') + O.add((restr2, UR(namespaces['rdf']+'#type'), UR(namespaces['owl']+'#Restriction') )) + O.add((restr2, UR(namespaces['owl']+'#onProperty'), p )) + O.add((cls, UR(namespaces['rdfs']+'#subClassOf'),restr2 )) + O.add((restr2, UR(namespaces['owl']+'#minCardinality'), 3 )) + O.attach_fd() + for var in O.variables.values(): + var.finish(O.variables, O.constraints) + py.test.raises(ConsistencyFailure, O.consistency) + + def test_terminology_subclassof_cardinality(self): + from pypy.lib.pyontology.pyontology import * + cls = URIRef('cls') + cls2 = URIRef('cls2') + O = Ontology() + O.add((cls, UR(namespaces['rdfs']+'#type'), UR(namespaces['owl']+'#Class'))) + O.add((cls2, UR(namespaces['rdfs']+'#type'), UR(namespaces['owl']+'#Class'))) + p = O.make_var(Property,URIRef('p')) + p = URIRef('p') + O.add((p, UR(namespaces['rdfs']+'#type'), UR(namespaces['owl']+'#ObjectProperty'))) + + restr = BNode('anon') + O.add((restr, UR(namespaces['rdfs']+'#type'), UR(namespaces['owl']+'#Restriction'))) + O.add((restr, UR(namespaces['rdfs']+'#onProperty'), p )) + O.add((cls, UR(namespaces['rdfs']+'#subClassOf'),restr )) + O.add((restr, UR(namespaces['rdfs']+'#maxCardinality'), 2 )) + + restr2 = BNode('anon2') + O.add((restr2, UR(namespaces['rdfs']+'#type'), UR(namespaces['owl']+'#Restriction'))) + O.add((restr2, UR(namespaces['rdfs']+'#onProperty'), p )) + O.add((cls, UR(namespaces['rdfs']+'#subClassOf'),restr2 )) + O.add((restr2, UR(namespaces['rdfs']+'#minCardinality'), 3 )) + O.add((cls2, UR(namespaces['rdfs']+'#subClassOf'), cls )) + O.attach_fd() + for var in O.variables.values(): + var.finish(O.variables, O.constraints) + py.test.raises(ConsistencyFailure, O.consistency) + + def test_add_file(self): + from pypy.lib.pyontology.pyontology import * + O = Ontology() + O.add_file('premises001.rdf') + trip = list(O.graph.triples((None,)*3)) + # O.attach_fd() + ll = len(O.variables) + l = len(trip) + O.add_file('conclusions001.rdf') + O.attach_fd() + lll = len(O.variables) + assert len(list(O.graph.triples((None,)*3))) > l + + def test_more_cardinality(self): + from pypy.lib.pyontology.pyontology import * + O = Ontology() + O.add_file('premises003.rdf') + trip = list(O.graph.triples((None,)*3)) + # O.attach_fd() + ll = len(O.variables) + l = len(trip) + O.add_file('conclusions003.rdf') + O.attach_fd() + O.consistency() + lll = len(O.variables) + assert len(list(O.graph.triples((None,)*3))) > l + + def test_import(self): + from pypy.lib.pyontology.pyontology import * + O = Ontology() + s = URIRef('s') + O.imports(s,URIRef('http://www.w3.org/2002/03owlt/imports/support001-A')) + + def test_complementof(self): + from pypy.lib.pyontology.pyontology import * + O = Ontology() + a_cls = URIRef('a') + b_cls = URIRef('b') + O.type(a_cls, URIRef(namespaces['owl']+'#Class')) + O.type(b_cls, URIRef(namespaces['owl']+'#Class')) + O.oneOf(a_cls, [URIRef('i1'), URIRef('i2'), URIRef('i3'), URIRef('i4')]) + for i in ['i1', 'i2', 'i3', 'i4']: + O.type(URIRef(i), URIRef(namespaces['owl']+'#Thing')) + O.type(URIRef('i5'), URIRef(namespaces['owl']+'#Thing')) + O.complementOf(b_cls, a_cls) + O.consistency() + assert list(O.variables[O.make_var(None, b_cls)].getValues()) == ['i5'] + + def test_complementof_raise(self): + from pypy.lib.pyontology.pyontology import * + O = Ontology() + a_cls = URIRef('a') + b_cls = URIRef('b') + O.type(a_cls, URIRef(namespaces['owl']+'#Class')) + O.type(b_cls, URIRef(namespaces['owl']+'#Class')) + O.oneOf(a_cls, [URIRef('i1'), URIRef('i2'), URIRef('i3'), URIRef('i4')]) + for i in ['i1', 'i2', 'i3', 'i4']: + O.type(URIRef(i), URIRef(namespaces['owl']+'#Thing')) + O.type(URIRef('i5'), URIRef(namespaces['owl']+'#Thing')) + O.type(URIRef('i4'), b_cls) + O.type(URIRef('i4'), a_cls) + O.complementOf(b_cls, a_cls) + # The above ontology states that 'b' is complement of 'a'. But that leads + # to an inconsistency as 'i4' is of type 'a' and 'b' + raises(ConsistencyFailure, O.consistency) + + def test_class_promotion(self): + from pypy.lib.pyontology.pyontology import * + O = Ontology() + a_cls = URIRef('a') + O.type(a_cls, URIRef(namespaces['owl']+'#Class')) + + assert isinstance(O.variables['a_'], ClassDomain) + O.type(a_cls, URIRef(namespaces['owl']+'#Restriction')) + assert isinstance(O.variables['a_'], Restriction) + + def test_class_demotion(self): + from pypy.lib.pyontology.pyontology import * + O = Ontology() + a_cls = URIRef('a') + O.type(a_cls, URIRef(namespaces['owl']+'#Restriction')) + O.variables[O.make_var(None, a_cls)].property = "SomeProp" + assert isinstance(O.variables['a_'], Restriction) + + O.type(a_cls, URIRef(namespaces['owl']+'#Class')) + + assert isinstance(O.variables['a_'], Restriction) + assert O.variables[O.make_var(None, a_cls)].property == "SomeProp" + + def test_property_to_objectproperty(self): + from pypy.lib.pyontology.pyontology import * + O = Ontology() + a_cls = URIRef('a') + O.type(a_cls, URIRef(namespaces['rdf']+'#Property')) + assert isinstance(O.variables['a_'], Property) + O.type(a_cls, URIRef(namespaces['owl']+'#ObjectProperty')) + assert isinstance(O.variables['a_'], Property) + + O.type(a_cls, URIRef(namespaces['rdf']+'#Property')) + + assert isinstance(O.variables['a_'], ObjectProperty) + + def test_individual(self): + # test comparison (unknown, equal, different) + from pypy.lib.pyontology.pyontology import * + O = Ontology() + first = URIRef('first') + second = URIRef('second') + O.type(first, URIRef(namespaces['owl']+'#Thing')) + assert isinstance(list(O.variables['owl_Thing'].getValues())[0], Individual) + + def test_recording_of_properties(self): + from pypy.lib.pyontology.pyontology import * + O = Ontology() + first = URIRef('first') + second = URIRef('second') + # O.type(first, URIRef(namespaces['owl']+'#SymmetricProperty')) + O.consider_triple((first, URIRef(namespaces['rdf']+'#type'), URIRef(namespaces['owl']+'#SymmetricProperty'))) + assert isinstance(O.variables['first_'], SymmetricProperty) + assert 'first_' in O.variables['owl_ObjectProperty'] #.getValues() + assert 'first_' in O.variables['rdf_Property'] # .getValues() From mwh at codespeak.net Mon Feb 19 15:49:25 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Mon, 19 Feb 2007 15:49:25 +0100 (CET) Subject: [pypy-svn] r39210 - pypy/branch/ast-experiments/pypy/module/recparser/test Message-ID: <20070219144925.ACBDA101B6@code0.codespeak.net> Author: mwh Date: Mon Feb 19 15:49:22 2007 New Revision: 39210 Modified: pypy/branch/ast-experiments/pypy/module/recparser/test/test_dyn_grammarrules.py Log: fix shallow failures in test_dyn_grammarrules.py Modified: pypy/branch/ast-experiments/pypy/module/recparser/test/test_dyn_grammarrules.py ============================================================================== --- pypy/branch/ast-experiments/pypy/module/recparser/test/test_dyn_grammarrules.py (original) +++ pypy/branch/ast-experiments/pypy/module/recparser/test/test_dyn_grammarrules.py Mon Feb 19 15:49:22 2007 @@ -1,7 +1,12 @@ +from pypy.conftest import gettestobjspace + class AppTest_InsertGrammarRules: + def setup_class(cls): + space = gettestobjspace(usemodules=('dyngram', 'recparser')) + cls.space = space def test_do_while(self): - import parser + import dyngram, parser newrules = """ compound_stmt: if_stmt | on_stmt | unless_stmt | dountil_stmt | while_stmt | for_stmt | try_stmt | with_stmt | funcdef | classdef @@ -40,10 +45,10 @@ test = parser.ASTIf([(parser.ASTName(varname), suite)], else_, items[0].lineno) return parser.ASTStmt([assign, test], items[0].lineno) - parser.insert_grammar_rule(newrules, {'dountil_stmt' : build_dountil_stmt, - 'unless_stmt': build_unless_stmt, - 'on_stmt' : build_on_stmt, - }) + dyngram.insert_grammar_rule(newrules, {'dountil_stmt' : build_dountil_stmt, + 'unless_stmt': build_unless_stmt, + 'on_stmt' : build_on_stmt, + }) # now we should be able to use do...until and unless statements d = {} From auc at codespeak.net Mon Feb 19 17:03:21 2007 From: auc at codespeak.net (auc at codespeak.net) Date: Mon, 19 Feb 2007 17:03:21 +0100 (CET) Subject: [pypy-svn] r39211 - pypy/dist/pypy/lib/pyontology Message-ID: <20070219160321.8FF611025E@code0.codespeak.net> Author: auc Date: Mon Feb 19 17:03:19 2007 New Revision: 39211 Modified: pypy/dist/pypy/lib/pyontology/pyontology.py Log: accepts cslib Modified: pypy/dist/pypy/lib/pyontology/pyontology.py ============================================================================== --- pypy/dist/pypy/lib/pyontology/pyontology.py (original) +++ pypy/dist/pypy/lib/pyontology/pyontology.py Mon Feb 19 17:03:19 2007 @@ -1,10 +1,15 @@ -import autopath -from rdflib import Graph, URIRef, BNode, Literal as rdflib_literal -from logilab.constraint import Repository -from logilab.constraint.fd import FiniteDomain as fd +#import autopath +try: + from cslib import Repository + from cslib.fd import FiniteDomain as fd + print 'using pypy.lib.cslib' +except ImportError: + print 'using logilab.constraint' + from logilab.constraint import Repository + from logilab.constraint.fd import FiniteDomain as fd from logilab.constraint.propagation import AbstractDomain, AbstractConstraint,\ - ConsistencyFailure -from pypy.lib.pyontology.sparql_grammar import SPARQLGrammar as SP + ConsistencyFailure +from pyontology.sparql_grammar import SPARQLGrammar as SP # name clash ? from constraint_classes import * Solver = MySolver Expression = MyExpression @@ -16,6 +21,9 @@ py.log.setconsumer("Pyontology", None) #py.log.setconsumer("Pyontology", ansi_log) +from rdflib import Graph, URIRef, BNode, Literal as rdflib_literal + + namespaces = { 'rdf' : 'http://www.w3.org/1999/02/22-rdf-syntax-ns', 'rdfs' : 'http://www.w3.org/2000/01/rdf-schema', From guido at codespeak.net Mon Feb 19 22:02:29 2007 From: guido at codespeak.net (guido at codespeak.net) Date: Mon, 19 Feb 2007 22:02:29 +0100 (CET) Subject: [pypy-svn] r39218 - in pypy/branch/guido-buildtool-web/pypy/tool/build: . web web/templates web/test Message-ID: <20070219210229.E668B10284@code0.codespeak.net> Author: guido Date: Mon Feb 19 22:02:27 2007 New Revision: 39218 Modified: pypy/branch/guido-buildtool-web/pypy/tool/build/build.py pypy/branch/guido-buildtool-web/pypy/tool/build/web/app.py pypy/branch/guido-buildtool-web/pypy/tool/build/web/server.py pypy/branch/guido-buildtool-web/pypy/tool/build/web/templates/buildersinfo.html pypy/branch/guido-buildtool-web/pypy/tool/build/web/test/test_app.py pypy/branch/guido-buildtool-web/pypy/tool/build/web/test/test_server.py Log: Added id() method to BuildRequest that returns a consistent, reproducable (but hopefully still unique enough) ID for that BuildRequest, so the web app can link to it etc., removed the Resource base class, now the Resources are plain callables (that must have a .exposed attribute set to True), probably fixed HEAD support. Modified: pypy/branch/guido-buildtool-web/pypy/tool/build/build.py ============================================================================== --- pypy/branch/guido-buildtool-web/pypy/tool/build/build.py (original) +++ pypy/branch/guido-buildtool-web/pypy/tool/build/build.py Mon Feb 19 22:02:27 2007 @@ -147,6 +147,13 @@ build_end_time: %(build_end_time)s """ % self.todict() + def id(self): + # XXX can this be made better? we certainly don't want clashes :| + str = '%r\n%r\n%r\n%r\n%r' % (self.email, self.sysinfo, + self.compileinfo, self.svnurl, + self.svnrev) + return '%s.%s' % (self.request_time, py.std.md5.new(str).hexdigest()) + def _fromstring(cls, s): data = {} for line in s.strip().split('\n'): Modified: pypy/branch/guido-buildtool-web/pypy/tool/build/web/app.py ============================================================================== --- pypy/branch/guido-buildtool-web/pypy/tool/build/web/app.py (original) +++ pypy/branch/guido-buildtool-web/pypy/tool/build/web/app.py Mon Feb 19 22:02:27 2007 @@ -7,8 +7,7 @@ from pypy.tool.build import config from pypy.tool.build import execnetconference from pypy.tool.build.build import BuildRequest -from pypy.tool.build.web.server import HTTPError, Resource, Collection, \ - Handler, FsFile +from pypy.tool.build.web.server import HTTPError, Collection, Handler, FsFile from templess import templess @@ -19,17 +18,10 @@ '"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">\n%s' % ( html.strip().encode('UTF-8'),)) -class IndexPage(Resource): - """ the index page """ - def handle(self, handler, path, query): - template = templess.template( - mypath.join('templates/index.html').read()) - return ({'Content-Type': 'text/html; charset=UTF-8'}, - fix_html(template.unicode({}))) - -class ServerPage(Resource): +class ServerPage(object): """ base class for pages that communicate with the server """ + exposed = True def __init__(self, config, gateway=None): self.config = config @@ -71,7 +63,7 @@ class ServerStatusPage(ServerPage): """ a page displaying overall meta server statistics """ - def handle(self, handler, path, query): + def __call__(self, handler, path, query): template = templess.template( mypath.join('templates/serverstatus.html').read()) return ({'Content-Type': 'text/html; charset=UTF-8'}, @@ -81,7 +73,7 @@ return self.call_method('status') class BuildersInfoPage(ServerPage): - def handle(self, handler, path, query): + def __call__(self, handler, path, query): template = templess.template( mypath.join('templates/buildersinfo.html').read()) return ({'Content-Type': 'text/html; charset=UTF-8'}, @@ -95,7 +87,11 @@ binfo['sysinfo'] = [binfo['sysinfo']] if binfo['busy_on']: b = binfo['busy_on'] - d = BuildRequest.fromstring(binfo['busy_on']).todict() + req = BuildRequest.fromstring(binfo['busy_on']) + id = req.id() + d = req.todict() + d['id'] = id + d['href'] = '/builds/%s' % (id,) d.pop('sysinfo', None) # same as builder d.pop('build_end_time', None) # it's still busy ;) # templess doesn't understand dicts this way... @@ -115,13 +111,13 @@ super(BuildPage, self).__init__(config, gateway) self._buildid = buildid - def handle(self, handler, path, query): + def __call__(self, handler, path, query): pass class BuildsIndexPage(ServerPage): """ display the list of available builds """ - def handle(self, handler, path, query): + def __call__(self, handler, path, query): template = templess.template( mypath.join('templates/builds.html').read()) return ({'Content-Type': 'text/html; charset=UTF-8'}, @@ -153,11 +149,17 @@ class Application(Collection): """ the application root """ - index = IndexPage() style = FsFile(mypath.join('theme/style.css'), 'text/css') serverstatus = ServerStatusPage(config) buildersinfo = BuildersInfoPage(config) builds = Builds(config) + + def index(self, handler, path, query): + template = templess.template( + mypath.join('templates/index.html').read()) + return ({'Content-Type': 'text/html; charset=UTF-8'}, + fix_html(template.unicode({}))) + index.exposed = True class AppHandler(Handler): application = Application() Modified: pypy/branch/guido-buildtool-web/pypy/tool/build/web/server.py ============================================================================== --- pypy/branch/guido-buildtool-web/pypy/tool/build/web/server.py (original) +++ pypy/branch/guido-buildtool-web/pypy/tool/build/web/server.py Mon Feb 19 22:02:27 2007 @@ -1,3 +1,5 @@ +import sys +import traceback from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler # some generic stuff to make working with BaseHTTPServer a bit nicer... @@ -36,28 +38,18 @@ data = ' (%s)' % (self.data,) return '' % (self.status, self.message, data) -class Resource(object): - """ an HTTP resource - - essentially this is an object with a path that does not end on a slash, - and no support for PATH_INFO - """ - - def handle(self, handler, path, query): - """ handle a single request to self - - returns a tuple (content_type, data) where data is either a string - (non-unicode!) or a file-like object with a read() method that - accepts an integer (size) argument - """ - raise NotImplemented('abstract base class') - -class Collection(Resource): +class Collection(object): """ an HTTP collection essentially this is a container object that has a path that ends on a slash, and support for PATH_INFO (so can have (virtual or not) children) + + children are callable attributes of ourselves that have an 'exposed' + attribute themselves, that accept 3 arguments: 'handler', a reference + to the BaseHTTPHandler that handles the request (XXX should be + abstracted?), 'path', the requested path to the object, and 'query', + the (unparsed!) GET query string (without a preceding ?) """ def traverse(self, path, orgpath): @@ -72,7 +64,7 @@ a lookup on self, if that fails a 404 is raised, if successful the item is used to continue traversal (if the object found is a Collection type) or to handle the request (if the object found - is a Resource type) + is a callable with .exposed set to True) if path equals '', a lookup for 'index' is done @@ -83,7 +75,9 @@ if name == '': name = 'index' resource = getattr(self, name, None) - if resource is None or not isinstance(resource, Resource): + if (resource is None or (not isinstance(resource, Collection) and + (not callable(resource) or + not getattr(resource, 'exposed', True)))): raise HTTPError(404) if path: if not isinstance(resource, Collection): @@ -93,6 +87,9 @@ if isinstance(resource, Collection): # targeting a collection directly: redirect to its 'index' raise HTTPError(301, orgpath + '/') + if not getattr(resource, 'exposed', False): + # don't reveal what is not accessible... + raise HTTPError(404) return resource class Handler(BaseHTTPRequestHandler): @@ -107,15 +104,22 @@ path, query = self.process_path(self.path) try: resource = self.find_resource(path, query) - headers, data = resource.handle(self, path, query) + headers, data = resource(self, path, query) except HTTPError, e: status = e.status headers, data = self.process_http_error(e) + except: + exc, e, tb = sys.exc_info() + tb_formatted = '\n'.join(traceback.format_tb(tb)) + status = 200 + data = 'An error has occurred: %s - %s\n\n%s' % (exc, e, + tb_formatted) + headers = {'Content-Type': 'text/plain'} else: status = 200 if not 'content-type' in [k.lower() for k in headers]: headers['Content-Type'] = 'text/html; charset=UTF-8' - self.response(status, headers, data) + self.response(status, headers, data, send_body) do_POST = do_GET @@ -156,7 +160,7 @@ body = 'Error: %s (%s)' % (e.status, e.message) return headers, body - def response(self, status, headers, body): + def response(self, status, headers, body, send_body=True): """ generate the HTTP response and send it to the client """ self.send_response(status) @@ -166,6 +170,8 @@ for keyword, value in headers.iteritems(): self.send_header(keyword, value) self.end_headers() + if not send_body: + return if isinstance(body, str): self.wfile.write(body) elif hasattr(body, 'read'): @@ -183,15 +189,16 @@ server = HTTPServer(address, handler) server.serve_forever() -# ready-to-use Collection and Resource implementations -class FsFile(Resource): +# ready-to-use Collection and resource implementations +class FsFile(object): + exposed = True debug = False def __init__(self, path, content_type): self._path = path self._content_type = content_type _data = None - def handle(self, handler, path, query): + def __call__(self, handler, path, query): if self._data is None or self.debug: self._data = self._path.read() return ({'Content-Type': self._content_type}, self._data) Modified: pypy/branch/guido-buildtool-web/pypy/tool/build/web/templates/buildersinfo.html ============================================================================== --- pypy/branch/guido-buildtool-web/pypy/tool/build/web/templates/buildersinfo.html (original) +++ pypy/branch/guido-buildtool-web/pypy/tool/build/web/templates/buildersinfo.html Mon Feb 19 22:02:27 2007 @@ -30,6 +30,7 @@

busy on build:
nothing
+
request time: Modified: pypy/branch/guido-buildtool-web/pypy/tool/build/web/test/test_app.py ============================================================================== --- pypy/branch/guido-buildtool-web/pypy/tool/build/web/test/test_app.py (original) +++ pypy/branch/guido-buildtool-web/pypy/tool/build/web/test/test_app.py Mon Feb 19 22:02:27 2007 @@ -65,9 +65,9 @@ mod.gateway.exit() class TestIndexPage(object): - def test_handle(self): - p = IndexPage() - headers, html = p.handle(None, '/', '') + def test_call(self): + a = Application() + headers, html = a.index(None, '/', '') assert headers == {'Content-Type': 'text/html; charset=UTF-8'} assert html.strip().startswith('') @@ -80,12 +80,12 @@ server_channel.send(('set_status', {'foo': 'bar'})) assert p.get_status() == {'foo': 'bar'} - def test_handle(self): + def test_call(self): server_channel.send(('set_status', {'builders': 3, 'running': 2, 'done': 7, 'waiting': 5, 'queued': 2})) p = ServerStatusPage(config, gateway) - headers, html = p.handle(None, '/serverstatus', '') + headers, html = p(None, '/serverstatus', '') assert headers == {'Content-Type': 'text/html; charset=UTF-8'} assert html.strip().startswith('') @@ -99,7 +99,7 @@ 'busy_on': None}])) assert p.get_buildersinfo() == [{'sysinfo': ['foo'], 'busy_on': None}] - def test_handle(self): + def test_call(self): b = build.BuildRequest('foo at bar.com', {}, {'foo': 'bar'}, 'http://codespeak.net/svn/pypy/dist', 10, 2, 123456789) @@ -119,23 +119,23 @@ 'busy_on': busy_on, }])) p = BuildersInfoPage(config, gateway) - headers, html = p.handle(None, '/buildersinfo', '') + headers, html = p(None, '/buildersinfo', '') assert headers == {'Content-Type': 'text/html; charset=UTF-8'} assert html.strip().startswith('') html_validate(html) class TestBuildPage(object): - def test_handle(self): + def test_call(self): pass class TestBuildsIndexPage(object): def test_get_builds(self): pass - def test_handle(self): + def test_call(self): p = BuildsIndexPage(config, gateway) - headers, html = p.handle(None, '/builds/', '') + headers, html = p(None, '/builds/', '') assert headers == {'Content-Type': 'text/html; charset=UTF-8'} assert html.strip().startswith('') Modified: pypy/branch/guido-buildtool-web/pypy/tool/build/web/test/test_server.py ============================================================================== --- pypy/branch/guido-buildtool-web/pypy/tool/build/web/test/test_server.py (original) +++ pypy/branch/guido-buildtool-web/pypy/tool/build/web/test/test_server.py Mon Feb 19 22:02:27 2007 @@ -10,8 +10,10 @@ def log_request(self, code='-', size='-'): pass -class SomePage(Resource): - def handle(self, server, path, query): +class SomePage(object): + """ test resource """ + exposed = True + def __call__(self, handler, path, query): return ('text/plain', 'foo') def build_app_structure(): @@ -101,12 +103,12 @@ py.test.raises(ValueError, "self.handler.response(200, {}, u'xxx')") class TestFsFile(object): - def test_handle(self): + def test_call(self): temp = py.test.ensuretemp('TestStaticResource.test_handle') foo = temp.ensure('foo.txt') foo.write('foo') r = FsFile(foo, 'text/plain') - ret = r.handle(None, '/bar/foo.txt', '') + ret = r(None, '/bar/foo.txt', '') assert ret[0] == {'Content-Type': 'text/plain'} assert ret[1] == 'foo' From auc at codespeak.net Tue Feb 20 09:33:38 2007 From: auc at codespeak.net (auc at codespeak.net) Date: Tue, 20 Feb 2007 09:33:38 +0100 (CET) Subject: [pypy-svn] r39220 - in pypy/dist/pypy: module/_cslib rlib/cslib rlib/cslib/test Message-ID: <20070220083338.479161028D@code0.codespeak.net> Author: auc Date: Tue Feb 20 09:33:36 2007 New Revision: 39220 Modified: pypy/dist/pypy/module/_cslib/fd.py pypy/dist/pypy/module/_cslib/propagation.py pypy/dist/pypy/rlib/cslib/rconstraint.py pypy/dist/pypy/rlib/cslib/rpropagation.py pypy/dist/pypy/rlib/cslib/test/test_cslib.py Log: oops Modified: pypy/dist/pypy/module/_cslib/fd.py ============================================================================== --- pypy/dist/pypy/module/_cslib/fd.py (original) +++ pypy/dist/pypy/module/_cslib/fd.py Tue Feb 20 09:33:36 2007 @@ -6,7 +6,7 @@ from pypy.objspace.std.listobject import W_ListObject, W_TupleObject from pypy.objspace.std.intobject import W_IntObject -from pypy.rlib import rdomain as rd +from pypy.rlib.cslib import rdomain as rd class _FiniteDomain(rd.BaseFiniteDomain): """ Modified: pypy/dist/pypy/module/_cslib/propagation.py ============================================================================== --- pypy/dist/pypy/module/_cslib/propagation.py (original) +++ pypy/dist/pypy/module/_cslib/propagation.py Tue Feb 20 09:33:36 2007 @@ -1,5 +1,6 @@ -from pypy.rlib.rpropagation import Repository, Solver -import pypy.rlib.rdistributor as rd +from pypy.rlib.cslib.rpropagation import Repository, Solver +import pypy.rlib.cslib.rdistributor as rd + from pypy.module._cslib import fd from pypy.module._cslib.constraint import W_AbstractConstraint @@ -8,7 +9,6 @@ from pypy.interpreter import typedef, gateway, baseobjspace from pypy.interpreter.gateway import interp2app -#from pypy.objspace.std.listobject import W_ListObject, W_TupleObject from pypy.objspace.std.intobject import W_IntObject from pypy.objspace.std.listobject import W_ListObject from pypy.objspace.std.tupleobject import W_TupleObject Modified: pypy/dist/pypy/rlib/cslib/rconstraint.py ============================================================================== --- pypy/dist/pypy/rlib/cslib/rconstraint.py (original) +++ pypy/dist/pypy/rlib/cslib/rconstraint.py Tue Feb 20 09:33:36 2007 @@ -1,5 +1,5 @@ -from pypy.rlib.btree import BTreeNode -from pypy.rlib.rdomain import BaseFiniteDomain, ConsistencyError +from pypy.rlib.cslib.btree import BTreeNode +from pypy.rlib.cslib.rdomain import BaseFiniteDomain, ConsistencyError class AbstractConstraint: Modified: pypy/dist/pypy/rlib/cslib/rpropagation.py ============================================================================== --- pypy/dist/pypy/rlib/cslib/rpropagation.py (original) +++ pypy/dist/pypy/rlib/cslib/rpropagation.py Tue Feb 20 09:33:36 2007 @@ -1,5 +1,5 @@ """The code of the constraint propagation algorithms""" -from pypy.rlib.rconstraint import AbstractConstraint, ConsistencyError +from pypy.rlib.cslib.rconstraint import AbstractConstraint, ConsistencyError class Repository: """Stores variables, domains and constraints Modified: pypy/dist/pypy/rlib/cslib/test/test_cslib.py ============================================================================== --- pypy/dist/pypy/rlib/cslib/test/test_cslib.py (original) +++ pypy/dist/pypy/rlib/cslib/test/test_cslib.py Tue Feb 20 09:33:36 2007 @@ -1,7 +1,7 @@ import os -from pypy.rlib import rconstraint as rc, rdomain as rd -from pypy.rlib import rpropagation as rp, rdistributor as rdist +from pypy.rlib.cslib import rconstraint as rc, rdomain as rd +from pypy.rlib.cslib import rpropagation as rp, rdistributor as rdist def debug(msg): From ac at codespeak.net Tue Feb 20 11:40:06 2007 From: ac at codespeak.net (ac at codespeak.net) Date: Tue, 20 Feb 2007 11:40:06 +0100 (CET) Subject: [pypy-svn] r39222 - in pypy/dist/pypy: bin translator/goal Message-ID: <20070220104006.ED02F10298@code0.codespeak.net> Author: ac Date: Tue Feb 20 11:40:05 2007 New Revision: 39222 Modified: pypy/dist/pypy/bin/py.py pypy/dist/pypy/translator/goal/app_main.py Log: Import site module on startup. Modified: pypy/dist/pypy/bin/py.py ============================================================================== --- pypy/dist/pypy/bin/py.py (original) +++ pypy/dist/pypy/bin/py.py Tue Feb 20 11:40:05 2007 @@ -13,7 +13,7 @@ from pypy.tool import option from py.compat.optparse import make_option -from pypy.interpreter import main, interactive, error +from pypy.interpreter import main, interactive, error, gateway from pypy.config.config import OptionDescription, BoolOption, StrOption from pypy.config.config import Config, to_optparse import os, sys @@ -37,6 +37,15 @@ default=None, cmdline="-c"), ]) +pypy_init = gateway.applevel(''' +def pypy_init(): + try: + import site + except: + import sys + print >> sys.stderr, "import site' failed" + +''').interphook('pypy_init') def main_(argv=None): starttime = time.time() config, parser = option.get_standard_options() @@ -90,6 +99,7 @@ try: def do_start(): space.startup() + pypy_init(space) if main.run_toplevel(space, do_start, verbose=interactiveconfig.verbose): # compile and run it 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 Tue Feb 20 11:40:05 2007 @@ -214,6 +214,12 @@ mainmodule = type(sys)('__main__') sys.modules['__main__'] = mainmodule + try: + import site + except: + print >> sys.stderr, "import site' failed" + + # set up the Ctrl-C => KeyboardInterrupt signal handler, if the # signal module is available try: From mwh at codespeak.net Tue Feb 20 11:46:28 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Tue, 20 Feb 2007 11:46:28 +0100 (CET) Subject: [pypy-svn] r39223 - pypy/dist/pypy/module/crypt Message-ID: <20070220104628.6D7381029C@code0.codespeak.net> Author: mwh Date: Tue Feb 20 11:46:27 2007 New Revision: 39223 Modified: pypy/dist/pypy/module/crypt/interp_crypt.py Log: you don't want -lcrypt to end up in the linker command on darwin. this is probably needlessly tortuous, but hey, it works. Modified: pypy/dist/pypy/module/crypt/interp_crypt.py ============================================================================== --- pypy/dist/pypy/module/crypt/interp_crypt.py (original) +++ pypy/dist/pypy/module/crypt/interp_crypt.py Tue Feb 20 11:46:27 2007 @@ -8,10 +8,16 @@ class CConfig: _includes_ = ('unistd.h',) - cryptlib = ctypes_platform.Library('crypt') + if sys.platform != 'darwin': + cryptlib = ctypes_platform.Library('crypt') globals().update(ctypes_platform.configure(CConfig)) +if sys.platform == 'darwin': + dllname = find_library('c') + assert dllname is not None + cryptlib = cdll.LoadLibrary(dllname) + c_crypt = cryptlib.crypt c_crypt.argtypes = [c_char_p, c_char_p] c_crypt.restype = c_char_p From fijal at codespeak.net Tue Feb 20 14:01:41 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 20 Feb 2007 14:01:41 +0100 (CET) Subject: [pypy-svn] r39230 - in pypy/dist/pypy/lib/distributed: . demo test Message-ID: <20070220130141.E8F511029A@code0.codespeak.net> Author: fijal Date: Tue Feb 20 14:01:33 2007 New Revision: 39230 Added: pypy/dist/pypy/lib/distributed/demo/ pypy/dist/pypy/lib/distributed/demo/show.py Modified: pypy/dist/pypy/lib/distributed/__init__.py pypy/dist/pypy/lib/distributed/objkeeper.py pypy/dist/pypy/lib/distributed/protocol.py pypy/dist/pypy/lib/distributed/test/test_distributed.py Log: Few fixes, failing test and a demo Modified: pypy/dist/pypy/lib/distributed/__init__.py ============================================================================== --- pypy/dist/pypy/lib/distributed/__init__.py (original) +++ pypy/dist/pypy/lib/distributed/__init__.py Tue Feb 20 14:01:33 2007 @@ -1,2 +1,6 @@ -from protocol import RemoteProtocol, test_env, remote_loop +try: + from protocol import RemoteProtocol, test_env, remote_loop +except ImportError: + # UGH. This is needed for tests + pass Added: pypy/dist/pypy/lib/distributed/demo/show.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/lib/distributed/demo/show.py Tue Feb 20 14:01:33 2007 @@ -0,0 +1,47 @@ +""" Notes: you need to have pylib, greenexecnet, greensock2 and pypeers +symlinked in pypy/lib dir +""" + +import sys +import greenexecnet +import py + +remote = py.code.Source(""" +class X: + def __init__(self, z): + self.z = z + + def meth(self, x): + return self.z + x() + + def raising(self): + 1/0 + +x = X(3) + +from distributed import RemoteProtocol, remote_loop +remote_loop(RemoteProtocol(channel.send, channel.receive, {'x':x})) +""") + +if __name__ == '__main__': + gw = greenexecnet.SshGateway('localhost', remotepython=sys.executable) + ch = gw.remote_exec(str(remote)) + from distributed import RemoteProtocol + rp = RemoteProtocol(ch.send, ch.receive, {}) + x = rp.get_remote("x") + + # examples: + # def f(): + # return 3 + # x.meth(f) # should be 3 + 3, but f called locally + + # try: + # x.raising + # except: + # import sys + # e = sys.exc_info() + # e[2].tb_next.tb_next.tb_frame.f_locals['self'].z + # # should be 3 (remote z), note that one frame is not cut properly + + import code + code.interact(local=locals()) Modified: pypy/dist/pypy/lib/distributed/objkeeper.py ============================================================================== --- pypy/dist/pypy/lib/distributed/objkeeper.py (original) +++ pypy/dist/pypy/lib/distributed/objkeeper.py Tue Feb 20 14:01:33 2007 @@ -26,8 +26,6 @@ return len(self.exported_objects) - 1 def ignore(self, key, value): - #key not in ('__dict__', '__weakref__', '__class__', '__new__', - # '__base__', '__flags__', '__mro__', '__bases__')] if key in ('__dict__', '__weakref__', '__class__', '__new__'): return True if isinstance(value, GetSetDescriptor): @@ -39,8 +37,6 @@ return self.exported_types[tp] except KeyError: print "Registering type %s as %s" % (tp, self.exported_types_id) - if str(tp).find('getset') != -1: - import pdb;pdb.set_trace() self.exported_types[tp] = self.exported_types_id tp_id = self.exported_types_id self.exported_types_id += 1 @@ -60,14 +56,11 @@ if '__doc__' in _dict: d['__doc__'] = protocol.unwrap(_dict['__doc__']) tp = type(_name, (object,), d) + # Make sure we cannot instantiate the remote type self.remote_types[type_id] = tp for key, value in _dict.items(): if key != '__doc__': - try: - setattr(tp, key, protocol.unwrap(value)) - except TypeError: - # XXX this stays here for debugging reasons - import pdb;pdb.set_trace() + setattr(tp, key, protocol.unwrap(value)) def get_type(self, id): return self.remote_types[id] Modified: pypy/dist/pypy/lib/distributed/protocol.py ============================================================================== --- pypy/dist/pypy/lib/distributed/protocol.py (original) +++ pypy/dist/pypy/lib/distributed/protocol.py Tue Feb 20 14:01:33 2007 @@ -49,9 +49,11 @@ """ TODO list: -1. Add some garbage collection -2. Add caching of objects that are presented (even on name level) -3. Add exceptions, frames and error handling +1. Garbage collection - we would like probably to use weakrefs, but + since they're not perfectly working in pypy, let's live it alone for now +2. Some error handling - exceptions are working, there are still some + applications where it all explodes. +3. Support inheritance and recursive types """ from pypymagic import pypy_repr Modified: pypy/dist/pypy/lib/distributed/test/test_distributed.py ============================================================================== --- pypy/dist/pypy/lib/distributed/test/test_distributed.py (original) +++ pypy/dist/pypy/lib/distributed/test/test_distributed.py Tue Feb 20 14:01:33 2007 @@ -197,3 +197,14 @@ #assert tb.tb_next is None else: raise AssertionError("Did not raise") + + def test_instantiate_remote_type(self): + py.test.skip("Land of infinite recursion") + from distributed import test_env + + class C: + pass + + protocol = test_env({'C':C}) + xC = protocol.get_remote('C') + xC() From ac at codespeak.net Tue Feb 20 14:10:17 2007 From: ac at codespeak.net (ac at codespeak.net) Date: Tue, 20 Feb 2007 14:10:17 +0100 (CET) Subject: [pypy-svn] r39233 - in pypy/dist/pypy: bin translator/goal Message-ID: <20070220131017.1264C102A2@code0.codespeak.net> Author: ac Date: Tue Feb 20 14:10:15 2007 New Revision: 39233 Modified: pypy/dist/pypy/bin/py.py pypy/dist/pypy/translator/goal/app_main.py Log: Implement -S (don't 'import site') option. Modified: pypy/dist/pypy/bin/py.py ============================================================================== --- pypy/dist/pypy/bin/py.py (original) +++ pypy/dist/pypy/bin/py.py Tue Feb 20 14:10:15 2007 @@ -29,6 +29,8 @@ BoolOption("optimize", "dummy optimization flag for compatibility with CPython", default=False, cmdline="-O"), + BoolOption("no_site_import", "do not 'import site' on initialization", + default=False, cmdline="-S"), StrOption("runmodule", "library module to be run as a script (terminates option list)", default=None, cmdline="-m"), @@ -38,14 +40,15 @@ ]) pypy_init = gateway.applevel(''' -def pypy_init(): - try: - import site - except: - import sys - print >> sys.stderr, "import site' failed" - +def pypy_init(import_site): + if import_site: + try: + import site + except: + import sys + print >> sys.stderr, "import site' failed" ''').interphook('pypy_init') + def main_(argv=None): starttime = time.time() config, parser = option.get_standard_options() @@ -99,7 +102,7 @@ try: def do_start(): space.startup() - pypy_init(space) + pypy_init(space, space.wrap(not interactiveconfig.no_site_import)) if main.run_toplevel(space, do_start, verbose=interactiveconfig.verbose): # compile and run it 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 Tue Feb 20 14:10:15 2007 @@ -6,6 +6,7 @@ -i inspect interactively after running script -O dummy optimization flag for compatibility with C Python -c CMD program passed in as CMD (terminates option list) + -S do not 'import site' on initialization -u unbuffered binary stdout and stderr -h, --help show this help message and exit --version print the PyPy version @@ -172,6 +173,7 @@ go_interactive = False run_command = False + import_site = True i = 0 while i < len(argv): arg = argv[i] @@ -198,6 +200,8 @@ elif arg == '-h' or arg == '--help': print_help() return 0 + elif arg == '-S': + import_site = False elif arg == '--': i += 1 break # terminates option list @@ -214,10 +218,11 @@ mainmodule = type(sys)('__main__') sys.modules['__main__'] = mainmodule - try: - import site - except: - print >> sys.stderr, "import site' failed" + if import_site: + try: + import site + except: + print >> sys.stderr, "import site' failed" # set up the Ctrl-C => KeyboardInterrupt signal handler, if the From ludal at codespeak.net Tue Feb 20 15:48:09 2007 From: ludal at codespeak.net (ludal at codespeak.net) Date: Tue, 20 Feb 2007 15:48:09 +0100 (CET) Subject: [pypy-svn] r39239 - pypy/dist/pypy/rpython/memory/gctransform Message-ID: <20070220144809.C038E10109@code0.codespeak.net> Author: ludal Date: Tue Feb 20 15:48:09 2007 New Revision: 39239 Modified: pypy/dist/pypy/rpython/memory/gctransform/framework.py pypy/dist/pypy/rpython/memory/gctransform/stacklessframework.py Log: optimize handling of root_stack in gc framework This doesn't result in faster code, but saves the generation of 500000 lines of C in -o logic builds, and roughly 10% lines on a pypy standalone build with --gc-framework, resulting in faster generation and compilation times. Modified: pypy/dist/pypy/rpython/memory/gctransform/framework.py ============================================================================== --- pypy/dist/pypy/rpython/memory/gctransform/framework.py (original) +++ pypy/dist/pypy/rpython/memory/gctransform/framework.py Tue Feb 20 15:48:09 2007 @@ -146,19 +146,36 @@ self.frameworkgc_setup_ptr = getfn(frameworkgc_setup, [], annmodel.s_None) - if StackRootIterator.push_root is None: - self.push_root_ptr = None - else: + if StackRootIterator.need_root_stack: + self.pop_root_ptr = getfn(StackRootIterator.pop_root, [], + annmodel.s_None, + inline = True) self.push_root_ptr = getfn(StackRootIterator.push_root, [annmodel.SomeAddress()], annmodel.s_None, inline = True) - if StackRootIterator.pop_root is None: - self.pop_root_ptr = None + self.incr_stack_ptr = getfn(StackRootIterator.incr_stack, + [annmodel.SomeInteger()], + annmodel.SomeAddress(), + inline = True) + self.decr_stack_ptr = getfn(StackRootIterator.decr_stack, + [annmodel.SomeInteger()], + annmodel.s_None, + inline = True) + self.save_addr_ptr = getfn(StackRootIterator.save_addr, + [annmodel.SomeAddress(), + annmodel.SomeInteger(), + annmodel.SomeAddress()], + annmodel.s_None, + inline = True) else: - self.pop_root_ptr = getfn(StackRootIterator.pop_root, [], - annmodel.s_None, - inline = True) + self.push_root_ptr = None + self.pop_root_ptr = None + self.incr_stack_ptr = None + self.decr_stack_ptr = None + self.save_addr_ptr = None + + classdef = bk.getuniqueclassdef(GCClass) s_gc = annmodel.SomeInstance(classdef) @@ -243,6 +260,22 @@ i += 1 setup_root_stack = staticmethod(setup_root_stack) + need_root_stack = True + + def incr_stack(n): + top = gcdata.root_stack_top + gcdata.root_stack_top = top + n*sizeofaddr + return top + incr_stack = staticmethod(incr_stack) + + def save_addr(top, k, addr): + top.address[k] = addr + save_addr = staticmethod(save_addr) + + def decr_stack(n): + gcdata.root_stack_top -= n*sizeofaddr + decr_stack = staticmethod(decr_stack) + def push_root(addr): top = gcdata.root_stack_top top.address[0] = addr @@ -554,18 +587,24 @@ if self.push_root_ptr is None: return livevars = [var for var in self.livevars if not var_ispyobj(var)] - for var in livevars: + c_len = rmodel.inputconst(lltype.Signed, len(livevars) ) + base_addr = hop.genop("direct_call", [self.incr_stack_ptr, c_len ], + resulttype=llmemory.Address) + for k,var in enumerate(livevars): + c_k = rmodel.inputconst(lltype.Signed, k) v_adr = gen_cast(hop.llops, llmemory.Address, var) - hop.genop("direct_call", [self.push_root_ptr, v_adr]) + hop.genop("direct_call", [self.save_addr_ptr, base_addr, c_k, v_adr]) def pop_roots(self, hop): if self.pop_root_ptr is None: return livevars = [var for var in self.livevars if not var_ispyobj(var)] - for var in livevars[::-1]: - # XXX specific to non-moving collectors - hop.genop("direct_call", [self.pop_root_ptr]) - #hop.genop("gc_reload_possibly_moved", [var]) + c_len = rmodel.inputconst(lltype.Signed, len(livevars) ) + hop.genop("direct_call", [self.decr_stack_ptr, c_len ] ) +## for var in livevars[::-1]: +## # XXX specific to non-moving collectors +## hop.genop("direct_call", [self.pop_root_ptr]) +## #hop.genop("gc_reload_possibly_moved", [var]) # XXX copied and modified from lltypelayout.py def offsets_to_gc_pointers(TYPE): Modified: pypy/dist/pypy/rpython/memory/gctransform/stacklessframework.py ============================================================================== --- pypy/dist/pypy/rpython/memory/gctransform/stacklessframework.py (original) +++ pypy/dist/pypy/rpython/memory/gctransform/stacklessframework.py Tue Feb 20 15:48:09 2007 @@ -61,8 +61,7 @@ pass setup_root_stack = staticmethod(setup_root_stack) - push_root = None - pop_root = None + need_root_stack = False def __init__(self): frame = llmemory.cast_ptr_to_adr(stack_capture()) From alix at codespeak.net Tue Feb 20 16:36:46 2007 From: alix at codespeak.net (alix at codespeak.net) Date: Tue, 20 Feb 2007 16:36:46 +0100 (CET) Subject: [pypy-svn] r39240 - pypy/extradoc/sprintinfo/trillke-2007 Message-ID: <20070220153646.7AFD010118@code0.codespeak.net> Author: alix Date: Tue Feb 20 16:36:39 2007 New Revision: 39240 Modified: pypy/extradoc/sprintinfo/trillke-2007/people.txt Log: updated Modified: pypy/extradoc/sprintinfo/trillke-2007/people.txt ============================================================================== --- pypy/extradoc/sprintinfo/trillke-2007/people.txt (original) +++ pypy/extradoc/sprintinfo/trillke-2007/people.txt Tue Feb 20 16:36:39 2007 @@ -27,7 +27,8 @@ Holger Krekel 25th-8th private Alix Einfeldt 25th-8th private Lene Wagner 25th-8th private -Richard Emslie ?-5th ? +Richard Emslie ?-5th (klocke) +Stefan Busemann 26th-28th klocke ==================== ============== ===================== People on the following list were present at previous sprints: @@ -35,7 +36,6 @@ ==================== ============== ===================== Name Arrive/Depart Accomodation ==================== ============== ===================== -Christian Tismer ? ? Anders Lehmann ? ? Niklaus Haldimann ? ? Amaury Forgeot d'Arc ? ? From cfbolz at codespeak.net Tue Feb 20 19:38:30 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Tue, 20 Feb 2007 19:38:30 +0100 (CET) Subject: [pypy-svn] r39241 - pypy/dist/pypy/tool Message-ID: <20070220183830.AC4FF10118@code0.codespeak.net> Author: cfbolz Date: Tue Feb 20 19:38:29 2007 New Revision: 39241 Modified: pypy/dist/pypy/tool/statistic_over_time.py Log: remove dead code 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 Feb 20 19:38:29 2007 @@ -3,11 +3,6 @@ import datetime import time -try: - path = py.path.svnwc(py.std.sys.argv[1]) -except IndexError: - path = py.path.svnwc() - URL = "http://codespeak.net/svn/pypy/dist" tempdir = py.path.svnwc(py.test.ensuretemp("pypy-dist")) From cfbolz at codespeak.net Tue Feb 20 19:53:32 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Tue, 20 Feb 2007 19:53:32 +0100 (CET) Subject: [pypy-svn] r39242 - pypy/dist/pypy/doc/statistic Message-ID: <20070220185332.449BD10122@code0.codespeak.net> Author: cfbolz Date: Tue Feb 20 19:53:31 2007 New Revision: 39242 Modified: pypy/dist/pypy/doc/statistic/release_dates.csv pypy/dist/pypy/doc/statistic/sprint_dates.csv Log: add recent dates Modified: pypy/dist/pypy/doc/statistic/release_dates.csv ============================================================================== --- pypy/dist/pypy/doc/statistic/release_dates.csv (original) +++ pypy/dist/pypy/doc/statistic/release_dates.csv Tue Feb 20 19:53:31 2007 @@ -5,3 +5,5 @@ 2005-08-28,"PyPy 0.7.0" 2005-11-03,"PyPy 0.8.0" 2006-06-25,"PyPy 0.9.0" +2006-06-25,"PyPy 0.9.0" +2007-02-17,"PyPy 0.99.0" Modified: pypy/dist/pypy/doc/statistic/sprint_dates.csv ============================================================================== --- pypy/dist/pypy/doc/statistic/sprint_dates.csv (original) +++ pypy/dist/pypy/doc/statistic/sprint_dates.csv Tue Feb 20 19:53:31 2007 @@ -20,3 +20,7 @@ "Japan",2006-04-23,2006-04-29 "Duesseldorf",2006-06-02,2006-06-09 "Europython/Genf",2006-07-06,2006-07-09 +"Limerick",2006-08-21,2006-08-27 +"Duesseldorf",2006-10-30,2006-11-05 +"Leysin",2007-01-08,2007-01-14 +"Hildesheim",2007-03-01,2007-03-05 From cfbolz at codespeak.net Tue Feb 20 19:54:58 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Tue, 20 Feb 2007 19:54:58 +0100 (CET) Subject: [pypy-svn] r39243 - pypy/dist/pypy/doc/statistic Message-ID: <20070220185458.C147810123@code0.codespeak.net> Author: cfbolz Date: Tue Feb 20 19:54:56 2007 New Revision: 39243 Modified: pypy/dist/pypy/doc/statistic/statistic_irc_log.txt Log: irc statistics - just as useless as before :-) Modified: pypy/dist/pypy/doc/statistic/statistic_irc_log.txt ============================================================================== --- pypy/dist/pypy/doc/statistic/statistic_irc_log.txt (original) +++ pypy/dist/pypy/doc/statistic/statistic_irc_log.txt Tue Feb 20 19:54:56 2007 @@ -510,3 +510,221 @@ 2006-07-15, 180, 16 2006-07-16, 175, 14 2006-07-17, 526, 20 +2006-07-18, 421, 19 +2006-07-19, 607, 20 +2006-07-20, 575, 38 +2006-07-21, 369, 31 +2006-07-22, 293, 13 +2006-07-23, 449, 18 +2006-07-24, 1042, 23 +2006-07-25, 749, 25 +2006-07-26, 348, 22 +2006-07-27, 938, 22 +2006-07-28, 660, 19 +2006-07-29, 350, 19 +2006-07-30, 773, 12 +2006-07-31, 266, 18 +2006-08-01, 561, 26 +2006-08-02, 438, 20 +2006-08-03, 562, 22 +2006-08-04, 431, 20 +2006-08-05, 57, 13 +2006-08-06, 182, 19 +2006-08-07, 719, 22 +2006-08-08, 321, 21 +2006-08-09, 328, 15 +2006-08-10, 153, 23 +2006-08-11, 374, 14 +2006-08-12, 213, 16 +2006-08-13, 43, 9 +2006-08-14, 296, 15 +2006-08-15, 301, 19 +2006-08-16, 278, 18 +2006-08-17, 120, 19 +2006-08-18, 74, 23 +2006-08-19, 0, 9 +2006-08-20, 116, 13 +2006-08-21, 130, 23 +2006-08-22, 84, 21 +2006-08-23, 85, 22 +2006-08-24, 138, 21 +2006-08-25, 44, 23 +2006-08-26, 130, 16 +2006-08-27, 97, 21 +2006-08-28, 101, 35 +2006-08-29, 806, 23 +2006-08-30, 596, 26 +2006-08-31, 537, 24 +2006-09-01, 102, 17 +2006-09-02, 162, 15 +2006-09-03, 15, 10 +2006-09-04, 179, 22 +2006-09-05, 169, 16 +2006-09-06, 422, 22 +2006-09-07, 564, 27 +2006-09-08, 157, 19 +2006-09-09, 198, 11 +2006-09-10, 206, 10 +2006-09-11, 294, 21 +2006-09-12, 310, 21 +2006-09-13, 290, 19 +2006-09-14, 313, 26 +2006-09-15, 340, 25 +2006-09-16, 342, 20 +2006-09-17, 398, 16 +2006-09-18, 411, 19 +2006-09-19, 178, 23 +2006-09-20, 471, 18 +2006-09-21, 164, 23 +2006-09-22, 217, 22 +2006-09-23, 220, 11 +2006-09-24, 126, 8 +2006-09-25, 346, 20 +2006-09-26, 117, 17 +2006-09-27, 298, 22 +2006-09-28, 722, 24 +2006-09-29, 515, 26 +2006-09-30, 106, 21 +2006-10-01, 145, 18 +2006-10-02, 564, 18 +2006-10-03, 466, 32 +2006-10-04, 873, 31 +2006-10-05, 709, 28 +2006-10-06, 600, 23 +2006-10-07, 86, 16 +2006-10-08, 278, 15 +2006-10-09, 659, 29 +2006-10-10, 945, 24 +2006-10-11, 966, 20 +2006-10-12, 887, 26 +2006-10-13, 249, 24 +2006-10-14, 10, 15 +2006-10-15, 34, 19 +2006-10-16, 709, 23 +2006-10-17, 410, 23 +2006-10-18, 501, 25 +2006-10-19, 552, 29 +2006-10-20, 109, 18 +2006-10-21, 380, 14 +2006-10-22, 66, 13 +2006-10-23, 133, 17 +2006-10-24, 162, 15 +2006-10-25, 84, 14 +2006-10-26, 149, 13 +2006-10-27, 359, 13 +2006-10-28, 252, 18 +2006-10-29, 170, 18 +2006-10-30, 62, 20 +2006-10-31, 286, 23 +2006-11-01, 188, 20 +2006-11-02, 291, 35 +2006-11-03, 212, 19 +2006-11-04, 166, 24 +2006-11-05, 131, 24 +2006-11-06, 405, 24 +2006-11-07, 802, 30 +2006-11-08, 1229, 26 +2006-11-09, 1277, 27 +2006-11-10, 331, 24 +2006-11-11, 450, 19 +2006-11-12, 330, 17 +2006-11-13, 781, 18 +2006-11-14, 535, 25 +2006-11-15, 574, 17 +2006-11-16, 340, 19 +2006-11-17, 522, 20 +2006-11-18, 114, 14 +2006-11-19, 238, 16 +2006-11-20, 211, 25 +2006-11-21, 475, 26 +2006-11-22, 173, 16 +2006-11-23, 513, 24 +2006-11-24, 683, 20 +2006-11-25, 151, 15 +2006-11-26, 196, 30 +2006-11-27, 370, 22 +2006-11-28, 336, 22 +2006-11-29, 379, 28 +2006-11-30, 727, 24 +2006-12-01, 628, 19 +2006-12-02, 204, 12 +2006-12-03, 437, 14 +2006-12-04, 491, 25 +2006-12-05, 361, 22 +2006-12-06, 410, 25 +2006-12-07, 536, 23 +2006-12-08, 255, 22 +2006-12-09, 151, 41 +2006-12-10, 52, 12 +2006-12-11, 704, 32 +2006-12-12, 472, 25 +2006-12-13, 521, 29 +2006-12-14, 201, 23 +2006-12-15, 538, 27 +2006-12-16, 282, 18 +2006-12-17, 111, 14 +2006-12-18, 177, 18 +2006-12-19, 381, 20 +2006-12-20, 399, 25 +2006-12-21, 397, 26 +2006-12-22, 240, 41 +2006-12-23, 15, 16 +2006-12-24, 15, 10 +2006-12-25, 82, 10 +2006-12-26, 3, 12 +2006-12-27, 256, 18 +2006-12-28, 220, 19 +2006-12-29, 103, 16 +2006-12-30, 285, 12 +2006-12-31, 548, 17 +2007-01-01, 544, 14 +2007-01-02, 263, 15 +2007-01-03, 631, 18 +2007-01-04, 297, 12 +2007-01-05, 392, 17 +2007-01-06, 103, 14 +2007-01-07, 53, 12 +2007-01-08, 232, 28 +2007-01-09, 98, 32 +2007-01-10, 183, 27 +2007-01-11, 162, 27 +2007-01-12, 694, 24 +2007-01-13, 246, 24 +2007-01-14, 81, 26 +2007-01-15, 327, 27 +2007-01-16, 799, 22 +2007-01-17, 222, 22 +2007-01-18, 158, 23 +2007-01-19, 819, 27 +2007-01-20, 226, 18 +2007-01-21, 117, 17 +2007-01-22, 490, 27 +2007-01-23, 279, 27 +2007-01-24, 374, 21 +2007-01-25, 449, 20 +2007-01-26, 321, 18 +2007-01-27, 156, 13 +2007-01-28, 376, 14 +2007-01-29, 427, 21 +2007-01-30, 715, 22 +2007-01-31, 624, 30 +2007-02-01, 446, 20 +2007-02-02, 248, 25 +2007-02-03, 437, 16 +2007-02-04, 256, 19 +2007-02-05, 473, 19 +2007-02-06, 198, 16 +2007-02-07, 439, 35 +2007-02-08, 472, 17 +2007-02-09, 803, 24 +2007-02-10, 274, 23 +2007-02-11, 622, 18 +2007-02-12, 786, 23 +2007-02-13, 1172, 25 +2007-02-14, 1101, 28 +2007-02-15, 1236, 23 +2007-02-16, 793, 23 +2007-02-17, 1399, 22 +2007-02-18, 636, 18 +2007-02-19, 761, 28 +2007-02-20, 414, 23 From mwh at codespeak.net Tue Feb 20 20:07:24 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Tue, 20 Feb 2007 20:07:24 +0100 (CET) Subject: [pypy-svn] r39244 - pypy/dist/pypy/lib/distributed Message-ID: <20070220190724.63BCF10129@code0.codespeak.net> Author: mwh Date: Tue Feb 20 20:07:20 2007 New Revision: 39244 Modified: pypy/dist/pypy/lib/distributed/protocol.py Log: two small typos Modified: pypy/dist/pypy/lib/distributed/protocol.py ============================================================================== --- pypy/dist/pypy/lib/distributed/protocol.py (original) +++ pypy/dist/pypy/lib/distributed/protocol.py Tue Feb 20 20:07:20 2007 @@ -39,7 +39,7 @@ from pypymagic import transparent_proxy as proxy from pypymagic import get_transparent_controller except ImportError: - raise ImportError("Cannot work without transparent proxy functional") + raise ImportError("Cannot work without transparent proxy functionality") from distributed.objkeeper import ObjKeeper import sys @@ -50,7 +50,7 @@ TODO list: 1. Garbage collection - we would like probably to use weakrefs, but - since they're not perfectly working in pypy, let's live it alone for now + since they're not perfectly working in pypy, let's leave it alone for now 2. Some error handling - exceptions are working, there are still some applications where it all explodes. 3. Support inheritance and recursive types From santagada at codespeak.net Tue Feb 20 21:25:42 2007 From: santagada at codespeak.net (santagada at codespeak.net) Date: Tue, 20 Feb 2007 21:25:42 +0100 (CET) Subject: [pypy-svn] r39245 - in pypy/dist/pypy/lang/js: . test/ecma Message-ID: <20070220202542.582E610117@code0.codespeak.net> Author: santagada Date: Tue Feb 20 21:25:41 2007 New Revision: 39245 Modified: pypy/dist/pypy/lang/js/interpreter.py pypy/dist/pypy/lang/js/jsobj.py pypy/dist/pypy/lang/js/test/ecma/conftest.py pypy/dist/pypy/lang/js/test/ecma/shell.js Log: improvements to the test runner and some more opcodes implemented Modified: pypy/dist/pypy/lang/js/interpreter.py ============================================================================== --- pypy/dist/pypy/lang/js/interpreter.py (original) +++ pypy/dist/pypy/lang/js/interpreter.py Tue Feb 20 21:25:41 2007 @@ -79,6 +79,17 @@ def decision(self, ctx, op1, op2): raise NotImplementedError +class BinaryBitwiseOp(BinaryOp): + def eval(self, ctx): + s5 = self.left.eval(ctx).GetValue().ToInt32() + s6 = self.right.eval(ctx).GetValue().ToInt32() + if DEBUG: + print "bitwisecomp, op1 and op2 ", s2, s4 + return self.decision(ctx, s5, s6) + + def decision(self, ctx, op1, op2): + raise NotImplementedError + class BinaryLogicOp(BinaryOp): pass @@ -150,7 +161,7 @@ class Interpreter(object): """Creates a js interpreter""" def __init__(self): - w_Global = W_Object() + w_Global = W_Object(Class="global") ctx = global_context(w_Global) w_ObjPrototype = W_Object(Prototype=None, Class='Object') @@ -174,6 +185,8 @@ w_Global.Put('Math', w_math) w_math.Put('abs', W_Builtin(absjs, Class='function')) w_math.Put('floor', W_Builtin(floorjs, Class='function')) + w_math.Put('E', W_Number(math.e)) + w_math.Put('PI', W_Number(math.pi)) w_Global.Put('String', W_Builtin(stringjs, Class='String')) @@ -262,6 +275,24 @@ else: raise e +class BitwiseAnd(BinaryBitwiseOp): + opcode = 'BITWISE_AND' + + def decision(self, ctx, op1, op2): + return W_Number(op1&op2) + +class BitwiseOR(BinaryBitwiseOp): + opcode = 'BITWISE_OR' + + def decision(self, ctx, op1, op2): + return W_Number(op1|op2) + +class BitwiseXOR(BinaryBitwiseOp): + opcode = 'BITWISE_XOR' + + def decision(self, ctx, op1, op2): + return W_Number(op1^op2) + class Unconditional(Statement): def from_tree(self, t): pieces = get_string(t, 'target').split(',') @@ -520,7 +551,7 @@ return W_Boolean(True) r3 = r1.GetBase() r4 = r1.GetPropertyName() - return r3.Delete(r4) + return W_Boolean(r3.Delete(r4)) class Increment(UnaryOp): opcode = 'INCREMENT' @@ -533,6 +564,18 @@ thing.PutValue(resl, ctx) return val +class Decrement(UnaryOp): + opcode = 'DECREMENT' + + def eval(self, ctx): + thing = self.expr.eval(ctx) + val = thing.GetValue() + x = val.ToNumber() + resl = Plus().mathop(ctx, W_Number(x), W_Number(-1)) + thing.PutValue(resl, ctx) + return val + + class Index(BinaryOp): opcode = 'INDEX' Modified: pypy/dist/pypy/lang/js/jsobj.py ============================================================================== --- pypy/dist/pypy/lang/js/jsobj.py (original) +++ pypy/dist/pypy/lang/js/jsobj.py Tue Feb 20 21:25:41 2007 @@ -61,6 +61,9 @@ def ToNumber(self): return NaN + def ToInt32(self): + return 0 + def Get(self, P): raise NotImplementedError @@ -394,6 +397,9 @@ def type(self): return 'number' + + def ToInt32(self): + return int(self.floatval) class W_List(W_Root): def __init__(self, list_w): Modified: pypy/dist/pypy/lang/js/test/ecma/conftest.py ============================================================================== --- pypy/dist/pypy/lang/js/test/ecma/conftest.py (original) +++ pypy/dist/pypy/lang/js/test/ecma/conftest.py Tue Feb 20 21:25:41 2007 @@ -3,6 +3,9 @@ from pypy.lang.js.jsobj import W_Array, JsBaseExcept from pypy.lang.js.jsparser import JsSyntaxError from py.__.test.outcome import Failed +import pypy.lang.js as js + +# js.jsobj.DEBUG = True rootdir = py.magic.autopath().dirpath() exclusionlist = ['shell.js', 'browser.js'] @@ -35,9 +38,9 @@ def __init__(self, fspath, parent=None): super(JSTestFile, self).__init__(fspath, parent) - self.name = fspath.purebasename + " JSFILE" + self.name = fspath.purebasename self.fspath = fspath - + def run(self): if not py.test.config.option.ecma: py.test.skip("ECMA tests disabled, run with --ecma") @@ -48,29 +51,31 @@ t = load_source(self.fspath.read()) try: t.execute(self.interp.global_context) - except (JsBaseExcept, JsSyntaxError): - raise Failed(excinfo=py.code.ExceptionInfo()) + except JsSyntaxError: + raise Failed(msg="Syntax Error",excinfo=py.code.ExceptionInfo()) + except JsBaseExcept: + raise Failed(msg="Javascript Error", excinfo=py.code.ExceptionInfo()) testcases = self.interp.global_context.resolve_identifier('testcases') - values = testcases.GetValue().array + testcount = testcases.GetValue().Get('length').GetValue().ToNumber() self.testcases = testcases - result = [str(i) for i in range(len(values))] - return result + # result = [str(i) for i in range(len(values))] + return range(testcount) - def join(self, name): - return JSTestItem(name, parent = self) + def join(self, number): + return JSTestItem(number, parent = self) def teardown(self): self.testcases.PutValue(W_Array(), self.interp.global_context) class JSTestItem(py.test.collect.Item): - def __init__(self, name, parent=None): - super(JSTestItem, self).__init__(name, parent) - self.name = name + def __init__(self, number, parent=None): + super(JSTestItem, self).__init__(str(number), parent) + self.number = number def run(self): ctx = JSTestFile.interp.global_context r3 = ctx.resolve_identifier('run_test').GetValue() - result = r3.Call(ctx=ctx, args=[W_Number(int(self.name)),]).ToNumber() + result = r3.Call(ctx=ctx, args=[W_Number(self.number),]).ToNumber() if result == 0: py.test.fail() elif result == -1: Modified: pypy/dist/pypy/lang/js/test/ecma/shell.js ============================================================================== --- pypy/dist/pypy/lang/js/test/ecma/shell.js (original) +++ pypy/dist/pypy/lang/js/test/ecma/shell.js Tue Feb 20 21:25:41 2007 @@ -50,7 +50,7 @@ var PASSED = " PASSED!" var FAILED = " FAILED! expected: "; -var DEBUG = false; +var DEBUG = true; var DESCRIPTION; var EXPECTED; @@ -140,7 +140,7 @@ // } // } // stopTest(); - return ( testcases ); + return testcases.length } /* @@ -194,17 +194,14 @@ */ function run_test(tc) { - // try - // { - print(tc) - getTestCaseResult(testcases[tc].expect, testcases[tc].actual) - testcases[tc].reason += ( testcases[tc].passed ) ? "" : "wrong value "; - return testcases[tc].passed? 1:0; - // } - // catch(e) - // { - // return -1 - // } + // try { + getTestCaseResult(testcases[tc].expect, testcases[tc].actual) + testcases[tc].reason += ( testcases[tc].passed ) ? "" : "wrong value "; + return testcases[tc].passed? 1:0; + // } + // catch(e) { + // return -1; + // } } function writeTestCaseResult( expect, actual, string ) { var passed = getTestCaseResult( expect, actual ); From santagada at codespeak.net Tue Feb 20 21:28:04 2007 From: santagada at codespeak.net (santagada at codespeak.net) Date: Tue, 20 Feb 2007 21:28:04 +0100 (CET) Subject: [pypy-svn] r39246 - pypy/dist/pypy/lang/js/test/ecma Message-ID: <20070220202804.192F010129@code0.codespeak.net> Author: santagada Date: Tue Feb 20 21:28:03 2007 New Revision: 39246 Modified: pypy/dist/pypy/lang/js/test/ecma/conftest.py Log: turn debugging on... lets see if this will help the test results or not Modified: pypy/dist/pypy/lang/js/test/ecma/conftest.py ============================================================================== --- pypy/dist/pypy/lang/js/test/ecma/conftest.py (original) +++ pypy/dist/pypy/lang/js/test/ecma/conftest.py Tue Feb 20 21:28:03 2007 @@ -5,7 +5,7 @@ from py.__.test.outcome import Failed import pypy.lang.js as js -# js.jsobj.DEBUG = True +js.jsobj.DEBUG = True rootdir = py.magic.autopath().dirpath() exclusionlist = ['shell.js', 'browser.js'] From mwh at codespeak.net Wed Feb 21 09:57:30 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Wed, 21 Feb 2007 09:57:30 +0100 (CET) Subject: [pypy-svn] r39250 - in pypy/extradoc/talk/pycon2007/pycon07.key: . thumbs Message-ID: <20070221085730.18A4D100D0@code0.codespeak.net> Author: mwh Date: Wed Feb 21 09:57:27 2007 New Revision: 39250 Added: pypy/extradoc/talk/pycon2007/pycon07.key/thumbs/mt0-7.tiff (contents, props changed) pypy/extradoc/talk/pycon2007/pycon07.key/thumbs/st1.tiff (contents, props changed) pypy/extradoc/talk/pycon2007/pycon07.key/thumbs/st11.tiff (contents, props changed) pypy/extradoc/talk/pycon2007/pycon07.key/thumbs/st16.tiff (contents, props changed) pypy/extradoc/talk/pycon2007/pycon07.key/thumbs/st22.tiff (contents, props changed) pypy/extradoc/talk/pycon2007/pycon07.key/thumbs/st23-1.tiff (contents, props changed) pypy/extradoc/talk/pycon2007/pycon07.key/thumbs/st25-1.tiff (contents, props changed) pypy/extradoc/talk/pycon2007/pycon07.key/thumbs/st25.tiff (contents, props changed) pypy/extradoc/talk/pycon2007/pycon07.key/thumbs/st28.tiff (contents, props changed) pypy/extradoc/talk/pycon2007/pycon07.key/thumbs/st30.tiff (contents, props changed) pypy/extradoc/talk/pycon2007/pycon07.key/thumbs/st31.tiff (contents, props changed) pypy/extradoc/talk/pycon2007/pycon07.key/thumbs/st32-2.tiff (contents, props changed) pypy/extradoc/talk/pycon2007/pycon07.key/thumbs/st32-3.tiff (contents, props changed) pypy/extradoc/talk/pycon2007/pycon07.key/thumbs/st32-4.tiff (contents, props changed) pypy/extradoc/talk/pycon2007/pycon07.key/thumbs/st32-5.tiff (contents, props changed) pypy/extradoc/talk/pycon2007/pycon07.key/thumbs/st32.tiff (contents, props changed) pypy/extradoc/talk/pycon2007/pycon07.key/thumbs/st7-1.tiff (contents, props changed) Modified: pypy/extradoc/talk/pycon2007/pycon07.key/index.apxl.gz pypy/extradoc/talk/pycon2007/pycon07.key/thumbs/st2.tiff Log: some progress Modified: pypy/extradoc/talk/pycon2007/pycon07.key/index.apxl.gz ============================================================================== Binary files. No diff available. Added: pypy/extradoc/talk/pycon2007/pycon07.key/thumbs/mt0-7.tiff ============================================================================== Binary file. No diff available. Added: pypy/extradoc/talk/pycon2007/pycon07.key/thumbs/st1.tiff ============================================================================== Binary file. No diff available. Added: pypy/extradoc/talk/pycon2007/pycon07.key/thumbs/st11.tiff ============================================================================== Binary file. No diff available. Added: pypy/extradoc/talk/pycon2007/pycon07.key/thumbs/st16.tiff ============================================================================== Binary file. No diff available. Modified: pypy/extradoc/talk/pycon2007/pycon07.key/thumbs/st2.tiff ============================================================================== Binary files. No diff available. Added: pypy/extradoc/talk/pycon2007/pycon07.key/thumbs/st22.tiff ============================================================================== Binary file. No diff available. Added: pypy/extradoc/talk/pycon2007/pycon07.key/thumbs/st23-1.tiff ============================================================================== Binary file. No diff available. Added: pypy/extradoc/talk/pycon2007/pycon07.key/thumbs/st25-1.tiff ============================================================================== Binary file. No diff available. Added: pypy/extradoc/talk/pycon2007/pycon07.key/thumbs/st25.tiff ============================================================================== Binary file. No diff available. Added: pypy/extradoc/talk/pycon2007/pycon07.key/thumbs/st28.tiff ============================================================================== Binary file. No diff available. Added: pypy/extradoc/talk/pycon2007/pycon07.key/thumbs/st30.tiff ============================================================================== Binary file. No diff available. Added: pypy/extradoc/talk/pycon2007/pycon07.key/thumbs/st31.tiff ============================================================================== Binary file. No diff available. Added: pypy/extradoc/talk/pycon2007/pycon07.key/thumbs/st32-2.tiff ============================================================================== Binary file. No diff available. Added: pypy/extradoc/talk/pycon2007/pycon07.key/thumbs/st32-3.tiff ============================================================================== Binary file. No diff available. Added: pypy/extradoc/talk/pycon2007/pycon07.key/thumbs/st32-4.tiff ============================================================================== Binary file. No diff available. Added: pypy/extradoc/talk/pycon2007/pycon07.key/thumbs/st32-5.tiff ============================================================================== Binary file. No diff available. Added: pypy/extradoc/talk/pycon2007/pycon07.key/thumbs/st32.tiff ============================================================================== Binary file. No diff available. Added: pypy/extradoc/talk/pycon2007/pycon07.key/thumbs/st7-1.tiff ============================================================================== Binary file. No diff available. From cfbolz at codespeak.net Wed Feb 21 10:17:50 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 21 Feb 2007 10:17:50 +0100 (CET) Subject: [pypy-svn] r39252 - pypy/extradoc/pypy.org Message-ID: <20070221091750.3E8E710149@code0.codespeak.net> Author: cfbolz Date: Wed Feb 21 10:17:47 2007 New Revision: 39252 Modified: pypy/extradoc/pypy.org/confrest.py Log: make confrest work with the py-lib changes Modified: pypy/extradoc/pypy.org/confrest.py ============================================================================== --- pypy/extradoc/pypy.org/confrest.py (original) +++ pypy/extradoc/pypy.org/confrest.py Wed Feb 21 10:17:47 2007 @@ -14,6 +14,7 @@ " ", id="menubar") class Project(Project): + mydir = py.magic.autopath().dirpath() title = "PyPy EU Project" stylesheet = 'http://codespeak.net/pypy/dist/pypy/doc/style.css' encoding = 'latin1' From cfbolz at codespeak.net Wed Feb 21 10:18:02 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 21 Feb 2007 10:18:02 +0100 (CET) Subject: [pypy-svn] r39253 - pypy/extradoc/pypy.org Message-ID: <20070221091802.D98D510149@code0.codespeak.net> Author: cfbolz Date: Wed Feb 21 10:17:56 2007 New Revision: 39253 Modified: pypy/extradoc/pypy.org/news.txt Log: update news a bit Modified: pypy/extradoc/pypy.org/news.txt ============================================================================== --- pypy/extradoc/pypy.org/news.txt (original) +++ pypy/extradoc/pypy.org/news.txt Wed Feb 21 10:17:56 2007 @@ -1,9 +1,56 @@ +PyPy 0.99.0: optimizations, backends, new object spaces and more +------------------------------------------------------------------- + +We are proud to release PyPy 0.99.0, our fifth public release. See +the `release announcement `__ to read about the +many new features in this release. See also our detailed instructions on +how to `get started`_. *(February 17th, 2007)* + +.. _`get started`: http://codespeak.net/pypy/dist/pypy/doc/getting-started.html + + +py lib 0.9.0: py.test, distributed execution, greenlets and more +------------------------------------------------------------------- + +Our development support and testing library was publically released, see the +`0.9 release announcement `__ +and its extensive `online documentation `__. +*(February 15th, 2007)* + + +Leysin Sprint, 8th - 14th January 2007 +--------------------------------------------------------- + +The PyPy Leysin sprint is over. We worked hard on various topics, including +preparing the upcoming py-lib and PyPy releases. For more details, see the +`Leysin sprint report`_, the `Leysin announcement`_ and the +`list of people present`_. + +.. _`Leysin announcement`: http://codespeak.net/pypy/extradoc/sprintinfo/leysin-winter-2007/announcement.html +.. _`Leysin sprint report`: http://codespeak.net/pipermail/pypy-dev/2007q1/003481.html +.. _`list of people present`: http://codespeak.net/svn/pypy/extradoc/sprintinfo/leysin-winter-2007/people.txt + + + + +Duesseldorf sprint #2, 30th October - 5th November over +---------------------------------------------------------- + +PyPy has sprinted at the Heinrich-Heine-Universit?t D?sseldorf. +It was a very productive sprint with work done +in various areas. Read the `sprint report`_ for a detailed description of what +was achieved and the `full announcement`_ for various details. + +.. _`full announcement`: http://codespeak.net/pypy/extradoc/sprintinfo/ddorf2006b/announce.html +.. _`sprint report`: http://codespeak.net/pipermail/pypy-dev/2006q4/003396.html + + PyPy at University of Limerick: sprint and workshop 21-28th of August 2006 ------------------------------------------------------------------------------- -PyPy will sprint at the University of Limerick in Ireland, hosted by partners in our -sister project Calibre. During the first day of the sprint, the 21st, we will -arrange a workshop with tutorials, talks and discussions on both technical (JIT, VM) +PyPy has sprinted at the University of Limerick in Ireland, hosted by partners in our +sister project Calibre. During the first day of the sprint, the 21st, we +arranged a workshop with tutorials, talks and discussions on both technical (JIT, VM) and methodological topics (F/OSS/Agile, Distributed). See sprint announcement http://codespeak.net/pypy/extradoc/sprintinfo/ireland-2006/announce.html From cfbolz at codespeak.net Wed Feb 21 10:20:17 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 21 Feb 2007 10:20:17 +0100 (CET) Subject: [pypy-svn] r39254 - pypy/extradoc/pypy.org Message-ID: <20070221092017.6C44010154@code0.codespeak.net> Author: cfbolz Date: Wed Feb 21 10:20:14 2007 New Revision: 39254 Modified: pypy/extradoc/pypy.org/consortium.txt Log: remove another mention of strakt Modified: pypy/extradoc/pypy.org/consortium.txt ============================================================================== --- pypy/extradoc/pypy.org/consortium.txt (original) +++ pypy/extradoc/pypy.org/consortium.txt Wed Feb 21 10:20:14 2007 @@ -7,7 +7,7 @@ Alastair Burt [alastair.burt at dfki de] Anders Lehmann [anders.lehmann at dfki de] -AB Strakt http://www.strakt.com +Open End AB (formerly AB Strakt) http://www.openend.se Jacob Hall?n [jacob at strakt com] (project manager) Samuele Pedroni [pedronis at strakt com] (technical board) Anders Chrigstr?m [ac at strakt com] From alix at codespeak.net Wed Feb 21 10:40:13 2007 From: alix at codespeak.net (alix at codespeak.net) Date: Wed, 21 Feb 2007 10:40:13 +0100 (CET) Subject: [pypy-svn] r39255 - pypy/extradoc/sprintinfo/trillke-2007 Message-ID: <20070221094013.5DAF910158@code0.codespeak.net> Author: alix Date: Wed Feb 21 10:40:09 2007 New Revision: 39255 Modified: pypy/extradoc/sprintinfo/trillke-2007/people.txt Log: updated Modified: pypy/extradoc/sprintinfo/trillke-2007/people.txt ============================================================================== --- pypy/extradoc/sprintinfo/trillke-2007/people.txt (original) +++ pypy/extradoc/sprintinfo/trillke-2007/people.txt Wed Feb 21 10:40:09 2007 @@ -13,22 +13,22 @@ Samuele Pedroni 25th-5th Parkhotel Bergh?lzchen Anders Chrigstr?m 25th-5th Parkhotel Bergh?lzchen Christian Tismer 28th-5th Klocke -Anders Sigfridsson 2-4th klocke +Anders Sigfridsson 1st-5thth klocke Michael Hudson 27th-5th klocke Antonio Cuni 25th-5th klocke -TAV? 1-4th? undetermined +Richard Emslie 27thh klocke +Stefan Busemann 26th-28th klocke +TAV? 1st-4th? undetermined Stephan Diehl 2nd-4th private/shared alex Alexander Schremmer 1st-5th private/shared stephan Maciej Fijalkowski 28-6th+X private Guido Wesdorp 26th-5th private Carl Friedrich Bolz 25th-6th private Armin Rigo 26th-6+X private -Jens-Uwe Mager 1-4th?? private +Jens-Uwe Mager 1st-4th?? private Holger Krekel 25th-8th private Alix Einfeldt 25th-8th private Lene Wagner 25th-8th private -Richard Emslie ?-5th (klocke) -Stefan Busemann 26th-28th klocke ==================== ============== ===================== People on the following list were present at previous sprints: From ac at codespeak.net Wed Feb 21 10:51:12 2007 From: ac at codespeak.net (ac at codespeak.net) Date: Wed, 21 Feb 2007 10:51:12 +0100 (CET) Subject: [pypy-svn] r39257 - pypy/dist/lib-python/modified-2.4.1 Message-ID: <20070221095112.82EBB10167@code0.codespeak.net> Author: ac Date: Wed Feb 21 10:51:11 2007 New Revision: 39257 Modified: pypy/dist/lib-python/modified-2.4.1/socket.py Log: _fileobject needs to parttake in the recounting of the socket object. Modified: pypy/dist/lib-python/modified-2.4.1/socket.py ============================================================================== --- pypy/dist/lib-python/modified-2.4.1/socket.py (original) +++ pypy/dist/lib-python/modified-2.4.1/socket.py Wed Feb 21 10:51:11 2007 @@ -144,6 +144,8 @@ raise error(EBADF, 'Bad file descriptor') def _drop(self): pass + def _reuse(self): + pass send = recv = sendto = recvfrom = __getattr__ = _dummy class _socketobject(object): @@ -188,6 +190,7 @@ Return a regular file object corresponding to the socket. The mode and bufsize arguments are as for the built-in open() function.""" + self._sock._reuse() return _fileobject(self._sock, mode, bufsize) _s = ("def %s(self, *args): return self._sock.%s(*args)\n\n" @@ -232,6 +235,7 @@ try: if self._sock: self.flush() + self._sock._drop() finally: self._sock = None From fijal at codespeak.net Wed Feb 21 10:53:57 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 21 Feb 2007 10:53:57 +0100 (CET) Subject: [pypy-svn] r39259 - pypy/dist/pypy/translator/js/examples Message-ID: <20070221095357.3B88A1016C@code0.codespeak.net> Author: fijal Date: Wed Feb 21 10:53:56 2007 New Revision: 39259 Removed: pypy/dist/pypy/translator/js/examples/console.py Log: Remove outdated demo From ac at codespeak.net Wed Feb 21 10:55:05 2007 From: ac at codespeak.net (ac at codespeak.net) Date: Wed, 21 Feb 2007 10:55:05 +0100 (CET) Subject: [pypy-svn] r39260 - pypy/dist/lib-python/modified-2.4.1 Message-ID: <20070221095505.6926E1016F@code0.codespeak.net> Author: ac Date: Wed Feb 21 10:55:04 2007 New Revision: 39260 Modified: pypy/dist/lib-python/modified-2.4.1/socket.py Log: Slightly more robust refounting. Modified: pypy/dist/lib-python/modified-2.4.1/socket.py ============================================================================== --- pypy/dist/lib-python/modified-2.4.1/socket.py (original) +++ pypy/dist/lib-python/modified-2.4.1/socket.py Wed Feb 21 10:55:04 2007 @@ -232,12 +232,14 @@ closed = property(_getclosed, doc="True if the file is closed") def close(self): - try: - if self._sock: + if self._sock: + try: self.flush() - self._sock._drop() - finally: - self._sock = None + finally: + if self._sock: + s = self._sock + self._sock = None + s._drop() def __del__(self): try: From hpk at codespeak.net Wed Feb 21 11:08:36 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Wed, 21 Feb 2007 11:08:36 +0100 (CET) Subject: [pypy-svn] r39261 - pypy/extradoc/pypy.org Message-ID: <20070221100836.4C0F510174@code0.codespeak.net> Author: hpk Date: Wed Feb 21 11:08:34 2007 New Revision: 39261 Modified: pypy/extradoc/pypy.org/confrest.py Log: fix confrest to adhere to docpath lookup Modified: pypy/extradoc/pypy.org/confrest.py ============================================================================== --- pypy/extradoc/pypy.org/confrest.py (original) +++ pypy/extradoc/pypy.org/confrest.py Wed Feb 21 11:08:34 2007 @@ -13,6 +13,10 @@ class_="menu"), " ", " ", id="menubar") + def get_doclink(self, target): + return relpath(self.targetpath.strpath, + self.project.get_docpath().join(target).strpath) + class Project(Project): mydir = py.magic.autopath().dirpath() title = "PyPy EU Project" @@ -28,5 +32,7 @@ height=105, width=213), ) Page = PyPyPage + def get_docpath(self): + return self.mydir From cfbolz at codespeak.net Wed Feb 21 11:46:02 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 21 Feb 2007 11:46:02 +0100 (CET) Subject: [pypy-svn] r39262 - pypy/dist/pypy/doc/statistic Message-ID: <20070221104602.BE8981017D@code0.codespeak.net> Author: cfbolz Date: Wed Feb 21 11:46:01 2007 New Revision: 39262 Modified: pypy/dist/pypy/doc/statistic/subscribers.txt Log: update subscription logs Modified: pypy/dist/pypy/doc/statistic/subscribers.txt ============================================================================== --- pypy/dist/pypy/doc/statistic/subscribers.txt (original) +++ pypy/dist/pypy/doc/statistic/subscribers.txt Wed Feb 21 11:46:01 2007 @@ -929,3 +929,169 @@ 2006/07/14, 310, 56 2006/07/15, 310, 56 2006/07/16, 310, 56 +2006-07-17, 293, 55 +2006-07-19, 293, 55 +2006-07-20, 294, 56 +2006-07-21, 294, 56 +2006-07-23, 294, 56 +2006-07-24, 295, 56 +2006-07-25, 293, 56 +2006-07-26, 292, 56 +2006-07-27, 290, 56 +2006-07-30, 290, 56 +2006-07-31, 290, 56 +2006-08-01, 291, 56 +2006-08-02, 290, 56 +2006-08-03, 290, 56 +2006-08-04, 290, 56 +2006-08-05, 290, 56 +2006-08-07, 290, 56 +2006-08-09, 290, 56 +2006-08-10, 290, 56 +2006-08-11, 291, 56 +2006-08-12, 291, 56 +2006-08-15, 291, 56 +2006-08-16, 291, 56 +2006-08-17, 292, 56 +2006-08-19, 293, 56 +2006-08-21, 294, 56 +2006-08-22, 293, 56 +2006-08-23, 293, 56 +2006-08-24, 293, 56 +2006-08-25, 296, 58 +2006-08-26, 297, 57 +2006-08-29, 297, 57 +2006-08-30, 297, 57 +2006-08-31, 297, 57 +2006-09-01, 297, 57 +2006-09-02, 297, 57 +2006-09-03, 297, 57 +2006-09-05, 297, 57 +2006-09-06, 297, 57 +2006-09-07, 297, 57 +2006-09-08, 297, 58 +2006-09-11, 298, 58 +2006-09-12, 298, 58 +2006-09-13, 298, 58 +2006-09-14, 301, 58 +2006-09-15, 301, 58 +2006-09-16, 302, 58 +2006-09-17, 303, 58 +2006-09-18, 303, 58 +2006-09-19, 304, 58 +2006-09-20, 305, 58 +2006-09-22, 305, 58 +2006-09-23, 306, 58 +2006-09-25, 306, 58 +2006-09-26, 306, 58 +2006-09-27, 306, 58 +2006-09-28, 306, 58 +2006-09-29, 307, 58 +2006-09-30, 308, 58 +2006-10-01, 308, 58 +2006-10-02, 308, 58 +2006-10-03, 309, 58 +2006-10-04, 309, 57 +2006-10-05, 310, 57 +2006-10-06, 312, 57 +2006-10-07, 312, 57 +2006-10-10, 313, 57 +2006-10-11, 313, 57 +2006-10-12, 313, 57 +2006-10-13, 313, 57 +2006-10-14, 313, 57 +2006-10-16, 315, 57 +2006-10-17, 316, 57 +2006-10-18, 316, 57 +2006-10-19, 316, 57 +2006-10-20, 316, 57 +2006-10-21, 316, 57 +2006-10-23, 316, 57 +2006-10-24, 317, 57 +2006-10-25, 317, 57 +2006-10-26, 317, 57 +2006-10-28, 317, 57 +2006-10-29, 317, 57 +2006-10-30, 318, 57 +2006-10-31, 317, 57 +2006-11-02, 318, 57 +2006-11-03, 318, 57 +2006-11-04, 318, 57 +2006-11-06, 318, 56 +2006-11-07, 318, 56 +2006-11-08, 318, 56 +2006-11-09, 319, 56 +2006-11-10, 319, 56 +2006-11-11, 319, 56 +2006-11-13, 320, 56 +2006-11-14, 320, 56 +2006-11-15, 320, 56 +2006-11-16, 321, 56 +2006-11-17, 320, 56 +2006-11-21, 320, 56 +2006-11-22, 321, 56 +2006-11-24, 320, 56 +2006-11-25, 322, 56 +2006-11-27, 322, 56 +2006-11-28, 323, 56 +2006-11-29, 322, 56 +2006-11-30, 322, 56 +2006-12-01, 322, 55 +2006-12-04, 322, 55 +2006-12-05, 323, 55 +2006-12-06, 322, 55 +2006-12-08, 323, 55 +2006-12-10, 323, 55 +2006-12-11, 323, 55 +2006-12-14, 323, 55 +2006-12-19, 323, 55 +2006-12-21, 323, 55 +2006-12-24, 323, 55 +2006-12-27, 323, 55 +2006-12-28, 323, 55 +2006-12-29, 324, 55 +2006-12-30, 324, 55 +2006-12-31, 323, 55 +2007-01-02, 322, 55 +2007-01-03, 322, 55 +2007-01-04, 322, 55 +2007-01-05, 322, 55 +2007-01-07, 322, 55 +2007-01-08, 321, 55 +2007-01-09, 322, 55 +2007-01-11, 322, 55 +2007-01-12, 322, 55 +2007-01-14, 322, 55 +2007-01-15, 322, 55 +2007-01-16, 323, 55 +2007-01-18, 324, 55 +2007-01-19, 324, 55 +2007-01-22, 324, 55 +2007-01-23, 324, 56 +2007-01-24, 324, 56 +2007-01-25, 324, 56 +2007-01-26, 323, 56 +2007-01-27, 322, 56 +2007-01-28, 322, 56 +2007-01-29, 322, 56 +2007-01-30, 322, 55 +2007-01-31, 321, 55 +2007-02-01, 321, 55 +2007-02-02, 321, 55 +2007-02-03, 321, 55 +2007-02-04, 321, 55 +2007-02-05, 320, 55 +2007-02-06, 320, 55 +2007-02-07, 321, 55 +2007-02-08, 321, 55 +2007-02-09, 322, 55 +2007-02-10, 322, 55 +2007-02-11, 322, 55 +2007-02-12, 322, 55 +2007-02-13, 322, 55 +2007-02-14, 322, 55 +2007-02-15, 322, 55 +2007-02-16, 323, 55 +2007-02-17, 324, 56 +2007-02-18, 323, 56 +2007-02-19, 324, 56 From cfbolz at codespeak.net Wed Feb 21 12:43:16 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 21 Feb 2007 12:43:16 +0100 (CET) Subject: [pypy-svn] r39266 - pypy/dist/pypy/doc/statistic Message-ID: <20070221114316.23B9110187@code0.codespeak.net> Author: cfbolz Date: Wed Feb 21 12:43:14 2007 New Revision: 39266 Modified: pypy/dist/pypy/doc/statistic/post.txt Log: update posting statistics Modified: pypy/dist/pypy/doc/statistic/post.txt ============================================================================== --- pypy/dist/pypy/doc/statistic/post.txt (original) +++ pypy/dist/pypy/doc/statistic/post.txt Wed Feb 21 12:43:14 2007 @@ -42,3 +42,10 @@ 2006-4,138,961 2006-5,67,609 2006-6,38,757 +2006-7, 111, 687 +2006-8, 60, 506 +2006-9, 11, 436 +2006-10, 27, 521 +2006-11, 32, 659 +2006-12, 57, 514 +2007-1, 37, 742 From fijal at codespeak.net Wed Feb 21 12:58:40 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 21 Feb 2007 12:58:40 +0100 (CET) Subject: [pypy-svn] r39267 - pypy/dist/pypy/lib/distributed/test Message-ID: <20070221115840.622B21018B@code0.codespeak.net> Author: fijal Date: Wed Feb 21 12:58:38 2007 New Revision: 39267 Modified: pypy/dist/pypy/lib/distributed/test/test_distributed.py Log: Fix skip Modified: pypy/dist/pypy/lib/distributed/test/test_distributed.py ============================================================================== --- pypy/dist/pypy/lib/distributed/test/test_distributed.py (original) +++ pypy/dist/pypy/lib/distributed/test/test_distributed.py Wed Feb 21 12:58:38 2007 @@ -199,7 +199,7 @@ raise AssertionError("Did not raise") def test_instantiate_remote_type(self): - py.test.skip("Land of infinite recursion") + skip("Land of infinite recursion") from distributed import test_env class C: From mwh at codespeak.net Wed Feb 21 13:02:49 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Wed, 21 Feb 2007 13:02:49 +0100 (CET) Subject: [pypy-svn] r39269 - pypy/extradoc/talk/pycon2007/demos Message-ID: <20070221120249.A72DA10196@code0.codespeak.net> Author: mwh Date: Wed Feb 21 13:02:46 2007 New Revision: 39269 Added: pypy/extradoc/talk/pycon2007/demos/ pypy/extradoc/talk/pycon2007/demos/enabledo.py (contents, props changed) Log: demo no 1: code stolen from test_dyngram to add a do:until: statement at runtime. Added: pypy/extradoc/talk/pycon2007/demos/enabledo.py ============================================================================== --- (empty file) +++ pypy/extradoc/talk/pycon2007/demos/enabledo.py Wed Feb 21 13:02:46 2007 @@ -0,0 +1,43 @@ +import dyngram, parser + +newrules = """ +compound_stmt: if_stmt | on_stmt | unless_stmt | dountil_stmt | while_stmt | for_stmt | try_stmt | with_stmt | funcdef | classdef +dountil_stmt: 'do' ':' suite 'until' test +unless_stmt: 'unless' test ':' suite +on_stmt: 'on' NAME '=' test ':' suite ['else' ':' suite] +""" + +def build_dountil_stmt(items): + """ 'do' ':' suite 'until' ':' test """ + lineno = items[0].lineno + suite = items[2] + test = items[-1] + while_stmt = parser.ASTWhile(parser.ASTNot(test), suite, None, lineno) + return parser.ASTStmt([suite, while_stmt], lineno) + +def build_unless_stmt(its): + """ 'unless' test ':' suite """ + lineno = its[0].lineno + return parser.ASTIf([(parser.ASTNot(its[1]), its[3])], None, lineno) + +def make_assignment(var, node): + # XXX: consts.OP_APPLY + return parser.ASTAssign([parser.ASTAssName('x', 0)], node) + +def build_on_stmt(items): + """ 'on' NAME = test ':' suite 'else' ':' suite""" + varname = items[1].value + test = items[3] + suite = items[5] + assign = make_assignment(varname, test) + if len(items) == 9: + else_ = items[-1] + else: + else_ = None + test = parser.ASTIf([(parser.ASTName(varname), suite)], else_, items[0].lineno) + return parser.ASTStmt([assign, test], items[0].lineno) + +dyngram.insert_grammar_rule(newrules, {'dountil_stmt' : build_dountil_stmt, + 'unless_stmt': build_unless_stmt, + 'on_stmt' : build_on_stmt, + }) From mwh at codespeak.net Wed Feb 21 13:04:08 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Wed, 21 Feb 2007 13:04:08 +0100 (CET) Subject: [pypy-svn] r39270 - pypy/extradoc/talk/pycon2007/demos Message-ID: <20070221120408.61ED41019E@code0.codespeak.net> Author: mwh Date: Wed Feb 21 13:04:06 2007 New Revision: 39270 Added: pypy/extradoc/talk/pycon2007/demos/listserver.py (contents, props changed) pypy/extradoc/talk/pycon2007/demos/proxy.py (contents, props changed) Log: demo no 2: a silly web server that serves up a list, and a list proxy that uses it for the items of the list. Added: pypy/extradoc/talk/pycon2007/demos/listserver.py ============================================================================== --- (empty file) +++ pypy/extradoc/talk/pycon2007/demos/listserver.py Wed Feb 21 13:04:06 2007 @@ -0,0 +1,66 @@ +from nevow import inevow, tags, loaders, rend, appserver +from twisted.application import internet, service +from zope.interface import implements +import random + +class GetItem(object): + implements(inevow.IResource) + def __init__(self, sharedlist): + self.sharedlist = sharedlist + def renderHTTP(self, ctx): + item = int(ctx.arg('item')) + req = ctx.locate(inevow.IRequest) + req.setHeader('content-type', "text/plain") + return str(self.sharedlist[item]) + +class SetItem(object): + implements(inevow.IResource) + def __init__(self, sharedlist): + self.sharedlist = sharedlist + def renderHTTP(self, ctx): + item = int(ctx.arg('item')) + value = int(ctx.arg('value')) + self.sharedlist[item] = value + req = ctx.locate(inevow.IRequest) + req.redirect('/') + return '' + +class Root(rend.Page): + def __init__(self, sharedlist): + rend.Page.__init__(self) + self.sharedlist = sharedlist + docFactory = loaders.xmlstr('''\ + + + + A list + + +
+ Get Item: +
+
+ Set Item: +
+ + + ''') + def render_list(self, ctx, data): + return ctx.tag.fillSlots('list', str(self.sharedlist)) + +theList = range(10) +random.shuffle(theList) + +application = service.Application("pydoctor demo") + +root = Root(theList) +root.putChild('getitem', GetItem(theList)) +root.putChild('setitem', SetItem(theList)) + +internet.TCPServer( + 8080, + appserver.NevowSite( + root + ) +).setServiceParent(application) Added: pypy/extradoc/talk/pycon2007/demos/proxy.py ============================================================================== --- (empty file) +++ pypy/extradoc/talk/pycon2007/demos/proxy.py Wed Feb 21 13:04:06 2007 @@ -0,0 +1,101 @@ +from pypymagic import transparent_proxy +import urllib + +class ControllerBase(object): + def perform(self, name, *args, **kw): + if name.startswith('__') and name.endswith('__'): + attr = 'special_' + name[2:-2] + else: + attr = 'meth_' + name + return getattr(self, attr)(*args, **kw) + +class ListControllerBase(ControllerBase): + """ implementation of list behaviour in terms of just 'getitem', + 'setitem' and 'insert'. """ + + def getitem(self, item): + raise NotImplementedError + + def setitem(self, item, value): + raise NotImplementedError + + def delitem(self, item): + raise NotImplementedError + + def insert(self, item, value): + raise NotImplementedError + + def len(self): + """ you probably want to override this too """ + return len(list(self._iter())) + + # ---------------------------------------------------------------- + + def special_getitem(self, item): + if isinstance(item, slice): + return [self.getitem(i) for i in range(*item.indices(self.len()))] + else: + return self.getitem(item) + + def special_setitem(self, item, value): + self.setitem(item, value) + + def special_delitem(self, item): + self.delitem(item) + + def special_len(self): + return self.len() + + def special_repr(self): + r = [] + for i in range(len(self.proxy)): + r.append(repr(self.proxy[i])) + return '[' + ', '.join(r) + ']' + + def special_contains(self, obj): + for o in self._iter(): + if o == obj: + return True + return False + + def meth_insert(self, item, value): + self.insert(item, value) + + def _iter(self): + i = 0 + while 1: + try: + yield self.getitem(i) + except IndexError: + return + i += 1 + +class SillyListController(ListControllerBase): + def getitem(self, item): + if item > 9: + raise IndexError + else: + return int(urllib.urlopen("http://localhost:8080/getitem?item=" + str(item)).read()) + + def setitem(self, item, value): + if item > 9: + raise IndexError + else: + data = urllib.urlencode({'item':item, 'value':value}) + urllib.urlopen('http://localhost:8080/setitem', data=data).read() + +def l(): + c = SillyListController() + c.proxy = transparent_proxy(list, c.perform) + return c.proxy + +class InstanceController(object): + pass + +def wrap(cls, obj): + controller = cls(obj) + controller.proxy = transparent_proxy(type(obj), controller.perform) + return controller.proxy + +if __name__ == '__main__': + print l()[0] From xoraxax at codespeak.net Wed Feb 21 14:39:43 2007 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Wed, 21 Feb 2007 14:39:43 +0100 (CET) Subject: [pypy-svn] r39276 - pypy/extradoc/sprintinfo/trillke-2007 Message-ID: <20070221133943.5B7C0101AC@code0.codespeak.net> Author: xoraxax Date: Wed Feb 21 14:39:39 2007 New Revision: 39276 Modified: pypy/extradoc/sprintinfo/trillke-2007/people.txt Log: TAV will not be able to come, according to #pypy. Modified: pypy/extradoc/sprintinfo/trillke-2007/people.txt ============================================================================== --- pypy/extradoc/sprintinfo/trillke-2007/people.txt (original) +++ pypy/extradoc/sprintinfo/trillke-2007/people.txt Wed Feb 21 14:39:39 2007 @@ -18,7 +18,6 @@ Antonio Cuni 25th-5th klocke Richard Emslie 27thh klocke Stefan Busemann 26th-28th klocke -TAV? 1st-4th? undetermined Stephan Diehl 2nd-4th private/shared alex Alexander Schremmer 1st-5th private/shared stephan Maciej Fijalkowski 28-6th+X private From fijal at codespeak.net Wed Feb 21 15:02:21 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 21 Feb 2007 15:02:21 +0100 (CET) Subject: [pypy-svn] r39277 - in pypy/dist/pypy/translator/js/examples: . data test Message-ID: <20070221140221.B6E85101C0@code0.codespeak.net> Author: fijal Date: Wed Feb 21 15:02:19 2007 New Revision: 39277 Added: pypy/dist/pypy/translator/js/examples/console.py pypy/dist/pypy/translator/js/examples/data/console.html pypy/dist/pypy/translator/js/examples/test/test_console.py Modified: pypy/dist/pypy/translator/js/examples/test/test_examples.py Log: Added example of console involving subprocess Added: pypy/dist/pypy/translator/js/examples/console.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/js/examples/console.py Wed Feb 21 15:02:19 2007 @@ -0,0 +1,97 @@ + +import subprocess +import fcntl +import os +import py +import time + +from pypy.translator.js.lib import server +from pypy.translator.js.main import rpython2javascript +from pypy.translator.js.lib.support import callback +from pypy.translator.js import commproxy + +commproxy.USE_MOCHIKIT = True + +FUNCTION_LIST = ["console_onload"] + + +def js_source(): + import console_client + return rpython2javascript(console_client, FUNCTION_LIST) + +def run_console(python): + pipe = subprocess.Popen([python, "-u", "-i"], stdout=subprocess.PIPE, + stdin=subprocess.PIPE, stderr=subprocess.STDOUT, + close_fds=True, bufsize=0) + # a bit of POSIX voodoo + fcntl.fcntl(pipe.stdout.fileno(), fcntl.F_SETFL, os.O_NONBLOCK) + return pipe + +def interact(pipe, to_write=None): + if to_write is not None: + pipe.stdin.write(to_write + "\n") + try: + return pipe.stdout.read() + except IOError: + time.sleep(.1) + return "" + +class Sessions(object): + def __init__(self): + self.sessions = {} + + def new_session(self): + pipe = run_console("python") + self.sessions[pipe.pid] = pipe + return pipe.pid + + def update_session(self, pid, to_write=None): + pipe = self.sessions[pid] + return interact(pipe, to_write) + +# We hack here, cause in exposed methods we don't have global 'server' +# state +sessions = Sessions() + +class ExportedMethods(server.ExportedMethods): + @callback(retval=int) + def get_console(self): + retval = sessions.new_session() + return retval + + @callback(retval=[str]) + def refresh(self, pid=0, to_write=""): + try: + return ["refresh", sessions.update_session(int(pid), to_write)] + except KeyError: + return ["disconnected"] + + @callback(retval=[str]) + def refresh_empty(self, pid=0): + try: + return ["refresh", sessions.update_session(int(pid), None)] + except KeyError: + return ["disconnected"] + + +exported_methods = ExportedMethods() + +class Handler(server.Handler): + exported_methods = exported_methods + static_dir = py.path.local(__file__).dirpath().join("data") + index = server.Static(static_dir.join("console.html")) + MochiKit = server.StaticDir('MochiKit') + + def source_js(self): + if hasattr(self.server, 'source'): + source = self.server.source + else: + source = js_source() + self.server.source = source + return "text/javascript", source + source_js.exposed = True + +if __name__ == '__main__': + addr = ('', 8007) + httpd = server.create_server(server_address=addr, handler=Handler) + httpd.serve_forever() Added: pypy/dist/pypy/translator/js/examples/data/console.html ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/js/examples/data/console.html Wed Feb 21 15:02:19 2007 @@ -0,0 +1,15 @@ + + + + + Console + + + +

Python console

+

+   >>> 
+   

+ + \ No newline at end of file Added: pypy/dist/pypy/translator/js/examples/test/test_console.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/js/examples/test/test_console.py Wed Feb 21 15:02:19 2007 @@ -0,0 +1,16 @@ + +from pypy.translator.js.examples import console + +def test_run_console(): + """ Check if we can read anything + """ + pipe = console.run_console("python") + pipe.stdin.close() + t = False + while not t: + try: + d = pipe.stdout.read() + t = True + except IOError: + import time + time.sleep(.1) Modified: pypy/dist/pypy/translator/js/examples/test/test_examples.py ============================================================================== --- pypy/dist/pypy/translator/js/examples/test/test_examples.py (original) +++ pypy/dist/pypy/translator/js/examples/test/test_examples.py Wed Feb 21 15:02:19 2007 @@ -26,3 +26,7 @@ use_pdb=False) +def test_console_2_build(): + from pypy.translator.js.examples import console, console_client + assert rpython2javascript(console_client, console.FUNCTION_LIST, + use_pdb=False) From fijal at codespeak.net Wed Feb 21 15:03:44 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 21 Feb 2007 15:03:44 +0100 (CET) Subject: [pypy-svn] r39278 - pypy/dist/pypy/translator/js/examples/data Message-ID: <20070221140344.2DFE8101C4@code0.codespeak.net> Author: fijal Date: Wed Feb 21 15:03:41 2007 New Revision: 39278 Modified: pypy/dist/pypy/translator/js/examples/data/console.html Log: Import global mochikit by default Modified: pypy/dist/pypy/translator/js/examples/data/console.html ============================================================================== --- pypy/dist/pypy/translator/js/examples/data/console.html (original) +++ pypy/dist/pypy/translator/js/examples/data/console.html Wed Feb 21 15:03:41 2007 @@ -1,7 +1,7 @@ - + Console From cfbolz at codespeak.net Wed Feb 21 15:34:48 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 21 Feb 2007 15:34:48 +0100 (CET) Subject: [pypy-svn] r39285 - pypy/dist/pypy/doc/statistic Message-ID: <20070221143448.764C5101BF@code0.codespeak.net> Author: cfbolz Date: Wed Feb 21 15:34:46 2007 New Revision: 39285 Added: pypy/dist/pypy/doc/statistic/python-list.txt Log: mentions on c.l.p. easy to do, but not that interesting Added: pypy/dist/pypy/doc/statistic/python-list.txt ============================================================================== --- (empty file) +++ pypy/dist/pypy/doc/statistic/python-list.txt Wed Feb 21 15:34:46 2007 @@ -0,0 +1,52 @@ +Activity on comp.lang.python +date, "pypy", "py.test" +2003-1, 112, 0 +2003-2, 78, 5 +2003-3, 1, 0 +2003-4, 2, 0 +2003-5, 2, 0 +2003-6, 32, 0 +2003-7, 23, 0 +2003-8, 23, 0 +2003-9, 30, 0 +2003-10, 46, 0 +2003-11, 42, 0 +2003-12, 14, 0 +2004-1, 41, 0 +2004-2, 10, 0 +2004-3, 18, 0 +2004-4, 30, 0 +2004-5, 8, 0 +2004-6, 4, 0 +2004-7, 19, 0 +2004-8, 22, 0 +2004-9, 0, 0 +2004-10, 55, 0 +2004-11, 9, 16 +2004-12, 36, 5 +2005-1, 50, 1 +2005-2, 65, 23 +2005-3, 12, 0 +2005-4, 23, 128 +2005-5, 245, 4 +2005-6, 37, 4 +2005-7, 20, 1 +2005-8, 134, 9 +2005-9, 68, 3 +2005-10, 39, 0 +2005-11, 102, 9 +2005-12, 173, 5 +2006-1, 90, 21 +2006-2, 77, 14 +2006-3, 42, 9 +2006-4, 37, 3 +2006-5, 7, 3 +2006-6, 100, 2 +2006-7, 75, 4 +2006-8, 18, 0 +2006-9, 57, 11 +2006-10, 15, 0 +2006-11, 98, 0 +2006-12, 47, 0 +2007-1, 35, 1 +2007-2, 71, 5 From ludal at codespeak.net Wed Feb 21 16:58:18 2007 From: ludal at codespeak.net (ludal at codespeak.net) Date: Wed, 21 Feb 2007 16:58:18 +0100 (CET) Subject: [pypy-svn] r39294 - pypy/dist/pypy/doc Message-ID: <20070221155818.ADD80101BF@code0.codespeak.net> Author: ludal Date: Wed Feb 21 16:58:17 2007 New Revision: 39294 Modified: pypy/dist/pypy/doc/cleanup-todo.txt Log: add some notes to cleanup-todo.txt Modified: pypy/dist/pypy/doc/cleanup-todo.txt ============================================================================== --- pypy/dist/pypy/doc/cleanup-todo.txt (original) +++ pypy/dist/pypy/doc/cleanup-todo.txt Wed Feb 21 16:58:17 2007 @@ -14,8 +14,15 @@ - keepalives need to die, finally - change weakrefs to work together with the GC +C backend +~~~~~~~~~ + + - check why .rodata section gets bigger when compiled with inlining + - try to generate const struct {...} for contant rpython strings + interpreter ----------- - review the things implemented at applevel whether they are performance- critical + From auc at codespeak.net Wed Feb 21 17:03:05 2007 From: auc at codespeak.net (auc at codespeak.net) Date: Wed, 21 Feb 2007 17:03:05 +0100 (CET) Subject: [pypy-svn] r39295 - pypy/dist/pypy/module/_cslib Message-ID: <20070221160305.9B4CD101C0@code0.codespeak.net> Author: auc Date: Wed Feb 21 17:02:58 2007 New Revision: 39295 Modified: pypy/dist/pypy/module/_cslib/constraint.py Log: re oops Modified: pypy/dist/pypy/module/_cslib/constraint.py ============================================================================== --- pypy/dist/pypy/module/_cslib/constraint.py (original) +++ pypy/dist/pypy/module/_cslib/constraint.py Wed Feb 21 17:02:58 2007 @@ -10,7 +10,7 @@ from pypy.objspace.std.dictobject import W_DictObject from pypy.module._cslib.fd import _FiniteDomain -from pypy.rlib import rconstraint as rc +from pypy.rlib.cslib import rconstraint as rc class W_AbstractConstraint(baseobjspace.Wrappable): From pedronis at codespeak.net Wed Feb 21 17:08:07 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Wed, 21 Feb 2007 17:08:07 +0100 (CET) Subject: [pypy-svn] r39296 - pypy/dist/pypy/objspace Message-ID: <20070221160807.2043F101A9@code0.codespeak.net> Author: pedronis Date: Wed Feb 21 17:08:05 2007 New Revision: 39296 Modified: pypy/dist/pypy/objspace/thunk.py Log: make this translate again. Modified: pypy/dist/pypy/objspace/thunk.py ============================================================================== --- pypy/dist/pypy/objspace/thunk.py (original) +++ pypy/dist/pypy/objspace/thunk.py Wed Feb 21 17:08:05 2007 @@ -97,7 +97,7 @@ app_become = gateway.interp2app(become) def lazy(space, w_callable): - meth = Method(space, space.wrap(app_thunk), + meth = Method(space, space.w_fn_thunk, w_callable, space.type(w_callable)) return space.wrap(meth) app_lazy = gateway.interp2app(lazy) @@ -173,8 +173,9 @@ space = std.Space(*args, **kwds) patch_space_in_place(space, 'thunk', proxymaker) w_pypymagic = space.getbuiltinmodule("pypymagic") + space.w_fn_thunk = space.wrap(app_thunk) space.setattr(w_pypymagic, space.wrap('thunk'), - space.wrap(app_thunk)) + space.w_fn_thunk) space.setattr(w_pypymagic, space.wrap('is_thunk'), space.wrap(app_is_thunk)) space.setattr(w_pypymagic, space.wrap('become'), From pedronis at codespeak.net Wed Feb 21 17:08:38 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Wed, 21 Feb 2007 17:08:38 +0100 (CET) Subject: [pypy-svn] r39297 - pypy/dist/pypy/objspace Message-ID: <20070221160838.889FE101CF@code0.codespeak.net> Author: pedronis Date: Wed Feb 21 17:08:37 2007 New Revision: 39297 Modified: pypy/dist/pypy/objspace/taint.py Log: step toward making this translatable, lookup* needs a solution tough Modified: pypy/dist/pypy/objspace/taint.py ============================================================================== --- pypy/dist/pypy/objspace/taint.py (original) +++ pypy/dist/pypy/objspace/taint.py Wed Feb 21 17:08:37 2007 @@ -129,7 +129,7 @@ unwrap_spec=[gateway.ObjSpace, gateway.W_Root, 'args_w']) def taint_atomic(space, w_callable): - meth = Method(space, space.wrap(app_taint_atomic_function), + meth = Method(space, space.wrap(space.w_fn_taint_atomic_function), w_callable, space.type(w_callable)) return space.wrap(meth) app_taint_atomic = gateway.interp2app(taint_atomic) @@ -194,6 +194,7 @@ self.wrap(app_is_tainted)) self.setattr(w_pypymagic, self.wrap('untaint'), self.wrap(app_untaint)) + self.w_fn_taint_atomic_function = self.wrap(app_taint_atomic_function) self.setattr(w_pypymagic, self.wrap('taint_atomic'), self.wrap(app_taint_atomic)) self.setattr(w_pypymagic, self.wrap('TaintError'), From ludal at codespeak.net Wed Feb 21 17:12:18 2007 From: ludal at codespeak.net (ludal at codespeak.net) Date: Wed, 21 Feb 2007 17:12:18 +0100 (CET) Subject: [pypy-svn] r39298 - pypy/dist/pypy/doc Message-ID: <20070221161218.E6EBB101D8@code0.codespeak.net> Author: ludal Date: Wed Feb 21 17:12:17 2007 New Revision: 39298 Modified: pypy/dist/pypy/doc/cleanup-todo.txt Log: revert changes to cleanup-todo.txt -- moved to the tracker Modified: pypy/dist/pypy/doc/cleanup-todo.txt ============================================================================== --- pypy/dist/pypy/doc/cleanup-todo.txt (original) +++ pypy/dist/pypy/doc/cleanup-todo.txt Wed Feb 21 17:12:17 2007 @@ -14,12 +14,6 @@ - keepalives need to die, finally - change weakrefs to work together with the GC -C backend -~~~~~~~~~ - - - check why .rodata section gets bigger when compiled with inlining - - try to generate const struct {...} for contant rpython strings - interpreter ----------- From cfbolz at codespeak.net Wed Feb 21 18:28:50 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 21 Feb 2007 18:28:50 +0100 (CET) Subject: [pypy-svn] r39300 - pypy/dist/pypy/doc/statistic Message-ID: <20070221172850.27CA4101C6@code0.codespeak.net> Author: cfbolz Date: Wed Feb 21 18:28:49 2007 New Revision: 39300 Modified: pypy/dist/pypy/doc/statistic/loc.txt Log: update lines of code with cool historical data Modified: pypy/dist/pypy/doc/statistic/loc.txt ============================================================================== --- pypy/dist/pypy/doc/statistic/loc.txt (original) +++ pypy/dist/pypy/doc/statistic/loc.txt Wed Feb 21 18:28:49 2007 @@ -1,571 +1,1039 @@ Lines of Code in the pypy subtree date, lines of code, lines of testcode -2006/07/17, 243883, 61480 -2006/07/16, 243621, 61344 -2006/07/15, 243520, 61313 -2006/07/14, 243459, 61314 -2006/07/13, 243406, 61287 -2006/07/12, 243281, 61279 -2006/07/11, 242885, 60796 -2006/07/10, 242273, 60532 -2006/07/09, 242229, 60524 -2006/07/08, 241573, 60173 -2006/07/07, 239546, 59615 -2006/07/06, 238884, 59396 -2006/07/05, 238901, 59013 -2006/07/04, 238724, 59012 -2006/07/03, 238674, 59009 -2006/07/02, 238651, 59001 -2006/07/01, 238361, 58943 -2006/06/30, 238742, 58961 -2006/06/29, 238832, 58938 -2006/06/28, 238484, 58830 -2006/06/27, 238361, 58778 -2006/06/26, 238162, 58755 -2006/06/25, 237964, 58689 -2006/06/24, 237586, 58460 -2006/06/23, 237265, 58460 -2006/06/22, 237228, 58454 -2006/06/21, 236934, 58324 -2006/06/20, 237711, 58324 -2006/06/19, 237290, 58140 -2006/06/18, 237243, 57759 -2006/06/17, 237227, 57705 -2006/06/16, 237223, 57674 -2006/06/15, 237010, 57438 -2006/06/14, 236747, 57335 -2006/06/13, 236849, 57211 -2006/06/12, 237246, 57071 -2006/06/11, 236558, 56800 -2006/06/10, 236447, 56788 -2006/06/09, 236391, 56722 -2006/06/08, 237731, 58790 -2006/06/07, 237402, 58537 -2006/06/06, 236730, 58474 -2006/06/05, 236286, 58331 -2006/06/04, 236020, 58196 -2006/06/03, 236072, 57355 -2006/06/02, 235690, 57191 -2006/05/31, 235493, 57122 -2006/05/30, 235501, 57122 -2006/05/29, 204409, 57115 -2006/05/28, 203670, 55592 -2006/05/27, 203653, 55592 -2006/05/26, 203563, 55563 -2006/05/25, 203490, 55570 -2006/05/24, 203342, 55383 -2006/05/23, 199431, 55391 -2006/05/22, 199114, 55577 -2006/05/21, 199040, 55475 -2006/05/20, 198903, 55211 -2006/05/19, 197404, 55047 -2006/05/18, 197223, 54967 -2006/05/17, 197172, 55029 -2006/05/16, 196171, 54954 -2006/05/15, 195827, 54685 -2006/05/14, 195622, 54424 -2006/05/13, 196169, 54314 -2006/05/12, 195535, 54202 -2006/05/11, 195221, 54028 -2006/05/10, 194921, 53800 -2006/05/09, 194384, 53587 -2006/05/08, 194325, 53503 -2006/05/07, 194263, 53544 -2006/05/06, 194029, 53366 -2006/05/05, 193577, 53008 -2006/05/04, 193297, 52720 -2006/05/03, 193237, 52548 -2006/05/02, 192950, 52435 -2006/05/01, 192740, 52245 -2006/04/30, 192740, 52241 -2006/04/29, 192654, 52220 -2006/04/28, 192251, 51836 -2006/04/27, 191806, 51553 -2006/04/26, 191265, 51180 -2006/04/25, 191060, 50946 -2006/04/24, 190581, 50716 -2006/04/23, 190100, 50476 -2006/04/22, 189708, 50343 -2006/04/21, 189444, 50233 -2006/04/20, 189386, 50060 -2006/04/19, 188764, 50000 -2006/04/18, 188368, 49760 -2006/04/17, 188185, 49343 -2006/04/16, 188073, 49083 -2006/04/15, 187874, 49072 -2006/04/14, 187650, 48936 -2006/04/13, 187417, 48900 -2006/04/12, 187328, 48773 -2006/04/11, 187071, 48645 -2006/04/10, 186785, 48474 -2006/04/09, 186394, 48077 -2006/04/08, 178733, 47684 -2006/04/07, 178276, 47631 -2006/04/06, 177675, 47389 -2006/04/05, 178170, 47256 -2006/04/04, 176373, 47399 -2006/04/03, 175795, 47186 -2006/04/02, 175537, 47085 -2006/04/01, 175211, 46910 -2006/03/31, 174915, 46889 -2006/03/30, 174706, 46787 -2006/03/29, 174706, 46762 -2006/03/28, 174663, 46741 -2006/03/27, 174514, 46658 -2006/03/26, 174271, 46600 -2006/03/25, 174223, 46600 -2006/03/24, 174140, 46532 -2006/03/23, 173493, 46142 -2006/03/22, 172896, 45937 -2006/03/21, 172152, 45725 -2006/03/20, 171933, 45506 -2006/03/19, 171607, 45205 -2006/03/18, 171465, 45202 -2006/03/17, 171385, 45125 -2006/03/16, 171176, 44945 -2006/03/15, 170968, 44841 -2006/03/14, 170944, 44877 -2006/03/13, 170830, 44738 -2006/03/12, 170626, 44743 -2006/03/11, 170597, 44743 -2006/03/10, 170589, 44743 -2006/03/09, 170579, 44855 -2006/03/08, 170180, 44731 -2006/03/07, 170046, 44647 -2006/03/06, 170008, 44611 -2006/03/04, 169917, 44512 -2006/03/03, 169915, 44512 -2006/03/02, 169723, 44499 -2006/03/01, 169535, 44112 -2006/02/28, 169197, 43619 -2006/02/27, 169940, 43442 -2006/02/26, 169558, 43279 -2006/02/25, 169557, 43279 -2006/02/23, 169557, 43279 -2006/02/22, 169433, 43239 -2006/02/21, 169602, 43297 -2006/02/20, 169263, 43201 -2006/02/19, 168953, 43173 -2006/02/18, 168844, 43089 -2006/02/17, 168836, 43089 -2006/02/16, 168628, 42835 -2006/02/15, 168112, 42671 -2006/02/14, 168068, 42354 -2006/02/13, 167901, 42278 -2006/02/12, 167741, 41981 -2006/02/11, 167719, 41992 -2006/02/10, 167651, 41888 -2006/02/09, 167396, 41812 -2006/02/08, 167122, 41723 -2006/02/07, 166496, 41367 -2006/02/06, 166453, 41209 -2006/02/05, 166436, 41110 -2006/02/04, 166270, 40962 -2006/02/03, 166074, 40861 -2006/02/02, 165996, 40725 -2006/02/01, 165903, 40680 -2006/01/31, 165833, 40588 -2006/01/30, 165580, 40016 -2006/01/29, 165580, 40015 -2006/01/28, 165022, 39852 -2006/01/27, 165729, 39552 -2006/01/26, 164445, 39306 -2006/01/25, 163208, 38818 -2006/01/24, 162825, 38485 -2006/01/23, 162130, 38129 -2006/01/22, 161327, 37820 -2006/01/21, 161311, 37789 -2006/01/20, 161285, 37794 -2006/01/19, 161141, 37707 -2006/01/18, 160809, 37566 -2006/01/17, 160737, 37562 -2006/01/16, 160714, 37551 -2006/01/15, 160640, 37439 -2006/01/14, 160642, 37353 -2006/01/13, 160359, 37217 -2006/01/12, 160335, 37215 -2006/01/11, 160307, 37098 -2006/01/10, 160237, 37028 -2006/01/09, 159988, 36799 -2006/01/08, 159964, 36760 -2006/01/07, 159822, 36617 -2006/01/06, 159735, 36497 -2006/01/05, 159787, 36462 -2006/01/04, 159796, 36423 -2006/01/02, 159692, 36336 -2005/12/31, 159549, 36333 -2005/12/30, 159520, 36330 -2005/12/29, 159455, 36319 -2005/12/27, 159374, 36285 -2005/12/25, 159321, 36247 -2005/12/24, 159321, 36197 -2005/12/23, 159305, 36195 -2005/12/22, 159276, 36124 -2005/12/21, 159197, 36060 -2005/12/20, 159100, 36030 -2005/12/19, 159083, 36018 -2005/12/18, 159070, 35868 -2005/12/17, 158902, 35713 -2005/12/16, 158822, 35712 -2005/12/15, 158751, 35651 -2005/12/14, 158266, 35238 -2005/12/13, 158273, 35108 -2005/12/12, 157583, 35018 -2005/12/11, 157466, 35017 -2005/12/10, 157305, 34891 -2005/12/09, 156931, 34791 -2005/12/08, 156568, 33832 -2005/12/07, 154963, 33506 -2005/12/06, 154069, 33216 -2005/12/05, 154085, 33187 -2005/12/04, 154104, 33187 -2005/12/03, 153937, 33205 -2005/12/02, 153897, 33205 -2005/12/01, 153738, 33186 -2005/11/30, 153293, 33011 -2005/11/29, 153246, 33011 -2005/11/28, 153190, 33011 -2005/11/27, 152884, 32862 -2005/11/25, 152830, 32830 -2005/11/23, 152830, 32830 -2005/11/23, 152830, 32830 -2005/11/22, 152844, 32830 -2005/11/21, 152822, 32825 -2005/11/19, 152702, 32718 -2005/11/18, 152704, 32718 -2005/11/17, 152702, 32718 -2005/11/16, 152126, 32718 -2005/11/15, 152151, 32690 -2005/11/14, 152151, 32690 -2005/11/13, 152123, 32696 -2005/11/12, 152031, 32696 -2005/11/11, 152031, 32696 -2005/11/10, 151995, 32548 -2005/11/09, 152051, 32550 -2005/11/08, 152062, 32545 -2005/11/07, 152059, 32545 -2005/11/06, 152076, 32545 -2005/11/05, 152018, 32514 -2005/11/04, 151923, 32514 -2005/11/03, 151918, 32514 -2005/11/02, 151918, 32514 -2005/11/01, 151913, 32508 -2005/10/31, 151905, 32496 -2005/10/30, 151701, 32470 -2005/10/29, 151768, 32470 -2005/10/28, 151704, 32470 -2005/10/27, 151521, 32461 -2005/10/26, 156875, 32344 -2005/10/25, 156761, 31982 -2005/10/24, 156358, 31940 -2005/10/23, 156153, 31954 -2005/10/22, 156124, 31942 -2005/10/21, 156006, 31832 -2005/10/20, 155670, 31818 -2005/10/19, 155548, 31764 -2005/10/18, 155323, 31407 -2005/10/17, 155558, 31306 -2005/10/16, 155503, 31283 -2005/10/15, 155217, 31128 -2005/10/14, 154456, 30886 -2005/10/13, 153234, 30314 -2005/10/12, 153415, 30315 -2005/10/11, 152893, 30132 -2005/10/10, 152248, 29917 -2005/10/09, 150340, 28002 -2005/10/08, 150336, 28002 -2005/10/07, 150310, 27981 -2005/10/06, 150147, 27867 -2005/10/05, 161650, 28403 -2005/10/04, 161652, 28325 -2005/10/03, 161470, 28231 -2005/10/02, 161405, 28148 -2005/10/01, 161217, 28060 -2005/09/30, 161908, 28024 -2005/09/29, 161926, 27969 -2005/09/28, 161945, 27912 -2005/09/27, 161746, 27929 -2005/09/26, 161707, 27865 -2005/09/25, 161178, 27660 -2005/09/24, 161159, 27660 -2005/09/23, 161014, 27616 -2005/09/22, 160766, 27591 -2005/09/21, 160716, 27585 -2005/09/20, 160520, 27565 -2005/09/19, 160423, 27449 -2005/09/18, 160256, 27417 -2005/09/17, 160147, 27417 -2005/09/16, 160250, 27355 -2005/09/15, 160186, 27308 -2005/09/14, 160100, 27289 -2005/09/13, 160295, 27222 -2005/09/12, 159914, 27003 -2005/09/11, 159590, 26842 -2005/09/10, 159474, 26604 -2005/09/09, 159532, 26410 -2005/09/08, 159095, 26194 -2005/09/07, 159089, 26078 -2005/09/06, 158929, 26044 -2005/09/05, 153175, 25883 -2005/09/04, 152749, 25883 -2005/09/03, 152637, 25829 -2005/09/02, 152608, 25829 -2005/09/01, 152432, 25673 -2005/08/31, 152475, 25673 -2005/08/30, 152432, 25655 -2005/08/29, 152082, 25747 -2005/08/28, 151807, 25680 -2005/08/27, 151828, 25688 -2005/08/26, 151296, 25435 -2005/08/25, 150138, 25151 -2005/08/24, 150268, 24873 -2005/08/23, 149698, 24405 -2005/08/22, 149110, 24116 -2005/08/20, 148620, 23925 -2005/08/19, 148620, 23925 -2005/08/18, 147807, 23409 -2005/08/17, 147700, 23385 -2005/08/16, 147613, 23353 -2005/08/15, 147602, 23349 -2005/08/14, 147325, 23329 -2005/08/13, 147307, 23316 -2005/08/12, 147266, 23259 -2005/08/11, 146795, 23113 -2005/08/10, 146311, 22828 -2005/08/09, 145674, 21822 -2005/08/08, 145076, 21661 -2005/08/07, 144812, 21489 -2005/08/06, 144699, 21466 -2005/08/05, 144471, 21098 -2005/08/04, 144278, 20895 -2005/08/03, 143636, 20718 -2005/08/02, 141678, 19969 -2005/07/31, 140413, 19866 -2005/07/30, 140023, 19365 -2005/07/29, 139511, 19128 -2005/07/28, 139093, 18793 -2005/07/27, 135175, 18670 -2005/07/26, 134555, 18519 -2005/07/25, 133921, 18324 -2005/07/24, 133359, 18035 -2005/07/23, 133322, 18020 -2005/07/22, 133289, 18016 -2005/07/21, 133068, 17799 -2005/07/20, 132758, 17419 -2005/07/19, 132611, 17276 -2005/07/18, 135877, 17663 -2005/07/15, 135695, 17468 -2005/07/14, 135576, 17401 -2005/07/13, 135456, 17254 -2005/07/12, 134835, 17106 -2005/07/11, 134472, 16944 -2005/07/10, 134279, 16770 -2005/07/09, 134189, 16711 -2005/07/07, 134141, 16707 -2005/07/06, 133732, 16589 -2005/07/05, 132622, 16446 -2005/07/04, 127161, 16176 -2005/07/03, 126972, 16148 -2005/07/02, 114021, 15697 -2005/07/01, 114035, 15625 -2005/06/30, 113952, 15603 -2005/06/29, 113952, 15603 -2005/06/28, 113886, 15562 -2005/06/26, 113883, 15561 -2005/06/25, 113704, 15474 -2005/06/24, 113296, 15214 -2005/06/23, 114363, 15004 -2005/06/22, 113623, 14689 -2005/06/21, 113628, 14678 -2005/06/20, 113060, 14432 -2005/06/19, 112774, 14332 -2005/06/18, 112462, 14266 -2005/06/17, 111660, 14165 -2005/06/16, 111272, 13979 -2005/06/15, 111031, 13891 -2005/06/14, 111088, 13725 -2005/06/13, 112895, 13446 -2005/06/12, 112856, 13332 -2005/06/11, 112825, 13178 -2005/06/10, 112796, 13151 -2005/06/09, 112505, 13115 -2005/06/08, 113246, 12999 -2005/06/07, 104662, 12955 -2005/06/06, 104657, 12995 -2005/06/05, 103949, 12880 -2005/06/04, 102228, 13525 -2005/06/03, 101734, 13461 -2005/06/02, 101619, 13444 -2005/06/01, 101442, 13353 -2005/05/31, 100942, 13201 -2005/05/30, 100321, 13014 -2005/05/29, 100002, 12811 -2005/05/28, 99760, 12742 -2005/05/27, 99874, 12742 -2005/05/26, 99681, 12701 -2005/05/25, 99295, 12693 -2005/05/24, 99080, 12693 -2005/05/23, 98647, 12664 -2005/05/22, 73426, 12608 -2005/05/21, 73363, 12587 -2005/05/20, 71816, 12433 -2005/05/19, 71673, 12429 -2005/05/18, 79865, 12413 -2005/05/17, 66595, 13184 -2005/05/16, 66562, 13121 -2005/05/15, 66548, 13088 -2005/05/14, 64917, 12761 -2005/05/13, 64811, 12749 -2005/05/12, 64790, 12735 -2005/05/11, 64484, 12685 -2005/05/10, 64144, 12557 -2005/05/09, 63755, 12352 -2005/05/08, 63690, 12349 -2005/05/07, 63552, 12329 -2005/05/06, 63489, 12329 -2005/05/05, 63428, 12267 -2005/05/04, 63289, 12171 -2005/05/03, 63010, 12163 -2005/05/02, 62628, 12096 -2005/05/01, 62128, 11466 -2005/04/30, 63937, 16140 -2005/04/29, 63797, 15974 -2005/04/28, 61815, 15250 -2005/04/27, 61763, 15262 -2005/04/26, 60919, 15192 -2005/04/25, 60595, 15369 -2005/04/24, 58807, 14955 -2005/04/23, 58565, 14939 -2005/04/22, 58565, 14939 -2005/04/21, 58521, 14898 -2005/04/20, 58504, 14881 -2005/04/19, 59131, 14097 -2005/04/18, 59087, 14047 -2005/04/17, 59013, 14000 -2005/04/16, 59050, 13979 -2005/04/15, 58914, 13931 -2005/04/14, 58819, 13856 -2005/04/13, 58464, 13699 -2005/04/12, 58127, 13668 -2005/04/11, 57717, 13522 -2005/04/10, 57578, 13545 -2005/04/09, 57270, 13538 -2005/04/08, 57306, 13520 -2005/04/07, 56983, 13422 -2005/04/06, 56885, 13380 -2005/04/05, 56748, 13356 -2005/04/04, 56579, 13340 -2005/04/03, 56272, 13325 -2005/04/02, 56072, 13325 -2005/04/01, 55751, 13280 -2005/03/31, 54997, 13276 -2005/03/30, 54890, 13167 -2005/03/29, 54788, 13157 -2005/03/28, 54272, 13111 -2005/03/27, 54216, 13108 -2005/03/24, 54198, 13096 -2005/03/23, 54091, 13093 -2005/03/22, 54019, 15607 -2005/03/21, 50164, 15056 -2005/03/20, 50569, 15353 -2005/03/19, 48756, 11768 -2005/03/17, 48791, 11755 -2005/03/15, 48683, 11755 -2005/03/14, 48645, 11755 -2005/03/13, 48629, 11754 -2005/03/12, 48605, 11671 -2005/03/11, 48566, 11653 -2005/03/10, 48463, 11638 -2005/03/06, 47912, 11638 -2005/03/05, 47888, 11628 -2005/03/04, 47719, 11596 -2005/03/03, 47863, 11666 -2005/03/02, 47765, 11661 -2005/03/01, 47635, 11565 -2005/02/28, 47752, 11643 -2005/02/27, 47624, 11627 -2005/02/26, 47624, 11627 -2005/02/25, 47623, 11627 -2005/02/24, 47429, 11567 -2005/02/23, 47309, 11563 -2005/02/22, 47252, 11557 -2005/02/21, 47207, 11362 -2005/02/19, 47139, 11363 -2005/02/18, 46949, 11283 -2005/02/17, 46971, 11167 -2005/02/16, 46912, 11167 -2005/02/15, 46912, 11167 -2005/02/14, 46513, 11092 -2005/02/13, 46454, 11085 -2005/02/13, 46454, 11085 -2005/02/13, 46454, 11085 -2005/02/11, 43929, 11085 -2005/02/10, 43918, 11075 -2005/02/09, 37442, 11055 -2005/02/08, 37341, 11046 -2005/02/07, 37299, 11031 -2005/02/06, 37347, 11064 -2005/02/05, 36551, 10929 -2005/02/04, 36471, 10929 -2005/02/03, 37045, 10890 -2005/02/02, 36931, 10843 -2005/02/01, 36390, 10292 -2005/01/31, 35541, 10266 -2005/01/30, 35430, 10266 -2005/01/29, 35440, 10266 -2005/01/28, 35443, 9696 -2005/01/27, 31118, 9024 -2005/01/26, 33547, 9492 -2005/01/25, 33281, 9335 -2005/01/24, 32679, 8707 -2005/01/23, 32486, 8707 -2005/01/22, 32108, 8555 -2005/01/20, 32091, 8560 -2005/01/19, 32110, 8543 -2005/01/18, 32110, 8166 -2005/01/17, 32110, 8166 -2005/01/16, 32108, 8165 -2005/01/15, 32108, 8154 -2005/01/14, 32103, 8154 -2005/01/13, 32095, 8154 -2005/01/12, 32119, 8145 -2005/01/11, 30569, 8097 -2005/01/10, 30702, 8130 -2005/01/09, 30701, 8248 -2005/01/08, 30701, 8256 -2005/01/03, 30565, 8352 -2005/01/02, 30565, 8357 -2005/01/01, 30565, 8357 -2004/12/30, 30860, 8378 -2004/12/27, 30860, 8375 -2004/12/24, 30812, 8383 -2004/12/22, 30939, 8352 -2004/12/20, 30881, 8352 -2004/12/19, 30881, 8352 -2004/12/18, 30760, 8352 -2004/12/17, 30748, 8342 -2004/12/16, 30679, 8332 -2004/12/13, 30652, 8332 -2004/12/10, 30631, 8332 -2004/12/09, 30622, 8318 -2004/12/08, 30490, 8273 -2004/12/07, 30489, 8273 -2004/12/06, 30465, 8242 -2004/12/04, 30404, 8242 -2004/11/30, 30261, 8242 -2004/11/29, 30175, 8232 -2004/11/28, 30151, 8115 -2004/11/27, 30150, 8115 -2004/11/25, 30148, 8115 -2004/11/24, 30139, 8115 +2003-02-19, 1436, 0 +2003-02-20, 1603, 114 +2003-02-21, 2637, 401 +2003-02-22, 2921, 121 +2003-02-23, 3674, 969 +2003-02-24, 3674, 969 +2003-02-25, 3808, 998 +2003-02-26, 3808, 998 +2003-02-27, 3808, 998 +2003-02-28, 3847, 1054 +2003-03-01, 3854, 1056 +2003-03-03, 3865, 1114 +2003-03-04, 3865, 1116 +2003-03-18, 3865, 1116 +2003-04-06, 3865, 1116 +2003-04-11, 3865, 1116 +2003-04-18, 3892, 1221 +2003-04-19, 3943, 1273 +2003-05-22, 3943, 1273 +2003-05-25, 3943, 1273 +2003-05-26, 4239, 1414 +2003-05-27, 4714, 1668 +2003-05-28, 5603, 1847 +2003-05-29, 5735, 1883 +2003-05-30, 6515, 2380 +2003-05-31, 6927, 2393 +2003-06-01, 7144, 2396 +2003-06-02, 7152, 2400 +2003-06-05, 7195, 2400 +2003-06-06, 7212, 2400 +2003-06-07, 7215, 2400 +2003-06-08, 7228, 2390 +2003-06-09, 7230, 2390 +2003-06-13, 7356, 2387 +2003-06-14, 7436, 2387 +2003-06-15, 7436, 2387 +2003-06-16, 7558, 2411 +2003-06-17, 7568, 2411 +2003-06-18, 7708, 2465 +2003-06-19, 7796, 2460 +2003-06-20, 7794, 2467 +2003-06-21, 7823, 2479 +2003-06-22, 9536, 2608 +2003-06-23, 10196, 3153 +2003-06-24, 10675, 3428 +2003-06-28, 11165, 3571 +2003-06-29, 11173, 3579 +2003-06-30, 11173, 3579 +2003-07-01, 11336, 3597 +2003-07-02, 11344, 3597 +2003-07-03, 11344, 3597 +2003-07-04, 11344, 3597 +2003-07-06, 11354, 3597 +2003-07-07, 11354, 3597 +2003-07-08, 11544, 3621 +2003-07-10, 11544, 3621 +2003-07-12, 11544, 3621 +2003-07-13, 11544, 3621 +2003-07-14, 11617, 3625 +2003-07-15, 11617, 3625 +2003-07-16, 11617, 3625 +2003-07-17, 11617, 3625 +2003-07-18, 11617, 3625 +2003-07-19, 11617, 3625 +2003-07-24, 11617, 3625 +2003-07-26, 11617, 3625 +2003-07-27, 11617, 3625 +2003-07-28, 11617, 3625 +2003-07-29, 11617, 3625 +2003-07-30, 11617, 3625 +2003-07-31, 11617, 3625 +2003-08-01, 11617, 3625 +2003-08-02, 11617, 3625 +2003-08-06, 11617, 3625 +2003-08-07, 11617, 3625 +2003-08-09, 11617, 3625 +2003-08-10, 11617, 3625 +2003-08-17, 11617, 3625 +2003-08-24, 11617, 3625 +2003-08-25, 11617, 3625 +2003-09-02, 11617, 3625 +2003-09-07, 11617, 3625 +2003-09-08, 11617, 3625 +2003-09-09, 11617, 3625 +2003-09-10, 11617, 3625 +2003-09-12, 11617, 3625 +2003-09-13, 11617, 3625 +2003-09-14, 11617, 3625 +2003-09-15, 11617, 3625 +2003-09-16, 11617, 3625 +2003-09-17, 11617, 3625 +2003-09-18, 11954, 3536 +2003-09-19, 11976, 3541 +2003-09-20, 11976, 3541 +2003-09-21, 11976, 3541 +2003-09-22, 11976, 3541 +2003-09-23, 12024, 3671 +2003-09-25, 12024, 3671 +2003-09-26, 12024, 3671 +2003-09-28, 12024, 3671 +2003-09-29, 12024, 3677 +2003-09-30, 12393, 3760 +2003-10-01, 12900, 3965 +2003-10-02, 13241, 4310 +2003-10-03, 13241, 4310 +2003-10-04, 13310, 4356 +2003-10-05, 12443, 4223 +2003-10-06, 12415, 4223 +2003-10-07, 12415, 4223 +2003-10-08, 12417, 4223 +2003-10-09, 12417, 4223 +2003-10-10, 12875, 4431 +2003-10-11, 12884, 4452 +2003-10-12, 12970, 4492 +2003-10-13, 12984, 4492 +2003-10-14, 12984, 4492 +2003-10-15, 12974, 4492 +2003-10-16, 13051, 4492 +2003-10-17, 13094, 4521 +2003-10-18, 13131, 4561 +2003-10-20, 13131, 4561 +2003-10-21, 13131, 4561 +2003-10-23, 13147, 4570 +2003-10-24, 13268, 4413 +2003-10-25, 13276, 4416 +2003-10-26, 13372, 4409 +2003-10-27, 13641, 4403 +2003-10-28, 13699, 4409 +2003-10-29, 13850, 4419 +2003-10-30, 13848, 4431 +2003-10-31, 13854, 4431 +2003-11-03, 13704, 4437 +2003-11-04, 13704, 4437 +2003-11-05, 13711, 4437 +2003-11-10, 13711, 4437 +2003-11-11, 13872, 4634 +2003-11-13, 13872, 4634 +2003-11-14, 13872, 4634 +2003-11-17, 13872, 4634 +2003-11-18, 13850, 4682 +2003-11-19, 13954, 4508 +2003-11-20, 14086, 4555 +2003-11-21, 14226, 4565 +2003-11-22, 14231, 4565 +2003-11-24, 14170, 4620 +2003-11-25, 14170, 4620 +2003-11-26, 14120, 4624 +2003-11-27, 14543, 4673 +2003-11-28, 14546, 4673 +2003-11-29, 14546, 4673 +2003-11-30, 15350, 4695 +2003-12-01, 15350, 4695 +2003-12-02, 15350, 4695 +2003-12-03, 15350, 4695 +2003-12-04, 15350, 4695 +2003-12-08, 15350, 4695 +2003-12-09, 15352, 4695 +2003-12-10, 15352, 4695 +2003-12-11, 15352, 4695 +2003-12-12, 15352, 4695 +2003-12-13, 15352, 4695 +2003-12-15, 15474, 4695 +2003-12-16, 16321, 4701 +2003-12-17, 17469, 4878 +2003-12-18, 17793, 5121 +2003-12-19, 19327, 5002 +2003-12-20, 19795, 5058 +2003-12-21, 20048, 5121 +2003-12-22, 20062, 5145 +2003-12-23, 20118, 5156 +2003-12-24, 20232, 5178 +2003-12-27, 20232, 5178 +2003-12-28, 20232, 5178 +2003-12-29, 20232, 5178 +2003-12-31, 20232, 5178 +2004-01-01, 20404, 5292 +2004-01-02, 20418, 5292 +2004-01-05, 20418, 5292 +2004-01-06, 20283, 5284 +2004-01-07, 20283, 5284 +2004-01-08, 20284, 5284 +2004-01-09, 20351, 5284 +2004-01-10, 20351, 5284 +2004-01-11, 20350, 5284 +2004-01-12, 20356, 5284 +2004-01-13, 20356, 5284 +2004-01-14, 20356, 5284 +2004-01-15, 20356, 5284 +2004-01-16, 20356, 5284 +2004-01-17, 20356, 5284 +2004-01-18, 20356, 5284 +2004-01-19, 20360, 5284 +2004-01-20, 20360, 5284 +2004-01-21, 20360, 5284 +2004-01-22, 20360, 5284 +2004-01-23, 20360, 5284 +2004-01-26, 20360, 5284 +2004-01-27, 20360, 5284 +2004-01-28, 20360, 5284 +2004-01-29, 20360, 5284 +2004-01-30, 20360, 5284 +2004-02-02, 20360, 5284 +2004-02-03, 20360, 5284 +2004-02-04, 20360, 5284 +2004-02-05, 20360, 5284 +2004-02-07, 20360, 5284 +2004-02-08, 20360, 5284 +2004-02-09, 20360, 5284 +2004-02-10, 20360, 5284 +2004-02-11, 20360, 5284 +2004-02-12, 20380, 5284 +2004-02-13, 20380, 5284 +2004-02-14, 20380, 5284 +2004-02-15, 20380, 5284 +2004-02-16, 20372, 5284 +2004-02-19, 20442, 5289 +2004-02-20, 20442, 5289 +2004-02-21, 20442, 5289 +2004-02-23, 20442, 5289 +2004-02-24, 20442, 5289 +2004-02-25, 20442, 5289 +2004-02-26, 20442, 5289 +2004-02-27, 20442, 5289 +2004-02-28, 20442, 5289 +2004-02-29, 20442, 5289 +2004-03-01, 20442, 5289 +2004-03-02, 20442, 5289 +2004-03-03, 20442, 5289 +2004-03-04, 20442, 5289 +2004-03-05, 20442, 5289 +2004-03-06, 20442, 5289 +2004-03-07, 20442, 5289 +2004-03-08, 20442, 5289 +2004-03-09, 20442, 5289 +2004-03-10, 20442, 5289 +2004-03-11, 20442, 5289 +2004-03-12, 20442, 5289 +2004-03-13, 20442, 5289 +2004-03-14, 20442, 5289 +2004-03-16, 20442, 5289 +2004-03-17, 20442, 5289 +2004-03-18, 20442, 5289 +2004-03-19, 20442, 5289 +2004-03-21, 20442, 5289 +2004-03-22, 20442, 5289 +2004-03-23, 20442, 5289 +2004-03-24, 21127, 5289 +2004-03-25, 21128, 5289 +2004-03-26, 21128, 5289 +2004-03-28, 21128, 5289 +2004-03-29, 20587, 5289 +2004-03-30, 20587, 5289 +2004-03-31, 20587, 5289 +2004-04-01, 20587, 5289 +2004-04-02, 20587, 5289 +2004-04-03, 20587, 5289 +2004-04-04, 20587, 5289 +2004-04-05, 20587, 5289 +2004-04-06, 20587, 5289 +2004-04-07, 20587, 5289 +2004-04-08, 20587, 5289 +2004-04-09, 20587, 5289 +2004-04-10, 20587, 5289 +2004-04-11, 20587, 5289 +2004-04-13, 20587, 5289 +2004-04-14, 20587, 5289 +2004-04-15, 20587, 5289 +2004-04-16, 20587, 5289 +2004-04-17, 20587, 5289 +2004-04-18, 20587, 5289 +2004-04-19, 20587, 5289 +2004-04-20, 20587, 5289 +2004-04-21, 20587, 5289 +2004-04-22, 20587, 5289 +2004-04-23, 20587, 5289 +2004-04-24, 20587, 5289 +2004-04-25, 20587, 5289 +2004-04-26, 20587, 5289 +2004-04-27, 20587, 5289 +2004-04-28, 20587, 5289 +2004-04-29, 20587, 5289 +2004-04-30, 20587, 5289 +2004-05-01, 20587, 5289 +2004-05-02, 20587, 5289 +2004-05-03, 20587, 5289 +2004-05-04, 20587, 5289 +2004-05-05, 20587, 5289 +2004-05-06, 20587, 5289 +2004-05-07, 20890, 5143 +2004-05-08, 21079, 5148 +2004-05-09, 21165, 5166 +2004-05-10, 21150, 5166 +2004-05-11, 21150, 5166 +2004-05-12, 21508, 5171 +2004-05-13, 21508, 5171 +2004-05-14, 21508, 5171 +2004-05-15, 21508, 5171 +2004-05-16, 21508, 5171 +2004-05-17, 21508, 5171 +2004-05-18, 21508, 5171 +2004-05-19, 21508, 5171 +2004-05-20, 21508, 5171 +2004-05-21, 21508, 5171 +2004-05-22, 21537, 5199 +2004-05-23, 21537, 5199 +2004-05-24, 21537, 5199 +2004-05-25, 21537, 5199 +2004-05-26, 21537, 5199 +2004-05-27, 21537, 5199 +2004-05-28, 21673, 5214 +2004-05-29, 21673, 5215 +2004-05-30, 21673, 5215 +2004-05-31, 21673, 5215 +2004-06-01, 21848, 5308 +2004-06-02, 22297, 5451 +2004-06-03, 22297, 5474 +2004-06-04, 22310, 5491 +2004-06-05, 22551, 5508 +2004-06-06, 22480, 5496 +2004-06-07, 23177, 5557 +2004-06-08, 23177, 5557 +2004-06-09, 23177, 5557 +2004-06-10, 23181, 5554 +2004-06-11, 24001, 5609 +2004-06-12, 24124, 5618 +2004-06-13, 24341, 5677 +2004-06-15, 24370, 5691 +2004-06-16, 24078, 5704 +2004-06-17, 24218, 5720 +2004-06-18, 24217, 5723 +2004-06-19, 24217, 5723 +2004-06-20, 24217, 5723 +2004-06-21, 24217, 5723 +2004-06-22, 24607, 5723 +2004-06-23, 24607, 5723 +2004-06-24, 24609, 5723 +2004-06-25, 24740, 5751 +2004-06-26, 24865, 5810 +2004-06-27, 24939, 5906 +2004-06-28, 25972, 5974 +2004-06-29, 25986, 5984 +2004-06-30, 25841, 5986 +2004-07-01, 25840, 5986 +2004-07-02, 25937, 5986 +2004-07-03, 25738, 5986 +2004-07-04, 25475, 5986 +2004-07-05, 25475, 5986 +2004-07-06, 25264, 6712 +2004-07-07, 25259, 6780 +2004-07-08, 25259, 6780 +2004-07-09, 25258, 6780 +2004-07-10, 25262, 6799 +2004-07-11, 25262, 6799 +2004-07-12, 25266, 6802 +2004-07-13, 25161, 6825 +2004-07-14, 25161, 6834 +2004-07-15, 25172, 6846 +2004-07-16, 24911, 6757 +2004-07-17, 23902, 6689 +2004-07-21, 23902, 6689 +2004-07-22, 23941, 6690 +2004-07-23, 23971, 6680 +2004-07-24, 24148, 6687 +2004-07-25, 24200, 6687 +2004-07-26, 24354, 6717 +2004-07-27, 24354, 6717 +2004-07-28, 24527, 6755 +2004-07-29, 24527, 6755 +2004-07-30, 24527, 6755 +2004-07-31, 24527, 6755 +2004-08-01, 24527, 6755 +2004-08-02, 24527, 6755 +2004-08-03, 24527, 6755 +2004-08-04, 24527, 6755 +2004-08-05, 24527, 6755 +2004-08-06, 24527, 6755 +2004-08-07, 24527, 6755 +2004-08-08, 24527, 6755 +2004-08-09, 24527, 6755 +2004-08-10, 24527, 6755 +2004-08-11, 24527, 6755 +2004-08-12, 24527, 6755 +2004-08-13, 24527, 6758 +2004-08-14, 24796, 6758 +2004-08-15, 24803, 6758 +2004-08-16, 25070, 6758 +2004-08-17, 25079, 6758 +2004-08-18, 25122, 6758 +2004-08-19, 25122, 6758 +2004-08-20, 25122, 6758 +2004-08-21, 25122, 6758 +2004-08-22, 25122, 6758 +2004-08-23, 25122, 6758 +2004-08-24, 25426, 6758 +2004-08-25, 25426, 6758 +2004-08-26, 25426, 6758 +2004-08-27, 25426, 6758 +2004-08-30, 25426, 6758 +2004-08-31, 25426, 6758 +2004-09-01, 25426, 6758 +2004-09-02, 25426, 6758 +2004-09-03, 25426, 6758 +2004-09-04, 25426, 6758 +2004-09-06, 25426, 6758 +2004-09-07, 26640, 6881 +2004-09-08, 26640, 6881 +2004-09-09, 26840, 6882 +2004-09-10, 26934, 6882 +2004-09-11, 27425, 6889 +2004-09-12, 27401, 6889 +2004-09-13, 27401, 6889 +2004-09-14, 27401, 6889 +2004-09-15, 27401, 6889 +2004-09-16, 27401, 6889 +2004-09-17, 27401, 6889 +2004-09-18, 27401, 6889 +2004-09-19, 27401, 6889 +2004-09-20, 27401, 6889 +2004-09-21, 27401, 6889 +2004-09-22, 27720, 6889 +2004-09-23, 27720, 6889 +2004-09-24, 27720, 6889 +2004-09-25, 27855, 6909 +2004-09-26, 27855, 6909 +2004-09-27, 27855, 6909 +2004-09-28, 27855, 6909 +2004-09-29, 27855, 6909 +2004-09-30, 27855, 6909 +2004-10-01, 27855, 6909 +2004-10-02, 27855, 6909 +2004-10-03, 27855, 6909 +2004-10-04, 27855, 6909 +2004-10-05, 27855, 6909 +2004-10-06, 27855, 6909 +2004-10-07, 27855, 6909 +2004-10-08, 27855, 6909 +2004-10-09, 27855, 6909 +2004-10-10, 25999, 6909 +2004-10-11, 26069, 6913 +2004-10-13, 26069, 6913 +2004-10-14, 26069, 6913 +2004-10-15, 26129, 6917 +2004-10-16, 26129, 6917 +2004-10-17, 26129, 6917 +2004-10-18, 26129, 6917 +2004-10-19, 26147, 6917 +2004-10-20, 26147, 6917 +2004-10-21, 26147, 6917 +2004-10-22, 26147, 6917 +2004-10-23, 26147, 6917 +2004-10-24, 26147, 6917 +2004-10-25, 26147, 6917 +2004-10-26, 26147, 6917 +2004-10-27, 26147, 6917 +2004-10-28, 26147, 6917 +2004-10-29, 26147, 6917 +2004-10-30, 26147, 6917 +2004-10-31, 26147, 6917 +2004-11-01, 26147, 6917 +2004-11-02, 26147, 6917 +2004-11-03, 26147, 6917 +2004-11-04, 26147, 6917 +2004-11-05, 26147, 6917 +2004-11-06, 26147, 6917 +2004-11-08, 26147, 6917 +2004-11-09, 26147, 6917 +2004-11-10, 26147, 6917 +2004-11-11, 26160, 6917 +2004-11-12, 26170, 6917 +2004-11-14, 26169, 6917 +2004-11-15, 26168, 6917 +2004-11-16, 25751, 6829 +2004-11-17, 26131, 6844 +2004-11-18, 26504, 6927 +2004-11-19, 27590, 7162 +2004-11-20, 28246, 7206 +2004-11-21, 29449, 7880 +2004-11-22, 29516, 7927 2004/11/23, 30041, 8108 -2004/11/22, 29505, 8005 -2004/11/21, 29516, 7927 -2004/11/20, 29449, 7880 -2004/11/19, 28244, 7206 -2004/11/18, 27590, 7162 -2004/11/17, 26504, 6927 -2004/11/16, 26131, 6829 -2004/11/15, 25751, 6829 -2004/11/12, 26169, 6917 -2004/11/11, 26170, 6917 +2004/11/24, 30139, 8115 +2004/11/25, 30148, 8115 +2004/11/27, 30150, 8115 +2004/11/28, 30151, 8115 +2004/11/29, 30175, 8232 +2004/11/30, 30261, 8242 +2004/12/04, 30404, 8242 +2004/12/06, 30465, 8242 +2004/12/07, 30489, 8273 +2004/12/08, 30490, 8273 +2004/12/09, 30622, 8318 +2004/12/10, 30631, 8332 +2004/12/13, 30652, 8332 +2004/12/16, 30679, 8332 +2004/12/17, 30748, 8342 +2004/12/18, 30760, 8352 +2004/12/19, 30881, 8352 +2004/12/20, 30881, 8352 +2004/12/22, 30939, 8352 +2004/12/24, 30812, 8383 +2004/12/27, 30860, 8375 +2004/12/30, 30860, 8378 +2005/01/01, 30565, 8357 +2005/01/02, 30565, 8357 +2005/01/03, 30565, 8352 +2005/01/08, 30701, 8256 +2005/01/09, 30701, 8248 +2005/01/10, 30702, 8130 +2005/01/11, 30569, 8097 +2005/01/12, 32119, 8145 +2005/01/13, 32095, 8154 +2005/01/14, 32103, 8154 +2005/01/15, 32108, 8154 +2005/01/16, 32108, 8165 +2005/01/17, 32110, 8166 +2005/01/18, 32110, 8166 +2005/01/19, 32110, 8543 +2005/01/20, 32091, 8560 +2005/01/22, 32108, 8555 +2005/01/23, 32486, 8707 +2005/01/24, 32679, 8707 +2005/01/25, 33281, 9335 +2005/01/26, 33547, 9492 +2005/01/27, 31118, 9024 +2005/01/28, 35443, 9696 +2005/01/29, 35440, 10266 +2005/01/30, 35430, 10266 +2005/01/31, 35541, 10266 +2005/02/01, 36390, 10292 +2005/02/02, 36931, 10843 +2005/02/03, 37045, 10890 +2005/02/04, 36471, 10929 +2005/02/05, 36551, 10929 +2005/02/06, 37347, 11064 +2005/02/07, 37299, 11031 +2005/02/08, 37341, 11046 +2005/02/09, 37442, 11055 +2005/02/10, 43918, 11075 +2005/02/11, 43929, 11085 +2005/02/13, 46454, 11085 +2005/02/13, 46454, 11085 +2005/02/13, 46454, 11085 +2005/02/14, 46513, 11092 +2005/02/15, 46912, 11167 +2005/02/16, 46912, 11167 +2005/02/17, 46971, 11167 +2005/02/18, 46949, 11283 +2005/02/19, 47139, 11363 +2005/02/21, 47207, 11362 +2005/02/22, 47252, 11557 +2005/02/23, 47309, 11563 +2005/02/24, 47429, 11567 +2005/02/25, 47623, 11627 +2005/02/26, 47624, 11627 +2005/02/27, 47624, 11627 +2005/02/28, 47752, 11643 +2005/03/01, 47635, 11565 +2005/03/02, 47765, 11661 +2005/03/03, 47863, 11666 +2005/03/04, 47719, 11596 +2005/03/05, 47888, 11628 +2005/03/06, 47912, 11638 +2005/03/10, 48463, 11638 +2005/03/11, 48566, 11653 +2005/03/12, 48605, 11671 +2005/03/13, 48629, 11754 +2005/03/14, 48645, 11755 +2005/03/15, 48683, 11755 +2005/03/17, 48791, 11755 +2005/03/19, 48756, 11768 +2005/03/20, 50569, 15353 +2005/03/21, 50164, 15056 +2005/03/22, 54019, 15607 +2005/03/23, 54091, 13093 +2005/03/24, 54198, 13096 +2005/03/27, 54216, 13108 +2005/03/28, 54272, 13111 +2005/03/29, 54788, 13157 +2005/03/30, 54890, 13167 +2005/03/31, 54997, 13276 +2005/04/01, 55751, 13280 +2005/04/02, 56072, 13325 +2005/04/03, 56272, 13325 +2005/04/04, 56579, 13340 +2005/04/05, 56748, 13356 +2005/04/06, 56885, 13380 +2005/04/07, 56983, 13422 +2005/04/08, 57306, 13520 +2005/04/09, 57270, 13538 +2005/04/10, 57578, 13545 +2005/04/11, 57717, 13522 +2005/04/12, 58127, 13668 +2005/04/13, 58464, 13699 +2005/04/14, 58819, 13856 +2005/04/15, 58914, 13931 +2005/04/16, 59050, 13979 +2005/04/17, 59013, 14000 +2005/04/18, 59087, 14047 +2005/04/19, 59131, 14097 +2005/04/20, 58504, 14881 +2005/04/21, 58521, 14898 +2005/04/22, 58565, 14939 +2005/04/23, 58565, 14939 +2005/04/24, 58807, 14955 +2005/04/25, 60595, 15369 +2005/04/26, 60919, 15192 +2005/04/27, 61763, 15262 +2005/04/28, 61815, 15250 +2005/04/29, 63797, 15974 +2005/04/30, 63937, 16140 +2005/05/01, 62128, 11466 +2005/05/02, 62628, 12096 +2005/05/03, 63010, 12163 +2005/05/04, 63289, 12171 +2005/05/05, 63428, 12267 +2005/05/06, 63489, 12329 +2005/05/07, 63552, 12329 +2005/05/08, 63690, 12349 +2005/05/09, 63755, 12352 +2005/05/10, 64144, 12557 +2005/05/11, 64484, 12685 +2005/05/12, 64790, 12735 +2005/05/13, 64811, 12749 +2005/05/14, 64917, 12761 +2005/05/15, 66548, 13088 +2005/05/16, 66562, 13121 +2005/05/17, 66595, 13184 +2005/05/18, 79865, 12413 +2005/05/19, 71673, 12429 +2005/05/20, 71816, 12433 +2005/05/21, 73363, 12587 +2005/05/22, 73426, 12608 +2005/05/23, 98647, 12664 +2005/05/24, 99080, 12693 +2005/05/25, 99295, 12693 +2005/05/26, 99681, 12701 +2005/05/27, 99874, 12742 +2005/05/28, 99760, 12742 +2005/05/29, 100002, 12811 +2005/05/30, 100321, 13014 +2005/05/31, 100942, 13201 +2005/06/01, 101442, 13353 +2005/06/02, 101619, 13444 +2005/06/03, 101734, 13461 +2005/06/04, 102228, 13525 +2005/06/05, 103949, 12880 +2005/06/06, 104657, 12995 +2005/06/07, 104662, 12955 +2005/06/08, 113246, 12999 +2005/06/09, 112505, 13115 +2005/06/10, 112796, 13151 +2005/06/11, 112825, 13178 +2005/06/12, 112856, 13332 +2005/06/13, 112895, 13446 +2005/06/14, 111088, 13725 +2005/06/15, 111031, 13891 +2005/06/16, 111272, 13979 +2005/06/17, 111660, 14165 +2005/06/18, 112462, 14266 +2005/06/19, 112774, 14332 +2005/06/20, 113060, 14432 +2005/06/21, 113628, 14678 +2005/06/22, 113623, 14689 +2005/06/23, 114363, 15004 +2005/06/24, 113296, 15214 +2005/06/25, 113704, 15474 +2005/06/26, 113883, 15561 +2005/06/28, 113886, 15562 +2005/06/29, 113952, 15603 +2005/06/30, 113952, 15603 +2005/07/01, 114035, 15625 +2005/07/02, 114021, 15697 +2005/07/03, 126972, 16148 +2005/07/04, 127161, 16176 +2005/07/05, 132622, 16446 +2005/07/06, 133732, 16589 +2005/07/07, 134141, 16707 +2005/07/09, 134189, 16711 +2005/07/10, 134279, 16770 +2005/07/11, 134472, 16944 +2005/07/12, 134835, 17106 +2005/07/13, 135456, 17254 +2005/07/14, 135576, 17401 +2005/07/15, 135695, 17468 +2005/07/18, 135877, 17663 +2005/07/19, 132611, 17276 +2005/07/20, 132758, 17419 +2005/07/21, 133068, 17799 +2005/07/22, 133289, 18016 +2005/07/23, 133322, 18020 +2005/07/24, 133359, 18035 +2005/07/25, 133921, 18324 +2005/07/26, 134555, 18519 +2005/07/27, 135175, 18670 +2005/07/28, 139093, 18793 +2005/07/29, 139511, 19128 +2005/07/30, 140023, 19365 +2005/07/31, 140413, 19866 +2005/08/02, 141678, 19969 +2005/08/03, 143636, 20718 +2005/08/04, 144278, 20895 +2005/08/05, 144471, 21098 +2005/08/06, 144699, 21466 +2005/08/07, 144812, 21489 +2005/08/08, 145076, 21661 +2005/08/09, 145674, 21822 +2005/08/10, 146311, 22828 +2005/08/11, 146795, 23113 +2005/08/12, 147266, 23259 +2005/08/13, 147307, 23316 +2005/08/14, 147325, 23329 +2005/08/15, 147602, 23349 +2005/08/16, 147613, 23353 +2005/08/17, 147700, 23385 +2005/08/18, 147807, 23409 +2005/08/19, 148620, 23925 +2005/08/20, 148620, 23925 +2005/08/22, 149110, 24116 +2005/08/23, 149698, 24405 +2005/08/24, 150268, 24873 +2005/08/25, 150138, 25151 +2005/08/26, 151296, 25435 +2005/08/27, 151828, 25688 +2005/08/28, 151807, 25680 +2005/08/29, 152082, 25747 +2005/08/30, 152432, 25655 +2005/08/31, 152475, 25673 +2005/09/01, 152432, 25673 +2005/09/02, 152608, 25829 +2005/09/03, 152637, 25829 +2005/09/04, 152749, 25883 +2005/09/05, 153175, 25883 +2005/09/06, 158929, 26044 +2005/09/07, 159089, 26078 +2005/09/08, 159095, 26194 +2005/09/09, 159532, 26410 +2005/09/10, 159474, 26604 +2005/09/11, 159590, 26842 +2005/09/12, 159914, 27003 +2005/09/13, 160295, 27222 +2005/09/14, 160100, 27289 +2005/09/15, 160186, 27308 +2005/09/16, 160250, 27355 +2005/09/17, 160147, 27417 +2005/09/18, 160256, 27417 +2005/09/19, 160423, 27449 +2005/09/20, 160520, 27565 +2005/09/21, 160716, 27585 +2005/09/22, 160766, 27591 +2005/09/23, 161014, 27616 +2005/09/24, 161159, 27660 +2005/09/25, 161178, 27660 +2005/09/26, 161707, 27865 +2005/09/27, 161746, 27929 +2005/09/28, 161945, 27912 +2005/09/29, 161926, 27969 +2005/09/30, 161908, 28024 +2005/10/01, 161217, 28060 +2005/10/02, 161405, 28148 +2005/10/03, 161470, 28231 +2005/10/04, 161652, 28325 +2005/10/05, 161650, 28403 +2005/10/06, 150147, 27867 +2005/10/07, 150310, 27981 +2005/10/08, 150336, 28002 +2005/10/09, 150340, 28002 +2005/10/10, 152248, 29917 +2005/10/11, 152893, 30132 +2005/10/12, 153415, 30315 +2005/10/13, 153234, 30314 +2005/10/14, 154456, 30886 +2005/10/15, 155217, 31128 +2005/10/16, 155503, 31283 +2005/10/17, 155558, 31306 +2005/10/18, 155323, 31407 +2005/10/19, 155548, 31764 +2005/10/20, 155670, 31818 +2005/10/21, 156006, 31832 +2005/10/22, 156124, 31942 +2005/10/23, 156153, 31954 +2005/10/24, 156358, 31940 +2005/10/25, 156761, 31982 +2005/10/26, 156875, 32344 +2005/10/27, 151521, 32461 +2005/10/28, 151704, 32470 +2005/10/29, 151768, 32470 +2005/10/30, 151701, 32470 +2005/10/31, 151905, 32496 +2005/11/01, 151913, 32508 +2005/11/02, 151918, 32514 +2005/11/03, 151918, 32514 +2005/11/04, 151923, 32514 +2005/11/05, 152018, 32514 +2005/11/06, 152076, 32545 +2005/11/07, 152059, 32545 +2005/11/08, 152062, 32545 +2005/11/09, 152051, 32550 +2005/11/10, 151995, 32548 +2005/11/11, 152031, 32696 +2005/11/12, 152031, 32696 +2005/11/13, 152123, 32696 +2005/11/14, 152151, 32690 +2005/11/15, 152151, 32690 +2005/11/16, 152126, 32718 +2005/11/17, 152702, 32718 +2005/11/18, 152704, 32718 +2005/11/19, 152702, 32718 +2005/11/21, 152822, 32825 +2005/11/22, 152844, 32830 +2005/11/23, 152830, 32830 +2005/11/23, 152830, 32830 +2005/11/25, 152830, 32830 +2005/11/27, 152884, 32862 +2005/11/28, 153190, 33011 +2005/11/29, 153246, 33011 +2005/11/30, 153293, 33011 +2005/12/01, 153738, 33186 +2005/12/02, 153897, 33205 +2005/12/03, 153937, 33205 +2005/12/04, 154104, 33187 +2005/12/05, 154085, 33187 +2005/12/06, 154069, 33216 +2005/12/07, 154963, 33506 +2005/12/08, 156568, 33832 +2005/12/09, 156931, 34791 +2005/12/10, 157305, 34891 +2005/12/11, 157466, 35017 +2005/12/12, 157583, 35018 +2005/12/13, 158273, 35108 +2005/12/14, 158266, 35238 +2005/12/15, 158751, 35651 +2005/12/16, 158822, 35712 +2005/12/17, 158902, 35713 +2005/12/18, 159070, 35868 +2005/12/19, 159083, 36018 +2005/12/20, 159100, 36030 +2005/12/21, 159197, 36060 +2005/12/22, 159276, 36124 +2005/12/23, 159305, 36195 +2005/12/24, 159321, 36197 +2005/12/25, 159321, 36247 +2005/12/27, 159374, 36285 +2005/12/29, 159455, 36319 +2005/12/30, 159520, 36330 +2005/12/31, 159549, 36333 +2006/01/02, 159692, 36336 +2006/01/04, 159796, 36423 +2006/01/05, 159787, 36462 +2006/01/06, 159735, 36497 +2006/01/07, 159822, 36617 +2006/01/08, 159964, 36760 +2006/01/09, 159988, 36799 +2006/01/10, 160237, 37028 +2006/01/11, 160307, 37098 +2006/01/12, 160335, 37215 +2006/01/13, 160359, 37217 +2006/01/14, 160642, 37353 +2006/01/15, 160640, 37439 +2006/01/16, 160714, 37551 +2006/01/17, 160737, 37562 +2006/01/18, 160809, 37566 +2006/01/19, 161141, 37707 +2006/01/20, 161285, 37794 +2006/01/21, 161311, 37789 +2006/01/22, 161327, 37820 +2006/01/23, 162130, 38129 +2006/01/24, 162825, 38485 +2006/01/25, 163208, 38818 +2006/01/26, 164445, 39306 +2006/01/27, 165729, 39552 +2006/01/28, 165022, 39852 +2006/01/29, 165580, 40015 +2006/01/30, 165580, 40016 +2006/01/31, 165833, 40588 +2006/02/01, 165903, 40680 +2006/02/02, 165996, 40725 +2006/02/03, 166074, 40861 +2006/02/04, 166270, 40962 +2006/02/05, 166436, 41110 +2006/02/06, 166453, 41209 +2006/02/07, 166496, 41367 +2006/02/08, 167122, 41723 +2006/02/09, 167396, 41812 +2006/02/10, 167651, 41888 +2006/02/11, 167719, 41992 +2006/02/12, 167741, 41981 +2006/02/13, 167901, 42278 +2006/02/14, 168068, 42354 +2006/02/15, 168112, 42671 +2006/02/16, 168628, 42835 +2006/02/17, 168836, 43089 +2006/02/18, 168844, 43089 +2006/02/19, 168953, 43173 +2006/02/20, 169263, 43201 +2006/02/21, 169602, 43297 +2006/02/22, 169433, 43239 +2006/02/23, 169557, 43279 +2006/02/25, 169557, 43279 +2006/02/26, 169558, 43279 +2006/02/27, 169940, 43442 +2006/02/28, 169197, 43619 +2006/03/01, 169535, 44112 +2006/03/02, 169723, 44499 +2006/03/03, 169915, 44512 +2006/03/04, 169917, 44512 +2006/03/06, 170008, 44611 +2006/03/07, 170046, 44647 +2006/03/08, 170180, 44731 +2006/03/09, 170579, 44855 +2006/03/10, 170589, 44743 +2006/03/11, 170597, 44743 +2006/03/12, 170626, 44743 +2006/03/13, 170830, 44738 +2006/03/14, 170944, 44877 +2006/03/15, 170968, 44841 +2006/03/16, 171176, 44945 +2006/03/17, 171385, 45125 +2006/03/18, 171465, 45202 +2006/03/19, 171607, 45205 +2006/03/20, 171933, 45506 +2006/03/21, 172152, 45725 +2006/03/22, 172896, 45937 +2006/03/23, 173493, 46142 +2006/03/24, 174140, 46532 +2006/03/25, 174223, 46600 +2006/03/26, 174271, 46600 +2006/03/27, 174514, 46658 +2006/03/28, 174663, 46741 +2006/03/29, 174706, 46762 +2006/03/30, 174706, 46787 +2006/03/31, 174915, 46889 +2006/04/01, 175211, 46910 +2006/04/02, 175537, 47085 +2006/04/03, 175795, 47186 +2006/04/04, 176373, 47399 +2006/04/05, 178170, 47256 +2006/04/06, 177675, 47389 +2006/04/07, 178276, 47631 +2006/04/08, 178733, 47684 +2006/04/09, 186394, 48077 +2006/04/10, 186785, 48474 +2006/04/11, 187071, 48645 +2006/04/12, 187328, 48773 +2006/04/13, 187417, 48900 +2006/04/14, 187650, 48936 +2006/04/15, 187874, 49072 +2006/04/16, 188073, 49083 +2006/04/17, 188185, 49343 +2006/04/18, 188368, 49760 +2006/04/19, 188764, 50000 +2006/04/20, 189386, 50060 +2006/04/21, 189444, 50233 +2006/04/22, 189708, 50343 +2006/04/23, 190100, 50476 +2006/04/24, 190581, 50716 +2006/04/25, 191060, 50946 +2006/04/26, 191265, 51180 +2006/04/27, 191806, 51553 +2006/04/28, 192251, 51836 +2006/04/29, 192654, 52220 +2006/04/30, 192740, 52241 +2006/05/01, 192740, 52245 +2006/05/02, 192950, 52435 +2006/05/03, 193237, 52548 +2006/05/04, 193297, 52720 +2006/05/05, 193577, 53008 +2006/05/06, 194029, 53366 +2006/05/07, 194263, 53544 +2006/05/08, 194325, 53503 +2006/05/09, 194384, 53587 +2006/05/10, 194921, 53800 +2006/05/11, 195221, 54028 +2006/05/12, 195535, 54202 +2006/05/13, 196169, 54314 +2006/05/14, 195622, 54424 +2006/05/15, 195827, 54685 +2006/05/16, 196171, 54954 +2006/05/17, 197172, 55029 +2006/05/18, 197223, 54967 +2006/05/19, 197404, 55047 +2006/05/20, 198903, 55211 +2006/05/21, 199040, 55475 +2006/05/22, 199114, 55577 +2006/05/23, 199431, 55391 +2006/05/24, 203342, 55383 +2006/05/25, 203490, 55570 +2006/05/26, 203563, 55563 +2006/05/27, 203653, 55592 +2006/05/28, 203670, 55592 +2006/05/29, 204409, 57115 +2006/05/30, 235501, 57122 +2006/05/31, 235493, 57122 +2006/06/02, 235690, 57191 +2006/06/03, 236072, 57355 +2006/06/04, 236020, 58196 +2006/06/05, 236286, 58331 +2006/06/06, 236730, 58474 +2006/06/07, 237402, 58537 +2006/06/08, 237731, 58790 +2006/06/09, 236391, 56722 +2006/06/10, 236447, 56788 +2006/06/11, 236558, 56800 +2006/06/12, 237246, 57071 +2006/06/13, 236849, 57211 +2006/06/14, 236747, 57335 +2006/06/15, 237010, 57438 +2006/06/16, 237223, 57674 +2006/06/17, 237227, 57705 +2006/06/18, 237243, 57759 +2006/06/19, 237290, 58140 +2006/06/20, 237711, 58324 +2006/06/21, 236934, 58324 +2006/06/22, 237228, 58454 +2006/06/23, 237265, 58460 +2006/06/24, 237586, 58460 +2006/06/25, 237964, 58689 +2006/06/26, 238162, 58755 +2006/06/27, 238361, 58778 +2006/06/28, 238484, 58830 +2006/06/29, 238832, 58938 +2006/06/30, 238742, 58961 +2006/07/01, 238361, 58943 +2006/07/02, 238651, 59001 +2006/07/03, 238674, 59009 +2006/07/04, 238724, 59012 +2006/07/05, 238901, 59013 +2006/07/06, 238884, 59396 +2006/07/07, 239546, 59615 +2006/07/08, 241573, 60173 +2006/07/09, 242229, 60524 +2006/07/10, 242273, 60532 +2006/07/11, 242885, 60796 +2006/07/12, 243281, 61279 +2006/07/13, 243406, 61287 +2006/07/14, 243459, 61314 +2006/07/15, 243520, 61313 +2006/07/16, 243621, 61344 +2006/07/17, 243883, 61480 From fijal at codespeak.net Thu Feb 22 09:29:46 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 22 Feb 2007 09:29:46 +0100 (CET) Subject: [pypy-svn] r39309 - pypy/dist/pypy/translator/js/examples Message-ID: <20070222082946.27A7210193@code0.codespeak.net> Author: fijal Date: Thu Feb 22 09:29:45 2007 New Revision: 39309 Added: pypy/dist/pypy/translator/js/examples/console_client.py Log: Missing import Added: pypy/dist/pypy/translator/js/examples/console_client.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/js/examples/console_client.py Thu Feb 22 09:29:45 2007 @@ -0,0 +1,62 @@ + +from pypy.translator.js.modules import dom +from pypy.translator.js.modules.mochikit import log, createLoggingPane +from pypy.translator.js.examples.console import exported_methods + +class Glob(object): + pass + +glob = Glob() + +def add_text(txt): + dom.document.getElementById("data").innerHTML += txt + +def refresh_console(msg): + inp_elem = dom.document.getElementById("inp") + inp_elem.disabled = False + inp_elem.scrollIntoView() + log(msg[0]) + if msg[0] == "refresh": + data = msg[1] + log(data) + if data.endswith(">>> ") or data.endswith("... "): + # prove positive slice here + l = len(data) - 4 + assert l >= 0 + glob.prompt = data[l:] + data = data[:l] + else: + exported_methods.refresh_empty(glob.sess_id, refresh_console) + add_text(data) + elif msg[0] == 'disconnect': + dom.document.getElementById("error").innerHTML = "ERROR! disconnected" + +def set_sessid(sessid): + glob.sess_id = sessid + exported_methods.refresh_empty(sessid, refresh_console) + +def empty_callback(msg): + inp_elem = dom.document.getElementById("inp") + inp_elem.disabled = False + inp_elem.scrollIntoView() + +def keypressed(key): + kc = key.keyCode + if kc == ord("\r"): + inp_elem = dom.document.getElementById("inp") + cmd = inp_elem.value + inp_elem.value = '' + inp_elem.disabled = True + add_text(glob.prompt + cmd + "\n") + #if not cmd: + # exported_methods.refresh(glob.sess_id, cmd, empty_callback) + #else: + exported_methods.refresh(glob.sess_id, cmd, refresh_console) + +def console_onload(): + createLoggingPane(True) + inp_elem = dom.document.getElementById("inp") + inp_elem.focus() + dom.document.onkeypress = keypressed + exported_methods.get_console(set_sessid) + From cfbolz at codespeak.net Thu Feb 22 11:36:07 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 22 Feb 2007 11:36:07 +0100 (CET) Subject: [pypy-svn] r39310 - pypy/dist/pypy/doc/statistic Message-ID: <20070222103607.A13D410151@code0.codespeak.net> Author: cfbolz Date: Thu Feb 22 11:36:05 2007 New Revision: 39310 Modified: pypy/dist/pypy/doc/statistic/loc.txt pypy/dist/pypy/doc/statistic/number_files.txt Log: update some more statistics Modified: pypy/dist/pypy/doc/statistic/loc.txt ============================================================================== --- pypy/dist/pypy/doc/statistic/loc.txt (original) +++ pypy/dist/pypy/doc/statistic/loc.txt Thu Feb 22 11:36:05 2007 @@ -1037,3 +1037,220 @@ 2006/07/15, 243520, 61313 2006/07/16, 243621, 61344 2006/07/17, 243883, 61480 +2006-07-17, 243621, 61344 +2006-07-18, 243886, 61525 +2006-07-19, 244520, 61568 +2006-07-20, 244866, 61922 +2006-07-21, 244969, 61966 +2006-07-22, 245046, 62020 +2006-07-23, 245229, 62043 +2006-07-24, 245421, 62142 +2006-07-25, 245618, 62211 +2006-07-26, 245251, 62324 +2006-07-27, 245921, 62650 +2006-07-28, 246016, 62694 +2006-07-29, 249837, 62836 +2006-07-30, 249901, 62893 +2006-07-31, 249933, 62894 +2006-08-01, 250022, 62941 +2006-08-02, 250276, 63020 +2006-08-03, 248113, 62052 +2006-08-04, 248192, 62110 +2006-08-05, 249951, 62532 +2006-08-06, 250333, 62659 +2006-08-07, 250401, 62670 +2006-08-08, 252585, 63100 +2006-08-09, 252849, 63027 +2006-08-10, 253370, 63137 +2006-08-11, 253464, 63219 +2006-08-12, 253592, 63309 +2006-08-13, 253597, 63309 +2006-08-14, 253600, 63309 +2006-08-15, 253707, 63375 +2006-08-16, 254098, 63549 +2006-08-17, 254591, 63698 +2006-08-18, 254640, 63783 +2006-08-19, 254723, 63783 +2006-08-20, 254707, 63789 +2006-08-21, 254932, 64065 +2006-08-22, 254820, 63836 +2006-08-23, 255008, 63958 +2006-08-24, 255255, 64074 +2006-08-25, 255383, 64175 +2006-08-26, 255553, 64197 +2006-08-27, 255283, 64604 +2006-08-28, 255368, 64660 +2006-08-29, 255368, 64660 +2006-08-30, 256002, 64772 +2006-08-31, 255939, 64828 +2006-09-01, 256059, 64897 +2006-09-02, 256072, 64896 +2006-09-03, 256651, 65050 +2006-09-04, 256654, 65213 +2006-09-05, 256678, 65296 +2006-09-06, 256933, 65562 +2006-09-07, 257168, 65707 +2006-09-08, 257380, 65826 +2006-09-09, 257996, 66107 +2006-09-10, 258138, 66194 +2006-09-11, 258419, 66313 +2006-09-12, 258503, 66321 +2006-09-13, 258624, 66365 +2006-09-14, 258625, 66401 +2006-09-15, 258783, 66509 +2006-09-16, 258785, 66512 +2006-09-17, 258806, 66519 +2006-09-18, 258424, 66766 +2006-09-19, 258438, 66797 +2006-09-20, 258438, 66797 +2006-09-21, 258436, 66851 +2006-09-22, 258059, 67034 +2006-09-23, 258667, 67089 +2006-09-24, 258792, 67181 +2006-09-25, 258793, 67181 +2006-09-26, 258797, 67221 +2006-09-27, 258858, 67228 +2006-09-28, 259082, 67296 +2006-09-29, 258980, 67013 +2006-09-30, 258822, 67973 +2006-10-01, 258935, 68062 +2006-10-02, 259055, 68084 +2006-10-03, 259204, 68209 +2006-10-04, 296696, 68497 +2006-10-05, 298069, 68956 +2006-10-06, 298223, 69071 +2006-10-07, 298327, 69155 +2006-10-08, 298428, 69175 +2006-10-09, 298430, 69177 +2006-10-10, 297621, 69224 +2006-10-11, 296425, 68673 +2006-10-12, 294584, 68892 +2006-10-13, 294744, 68942 +2006-10-14, 295543, 68963 +2006-10-15, 295543, 68963 +2006-10-16, 295732, 68963 +2006-10-17, 295851, 69007 +2006-10-18, 296612, 69393 +2006-10-19, 296832, 69369 +2006-10-20, 297146, 69404 +2006-10-21, 297332, 69565 +2006-10-22, 298113, 69570 +2006-10-23, 298120, 69570 +2006-10-24, 298222, 69603 +2006-10-25, 298556, 69777 +2006-10-26, 298706, 69813 +2006-10-27, 298766, 70013 +2006-10-28, 298359, 69758 +2006-10-29, 298359, 69758 +2006-10-30, 298357, 69735 +2006-10-31, 299054, 69842 +2006-11-01, 300281, 69956 +2006-11-02, 300230, 69927 +2006-11-03, 300443, 70008 +2006-11-04, 300886, 70417 +2006-11-05, 301166, 70513 +2006-11-06, 301201, 70616 +2006-11-07, 300495, 69816 +2006-11-08, 300804, 70084 +2006-11-09, 300878, 70257 +2006-11-10, 301106, 70340 +2006-11-11, 301302, 70392 +2006-11-12, 301728, 70598 +2006-11-13, 314202, 72483 +2006-11-14, 314394, 72265 +2006-11-15, 314736, 72346 +2006-11-16, 315160, 72531 +2006-11-17, 315070, 72670 +2006-11-18, 315097, 72705 +2006-11-19, 315261, 72795 +2006-11-20, 315333, 72837 +2006-11-21, 315777, 72949 +2006-11-22, 316130, 73006 +2006-11-23, 316162, 73035 +2006-11-24, 316338, 73248 +2006-11-25, 316378, 73355 +2006-11-26, 316415, 73366 +2006-11-27, 316532, 73366 +2006-11-28, 318388, 73700 +2006-11-29, 318515, 73704 +2006-11-30, 318645, 73752 +2006-12-01, 318816, 73833 +2006-12-02, 318840, 73899 +2006-12-03, 318845, 73899 +2006-12-04, 318930, 73941 +2006-12-05, 319614, 73996 +2006-12-06, 319623, 74108 +2006-12-07, 319828, 74140 +2006-12-08, 320019, 74173 +2006-12-09, 320215, 74192 +2006-12-10, 320927, 74430 +2006-12-11, 320937, 74505 +2006-12-12, 321194, 74652 +2006-12-13, 321238, 74723 +2006-12-14, 321114, 74849 +2006-12-15, 321900, 75884 +2006-12-16, 322135, 76292 +2006-12-17, 322261, 76341 +2006-12-18, 322384, 76348 +2006-12-19, 322382, 76315 +2006-12-20, 322718, 76471 +2006-12-21, 322961, 76259 +2006-12-22, 323044, 76354 +2006-12-23, 323068, 76392 +2006-12-24, 323117, 76424 +2006-12-25, 323123, 76420 +2006-12-26, 323108, 76427 +2006-12-27, 321740, 76431 +2006-12-28, 321872, 76671 +2006-12-29, 322115, 76909 +2006-12-30, 322246, 76916 +2006-12-31, 322288, 77018 +2007-01-01, 322277, 77019 +2007-01-02, 322403, 77007 +2007-01-03, 322478, 77390 +2007-01-04, 322672, 77448 +2007-01-05, 322736, 77448 +2007-01-06, 322746, 77448 +2007-01-07, 322751, 77449 +2007-01-08, 322751, 77449 +2007-01-09, 323243, 77508 +2007-01-10, 323870, 77955 +2007-01-11, 324115, 78315 +2007-01-12, 324587, 78684 +2007-01-13, 325435, 79072 +2007-01-14, 325840, 79048 +2007-01-15, 327282, 79265 +2007-01-16, 327409, 79308 +2007-01-17, 327661, 79392 +2007-01-18, 327683, 79412 +2007-01-19, 327710, 79413 +2007-01-20, 327918, 79523 +2007-01-21, 328238, 79543 +2007-01-22, 328265, 79543 +2007-01-23, 328471, 79704 +2007-01-24, 328920, 79596 +2007-01-25, 329021, 79667 +2007-01-26, 329599, 79832 +2007-01-27, 329913, 80096 +2007-01-28, 329973, 80135 +2007-01-29, 330044, 80152 +2007-01-30, 330947, 80359 +2007-01-31, 331201, 80459 +2007-02-01, 331558, 80704 +2007-02-02, 331301, 80417 +2007-02-03, 331338, 80446 +2007-02-04, 331374, 80467 +2007-02-05, 331386, 80467 +2007-02-06, 332398, 80586 +2007-02-07, 332416, 80605 +2007-02-08, 332417, 80637 +2007-02-09, 332470, 80667 +2007-02-10, 332813, 80738 +2007-02-11, 332829, 80737 +2007-02-12, 333328, 80848 +2007-02-13, 333567, 81010 +2007-02-14, 333735, 81254 +2007-02-15, 334047, 81257 +2007-02-16, 333963, 81385 +2007-02-17, 335704, 81385 +2007-02-18, 335734, 81378 Modified: pypy/dist/pypy/doc/statistic/number_files.txt ============================================================================== --- pypy/dist/pypy/doc/statistic/number_files.txt (original) +++ pypy/dist/pypy/doc/statistic/number_files.txt Thu Feb 22 11:36:05 2007 @@ -1,570 +1,1253 @@ Number of files in the pypy subtree date, number of files, number of testfiles -2006/07/17, 1044, 408 -2006/07/16, 1043, 408 -2006/07/15, 1042, 407 -2006/07/14, 1041, 407 -2006/07/13, 1040, 407 -2006/07/12, 1039, 407 -2006/07/11, 1036, 406 -2006/07/10, 1038, 403 -2006/07/09, 1038, 403 -2006/07/08, 1036, 402 -2006/07/07, 1031, 393 -2006/07/06, 1020, 386 -2006/07/05, 1016, 384 -2006/07/04, 1015, 384 -2006/07/03, 1015, 384 -2006/07/02, 1015, 384 -2006/07/01, 1012, 384 -2006/06/30, 1012, 384 -2006/06/29, 1019, 384 -2006/06/28, 1018, 381 -2006/06/27, 1017, 381 -2006/06/26, 1017, 381 -2006/06/25, 1016, 380 -2006/06/24, 1013, 378 -2006/06/23, 1011, 378 -2006/06/22, 1011, 378 -2006/06/21, 1003, 377 -2006/06/20, 1007, 377 -2006/06/19, 1007, 377 -2006/06/18, 1007, 377 -2006/06/17, 1007, 377 -2006/06/16, 1007, 377 -2006/06/15, 1006, 375 -2006/06/14, 1005, 371 -2006/06/13, 1004, 371 -2006/06/12, 1010, 371 -2006/06/11, 1005, 369 -2006/06/10, 1004, 369 -2006/06/09, 1004, 369 -2006/06/08, 1021, 386 -2006/06/07, 1019, 385 -2006/06/06, 1010, 384 -2006/06/05, 1003, 381 -2006/06/04, 998, 379 -2006/06/03, 990, 374 -2006/06/02, 988, 374 -2006/05/31, 982, 372 -2006/05/30, 982, 372 -2006/05/29, 981, 372 -2006/05/28, 977, 362 -2006/05/27, 977, 362 -2006/05/26, 976, 362 -2006/05/25, 976, 361 -2006/05/24, 976, 361 -2006/05/23, 975, 359 -2006/05/22, 974, 359 -2006/05/21, 974, 359 -2006/05/20, 972, 358 -2006/05/19, 961, 357 -2006/05/18, 960, 356 -2006/05/17, 962, 357 -2006/05/16, 952, 357 -2006/05/15, 952, 357 -2006/05/14, 952, 356 -2006/05/13, 957, 356 -2006/05/12, 957, 356 -2006/05/11, 955, 355 -2006/05/10, 955, 355 -2006/05/09, 950, 354 -2006/05/08, 949, 353 -2006/05/07, 950, 353 -2006/05/06, 950, 353 -2006/05/05, 949, 351 -2006/05/04, 948, 351 -2006/05/03, 949, 350 -2006/05/02, 949, 349 -2006/05/01, 948, 347 -2006/04/30, 948, 347 -2006/04/29, 946, 347 -2006/04/28, 945, 345 -2006/04/27, 943, 342 -2006/04/26, 943, 339 -2006/04/25, 940, 338 -2006/04/24, 935, 336 -2006/04/23, 930, 333 -2006/04/22, 927, 328 -2006/04/21, 924, 326 -2006/04/20, 919, 325 -2006/04/19, 910, 323 -2006/04/18, 900, 321 -2006/04/17, 900, 320 -2006/04/16, 897, 319 -2006/04/15, 896, 318 -2006/04/14, 887, 316 -2006/04/13, 884, 316 -2006/04/12, 880, 315 -2006/04/11, 878, 313 -2006/04/10, 878, 312 -2006/04/09, 875, 309 -2006/04/08, 854, 308 -2006/04/07, 852, 308 -2006/04/06, 848, 305 -2006/04/05, 853, 305 -2006/04/04, 846, 305 -2006/04/03, 842, 305 -2006/04/02, 840, 304 -2006/04/01, 829, 302 -2006/03/31, 821, 301 -2006/03/30, 820, 300 -2006/03/29, 820, 300 -2006/03/28, 818, 300 -2006/03/27, 815, 299 -2006/03/26, 814, 299 -2006/03/25, 813, 299 -2006/03/24, 813, 297 -2006/03/23, 809, 295 -2006/03/22, 806, 294 -2006/03/21, 792, 292 -2006/03/20, 792, 292 -2006/03/19, 788, 291 -2006/03/18, 786, 291 -2006/03/17, 786, 291 -2006/03/16, 785, 290 -2006/03/15, 784, 290 -2006/03/14, 784, 289 -2006/03/13, 784, 289 -2006/03/12, 781, 288 -2006/03/11, 781, 288 -2006/03/10, 781, 288 -2006/03/09, 781, 288 -2006/03/08, 778, 287 -2006/03/07, 777, 287 -2006/03/06, 777, 287 -2006/03/04, 776, 287 -2006/03/03, 776, 287 -2006/03/02, 776, 287 -2006/03/01, 775, 287 -2006/02/28, 766, 284 -2006/02/27, 764, 283 -2006/02/26, 762, 282 -2006/02/25, 762, 282 -2006/02/23, 762, 282 -2006/02/22, 761, 281 -2006/02/21, 761, 281 -2006/02/20, 760, 279 -2006/02/19, 760, 279 -2006/02/18, 759, 279 -2006/02/17, 759, 279 -2006/02/16, 759, 278 -2006/02/15, 756, 276 -2006/02/14, 756, 275 -2006/02/13, 755, 275 -2006/02/12, 755, 275 -2006/02/11, 754, 275 -2006/02/10, 754, 275 -2006/02/09, 754, 275 -2006/02/08, 753, 275 -2006/02/07, 749, 274 -2006/02/06, 749, 271 -2006/02/05, 749, 270 -2006/02/04, 749, 270 -2006/02/03, 747, 269 -2006/02/02, 747, 268 -2006/02/01, 746, 268 -2006/01/31, 746, 268 -2006/01/30, 745, 265 -2006/01/29, 745, 265 -2006/01/28, 744, 265 -2006/01/27, 746, 266 -2006/01/26, 735, 264 -2006/01/25, 731, 261 -2006/01/24, 725, 257 -2006/01/23, 721, 255 -2006/01/22, 715, 253 -2006/01/21, 715, 253 -2006/01/20, 715, 253 -2006/01/19, 714, 252 -2006/01/18, 713, 251 -2006/01/17, 713, 251 -2006/01/16, 713, 251 -2006/01/15, 713, 251 -2006/01/14, 713, 250 -2006/01/13, 712, 249 -2006/01/12, 712, 249 -2006/01/11, 712, 249 -2006/01/10, 712, 249 -2006/01/09, 711, 248 -2006/01/08, 711, 248 -2006/01/07, 711, 248 -2006/01/06, 711, 247 -2006/01/05, 710, 247 -2006/01/04, 710, 247 -2006/01/02, 710, 247 -2005/12/31, 708, 247 -2005/12/30, 708, 247 -2005/12/29, 706, 247 -2005/12/27, 704, 246 -2005/12/25, 704, 246 -2005/12/24, 704, 246 -2005/12/23, 704, 246 -2005/12/22, 704, 245 -2005/12/21, 704, 245 -2005/12/20, 704, 243 -2005/12/19, 704, 243 -2005/12/18, 704, 243 -2005/12/17, 704, 243 -2005/12/16, 703, 243 -2005/12/15, 703, 243 -2005/12/14, 700, 240 -2005/12/13, 700, 239 -2005/12/12, 699, 239 -2005/12/11, 699, 239 -2005/12/10, 698, 240 -2005/12/09, 698, 240 -2005/12/08, 694, 237 -2005/12/07, 694, 235 -2005/12/06, 690, 233 -2005/12/05, 690, 233 -2005/12/04, 690, 233 -2005/12/03, 690, 233 -2005/12/02, 690, 233 -2005/12/01, 689, 232 -2005/11/30, 687, 233 -2005/11/29, 686, 233 -2005/11/28, 685, 233 -2005/11/27, 683, 232 -2005/11/25, 683, 232 -2005/11/23, 683, 232 -2005/11/22, 683, 232 -2005/11/21, 683, 232 -2005/11/19, 683, 232 -2005/11/18, 683, 232 -2005/11/17, 683, 232 -2005/11/16, 682, 232 -2005/11/15, 683, 232 -2005/11/14, 683, 232 -2005/11/13, 683, 232 -2005/11/12, 683, 232 -2005/11/11, 683, 232 -2005/11/10, 683, 231 -2005/11/09, 681, 231 -2005/11/08, 681, 231 -2005/11/07, 681, 231 -2005/11/06, 681, 231 -2005/11/05, 681, 231 -2005/11/04, 681, 231 -2005/11/03, 681, 231 -2005/11/02, 681, 231 -2005/11/01, 681, 231 -2005/10/31, 681, 231 -2005/10/30, 681, 231 -2005/10/29, 684, 231 -2005/10/28, 684, 231 -2005/10/27, 684, 230 -2005/10/26, 697, 230 -2005/10/25, 697, 229 -2005/10/24, 698, 229 -2005/10/23, 698, 230 -2005/10/22, 698, 230 -2005/10/21, 698, 230 -2005/10/20, 696, 230 -2005/10/19, 696, 230 -2005/10/18, 695, 229 -2005/10/17, 693, 228 -2005/10/16, 693, 228 -2005/10/15, 688, 226 -2005/10/14, 681, 224 -2005/10/13, 662, 217 -2005/10/12, 663, 217 -2005/10/11, 657, 216 -2005/10/10, 652, 216 -2005/10/09, 629, 201 -2005/10/08, 629, 201 -2005/10/07, 629, 201 -2005/10/06, 629, 200 -2005/10/05, 648, 202 -2005/10/04, 650, 202 -2005/10/03, 648, 201 -2005/10/02, 647, 201 -2005/10/01, 643, 199 -2005/09/30, 644, 200 -2005/09/29, 645, 199 -2005/09/28, 645, 199 -2005/09/27, 645, 200 -2005/09/26, 641, 199 -2005/09/25, 638, 195 -2005/09/24, 638, 195 -2005/09/23, 638, 196 -2005/09/22, 637, 196 -2005/09/21, 636, 196 -2005/09/20, 635, 196 -2005/09/19, 635, 196 -2005/09/18, 632, 196 -2005/09/17, 631, 196 -2005/09/16, 631, 196 -2005/09/15, 631, 196 -2005/09/14, 629, 196 -2005/09/13, 629, 196 -2005/09/12, 623, 192 -2005/09/11, 623, 192 -2005/09/10, 623, 192 -2005/09/09, 625, 192 -2005/09/08, 622, 191 -2005/09/07, 647, 191 -2005/09/06, 646, 191 -2005/09/05, 631, 191 -2005/09/04, 630, 191 -2005/09/03, 630, 191 -2005/09/02, 630, 191 -2005/09/01, 630, 190 -2005/08/31, 630, 190 -2005/08/30, 630, 190 -2005/08/29, 630, 190 -2005/08/28, 630, 190 -2005/08/27, 630, 190 -2005/08/26, 626, 188 -2005/08/25, 625, 187 -2005/08/24, 633, 187 -2005/08/23, 630, 185 -2005/08/22, 626, 182 -2005/08/20, 623, 181 -2005/08/19, 623, 181 -2005/08/18, 608, 176 -2005/08/17, 607, 176 -2005/08/16, 607, 176 -2005/08/15, 606, 175 -2005/08/14, 605, 175 -2005/08/13, 605, 175 -2005/08/12, 605, 175 -2005/08/11, 605, 175 -2005/08/10, 601, 173 -2005/08/09, 596, 171 -2005/08/08, 594, 171 -2005/08/07, 591, 169 -2005/08/06, 590, 169 -2005/08/05, 589, 168 -2005/08/04, 588, 167 -2005/08/03, 583, 167 -2005/08/02, 574, 165 -2005/07/31, 573, 164 -2005/07/30, 571, 161 -2005/07/29, 565, 157 -2005/07/28, 557, 156 -2005/07/27, 544, 155 -2005/07/26, 541, 154 -2005/07/25, 534, 154 -2005/07/24, 527, 149 -2005/07/23, 527, 149 -2005/07/22, 527, 149 -2005/07/21, 527, 148 -2005/07/20, 526, 144 -2005/07/19, 523, 144 -2005/07/18, 541, 149 -2005/07/15, 538, 148 -2005/07/14, 537, 148 -2005/07/13, 536, 148 -2005/07/12, 536, 148 -2005/07/11, 535, 148 -2005/07/10, 535, 148 -2005/07/09, 531, 147 -2005/07/07, 531, 147 -2005/07/06, 528, 143 -2005/07/05, 524, 141 -2005/07/04, 507, 141 -2005/07/03, 507, 141 -2005/07/02, 472, 138 -2005/07/01, 472, 137 -2005/06/30, 471, 137 -2005/06/29, 471, 137 -2005/06/28, 470, 137 -2005/06/26, 470, 137 -2005/06/25, 470, 137 -2005/06/24, 469, 136 -2005/06/23, 473, 135 -2005/06/22, 472, 134 -2005/06/21, 472, 134 -2005/06/20, 470, 134 -2005/06/19, 468, 133 -2005/06/18, 466, 131 -2005/06/17, 455, 130 -2005/06/16, 455, 130 -2005/06/15, 456, 130 -2005/06/14, 457, 130 -2005/06/13, 474, 127 -2005/06/12, 474, 126 -2005/06/11, 473, 126 -2005/06/10, 473, 125 -2005/06/09, 472, 124 -2005/06/08, 471, 125 -2005/06/07, 469, 124 -2005/06/06, 469, 124 -2005/06/05, 462, 122 -2005/06/04, 459, 123 -2005/06/03, 458, 122 -2005/06/02, 458, 122 -2005/06/01, 457, 121 -2005/05/31, 457, 120 -2005/05/30, 454, 118 -2005/05/29, 453, 114 -2005/05/28, 452, 114 -2005/05/27, 452, 114 -2005/05/26, 448, 114 -2005/05/25, 448, 114 -2005/05/24, 446, 114 -2005/05/23, 440, 113 -2005/05/22, 434, 113 -2005/05/21, 436, 113 -2005/05/20, 425, 112 -2005/05/19, 425, 112 -2005/05/18, 426, 112 -2005/05/17, 385, 115 -2005/05/16, 385, 115 -2005/05/15, 386, 115 -2005/05/14, 375, 114 -2005/05/13, 375, 114 -2005/05/12, 374, 113 -2005/05/11, 372, 111 -2005/05/10, 371, 110 -2005/05/09, 368, 108 -2005/05/08, 367, 108 -2005/05/07, 367, 107 -2005/05/06, 367, 107 -2005/05/05, 367, 107 -2005/05/04, 366, 106 -2005/05/03, 366, 106 -2005/05/02, 364, 105 -2005/05/01, 357, 104 -2005/04/30, 368, 113 -2005/04/29, 368, 112 -2005/04/28, 365, 110 -2005/04/27, 365, 110 -2005/04/26, 363, 110 -2005/04/25, 342, 129 -2005/04/24, 327, 104 -2005/04/23, 325, 104 -2005/04/22, 325, 104 -2005/04/21, 325, 104 -2005/04/20, 325, 103 -2005/04/19, 326, 101 -2005/04/18, 326, 101 -2005/04/17, 326, 101 -2005/04/16, 323, 100 -2005/04/15, 322, 100 -2005/04/14, 321, 100 -2005/04/13, 317, 97 -2005/04/12, 316, 97 -2005/04/11, 313, 96 -2005/04/10, 311, 97 -2005/04/09, 310, 97 -2005/04/08, 310, 97 -2005/04/07, 310, 97 -2005/04/06, 310, 97 -2005/04/05, 310, 97 -2005/04/04, 310, 97 -2005/04/03, 309, 97 -2005/04/02, 305, 97 -2005/04/01, 297, 97 -2005/03/31, 291, 97 -2005/03/30, 290, 97 -2005/03/29, 290, 97 -2005/03/28, 289, 96 -2005/03/27, 289, 96 -2005/03/24, 289, 96 -2005/03/23, 289, 96 -2005/03/22, 288, 97 -2005/03/21, 276, 95 -2005/03/20, 272, 94 -2005/03/19, 267, 90 -2005/03/17, 266, 90 -2005/03/15, 265, 90 -2005/03/14, 265, 90 -2005/03/13, 265, 90 -2005/03/12, 265, 90 -2005/03/11, 265, 90 -2005/03/10, 265, 90 -2005/03/06, 264, 90 -2005/03/05, 264, 90 -2005/03/04, 264, 90 -2005/03/03, 264, 90 -2005/03/02, 264, 90 -2005/03/01, 263, 90 -2005/02/28, 263, 90 -2005/02/27, 262, 90 -2005/02/26, 262, 90 -2005/02/25, 262, 90 -2005/02/24, 261, 89 -2005/02/23, 259, 89 -2005/02/22, 259, 89 -2005/02/21, 259, 88 -2005/02/19, 259, 88 -2005/02/18, 244, 88 -2005/02/17, 244, 87 -2005/02/16, 244, 87 -2005/02/15, 244, 87 -2005/02/14, 243, 87 -2005/02/13, 243, 87 -2005/02/13, 243, 87 -2005/02/13, 243, 87 -2005/02/11, 242, 87 -2005/02/10, 242, 86 -2005/02/09, 240, 85 -2005/02/08, 240, 85 -2005/02/07, 240, 85 -2005/02/06, 239, 85 -2005/02/05, 231, 84 -2005/02/04, 231, 84 -2005/02/03, 232, 83 -2005/02/02, 232, 83 -2005/02/01, 231, 82 -2005/01/31, 228, 82 -2005/01/30, 228, 82 -2005/01/29, 228, 82 -2005/01/28, 232, 80 -2005/01/27, 211, 79 -2005/01/26, 225, 80 -2005/01/25, 225, 80 -2005/01/24, 224, 78 -2005/01/23, 224, 78 -2005/01/22, 224, 78 -2005/01/20, 224, 78 -2005/01/19, 224, 78 -2005/01/18, 224, 77 -2005/01/17, 224, 77 -2005/01/16, 224, 77 -2005/01/15, 224, 77 -2005/01/14, 224, 77 -2005/01/13, 224, 77 -2005/01/12, 224, 77 -2005/01/11, 218, 76 -2005/01/10, 218, 76 -2005/01/09, 218, 76 -2005/01/08, 218, 76 -2005/01/03, 218, 76 -2005/01/02, 218, 76 -2005/01/01, 218, 76 -2004/12/30, 218, 76 -2004/12/27, 218, 76 -2004/12/24, 218, 76 -2004/12/22, 218, 75 -2004/12/20, 218, 75 -2004/12/19, 218, 75 -2004/12/18, 217, 75 -2004/12/17, 217, 75 -2004/12/16, 217, 74 -2004/12/13, 216, 74 -2004/12/10, 216, 74 -2004/12/09, 216, 74 -2004/12/08, 216, 74 -2004/12/07, 216, 74 -2004/12/06, 216, 73 -2004/12/04, 216, 73 -2004/11/30, 214, 73 -2004/11/29, 213, 73 -2004/11/28, 213, 72 -2004/11/27, 213, 72 -2004/11/25, 213, 72 -2004/11/24, 213, 72 -2004/11/23, 211, 72 -2004/11/22, 210, 71 -2004/11/21, 210, 71 -2004/11/20, 210, 71 -2004/11/19, 208, 69 -2004/11/18, 208, 69 -2004/11/17, 204, 67 -2004/11/16, 201, 66 -2004/11/15, 203, 67 +2003-02-19, 8, 0 +2003-02-20, 10, 1 +2003-02-21, 29, 5 +2003-02-22, 30, 4 +2003-02-23, 49, 12 +2003-02-24, 49, 12 +2003-02-25, 48, 12 +2003-02-26, 48, 12 +2003-02-27, 48, 12 +2003-02-28, 48, 12 +2003-03-01, 48, 12 +2003-03-03, 48, 13 +2003-03-04, 48, 13 +2003-03-18, 48, 13 +2003-04-06, 48, 13 +2003-04-11, 48, 13 +2003-04-18, 48, 14 +2003-04-19, 48, 15 +2003-05-22, 48, 15 +2003-05-25, 48, 15 +2003-05-26, 52, 19 +2003-05-27, 59, 26 +2003-05-28, 70, 27 +2003-05-29, 71, 26 +2003-05-30, 75, 37 +2003-05-31, 87, 37 +2003-06-01, 92, 37 +2003-06-02, 92, 37 +2003-06-05, 92, 37 +2003-06-06, 93, 37 +2003-06-07, 93, 37 +2003-06-08, 92, 37 +2003-06-09, 92, 37 +2003-06-13, 92, 37 +2003-06-14, 93, 37 +2003-06-15, 93, 37 +2003-06-16, 94, 37 +2003-06-17, 94, 37 +2003-06-18, 94, 37 +2003-06-19, 92, 37 +2003-06-20, 92, 37 +2003-06-21, 92, 37 +2003-06-22, 98, 40 +2003-06-23, 102, 42 +2003-06-24, 103, 43 +2003-06-28, 104, 43 +2003-06-29, 104, 43 +2003-06-30, 104, 43 +2003-07-01, 104, 43 +2003-07-02, 104, 43 +2003-07-03, 104, 43 +2003-07-04, 104, 43 +2003-07-06, 104, 43 +2003-07-07, 104, 43 +2003-07-08, 106, 43 +2003-07-10, 106, 43 +2003-07-12, 106, 43 +2003-07-13, 106, 43 +2003-07-14, 106, 43 +2003-07-15, 106, 43 +2003-07-16, 106, 43 +2003-07-17, 106, 43 +2003-07-18, 106, 43 +2003-07-19, 106, 43 +2003-07-24, 106, 43 +2003-07-26, 106, 43 +2003-07-27, 106, 43 +2003-07-28, 106, 43 +2003-07-29, 106, 43 +2003-07-30, 106, 43 +2003-07-31, 106, 43 +2003-08-01, 106, 43 +2003-08-02, 106, 43 +2003-08-06, 106, 43 +2003-08-07, 106, 43 +2003-08-09, 106, 43 +2003-08-10, 106, 43 +2003-08-17, 106, 43 +2003-08-24, 106, 43 +2003-08-25, 106, 43 +2003-09-02, 106, 43 +2003-09-07, 106, 43 +2003-09-08, 106, 43 +2003-09-09, 106, 43 +2003-09-10, 106, 43 +2003-09-12, 106, 43 +2003-09-13, 106, 43 +2003-09-14, 106, 43 +2003-09-15, 106, 43 +2003-09-16, 106, 43 +2003-09-17, 106, 43 +2003-09-18, 108, 42 +2003-09-19, 108, 42 +2003-09-20, 108, 42 +2003-09-21, 108, 42 +2003-09-22, 108, 42 +2003-09-23, 108, 46 +2003-09-25, 108, 46 +2003-09-26, 108, 46 +2003-09-28, 108, 46 +2003-09-29, 108, 46 +2003-09-30, 118, 48 +2003-10-01, 121, 49 +2003-10-02, 124, 53 +2003-10-03, 124, 53 +2003-10-04, 124, 53 +2003-10-05, 118, 52 +2003-10-06, 118, 52 +2003-10-07, 118, 52 +2003-10-08, 118, 52 +2003-10-09, 118, 52 +2003-10-10, 122, 53 +2003-10-11, 123, 54 +2003-10-12, 123, 54 +2003-10-13, 123, 54 +2003-10-14, 123, 54 +2003-10-15, 123, 54 +2003-10-16, 124, 54 +2003-10-17, 125, 54 +2003-10-18, 126, 54 +2003-10-20, 126, 54 +2003-10-21, 126, 54 +2003-10-23, 126, 54 +2003-10-24, 127, 54 +2003-10-25, 127, 54 +2003-10-26, 130, 54 +2003-10-27, 131, 53 +2003-10-28, 131, 53 +2003-10-29, 131, 53 +2003-10-30, 131, 53 +2003-10-31, 131, 53 +2003-11-03, 130, 53 +2003-11-04, 130, 53 +2003-11-05, 130, 53 +2003-11-10, 130, 53 +2003-11-11, 131, 54 +2003-11-13, 131, 54 +2003-11-14, 131, 54 +2003-11-17, 131, 54 +2003-11-18, 131, 55 +2003-11-19, 131, 54 +2003-11-20, 131, 54 +2003-11-21, 131, 54 +2003-11-22, 131, 54 +2003-11-24, 130, 55 +2003-11-25, 130, 55 +2003-11-26, 129, 55 +2003-11-27, 133, 55 +2003-11-28, 133, 55 +2003-11-29, 133, 55 +2003-11-30, 140, 55 +2003-12-01, 140, 55 +2003-12-02, 140, 55 +2003-12-03, 140, 55 +2003-12-04, 140, 55 +2003-12-08, 140, 55 +2003-12-09, 140, 55 +2003-12-10, 140, 55 +2003-12-11, 140, 55 +2003-12-12, 140, 55 +2003-12-13, 140, 55 +2003-12-15, 140, 55 +2003-12-16, 145, 55 +2003-12-17, 147, 56 +2003-12-18, 149, 57 +2003-12-19, 156, 57 +2003-12-20, 159, 58 +2003-12-21, 161, 58 +2003-12-22, 161, 58 +2003-12-23, 161, 58 +2003-12-24, 162, 58 +2003-12-27, 162, 58 +2003-12-28, 162, 58 +2003-12-29, 162, 58 +2003-12-31, 162, 58 +2004-01-01, 165, 59 +2004-01-02, 165, 59 +2004-01-05, 165, 59 +2004-01-06, 160, 59 +2004-01-07, 160, 59 +2004-01-08, 160, 59 +2004-01-09, 161, 59 +2004-01-10, 161, 59 +2004-01-11, 161, 59 +2004-01-12, 161, 59 +2004-01-13, 161, 59 +2004-01-14, 161, 59 +2004-01-15, 161, 59 +2004-01-16, 161, 59 +2004-01-17, 161, 59 +2004-01-18, 161, 59 +2004-01-19, 161, 59 +2004-01-20, 161, 59 +2004-01-21, 161, 59 +2004-01-22, 161, 59 +2004-01-23, 161, 59 +2004-01-26, 161, 59 +2004-01-27, 161, 59 +2004-01-28, 161, 59 +2004-01-29, 161, 59 +2004-01-30, 161, 59 +2004-02-02, 161, 59 +2004-02-03, 161, 59 +2004-02-04, 161, 59 +2004-02-05, 161, 59 +2004-02-07, 161, 59 +2004-02-08, 161, 59 +2004-02-09, 161, 59 +2004-02-10, 161, 59 +2004-02-11, 161, 59 +2004-02-12, 161, 59 +2004-02-13, 161, 59 +2004-02-14, 161, 59 +2004-02-15, 161, 59 +2004-02-16, 161, 59 +2004-02-19, 161, 59 +2004-02-20, 161, 59 +2004-02-21, 161, 59 +2004-02-23, 161, 59 +2004-02-24, 161, 59 +2004-02-25, 161, 59 +2004-02-26, 161, 59 +2004-02-27, 161, 59 +2004-02-28, 161, 59 +2004-02-29, 161, 59 +2004-03-01, 161, 59 +2004-03-02, 161, 59 +2004-03-03, 161, 59 +2004-03-04, 161, 59 +2004-03-05, 161, 59 +2004-03-06, 161, 59 +2004-03-07, 161, 59 +2004-03-08, 161, 59 +2004-03-09, 161, 59 +2004-03-10, 161, 59 +2004-03-11, 161, 59 +2004-03-12, 161, 59 +2004-03-13, 161, 59 +2004-03-14, 161, 59 +2004-03-16, 161, 59 +2004-03-17, 161, 59 +2004-03-18, 161, 59 +2004-03-19, 161, 59 +2004-03-21, 161, 59 +2004-03-22, 161, 59 +2004-03-23, 161, 59 +2004-03-24, 162, 59 +2004-03-25, 162, 59 +2004-03-26, 162, 59 +2004-03-28, 162, 59 +2004-03-29, 161, 59 +2004-03-30, 161, 59 +2004-03-31, 161, 59 +2004-04-01, 161, 59 +2004-04-02, 161, 59 +2004-04-03, 161, 59 +2004-04-04, 161, 59 +2004-04-05, 161, 59 +2004-04-06, 161, 59 +2004-04-07, 161, 59 +2004-04-08, 161, 59 +2004-04-09, 161, 59 +2004-04-10, 161, 59 +2004-04-11, 161, 59 +2004-04-13, 161, 59 +2004-04-14, 161, 59 +2004-04-15, 161, 59 +2004-04-16, 161, 59 +2004-04-17, 161, 59 +2004-04-18, 161, 59 +2004-04-19, 161, 59 +2004-04-20, 161, 59 +2004-04-21, 161, 59 +2004-04-22, 161, 59 +2004-04-23, 161, 59 +2004-04-24, 161, 59 +2004-04-25, 161, 59 +2004-04-26, 161, 59 +2004-04-27, 161, 59 +2004-04-28, 161, 59 +2004-04-29, 161, 59 +2004-04-30, 161, 59 +2004-05-01, 161, 59 +2004-05-02, 161, 59 +2004-05-03, 161, 59 +2004-05-04, 161, 59 +2004-05-05, 161, 59 +2004-05-06, 161, 59 +2004-05-07, 164, 59 +2004-05-08, 165, 59 +2004-05-09, 165, 59 +2004-05-10, 165, 59 +2004-05-11, 165, 59 +2004-05-12, 167, 59 +2004-05-13, 167, 59 +2004-05-14, 167, 59 +2004-05-15, 167, 59 +2004-05-16, 167, 59 +2004-05-17, 167, 59 +2004-05-18, 167, 59 +2004-05-19, 167, 59 +2004-05-20, 167, 59 +2004-05-21, 167, 59 +2004-05-22, 167, 59 +2004-05-23, 167, 59 +2004-05-24, 167, 59 +2004-05-25, 167, 59 +2004-05-26, 167, 59 +2004-05-27, 167, 59 +2004-05-28, 168, 59 +2004-05-29, 168, 59 +2004-05-30, 168, 59 +2004-05-31, 168, 59 +2004-06-01, 176, 61 +2004-06-02, 188, 63 +2004-06-03, 188, 63 +2004-06-04, 188, 63 +2004-06-05, 190, 63 +2004-06-06, 190, 63 +2004-06-07, 195, 64 +2004-06-08, 195, 64 +2004-06-09, 195, 64 +2004-06-10, 195, 64 +2004-06-11, 198, 64 +2004-06-12, 198, 64 +2004-06-13, 199, 64 +2004-06-15, 199, 64 +2004-06-16, 184, 65 +2004-06-17, 185, 64 +2004-06-18, 185, 64 +2004-06-19, 185, 64 +2004-06-20, 185, 64 +2004-06-21, 185, 64 +2004-06-22, 186, 64 +2004-06-23, 186, 64 +2004-06-24, 186, 64 +2004-06-25, 186, 64 +2004-06-26, 187, 64 +2004-06-27, 188, 65 +2004-06-28, 195, 67 +2004-06-29, 195, 67 +2004-06-30, 195, 67 +2004-07-01, 195, 67 +2004-07-02, 196, 67 +2004-07-03, 195, 67 +2004-07-04, 194, 67 +2004-07-05, 194, 67 +2004-07-06, 195, 69 +2004-07-07, 195, 69 +2004-07-08, 195, 69 +2004-07-09, 195, 69 +2004-07-10, 195, 69 +2004-07-11, 195, 69 +2004-07-12, 198, 69 +2004-07-13, 198, 69 +2004-07-14, 198, 69 +2004-07-15, 198, 69 +2004-07-16, 198, 68 +2004-07-17, 192, 66 +2004-07-21, 192, 66 +2004-07-22, 192, 66 +2004-07-23, 192, 66 +2004-07-24, 194, 66 +2004-07-25, 195, 66 +2004-07-26, 195, 66 +2004-07-27, 195, 66 +2004-07-28, 197, 67 +2004-07-29, 197, 67 +2004-07-30, 197, 67 +2004-07-31, 197, 67 +2004-08-01, 197, 67 +2004-08-02, 197, 67 +2004-08-03, 197, 67 +2004-08-04, 197, 67 +2004-08-05, 197, 67 +2004-08-06, 197, 67 +2004-08-07, 197, 67 +2004-08-08, 197, 67 +2004-08-09, 197, 67 +2004-08-10, 197, 67 +2004-08-11, 197, 67 +2004-08-12, 197, 67 +2004-08-13, 197, 67 +2004-08-14, 198, 67 +2004-08-15, 198, 67 +2004-08-16, 199, 67 +2004-08-17, 199, 67 +2004-08-18, 199, 67 +2004-08-19, 199, 67 +2004-08-20, 199, 67 +2004-08-21, 199, 67 +2004-08-22, 199, 67 +2004-08-23, 199, 67 +2004-08-24, 200, 67 +2004-08-25, 200, 67 +2004-08-26, 200, 67 +2004-08-27, 200, 67 +2004-08-30, 200, 67 +2004-08-31, 200, 67 +2004-09-01, 200, 67 +2004-09-02, 200, 67 +2004-09-03, 200, 67 +2004-09-04, 200, 67 +2004-09-06, 200, 67 +2004-09-07, 205, 68 +2004-09-08, 205, 68 +2004-09-09, 206, 68 +2004-09-10, 207, 68 +2004-09-11, 207, 68 +2004-09-12, 207, 68 +2004-09-13, 207, 68 +2004-09-14, 207, 68 +2004-09-15, 207, 68 +2004-09-16, 207, 68 +2004-09-17, 207, 68 +2004-09-18, 207, 68 +2004-09-19, 207, 68 +2004-09-20, 207, 68 +2004-09-21, 207, 68 +2004-09-22, 207, 68 +2004-09-23, 207, 68 +2004-09-24, 207, 68 +2004-09-25, 207, 68 +2004-09-26, 207, 68 +2004-09-27, 207, 68 +2004-09-28, 207, 68 +2004-09-29, 207, 68 +2004-09-30, 207, 68 +2004-10-01, 207, 68 +2004-10-02, 207, 68 +2004-10-03, 207, 68 +2004-10-04, 207, 68 +2004-10-05, 207, 68 +2004-10-06, 207, 68 +2004-10-07, 207, 68 +2004-10-08, 207, 68 +2004-10-09, 207, 68 +2004-10-10, 202, 68 +2004-10-11, 202, 68 +2004-10-13, 202, 68 +2004-10-14, 202, 68 +2004-10-15, 202, 68 +2004-10-16, 202, 68 +2004-10-17, 202, 68 +2004-10-18, 202, 68 +2004-10-19, 202, 68 +2004-10-20, 202, 68 +2004-10-21, 202, 68 +2004-10-22, 202, 68 +2004-10-23, 202, 68 +2004-10-24, 202, 68 +2004-10-25, 202, 68 +2004-10-26, 202, 68 +2004-10-27, 202, 68 +2004-10-28, 202, 68 +2004-10-29, 202, 68 +2004-10-30, 202, 68 +2004-10-31, 202, 68 +2004-11-01, 202, 68 +2004-11-02, 202, 68 +2004-11-03, 202, 68 +2004-11-04, 202, 68 +2004-11-05, 202, 68 +2004-11-06, 202, 68 +2004-11-08, 202, 68 +2004-11-09, 202, 68 +2004-11-10, 202, 68 +2004-11-11, 202, 68 2004/11/12, 202, 68 -2004/11/11, 202, 68 +2004/11/15, 203, 67 +2004/11/16, 201, 66 +2004/11/17, 204, 67 +2004/11/18, 208, 69 +2004/11/19, 208, 69 +2004/11/20, 210, 71 +2004/11/21, 210, 71 +2004/11/22, 210, 71 +2004/11/23, 211, 72 +2004/11/24, 213, 72 +2004/11/25, 213, 72 +2004/11/27, 213, 72 +2004/11/28, 213, 72 +2004/11/29, 213, 73 +2004/11/30, 214, 73 +2004/12/04, 216, 73 +2004/12/06, 216, 73 +2004/12/07, 216, 74 +2004/12/08, 216, 74 +2004/12/09, 216, 74 +2004/12/10, 216, 74 +2004/12/13, 216, 74 +2004/12/16, 217, 74 +2004/12/17, 217, 75 +2004/12/18, 217, 75 +2004/12/19, 218, 75 +2004/12/20, 218, 75 +2004/12/22, 218, 75 +2004/12/24, 218, 76 +2004/12/27, 218, 76 +2004/12/30, 218, 76 +2005/01/01, 218, 76 +2005/01/02, 218, 76 +2005/01/03, 218, 76 +2005/01/08, 218, 76 +2005/01/09, 218, 76 +2005/01/10, 218, 76 +2005/01/11, 218, 76 +2005/01/12, 224, 77 +2005/01/13, 224, 77 +2005/01/14, 224, 77 +2005/01/15, 224, 77 +2005/01/16, 224, 77 +2005/01/17, 224, 77 +2005/01/18, 224, 77 +2005/01/19, 224, 78 +2005/01/20, 224, 78 +2005/01/22, 224, 78 +2005/01/23, 224, 78 +2005/01/24, 224, 78 +2005/01/25, 225, 80 +2005/01/26, 225, 80 +2005/01/27, 211, 79 +2005/01/28, 232, 80 +2005/01/29, 228, 82 +2005/01/30, 228, 82 +2005/01/31, 228, 82 +2005/02/01, 231, 82 +2005/02/02, 232, 83 +2005/02/03, 232, 83 +2005/02/04, 231, 84 +2005/02/05, 231, 84 +2005/02/06, 239, 85 +2005/02/07, 240, 85 +2005/02/08, 240, 85 +2005/02/09, 240, 85 +2005/02/10, 242, 86 +2005/02/11, 242, 87 +2005/02/13, 243, 87 +2005/02/13, 243, 87 +2005/02/13, 243, 87 +2005/02/14, 243, 87 +2005/02/15, 244, 87 +2005/02/16, 244, 87 +2005/02/17, 244, 87 +2005/02/18, 244, 88 +2005/02/19, 259, 88 +2005/02/21, 259, 88 +2005/02/22, 259, 89 +2005/02/23, 259, 89 +2005/02/24, 261, 89 +2005/02/25, 262, 90 +2005/02/26, 262, 90 +2005/02/27, 262, 90 +2005/02/28, 263, 90 +2005/03/01, 263, 90 +2005/03/02, 264, 90 +2005/03/03, 264, 90 +2005/03/04, 264, 90 +2005/03/05, 264, 90 +2005/03/06, 264, 90 +2005/03/10, 265, 90 +2005/03/11, 265, 90 +2005/03/12, 265, 90 +2005/03/13, 265, 90 +2005/03/14, 265, 90 +2005/03/15, 265, 90 +2005/03/17, 266, 90 +2005/03/19, 267, 90 +2005/03/20, 272, 94 +2005/03/21, 276, 95 +2005/03/22, 288, 97 +2005/03/23, 289, 96 +2005/03/24, 289, 96 +2005/03/27, 289, 96 +2005/03/28, 289, 96 +2005/03/29, 290, 97 +2005/03/30, 290, 97 +2005/03/31, 291, 97 +2005/04/01, 297, 97 +2005/04/02, 305, 97 +2005/04/03, 309, 97 +2005/04/04, 310, 97 +2005/04/05, 310, 97 +2005/04/06, 310, 97 +2005/04/07, 310, 97 +2005/04/08, 310, 97 +2005/04/09, 310, 97 +2005/04/10, 311, 97 +2005/04/11, 313, 96 +2005/04/12, 316, 97 +2005/04/13, 317, 97 +2005/04/14, 321, 100 +2005/04/15, 322, 100 +2005/04/16, 323, 100 +2005/04/17, 326, 101 +2005/04/18, 326, 101 +2005/04/19, 326, 101 +2005/04/20, 325, 103 +2005/04/21, 325, 104 +2005/04/22, 325, 104 +2005/04/23, 325, 104 +2005/04/24, 327, 104 +2005/04/25, 342, 129 +2005/04/26, 363, 110 +2005/04/27, 365, 110 +2005/04/28, 365, 110 +2005/04/29, 368, 112 +2005/04/30, 368, 113 +2005/05/01, 357, 104 +2005/05/02, 364, 105 +2005/05/03, 366, 106 +2005/05/04, 366, 106 +2005/05/05, 367, 107 +2005/05/06, 367, 107 +2005/05/07, 367, 107 +2005/05/08, 367, 108 +2005/05/09, 368, 108 +2005/05/10, 371, 110 +2005/05/11, 372, 111 +2005/05/12, 374, 113 +2005/05/13, 375, 114 +2005/05/14, 375, 114 +2005/05/15, 386, 115 +2005/05/16, 385, 115 +2005/05/17, 385, 115 +2005/05/18, 426, 112 +2005/05/19, 425, 112 +2005/05/20, 425, 112 +2005/05/21, 436, 113 +2005/05/22, 434, 113 +2005/05/23, 440, 113 +2005/05/24, 446, 114 +2005/05/25, 448, 114 +2005/05/26, 448, 114 +2005/05/27, 452, 114 +2005/05/28, 452, 114 +2005/05/29, 453, 114 +2005/05/30, 454, 118 +2005/05/31, 457, 120 +2005/06/01, 457, 121 +2005/06/02, 458, 122 +2005/06/03, 458, 122 +2005/06/04, 459, 123 +2005/06/05, 462, 122 +2005/06/06, 469, 124 +2005/06/07, 469, 124 +2005/06/08, 471, 125 +2005/06/09, 472, 124 +2005/06/10, 473, 125 +2005/06/11, 473, 126 +2005/06/12, 474, 126 +2005/06/13, 474, 127 +2005/06/14, 457, 130 +2005/06/15, 456, 130 +2005/06/16, 455, 130 +2005/06/17, 455, 130 +2005/06/18, 466, 131 +2005/06/19, 468, 133 +2005/06/20, 470, 134 +2005/06/21, 472, 134 +2005/06/22, 472, 134 +2005/06/23, 473, 135 +2005/06/24, 469, 136 +2005/06/25, 470, 137 +2005/06/26, 470, 137 +2005/06/28, 470, 137 +2005/06/29, 471, 137 +2005/06/30, 471, 137 +2005/07/01, 472, 137 +2005/07/02, 472, 138 +2005/07/03, 507, 141 +2005/07/04, 507, 141 +2005/07/05, 524, 141 +2005/07/06, 528, 143 +2005/07/07, 531, 147 +2005/07/09, 531, 147 +2005/07/10, 535, 148 +2005/07/11, 535, 148 +2005/07/12, 536, 148 +2005/07/13, 536, 148 +2005/07/14, 537, 148 +2005/07/15, 538, 148 +2005/07/18, 541, 149 +2005/07/19, 523, 144 +2005/07/20, 526, 144 +2005/07/21, 527, 148 +2005/07/22, 527, 149 +2005/07/23, 527, 149 +2005/07/24, 527, 149 +2005/07/25, 534, 154 +2005/07/26, 541, 154 +2005/07/27, 544, 155 +2005/07/28, 557, 156 +2005/07/29, 565, 157 +2005/07/30, 571, 161 +2005/07/31, 573, 164 +2005/08/02, 574, 165 +2005/08/03, 583, 167 +2005/08/04, 588, 167 +2005/08/05, 589, 168 +2005/08/06, 590, 169 +2005/08/07, 591, 169 +2005/08/08, 594, 171 +2005/08/09, 596, 171 +2005/08/10, 601, 173 +2005/08/11, 605, 175 +2005/08/12, 605, 175 +2005/08/13, 605, 175 +2005/08/14, 605, 175 +2005/08/15, 606, 175 +2005/08/16, 607, 176 +2005/08/17, 607, 176 +2005/08/18, 608, 176 +2005/08/19, 623, 181 +2005/08/20, 623, 181 +2005/08/22, 626, 182 +2005/08/23, 630, 185 +2005/08/24, 633, 187 +2005/08/25, 625, 187 +2005/08/26, 626, 188 +2005/08/27, 630, 190 +2005/08/28, 630, 190 +2005/08/29, 630, 190 +2005/08/30, 630, 190 +2005/08/31, 630, 190 +2005/09/01, 630, 190 +2005/09/02, 630, 191 +2005/09/03, 630, 191 +2005/09/04, 630, 191 +2005/09/05, 631, 191 +2005/09/06, 646, 191 +2005/09/07, 647, 191 +2005/09/08, 622, 191 +2005/09/09, 625, 192 +2005/09/10, 623, 192 +2005/09/11, 623, 192 +2005/09/12, 623, 192 +2005/09/13, 629, 196 +2005/09/14, 629, 196 +2005/09/15, 631, 196 +2005/09/16, 631, 196 +2005/09/17, 631, 196 +2005/09/18, 632, 196 +2005/09/19, 635, 196 +2005/09/20, 635, 196 +2005/09/21, 636, 196 +2005/09/22, 637, 196 +2005/09/23, 638, 196 +2005/09/24, 638, 195 +2005/09/25, 638, 195 +2005/09/26, 641, 199 +2005/09/27, 645, 200 +2005/09/28, 645, 199 +2005/09/29, 645, 199 +2005/09/30, 644, 200 +2005/10/01, 643, 199 +2005/10/02, 647, 201 +2005/10/03, 648, 201 +2005/10/04, 650, 202 +2005/10/05, 648, 202 +2005/10/06, 629, 200 +2005/10/07, 629, 201 +2005/10/08, 629, 201 +2005/10/09, 629, 201 +2005/10/10, 652, 216 +2005/10/11, 657, 216 +2005/10/12, 663, 217 +2005/10/13, 662, 217 +2005/10/14, 681, 224 +2005/10/15, 688, 226 +2005/10/16, 693, 228 +2005/10/17, 693, 228 +2005/10/18, 695, 229 +2005/10/19, 696, 230 +2005/10/20, 696, 230 +2005/10/21, 698, 230 +2005/10/22, 698, 230 +2005/10/23, 698, 230 +2005/10/24, 698, 229 +2005/10/25, 697, 229 +2005/10/26, 697, 230 +2005/10/27, 684, 230 +2005/10/28, 684, 231 +2005/10/29, 684, 231 +2005/10/30, 681, 231 +2005/10/31, 681, 231 +2005/11/01, 681, 231 +2005/11/02, 681, 231 +2005/11/03, 681, 231 +2005/11/04, 681, 231 +2005/11/05, 681, 231 +2005/11/06, 681, 231 +2005/11/07, 681, 231 +2005/11/08, 681, 231 +2005/11/09, 681, 231 +2005/11/10, 683, 231 +2005/11/11, 683, 232 +2005/11/12, 683, 232 +2005/11/13, 683, 232 +2005/11/14, 683, 232 +2005/11/15, 683, 232 +2005/11/16, 682, 232 +2005/11/17, 683, 232 +2005/11/18, 683, 232 +2005/11/19, 683, 232 +2005/11/21, 683, 232 +2005/11/22, 683, 232 +2005/11/23, 683, 232 +2005/11/25, 683, 232 +2005/11/27, 683, 232 +2005/11/28, 685, 233 +2005/11/29, 686, 233 +2005/11/30, 687, 233 +2005/12/01, 689, 232 +2005/12/02, 690, 233 +2005/12/03, 690, 233 +2005/12/04, 690, 233 +2005/12/05, 690, 233 +2005/12/06, 690, 233 +2005/12/07, 694, 235 +2005/12/08, 694, 237 +2005/12/09, 698, 240 +2005/12/10, 698, 240 +2005/12/11, 699, 239 +2005/12/12, 699, 239 +2005/12/13, 700, 239 +2005/12/14, 700, 240 +2005/12/15, 703, 243 +2005/12/16, 703, 243 +2005/12/17, 704, 243 +2005/12/18, 704, 243 +2005/12/19, 704, 243 +2005/12/20, 704, 243 +2005/12/21, 704, 245 +2005/12/22, 704, 245 +2005/12/23, 704, 246 +2005/12/24, 704, 246 +2005/12/25, 704, 246 +2005/12/27, 704, 246 +2005/12/29, 706, 247 +2005/12/30, 708, 247 +2005/12/31, 708, 247 +2006/01/02, 710, 247 +2006/01/04, 710, 247 +2006/01/05, 710, 247 +2006/01/06, 711, 247 +2006/01/07, 711, 248 +2006/01/08, 711, 248 +2006/01/09, 711, 248 +2006/01/10, 712, 249 +2006/01/11, 712, 249 +2006/01/12, 712, 249 +2006/01/13, 712, 249 +2006/01/14, 713, 250 +2006/01/15, 713, 251 +2006/01/16, 713, 251 +2006/01/17, 713, 251 +2006/01/18, 713, 251 +2006/01/19, 714, 252 +2006/01/20, 715, 253 +2006/01/21, 715, 253 +2006/01/22, 715, 253 +2006/01/23, 721, 255 +2006/01/24, 725, 257 +2006/01/25, 731, 261 +2006/01/26, 735, 264 +2006/01/27, 746, 266 +2006/01/28, 744, 265 +2006/01/29, 745, 265 +2006/01/30, 745, 265 +2006/01/31, 746, 268 +2006/02/01, 746, 268 +2006/02/02, 747, 268 +2006/02/03, 747, 269 +2006/02/04, 749, 270 +2006/02/05, 749, 270 +2006/02/06, 749, 271 +2006/02/07, 749, 274 +2006/02/08, 753, 275 +2006/02/09, 754, 275 +2006/02/10, 754, 275 +2006/02/11, 754, 275 +2006/02/12, 755, 275 +2006/02/13, 755, 275 +2006/02/14, 756, 275 +2006/02/15, 756, 276 +2006/02/16, 759, 278 +2006/02/17, 759, 279 +2006/02/18, 759, 279 +2006/02/19, 760, 279 +2006/02/20, 760, 279 +2006/02/21, 761, 281 +2006/02/22, 761, 281 +2006/02/23, 762, 282 +2006/02/25, 762, 282 +2006/02/26, 762, 282 +2006/02/27, 764, 283 +2006/02/28, 766, 284 +2006/03/01, 775, 287 +2006/03/02, 776, 287 +2006/03/03, 776, 287 +2006/03/04, 776, 287 +2006/03/06, 777, 287 +2006/03/07, 777, 287 +2006/03/08, 778, 287 +2006/03/09, 781, 288 +2006/03/10, 781, 288 +2006/03/11, 781, 288 +2006/03/12, 781, 288 +2006/03/13, 784, 289 +2006/03/14, 784, 289 +2006/03/15, 784, 290 +2006/03/16, 785, 290 +2006/03/17, 786, 291 +2006/03/18, 786, 291 +2006/03/19, 788, 291 +2006/03/20, 792, 292 +2006/03/21, 792, 292 +2006/03/22, 806, 294 +2006/03/23, 809, 295 +2006/03/24, 813, 297 +2006/03/25, 813, 299 +2006/03/26, 814, 299 +2006/03/27, 815, 299 +2006/03/28, 818, 300 +2006/03/29, 820, 300 +2006/03/30, 820, 300 +2006/03/31, 821, 301 +2006/04/01, 829, 302 +2006/04/02, 840, 304 +2006/04/03, 842, 305 +2006/04/04, 846, 305 +2006/04/05, 853, 305 +2006/04/06, 848, 305 +2006/04/07, 852, 308 +2006/04/08, 854, 308 +2006/04/09, 875, 309 +2006/04/10, 878, 312 +2006/04/11, 878, 313 +2006/04/12, 880, 315 +2006/04/13, 884, 316 +2006/04/14, 887, 316 +2006/04/15, 896, 318 +2006/04/16, 897, 319 +2006/04/17, 900, 320 +2006/04/18, 900, 321 +2006/04/19, 910, 323 +2006/04/20, 919, 325 +2006/04/21, 924, 326 +2006/04/22, 927, 328 +2006/04/23, 930, 333 +2006/04/24, 935, 336 +2006/04/25, 940, 338 +2006/04/26, 943, 339 +2006/04/27, 943, 342 +2006/04/28, 945, 345 +2006/04/29, 946, 347 +2006/04/30, 948, 347 +2006/05/01, 948, 347 +2006/05/02, 949, 349 +2006/05/03, 949, 350 +2006/05/04, 948, 351 +2006/05/05, 949, 351 +2006/05/06, 950, 353 +2006/05/07, 950, 353 +2006/05/08, 949, 353 +2006/05/09, 950, 354 +2006/05/10, 955, 355 +2006/05/11, 955, 355 +2006/05/12, 957, 356 +2006/05/13, 957, 356 +2006/05/14, 952, 356 +2006/05/15, 952, 357 +2006/05/16, 952, 357 +2006/05/17, 962, 357 +2006/05/18, 960, 356 +2006/05/19, 961, 357 +2006/05/20, 972, 358 +2006/05/21, 974, 359 +2006/05/22, 974, 359 +2006/05/23, 975, 359 +2006/05/24, 976, 361 +2006/05/25, 976, 361 +2006/05/26, 976, 362 +2006/05/27, 977, 362 +2006/05/28, 977, 362 +2006/05/29, 981, 372 +2006/05/30, 982, 372 +2006/05/31, 982, 372 +2006/06/02, 988, 374 +2006/06/03, 990, 374 +2006/06/04, 998, 379 +2006/06/05, 1003, 381 +2006/06/06, 1010, 384 +2006/06/07, 1019, 385 +2006/06/08, 1021, 386 +2006/06/09, 1004, 369 +2006/06/10, 1004, 369 +2006/06/11, 1005, 369 +2006/06/12, 1010, 371 +2006/06/13, 1004, 371 +2006/06/14, 1005, 371 +2006/06/15, 1006, 375 +2006/06/16, 1007, 377 +2006/06/17, 1007, 377 +2006/06/18, 1007, 377 +2006/06/19, 1007, 377 +2006/06/20, 1007, 377 +2006/06/21, 1003, 377 +2006/06/22, 1011, 378 +2006/06/23, 1011, 378 +2006/06/24, 1013, 378 +2006/06/25, 1016, 380 +2006/06/26, 1017, 381 +2006/06/27, 1017, 381 +2006/06/28, 1018, 381 +2006/06/29, 1019, 384 +2006/06/30, 1012, 384 +2006/07/01, 1012, 384 +2006/07/02, 1015, 384 +2006/07/03, 1015, 384 +2006/07/04, 1015, 384 +2006/07/05, 1016, 384 +2006/07/06, 1020, 386 +2006/07/07, 1031, 393 +2006/07/08, 1036, 402 +2006/07/09, 1038, 403 +2006/07/10, 1038, 403 +2006/07/11, 1036, 406 +2006/07/12, 1039, 407 +2006/07/13, 1040, 407 +2006/07/14, 1041, 407 +2006/07/15, 1042, 407 +2006/07/16, 1043, 408 +2006/07/17, 1044, 408 +2006-07-18, 1044, 408 +2006-07-19, 1044, 408 +2006-07-20, 1043, 409 +2006-07-21, 1045, 409 +2006-07-22, 1045, 409 +2006-07-23, 1045, 409 +2006-07-24, 1046, 409 +2006-07-25, 1046, 410 +2006-07-26, 1046, 410 +2006-07-27, 1063, 415 +2006-07-28, 1065, 415 +2006-07-29, 1068, 416 +2006-07-30, 1068, 416 +2006-07-31, 1068, 416 +2006-08-01, 1071, 416 +2006-08-02, 1073, 416 +2006-08-03, 1061, 412 +2006-08-04, 1062, 413 +2006-08-05, 1067, 414 +2006-08-06, 1067, 414 +2006-08-07, 1067, 414 +2006-08-08, 1080, 418 +2006-08-09, 1081, 420 +2006-08-10, 1085, 421 +2006-08-11, 1087, 423 +2006-08-12, 1088, 423 +2006-08-13, 1088, 423 +2006-08-14, 1088, 423 +2006-08-15, 1088, 423 +2006-08-16, 1089, 424 +2006-08-17, 1091, 424 +2006-08-18, 1091, 424 +2006-08-19, 1091, 424 +2006-08-20, 1091, 424 +2006-08-21, 1091, 424 +2006-08-22, 1091, 424 +2006-08-23, 1092, 425 +2006-08-24, 1096, 425 +2006-08-25, 1097, 426 +2006-08-26, 1102, 426 +2006-08-27, 1107, 427 +2006-08-28, 1108, 427 +2006-08-29, 1108, 427 +2006-08-30, 1109, 427 +2006-08-31, 1109, 431 +2006-09-01, 1113, 432 +2006-09-02, 1113, 432 +2006-09-03, 1116, 433 +2006-09-04, 1118, 435 +2006-09-05, 1118, 435 +2006-09-06, 1119, 436 +2006-09-07, 1119, 437 +2006-09-08, 1119, 438 +2006-09-09, 1121, 441 +2006-09-10, 1121, 441 +2006-09-11, 1122, 442 +2006-09-12, 1122, 442 +2006-09-13, 1122, 444 +2006-09-14, 1122, 444 +2006-09-15, 1123, 445 +2006-09-16, 1123, 445 +2006-09-17, 1123, 445 +2006-09-18, 1124, 447 +2006-09-19, 1124, 447 +2006-09-20, 1124, 447 +2006-09-21, 1124, 447 +2006-09-22, 1123, 447 +2006-09-23, 1124, 448 +2006-09-24, 1124, 448 +2006-09-25, 1124, 448 +2006-09-26, 1124, 448 +2006-09-27, 1124, 448 +2006-09-28, 1124, 448 +2006-09-29, 1119, 448 +2006-09-30, 1117, 448 +2006-10-01, 1117, 448 +2006-10-02, 1118, 448 +2006-10-03, 1118, 448 +2006-10-04, 1121, 449 +2006-10-05, 1128, 456 +2006-10-06, 1130, 456 +2006-10-07, 1130, 456 +2006-10-08, 1130, 456 +2006-10-09, 1130, 456 +2006-10-10, 1132, 462 +2006-10-11, 1124, 457 +2006-10-12, 1129, 458 +2006-10-13, 1129, 458 +2006-10-14, 1134, 458 +2006-10-15, 1134, 458 +2006-10-16, 1138, 458 +2006-10-17, 1139, 459 +2006-10-18, 1143, 457 +2006-10-19, 1145, 457 +2006-10-20, 1146, 458 +2006-10-21, 1146, 458 +2006-10-22, 1150, 459 +2006-10-23, 1150, 459 +2006-10-24, 1151, 459 +2006-10-25, 1151, 460 +2006-10-26, 1151, 461 +2006-10-27, 1151, 461 +2006-10-28, 1150, 460 +2006-10-29, 1150, 460 +2006-10-30, 1150, 460 +2006-10-31, 1162, 463 +2006-11-01, 1168, 466 +2006-11-02, 1167, 464 +2006-11-03, 1171, 466 +2006-11-04, 1171, 467 +2006-11-05, 1175, 467 +2006-11-06, 1175, 472 +2006-11-07, 1172, 470 +2006-11-08, 1174, 472 +2006-11-09, 1175, 473 +2006-11-10, 1175, 473 +2006-11-11, 1174, 473 +2006-11-12, 1178, 473 +2006-11-13, 1219, 488 +2006-11-14, 1220, 488 +2006-11-15, 1221, 489 +2006-11-16, 1221, 490 +2006-11-17, 1221, 490 +2006-11-18, 1221, 490 +2006-11-19, 1223, 491 +2006-11-20, 1225, 492 +2006-11-21, 1226, 493 +2006-11-22, 1226, 493 +2006-11-23, 1226, 493 +2006-11-24, 1229, 494 +2006-11-25, 1229, 494 +2006-11-26, 1229, 494 +2006-11-27, 1230, 494 +2006-11-28, 1230, 495 +2006-11-29, 1232, 495 +2006-11-30, 1233, 495 +2006-12-01, 1235, 495 +2006-12-02, 1235, 495 +2006-12-03, 1235, 495 +2006-12-04, 1235, 495 +2006-12-05, 1245, 500 +2006-12-06, 1246, 501 +2006-12-07, 1246, 501 +2006-12-08, 1246, 501 +2006-12-09, 1247, 501 +2006-12-10, 1254, 501 +2006-12-11, 1254, 506 +2006-12-12, 1254, 506 +2006-12-13, 1254, 506 +2006-12-14, 1258, 507 +2006-12-15, 1265, 512 +2006-12-16, 1267, 514 +2006-12-17, 1268, 514 +2006-12-18, 1268, 514 +2006-12-19, 1268, 513 +2006-12-20, 1268, 513 +2006-12-21, 1271, 512 +2006-12-22, 1271, 513 +2006-12-23, 1271, 513 +2006-12-24, 1271, 513 +2006-12-25, 1271, 513 +2006-12-26, 1270, 513 +2006-12-27, 1269, 513 +2006-12-28, 1271, 513 +2006-12-29, 1272, 514 +2006-12-30, 1273, 514 +2006-12-31, 1273, 514 +2007-01-01, 1273, 514 +2007-01-02, 1276, 513 +2007-01-03, 1277, 515 +2007-01-04, 1276, 515 +2007-01-05, 1278, 515 +2007-01-06, 1278, 515 +2007-01-07, 1278, 515 +2007-01-08, 1278, 515 +2007-01-09, 1283, 516 +2007-01-10, 1283, 517 +2007-01-11, 1284, 522 +2007-01-12, 1285, 525 +2007-01-13, 1292, 531 +2007-01-14, 1292, 531 +2007-01-15, 1296, 533 +2007-01-16, 1300, 533 +2007-01-17, 1301, 533 +2007-01-18, 1301, 533 +2007-01-19, 1301, 533 +2007-01-20, 1301, 533 +2007-01-21, 1301, 533 +2007-01-22, 1301, 533 +2007-01-23, 1303, 534 +2007-01-24, 1308, 535 +2007-01-25, 1309, 535 +2007-01-26, 1311, 535 +2007-01-27, 1315, 538 +2007-01-28, 1316, 538 +2007-01-29, 1316, 538 +2007-01-30, 1318, 539 +2007-01-31, 1318, 540 +2007-02-01, 1319, 541 +2007-02-02, 1315, 538 +2007-02-03, 1315, 538 +2007-02-04, 1318, 538 +2007-02-05, 1318, 538 +2007-02-06, 1320, 539 +2007-02-07, 1320, 539 +2007-02-08, 1320, 539 +2007-02-09, 1320, 539 +2007-02-10, 1321, 540 +2007-02-11, 1321, 540 +2007-02-12, 1329, 540 +2007-02-13, 1333, 542 +2007-02-14, 1336, 544 +2007-02-15, 1341, 544 +2007-02-16, 1332, 546 +2007-02-17, 1350, 546 +2007-02-18, 1350, 546 From pedronis at codespeak.net Thu Feb 22 14:36:31 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Thu, 22 Feb 2007 14:36:31 +0100 (CET) Subject: [pypy-svn] r39312 - pypy/dist/pypy/objspace Message-ID: <20070222133631.E75EC10150@code0.codespeak.net> Author: pedronis Date: Thu Feb 22 14:36:30 2007 New Revision: 39312 Modified: pypy/dist/pypy/objspace/taint.py Log: double wrap Modified: pypy/dist/pypy/objspace/taint.py ============================================================================== --- pypy/dist/pypy/objspace/taint.py (original) +++ pypy/dist/pypy/objspace/taint.py Thu Feb 22 14:36:30 2007 @@ -129,7 +129,7 @@ unwrap_spec=[gateway.ObjSpace, gateway.W_Root, 'args_w']) def taint_atomic(space, w_callable): - meth = Method(space, space.wrap(space.w_fn_taint_atomic_function), + meth = Method(space, space.w_fn_taint_atomic_function, w_callable, space.type(w_callable)) return space.wrap(meth) app_taint_atomic = gateway.interp2app(taint_atomic) From ac at codespeak.net Thu Feb 22 17:58:51 2007 From: ac at codespeak.net (ac at codespeak.net) Date: Thu, 22 Feb 2007 17:58:51 +0100 (CET) Subject: [pypy-svn] r39314 - pypy/dist/pypy/module/_stackless Message-ID: <20070222165851.43778100C3@code0.codespeak.net> Author: ac Date: Thu Feb 22 17:58:49 2007 New Revision: 39314 Modified: pypy/dist/pypy/module/_stackless/interp_greenlet.py Log: Remove some debug prints. Modified: pypy/dist/pypy/module/_stackless/interp_greenlet.py ============================================================================== --- pypy/dist/pypy/module/_stackless/interp_greenlet.py (original) +++ pypy/dist/pypy/module/_stackless/interp_greenlet.py Thu Feb 22 17:58:49 2007 @@ -73,16 +73,12 @@ _get_state = staticmethod(_get_state) def hello(self): - print "hello ", id(self), self.subctx.framestack.items - print syncstate.things_to_do, syncstate.temp_exc ec = self.space.getexecutioncontext() self.subctx.enter(ec) def goodbye(self): ec = self.space.getexecutioncontext() self.subctx.leave(ec) - print "goodbye", id(self), self.subctx.framestack.items - print syncstate.things_to_do, syncstate.temp_exc def w_getcurrent(space): return space.wrap(AppGreenlet._get_state(space).current) From ac at codespeak.net Thu Feb 22 18:08:13 2007 From: ac at codespeak.net (ac at codespeak.net) Date: Thu, 22 Feb 2007 18:08:13 +0100 (CET) Subject: [pypy-svn] r39315 - pypy/dist/pypy/translator/c/src Message-ID: <20070222170813.E2C601013D@code0.codespeak.net> Author: ac Date: Thu Feb 22 18:08:12 2007 New Revision: 39315 Modified: pypy/dist/pypy/translator/c/src/signals.h Log: Use sigaction (if available) instead of signal so that interuptable sys-calls won't be restarted, thus making Ctrl-c work more often. Modified: pypy/dist/pypy/translator/c/src/signals.h ============================================================================== --- pypy/dist/pypy/translator/c/src/signals.h (original) +++ pypy/dist/pypy/translator/c/src/signals.h Thu Feb 22 18:08:12 2007 @@ -54,12 +54,30 @@ void pypysig_ignore(int signum) { +#ifdef SA_RESTART + /* assume sigaction exists */ + struct sigaction context; + context.sa_handler = SIG_IGN; + sigemptyset(&context.sa_mask); + context.sa_flags = 0; + sigaction(signum, &context, NULL); +#else signal(signum, SIG_IGN); +#endif } void pypysig_default(int signum) { +#ifdef SA_RESTART + /* assume sigaction exists */ + struct sigaction context; + context.sa_handler = SIG_DFL; + sigemptyset(&context.sa_mask); + context.sa_flags = 0; + sigaction(signum, &context, NULL); +#else signal(signum, SIG_DFL); +#endif } static void signal_setflag_handler(int signum) @@ -71,7 +89,16 @@ void pypysig_setflag(int signum) { +#ifdef SA_RESTART + /* assume sigaction exists */ + struct sigaction context; + context.sa_handler = signal_setflag_handler; + sigemptyset(&context.sa_mask); + context.sa_flags = 0; + sigaction(signum, &context, NULL); +#else signal(signum, signal_setflag_handler); +#endif } int pypysig_poll(void) From fijal at codespeak.net Thu Feb 22 21:42:08 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 22 Feb 2007 21:42:08 +0100 (CET) Subject: [pypy-svn] r39320 - pypy/dist/pypy/translator/js/examples Message-ID: <20070222204208.509D810135@code0.codespeak.net> Author: fijal Date: Thu Feb 22 21:42:06 2007 New Revision: 39320 Modified: pypy/dist/pypy/translator/js/examples/console.py Log: typo Modified: pypy/dist/pypy/translator/js/examples/console.py ============================================================================== --- pypy/dist/pypy/translator/js/examples/console.py (original) +++ pypy/dist/pypy/translator/js/examples/console.py Thu Feb 22 21:42:06 2007 @@ -23,7 +23,7 @@ pipe = subprocess.Popen([python, "-u", "-i"], stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.STDOUT, close_fds=True, bufsize=0) - # a bit of POSIX voodoo + # a bit of a POSIX voodoo fcntl.fcntl(pipe.stdout.fileno(), fcntl.F_SETFL, os.O_NONBLOCK) return pipe From fijal at codespeak.net Thu Feb 22 21:45:13 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 22 Feb 2007 21:45:13 +0100 (CET) Subject: [pypy-svn] r39321 - in pypy/dist/pypy/translator/js/examples: . console console/data console/test test Message-ID: <20070222204513.4103810147@code0.codespeak.net> Author: fijal Date: Thu Feb 22 21:45:11 2007 New Revision: 39321 Added: pypy/dist/pypy/translator/js/examples/console/ (props changed) pypy/dist/pypy/translator/js/examples/console/__init__.py (contents, props changed) pypy/dist/pypy/translator/js/examples/console/client.py (contents, props changed) - copied, changed from r39309, pypy/dist/pypy/translator/js/examples/console_client.py pypy/dist/pypy/translator/js/examples/console/console.py (props changed) - copied unchanged from r39320, pypy/dist/pypy/translator/js/examples/console.py pypy/dist/pypy/translator/js/examples/console/data/ pypy/dist/pypy/translator/js/examples/console/test/ (props changed) pypy/dist/pypy/translator/js/examples/console/test/test_console.py (contents, props changed) - copied, changed from r39277, pypy/dist/pypy/translator/js/examples/test/test_console.py Removed: pypy/dist/pypy/translator/js/examples/console.py pypy/dist/pypy/translator/js/examples/console_client.py pypy/dist/pypy/translator/js/examples/test/test_console.py Modified: pypy/dist/pypy/translator/js/examples/test/test_examples.py Log: Move console to it's own directory Added: pypy/dist/pypy/translator/js/examples/console/__init__.py ============================================================================== Modified: pypy/dist/pypy/translator/js/examples/test/test_examples.py ============================================================================== --- pypy/dist/pypy/translator/js/examples/test/test_examples.py (original) +++ pypy/dist/pypy/translator/js/examples/test/test_examples.py Thu Feb 22 21:45:11 2007 @@ -27,6 +27,6 @@ def test_console_2_build(): - from pypy.translator.js.examples import console, console_client - assert rpython2javascript(console_client, console.FUNCTION_LIST, + from pypy.translator.js.examples.console import console, client + assert rpython2javascript(client, console.FUNCTION_LIST, use_pdb=False) From fijal at codespeak.net Thu Feb 22 21:45:53 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 22 Feb 2007 21:45:53 +0100 (CET) Subject: [pypy-svn] r39322 - in pypy/dist/pypy/translator/js/examples: console/data data Message-ID: <20070222204553.A8ED510149@code0.codespeak.net> Author: fijal Date: Thu Feb 22 21:45:52 2007 New Revision: 39322 Added: pypy/dist/pypy/translator/js/examples/console/data/console.html - copied unchanged from r39278, pypy/dist/pypy/translator/js/examples/data/console.html Removed: pypy/dist/pypy/translator/js/examples/data/console.html Log: move that file as well From fijal at codespeak.net Thu Feb 22 21:47:21 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 22 Feb 2007 21:47:21 +0100 (CET) Subject: [pypy-svn] r39323 - pypy/dist/pypy/translator/js/examples/console Message-ID: <20070222204721.AA00E1014B@code0.codespeak.net> Author: fijal Date: Thu Feb 22 21:47:17 2007 New Revision: 39323 Modified: pypy/dist/pypy/translator/js/examples/console/console.py Log: Adapt to file move Modified: pypy/dist/pypy/translator/js/examples/console/console.py ============================================================================== --- pypy/dist/pypy/translator/js/examples/console/console.py (original) +++ pypy/dist/pypy/translator/js/examples/console/console.py Thu Feb 22 21:47:17 2007 @@ -16,8 +16,8 @@ def js_source(): - import console_client - return rpython2javascript(console_client, FUNCTION_LIST) + import client + return rpython2javascript(client, FUNCTION_LIST) def run_console(python): pipe = subprocess.Popen([python, "-u", "-i"], stdout=subprocess.PIPE, From santagada at codespeak.net Thu Feb 22 23:04:49 2007 From: santagada at codespeak.net (santagada at codespeak.net) Date: Thu, 22 Feb 2007 23:04:49 +0100 (CET) Subject: [pypy-svn] r39324 - in pypy/dist/pypy/lang/js: . test test/ecma Message-ID: <20070222220449.ECB3010158@code0.codespeak.net> Author: santagada Date: Thu Feb 22 23:04:46 2007 New Revision: 39324 Modified: pypy/dist/pypy/lang/js/interpreter.py pypy/dist/pypy/lang/js/jsobj.py pypy/dist/pypy/lang/js/test/ecma/conftest.py pypy/dist/pypy/lang/js/test/test_interp.py Log: new operations and the for-in statement Modified: pypy/dist/pypy/lang/js/interpreter.py ============================================================================== --- pypy/dist/pypy/lang/js/interpreter.py (original) +++ pypy/dist/pypy/lang/js/interpreter.py Thu Feb 22 23:04:46 2007 @@ -62,6 +62,7 @@ class UnaryOp(Expression): def from_tree(self, t): self.expr = get_obj(t, '0') + self.postfix = bool(get_string(t, 'postfix')) class BinaryOp(Expression): def from_tree(self, t): @@ -247,15 +248,27 @@ v3 = self.right.eval(ctx).GetValue() op = self.value if op == "=": - v1.PutValue(v3, ctx) + val = v3 elif op == "*": - v1.PutValue(Mult().mathop(ctx, v1.GetValue(), v3), ctx) + val = Mult().mathop(ctx, v1.GetValue(), v3) elif op == "+": - v1.PutValue(Plus().mathop(ctx, v1.GetValue(), v3), ctx) + val = Plus().mathop(ctx, v1.GetValue(), v3) + elif op == "/": + val = Div().mathop(ctx, v1.GetValue(), v3) + elif op == "%": + val = Mod().mathop(ctx, v1.GetValue(), v3) + elif op == "&": + val = BitwiseAnd().mathop(ctx, v1.GetValue(), v3) + elif op == "|": + val = BitwiseOR().mathop(ctx, v1.GetValue(), v3) + elif op == "^": + val = BitwiseXOR().mathop(ctx, v1.GetValue(), v3) else: print op raise NotImplementedError() - return v3 + + v1.PutValue(val, ctx) + return val class Block(Statement): opcode = 'BLOCK' @@ -281,6 +294,14 @@ def decision(self, ctx, op1, op2): return W_Number(op1&op2) +class BitwiseNot(UnaryOp): + opcode = 'BITWISE_NOT' + + def eval(self, ctx): + op1 = self.expr.eval(ctx).GetValue().ToInt32() + return W_Number(~op1) + + class BitwiseOR(BinaryBitwiseOp): opcode = 'BITWISE_OR' @@ -562,7 +583,11 @@ x = val.ToNumber() resl = Plus().mathop(ctx, W_Number(x), W_Number(1)) thing.PutValue(resl, ctx) - return val + if self.postfix: + return val + else: + return resl + class Decrement(UnaryOp): opcode = 'DECREMENT' @@ -573,7 +598,10 @@ x = val.ToNumber() resl = Plus().mathop(ctx, W_Number(x), W_Number(-1)) thing.PutValue(resl, ctx) - return val + if self.postfix: + return val + else: + return resl class Index(BinaryOp): @@ -861,13 +889,34 @@ self.expr.eval(ctx) return w_Undefined -class While(Statement): - opcode = 'WHILE' - +class WhileBase(Statement): def from_tree(self, t): self.condition = get_obj(t, 'condition') self.body = get_obj(t, 'body') +class Do(WhileBase): + opcode = 'DO' + + def execute(self, ctx): + try: + self.body.execute(ctx) + except ExecutionReturned, e: + if e.type == 'break': + return + elif e.type == 'continue': + pass + while self.condition.eval(ctx).ToBoolean(): + try: + self.body.execute(ctx) + except ExecutionReturned, e: + if e.type == 'break': + break + elif e.type == 'continue': + continue + +class While(WhileBase): + opcode = 'WHILE' + def execute(self, ctx): while self.condition.eval(ctx).ToBoolean(): try: @@ -878,6 +927,30 @@ elif e.type == 'continue': continue +class ForIn(Statement): + opcode = 'FOR_IN' + + def from_tree(self, t): + self.object = get_obj(t, 'object') + self.body = get_obj(t, 'body') + self.iterator = get_obj(t, 'iterator') + + def execute(self, ctx): + obj = self.object.eval(ctx).GetValue().ToObject() + for prop in obj.propdict.values(): + if prop.de: + continue + iterator = self.iterator.eval(ctx) + print prop.name + iterator.PutValue(prop.value, ctx) + try: + result = self.body.execute(ctx) + except ExecutionReturned, e: + if e.type == 'break': + break + elif e.type == 'continue': + continue + class For(Statement): opcode = 'FOR' @@ -980,3 +1053,16 @@ else: raise NotImplementedError("Dont know how to handle %s" % opcode) +def wrap_arguments(pyargs): + "receives a list of arguments and wrap then in their js equivalents" + res = [] + for arg in pyargs: + if isinstance(arg, W_Root) + res.append(arg) + elif isinstance(arg, str): + res.append(W_String(arg)) + elif isinstance(arg, int) or isinstance(arg, float) or isinstance(arg, long): + res.append(W_Number(arg)) + elif isinstance(arg, bool): + res.append(W_Boolean(arg)) + elif isinstance(arg, ) Modified: pypy/dist/pypy/lang/js/jsobj.py ============================================================================== --- pypy/dist/pypy/lang/js/jsobj.py (original) +++ pypy/dist/pypy/lang/js/jsobj.py Thu Feb 22 23:04:46 2007 @@ -127,7 +127,7 @@ Value=w_Undefined, callfunc=None): self.propdict = {} self.propdict['prototype'] = Property('prototype', w_Undefined, - dd=True) + dd=True, de=True) self.Prototype = Prototype self.Class = Class self.callfunc = callfunc @@ -242,7 +242,7 @@ Value=w_Undefined, callfunc=None): W_PrimitiveObject.__init__(self, ctx, Prototype, Class, Value, callfunc) - self.propdict['toString'] = Property('toString', W_Builtin(str_builtin)) + self.propdict['toString'] = Property('toString', W_Builtin(str_builtin), de=True) class W_Builtin(W_PrimitiveObject): @@ -286,12 +286,13 @@ Value=w_Undefined, callfunc=None): W_PrimitiveObject.__init__(self, ctx, Prototype, Class, Value, callfunc) toString = W_Builtin(array_str_builtin) - self.Put('toString', toString) + self.Put('toString', toString, de=True) self.Put('length', W_Number(0)) self.array = [] self.set_builtin_call(arraycallbi) - - def Put(self, P, V): + + def Put(self, P, V, dd=False, + ro=False, de=False, it=False): try: x = int(P) # print "puting", V, 'in', x @@ -303,11 +304,7 @@ self.array[x]= V except ValueError: - if not self.CanPut(P): return - if P in self.propdict: - self.propdict[P].value = V - else: - self.propdict[P] = Property(P, V) + super(W_Array, self).Put(P, V, dd, ro, de, it) def Get(self, P): try: @@ -500,6 +497,7 @@ if self.base is None: base = ctx.scope[-1] base.Put(self.property_name, w) + return w def GetBase(self): return self.base Modified: pypy/dist/pypy/lang/js/test/ecma/conftest.py ============================================================================== --- pypy/dist/pypy/lang/js/test/ecma/conftest.py (original) +++ pypy/dist/pypy/lang/js/test/ecma/conftest.py Thu Feb 22 23:04:46 2007 @@ -2,7 +2,7 @@ from pypy.lang.js.interpreter import * from pypy.lang.js.jsobj import W_Array, JsBaseExcept from pypy.lang.js.jsparser import JsSyntaxError -from py.__.test.outcome import Failed +from py.__.test.outcome import Failed, ExceptionFailure import pypy.lang.js as js js.jsobj.DEBUG = True @@ -77,7 +77,7 @@ r3 = ctx.resolve_identifier('run_test').GetValue() result = r3.Call(ctx=ctx, args=[W_Number(self.number),]).ToNumber() if result == 0: - py.test.fail() + raise Failed(msg="Results don't match") elif result == -1: py.test.skip() @@ -85,5 +85,5 @@ def _getpathlineno(self): return self.parent.parent.fspath, 0 - -Directory = JSDirectory +if py.test.config.option.ecma: + Directory = JSDirectory Modified: pypy/dist/pypy/lang/js/test/test_interp.py ============================================================================== --- pypy/dist/pypy/lang/js/test/test_interp.py (original) +++ pypy/dist/pypy/lang/js/test/test_interp.py Thu Feb 22 23:04:46 2007 @@ -462,3 +462,11 @@ delete x.y print(x.y) """, ['undefined']) + + def test_forin(self): + self.assert_prints(""" + var x = {a:5} + for(y in x){ + print(y) + } + """, ['5',]) From santagada at codespeak.net Fri Feb 23 01:39:13 2007 From: santagada at codespeak.net (santagada at codespeak.net) Date: Fri, 23 Feb 2007 01:39:13 +0100 (CET) Subject: [pypy-svn] r39325 - pypy/dist/pypy/lang/js Message-ID: <20070223003913.3FEDC1015A@code0.codespeak.net> Author: santagada Date: Fri Feb 23 01:39:11 2007 New Revision: 39325 Modified: pypy/dist/pypy/lang/js/interpreter.py Log: fix the new function Modified: pypy/dist/pypy/lang/js/interpreter.py ============================================================================== --- pypy/dist/pypy/lang/js/interpreter.py (original) +++ pypy/dist/pypy/lang/js/interpreter.py Fri Feb 23 01:39:11 2007 @@ -1057,7 +1057,7 @@ "receives a list of arguments and wrap then in their js equivalents" res = [] for arg in pyargs: - if isinstance(arg, W_Root) + if isinstance(arg, W_Root): res.append(arg) elif isinstance(arg, str): res.append(W_String(arg)) @@ -1065,4 +1065,4 @@ res.append(W_Number(arg)) elif isinstance(arg, bool): res.append(W_Boolean(arg)) - elif isinstance(arg, ) + return res \ No newline at end of file From ludal at codespeak.net Fri Feb 23 15:32:26 2007 From: ludal at codespeak.net (ludal at codespeak.net) Date: Fri, 23 Feb 2007 15:32:26 +0100 (CET) Subject: [pypy-svn] r39341 - in pypy/dist/pypy/rpython: . test Message-ID: <20070223143226.90124101CC@code0.codespeak.net> Author: ludal Date: Fri Feb 23 15:32:25 2007 New Revision: 39341 Modified: pypy/dist/pypy/rpython/rfloat.py pypy/dist/pypy/rpython/rint.py pypy/dist/pypy/rpython/rtuple.py pypy/dist/pypy/rpython/test/test_rtuple.py Log: provides rtuple comparison. works for mixes of ints and floats, and probably every type that provides the necessary comparison operators Modified: pypy/dist/pypy/rpython/rfloat.py ============================================================================== --- pypy/dist/pypy/rpython/rfloat.py (original) +++ pypy/dist/pypy/rpython/rfloat.py Fri Feb 23 15:32:25 2007 @@ -110,6 +110,10 @@ def get_ll_eq_function(self): return None + get_ll_gt_function = get_ll_eq_function + get_ll_lt_function = get_ll_eq_function + get_ll_ge_function = get_ll_eq_function + get_ll_le_function = get_ll_eq_function def get_ll_hash_function(self): return ll_hash_float Modified: pypy/dist/pypy/rpython/rint.py ============================================================================== --- pypy/dist/pypy/rpython/rint.py (original) +++ pypy/dist/pypy/rpython/rint.py Fri Feb 23 15:32:25 2007 @@ -222,6 +222,13 @@ raise TyperError("not an integer: %r" % (value,)) def get_ll_eq_function(self): + return None + get_ll_gt_function = get_ll_eq_function + get_ll_lt_function = get_ll_eq_function + get_ll_ge_function = get_ll_eq_function + get_ll_le_function = get_ll_eq_function + + def get_ll_ge_function(self): return None def get_ll_hash_function(self): Modified: pypy/dist/pypy/rpython/rtuple.py ============================================================================== --- pypy/dist/pypy/rpython/rtuple.py (original) +++ pypy/dist/pypy/rpython/rtuple.py Fri Feb 23 15:32:25 2007 @@ -22,6 +22,7 @@ _gen_eq_function_cache = {} +_gen_cmp_function_cache = {} _gen_hash_function_cache = {} _gen_str_function_cache = {} @@ -46,6 +47,49 @@ _gen_eq_function_cache[key] = ll_eq return ll_eq +import os +def gen_cmp_function(items_r, op_funcs, eq_funcs, strict): + """generates <= and >= comparison ll_op for tuples + cmp_funcs is a tuple of (strict_comp, equality) functions + works for != with strict==True + """ + cmp_funcs = zip(op_funcs,eq_funcs) + autounrolling_funclist = unrolling_iterable(enumerate(cmp_funcs)) + key = tuple(cmp_funcs), strict + try: + return _gen_cmp_function_cache[key] + except KeyError: + def ll_cmp(t1, t2): + cmp_res = True + for i, (cmpfn, eqfn) in autounrolling_funclist: + attrname = 'item%d' % i + item1 = getattr(t1, attrname) + item2 = getattr(t2, attrname) + cmp_res = cmpfn(item1, item2) + if cmp_res: + # a strict compare is true we shortcut + return True + eq_res = eqfn(item1, item2) + if not eq_res: + # not strict and not equal we fail + return False + # Everything's equal here + if strict: + return False + else: + return True + _gen_cmp_function_cache[key] = ll_cmp + return ll_cmp + +def gen_gt_function(items_r, strict): + gt_funcs = [r_item.get_ll_gt_function() or operator.gt for r_item in items_r] + eq_funcs = [r_item.get_ll_eq_function() or operator.eq for r_item in items_r] + return gen_cmp_function( items_r, gt_funcs, eq_funcs, strict ) + +def gen_lt_function(items_r, strict): + lt_funcs = [r_item.get_ll_lt_function() or operator.lt for r_item in items_r] + eq_funcs = [r_item.get_ll_eq_function() or operator.eq for r_item in items_r] + return gen_cmp_function( items_r, lt_funcs, eq_funcs, strict ) def gen_hash_function(items_r): # based on CPython @@ -166,8 +210,20 @@ def get_ll_eq_function(self): return gen_eq_function(self.items_r) + def get_ll_ge_function(self): + return gen_gt_function(self.items_r, False) + + def get_ll_gt_function(self): + return gen_gt_function(self.items_r, True) + + def get_ll_le_function(self): + return gen_lt_function(self.items_r, False) + + def get_ll_lt_function(self): + return gen_lt_function(self.items_r, True) + def get_ll_hash_function(self): - return gen_hash_function(self.items_r) + return gen_hash_function(self.items_r) ll_str = property(gen_str_function) @@ -241,6 +297,30 @@ ll_eq = r_tup1.get_ll_eq_function() return hop.gendirectcall(ll_eq, v_tuple1, v_tuple2) + def rtype_ge((r_tup1, r_tup2), hop): + # XXX assumes that r_tup2 is convertible to r_tup1 + v_tuple1, v_tuple2 = hop.inputargs(r_tup1, r_tup1) + ll_ge = r_tup1.get_ll_ge_function() + return hop.gendirectcall(ll_ge, v_tuple1, v_tuple2) + + def rtype_gt((r_tup1, r_tup2), hop): + # XXX assumes that r_tup2 is convertible to r_tup1 + v_tuple1, v_tuple2 = hop.inputargs(r_tup1, r_tup1) + ll_gt = r_tup1.get_ll_gt_function() + return hop.gendirectcall(ll_gt, v_tuple1, v_tuple2) + + def rtype_le((r_tup1, r_tup2), hop): + # XXX assumes that r_tup2 is convertible to r_tup1 + v_tuple1, v_tuple2 = hop.inputargs(r_tup1, r_tup1) + ll_le = r_tup1.get_ll_le_function() + return hop.gendirectcall(ll_le, v_tuple1, v_tuple2) + + def rtype_lt((r_tup1, r_tup2), hop): + # XXX assumes that r_tup2 is convertible to r_tup1 + v_tuple1, v_tuple2 = hop.inputargs(r_tup1, r_tup1) + ll_lt = r_tup1.get_ll_lt_function() + return hop.gendirectcall(ll_lt, v_tuple1, v_tuple2) + def rtype_ne(tup1tup2, hop): v_res = tup1tup2.rtype_eq(hop) return hop.genop('bool_not', [v_res], resulttype=Bool) 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 Fri Feb 23 15:32:25 2007 @@ -280,6 +280,51 @@ res = self.interpret(f, [2]) assert res is True + TUPLES = [ + ((1,2), (2,3), -1), + ((1,2), (1,3), -1), + ((1,2), (1,1), 1), + ((1,2), (1,2), 0), + ((1.,2.),(2.,3.), -1), + ((1.,2.),(1.,3.), -1), + ((1.,2.),(1.,1.), 1), + ((1.,2.),(1.,2.), 0), + ((1,2.),(2,3.), -1), + ((1,2.),(1,3.), -1), + ((1,2.),(1,1.), 1), + ((1,2.),(1,2.), 0), +## ((1,"def"),(1,"abc"), -1), +## ((1.,"abc"),(1.,"abc"), 0), + ] + + def test_tuple_comparison(self): + def f_lt( a, b, c, d ): + return (a,b) < (c,d) + def f_le( a, b, c, d ): + return (a,b) <= (c,d) + def f_gt( a, b, c, d ): + return (a,b) > (c,d) + def f_ge( a, b, c, d ): + return (a,b) >= (c,d) + def test_lt( a,b,c,d,resu ): + res = self.interpret(f_lt,[a,b,c,d]) + assert res == (resu == -1), "Error (%s,%s)<(%s,%s) is %s(%s)" % (a,b,c,d,res,resu) + def test_le( a,b,c,d,resu ): + res = self.interpret(f_le,[a,b,c,d]) + assert res == (resu <= 0), "Error (%s,%s)<=(%s,%s) is %s(%s)" % (a,b,c,d,res,resu) + def test_gt( a,b,c,d,resu ): + res = self.interpret(f_gt,[a,b,c,d]) + assert res == ( resu == 1 ), "Error (%s,%s)>(%s,%s) is %s(%s)" % (a,b,c,d,res,resu) + def test_ge( a,b,c,d,resu ): + res = self.interpret(f_ge,[a,b,c,d]) + assert res == ( resu >= 0 ), "Error (%s,%s)>=(%s,%s) is %s(%s)" % (a,b,c,d,res,resu) + + for (a,b),(c,d),resu in self.TUPLES: + yield test_lt, a,b,c,d, resu + yield test_gt, a,b,c,d, resu + yield test_le, a,b,c,d, resu + yield test_ge, a,b,c,d, resu + def test_tuple_hash(self): def f(n): return hash((n, 6)) == hash((3, n*2)) From fijal at codespeak.net Fri Feb 23 16:37:27 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 23 Feb 2007 16:37:27 +0100 (CET) Subject: [pypy-svn] r39343 - pypy/dist/pypy/translator/js/examples/console Message-ID: <20070223153727.E0383100EB@code0.codespeak.net> Author: fijal Date: Fri Feb 23 16:37:25 2007 New Revision: 39343 Modified: pypy/dist/pypy/translator/js/examples/console/client.py Log: Use less innerHTML, saves some escaping troubles Modified: pypy/dist/pypy/translator/js/examples/console/client.py ============================================================================== --- pypy/dist/pypy/translator/js/examples/console/client.py (original) +++ pypy/dist/pypy/translator/js/examples/console/client.py Fri Feb 23 16:37:25 2007 @@ -9,7 +9,14 @@ glob = Glob() def add_text(txt): - dom.document.getElementById("data").innerHTML += txt + data_elem = dom.document.getElementById("data") + if data_elem.childNodes: + data = data_elem.childNodes[0].nodeValue + txt + else: + data = txt + while data_elem.childNodes: + data_elem.removeChild(data_elem.childNodes[0]) + data_elem.appendChild(dom.document.createTextNode(data)) def refresh_console(msg): inp_elem = dom.document.getElementById("inp") From mwh at codespeak.net Fri Feb 23 18:27:37 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 23 Feb 2007 18:27:37 +0100 (CET) Subject: [pypy-svn] r39344 - in pypy/extradoc/talk/pycon2007: . demos pycon07.key pycon07.key/thumbs Message-ID: <20070223172737.9497E101D4@code0.codespeak.net> Author: mwh Date: Fri Feb 23 18:27:34 2007 New Revision: 39344 Added: pypy/extradoc/talk/pycon2007/demos/bnb.sh pypy/extradoc/talk/pycon2007/demos/console.sh pypy/extradoc/talk/pycon2007/demos/jit.sh pypy/extradoc/talk/pycon2007/pycon07.key/thumbs/st22-1.tiff (contents, props changed) pypy/extradoc/talk/pycon2007/pycon07.key/thumbs/st23.tiff (contents, props changed) pypy/extradoc/talk/pycon2007/pycon07.key/thumbs/st24-1.tiff (contents, props changed) pypy/extradoc/talk/pycon2007/pycon07.key/thumbs/st26.tiff (contents, props changed) Modified: pypy/extradoc/talk/pycon2007/demos/listserver.py pypy/extradoc/talk/pycon2007/pycon07.key/index.apxl.gz pypy/extradoc/talk/pycon2007/pycon07.key/thumbs/mt0-10.tiff pypy/extradoc/talk/pycon2007/pycon07.key/thumbs/mt0-16.tiff pypy/extradoc/talk/pycon2007/pycon07.key/thumbs/mt0-33.tiff pypy/extradoc/talk/pycon2007/pycon07.key/thumbs/st0-1.tiff pypy/extradoc/talk/pycon2007/pycon07.key/thumbs/st1.tiff pypy/extradoc/talk/pycon2007/pycon07.key/thumbs/st2.tiff pypy/extradoc/talk/pycon2007/pycon07.key/thumbs/st22.tiff pypy/extradoc/talk/pycon2007/pycon07.key/thumbs/st23-1.tiff pypy/extradoc/talk/pycon2007/pycon07.key/thumbs/st25-1.tiff pypy/extradoc/talk/pycon2007/pycon07.key/thumbs/st28.tiff pypy/extradoc/talk/pycon2007/pycon07.key/thumbs/st31.tiff pypy/extradoc/talk/pycon2007/pycon07.key/thumbs/st32-2.tiff pypy/extradoc/talk/pycon2007/pycon07.key/thumbs/st32-4.tiff pypy/extradoc/talk/pycon2007/pycon07.key/thumbs/st32-5.tiff pypy/extradoc/talk/pycon2007/pycon07.key/thumbs/st32.tiff pypy/extradoc/talk/pycon2007/pycon07.key/thumbs/st6.tiff pypy/extradoc/talk/pycon2007/pycon07.pdf Log: updates to pycon talk, some files for demos Added: pypy/extradoc/talk/pycon2007/demos/bnb.sh ============================================================================== --- (empty file) +++ pypy/extradoc/talk/pycon2007/demos/bnb.sh Fri Feb 23 18:27:34 2007 @@ -0,0 +1,3 @@ +cd ~/Source/pypy/dist/pypy/translator/js/examples/bnb +/opt/local/bin/python2.4 start_bnb.py + Added: pypy/extradoc/talk/pycon2007/demos/console.sh ============================================================================== --- (empty file) +++ pypy/extradoc/talk/pycon2007/demos/console.sh Fri Feb 23 18:27:34 2007 @@ -0,0 +1,3 @@ +cd ~/Source/cs-user/arigo/hack/pypy-hack/js +python2.4 rxconsole.py + Added: pypy/extradoc/talk/pycon2007/demos/jit.sh ============================================================================== --- (empty file) +++ pypy/extradoc/talk/pycon2007/demos/jit.sh Fri Feb 23 18:27:34 2007 @@ -0,0 +1 @@ +gdb --args python2.4 `which py.test` ~/Source/pypy/dist/pypy/jit/codegen/ppc/test/test_genc_ts.py --trap -k test_very_simple -s Modified: pypy/extradoc/talk/pycon2007/demos/listserver.py ============================================================================== --- pypy/extradoc/talk/pycon2007/demos/listserver.py (original) +++ pypy/extradoc/talk/pycon2007/demos/listserver.py Fri Feb 23 18:27:34 2007 @@ -1,8 +1,22 @@ +import os +if not hasattr(os, 'utime'): + os.utime = lambda f:0 +try: + import stackless, types + stackless.function = types.FunctionType + stackless.instancemethod = types.MethodType +except ImportError: + pass + from nevow import inevow, tags, loaders, rend, appserver from twisted.application import internet, service +from twisted.internet import reactor from zope.interface import implements import random +import sys +sys.modules['syslog'] = internet + class GetItem(object): implements(inevow.IResource) def __init__(self, sharedlist): @@ -41,7 +55,7 @@ Get Item:
- Set Item: + Set Item:
@@ -52,7 +66,7 @@ theList = range(10) random.shuffle(theList) -application = service.Application("pydoctor demo") +application = service.Application("silly list server") root = Root(theList) root.putChild('getitem', GetItem(theList)) @@ -64,3 +78,5 @@ root ) ).setServiceParent(application) + + Modified: pypy/extradoc/talk/pycon2007/pycon07.key/index.apxl.gz ============================================================================== Binary files. No diff available. Modified: pypy/extradoc/talk/pycon2007/pycon07.key/thumbs/mt0-10.tiff ============================================================================== Binary files. No diff available. Modified: pypy/extradoc/talk/pycon2007/pycon07.key/thumbs/mt0-16.tiff ============================================================================== Binary files. No diff available. Modified: pypy/extradoc/talk/pycon2007/pycon07.key/thumbs/mt0-33.tiff ============================================================================== Binary files. No diff available. Modified: pypy/extradoc/talk/pycon2007/pycon07.key/thumbs/st0-1.tiff ============================================================================== Binary files. No diff available. Modified: pypy/extradoc/talk/pycon2007/pycon07.key/thumbs/st1.tiff ============================================================================== Binary files. No diff available. Modified: pypy/extradoc/talk/pycon2007/pycon07.key/thumbs/st2.tiff ============================================================================== Binary files. No diff available. Added: pypy/extradoc/talk/pycon2007/pycon07.key/thumbs/st22-1.tiff ============================================================================== Binary file. No diff available. Modified: pypy/extradoc/talk/pycon2007/pycon07.key/thumbs/st22.tiff ============================================================================== Binary files. No diff available. Modified: pypy/extradoc/talk/pycon2007/pycon07.key/thumbs/st23-1.tiff ============================================================================== Binary files. No diff available. Added: pypy/extradoc/talk/pycon2007/pycon07.key/thumbs/st23.tiff ============================================================================== Binary file. No diff available. Added: pypy/extradoc/talk/pycon2007/pycon07.key/thumbs/st24-1.tiff ============================================================================== Binary file. No diff available. Modified: pypy/extradoc/talk/pycon2007/pycon07.key/thumbs/st25-1.tiff ============================================================================== Binary files. No diff available. Added: pypy/extradoc/talk/pycon2007/pycon07.key/thumbs/st26.tiff ============================================================================== Binary file. No diff available. Modified: pypy/extradoc/talk/pycon2007/pycon07.key/thumbs/st28.tiff ============================================================================== Binary files. No diff available. Modified: pypy/extradoc/talk/pycon2007/pycon07.key/thumbs/st31.tiff ============================================================================== Binary files. No diff available. Modified: pypy/extradoc/talk/pycon2007/pycon07.key/thumbs/st32-2.tiff ============================================================================== Binary files. No diff available. Modified: pypy/extradoc/talk/pycon2007/pycon07.key/thumbs/st32-4.tiff ============================================================================== Binary files. No diff available. Modified: pypy/extradoc/talk/pycon2007/pycon07.key/thumbs/st32-5.tiff ============================================================================== Binary files. No diff available. Modified: pypy/extradoc/talk/pycon2007/pycon07.key/thumbs/st32.tiff ============================================================================== Binary files. No diff available. Modified: pypy/extradoc/talk/pycon2007/pycon07.key/thumbs/st6.tiff ============================================================================== Binary files. No diff available. Modified: pypy/extradoc/talk/pycon2007/pycon07.pdf ============================================================================== Binary files. No diff available. From cfbolz at codespeak.net Sat Feb 24 00:27:42 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sat, 24 Feb 2007 00:27:42 +0100 (CET) Subject: [pypy-svn] r39347 - in pypy/dist/pypy: annotation annotation/test rpython rpython/test Message-ID: <20070223232742.6E6B11008F@code0.codespeak.net> Author: cfbolz Date: Sat Feb 24 00:27:38 2007 New Revision: 39347 Modified: pypy/dist/pypy/annotation/test/test_annrpython.py pypy/dist/pypy/annotation/unaryop.py pypy/dist/pypy/rpython/rmodel.py pypy/dist/pypy/rpython/test/test_rlist.py Log: support for iterator.next methods. Modified: pypy/dist/pypy/annotation/test/test_annrpython.py ============================================================================== --- pypy/dist/pypy/annotation/test/test_annrpython.py (original) +++ pypy/dist/pypy/annotation/test/test_annrpython.py Sat Feb 24 00:27:38 2007 @@ -443,6 +443,14 @@ s = a.build_types(snippet.simple_iter, [list]) assert isinstance(s, annmodel.SomeIterator) + def test_simple_iter_next(self): + def f(x): + i = iter(range(x)) + return i.next() + a = self.RPythonAnnotator() + s = a.build_types(f, [int]) + assert isinstance(s, annmodel.SomeInteger) + def test_simple_iter_dict(self): a = self.RPythonAnnotator() t = somedict(annmodel.SomeInteger(), annmodel.SomeInteger()) Modified: pypy/dist/pypy/annotation/unaryop.py ============================================================================== --- pypy/dist/pypy/annotation/unaryop.py (original) +++ pypy/dist/pypy/annotation/unaryop.py Sat Feb 24 00:27:38 2007 @@ -506,6 +506,7 @@ def next(itr): return itr.s_container.getanyitem(*itr.variant) next.can_only_throw = _can_only_throw + method_next = next class __extend__(SomeInstance): Modified: pypy/dist/pypy/rpython/rmodel.py ============================================================================== --- pypy/dist/pypy/rpython/rmodel.py (original) +++ pypy/dist/pypy/rpython/rmodel.py Sat Feb 24 00:27:38 2007 @@ -272,6 +272,9 @@ v_iter, = hop.inputargs(self) return v_iter + def rtype_method_next(self, hop): + return self.rtype_next(self, hop) + class __extend__(annmodel.SomeIterator): # NOTE: SomeIterator is for iterators over any container, not just list 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 Feb 24 00:27:38 2007 @@ -283,6 +283,35 @@ res = self.interpret(dummyfn, []) assert res == 25 + def test_iterate_next(self): + def dummyfn(): + total = 0 + it = iter([1, 3, 5, 7, 9]) + while 1: + try: + x = it.next() + except StopIteration: + break + total += x + return total + res = self.interpret(dummyfn, []) + assert res == 25 + def dummyfn(): + total = 0 + l = [1, 3, 5, 7] + l.append(9) + it = iter(l) + while 1: + try: + x = it.next() + except StopIteration: + break + total += x + return total + res = self.interpret(dummyfn, []) + assert res == 25 + + def test_recursive(self): def dummyfn(N): l = [] From cfbolz at codespeak.net Sat Feb 24 00:48:16 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sat, 24 Feb 2007 00:48:16 +0100 (CET) Subject: [pypy-svn] r39348 - pypy/dist/pypy/rpython Message-ID: <20070223234816.157D4101E5@code0.codespeak.net> Author: cfbolz Date: Sat Feb 24 00:48:14 2007 New Revision: 39348 Modified: pypy/dist/pypy/rpython/rmodel.py Log: ah, humpf. I could have sworn that my test actually passed. Modified: pypy/dist/pypy/rpython/rmodel.py ============================================================================== --- pypy/dist/pypy/rpython/rmodel.py (original) +++ pypy/dist/pypy/rpython/rmodel.py Sat Feb 24 00:48:14 2007 @@ -273,7 +273,7 @@ return v_iter def rtype_method_next(self, hop): - return self.rtype_next(self, hop) + return self.rtype_next(hop) class __extend__(annmodel.SomeIterator): From fijal at codespeak.net Sat Feb 24 17:49:06 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 24 Feb 2007 17:49:06 +0100 (CET) Subject: [pypy-svn] r39365 - pypy/dist/pypy/rpython Message-ID: <20070224164906.8F6481017A@code0.codespeak.net> Author: fijal Date: Sat Feb 24 17:49:04 2007 New Revision: 39365 Modified: pypy/dist/pypy/rpython/extfunc.py Log: Small helper Modified: pypy/dist/pypy/rpython/extfunc.py ============================================================================== --- pypy/dist/pypy/rpython/extfunc.py (original) +++ pypy/dist/pypy/rpython/extfunc.py Sat Feb 24 17:49:04 2007 @@ -68,3 +68,11 @@ FunEntry.__name__ = export_name else: FunEntry.__name__ = function.func_name + +def is_external(func): + if getattr(func.value._callable, 'suggested_primitive', False): + return True + if hasattr(func.value, '_entry'): + if isinstance(func.value._entry, ExtFuncEntry): + return True + return False From fijal at codespeak.net Sat Feb 24 17:49:53 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 24 Feb 2007 17:49:53 +0100 (CET) Subject: [pypy-svn] r39366 - pypy/dist/pypy/translator/oosupport Message-ID: <20070224164953.55F65101BD@code0.codespeak.net> Author: fijal Date: Sat Feb 24 17:49:45 2007 New Revision: 39366 Modified: pypy/dist/pypy/translator/oosupport/metavm.py Log: Lift need of external functions to have suggested_primitive set (we need better way of handling that I fear) Modified: pypy/dist/pypy/translator/oosupport/metavm.py ============================================================================== --- pypy/dist/pypy/translator/oosupport/metavm.py (original) +++ pypy/dist/pypy/translator/oosupport/metavm.py Sat Feb 24 17:49:45 2007 @@ -13,6 +13,7 @@ from pypy.rpython.ootypesystem import ootype from pypy.rpython.ootypesystem.bltregistry import ExternalType +from pypy.rpython.extfunc import ExtFuncEntry, is_external class Generator(object): @@ -324,7 +325,8 @@ class _CallDispatcher(_GeneralDispatcher): def render(self, generator, op): func = op.args[0] - if getattr(func.value._callable, 'suggested_primitive', False): + # XXX we need to sort out stuff here at some point + if is_external(func): func_name = func.value._name.split("__")[0] try: return self.builtins.builtin_map[func_name](generator, op) From fijal at codespeak.net Sat Feb 24 18:00:17 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 24 Feb 2007 18:00:17 +0100 (CET) Subject: [pypy-svn] r39367 - pypy/dist/pypy/translator/js/modules Message-ID: <20070224170017.6D0B5101C0@code0.codespeak.net> Author: fijal Date: Sat Feb 24 18:00:13 2007 New Revision: 39367 Modified: pypy/dist/pypy/translator/js/modules/dom.py Log: Lift the need of suggested_primitive Modified: pypy/dist/pypy/translator/js/modules/dom.py ============================================================================== --- pypy/dist/pypy/translator/js/modules/dom.py (original) +++ pypy/dist/pypy/translator/js/modules/dom.py Sat Feb 24 18:00:13 2007 @@ -715,12 +715,6 @@ 'shiftKey': bool, }) -# XXX: Right now this is only way to get it rendered -setTimeout.suggested_primitive = True - -# the following code wraps minidom nodes with Node classes, and makes -# sure all methods on the nodes return wrapped nodes - class _FunctionWrapper(object): """makes sure function return values are wrapped if appropriate""" def __init__(self, callable): From fijal at codespeak.net Sat Feb 24 18:00:55 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 24 Feb 2007 18:00:55 +0100 (CET) Subject: [pypy-svn] r39368 - in pypy/dist/pypy/translator/js/modules: . test Message-ID: <20070224170055.D64CB101DA@code0.codespeak.net> Author: fijal Date: Sat Feb 24 18:00:49 2007 New Revision: 39368 Added: pypy/dist/pypy/translator/js/modules/test/test_mochikit.py Modified: pypy/dist/pypy/translator/js/modules/mochikit.py Log: User register_external and a test Modified: pypy/dist/pypy/translator/js/modules/mochikit.py ============================================================================== --- pypy/dist/pypy/translator/js/modules/mochikit.py (original) +++ pypy/dist/pypy/translator/js/modules/mochikit.py Sat Feb 24 18:00:49 2007 @@ -2,6 +2,8 @@ """ mochikit wrappers """ +from pypy.rpython.extfunc import register_external + def createLoggingPane(var): pass createLoggingPane.suggested_primitive = True @@ -34,4 +36,5 @@ def escapeHTML(data): return data -escapeHTML.suggested_primitive = True +register_external(escapeHTML, args=[str], result=str) + Added: pypy/dist/pypy/translator/js/modules/test/test_mochikit.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/js/modules/test/test_mochikit.py Sat Feb 24 18:00:49 2007 @@ -0,0 +1,9 @@ + +from pypy.translator.js.lib.support import js_source +from pypy.translator.js.modules.mochikit import * + +class TestRender(object): + def test_escape_html(self): + def x(): + escapeHTML("xxx") + "xxx" + assert js_source([x], use_pdb=False) From fijal at codespeak.net Sat Feb 24 18:02:00 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 24 Feb 2007 18:02:00 +0100 (CET) Subject: [pypy-svn] r39369 - pypy/dist/pypy/translator/js/modules/test Message-ID: <20070224170200.9CA32101DF@code0.codespeak.net> Author: fijal Date: Sat Feb 24 18:01:49 2007 New Revision: 39369 Modified: pypy/dist/pypy/translator/js/modules/test/test_mochikit.py Log: Be more verbose in this test Modified: pypy/dist/pypy/translator/js/modules/test/test_mochikit.py ============================================================================== --- pypy/dist/pypy/translator/js/modules/test/test_mochikit.py (original) +++ pypy/dist/pypy/translator/js/modules/test/test_mochikit.py Sat Feb 24 18:01:49 2007 @@ -6,4 +6,4 @@ def test_escape_html(self): def x(): escapeHTML("xxx") + "xxx" - assert js_source([x], use_pdb=False) + assert js_source([x], use_pdb=False).find("escapeHTML (") != -1 From hpk at codespeak.net Sun Feb 25 08:11:05 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sun, 25 Feb 2007 08:11:05 +0100 (CET) Subject: [pypy-svn] r39375 - pypy/extradoc Message-ID: <20070225071105.840BC101C0@code0.codespeak.net> Author: hpk Date: Sun Feb 25 08:11:01 2007 New Revision: 39375 Modified: pypy/extradoc/confrest.py Log: add mydir logic to correctly generate extradoc pages Modified: pypy/extradoc/confrest.py ============================================================================== --- pypy/extradoc/confrest.py (original) +++ pypy/extradoc/confrest.py Sun Feb 25 08:11:01 2007 @@ -1,4 +1,5 @@ from py.__.doc.confrest import * +import py class PyPyPage(Page): def fill(self): @@ -14,6 +15,10 @@ class_="menu"), " ", id="menubar") + def get_doclink(self, target): + return relpath(self.targetpath.strpath, + self.project.get_docpath().join(target).strpath) + class Project(Project): title = "PyPy" stylesheet = 'http://codespeak.net/pypy/dist/pypy/doc/style.css' @@ -25,5 +30,8 @@ src="http://codespeak.net/pypy/img/py-web1.png", height=110, width=149))) Page = PyPyPage + mydir = py.magic.autopath().dirpath() + def get_docpath(self): + return self.mydir From hpk at codespeak.net Sun Feb 25 08:12:54 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sun, 25 Feb 2007 08:12:54 +0100 (CET) Subject: [pypy-svn] r39376 - pypy/extradoc/sprintinfo/trillke-2007 Message-ID: <20070225071254.33012101EA@code0.codespeak.net> Author: hpk Date: Sun Feb 25 08:12:48 2007 New Revision: 39376 Modified: pypy/extradoc/sprintinfo/trillke-2007/people.txt Log: add georg according to his pypy-sprint mail Modified: pypy/extradoc/sprintinfo/trillke-2007/people.txt ============================================================================== --- pypy/extradoc/sprintinfo/trillke-2007/people.txt (original) +++ pypy/extradoc/sprintinfo/trillke-2007/people.txt Sun Feb 25 08:12:48 2007 @@ -20,6 +20,7 @@ Stefan Busemann 26th-28th klocke Stephan Diehl 2nd-4th private/shared alex Alexander Schremmer 1st-5th private/shared stephan +Georg Brandl 1st-5th private Maciej Fijalkowski 28-6th+X private Guido Wesdorp 26th-5th private Carl Friedrich Bolz 25th-6th private From fijal at codespeak.net Sun Feb 25 20:07:45 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 25 Feb 2007 20:07:45 +0100 (CET) Subject: [pypy-svn] r39391 - pypy/dist/pypy/translator/js Message-ID: <20070225190745.0B4A210195@code0.codespeak.net> Author: fijal Date: Sun Feb 25 20:07:43 2007 New Revision: 39391 Modified: pypy/dist/pypy/translator/js/commproxy.py Log: Patch from Daniel Nogradi to make POST way of handling xmlhttprequests work at least under ffox. Modified: pypy/dist/pypy/translator/js/commproxy.py ============================================================================== --- pypy/dist/pypy/translator/js/commproxy.py (original) +++ pypy/dist/pypy/translator/js/commproxy.py Sun Feb 25 20:07:43 2007 @@ -14,9 +14,7 @@ str = "" for(i in data) { if (data[i]) { - if (str.length == 0) { - str += "?"; - } else { + if (str.length != 0) { str += "&"; } str += escape(i) + "=" + escape(data[i].toString()); @@ -24,7 +22,7 @@ } //logDebug('%(call)s'+str); x.open("GET", '%(call)s' + str, true); - //x.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); + x.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); x.onreadystatechange = function () { %(real_callback)s(x, callback) }; //x.setRequestHeader("Connection", "close"); //x.send(data); @@ -131,6 +129,8 @@ METHOD_BODY = globals()[self.method + "_METHOD_BODY"] if USE_MOCHIKIT and self.use_xml: assert 0, "Cannot use mochikit and xml requests at the same time" + if USE_MOCHIKIT and self.method == "POST": + assert 0, "Cannot use mochikit with POST method" if USE_MOCHIKIT: ilasm.codegenerator.write(MOCHIKIT_BODY % {'class':self.name, 'method':url,\ 'args':','.join(real_args), 'data':data, 'call':method_name}) From fijal at codespeak.net Sun Feb 25 21:46:51 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 25 Feb 2007 21:46:51 +0100 (CET) Subject: [pypy-svn] r39394 - in pypy/dist/pypy/translator/js: . test Message-ID: <20070225204651.125FB1010B@code0.codespeak.net> Author: fijal Date: Sun Feb 25 21:46:49 2007 New Revision: 39394 Modified: pypy/dist/pypy/translator/js/main.py pypy/dist/pypy/translator/js/test/test_main.py Log: Another patch from Daniel Nogardi which allows not to specify function list, but instead just filename. And a test from myself :) Modified: pypy/dist/pypy/translator/js/main.py ============================================================================== --- pypy/dist/pypy/translator/js/main.py (original) +++ pypy/dist/pypy/translator/js/main.py Sun Feb 25 21:46:49 2007 @@ -14,6 +14,7 @@ from pypy.config.config import OptionDescription, BoolOption, StrOption from pypy.config.config import Config, to_optparse import py +import sys js_optiondescr = OptionDescription("jscompile", "", [ BoolOption("view", "View flow graphs", @@ -44,16 +45,29 @@ [:func_data.func_code.co_argcount]) def rpython2javascript_main(argv, jsconfig): - if len(argv) < 2: + if len(argv) == 0: print "usage: module " - import sys sys.exit(0) module_name = argv[0] - if module_name.endswith('.py'): - module_name = module_name[:-3] - function_names = argv[1:] - mod = __import__(module_name, None, None, ["Module"]) + if not module_name.endswith('.py'): + module_name += ".py" + mod = py.path.local(module_name).pyimport() + if len(argv) == 1: + function_names = [] + for function_name in dir(mod): + function = getattr(mod, function_name) + if callable(function) and getattr(function, '_client', False): + function_names.append( function_name ) + if not function_names: + print "Cannot find any function with _client=True in %s"\ + % module_name + sys.exit(1) + else: + function_names = argv[1:] source = rpython2javascript(mod, function_names, jsconfig=jsconfig) + if not source: + print "Exiting, source not generated" + sys.exit(1) open(jsconfig.output, "w").write(source) print "Written file %s" % jsconfig.output Modified: pypy/dist/pypy/translator/js/test/test_main.py ============================================================================== --- pypy/dist/pypy/translator/js/test/test_main.py (original) +++ pypy/dist/pypy/translator/js/test/test_main.py Sun Feb 25 21:46:49 2007 @@ -2,15 +2,22 @@ """ tests of rpython2javascript function """ -from pypy.translator.js.main import rpython2javascript +from pypy.translator.js.main import rpython2javascript, rpython2javascript_main,\ + js_optiondescr from pypy.translator.js import conftest from pypy.rpython.ootypesystem.bltregistry import BasicExternal, described import py import sys +from pypy.tool.udir import udir +from pypy.config.config import Config, to_optparse + #if not conftest.option.browser: # py.test.skip("Works only in browser (right now?)") +def setup_module(mod): + mod.jsconfig = Config(js_optiondescr) + class A(BasicExternal): def method(self, a={'a':'a'}): pass @@ -31,3 +38,32 @@ def test_module_none(): assert rpython2javascript(None, "fff") + +class TestJsMain(object): + def _test_not_raises(self, mod_file, args_rest=[]): + try: + rpython2javascript_main([str(mod_file)] + args_rest, + jsconfig) + except SystemExit: + py.test.fail("Exited") + + def _test_raises(self, mod_file, args_rest): + py.test.raises(SystemExit, rpython2javascript_main, + [str(mod_file)] + args_rest, jsconfig) + + def test_main_one(self): + udir.ensure("js_one.py").write(py.code.Source(""" + def f(): + pass + f._client = True + """)) + self._test_not_raises(udir.join("js_one.py")) + + def test_main_two(self): + udir.ensure("js_two.py").write(py.code.Source(""" + def f(): + pass + """)) + self._test_not_raises(udir.join("js_two.py"), ["f"]) + self._test_raises(udir.join("js_two.py"), []) + From tismer at codespeak.net Sun Feb 25 21:50:34 2007 From: tismer at codespeak.net (tismer at codespeak.net) Date: Sun, 25 Feb 2007 21:50:34 +0100 (CET) Subject: [pypy-svn] r39395 - pypy/extradoc/talk/pycon2007 Message-ID: <20070225205034.75255101CC@code0.codespeak.net> Author: tismer Date: Sun Feb 25 21:50:32 2007 New Revision: 39395 Added: pypy/extradoc/talk/pycon2007/The Essentials Of Stackless Python.ppt (contents, props changed) Log: finally a bunch of slides is there Added: pypy/extradoc/talk/pycon2007/The Essentials Of Stackless Python.ppt ============================================================================== Binary file. No diff available. From tismer at codespeak.net Sun Feb 25 23:31:45 2007 From: tismer at codespeak.net (tismer at codespeak.net) Date: Sun, 25 Feb 2007 23:31:45 +0100 (CET) Subject: [pypy-svn] r39396 - pypy/extradoc/talk/pycon2007 Message-ID: <20070225223145.C96F91019D@code0.codespeak.net> Author: tismer Date: Sun Feb 25 23:31:44 2007 New Revision: 39396 Added: pypy/extradoc/talk/pycon2007/The Essentials Of Stackless Python.pdf (contents, props changed) Modified: pypy/extradoc/talk/pycon2007/The Essentials Of Stackless Python.ppt Log: created pdf Added: pypy/extradoc/talk/pycon2007/The Essentials Of Stackless Python.pdf ============================================================================== Binary file. No diff available. Modified: pypy/extradoc/talk/pycon2007/The Essentials Of Stackless Python.ppt ============================================================================== Binary files. No diff available. From xoraxax at codespeak.net Sun Feb 25 23:57:45 2007 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sun, 25 Feb 2007 23:57:45 +0100 (CET) Subject: [pypy-svn] r39398 - pypy/dist/pypy/doc Message-ID: <20070225225745.D755410147@code0.codespeak.net> Author: xoraxax Date: Sun Feb 25 23:57:41 2007 New Revision: 39398 Modified: pypy/dist/pypy/doc/video-index.txt Log: Reformatted dates as ISO and added 2006 after PyCon everywhere in video_index.txt Modified: pypy/dist/pypy/doc/video-index.txt ============================================================================== --- pypy/dist/pypy/doc/video-index.txt (original) +++ pypy/dist/pypy/doc/video-index.txt Sun Feb 25 23:57:41 2007 @@ -43,8 +43,8 @@ If you need another license, don't hesitate to contact us. -Trailer: PyPy at the PyCon --------------------------- +Trailer: PyPy at the PyCon 2006 +------------------------------- 130mb: http://codespeak.net/download/pypy/video/pycon-trailer.avi.torrent @@ -57,7 +57,7 @@ :alt: Trailer PyPy at PyCon :align: left -This trailer shows the PyPy team at the PyCon, a behind-the-scenes at sprints, talks and everywhere else. +This trailer shows the PyPy team at the PyCon 2006, a behind-the-scenes at sprints, talks and everywhere else. PAL, 9 min, DivX AVI @@ -75,7 +75,7 @@ :alt: Interview with Tim Peters :align: left -Interview with CPython core developer Tim Peters at this years PyCon, Dallas, US. 2.3.2006 +Interview with CPython core developer Tim Peters at PyCon 2006, Dallas, US. (2006-03-02) PAL, 23 min, DivX AVI @@ -95,7 +95,7 @@ :alt: Interview with Bob Ippolito :align: left -What do you think about PyPy? Interview with American software developer Bob Ippolito at this years PyCon, Dallas, US. 1.3.2006 +What do you think about PyPy? Interview with American software developer Bob Ippolito at tPyCon 2006, Dallas, US. (2006-03-01) PAL 8 min, DivX AVI @@ -112,10 +112,10 @@ .. image:: image/introductory-talk-pycon.jpg :scale: 100 - :alt: Introductory talk at PyCon + :alt: Introductory talk at PyCon 2006 :align: left -This introductory talk is given by core developers Michael Hudson and Christian Tismer at the PyCon, Dallas, US. 26.2.2006 +This introductory talk is given by core developers Michael Hudson and Christian Tismer at PyCon 2006, Dallas, US. (2006-02-26) PAL, 28 min, divx AVI @@ -138,7 +138,7 @@ :alt: Agile talk :align: left -Core developer Holger Krekel and project manager Beatrice During are giving a talk on the agile open source methods used in the PyPy project at the PyCon, Dallas, US. 26.2.2006 +Core developer Holger Krekel and project manager Beatrice During are giving a talk on the agile open source methods used in the PyPy project at PyCon 2006, Dallas, US. (2006-02-26) PAL, 26 min, divx AVI @@ -161,7 +161,7 @@ :alt: Architecture session :align: left -This architecture session is given by core developers Holger Krekel and Armin Rigo at the PyCon, Dallas, US. 26.2.2006 +This architecture session is given by core developers Holger Krekel and Armin Rigo at PyCon 2006, Dallas, US. (2006-02-26) PAL, 48 min, divx AVI @@ -184,7 +184,7 @@ :alt: Sprint Tutorial :align: left -Sprint tutorial by core developer Michael Hudson at the PyCon sprint, Dallas, US. 27.2.2006 +Sprint tutorial by core developer Michael Hudson at PyCon 2006, Dallas, US. (2006-02-27) PAL, 44 min, divx AVI From afayolle at codespeak.net Mon Feb 26 08:46:02 2007 From: afayolle at codespeak.net (afayolle at codespeak.net) Date: Mon, 26 Feb 2007 08:46:02 +0100 (CET) Subject: [pypy-svn] r39399 - in pypy/branch/ast-experiments: . lib-python lib-python/modified-2.4.1 lib-python/modified-2.4.1/test pypy pypy/annotation pypy/annotation/test pypy/bin pypy/config pypy/config/test pypy/doc pypy/doc/config pypy/doc/js pypy/doc/statistic pypy/doc/tool pypy/jit/codegen/llvm pypy/lang/automata/test pypy/lang/js pypy/lang/js/test pypy/lang/js/test/ecma pypy/lib/cslib pypy/lib/distributed pypy/lib/distributed/demo pypy/lib/distributed/test pypy/lib/pyontology pypy/lib/pyontology/test pypy/module/_cslib pypy/module/_stackless pypy/module/crypt pypy/module/sys pypy/objspace pypy/objspace/std pypy/rlib/cslib pypy/rpython pypy/rpython/lltypesystem pypy/rpython/memory/gctransform pypy/rpython/test pypy/tool pypy/tool/build pypy/tool/build/templates pypy/tool/build/test pypy/translator/c/src pypy/translator/cli/test pypy/translator/goal pypy/translator/js pypy/translator/js/demo pypy/translator/js/examples pypy/translator/js/examples/bnb pypy/translator/js/examples/bnb/data pypy/translator/js/examples/console pypy/translator/js/examples/console/test pypy/translator/js/examples/data pypy/translator/js/examples/djangoping pypy/translator/js/examples/djangoping/test pypy/translator/js/examples/test pypy/translator/js/lib pypy/translator/js/lib/test pypy/translator/js/modules pypy/translator/js/modules/test pypy/translator/js/test pypy/translator/llvm pypy/translator/llvm/module pypy/translator/llvm/test pypy/translator/oosupport Message-ID: <20070226074602.62CAA10128@code0.codespeak.net> Author: afayolle Date: Mon Feb 26 08:45:45 2007 New Revision: 39399 Added: pypy/branch/ast-experiments/pypy/doc/config/commandline.txt - copied unchanged from r39398, pypy/dist/pypy/doc/config/commandline.txt pypy/branch/ast-experiments/pypy/doc/config/index.txt - copied unchanged from r39398, pypy/dist/pypy/doc/config/index.txt pypy/branch/ast-experiments/pypy/doc/config/mergedblocks.png - copied unchanged from r39398, pypy/dist/pypy/doc/config/mergedblocks.png pypy/branch/ast-experiments/pypy/doc/config/unmergedblocks.png - copied unchanged from r39398, pypy/dist/pypy/doc/config/unmergedblocks.png pypy/branch/ast-experiments/pypy/doc/js/testing.txt - copied unchanged from r39398, pypy/dist/pypy/doc/js/testing.txt pypy/branch/ast-experiments/pypy/doc/release-0.99.0.txt - copied unchanged from r39398, pypy/dist/pypy/doc/release-0.99.0.txt pypy/branch/ast-experiments/pypy/doc/statistic/python-list.txt - copied unchanged from r39398, pypy/dist/pypy/doc/statistic/python-list.txt pypy/branch/ast-experiments/pypy/lang/js/conftest.py - copied unchanged from r39398, pypy/dist/pypy/lang/js/conftest.py pypy/branch/ast-experiments/pypy/lang/js/test/ecma/conftest.py - copied unchanged from r39398, pypy/dist/pypy/lang/js/test/ecma/conftest.py pypy/branch/ast-experiments/pypy/lib/cslib/ - copied from r39398, pypy/dist/pypy/lib/cslib/ pypy/branch/ast-experiments/pypy/lib/distributed/demo/ - copied from r39398, pypy/dist/pypy/lib/distributed/demo/ pypy/branch/ast-experiments/pypy/module/_cslib/ - copied from r39398, pypy/dist/pypy/module/_cslib/ pypy/branch/ast-experiments/pypy/rlib/cslib/ - copied from r39398, pypy/dist/pypy/rlib/cslib/ pypy/branch/ast-experiments/pypy/tool/build/templates/ - copied from r39398, pypy/dist/pypy/tool/build/templates/ pypy/branch/ast-experiments/pypy/tool/build/test/test_webserver.py - copied unchanged from r39398, pypy/dist/pypy/tool/build/test/test_webserver.py pypy/branch/ast-experiments/pypy/tool/build/webapp.py - copied unchanged from r39398, pypy/dist/pypy/tool/build/webapp.py pypy/branch/ast-experiments/pypy/tool/build/webserver.py - copied unchanged from r39398, pypy/dist/pypy/tool/build/webserver.py pypy/branch/ast-experiments/pypy/translator/js/examples/console/ (props changed) - copied from r39398, pypy/dist/pypy/translator/js/examples/console/ pypy/branch/ast-experiments/pypy/translator/js/examples/djangoping/ (props changed) - copied from r39398, pypy/dist/pypy/translator/js/examples/djangoping/ pypy/branch/ast-experiments/pypy/translator/js/examples/guestbook.py - copied unchanged from r39398, pypy/dist/pypy/translator/js/examples/guestbook.py pypy/branch/ast-experiments/pypy/translator/js/examples/guestbook_client.py - copied unchanged from r39398, pypy/dist/pypy/translator/js/examples/guestbook_client.py pypy/branch/ast-experiments/pypy/translator/js/examples/test/test_examples.py - copied unchanged from r39398, pypy/dist/pypy/translator/js/examples/test/test_examples.py pypy/branch/ast-experiments/pypy/translator/js/modules/test/test_mochikit.py - copied unchanged from r39398, pypy/dist/pypy/translator/js/modules/test/test_mochikit.py Removed: pypy/branch/ast-experiments/pypy/doc/config/objspace.std.llvmallopts.txt pypy/branch/ast-experiments/pypy/doc/config/translation.debug_transform.txt pypy/branch/ast-experiments/pypy/translator/js/demo/ pypy/branch/ast-experiments/pypy/translator/js/examples/console.py Modified: pypy/branch/ast-experiments/LICENSE pypy/branch/ast-experiments/README pypy/branch/ast-experiments/lib-python/conftest.py pypy/branch/ast-experiments/lib-python/modified-2.4.1/socket.py pypy/branch/ast-experiments/lib-python/modified-2.4.1/test/test_descr.py pypy/branch/ast-experiments/pypy/annotation/test/test_annrpython.py pypy/branch/ast-experiments/pypy/annotation/unaryop.py pypy/branch/ast-experiments/pypy/bin/py.py pypy/branch/ast-experiments/pypy/config/config.py pypy/branch/ast-experiments/pypy/config/makerestdoc.py pypy/branch/ast-experiments/pypy/config/pypyoption.py pypy/branch/ast-experiments/pypy/config/test/test_makerestdoc.py pypy/branch/ast-experiments/pypy/config/translationoption.py pypy/branch/ast-experiments/pypy/conftest.py pypy/branch/ast-experiments/pypy/doc/_ref.txt pypy/branch/ast-experiments/pypy/doc/architecture.txt pypy/branch/ast-experiments/pypy/doc/cleanup-todo.txt pypy/branch/ast-experiments/pypy/doc/cli-backend.txt pypy/branch/ast-experiments/pypy/doc/coding-guide.txt pypy/branch/ast-experiments/pypy/doc/config/confrest.py pypy/branch/ast-experiments/pypy/doc/config/objspace.allworkingmodules.txt pypy/branch/ast-experiments/pypy/doc/config/objspace.compiler.txt pypy/branch/ast-experiments/pypy/doc/config/objspace.logbytecodes.txt pypy/branch/ast-experiments/pypy/doc/config/objspace.lowmem.txt pypy/branch/ast-experiments/pypy/doc/config/objspace.name.txt pypy/branch/ast-experiments/pypy/doc/config/objspace.nofaking.txt pypy/branch/ast-experiments/pypy/doc/config/objspace.opcodes.CALL_LIKELY_BUILTIN.txt pypy/branch/ast-experiments/pypy/doc/config/objspace.opcodes.txt pypy/branch/ast-experiments/pypy/doc/config/objspace.parser.txt pypy/branch/ast-experiments/pypy/doc/config/objspace.std.methodcachesize.txt pypy/branch/ast-experiments/pypy/doc/config/objspace.std.optimized_int_add.txt pypy/branch/ast-experiments/pypy/doc/config/objspace.std.prebuiltintfrom.txt pypy/branch/ast-experiments/pypy/doc/config/objspace.std.prebuiltintto.txt pypy/branch/ast-experiments/pypy/doc/config/objspace.std.txt pypy/branch/ast-experiments/pypy/doc/config/objspace.std.withdictmeasurement.txt pypy/branch/ast-experiments/pypy/doc/config/objspace.std.withfastslice.txt pypy/branch/ast-experiments/pypy/doc/config/objspace.std.withmethodcache.txt pypy/branch/ast-experiments/pypy/doc/config/objspace.std.withmethodcachecounter.txt pypy/branch/ast-experiments/pypy/doc/config/objspace.std.withmultidict.txt pypy/branch/ast-experiments/pypy/doc/config/objspace.std.withmultilist.txt pypy/branch/ast-experiments/pypy/doc/config/objspace.std.withprebuiltint.txt pypy/branch/ast-experiments/pypy/doc/config/objspace.std.withrangelist.txt pypy/branch/ast-experiments/pypy/doc/config/objspace.std.withsharingdict.txt pypy/branch/ast-experiments/pypy/doc/config/objspace.std.withstrdict.txt pypy/branch/ast-experiments/pypy/doc/config/objspace.std.withstrjoin.txt pypy/branch/ast-experiments/pypy/doc/config/objspace.std.withstrslice.txt pypy/branch/ast-experiments/pypy/doc/config/objspace.std.withtypeversion.txt pypy/branch/ast-experiments/pypy/doc/config/objspace.txt pypy/branch/ast-experiments/pypy/doc/config/objspace.usemodules._codecs.txt pypy/branch/ast-experiments/pypy/doc/config/objspace.usemodules._demo.txt pypy/branch/ast-experiments/pypy/doc/config/objspace.usemodules._file.txt pypy/branch/ast-experiments/pypy/doc/config/objspace.usemodules._pickle_support.txt pypy/branch/ast-experiments/pypy/doc/config/objspace.usemodules._random.txt pypy/branch/ast-experiments/pypy/doc/config/objspace.usemodules._stackless.txt pypy/branch/ast-experiments/pypy/doc/config/objspace.usemodules._weakref.txt pypy/branch/ast-experiments/pypy/doc/config/objspace.usemodules.bz2.txt pypy/branch/ast-experiments/pypy/doc/config/objspace.usemodules.posix.txt pypy/branch/ast-experiments/pypy/doc/config/objspace.usemodules.pypymagic.txt pypy/branch/ast-experiments/pypy/doc/config/objspace.usemodules.rctime.txt pypy/branch/ast-experiments/pypy/doc/config/objspace.usemodules.recparser.txt pypy/branch/ast-experiments/pypy/doc/config/objspace.usemodules.rsocket.txt pypy/branch/ast-experiments/pypy/doc/config/objspace.usemodules.time.txt pypy/branch/ast-experiments/pypy/doc/config/objspace.usemodules.txt pypy/branch/ast-experiments/pypy/doc/config/objspace.usepycfiles.txt pypy/branch/ast-experiments/pypy/doc/config/translation.backend.txt pypy/branch/ast-experiments/pypy/doc/config/translation.backendopt.clever_malloc_removal.txt pypy/branch/ast-experiments/pypy/doc/config/translation.backendopt.clever_malloc_removal_heuristic.txt pypy/branch/ast-experiments/pypy/doc/config/translation.backendopt.clever_malloc_removal_threshold.txt pypy/branch/ast-experiments/pypy/doc/config/translation.backendopt.constfold.txt pypy/branch/ast-experiments/pypy/doc/config/translation.backendopt.heap2stack.txt pypy/branch/ast-experiments/pypy/doc/config/translation.backendopt.inline.txt pypy/branch/ast-experiments/pypy/doc/config/translation.backendopt.inline_heuristic.txt pypy/branch/ast-experiments/pypy/doc/config/translation.backendopt.inline_threshold.txt pypy/branch/ast-experiments/pypy/doc/config/translation.backendopt.mallocs.txt pypy/branch/ast-experiments/pypy/doc/config/translation.backendopt.merge_if_blocks.txt pypy/branch/ast-experiments/pypy/doc/config/translation.backendopt.print_statistics.txt pypy/branch/ast-experiments/pypy/doc/config/translation.backendopt.profile_based_inline.txt pypy/branch/ast-experiments/pypy/doc/config/translation.backendopt.profile_based_inline_heuristic.txt pypy/branch/ast-experiments/pypy/doc/config/translation.backendopt.profile_based_inline_threshold.txt pypy/branch/ast-experiments/pypy/doc/config/translation.backendopt.raisingop2direct_call.txt pypy/branch/ast-experiments/pypy/doc/config/translation.backendopt.remove_asserts.txt pypy/branch/ast-experiments/pypy/doc/config/translation.backendopt.txt pypy/branch/ast-experiments/pypy/doc/config/translation.builtins_can_raise_exceptions.txt pypy/branch/ast-experiments/pypy/doc/config/translation.cc.txt pypy/branch/ast-experiments/pypy/doc/config/translation.cli.trace_calls.txt pypy/branch/ast-experiments/pypy/doc/config/translation.cli.txt pypy/branch/ast-experiments/pypy/doc/config/translation.compilerflags.txt pypy/branch/ast-experiments/pypy/doc/config/translation.countmallocs.txt pypy/branch/ast-experiments/pypy/doc/config/translation.debug.txt pypy/branch/ast-experiments/pypy/doc/config/translation.fork_before.txt pypy/branch/ast-experiments/pypy/doc/config/translation.gc.txt pypy/branch/ast-experiments/pypy/doc/config/translation.insist.txt pypy/branch/ast-experiments/pypy/doc/config/translation.instrument.txt pypy/branch/ast-experiments/pypy/doc/config/translation.instrumentctl.txt pypy/branch/ast-experiments/pypy/doc/config/translation.linkerflags.txt pypy/branch/ast-experiments/pypy/doc/config/translation.list_comprehension_operations.txt pypy/branch/ast-experiments/pypy/doc/config/translation.llvm_via_c.txt pypy/branch/ast-experiments/pypy/doc/config/translation.no__thread.txt pypy/branch/ast-experiments/pypy/doc/config/translation.output.txt pypy/branch/ast-experiments/pypy/doc/config/translation.profopt.txt pypy/branch/ast-experiments/pypy/doc/config/translation.simplifying.txt pypy/branch/ast-experiments/pypy/doc/config/translation.stackless.txt pypy/branch/ast-experiments/pypy/doc/config/translation.thread.txt pypy/branch/ast-experiments/pypy/doc/config/translation.txt pypy/branch/ast-experiments/pypy/doc/config/translation.type_system.txt pypy/branch/ast-experiments/pypy/doc/config/translation.vanilla.txt pypy/branch/ast-experiments/pypy/doc/config/translation.verbose.txt pypy/branch/ast-experiments/pypy/doc/config/translation.withsmallfuncsets.txt pypy/branch/ast-experiments/pypy/doc/configuration.txt pypy/branch/ast-experiments/pypy/doc/confrest.py pypy/branch/ast-experiments/pypy/doc/conftest.py pypy/branch/ast-experiments/pypy/doc/contact.txt pypy/branch/ast-experiments/pypy/doc/contributor.txt pypy/branch/ast-experiments/pypy/doc/dev_method.txt pypy/branch/ast-experiments/pypy/doc/eventhistory.txt pypy/branch/ast-experiments/pypy/doc/extcompiler.txt pypy/branch/ast-experiments/pypy/doc/extradoc.txt pypy/branch/ast-experiments/pypy/doc/faq.txt pypy/branch/ast-experiments/pypy/doc/geninterp.txt pypy/branch/ast-experiments/pypy/doc/getting-started.txt pypy/branch/ast-experiments/pypy/doc/glossary.txt pypy/branch/ast-experiments/pypy/doc/how-to-release.txt pypy/branch/ast-experiments/pypy/doc/index.txt pypy/branch/ast-experiments/pypy/doc/js/todo.txt pypy/branch/ast-experiments/pypy/doc/js/using.txt pypy/branch/ast-experiments/pypy/doc/js/webapps_with_pypy.txt pypy/branch/ast-experiments/pypy/doc/js/whatis.txt pypy/branch/ast-experiments/pypy/doc/news.txt pypy/branch/ast-experiments/pypy/doc/object-optimizations.txt pypy/branch/ast-experiments/pypy/doc/objspace-proxies.txt pypy/branch/ast-experiments/pypy/doc/objspace.txt pypy/branch/ast-experiments/pypy/doc/rctypes.txt pypy/branch/ast-experiments/pypy/doc/rlib.txt pypy/branch/ast-experiments/pypy/doc/statistic/loc.txt pypy/branch/ast-experiments/pypy/doc/statistic/number_files.txt pypy/branch/ast-experiments/pypy/doc/statistic/post.txt pypy/branch/ast-experiments/pypy/doc/statistic/release_dates.csv pypy/branch/ast-experiments/pypy/doc/statistic/sprint_dates.csv pypy/branch/ast-experiments/pypy/doc/statistic/statistic_irc_log.txt pypy/branch/ast-experiments/pypy/doc/statistic/subscribers.txt pypy/branch/ast-experiments/pypy/doc/tool/makecontributor.py pypy/branch/ast-experiments/pypy/doc/translation.txt pypy/branch/ast-experiments/pypy/doc/video-index.txt pypy/branch/ast-experiments/pypy/doc/windows.txt pypy/branch/ast-experiments/pypy/jit/codegen/llvm/rgenop.py pypy/branch/ast-experiments/pypy/lang/automata/test/test_dfa.py pypy/branch/ast-experiments/pypy/lang/js/driver.py pypy/branch/ast-experiments/pypy/lang/js/interpreter.py pypy/branch/ast-experiments/pypy/lang/js/js_interactive.py pypy/branch/ast-experiments/pypy/lang/js/jsobj.py pypy/branch/ast-experiments/pypy/lang/js/test/ecma/shell.js pypy/branch/ast-experiments/pypy/lang/js/test/test_interp.py pypy/branch/ast-experiments/pypy/lib/distributed/__init__.py pypy/branch/ast-experiments/pypy/lib/distributed/objkeeper.py pypy/branch/ast-experiments/pypy/lib/distributed/protocol.py pypy/branch/ast-experiments/pypy/lib/distributed/test/test_distributed.py pypy/branch/ast-experiments/pypy/lib/pyontology/pyontology.py pypy/branch/ast-experiments/pypy/lib/pyontology/test/test_ontology.py pypy/branch/ast-experiments/pypy/module/_stackless/interp_greenlet.py pypy/branch/ast-experiments/pypy/module/crypt/interp_crypt.py pypy/branch/ast-experiments/pypy/module/sys/version.py (contents, props changed) pypy/branch/ast-experiments/pypy/objspace/std/stringobject.py pypy/branch/ast-experiments/pypy/objspace/taint.py pypy/branch/ast-experiments/pypy/objspace/thunk.py pypy/branch/ast-experiments/pypy/rpython/extfunc.py pypy/branch/ast-experiments/pypy/rpython/lltypesystem/lltype.py pypy/branch/ast-experiments/pypy/rpython/memory/gctransform/framework.py pypy/branch/ast-experiments/pypy/rpython/memory/gctransform/stacklessframework.py pypy/branch/ast-experiments/pypy/rpython/rfloat.py pypy/branch/ast-experiments/pypy/rpython/rint.py pypy/branch/ast-experiments/pypy/rpython/rmodel.py pypy/branch/ast-experiments/pypy/rpython/rtuple.py pypy/branch/ast-experiments/pypy/rpython/test/test_rlist.py pypy/branch/ast-experiments/pypy/rpython/test/test_rtuple.py pypy/branch/ast-experiments/pypy/tool/build/build.py pypy/branch/ast-experiments/pypy/tool/build/metaserver.py pypy/branch/ast-experiments/pypy/tool/build/test/test_metaserver.py pypy/branch/ast-experiments/pypy/tool/makerelease.py pypy/branch/ast-experiments/pypy/tool/option.py pypy/branch/ast-experiments/pypy/tool/statistic_over_time.py pypy/branch/ast-experiments/pypy/translator/c/src/obmalloc.c (props changed) pypy/branch/ast-experiments/pypy/translator/c/src/signals.h (contents, props changed) pypy/branch/ast-experiments/pypy/translator/cli/test/runtest.py pypy/branch/ast-experiments/pypy/translator/goal/app_main.py pypy/branch/ast-experiments/pypy/translator/goal/bench-cronjob.py pypy/branch/ast-experiments/pypy/translator/goal/targetjsstandalone.py pypy/branch/ast-experiments/pypy/translator/goal/translate.py pypy/branch/ast-experiments/pypy/translator/js/commproxy.py pypy/branch/ast-experiments/pypy/translator/js/examples/bnb/ (props changed) pypy/branch/ast-experiments/pypy/translator/js/examples/bnb/__init__.py (props changed) pypy/branch/ast-experiments/pypy/translator/js/examples/bnb/bnb.py pypy/branch/ast-experiments/pypy/translator/js/examples/bnb/data/bnb.html pypy/branch/ast-experiments/pypy/translator/js/examples/bnb/servermessage.py pypy/branch/ast-experiments/pypy/translator/js/examples/console/test/ (props changed) pypy/branch/ast-experiments/pypy/translator/js/examples/data/index.html pypy/branch/ast-experiments/pypy/translator/js/examples/djangoping/test/ (props changed) pypy/branch/ast-experiments/pypy/translator/js/examples/over_client.py (contents, props changed) pypy/branch/ast-experiments/pypy/translator/js/examples/overmind.py (contents, props changed) pypy/branch/ast-experiments/pypy/translator/js/examples/pythonconsole.py pypy/branch/ast-experiments/pypy/translator/js/lib/support.py (contents, props changed) pypy/branch/ast-experiments/pypy/translator/js/lib/test/__init__.py (props changed) pypy/branch/ast-experiments/pypy/translator/js/lib/test/test_support.py (props changed) pypy/branch/ast-experiments/pypy/translator/js/lib/test/test_url.py (props changed) pypy/branch/ast-experiments/pypy/translator/js/lib/url.py (props changed) pypy/branch/ast-experiments/pypy/translator/js/main.py pypy/branch/ast-experiments/pypy/translator/js/modules/dom.py pypy/branch/ast-experiments/pypy/translator/js/modules/mochikit.py pypy/branch/ast-experiments/pypy/translator/js/test/test_extfunc.py (props changed) pypy/branch/ast-experiments/pypy/translator/js/test/test_main.py pypy/branch/ast-experiments/pypy/translator/js/test/test_rdict.py (props changed) pypy/branch/ast-experiments/pypy/translator/llvm/buildllvm.py pypy/branch/ast-experiments/pypy/translator/llvm/externs2ll.py pypy/branch/ast-experiments/pypy/translator/llvm/gc.py pypy/branch/ast-experiments/pypy/translator/llvm/genllvm.py pypy/branch/ast-experiments/pypy/translator/llvm/module/support.py pypy/branch/ast-experiments/pypy/translator/llvm/test/runtest.py pypy/branch/ast-experiments/pypy/translator/oosupport/metavm.py Log: merge trunk with branch svn merge -r 38798:39398 svn+ssh://codespeak.net/svn/pypy/dist Modified: pypy/branch/ast-experiments/LICENSE ============================================================================== --- pypy/branch/ast-experiments/LICENSE (original) +++ pypy/branch/ast-experiments/LICENSE Mon Feb 26 08:45:45 2007 @@ -27,49 +27,73 @@ DEALINGS IN THE SOFTWARE. -PyPy Copyright holders 2003-2006 +PyPy Copyright holders 2003-2007 ----------------------------------- Except when otherwise stated (look for LICENSE files or information at the beginning of each file) the files in the 'pypy' directory are each copyrighted by one or more of the following people and organizations: - Armin Rigo - Samuele Pedroni - Holger Krekel - Christian Tismer - Michael Hudson - Carl Friedrich Bolz - Eric van Riet Paap - Richard Emslie - Anders Chrigstrom - Niklaus Haldimann - Antonio Cuni - Maciek Fijalkowski - Aur?lien Camp?as - Seo Sanghyeon - Alex Martelli - Anders Lehmann - Stephan Diehl - Patrick Maupin - Ludovic Aubry - Bob Ippolito - Adrien Di Mascio - Jacob Hallen - Laura Creighton - Marius Gedminas - Amaury Forgeot d Arc - Boris Feigin - Valentino Volonghi - Bert Freudenberg - Andrew Thompson - Jonathan David Riehl - Amaury Forgeot D Arc - Alexandre Fayolle - Guido van Rossum + Armin Rigo + Samuele Pedroni + Michael Hudson + Carl Friedrich Bolz + Christian Tismer + Holger Krekel + Eric van Riet Paap + Antonio Cuni + Anders Chrigstrom + Maciek Fijalkowski + Richard Emslie + Aurelien Campeas + Anders Lehmann + Niklaus Haldimann + Seo Sanghyeon + Lawrence Oluyede + Alex Martelli + Ludovic Aubry + Adrien Di Mascio + Stephan Diehl + Guido Wesdorp + Stefan Schwarzer + Tomek Meka + Patrick Maupin + Leonardo Santagada + Bob Ippolito + Laura Creighton + Jacob Hallen + Marius Gedminas + Niko Matsakis + Amaury Forgeot d Arc + Guido van Rossum + Valentino Volonghi + Alexander Schremmer + Alexandre Fayolle + Wanja Saatkamp + Gerald Klix + Eugene Oden + Dinu Gherman + Guenter Jantzen + Ben Young + Nicolas Chauvat + Michael Twomey + Rocco Moretti + Simon Burton + Boris Feigin + Olivier Dormond + Gintautas Miliauskas + Stuart Williams + Jens-Uwe Mager + Brian Dorsey + Jonathan David Riehl + Anders Qvist + Beatrice During + Andreas Friedge + Alan McIntyre + Bert Freudenberg Heinrich-Heine University, Germany - AB Strakt, Sweden + Open End AB (formerly AB Strakt), Sweden merlinux GmbH, Germany tismerysoft GmbH, Germany Logilab Paris, France Modified: pypy/branch/ast-experiments/README ============================================================================== --- pypy/branch/ast-experiments/README (original) +++ pypy/branch/ast-experiments/README Mon Feb 26 08:45:45 2007 @@ -1,16 +1,17 @@ ======================================================= -PyPy: Python in Python implementation / Version 0.9.0 +PyPy: Python in Python implementation / Version 0.99.0 ======================================================= -PyPy is an implementation of the Python programming language, written -in Python. +Welcome to PyPy! -PyPy is very much a work in progress, but can already build a -self-contained Python implementation that is completely independent of -Python. +PyPy is both an implementation of the Python programming language, and +an extensive compiler framework for dynamic language implementations. +You can build self-contained Python implementations which execute +independently from CPython. -For more, we invite you to head over to our getting-started document: +We invite you to head over to our detailed getting-started document: + pypy/doc/getting-started.html or pypy/doc/getting-started.txt (local if you got a tarball or svn checkout) @@ -23,8 +24,9 @@ For information in what's new in this release, please read the release announcement: - pypy/doc/release-0.9.0.txt - http://codespeak.net/pypy/dist/pypy/doc/release-0.9.0.html + pypy/doc/release-0.99.0.txt or + pypy/doc/release-0.99.0.html + http://codespeak.net/pypy/dist/pypy/doc/release-0.99.0.html Since December 2004, the development of PyPy has been funded by the European Union's research programme. For more information on this Modified: pypy/branch/ast-experiments/lib-python/conftest.py ============================================================================== --- pypy/branch/ast-experiments/lib-python/conftest.py (original) +++ pypy/branch/ast-experiments/lib-python/conftest.py Mon Feb 26 08:45:45 2007 @@ -875,7 +875,7 @@ class ReallyRunFileExternal(py.test.collect.Item): _resultcache = None - def haskeyword(self, keyword): + def _haskeyword(self, keyword): if keyword == 'core': return self.parent.regrtest.core if keyword not in ('error', 'ok', 'timeout'): Modified: pypy/branch/ast-experiments/lib-python/modified-2.4.1/socket.py ============================================================================== --- pypy/branch/ast-experiments/lib-python/modified-2.4.1/socket.py (original) +++ pypy/branch/ast-experiments/lib-python/modified-2.4.1/socket.py Mon Feb 26 08:45:45 2007 @@ -144,6 +144,8 @@ raise error(EBADF, 'Bad file descriptor') def _drop(self): pass + def _reuse(self): + pass send = recv = sendto = recvfrom = __getattr__ = _dummy class _socketobject(object): @@ -188,6 +190,7 @@ Return a regular file object corresponding to the socket. The mode and bufsize arguments are as for the built-in open() function.""" + self._sock._reuse() return _fileobject(self._sock, mode, bufsize) _s = ("def %s(self, *args): return self._sock.%s(*args)\n\n" @@ -229,11 +232,14 @@ closed = property(_getclosed, doc="True if the file is closed") def close(self): - try: - if self._sock: + if self._sock: + try: self.flush() - finally: - self._sock = None + finally: + if self._sock: + s = self._sock + self._sock = None + s._drop() def __del__(self): try: Modified: pypy/branch/ast-experiments/lib-python/modified-2.4.1/test/test_descr.py ============================================================================== --- pypy/branch/ast-experiments/lib-python/modified-2.4.1/test/test_descr.py (original) +++ pypy/branch/ast-experiments/lib-python/modified-2.4.1/test/test_descr.py Mon Feb 26 08:45:45 2007 @@ -1193,7 +1193,6 @@ gc.collect() vereq(Counted.counter, 1) s = None - import gc gc.collect() gc.collect() gc.collect() @@ -2962,7 +2961,6 @@ raise TestFailed, "d.foo should be undefined now" # Test a nasty bug in recurse_down_subclasses() - import gc class A(object): pass class B(A): @@ -3895,7 +3893,7 @@ vereq(c.attr, 1) # this makes a crash more likely: - import gc; gc.collect() + gc.collect() vereq(hasattr(c, 'attr'), False) import warnings Modified: pypy/branch/ast-experiments/pypy/annotation/test/test_annrpython.py ============================================================================== --- pypy/branch/ast-experiments/pypy/annotation/test/test_annrpython.py (original) +++ pypy/branch/ast-experiments/pypy/annotation/test/test_annrpython.py Mon Feb 26 08:45:45 2007 @@ -443,6 +443,14 @@ s = a.build_types(snippet.simple_iter, [list]) assert isinstance(s, annmodel.SomeIterator) + def test_simple_iter_next(self): + def f(x): + i = iter(range(x)) + return i.next() + a = self.RPythonAnnotator() + s = a.build_types(f, [int]) + assert isinstance(s, annmodel.SomeInteger) + def test_simple_iter_dict(self): a = self.RPythonAnnotator() t = somedict(annmodel.SomeInteger(), annmodel.SomeInteger()) Modified: pypy/branch/ast-experiments/pypy/annotation/unaryop.py ============================================================================== --- pypy/branch/ast-experiments/pypy/annotation/unaryop.py (original) +++ pypy/branch/ast-experiments/pypy/annotation/unaryop.py Mon Feb 26 08:45:45 2007 @@ -506,6 +506,7 @@ def next(itr): return itr.s_container.getanyitem(*itr.variant) next.can_only_throw = _can_only_throw + method_next = next class __extend__(SomeInstance): Modified: pypy/branch/ast-experiments/pypy/bin/py.py ============================================================================== --- pypy/branch/ast-experiments/pypy/bin/py.py (original) +++ pypy/branch/ast-experiments/pypy/bin/py.py Mon Feb 26 08:45:45 2007 @@ -13,7 +13,7 @@ from pypy.tool import option from py.compat.optparse import make_option -from pypy.interpreter import main, interactive, error +from pypy.interpreter import main, interactive, error, gateway from pypy.config.config import OptionDescription, BoolOption, StrOption from pypy.config.config import Config, to_optparse import os, sys @@ -27,8 +27,10 @@ BoolOption("completer", "use readline commandline completer", default=False, cmdline="-C"), BoolOption("optimize", - "dummy optimization flag for compatibility with C Python", + "dummy optimization flag for compatibility with CPython", default=False, cmdline="-O"), + BoolOption("no_site_import", "do not 'import site' on initialization", + default=False, cmdline="-S"), StrOption("runmodule", "library module to be run as a script (terminates option list)", default=None, cmdline="-m"), @@ -37,6 +39,16 @@ default=None, cmdline="-c"), ]) +pypy_init = gateway.applevel(''' +def pypy_init(import_site): + if import_site: + try: + import site + except: + import sys + print >> sys.stderr, "import site' failed" +''').interphook('pypy_init') + def main_(argv=None): starttime = time.time() config, parser = option.get_standard_options() @@ -90,6 +102,7 @@ try: def do_start(): space.startup() + pypy_init(space, space.wrap(not interactiveconfig.no_site_import)) if main.run_toplevel(space, do_start, verbose=interactiveconfig.verbose): # compile and run it Modified: pypy/branch/ast-experiments/pypy/config/config.py ============================================================================== --- pypy/branch/ast-experiments/pypy/config/config.py (original) +++ pypy/branch/ast-experiments/pypy/config/config.py Mon Feb 26 08:45:45 2007 @@ -402,7 +402,8 @@ return paths -class OptHelpFormatter(optparse.IndentedHelpFormatter): +class OptHelpFormatter(optparse.TitledHelpFormatter): + extra_useage = None def expand_default(self, option): assert self.parser @@ -446,6 +447,14 @@ return option.help + def format_usage(self, usage): + # XXX bit of a hack + result = optparse.TitledHelpFormatter.format_usage(self, usage) + if self.extra_useage is not None: + return result + "\n" + self.extra_useage + "\n\n" + return result + + class ConfigUpdate(object): @@ -492,7 +501,7 @@ def to_optparse(config, useoptions=None, parser=None, - parserargs=None, parserkwargs=None): + parserargs=None, parserkwargs=None, extra_useage=None): grps = {} def get_group(name, doc): steps = name.split('.') @@ -509,8 +518,10 @@ parserargs = [] if parserkwargs is None: parserkwargs = {} + formatter = OptHelpFormatter() + formatter.extra_useage = extra_useage parser = optparse.OptionParser( - formatter=OptHelpFormatter(), + formatter=formatter, *parserargs, **parserkwargs) if useoptions is None: useoptions = config.getpaths(include_groups=True) Modified: pypy/branch/ast-experiments/pypy/config/makerestdoc.py ============================================================================== --- pypy/branch/ast-experiments/pypy/config/makerestdoc.py (original) +++ pypy/branch/ast-experiments/pypy/config/makerestdoc.py Mon Feb 26 08:45:45 2007 @@ -1,19 +1,27 @@ import py from py.__.rest.rst import Rest, Paragraph, Strong, ListItem, Title, Link -from py.__.rest.rst import Directive +from py.__.rest.rst import Directive, Em, Quote, Text from pypy.config.config import ChoiceOption, BoolOption, StrOption, IntOption from pypy.config.config import FloatOption, OptionDescription, Option, Config from pypy.config.config import ArbitraryOption, DEFAULT_OPTION_NAME from pypy.config.config import _getnegation +configdocdir = py.magic.autopath().dirpath().dirpath().join("doc", "config") + def get_fullpath(opt, path): if path: return "%s.%s" % (path, opt._name) else: return opt._name - + +def get_cmdline(cmdline, fullpath): + if cmdline is DEFAULT_OPTION_NAME: + return '--%s' % (fullpath.replace('.', '-'),) + else: + return cmdline + class __extend__(Option): def make_rest_doc(self, path=""): @@ -26,10 +34,7 @@ ListItem(Strong("name:"), self._name), ListItem(Strong("description:"), self.doc)) if self.cmdline is not None: - if self.cmdline is DEFAULT_OPTION_NAME: - cmdline = '--%s' % (fullpath.replace('.', '-'),) - else: - cmdline = self.cmdline + cmdline = get_cmdline(self.cmdline, fullpath) result.add(ListItem(Strong("command-line:"), cmdline)) return result @@ -140,15 +145,64 @@ stack = [] prefix = fullpath curr = content - for subpath in self.getpaths(include_groups=True): - subpath = fullpath + "." + subpath + config = Config(self) + for ending in self.getpaths(include_groups=True): + subpath = fullpath + "." + ending while not (subpath.startswith(prefix) and subpath[len(prefix)] == "."): curr, prefix = stack.pop() - print subpath, fullpath, curr - new = curr.add(ListItem(Link(subpath, subpath + ".html"))) + print subpath, fullpath, ending, curr + sub, step = config._cfgimpl_get_home_by_path(ending) + doc = getattr(sub._cfgimpl_descr, step).doc + if doc: + new = curr.add(ListItem(Link(subpath + ":", subpath + ".html"), + Em(doc))) + else: + new = curr.add(ListItem(Link(subpath + ":", subpath + ".html"))) stack.append((curr, prefix)) prefix = subpath curr = new return content + +def _get_section_header(cmdline, fullpath, subdescr): + # XXX: pypy specific hack + txtfile = configdocdir.join(fullpath + ".txt") + print txtfile, + if not txtfile.check(): + print "not found" + return "" + print "found" + content = txtfile.read() + if ".. internal" in content: + return "Internal Options" + return "" + +def make_cmdline_overview(descr): + content = Rest( + Title("Overwiew of Command Line Options for '%s'" % (descr._name, ), + abovechar="=", belowchar="=")) + cmdlines = [] + config = Config(descr) + for path in config.getpaths(include_groups=False): + subconf, step = config._cfgimpl_get_home_by_path(path) + fullpath = (descr._name + "." + path) + prefix = fullpath.rsplit(".", 1)[0] + subdescr = getattr(subconf._cfgimpl_descr, step) + cmdline = get_cmdline(subdescr.cmdline, fullpath) + if cmdline is not None: + header = _get_section_header(cmdline, fullpath, subdescr) + cmdlines.append((header, cmdline, fullpath, subdescr)) + cmdlines.sort(key=lambda x: (x[0], x[1].strip("-"))) + currheader = "" + curr = content + for header, cmdline, fullpath, subdescr in cmdlines: + if header != currheader: + content.add(Title(header, abovechar="", belowchar="=")) + curr = content.add(Paragraph()) + currheader = header + curr.add(ListItem(Link(cmdline + ":", fullpath + ".html"), + Text(subdescr.doc))) + return content + + Modified: pypy/branch/ast-experiments/pypy/config/pypyoption.py ============================================================================== --- pypy/branch/ast-experiments/pypy/config/pypyoption.py (original) +++ pypy/branch/ast-experiments/pypy/config/pypyoption.py Mon Feb 26 08:45:45 2007 @@ -23,20 +23,17 @@ working_modules = default_modules.copy() working_modules.update(dict.fromkeys( - ["rsocket", "unicodedata", "mmap", "fcntl", "rctime", "select", "bz2", + ["rsocket", "unicodedata", "mmap", "fcntl", "rctime", "select", "crypt", "signal", "dyngram", ] )) -if platform.machine() == "x86_64" and sys.maxint != 2147483647: - del working_modules['bz2'] # not 64 bit ready - module_dependencies = { } if os.name == "posix": module_dependencies['rctime'] = [("objspace.usemodules.select", True),] - -pypy_optiondescription = OptionDescription("objspace", "Object Space Option", [ + +pypy_optiondescription = OptionDescription("objspace", "Object Space Options", [ ChoiceOption("name", "Object Space name", ["std", "flow", "logic", "thunk", "cpy", "dump", "taint"], "std", @@ -49,11 +46,11 @@ }, cmdline='--objspace -o'), - ChoiceOption("parser", "parser", + ChoiceOption("parser", "which parser to use for app-level code", ["pypy", "cpython"], "pypy", cmdline='--parser'), - ChoiceOption("compiler", "compiler", + ChoiceOption("compiler", "which compiler to use for app-level code", ["cpython", "ast"], "ast", cmdline='--compiler'), @@ -106,7 +103,7 @@ default=False, requires=[("translation.gc", "boehm")]), - BoolOption("withprebuiltint", "prebuilt commonly used int objects", + BoolOption("withprebuiltint", "prebuild commonly used int objects", default=False, requires=[("objspace.std.withsmallint", False)]), @@ -145,7 +142,7 @@ BoolOption("withrangelist", "enable special range list implementation that does not " "actually create the full list until the resulting " - "list is mutaged", + "list is mutated", default=False), BoolOption("withtypeversion", @@ -160,7 +157,7 @@ requires=[("objspace.std.withmultidict", True), ("objspace.std.withtypeversion", True)]), BoolOption("withmethodcache", - "try to cache methods", + "try to cache method lookups", default=False, requires=[("objspace.std.withshadowtracking", True)]), BoolOption("withmethodcachecounter", @@ -207,15 +204,15 @@ ], cmdline="--faassen", negation=False), - BoolOption("llvmallopts", - "enable all optimizations, and use llvm compiled via C", - default=False, - requires=[("objspace.std.allopts", True), - ("translation.llvm_via_c", True), - ("translation.backend", "llvm")], - cmdline="--llvm-faassen", negation=False), +## BoolOption("llvmallopts", +## "enable all optimizations, and use llvm compiled via C", +## default=False, +## requires=[("objspace.std.allopts", True), +## ("translation.llvm_via_c", True), +## ("translation.backend", "llvm")], +## cmdline="--llvm-faassen", negation=False), ]), - BoolOption("lowmem", "Try to use little memory during translation", + BoolOption("lowmem", "Try to use less memory during translation", default=False, cmdline="--lowmem", requires=[("objspace.geninterp", False)]), Modified: pypy/branch/ast-experiments/pypy/config/test/test_makerestdoc.py ============================================================================== --- pypy/branch/ast-experiments/pypy/config/test/test_makerestdoc.py (original) +++ pypy/branch/ast-experiments/pypy/config/test/test_makerestdoc.py Mon Feb 26 08:45:45 2007 @@ -1,5 +1,5 @@ from pypy.config.config import * -import pypy.config.makerestdoc +from pypy.config.makerestdoc import make_cmdline_overview from py.__.doc.conftest import restcheck @@ -14,14 +14,16 @@ def generate_html(descr): config = Config(descr) txt = descr.make_rest_doc().text() - checkrest(txt, descr._name + ".txt") + + result = {"": checkrest(txt, descr._name + ".txt")} for path in config.getpaths(include_groups=True): subconf, step = config._cfgimpl_get_home_by_path(path) fullpath = (descr._name + "." + path) prefix = fullpath.rsplit(".", 1)[0] txt = getattr(subconf._cfgimpl_descr, step).make_rest_doc( prefix).text() - checkrest(txt, fullpath + ".txt") + result[path] = checkrest(txt, fullpath + ".txt") + return result def test_simple(): descr = OptionDescription("foo", "doc", [ @@ -60,6 +62,22 @@ requires=[("a0.bar", "c"), ("a0.B2", True)]), ChoiceOption("bar", "more doc", ["a", "b", "c"], default="a")]) - generate_html(descr) - + result = generate_html(descr) + assert "more doc" in result[""] +def test_cmdline_overview(): + descr = OptionDescription("foo", "doc", [ + ChoiceOption("bar", "more doc", ["a", "b", "c"]), + OptionDescription("sub", "nope", [ + ChoiceOption("subbar", "", ["d", "f"]), + BoolOption("boolean", "this is a boolean", default=False, + cmdline="-b --with-b") + ]), + StrOption("str", "string option!", default="strange"), + IntOption("int", "integer option", default=42), + FloatOption("float", "float option", default=py.std.math.pi), + ArbitraryOption("surprise", "special", defaultfactory=int), + ]) + generate_html(descr) + c = make_cmdline_overview(descr) + checkrest(c.text(), "index.txt") Modified: pypy/branch/ast-experiments/pypy/config/translationoption.py ============================================================================== --- pypy/branch/ast-experiments/pypy/config/translationoption.py (original) +++ pypy/branch/ast-experiments/pypy/config/translationoption.py Mon Feb 26 08:45:45 2007 @@ -11,7 +11,7 @@ translation_optiondescription = OptionDescription( "translation", "Translation Options", [ - BoolOption("stackless", "compile stackless features in", + BoolOption("stackless", "enable stackless features during compilation", default=False, cmdline="--stackless", requires=[("translation.type_system", "lltype")]), ChoiceOption("type_system", "Type system to use when RTyping", @@ -30,7 +30,7 @@ "cl": [("translation.type_system", "ootype")], }, cmdline="-b --backend"), - BoolOption("llvm_via_c", "compile llvm bytecode via C", + BoolOption("llvm_via_c", "compile llvm via C", default=False, cmdline="--llvm-via-c", requires=[("translation.backend", "llvm")]), ChoiceOption("gc", "Garbage Collection Strategy", @@ -53,19 +53,16 @@ cmdline=None), # misc - StrOption("cc", "Specify compiler", cmdline="--cc"), + StrOption("cc", "Specify compiler to use for compiling generated C", cmdline="--cc"), StrOption("profopt", "Specify profile based optimization script", cmdline="--profopt"), - BoolOption("debug_transform", "Perform the debug transformation", - default=False, cmdline="--debug-transform", negation=False), - BoolOption("instrument", "internal: turn instrumentation on", default=False, cmdline=None), ArbitraryOption("instrumentctl", "internal", - default=None), + default=None), StrOption("output", "Output file name", cmdline="--output"), - + # portability options BoolOption("vanilla", "Try to be as portable as possible, which is not much", @@ -75,16 +72,23 @@ BoolOption("no__thread", "don't use __thread for implementing TLS", default=False, cmdline="--no__thread", negation=False), - StrOption("compilerflags", "Specify flags for the compiler", + StrOption("compilerflags", "Specify flags for the C compiler", cmdline="--cflags"), - StrOption("linkerflags", "Specify flags for the linker", + StrOption("linkerflags", "Specify flags for the linker (C backend only)", cmdline="--ldflags"), # Flags of the TranslationContext: BoolOption("simplifying", "Simplify flow graphs", default=True), - BoolOption("builtins_can_raise_exceptions", "XXX", default=False, + BoolOption("builtins_can_raise_exceptions", + "When true, assume any call to a 'simple' builtin such as " + "'hex' can raise an arbitrary exception", + default=False, cmdline=None), - BoolOption("list_comprehension_operations", "XXX", default=False, + BoolOption("list_comprehension_operations", + "When true, look for and special-case the sequence of " + "operations that results from a list comprehension and " + "attempt to pre-allocate the list", + default=False, cmdline=None), ChoiceOption("fork_before", "(UNIX) Create restartable checkpoint before step", @@ -102,13 +106,15 @@ "for inlining", default="pypy.translator.backendopt.inline.inlining_heuristic", cmdline="--inline-heuristic"), - + BoolOption("print_statistics", "Print statistics while optimizing", default=False), BoolOption("merge_if_blocks", "Merge if ... elif chains", cmdline="--if-block-merge", default=True), BoolOption("raisingop2direct_call", - "Transform exception raising operations", + "Transform operations that can implicitly raise an " + "exception into calls to functions that explicitly " + "raise exceptions", default=False, cmdline="--raisingop2direct_call"), BoolOption("mallocs", "Remove mallocs", default=True), BoolOption("constfold", "Constant propagation", @@ -133,7 +139,7 @@ cmdline="--prof-based-inline-heuristic"), # control clever malloc removal BoolOption("clever_malloc_removal", - "Drives inlining to remove mallocs in a clever way", + "Drives inlining to remove mallocs in a clever way", default=False, cmdline="--clever-malloc-removal"), FloatOption("clever_malloc_removal_threshold", @@ -148,8 +154,9 @@ cmdline="--clever-malloc-removal-heuristic"), BoolOption("remove_asserts", - "Kill 'raise AssertionError', which lets the C " - "optimizer remove the asserts", default=False), + "Remove operations that look like 'raise AssertionError', " + "which lets the C optimizer remove the asserts", + default=False), ]), OptionDescription("cli", "GenCLI options", [ Modified: pypy/branch/ast-experiments/pypy/conftest.py ============================================================================== --- pypy/branch/ast-experiments/pypy/conftest.py (original) +++ pypy/branch/ast-experiments/pypy/conftest.py Mon Feb 26 08:45:45 2007 @@ -8,10 +8,11 @@ rootdir = py.magic.autopath().dirpath() +# distributed testing settings dist_rsync_roots = ['.', '../lib-python', '../py', '../demo'] dist_rsync_ignore = ['_cache'] -# +# # PyPy's command line extra options (these are added # to py.test's standard options) # Modified: pypy/branch/ast-experiments/pypy/doc/_ref.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/_ref.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/_ref.txt Mon Feb 26 08:45:45 2007 @@ -11,6 +11,7 @@ .. _`bin/`: ../../pypy/bin .. _`config/`: ../../pypy/config .. _`doc/`: ../../pypy/doc +.. _`doc/config/`: ../../pypy/doc/config .. _`doc/discussion/`: ../../pypy/doc/discussion .. _`interpreter/`: .. _`pypy/interpreter`: ../../pypy/interpreter @@ -32,6 +33,7 @@ .. _`jit/`: ../../pypy/jit .. _`jit/codegen/`: ../../pypy/jit/codegen .. _`pypy/jit/codegen/model.py`: ../../pypy/jit/codegen/model.py +.. _`jit/goal/`: ../../pypy/jit/goal .. _`jit/hintannotator/`: ../../pypy/jit/hintannotator .. _`jit/timeshifter/`: ../../pypy/jit/timeshifter .. _`pypy/jit/timeshifter/rvalue.py`: ../../pypy/jit/timeshifter/rvalue.py @@ -41,8 +43,9 @@ .. _`lang/prolog/`: ../../pypy/lang/prolog .. _`lib/`: .. _`pypy/lib/`: ../../pypy/lib +.. _`lib/app_test/`: ../../pypy/lib/app_test +.. _`lib/distributed/`: ../../pypy/lib/distributed .. _`pypy/lib/stackless.py`: ../../pypy/lib/stackless.py -.. _`lib/test2/`: .. _`pypy/lib/test2`: ../../pypy/lib/test2 .. _`module/`: .. _`pypy/module`: @@ -56,6 +59,7 @@ .. _`pypy/module/readline`: ../../pypy/module/readline .. _`objspace/`: .. _`pypy/objspace`: ../../pypy/objspace +.. _`objspace/cpy/`: .. _`pypy/objspace/cpy`: ../../pypy/objspace/cpy .. _`objspace/dump.py`: ../../pypy/objspace/dump.py .. _`objspace/flow/`: ../../pypy/objspace/flow @@ -69,7 +73,6 @@ .. _`pypy/objspace/trace.py`: ../../pypy/objspace/trace.py .. _`pypy/rlib`: .. _`rlib/`: ../../pypy/rlib -.. _`pypy/rlib/objectmodel.py`: ../../pypy/rlib/objectmodel.py .. _`pypy/rlib/rarithmetic.py`: ../../pypy/rlib/rarithmetic.py .. _`pypy/rlib/rctypes/rctypesobject.py`: ../../pypy/rlib/rctypes/rctypesobject.py .. _`pypy/rlib/rctypes/test/test_rctypesobject.py`: ../../pypy/rlib/rctypes/test/test_rctypesobject.py @@ -83,10 +86,6 @@ .. _`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 -.. _`pypy/rpython/memory/simulator.py`: ../../pypy/rpython/memory/simulator.py -.. _`pypy/rpython/memory/support.py`: ../../pypy/rpython/memory/support.py .. _`pypy/rpython/module/`: ../../pypy/rpython/module .. _`pypy/rpython/module/ll_os.py`: ../../pypy/rpython/module/ll_os.py .. _`pypy/rpython/module/test`: ../../pypy/rpython/module/test @@ -102,7 +101,6 @@ .. _`tool/`: ../../pypy/tool .. _`tool/algo/`: ../../pypy/tool/algo .. _`tool/pytest/`: ../../pypy/tool/pytest -.. _`tool/tb_server/`: ../../pypy/tool/tb_server .. _`pypy/translator`: .. _`translator/`: ../../pypy/translator .. _`translator/backendopt/`: ../../pypy/translator/backendopt @@ -114,6 +112,7 @@ .. _`translator/cli/`: ../../pypy/translator/cli .. _`translator/goal/`: ../../pypy/translator/goal .. _`pypy/translator/goal/targetnopstandalone.py`: ../../pypy/translator/goal/targetnopstandalone.py +.. _`pypy/translator/goal/targetprologstandalone.py`: ../../pypy/translator/goal/targetprologstandalone.py .. _`translator/js/`: ../../pypy/translator/js .. _`translator/jvm/`: ../../pypy/translator/jvm .. _`translator/lisp/`: ../../pypy/translator/lisp Modified: pypy/branch/ast-experiments/pypy/doc/architecture.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/architecture.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/architecture.txt Mon Feb 26 08:45:45 2007 @@ -20,6 +20,10 @@ Eventually, dynamic optimization techniques - implemented as another translation aspect - should become robust against language changes. +As part of this process, we ended up developing a general +framework for implementing dynamic languages and generating +virtual machines for them `[VMC]_`. As proof of concepts, we +have a Prolog and an in-progress JavaScript interpreter. PyPy - an implementation of Python in Python ============================================ @@ -70,19 +74,28 @@ details. (Because of the nature of Python, this is already a complicated task, although not as much as writing it in - say - C.) Then we use this as a "language specification" and manipulate it to -produce the more traditional interpreters that we want. In the above -sense, we are generating the concrete "mappings" of Python into -lower-level target platforms. - -So far (autumn 2005), we have already succeeded in turning this "language -specification" into reasonably efficient C-level code that performs -basically the same job as CPython. Memory management is inserted during -this *translation* process. It can be configured to use reference -counting or not; thus we have already achieved two very different -mappings of application Python code over C/Posix. We have -successfully also translated our Python interpreter into LLVM_ code, -and we are working on targeting higher-level environments like -Java and Squeak. +produce the more traditional interpreters that we want. In other words, +we are generating concrete interpreters, all able to execute normal +Python code, but themselves running on a variety of lower-level +target platforms. + +So far (early 2007), we have already succeeded in turning this +"language specification" into reasonably efficient C-level +code that performs basically the same job as CPython (either +by generating C source, or via LLVM_). We can also generate a +Python interpreter for .NET, and a Java (JVM) version is on +its way. + +In addition to the platform diversity, we can generate very +diverse interpreters for each platform. Some of these +differences come from the inclusion of optional language +features or optimizations; but more fundamentally, and +particularly when targetting C-level environments, many +low-level details are inserted during this *translation* +process - for example, memory management: the generated code +can use the Boehm garbage collector, our custom collectors, or +a simple reference counting scheme. These are all different +concrete realisations of our "language specification". In some senses, PyPy project's central component is not its interpreter implementation, but its configurable translator. @@ -180,11 +193,13 @@ target platform; - the *code generator* which translates the resulting flow graph into - another language, currently C, LLVM_, Javascript (experimental). + another language, currently C, LLVM_, .NET, Javascript (in-progress) + or Java (JVM - in-progress). -A more complete description of the phases of this process is out of the -scope of the present introduction. We will only give in the sequel a -short overview. +A more complete description of the phases of this process is +out of the scope of the present introduction. For more +details, see the `translation document`_. We will only give a +short overview in the sequel. .. _`initialization time`: @@ -241,45 +256,25 @@ .. image:: image/translation-greyscale-small.png -The complete translation process is described in more details in the -`translation document`_. You might also be interested in reading the -more theoretically-oriented paper `Compiling dynamic language -implementations`_. - -Status of the implementation (June 2006) -========================================== - -The work leading up to the pypy-0.9.0 release has concentrated on the -features of the translation. - -We can now produce a pypy-c that `has the majority of the features`_ -of `Stackless Python`_. We have integrated the mark and sweep garbage -collector written in RPython by Carl Friedrich as part of Google's -Summer of Code 2005 with the translation machinery, and can produce a -pypy-c that uses it for memory management. - -.. _`has the majority of the features`: stackless.html -.. _`Stackless Python`: http://www.stackless.com/ - -The self-contained PyPy version (single-threaded and using the -`Boehm-Demers-Weiser garbage collector`_) now runs around 4-5 times -slower than CPython, i.e. around 3 times faster than 0.8.0. - -We have improved our CPython compatibility still further, and now pass -around 95% of CPython's core tests, the main improvement over 0.8.0 -being the implementation of the _weakref module. - -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 230,000 -lines of code including 62,000 lines of tests. Refer to -the `statistics web page`_ for more detailed information. + +Further reading +=============== + +* `[VMC]`_ PyPy's approach to virtual machine construction + (Dynamic Languages Symposium 2006). + +* The `translation document`_ describes our translation process in detail. + You might also be interested in reading the more + theoretically-oriented paper `Compiling dynamic language + implementations`_. + +* All our `Technical reports`_. + +* `Getting started`_ with PyPy. + .. _`statistics web page`: http://codespeak.net/~hpk/pypy-stat/ -.. _`very compliant`: http://codespeak.net/~hpk/pypy-testresult/ +.. _`very compliant`: http://www2.openend.se/~pedronis/pypy-c-test/allworkingmodules/summary.html .. _`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 @@ -288,6 +283,8 @@ .. _LLVM: http://llvm.org/ .. _`PDF color version`: image/translation.pdf .. _`getting started`: getting-started.html +.. _`[VMC]`: http://codespeak.net/svn/pypy/extradoc/talk/dls2006/pypy-vm-construction.pdf +.. _`Technical reports`: index-report.html .. include:: _ref.txt Modified: pypy/branch/ast-experiments/pypy/doc/cleanup-todo.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/cleanup-todo.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/cleanup-todo.txt Mon Feb 26 08:45:45 2007 @@ -19,3 +19,4 @@ - review the things implemented at applevel whether they are performance- critical + Modified: pypy/branch/ast-experiments/pypy/doc/cli-backend.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/cli-backend.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/cli-backend.txt Mon Feb 26 08:45:45 2007 @@ -427,5 +427,5 @@ .. _`Standard Ecma 335`: http://www.ecma-international.org/publications/standards/Ecma-335.htm -.. _`flow graph`: http://codespeak.net/pypy/dist/pypy/doc/translation.html#the-flow-model -.. _`rtyper`: http://codespeak.net/pypy/dist/pypy/doc/rtyper.html +.. _`flow graph`: translation.html#the-flow-model +.. _`rtyper`: rtyper.html Modified: pypy/branch/ast-experiments/pypy/doc/coding-guide.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/coding-guide.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/coding-guide.txt Mon Feb 26 08:45:45 2007 @@ -686,9 +686,12 @@ Only specified names will be exported to a Mixed Module's applevel namespace. -Sometimes it is neccessary to really write some functions in C (or whatever -target language). See the `external functions documentation`_ for details. +Sometimes it is necessary to really write some functions in C (or +whatever target language). See `rctypes`_ and `external functions +documentation`_ for details. The latter approach is cumbersome and +being phased out and former has currently quite a few rough edges. +.. _`rctypes`: rctypes.html .. _`external functions documentation`: translation.html#extfunccalls application level definitions Modified: pypy/branch/ast-experiments/pypy/doc/config/confrest.py ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/config/confrest.py (original) +++ pypy/branch/ast-experiments/pypy/doc/config/confrest.py Mon Feb 26 08:45:45 2007 @@ -1,5 +1,5 @@ from pypy.doc.confrest import * -import pypy.config.makerestdoc +from pypy.config.makerestdoc import make_cmdline_overview from pypy.config.config import Config from pypy.config import pypyoption, translationoption @@ -16,10 +16,10 @@ self.menubar[:] = html.div( html.a("general documentation", href="../index.html", class_="menu"), " ", - html.a("translation options", href="translation.html", - class_="menu"), - html.a("standard interpreter options", href="objspace.html", - class_="menu"), + html.a("config index", href="index.html", + class_="menu"), " ", + html.a("command-line overview", href="commandline.html", + class_="menu"), " ", " ", id="menubar") class Project(Project): @@ -29,10 +29,20 @@ Page = PyPyPage def get_content(self, txtpath, encoding): + if txtpath.basename == "commandline.txt": + result = [".. contents::"] + for descr in all_optiondescrs: + result.append(".. %s_:\n" % (descr._name, )) + result.append(make_cmdline_overview(descr).text()) + result.append("") + result.append(txtpath.read()) + return "\n".join(result) fullpath = txtpath.purebasename start = fullpath.split(".")[0] path = fullpath.rsplit(".", 1)[0] - basedescr = start_to_descr[start] + basedescr = start_to_descr.get(start) + if basedescr is None: + return txtpath.read() if fullpath.count(".") == 0: descr = basedescr path = "" @@ -43,6 +53,9 @@ descr = getattr(subconf._cfgimpl_descr, step) text = unicode(descr.make_rest_doc(path).text()) if txtpath.check(file=True): - return u"%s\n\n%s" % (text, unicode(txtpath.read(), encoding)) + content = txtpath.read() + if content: + text += "\nDescription\n===========" + return u"%s\n\n%s" % (text, unicode(txtpath.read(), encoding)) return text Modified: pypy/branch/ast-experiments/pypy/doc/config/objspace.allworkingmodules.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/config/objspace.allworkingmodules.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/config/objspace.allworkingmodules.txt Mon Feb 26 08:45:45 2007 @@ -1,2 +1,2 @@ This option enables the usage of all modules that are known to be working well -and that translate without problem. +and that translate without problems. Modified: pypy/branch/ast-experiments/pypy/doc/config/objspace.compiler.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/config/objspace.compiler.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/config/objspace.compiler.txt Mon Feb 26 08:45:45 2007 @@ -0,0 +1,3 @@ +Internal option. + +.. internal Modified: pypy/branch/ast-experiments/pypy/doc/config/objspace.logbytecodes.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/config/objspace.logbytecodes.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/config/objspace.logbytecodes.txt Mon Feb 26 08:45:45 2007 @@ -0,0 +1,3 @@ +Internal option. + +.. internal Modified: pypy/branch/ast-experiments/pypy/doc/config/objspace.lowmem.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/config/objspace.lowmem.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/config/objspace.lowmem.txt Mon Feb 26 08:45:45 2007 @@ -0,0 +1,4 @@ +Try to use as little memory as possible *during translation*. Currently only +disables :config:`objspace.geninterp` which also makes the resulting binary +slower. + Modified: pypy/branch/ast-experiments/pypy/doc/config/objspace.name.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/config/objspace.name.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/config/objspace.name.txt Mon Feb 26 08:45:45 2007 @@ -1,12 +1,13 @@ -Which `Object Space`_ to use. The `Standard Object Space`_ gives the +Determine which `Object Space`_ to use. The `Standard Object Space`_ gives the normal Python semantics, the others are `Object Space Proxies`_ giving additional features (except the Flow Object Space which is not intended for normal usage): - * thunk_: adds lazy evaluation to Python - * logic_: logical programming features - * taint_: soft security - * dump_: dump all operations to a log + * thunk_: The thunk object space adds lazy evaluation to PyPy. + * logic_: The logic object space contains logical programming features. + * taint_: The taint object space adds soft security features. + * dump_: Using this object spaces results in the dumpimp of all operations + to a log. .. _`Object Space`: ../objspace.html .. _`Object Space Proxies`: ../objspace-proxies.html Modified: pypy/branch/ast-experiments/pypy/doc/config/objspace.nofaking.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/config/objspace.nofaking.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/config/objspace.nofaking.txt Mon Feb 26 08:45:45 2007 @@ -0,0 +1,7 @@ +This options prevents the automagic borrowing of implementations of +modules and types not present in PyPy from CPython. + +As such, it is required when translating, as then there is no CPython +to borrow from. For running py.py it is useful for testing the +implementation of modules like "posix", but it makes everything even +slower than it is already. Modified: pypy/branch/ast-experiments/pypy/doc/config/objspace.opcodes.CALL_LIKELY_BUILTIN.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/config/objspace.opcodes.CALL_LIKELY_BUILTIN.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/config/objspace.opcodes.CALL_LIKELY_BUILTIN.txt Mon Feb 26 08:45:45 2007 @@ -1,7 +1,7 @@ Introduce a new opcode called ``CALL_LIKELY_BUILTIN``. It is used when something is called, that looks like a builtin function (but could in reality be shadowed -by something in the module globals). For all module globals dictionaries it is -then tracked, which builtin name is shadowed in this module. If the +by a name in the module globals). For all module globals dictionaries it is +then tracked which builtin name is shadowed in this module. If the ``CALL_LIKELY_BUILTIN`` opcode is executed, it is checked whether the builtin is shadowed. If not, the corresponding builtin is called. Otherwise the object that is shadowing it is called instead. If no shadowing is happening, this saves two Modified: pypy/branch/ast-experiments/pypy/doc/config/objspace.opcodes.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/config/objspace.opcodes.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/config/objspace.opcodes.txt Mon Feb 26 08:45:45 2007 @@ -0,0 +1 @@ +.. intentionally empty Modified: pypy/branch/ast-experiments/pypy/doc/config/objspace.parser.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/config/objspace.parser.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/config/objspace.parser.txt Mon Feb 26 08:45:45 2007 @@ -0,0 +1,3 @@ +Internal option. + +.. internal Modified: pypy/branch/ast-experiments/pypy/doc/config/objspace.std.methodcachesize.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/config/objspace.std.methodcachesize.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/config/objspace.std.methodcachesize.txt Mon Feb 26 08:45:45 2007 @@ -0,0 +1 @@ +Set the cache size (number of entries) for :config:`objspace.std.withmethodcache`. Modified: pypy/branch/ast-experiments/pypy/doc/config/objspace.std.optimized_int_add.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/config/objspace.std.optimized_int_add.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/config/objspace.std.optimized_int_add.txt Mon Feb 26 08:45:45 2007 @@ -0,0 +1,2 @@ +Optimize the addition of two integers a bit. Enabling this option gives small +speedups. Modified: pypy/branch/ast-experiments/pypy/doc/config/objspace.std.prebuiltintfrom.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/config/objspace.std.prebuiltintfrom.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/config/objspace.std.prebuiltintfrom.txt Mon Feb 26 08:45:45 2007 @@ -0,0 +1 @@ +see :config:`objspace.std.withprebuiltint`. Modified: pypy/branch/ast-experiments/pypy/doc/config/objspace.std.prebuiltintto.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/config/objspace.std.prebuiltintto.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/config/objspace.std.prebuiltintto.txt Mon Feb 26 08:45:45 2007 @@ -0,0 +1 @@ +See :config:`objspace.std.withprebuiltint`. Modified: pypy/branch/ast-experiments/pypy/doc/config/objspace.std.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/config/objspace.std.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/config/objspace.std.txt Mon Feb 26 08:45:45 2007 @@ -0,0 +1 @@ +.. intentionally empty Modified: pypy/branch/ast-experiments/pypy/doc/config/objspace.std.withdictmeasurement.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/config/objspace.std.withdictmeasurement.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/config/objspace.std.withdictmeasurement.txt Mon Feb 26 08:45:45 2007 @@ -0,0 +1,3 @@ +Internal option. + +.. internal Modified: pypy/branch/ast-experiments/pypy/doc/config/objspace.std.withfastslice.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/config/objspace.std.withfastslice.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/config/objspace.std.withfastslice.txt Mon Feb 26 08:45:45 2007 @@ -1,5 +1,7 @@ -A variant of multilists_ that makes list slicing copy the list lazily (that is -only when the original list or the slice are mutated. +A variant of :config:`objspace.std.withmultilist` that makes list slicing copy +the list lazily (that is only when the original list or the slice are mutated). +This is not perfectly well tested. +See the description of `object reimplementations`_ for more details. -.. _multilists: objspace.std.withmultilist.html +.. _`object reimplementations`: ../object-optimizations.html Modified: pypy/branch/ast-experiments/pypy/doc/config/objspace.std.withmethodcache.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/config/objspace.std.withmethodcache.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/config/objspace.std.withmethodcache.txt Mon Feb 26 08:45:45 2007 @@ -0,0 +1,3 @@ +Enable method caching. See the section "Method Caching" in `Alternative object +implementations in the PyPy standard interpreter +<../object-optimizations.html#method-caching>`__. Modified: pypy/branch/ast-experiments/pypy/doc/config/objspace.std.withmethodcachecounter.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/config/objspace.std.withmethodcachecounter.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/config/objspace.std.withmethodcachecounter.txt Mon Feb 26 08:45:45 2007 @@ -0,0 +1 @@ +Testing/debug option for :config:`objspace.std.withmethodcache`. Modified: pypy/branch/ast-experiments/pypy/doc/config/objspace.std.withmultidict.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/config/objspace.std.withmultidict.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/config/objspace.std.withmultidict.txt Mon Feb 26 08:45:45 2007 @@ -1,13 +1,8 @@ This enables "multidicts". They are a different implementation of the Python -``dict`` type, indistinguishable for the normal user (when using multidicts, the -normal implementation is not used at all). When the multidict implementation is -used, a dictionary can change its internal representation over its lifetime. It -starts with an "empty" representation (that can represent only empty dicts). If -a few keys are added, it changes its representation to a "small" one (that is -optimized for small dicts). As long as only string keys are added, a -representation optimized for string keys is used. Since this case is extremely -common in Python, this makes multidicts a good deal faster than the regular -dictionary implementation. +``dict`` type, indistinguishable for the normal user (when using multidicts, +the normal implementation is not used at all). The flexibility of multidicts +is used by a couple of other, even more advanced object implementations. -The flexibility of multidicts is used by a couple of other, even more advanced -object implementations. +See the description of `object reimplementations`_ for more details. + +.. _`object reimplementations`: ../object-optimizations.html Modified: pypy/branch/ast-experiments/pypy/doc/config/objspace.std.withmultilist.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/config/objspace.std.withmultilist.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/config/objspace.std.withmultilist.txt Mon Feb 26 08:45:45 2007 @@ -1,11 +1,8 @@ This enables "multilists". They are a different implementation of the Python ``list`` type, indistinguishable for the normal user (when using multilists, the -normal implementation is not used at all). When the multilist implementation is -used, a list can change its internal representation over its lifetime. If a list -contains only strings, for example, the strings are stored directly without -their wrapper (which gives a memory benefit on large lists). +normal implementation is not used at all). -Another special representation of lists that multilists support is the "range -list", which is basically equivalent to what `objspace.std.withrangelist`_ does. +See the page about `object reimplementations`_ for more details. + +.. _`object reimplementations`: ../object-optimizations.html -.. _`objspace.std.withrangelist`: objspace.std.withrangelist.html Modified: pypy/branch/ast-experiments/pypy/doc/config/objspace.std.withprebuiltint.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/config/objspace.std.withprebuiltint.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/config/objspace.std.withprebuiltint.txt Mon Feb 26 08:45:45 2007 @@ -1,6 +1,5 @@ This option enables the caching of small integer objects (similar to what -CPython does). The range of which integers are cached can be influenced with the -`objspace.std.prebuiltintfrom`_ and `objspace.std.prebuiltintto`_ options. +CPython does). The range of which integers are cached can be influenced with +the :config:`objspace.std.prebuiltintfrom` and +:config:`objspace.std.prebuiltintto` options. -.. _`objspace.std.prebuiltintfrom`: objspace.std.prebuiltintfrom.html -.. _`objspace.std.prebuiltintto`: objspace.std.prebuiltintto.html Modified: pypy/branch/ast-experiments/pypy/doc/config/objspace.std.withrangelist.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/config/objspace.std.withrangelist.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/config/objspace.std.withrangelist.txt Mon Feb 26 08:45:45 2007 @@ -4,3 +4,8 @@ mutated (and for example only iterated over), it uses only enough memory to store the start, stop and step of the range. This makes using ``range`` as efficient as ``xrange``, as long as the result is only used in a ``for``-loop. + +See the page about `object reimplementations`_ for more details. + +.. _`object reimplementations`: ../object-optimizations.html + Modified: pypy/branch/ast-experiments/pypy/doc/config/objspace.std.withsharingdict.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/config/objspace.std.withsharingdict.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/config/objspace.std.withsharingdict.txt Mon Feb 26 08:45:45 2007 @@ -1,13 +1,6 @@ -Enable "sharing dictionaries". They are a special dict representation used -together with `multidicts`_. This dict representation is used only for instance -dictionaries and tries to make instance dictionaries use less memory (in fact, -in the ideal case the memory behaviour should be mostly like that of using -__slots__). +Enable "sharing dictionaries". -The idea is the following: Most instances of the same class have very similar -attributes. Therefore all the instance dictionaries of these instances all store -the same keys. To save memory, these common keys could be stored in a common -place. This is exactly what "sharing dictionaries" are doing: only the values -themselves are stored on the instance, the rest in a shared structure. +See the page about `object optimizations`_ for more details. + +.. _`object optimizations`: ../object-optimizations.html -.. _`multidicts`: objspace.std.withmultidict.html Modified: pypy/branch/ast-experiments/pypy/doc/config/objspace.std.withstrdict.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/config/objspace.std.withstrdict.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/config/objspace.std.withstrdict.txt Mon Feb 26 08:45:45 2007 @@ -0,0 +1 @@ +Obsolete. See :config:`objspace.std.withmultidict` instead. Modified: pypy/branch/ast-experiments/pypy/doc/config/objspace.std.withstrjoin.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/config/objspace.std.withstrjoin.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/config/objspace.std.withstrjoin.txt Mon Feb 26 08:45:45 2007 @@ -1,7 +1,7 @@ -Enable "string join" objects. They are a different implementation of the Python -``str`` type, indistinguishable for the normal user. They represent the lazy -addition of several strings without actually performing the addition (which -involves copying etc.). When the actual value of the string join object is -needed, the addition is performed. This makes it possible efficiently perform -string additions in a loop without using the ``"".join(list_of_strings)`` -pattern. +Enable "string join" objects. + +See the page about `object optimizations`_ for more details. + +.. _`object optimizations`: ../object-optimizations.html + + Modified: pypy/branch/ast-experiments/pypy/doc/config/objspace.std.withstrslice.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/config/objspace.std.withstrslice.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/config/objspace.std.withstrslice.txt Mon Feb 26 08:45:45 2007 @@ -1,8 +1,7 @@ -Enable "string slice" objects. They are a different implementation of the Python -``str`` type, indistinguishable for the normal user. They represent the lazy -slicing of a string without actually performing the slicing (which involves -copying). This is only done for slices of step one. When the actual value of -the string slice object is needed, the slicing is done (although a lot of string -methods don't make this necessary). This makes string slicing a very efficient -operation. It also saves memory in some cases but can also lead to memory leaks, -since the string slice retains a reference to the original string. +Enable "string slice" objects. + +See the page about `object optimizations`_ for more details. + +.. _`object optimizations`: ../object-optimizations.html + + Modified: pypy/branch/ast-experiments/pypy/doc/config/objspace.std.withtypeversion.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/config/objspace.std.withtypeversion.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/config/objspace.std.withtypeversion.txt Mon Feb 26 08:45:45 2007 @@ -2,3 +2,5 @@ (only internally visible) version that is updated when the type's dict is changed. This is e.g. used for invalidating caches. It does not make sense to enable this option alone. + +.. internal Modified: pypy/branch/ast-experiments/pypy/doc/config/objspace.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/config/objspace.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/config/objspace.txt Mon Feb 26 08:45:45 2007 @@ -0,0 +1 @@ +.. intentionally empty Modified: pypy/branch/ast-experiments/pypy/doc/config/objspace.usemodules._codecs.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/config/objspace.usemodules._codecs.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/config/objspace.usemodules._codecs.txt Mon Feb 26 08:45:45 2007 @@ -1,2 +1,2 @@ Use the '_codecs' module. -This module is expected to be working and is included by default. +Used by the 'codecs' standard lib module. This module is expected to be working and is included by default. Modified: pypy/branch/ast-experiments/pypy/doc/config/objspace.usemodules._demo.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/config/objspace.usemodules._demo.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/config/objspace.usemodules._demo.txt Mon Feb 26 08:45:45 2007 @@ -1 +1,5 @@ Use the '_demo' module. + +This is the demo module for the `extension compiler`_. Not enabled by default. + +.. _`extension compiler`: ../extcompiler.html Modified: pypy/branch/ast-experiments/pypy/doc/config/objspace.usemodules._file.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/config/objspace.usemodules._file.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/config/objspace.usemodules._file.txt Mon Feb 26 08:45:45 2007 @@ -1,2 +1,4 @@ -Use the '_file' module. -This module is essential, included by default and should not be removed. +Use the '_file' module. It is an internal module that contains helper +functionality for the builtin ``file`` type. + +.. internal Modified: pypy/branch/ast-experiments/pypy/doc/config/objspace.usemodules._pickle_support.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/config/objspace.usemodules._pickle_support.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/config/objspace.usemodules._pickle_support.txt Mon Feb 26 08:45:45 2007 @@ -1,2 +1,6 @@ Use the '_pickle_support' module. -This module is expected to be working and is included by default. +Internal helpers for pickling runtime builtin types (frames, cells, etc) +for `stackless`_ tasklet pickling support. +.. _`stackless`: ../stackless.html + +.. internal Modified: pypy/branch/ast-experiments/pypy/doc/config/objspace.usemodules._random.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/config/objspace.usemodules._random.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/config/objspace.usemodules._random.txt Mon Feb 26 08:45:45 2007 @@ -1,2 +1,2 @@ -Use the '_random' module. +Use the '_random' module. It is necessary to use the module "random" from the standard library. This module is expected to be working and is included by default. Modified: pypy/branch/ast-experiments/pypy/doc/config/objspace.usemodules._stackless.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/config/objspace.usemodules._stackless.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/config/objspace.usemodules._stackless.txt Mon Feb 26 08:45:45 2007 @@ -1 +1,6 @@ Use the '_stackless' module. + +Exposes the `stackless` primitives, and also implies a stackless build. +See also :config:`translation.stackless`. + +.. _`stackless`: ../stackless.html Modified: pypy/branch/ast-experiments/pypy/doc/config/objspace.usemodules._weakref.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/config/objspace.usemodules._weakref.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/config/objspace.usemodules._weakref.txt Mon Feb 26 08:45:45 2007 @@ -1,2 +1,6 @@ -Use the '_weakref' module. -This module is expected to be working and is included by default. +Use the '_weakref' module, necessary for the standard lib 'weakref' module. +PyPy's weakref implementation is not completely stable yet. The first +difference to CPython is that weak references only go away after the next +garbage collection, not immediately. The other problem seems to be that under +certain circumstances (that we have not determined) weak references keep the +object alive. Modified: pypy/branch/ast-experiments/pypy/doc/config/objspace.usemodules.bz2.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/config/objspace.usemodules.bz2.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/config/objspace.usemodules.bz2.txt Mon Feb 26 08:45:45 2007 @@ -1,2 +1,3 @@ Use the 'bz2' module. -This module is expected to be fully working. +This module is working "sometimes". It fails to build on 64 bit machines and +can have issues on 32 bit machines. Modified: pypy/branch/ast-experiments/pypy/doc/config/objspace.usemodules.posix.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/config/objspace.usemodules.posix.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/config/objspace.usemodules.posix.txt Mon Feb 26 08:45:45 2007 @@ -1,2 +1,3 @@ -Use the 'posix' module. -This module is essential, included by default and should not be removed. +Use the essential 'posix' module. +This module is essential, included by default and cannot be removed (even when +specified explicitly, the option gets overriden later). Modified: pypy/branch/ast-experiments/pypy/doc/config/objspace.usemodules.pypymagic.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/config/objspace.usemodules.pypymagic.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/config/objspace.usemodules.pypymagic.txt Mon Feb 26 08:45:45 2007 @@ -1,2 +1,7 @@ Use the 'pypymagic' module. This module is expected to be working and is included by default. +It contains special (sometimes slightly magic) PyPy-specific functionality. +For example most of the special functions described in the `object space proxies` +document are in the module. + +.. _`object space proxy`: ../objspace-proxies.html Modified: pypy/branch/ast-experiments/pypy/doc/config/objspace.usemodules.rctime.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/config/objspace.usemodules.rctime.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/config/objspace.usemodules.rctime.txt Mon Feb 26 08:45:45 2007 @@ -1,2 +1,7 @@ Use the 'rctime' module. -This module is expected to be fully working. + +'rctime' is our `rctypes`_ based implementation of the builtin 'time' module. +It supersedes the less complete :config:`objspace.usemodules.time`, +at least for C-like targets (the C and LLVM backends). + +.. _`rctypes`: ../rctypes.html Modified: pypy/branch/ast-experiments/pypy/doc/config/objspace.usemodules.recparser.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/config/objspace.usemodules.recparser.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/config/objspace.usemodules.recparser.txt Mon Feb 26 08:45:45 2007 @@ -1,2 +1,4 @@ Use the 'recparser' module. -This module is expected to be working and is included by default. +This is PyPy implementation of the standard library 'parser' module (e.g. if +this option is enabled and you say ``import parser`` you get this module). +It is enabled by default. Modified: pypy/branch/ast-experiments/pypy/doc/config/objspace.usemodules.rsocket.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/config/objspace.usemodules.rsocket.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/config/objspace.usemodules.rsocket.txt Mon Feb 26 08:45:45 2007 @@ -1,2 +1,7 @@ Use the 'rsocket' module. -This module is expected to be fully working. + +This is our implementation of '_socket', the Python builtin module +exposing socket primitives, which is wrapped and used by the standard +library 'socket.py' module. 'rsocket' is based on `rctypes`_. + +.. _`rctypes`: ../rctypes.html Modified: pypy/branch/ast-experiments/pypy/doc/config/objspace.usemodules.time.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/config/objspace.usemodules.time.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/config/objspace.usemodules.time.txt Mon Feb 26 08:45:45 2007 @@ -1 +1,4 @@ Use the 'time' module. + +Obsolete; use :config:`objspace.usemodules.rctime` for our up-to-date version +of the application-level 'time' module. Modified: pypy/branch/ast-experiments/pypy/doc/config/objspace.usemodules.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/config/objspace.usemodules.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/config/objspace.usemodules.txt Mon Feb 26 08:45:45 2007 @@ -0,0 +1 @@ +.. intentionally empty Modified: pypy/branch/ast-experiments/pypy/doc/config/objspace.usepycfiles.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/config/objspace.usepycfiles.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/config/objspace.usepycfiles.txt Mon Feb 26 08:45:45 2007 @@ -1,3 +1,4 @@ -Whether PyPy should import and generate "pyc" files. This is mostly always on, +If this option is used, then PyPy imports and generates "pyc" files in the +usual way. This is mostly always on, except when using other options that lead to PyPy-specific bytecodes that should not be cached on disk because they might confuse CPython. Modified: pypy/branch/ast-experiments/pypy/doc/config/translation.backend.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/config/translation.backend.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/config/translation.backend.txt Mon Feb 26 08:45:45 2007 @@ -0,0 +1,3 @@ +Which backend to use when translating, see `translation documentation`. + +.. _`translation documentation`: ../translation.html Modified: pypy/branch/ast-experiments/pypy/doc/config/translation.backendopt.clever_malloc_removal.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/config/translation.backendopt.clever_malloc_removal.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/config/translation.backendopt.clever_malloc_removal.txt Mon Feb 26 08:45:45 2007 @@ -0,0 +1,10 @@ +Try to inline flowgraphs based on whether doing so would enable malloc +removal (:config:`translation.backendopt.mallocs`.) by eliminating +calls that result in escaping. This is an experimental optimisation, +also right now some eager inlining is necessary for helpers doing +malloc itself to be inlined first for this to be effective. +This option enable also an extra subsequent malloc removal phase. + +Callee flowgraphs are considered candidates based on a weight heuristic like +for basic inlining. (see :config:`translation.backendopt.inline`, +:config:`translation.backendopt.clever_malloc_removal_threshold` ). Modified: pypy/branch/ast-experiments/pypy/doc/config/translation.backendopt.clever_malloc_removal_heuristic.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/config/translation.backendopt.clever_malloc_removal_heuristic.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/config/translation.backendopt.clever_malloc_removal_heuristic.txt Mon Feb 26 08:45:45 2007 @@ -0,0 +1,4 @@ +Internal option. Switch to a different weight heuristic for inlining. +This is for clever malloc removal (:config:`translation.backendopt.clever_malloc_removal`). + +.. internal Modified: pypy/branch/ast-experiments/pypy/doc/config/translation.backendopt.clever_malloc_removal_threshold.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/config/translation.backendopt.clever_malloc_removal_threshold.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/config/translation.backendopt.clever_malloc_removal_threshold.txt Mon Feb 26 08:45:45 2007 @@ -0,0 +1,2 @@ +Weight threshold used to decide whether to inline flowgraphs. +This is for clever malloc removal (:config:`translation.backendopt.clever_malloc_removal`). Modified: pypy/branch/ast-experiments/pypy/doc/config/translation.backendopt.constfold.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/config/translation.backendopt.constfold.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/config/translation.backendopt.constfold.txt Mon Feb 26 08:45:45 2007 @@ -0,0 +1 @@ +Do constant folding of operations and constant propagation on flowgraphs. Modified: pypy/branch/ast-experiments/pypy/doc/config/translation.backendopt.heap2stack.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/config/translation.backendopt.heap2stack.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/config/translation.backendopt.heap2stack.txt Mon Feb 26 08:45:45 2007 @@ -0,0 +1,2 @@ +Experimental optimisation, not very tested nor used at the moment. + Modified: pypy/branch/ast-experiments/pypy/doc/config/translation.backendopt.inline.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/config/translation.backendopt.inline.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/config/translation.backendopt.inline.txt Mon Feb 26 08:45:45 2007 @@ -0,0 +1,10 @@ +Inline flowgraphs based on an heuristic, the default one considers +essentially the a weight for the flowgraph based on the number of +low-level operations in them (see +:config:`translation.backendopt.inline_threshold` ). + +Some amount of inlining in order to have RPython builtin type helpers +inlined is needed for malloc removal +(:config:`translation.backendopt.mallocs`) to be effective. + +This optimisation is used by default. Modified: pypy/branch/ast-experiments/pypy/doc/config/translation.backendopt.inline_heuristic.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/config/translation.backendopt.inline_heuristic.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/config/translation.backendopt.inline_heuristic.txt Mon Feb 26 08:45:45 2007 @@ -0,0 +1,4 @@ +Internal option. Switch to a different weight heuristic for inlining. +This is for basic inlining (:config:`translation.backendopt.inline`). + +.. internal Modified: pypy/branch/ast-experiments/pypy/doc/config/translation.backendopt.inline_threshold.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/config/translation.backendopt.inline_threshold.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/config/translation.backendopt.inline_threshold.txt Mon Feb 26 08:45:45 2007 @@ -0,0 +1,2 @@ +Weight threshold used to decide whether to inline flowgraphs. +This is for basic inlining (:config:`translation.backendopt.inline`). Modified: pypy/branch/ast-experiments/pypy/doc/config/translation.backendopt.mallocs.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/config/translation.backendopt.mallocs.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/config/translation.backendopt.mallocs.txt Mon Feb 26 08:45:45 2007 @@ -0,0 +1,29 @@ +This optimization enables "malloc removal", which "explodes" +allocations of structures which do not escape from the function they +are allocated in into one or more additional local variables. + +An example. Consider this rather unlikely seeming code:: + + class C: + pass + def f(y): + c = C() + c.x = y + return c.x + +Malloc removal will spot that the ``C`` object can never leave ``f`` +and replace the above with code like this:: + + def f(y): + _c__x = y + return _c__x + +It is rare for code to be directly written in a way that allows this +optimization to be useful, but inlining often results in opportunities +for its use (and indeed, this is one of the main reasons PyPy does its +own inlining rather than relying on the C compilers). + +For much more information about this and other optimizations you can +read section 4.1 of the `technical report on "Massive Parallelism and +Translation Aspects" +`__. Modified: pypy/branch/ast-experiments/pypy/doc/config/translation.backendopt.merge_if_blocks.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/config/translation.backendopt.merge_if_blocks.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/config/translation.backendopt.merge_if_blocks.txt Mon Feb 26 08:45:45 2007 @@ -0,0 +1,26 @@ +This optimization converts parts of flow graphs that result from +chains of ifs and elifs like this into merged blocks. + +By default flow graphing this kind of code:: + + if x == 0: + f() + elif x == 1: + g() + elif x == 4: + h() + else: + j() + +will result in a chain of blocks with two exits, somewhat like this: + +.. image:: unmergedblocks.png + +(reflecting how Python would interpret this code). Running this +optimization will transform the block structure to contain a single +"choice block" with four exits: + +.. image:: mergedblocks.png + +This can then be turned into a switch by the C backend, allowing the C +compiler to produce more efficient code. Modified: pypy/branch/ast-experiments/pypy/doc/config/translation.backendopt.print_statistics.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/config/translation.backendopt.print_statistics.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/config/translation.backendopt.print_statistics.txt Mon Feb 26 08:45:45 2007 @@ -0,0 +1,2 @@ +Debugging option. Print statics about the forest of flowgraphs as they +go through the various backend optimisations. \ No newline at end of file Modified: pypy/branch/ast-experiments/pypy/doc/config/translation.backendopt.profile_based_inline.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/config/translation.backendopt.profile_based_inline.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/config/translation.backendopt.profile_based_inline.txt Mon Feb 26 08:45:45 2007 @@ -0,0 +1,10 @@ +Inline flowgraphs only for call-sites for which there was a minimal +number of calls during an instrumented run of the program. Callee +flowgraphs are considered candidates based on a weight heuristic like +for basic inlining. (see :config:`translation.backendopt.inline`, +:config:`translation.backendopt.profile_based_inline_threshold` ). + +The option takes as value a string which is the arguments to pass to +the program for the instrumented run. + +This optimisation is not used by default. \ No newline at end of file Modified: pypy/branch/ast-experiments/pypy/doc/config/translation.backendopt.profile_based_inline_heuristic.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/config/translation.backendopt.profile_based_inline_heuristic.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/config/translation.backendopt.profile_based_inline_heuristic.txt Mon Feb 26 08:45:45 2007 @@ -0,0 +1,4 @@ +Internal option. Switch to a different weight heuristic for inlining. +This is for profile-based inlining (:config:`translation.backendopt.profile_based_inline`). + +.. internal Modified: pypy/branch/ast-experiments/pypy/doc/config/translation.backendopt.profile_based_inline_threshold.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/config/translation.backendopt.profile_based_inline_threshold.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/config/translation.backendopt.profile_based_inline_threshold.txt Mon Feb 26 08:45:45 2007 @@ -0,0 +1,2 @@ +Weight threshold used to decide whether to inline flowgraphs. +This is for profile-based inlining (:config:`translation.backendopt.profile_based_inline`). Modified: pypy/branch/ast-experiments/pypy/doc/config/translation.backendopt.raisingop2direct_call.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/config/translation.backendopt.raisingop2direct_call.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/config/translation.backendopt.raisingop2direct_call.txt Mon Feb 26 08:45:45 2007 @@ -0,0 +1,3 @@ +Internal option. Transformation required by the LLVM backend. + +.. internal Modified: pypy/branch/ast-experiments/pypy/doc/config/translation.backendopt.remove_asserts.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/config/translation.backendopt.remove_asserts.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/config/translation.backendopt.remove_asserts.txt Mon Feb 26 08:45:45 2007 @@ -0,0 +1 @@ +Remove raising of assertions from the flowgraphs, which might give small speedups. Modified: pypy/branch/ast-experiments/pypy/doc/config/translation.backendopt.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/config/translation.backendopt.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/config/translation.backendopt.txt Mon Feb 26 08:45:45 2007 @@ -0,0 +1,5 @@ +This group contains options about various backend optimization passes. Most of +them are described in the `EU report about optimization`_ + +.. _`EU report about optimization`: http://codespeak.net/pypy/extradoc/eu-report/D07.1_Massive_Parallelism_and_Translation_Aspects-2006-12-15.pdf + Modified: pypy/branch/ast-experiments/pypy/doc/config/translation.builtins_can_raise_exceptions.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/config/translation.builtins_can_raise_exceptions.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/config/translation.builtins_can_raise_exceptions.txt Mon Feb 26 08:45:45 2007 @@ -0,0 +1,3 @@ +Internal option. + +.. internal Modified: pypy/branch/ast-experiments/pypy/doc/config/translation.cc.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/config/translation.cc.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/config/translation.cc.txt Mon Feb 26 08:45:45 2007 @@ -0,0 +1 @@ +Specify which C compiler to use. Modified: pypy/branch/ast-experiments/pypy/doc/config/translation.cli.trace_calls.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/config/translation.cli.trace_calls.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/config/translation.cli.trace_calls.txt Mon Feb 26 08:45:45 2007 @@ -0,0 +1,3 @@ +Internal. Debugging aid for the CLI backend. + +.. internal Modified: pypy/branch/ast-experiments/pypy/doc/config/translation.cli.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/config/translation.cli.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/config/translation.cli.txt Mon Feb 26 08:45:45 2007 @@ -0,0 +1 @@ +.. intentionally empty Modified: pypy/branch/ast-experiments/pypy/doc/config/translation.compilerflags.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/config/translation.compilerflags.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/config/translation.compilerflags.txt Mon Feb 26 08:45:45 2007 @@ -0,0 +1 @@ +Experimental. Specify extra flags to pass to the C compiler. Modified: pypy/branch/ast-experiments/pypy/doc/config/translation.countmallocs.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/config/translation.countmallocs.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/config/translation.countmallocs.txt Mon Feb 26 08:45:45 2007 @@ -0,0 +1,4 @@ +Internal; used by some of the C backend tests to check that the number of +allocations matches the number of frees. + +.. internal Modified: pypy/branch/ast-experiments/pypy/doc/config/translation.debug.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/config/translation.debug.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/config/translation.debug.txt Mon Feb 26 08:45:45 2007 @@ -0,0 +1,2 @@ +Record extra debugging information during annotation. This leads to slightly +less obscure error messages. Modified: pypy/branch/ast-experiments/pypy/doc/config/translation.fork_before.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/config/translation.fork_before.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/config/translation.fork_before.txt Mon Feb 26 08:45:45 2007 @@ -0,0 +1,4 @@ +This is an option mostly useful when working on the PyPy toolchain. If you use +it, translate.py will fork before the specified phase. If the translation +crashes after that fork, you can fix the bug in the toolchain, and continue +translation at the fork-point. Modified: pypy/branch/ast-experiments/pypy/doc/config/translation.gc.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/config/translation.gc.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/config/translation.gc.txt Mon Feb 26 08:45:45 2007 @@ -0,0 +1,15 @@ +Choose the Garbage Collector used by the translated program: + + - "ref": reference counting. Takes very long to translate and the result is + slow. + + - "framework": our custom mark-and-sweep collector. Takes moderately long and + is the fastest option without external dependencies. + + - "stacklessgc": same as "framework" but uses a different method to find the + garbage collection roots on the stack, by unwinding it, using stackless: + :config:`translation.stackless`. + + - "boehm": use the Boehm conservative GC + + Modified: pypy/branch/ast-experiments/pypy/doc/config/translation.insist.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/config/translation.insist.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/config/translation.insist.txt Mon Feb 26 08:45:45 2007 @@ -0,0 +1,4 @@ +Don't stop on the first `rtyping`_ error. Instead, try to rtype as much as +possible and show the collected error messages in the end. + +.. _`rtyping`: ../rtyper.html Modified: pypy/branch/ast-experiments/pypy/doc/config/translation.instrument.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/config/translation.instrument.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/config/translation.instrument.txt Mon Feb 26 08:45:45 2007 @@ -0,0 +1,3 @@ +Internal option. + +.. internal Modified: pypy/branch/ast-experiments/pypy/doc/config/translation.instrumentctl.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/config/translation.instrumentctl.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/config/translation.instrumentctl.txt Mon Feb 26 08:45:45 2007 @@ -0,0 +1,3 @@ +Internal option. + +.. internal Modified: pypy/branch/ast-experiments/pypy/doc/config/translation.linkerflags.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/config/translation.linkerflags.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/config/translation.linkerflags.txt Mon Feb 26 08:45:45 2007 @@ -0,0 +1 @@ +Experimental. Specify extra flags to pass to the linker. Modified: pypy/branch/ast-experiments/pypy/doc/config/translation.list_comprehension_operations.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/config/translation.list_comprehension_operations.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/config/translation.list_comprehension_operations.txt Mon Feb 26 08:45:45 2007 @@ -0,0 +1,2 @@ +Experimental optimisation for list comprehensions in RPython. + Modified: pypy/branch/ast-experiments/pypy/doc/config/translation.llvm_via_c.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/config/translation.llvm_via_c.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/config/translation.llvm_via_c.txt Mon Feb 26 08:45:45 2007 @@ -0,0 +1,6 @@ +This options compiles LLVM code by using llc to convert it to C, then +using gcc to compile this C instead of using LLVM's own code +generators. This generally results in better performance +(particularly when using :config:`translation.profopt` to use gcc's +profile-directed optimizations) but takes rather longer and uses more +RAM. Modified: pypy/branch/ast-experiments/pypy/doc/config/translation.no__thread.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/config/translation.no__thread.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/config/translation.no__thread.txt Mon Feb 26 08:45:45 2007 @@ -0,0 +1,4 @@ +Don't use gcc __thread attribute for fast thread local storage +implementation . Increases the chance that moving the resulting +executable to another same processor Linux machine will work. (see +:config:`translation.vanilla`). Modified: pypy/branch/ast-experiments/pypy/doc/config/translation.output.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/config/translation.output.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/config/translation.output.txt Mon Feb 26 08:45:45 2007 @@ -0,0 +1 @@ +Specify file name that the produced executable gets. Modified: pypy/branch/ast-experiments/pypy/doc/config/translation.profopt.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/config/translation.profopt.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/config/translation.profopt.txt Mon Feb 26 08:45:45 2007 @@ -0,0 +1,5 @@ +Use GCCs profile-guided optimizations. This option specifies the the +arguments with which to call pypy-c (and in general the translated +RPython program) to gather profile data. Example for pypy-c: "-c 'from +richards import main;main(); from test import pystone; +pystone.main()'" Modified: pypy/branch/ast-experiments/pypy/doc/config/translation.simplifying.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/config/translation.simplifying.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/config/translation.simplifying.txt Mon Feb 26 08:45:45 2007 @@ -0,0 +1,3 @@ +Internal option. + +.. internal Modified: pypy/branch/ast-experiments/pypy/doc/config/translation.stackless.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/config/translation.stackless.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/config/translation.stackless.txt Mon Feb 26 08:45:45 2007 @@ -0,0 +1,5 @@ +Run the `stackless transform`_ on each generated graph, which enables the use +of coroutines at RPython level and the "stackless" module when translating +PyPy. + +.. _`stackless transform`: ../stackless.html Modified: pypy/branch/ast-experiments/pypy/doc/config/translation.thread.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/config/translation.thread.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/config/translation.thread.txt Mon Feb 26 08:45:45 2007 @@ -0,0 +1,2 @@ +Enable threading. The only target where this has visible effect is PyPy (this +also enables the ``thread`` module then). Modified: pypy/branch/ast-experiments/pypy/doc/config/translation.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/config/translation.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/config/translation.txt Mon Feb 26 08:45:45 2007 @@ -0,0 +1 @@ +.. intentionally empty Modified: pypy/branch/ast-experiments/pypy/doc/config/translation.type_system.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/config/translation.type_system.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/config/translation.type_system.txt Mon Feb 26 08:45:45 2007 @@ -0,0 +1,4 @@ +Which type system to use when rtyping_. This option should not be set +explicitely. + +.. _rtyping: ../rtyper.html Modified: pypy/branch/ast-experiments/pypy/doc/config/translation.vanilla.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/config/translation.vanilla.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/config/translation.vanilla.txt Mon Feb 26 08:45:45 2007 @@ -0,0 +1,2 @@ +Try to make the resulting compiled program as portable (=moveable to another +machine) as possible. Which is not much. Modified: pypy/branch/ast-experiments/pypy/doc/config/translation.verbose.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/config/translation.verbose.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/config/translation.verbose.txt Mon Feb 26 08:45:45 2007 @@ -0,0 +1 @@ +Print some more information during translation. Modified: pypy/branch/ast-experiments/pypy/doc/config/translation.withsmallfuncsets.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/config/translation.withsmallfuncsets.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/config/translation.withsmallfuncsets.txt Mon Feb 26 08:45:45 2007 @@ -0,0 +1,3 @@ +Represent function sets smaller than this option's value as an integer instead +of a function pointer. A call is then done via a switch on that integer, which +allows inlining etc. Small numbers for this can speed up PyPy (try 5). Modified: pypy/branch/ast-experiments/pypy/doc/configuration.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/configuration.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/configuration.txt Mon Feb 26 08:45:45 2007 @@ -183,7 +183,7 @@ =================================== The two large parts of PyPy, the standard interpreter and the translation -toolchain, have too separate sets of options. The translation toolchain options +toolchain, have two separate sets of options. The translation toolchain options can be found on the ``config`` attribute of all ``TranslationContext`` instances and are described in translationoption.py_. The interpreter options are attached to the object space, also under the name ``config`` and are Modified: pypy/branch/ast-experiments/pypy/doc/confrest.py ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/confrest.py (original) +++ pypy/branch/ast-experiments/pypy/doc/confrest.py Mon Feb 26 08:45:45 2007 @@ -4,19 +4,29 @@ class PyPyPage(Page): def fill_menubar(self): self.menubar = html.div( - html.a("news", href="news.html", class_="menu"), " ", - html.a("getting-started", - href="getting-started.html", class_="menu"), " ", - html.a("documentation", href="index.html", class_="menu"), " ", - html.a("svn", href="https://codespeak.net/viewvc/pypy/dist/", class_="menu"), " ", - html.a("issues", - href="https://codespeak.net/issue/pypy-dev/", - class_="menu"), - html.a("contact", href="contact.html", class_="menu"), " ", - html.a("EU/project", + html.a("news", + href="http://codespeak.net/pypy/dist/pypy/doc/news.html", + class_="menu"), " ", + html.a("getting-started", + href=self.get_doclink("getting-started.html"), + class_="menu"), " ", + html.a("documentation", href=self.get_doclink("index.html"), + class_="menu"), " ", + html.a("svn", href="https://codespeak.net/viewvc/pypy/dist/", + class_="menu"), " ", + html.a("issues", + href="https://codespeak.net/issue/pypy-dev/", + class_="menu"), + html.a("contact", href=self.get_doclink("contact.html"), + class_="menu"), " ", + html.a("EU/project", href="http://pypy.org/", class_="menu"), " ", " ", id="menubar") + def get_doclink(self, target): + return relpath(self.targetpath.strpath, + self.project.get_docpath().join(target).strpath) + class Project(Project): mydir = py.magic.autopath().dirpath() Modified: pypy/branch/ast-experiments/pypy/doc/conftest.py ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/conftest.py (original) +++ pypy/branch/ast-experiments/pypy/doc/conftest.py Mon Feb 26 08:45:45 2007 @@ -1,5 +1,8 @@ import py from py.__.doc.conftest import Directory, DoctestText, ReSTChecker +from py.__.rest.directive import register_linkrole + +thisdir = py.magic.autopath().dirpath() Option = py.test.config.Option option = py.test.config.addoptions("pypy-doc options", @@ -41,3 +44,47 @@ class Directory(Directory): ReSTChecker = PyPyReSTChecker + +try: + from docutils.parsers.rst import directives, states, roles +except ImportError: + pass +else: + # enable :config: link role + def config_role(name, rawtext, text, lineno, inliner, options={}, + content=[]): + from docutils import nodes + from pypy.config.pypyoption import get_pypy_config + from pypy.config.makerestdoc import get_cmdline + txt = thisdir.join("config", text + ".txt") + html = thisdir.join("config", text + ".html") + assert txt.check() + assert name == "config" + sourcedir = py.path.local(inliner.document.settings._source).dirpath() + curr = sourcedir + prefix = "" + while 1: + relative = str(html.relto(curr)) + if relative: + break + curr = curr.dirpath() + prefix += "../" + config = get_pypy_config() + # begin horror + h, n = config._cfgimpl_get_home_by_path(text); + opt = getattr(h._cfgimpl_descr, n) + # end horror + cmdline = get_cmdline(opt.cmdline, text) + if cmdline is not None: + shortest_long_option = 'X'*1000 + for cmd in cmdline.split(): + if cmd.startswith('--') and len(cmd) < len(shortest_long_option): + shortest_long_option = cmd + text = shortest_long_option + target = prefix + relative + print text, target + reference_node = nodes.reference(rawtext, text, name=text, refuri=target) + return [reference_node], [] + config_role.content = True + config_role.options = {} + roles.register_canonical_role("config", config_role) Modified: pypy/branch/ast-experiments/pypy/doc/contact.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/contact.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/contact.txt Mon Feb 26 08:45:45 2007 @@ -39,7 +39,7 @@ conferences all year round. They will be happy to meet in person with anyone interested in the project. Here is the list of planned events_. -.. _events: http://codespeak.net/pypy/dist/pypy/doc/events.html +.. _events: http://codespeak.net/pypy/dist/pypy/doc/news.html PyPy calendar ============= Modified: pypy/branch/ast-experiments/pypy/doc/contributor.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/contributor.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/contributor.txt Mon Feb 26 08:45:45 2007 @@ -6,48 +6,73 @@ code base, ordered by number of commits (which is certainly not a very appropriate measure but it's something):: - Armin Rigo + Armin Rigo Samuele Pedroni - Christian Tismer - Holger Krekel Michael Hudson Carl Friedrich Bolz + Christian Tismer + Holger Krekel Eric van Riet Paap + Antonio Cuni Anders Chrigstrom + Maciek Fijalkowski Richard Emslie - Anders Lehmann + Aurelien Campeas + Anders Lehmann + Niklaus Haldimann Seo Sanghyeon + Lawrence Oluyede Alex Martelli Ludovic Aubry Adrien Di Mascio + Stephan Diehl + Guido Wesdorp Stefan Schwarzer - Tomek Meka + Tomek Meka Patrick Maupin + Leonardo Santagada Bob Ippolito - Jacob Hallen Laura Creighton - Marius Gedminas - Niklaus Haldimann + Jacob Hallen + Marius Gedminas + Niko Matsakis Amaury Forgeot d Arc Guido van Rossum - Stephan Diehl + Valentino Volonghi + Alexander Schremmer + Alexandre Fayolle + Wanja Saatkamp + Gerald Klix + Eugene Oden Dinu Gherman Guenter Jantzen - Rocco Moretti - Boris Feigin + Ben Young + Nicolas Chauvat + Michael Twomey + Rocco Moretti + Simon Burton + Boris Feigin Olivier Dormond - Valentino Volonghi + Gintautas Miliauskas + Stuart Williams + Jens-Uwe Mager Brian Dorsey Jonathan David Riehl + Anders Qvist + Beatrice During Andreas Friedge - Jens-Uwe Mager - Bert Freudenberg Alan McIntyre - Anders Qvist + Bert Freudenberg + Pieter Zieschang + Jean-Paul Calderone + Jacob Oscarson + Ignas Mikalajunas Lutz Paelike - Jacek Generowicz + Christopher Armstrong + Yusei Tahara Andrew Thompson - Ben Young - Alexander Schremmer + Jacek Generowicz + Joshua Gilbert + Anna Ravencroft + Martin Blais Michael Chermside - Modified: pypy/branch/ast-experiments/pypy/doc/dev_method.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/dev_method.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/dev_method.txt Mon Feb 26 08:45:45 2007 @@ -224,7 +224,7 @@ some middle ground - thus increases the importance of feedback. -.. _documentation: http://codespeak.net/pypy/dist/pypy/doc/getting-started.html +.. _documentation: getting-started.html Can I join in? ++++++++++++++ Modified: pypy/branch/ast-experiments/pypy/doc/eventhistory.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/eventhistory.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/eventhistory.txt Mon Feb 26 08:45:45 2007 @@ -140,7 +140,7 @@ all these documents are not approved by the European Union and therefore only preliminary. *(01/06/2006)* -.. _`reports for the EU`: http://codespeak.net/pypy/dist/pypy/doc/index-report.html +.. _`reports for the EU`: index-report.html PyPy Sprint in G??teborg 7th - 11th December 2005 @@ -168,7 +168,7 @@ the `getting started`_ document for instructions about downloading it and trying it out. There is also a short FAQ_. *(11/03/2005)* -.. _`release 0.8 announcement`: http://codespeak.net/pypy/dist/pypy/doc/release-0.8.0.html +.. _`release 0.8 announcement`: release-0.8.0.html PyPy Sprint in Paris 10th-16th October 2005 ======================================================== @@ -203,9 +203,9 @@ trying it out. We also have the beginning of a FAQ_. *(08/28/2005)* .. _`pypy-0.7.0`: -.. _`release announcement`: http://codespeak.net/pypy/dist/pypy/doc/release-0.7.0.html -.. _`getting started`: http://codespeak.net/pypy/dist/pypy/doc/getting-started.html -.. _FAQ: http://codespeak.net/pypy/dist/pypy/doc/faq.html +.. _`release announcement`: release-0.7.0.html +.. _`getting started`: getting-started.html +.. _FAQ: faq.html PyPy Sprint in Heidelberg 22nd-29th August 2005 ========================================================== @@ -268,7 +268,7 @@ .. _`pypy-dev`: http://codespeak.net/mailman/listinfo/pypy-dev .. _EuroPython: http://europython.org -.. _`translation`: http://codespeak.net/pypy/dist/pypy/doc/translation.html +.. _`translation`: translation.html .. _`sprint announcement`: http://codespeak.net/pypy/extradoc/sprintinfo/EP2005-announcement.html .. _`list of people coming`: http://codespeak.net/pypy/extradoc/sprintinfo/EP2005-people.html Modified: pypy/branch/ast-experiments/pypy/doc/extcompiler.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/extcompiler.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/extcompiler.txt Mon Feb 26 08:45:45 2007 @@ -179,7 +179,7 @@ This does not work, however, if you need special data attached to the instances of your class. For this case, you need the second solution: -write the class entierely at interp-level. Such a class must inherit +write the class entirely at interp-level. Such a class must inherit from ``pypy.interpreter.baseobjspace.Wrappable``. You can manipulate instances of such a class freely at interp-level. Instances of subclasses of ``Wrappable`` are *not* wrapped; they are merely Modified: pypy/branch/ast-experiments/pypy/doc/extradoc.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/extradoc.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/extradoc.txt Mon Feb 26 08:45:45 2007 @@ -133,7 +133,7 @@ * `GNU lightning`_ generates assembly language at runtime. -* Tunes_ is not entierely unrelated. (See also the `review of +* Tunes_ is not entirely unrelated. (See also the `review of programming languages`_.) .. _`CLR under the hood`: http://download.microsoft.com/download/2/4/d/24dfac0e-fec7-4252-91b9-fb2310603f14/CLRUnderTheHood.BradA.ppt @@ -144,7 +144,7 @@ .. _`Croquet`: http://www.opencroquet.org/ .. _`transparent dynamic optimization`: http://www.hpl.hp.com/techreports/1999/HPL-1999-77.pdf .. _Dynamo: http://www.hpl.hp.com/techreports/1999/HPL-1999-78.pdf -.. _testdesign: http://codespeak.net/pypy/dist/pypy/doc/coding-guide.html#test-design +.. _testdesign: coding-guide.html#test-design .. _feasible: http://codespeak.net/pipermail/pypy-dev/2004q2/001289.html .. _rock: http://codespeak.net/pipermail/pypy-dev/2004q1/001255.html .. _`GNU lightning`: http://www.gnu.org/software/lightning/lightning.html Modified: pypy/branch/ast-experiments/pypy/doc/faq.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/faq.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/faq.txt Mon Feb 26 08:45:45 2007 @@ -12,58 +12,52 @@ What is PyPy? ------------- -XXX +PyPy is both a Python reimplementation and a framework to implement +interpreters and virtual machines for programming languages, +especially dynamic ones. PyPy tries to find new answers about ease of +creation, flexibility, maintainability and speed trade-offs for +language implementations. For further details see our `goal and +architecture document`_ . ------------------------------------------------------- -Why a new implementation of Python? What does it add? ------------------------------------------------------- +.. _`goal and architecture document`: architecture.html -XXX -------------------------------------------------------------------- -What is the status of the project? Can it be used in practice yet? -------------------------------------------------------------------- +.. _`drop in replacement`: -PyPy is a very broad project with varying level of a completion among -parts. For example compiler toolchain is a relatively mature part, -which is known of running several other projects (see: XXX). - -XXX finish that one - ------------------------------------------ -Is PyPy a drop in replacement of CPython? ------------------------------------------ - -Not completely yet. There are various areas where PyPy is lacking, such as -threading_ and `extension modules`_. The language features (including built in -types and functions) are very complete and well tested, though. That means that -projects not using many extension modules can probably directly use PyPy. A -project using extension modules might get some problems, though. +------------------------------------------ +Is PyPy a drop in replacement for CPython? +------------------------------------------ ------------------------------- -On what platforms does it run? ------------------------------- +Not completely, at least not yet. There are various areas where PyPy is lacking, such as +threading_ and `extension modules`_. The language features (including builtin +types and functions) are very complete and well tested, though. This means that +a project not using many extension modules can probably directly use PyPy. A +project using extension modules might get some problems, though. -PyPy is regularly and extensively tested on Linux machines and on Mac OS X and -mostly works under Windows too (but is tested there less extensively). PyPy -needs a CPython running on the target platform to bootstrap, cross compilation -is not really meant to work, currently. Apart from that restriction, translating -PyPy is supposed to produce nice platform-independent code, so the chances are -not too bad that it works. - -Currently (due to time restrictions) we are not trying hard to make PyPy support -64 bit platforms. While this seems to still mostly work out, a few modules won't -work on 64 bit machines, such as ``bz2``. - ----------------------------------------------- -Which Python version (2.x?) does PyPy support? ----------------------------------------------- - -PyPy currently targets to be fully compatible with Python 2.4. That means that -it contains the stdandard library of Python 2.4 and that it supports 2.4 -features (such as decorators) but not the 2.5 features (with statement, ternary -operators). The 2.5 features will probably be eventually suported, the most -important reasons why nobody is working on them is that we did not promise this +-------------------------------- +On what platforms does PyPy run? +-------------------------------- + +PyPy is regularly and extensively tested on Linux machines and on Mac +OS X and mostly works under Windows too (but is tested there less +extensively). PyPy needs a CPython running on the target platform to +bootstrap, as cross compilation is not really meant to work yet. +At the moment you need CPython 2.4 for the translation process, 2.5 is +not fully supported. + +Currently (due to time restrictions) we are not trying hard to support +PyPy in a 64 bit environment. While things seem to mostly work, a few +modules won't work on 64 bit machines, such as ``bz2``. + +------------------------------------------------ +Which Python version (2.x?) does PyPy implement? +------------------------------------------------ + +PyPy currently aims to be fully compatible with Python 2.4. That means that +it contains the standard library of Python 2.4 and that it supports 2.4 +features (such as decorators) but not the 2.5 features (with statement, the ternary +operator). The 2.5 features will probably be eventually supported, the most +important reason why nobody is working on them is that we did not promise this to the EU and have currently enough other tasks. .. _threading: @@ -72,7 +66,7 @@ Do threads work? What are the modules that work? ------------------------------------------------- -Operating-System threads work in a limited way. If you enable the ``thread`` +Operating system-level threads work in a limited way. If you enable the ``thread`` module then PyPy will get support for GIL based threading. One limitation is that not that many IO operations actually release the GIL, which reduces the usefulness of threads. On the other hand, PyPy fully supports `stackless-like @@ -90,7 +84,7 @@ * mixed module implementations: exceptions, sys, __builtin__, posix _codecs, gc, _weakref, array, marshal, errno, math, _sre, parser, symbol, - _random, socket, unicodedata, mmap, fcntl, time, select, bz2, crypt, + _random, socket, unicodedata, mmap, fcntl, time, select, bz2, crypt, signal @@ -103,18 +97,38 @@ Can I use CPython extension modules? ------------------------------------ -No and there are no current plans to support this. CPython extension modules +No and there are no short-term plans to support this. CPython extension modules rely heavily on CPython's C API which contains a lot of implementation details -like reference counting, exact C-level objects implementations etc. +like reference counting, exact C-level object implementation and layout etc. -Although if your module uses ctypes rather than C-level code, there is a hope. -You can try to write a mixed module (see next question). +Although if your module uses ctypes rather than C-level code, there is +a hope -- you can try to write a mixed module (see next question). + +The long-term answer might be different. In principle, it should be possible +for PyPy to support the CPython C API (or at least a large subset of its +official part). It means that "in the fullness of time" you might be able to +simply recompile existing CPython extension modules and use them with PyPy. ------------------------------------------ How do I write extension modules for PyPy? ------------------------------------------ -XXX +PyPy extension modules are written in the form of `mixed modules`_, so +called because they can contain a mixture of compiled and interpreted +Python code. At the moment they all need to be translated together with the rest of PyPy. + +We have a proof concept of what we call the `extension compiler`_ and +our support for a static variant of the ctypes interface (`rctypes`_) to +help with their development. At the moment both have quite some rough +edges. This kind of module can even be cross-compiled to regular CPython +extension modules, although this doesn't deliver completely satisfying +results so far. This area is going to improve over time. + +.. _`mixed modules`: coding-guide.html#mixed-module-mechanism +.. _`extension compiler`: extcompiler.html +.. _`rctypes`: rctypes.html + +.. _`slower than CPython`: ----------------- How fast is PyPy? @@ -127,19 +141,21 @@ a factor of 2000. The first translated version was roughly 300 times slower than CPython. In later versions, we increased the speed. CPython was about 10-20 times as fast as version 0.8.0, 4-7 times as fast as version 0.9 and -2.4 - 5 times as fast as the current version (1.0). -Note that the speed heavily depends on the enabled options at compile time. +2 to 4 times as fast as the current version (0.99). +Note that the speed heavily depends on the options enabled at compile time. +.. _`prolog and javascript`: + ----------------------------------------------------------------------- What is this talk about a JavaScript and a Prolog interpreter in PyPy? ----------------------------------------------------------------------- -Since a Python interpreter is a rather large and intricate thing, our toolsuite -became quite advanced to support it. Therefore people had the idea of using it +Since a Python interpreter is a rather large and intricate thing, our tool suite +has become quite advanced to support it. This resulted in people having the idea of using it to implement interpreters for other dynamic languages than Python and get a lot of things for free (translation to various languages, stackless features, -garbage collection, implementation of various things like arbitraryly long +garbage collection, implementation of various things like arbitrarily long integers). Therefore people started to implement a `JavaScript interpreter`_ (Leonardo Santagada as his Summer of PyPy project) and a `Prolog interpreter`_ (Carl Friedrich Bolz as his Masters thesis). Both projects are undocumented and @@ -165,18 +181,13 @@ Coming to a sprint is usually also the best way to get into PyPy development. If you want to start on your own, take a look at the list of `project suggestions`_. If you get stuck or need advice, `contact us`_. Usually IRC is -the most immediate mean to get feedback (at least during some parts of the day, -many PyPy developers are in Europe) and the mailing list is better for long +the most immediate way to get feedback (at least during some parts of the day; +many PyPy developers are in Europe) and the `mailing list`_ is better for long discussions. .. _`project suggestions`: project-ideas.html .. _`contact us`: contact.html - ----------------------------------- -Why so many levels of abstraction? ----------------------------------- - -XXX see pypy-vm-construction +.. _`mailing list`: contact.html ---------------------------------------------------------------------- I am getting strange errors while playing with PyPy, what should I do? @@ -200,9 +211,9 @@ ------------------------------ RPython is a restricted subset of the Python language. The restrictions are to -ensure that type inference (and eventually translation to other languages) of +ensure that type inference (and so, ultimately, translation to other languages) of the program is possible. These restrictions only apply after the full import -happened, so at import time arbitrary Python code can be executed. Another +happens, so at import time arbitrary Python code can be executed. Another important point is that the property of "being RPython" always applies to a full program, not to single functions or modules (the translation tool chain does a full program analysis). @@ -211,14 +222,15 @@ of mixing types in arbitrary ways. RPython does not allow the usage of two different types in the same variable. In this respect (and in some others) it feels a bit like Java. Other features not allowed in RPython are the usage of -special methods (``__XXX__``) except ``__init__`` and ``__del__`` and reflection -capabilities (e.g. ``__dict__``). +special methods (``__xxx__``) except ``__init__`` and ``__del__``, and the +usage of reflection capabilities (e.g. ``__dict__``). Most existing standard library modules are not RPython, except for some functions in ``os``, ``math`` and ``time`` that are natively supported. In general it is quite unlikely that an existing Python -program is by chance RPython, mostly it has to be rewritten heavily. -To read more about RPython limitations read `RPython description`_ +program is by chance RPython; it is most likely that it would have to be +heavily rewritten. +To read more about the RPython limitations read the `RPython description`_. .. _`RPython description`: coding-guide.html#restricted-python @@ -265,9 +277,12 @@ Do I have to rewrite my programs in RPython? -------------------------------------------- -No. PyPy always runs your code in its own interpreter, which is a full -and compliant Python 2.4 interpreter. RPython_ is only the language in -which parts of PyPy itself are written. XXX +No. PyPy always runs your code in its own interpreter, which is a +full and compliant Python 2.4 interpreter. RPython_ is only the +language in which parts of PyPy itself are written and extension +modules for it. The answer to whether something needs to be written as +an extension module, apart from the "gluing to external libraries" reason, will +change over time as speed for normal Python code improves. ------------------------- Which backends are there? @@ -282,12 +297,12 @@ * Low level backends: C_, LLVM_ * High level backends: CLI_, JVM_, JavaScript_ -Partially implemented backends: +Partially implemented backends (both high-level): * Squeak_, `Common Lisp`_ -To learn more about backends take a look at the `translation document`_ +To learn more about backends take a look at the `translation document`_. .. _CLI: cli-backend.html .. _JavaScript: js/whatis.html @@ -298,24 +313,15 @@ .. _Squeak: translation.html#gensqueak .. _`Common Lisp`: translation.html#gencl -------------------------------------------------------- -Are there other projects that need the PyPy tool chain? -------------------------------------------------------- - -XXX - ---------------------- How do I compile PyPy? ---------------------- -See the `getting-started`_ guide. Note that at the moment this produces -an executable that contains a lot of things that are hard-coded for your -particular system (including paths and other stuff), so it's not -suitable for being installed or redistributed. XXX - ---------------------------------- -How do I compile my own programs? ---------------------------------- +See the `getting-started`_ guide. + +-------------------------------------- +How do I compile my own interpreters? +-------------------------------------- Start from the example of `pypy/translator/goal/targetnopstandalone.py`_, which you compile by @@ -325,36 +331,11 @@ You can have a look at intermediate C source code, which is (at the moment) put in ``/tmp/usession-*/testing_1/testing_1.c``. Of course, -all the function and stuff indirectly used by your ``entry_point()`` -function has to be RPython_. XXX - --------------------------------------------- -Why isn't there a simpler way of doing that? --------------------------------------------- - -One answer is that "officially speaking" supporting this is not a goal -of the PyPy project. - -XXX - -A better answer might be that when the target of compilation turns out -not to be RPython, working out *why* can be very difficult, and -working on the annotator to make these messages clearer -- even if -possible -- would take time away from other development tasks. - -It's not that writing RPython is difficult, but if there was some kind -of rpythonc compiling tool there would be much more temptation to try -to compile arbitrary, pre-existing Python programs and this is fairly -unlikely to work (to start, there is very little in the way of an -"RPython standard library"). XXX outdated - - ---------------------------------------------------------------------------- -What does the error message "slice start must be proven non-negative" mean? ---------------------------------------------------------------------------- - -XXX - +all the functions and stuff used directly and indirectly by your +``entry_point()`` function has to be RPython_. Another example you may +want to look at is `pypy/translator/goal/targetprologstandalone.py`_, +the target for the in-progress Prolog implementation; this target for +example enables a stackless build programmatically. .. _`RPython`: coding-guide.html#rpython Modified: pypy/branch/ast-experiments/pypy/doc/geninterp.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/geninterp.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/geninterp.txt Mon Feb 26 08:45:45 2007 @@ -18,8 +18,8 @@ any longer to execute this code. .. _`application-level`: coding-guide.html#app-preferable -.. _exceptions: http://codespeak.net/pypy/dist/pypy/lib/_exceptions.py -.. _oldstyle: http://codespeak.net/pypy/dist/pypy/lib/_classobj.py +.. _exceptions: ../../pypy/lib/_exceptions.py +.. _oldstyle: ../../pypy/lib/_classobj.py Examples are exceptions_ and oldstyle_ classes. They are needed in a very early phase of bootstrapping StdObjspace, but @@ -48,7 +48,7 @@ Example +++++++ -.. _implementation: http://codespeak.net/pypy/dist/pypy/translator/geninterplevel.py +.. _implementation: ../../pypy/translator/geninterplevel.py Let's try a little example. You might want to look at the flowgraph that it produces. Here, we directly run the Python translation and look at the @@ -177,8 +177,8 @@ Interplevel Snippets in the Sources +++++++++++++++++++++++++++++++++++ -.. _`_exceptions.py`: http://codespeak.net/pypy/dist/pypy/lib/_exceptions.py -.. _`_classobj.py`: http://codespeak.net/pypy/dist/pypy/lib/_classobj.py +.. _`_exceptions.py`: ../../pypy/lib/_exceptions.py +.. _`_classobj.py`: ../../pypy/lib/_classobj.py Code written in application space can consist of complete files to be translated (`_exceptions.py`_, `_classobj.py`_), or they Modified: pypy/branch/ast-experiments/pypy/doc/getting-started.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/getting-started.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/getting-started.txt Mon Feb 26 08:45:45 2007 @@ -20,33 +20,33 @@ translation aspect - should become robust against language changes. `more...`_ .. _Python: http://docs.python.org/ref -.. _`more...`: http://codespeak.net/pypy/dist/pypy/doc/architecture.html +.. _`more...`: architecture.html Just the facts ============== .. _gettingpypy: -Downloading & running the PyPy 0.9 release -------------------------------------------- +Downloading & running the PyPy 0.99 release +-------------------------------------------- Download one of the following release files and unpack it: -*pypy-0.9* +*pypy-0.99* * download one of - * `pypy-0.9.0.tar.bz2`_ (unix line endings) or - * `pypy-0.9.0.tar.gz`_ (unix line endings) or - * `pypy-0.9.0.zip`_ (windows line-endings) and unpack it + * `pypy-0.99.0.tar.bz2`_ (unix line endings) or + * `pypy-0.99.0.tar.gz`_ (unix line endings) or + * `pypy-0.99.0.zip`_ (windows line-endings) and unpack it * alternatively run - * ``svn co http://codespeak.net/svn/pypy/release/0.9.x pypy-0.9.x`` - (the 0.9 maintenance branch) + * ``svn co http://codespeak.net/svn/pypy/release/0.99.x pypy-0.99.x`` + (the 0.99 maintenance branch) -to get it from the subversion repository then change to the -``pypy-0.9.0`` or ``pypy-0.9.x`` directory and execute the following +to get it from the subversion repository. Then change to the +``pypy-0.99.0`` or ``pypy-0.99.x`` directory and execute the following command line:: python pypy/bin/py.py @@ -62,9 +62,9 @@ dependant on CPython anymore and becomes faster. .. _`95% of CPythons core language regression tests`: http://codespeak.net/~hpk/pypy-testresult/ -.. _`pypy-0.9.0.tar.bz2`: http://codespeak.net/download/pypy/pypy-0.9.0.tar.bz2 -.. _`pypy-0.9.0.zip`: http://codespeak.net/download/pypy/pypy-0.9.0.zip -.. _`pypy-0.9.0.tar.gz`: http://codespeak.net/download/pypy/pypy-0.9.0.tar.gz +.. _`pypy-0.99.0.tar.bz2`: http://codespeak.net/download/pypy/pypy-0.99.0.tar.bz2 +.. _`pypy-0.99.0.zip`: http://codespeak.net/download/pypy/pypy-0.99.0.zip +.. _`pypy-0.99.0.tar.gz`: http://codespeak.net/download/pypy/pypy-0.99.0.tar.gz Svn-check out & run the latest PyPy as a two-liner -------------------------------------------------- @@ -155,8 +155,8 @@ To start interpreting Python with PyPy, use Python 2.3 or greater:: - cd pypy/bin - python py.py + cd pypy + python bin/py.py After a few seconds (remember: this is running on top of CPython), you should be at the PyPy prompt, which is the same as the Python @@ -180,10 +180,9 @@ To list the PyPy interpreter command line options, type:: - cd pypy/bin - python py.py --help + cd pypy + python bin/py.py --help -(this will give you a daunting list, so it is a good idea to use a pager). py.py supports most of the options that CPython supports too (in addition to a large amount of options that can be used to customize py.py). As an example of using PyPy from the command line, you could type:: @@ -195,6 +194,9 @@ python py.py ../../lib-python/2.4.1/test/pystone.py 10 +See our `configuration sections`_ for details about what all the commandline +options do. + Special PyPy features -------------------------- @@ -240,9 +242,8 @@ |- 6 BINARY_ADD |- add(W_IntObject(1), W_IntObject(2)) -> W_IntObject(3) |- 7 STORE_NAME 0 (a) - |- setitem(W_DictObject([ + |- hash(W_StringObject('a')) -> W_IntObject(-468864544) + |- int_w(W_IntObject(-468864544)) -> -468864544 |-10 LOAD_CONST 2 () |-13 RETURN_VALUE |- <<<< leave a = 1 + 2 @ 1 >>>> @@ -257,8 +258,8 @@ object space, providing lazily-computed objects in a fully transparent manner:: - cd pypy/bin - python py.py -o thunk + cd pypy + python bin/py.py -o thunk >>>> from pypymagic import thunk >>>> def longcomputation(lst): @@ -286,8 +287,8 @@ It is interesting to note that this lazy-computing Python extension is solely implemented in a small `objspace/thunk.py`_ file consisting -of around 100 lines of code. Since the 0.8.0 release it is even possible -to `translate PyPy with the thunk object space`_. +of around 200 lines of code. Since the 0.8.0 release you +can `translate PyPy with the thunk object space`_. Logic programming +++++++++++++++++ @@ -300,8 +301,8 @@ Try it out:: - cd pypy/bin - python py.py -o logic + cd pypy + python bin/py.py -o logic >>>> X = newvar() # a logic variable >>>> bind(X, 42) # give it a value @@ -385,10 +386,13 @@ `Dot Graphviz`_ that does not crash. This is only needed if you want to look at the flowgraphs. + * Use Python-2.4 for using translation tools because python2.5 + is (as of revision 39130) not fully supported. + To start the interactive translator shell do:: - cd pypy/bin - python translatorshell.py + cd pypy + python bin/translatorshell.py Test snippets of translatable code are provided in the file ``pypy/translator/test/snippet.py``, which is imported under the name @@ -436,7 +440,7 @@ +++++++++++++++++++++++++++++++++++++++ To translate for LLVM (`low level virtual machine`_) you must first have `LLVM -installed with version 1.7`_ - the `how to install LLVM`_ provides some helpful +installed with version 1.9`_ - the `how to install LLVM`_ provides some helpful hints. Please note that you do not need the CFrontend to compile, make tools-only. @@ -509,7 +513,7 @@ executable directly from the shell; you can find the executable in one of the ``/tmp/usession-*`` directories:: - anto at anto anto$ mono /tmp/usession-anto/main.exe 4 5 + $ mono /tmp/usession-/main.exe 4 5 9 To translate and run for CLI you must have the SDK installed: Windows @@ -548,7 +552,7 @@ ultimate example of source that our translation toolchain can process:: cd pypy/translator/goal - python translate.py --run + python translate.py --run targetpypystandalone.py By default the translation process will try to use the `Boehm-Demers-Weiser garbage collector`_ for the translated PyPy (Use @@ -559,7 +563,11 @@ This whole process will take some time and quite a lot of memory. To reduce the memory footprint of the translation process you can use the -option ``--lowmem`` With this option the whole process should be +option ``--lowmem``:: + + python translate.py --run targetpypystandalone.py --lowmem + +With this option the whole process should be runnable on a machine with 512Mb of RAM. If the translation is finished running and after you closed the graph you will be greeted (because of ``--run`` option) by the friendly prompt of a PyPy @@ -580,7 +588,7 @@ With the default options, you can find the produced executable under the name ``pypy-c``. Type ``pypy-c --help`` to see the options it supports -- -mainly the same basic options of CPython. In addition, ``pypy-c --info`` +mainly the same basic options as CPython. In addition, ``pypy-c --info`` prints the translation options that where used to produce this particular executable. This executable contains a lot of things that are hard-coded for your particular system (including paths), so it's not really meant to @@ -609,13 +617,18 @@ sweep collector, with two different approaches for finding roots (as we have seen Boehm's collector is the default). +Find a more detailed description of the various options in our `configuration +sections`_. + You can also use the translate.py script to try out several smaller programs, e.g. a slightly changed version of Pystone:: cd pypy/translator/goal python translate.py targetrpystonedalone +This will produce the executable "targetrpystonedalone-c". +.. _`configuration sections`: config/index.html .. _`translate PyPy with the thunk object space`: @@ -676,35 +689,6 @@ fine. Once assembled, you can run the produced executable with the Microsoft Runtime. -You can also try the still very experimental ``clr`` module that -enables integration with the surrounding .NET environment. First, you -have to tell translate.py to include the ``clr`` module:: - - ./translate.py --text --batch --backend=cli targetpypystandalone.py --withmod-clr - -Then, you can dynamically load .NET classes using the -``clr.load_cli_classe`` method. After a class has been loaded, you can -instantiate and use it as it were a normal Python class. Special -methods such as indexers and properties are supported using the usual -Python syntax: - - >>>> import clr - >>>> ArrayList = clr.load_cli_class('System.Collections', 'ArrayList') - >>>> obj.Add(1) - 0 - >>>> obj.Add(2) - 1 - >>>> obj.Add("foo") - 2 - >>>> print obj[0], obj[1], obj[2] - 1 2 foo - >>>> print obj.Count - 3 - -At the moment the only way to load a .NET class is to explicitly use -``clr.load_cli_class``; in the future they will be automatically -loaded when accessing .NET namespaces as they were Python modules, as -IronPython does. .. _`start reading sources`: @@ -779,6 +763,16 @@ pygame: http://www.pygame.org/download.shtml +CTypes (highly recommended) +++++++++++++++++++++++++++++ + +`ctypes`_ (version 0.9.9.6 or later) is required if you want to translate PyPy +to C. See the `download page of ctypes`_. + +.. _`download page of ctypes`: http://sourceforge.net/project/showfiles.php?group_id=71702 +.. _`ctypes`: http://starship.python.net/crew/theller/ctypes/ + + CLISP +++++++ @@ -801,9 +795,7 @@ but if you want to have the ``py.test`` tool generally in your path, you might like to visit: - http://codespeak.net/py/current/doc/getting-started.html - - + http://codespeak.net/py/dist/download.html Getting involved ================================== @@ -815,7 +807,7 @@ as EuroPython or Pycon. Take a look at the list of upcoming events_ to plan where to meet with us. -.. _events: http://codespeak.net/pypy/dist/pypy/doc/events.html +.. _events: http://codespeak.net/pypy/dist/pypy/doc/news.html .. _`pypy-dev mailing list`: http://codespeak.net/mailman/listinfo/pypy-dev .. _`contact possibilities`: contact.html @@ -824,7 +816,7 @@ .. _`low level virtual machine`: http://llvm.org/ .. _`how to install LLVM`: http://llvm.org/docs/GettingStarted.html .. _`LLVM mailing list`: http://mail.cs.uiuc.edu/mailman/listinfo/llvmdev -.. _`LLVM installed with version 1.7`: http://llvm.org/releases +.. _`LLVM installed with version 1.9`: http://llvm.org/releases .. _`Spidermonkey`: http://www.mozilla.org/js/spidermonkey/ .. _`Google summer of code`: http://code.google.com/soc @@ -845,11 +837,11 @@ .. _mixedmodule.py: http://codespeak.net/svn/pypy/dist/pypy/interpreter/mixedmodule.py .. _typedef.py: http://codespeak.net/svn/pypy/dist/pypy/interpreter/typedef.py .. _Standard object space: objspace.html#the-standard-object-space -.. _objspace.py: http://codespeak.net/pypy/dist/pypy/objspace/std/objspace.py -.. _thunk: http://codespeak.net/pypy/dist/pypy/objspace/thunk.py -.. _trace: http://codespeak.net/pypy/dist/pypy/objspace/trace.py -.. _flow: http://codespeak.net/pypy/dist/pypy/objspace/flow/ -.. _translator.py: http://codespeak.net/pypy/dist/pypy/translator/translator.py +.. _objspace.py: ../../pypy/objspace/std/objspace.py +.. _thunk: ../../pypy/objspace/thunk.py +.. _trace: ../../pypy/objspace/trace.py +.. _flow: ../../pypy/objspace/flow/ +.. _translator.py: ../../pypy/translator/translator.py .. _mailing lists: contact.html .. _documentation: index.html .. _unit tests: coding-guide.html#test-design Modified: pypy/branch/ast-experiments/pypy/doc/glossary.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/glossary.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/glossary.txt Mon Feb 26 08:45:45 2007 @@ -45,7 +45,7 @@ **external function** Functions that we don't want to implement in Python for various - reasons (e.g. if they need to make calls into the OS) and whose + reasons (e.g. they need to make calls into the OS) and whose implementation will be provided by the backend. .. _`garbage collection framework`: @@ -68,12 +68,6 @@ `just in time compiler`_. Our jit now has `some draft documentation `__. -.. _`l3interpreter`: - -**l3interpreter** - Piece of code that is able to interpret L3 flow graphs. This code - is unfinished and its future is unclear. - .. _llinterpreter: **llinterpreter** Modified: pypy/branch/ast-experiments/pypy/doc/how-to-release.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/how-to-release.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/how-to-release.txt Mon Feb 26 08:45:45 2007 @@ -5,28 +5,43 @@ --------- As a meta rule setting up issues in the tracker for items here may help not forgetting things. +A set of todo files may also work. Check and prioritize all issues for the release, postpone some if necessary, create new issues also as necessary. A meeting (or meetings) should be organized to decide what things are priorities, should go in and work for the release. -An important thing is to get the documentation into an up-to-date state. + +An important thing is to get the documentation into an up-to-date state! Release Steps ---------------- -* at code freeze make a release branch under http://codepeak.net/svn/pypy/release/x.y(.z) , - some of the next updates may be done before or after branching; - make sure things are ported back to the trunk and to the branch as necessary -* XXX find out and list the set of testing necessary -* update dist/pypy/doc/contributort.txt (and possibly dist/LICENSE) +* at code freeze make a release branch under + http://codepeak.net/svn/pypy/release/x.y(.z). IMPORTANT: bump the + pypy version number in module/sys/version.py, notice that the branch + will capture the revision number of this change for the release; + some of the next updates may be done before or after branching; make + sure things are ported back to the trunk and to the branch as + necessary +* update dist/pypy/doc/contributor.txt (and possibly dist/LICENSE) * update dist/README * write release announcement dist/pypy/doc/release-x.y(.z).txt -* update the status section in dist/pypy/doc/architecture.txt * update dist/pypy/doc/getting-started.txt links at the top and release number references, make sure it is generally up-to-date -* use, after the necessary updates, dist/pypy/tool/makerealase.py to make the tarballs - on codespeak (XXX what about tagging the release?) -* test the download links in dist/pypy/doc/getting-started.txt and possibly in the release announcement, - ask people to test them +* use, after the necessary updates, dist/pypy/tool/makerelease.py to + make the tarballs on codespeak; this generates html doc for the + tarballs too. Use:: + + makerelease -tag .z pypy-x.y.z + + to tag and produce final tarballs. Without the '-tag' this can + be used to make pre-release testing tarballs. +* nowadays we have an extensive set of nightly builds and test + runs. Is probably good to do some minimal testing of the tarballs, + especially to check that things work even outside a working copy or + if some stuff is missing. We have some support for running part of + our nightly tests on tarballs (see + http://codespeak.net/svn/user/pedronis/tarball-testing). * write a news item for the release in dist/pypy/doc/news.txt -* send announcements to pypy-dev, pypy-funding, python-list, python-announce, python-dev ... +* send announcements to pypy-dev, pypy-funding, python-list, + python-announce, python-dev ... Modified: pypy/branch/ast-experiments/pypy/doc/index.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/index.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/index.txt Mon Feb 26 08:45:45 2007 @@ -30,9 +30,11 @@ Status_ of the project. -Meta-Documentation +Project Documentation ===================================== +architecture_ gives a complete view of PyPy's basic design. + `coding guide`_ helps you to write code for PyPy (especially also describes coding in RPython a bit). @@ -50,7 +52,7 @@ `PyPy video documentation`_ is a page linking to the videos (e.g. of talks and introductions) that are available. -`EU reports`_ is a page that contains links to the +`Technical reports`_ is a page that contains links to the reports that we submitted to the European Union. `license`_ contains licensing details (basically a straight MIT-license). @@ -85,14 +87,15 @@ Source Code Documentation =============================================== -architecture_ gives a complete view of PyPy's basic design. - `object spaces`_ discusses the object space interface and several implementations. `bytecode interpreter`_ explains the basic mechanisms of the bytecode interpreter and virtual machine. +`object optimizations`_ describer various alternative object implementations +(for strings, dicts and lists) in the standard object space. + `translation`_ is a detailed overview of our translation process. The rtyper_ is the largest component of our translation process. @@ -115,6 +118,9 @@ `rlib`_ describes some modules that can be used when implementing programs in RPython. +`configuration documentation`_ describes the various configuration options that +allow you to customize PyPy. + `CLI backend`_ describes the details of the .NET backend. `JIT Generation in PyPy`_ describes how we produce the Python Just-in-time Compiler @@ -130,14 +136,16 @@ .. _`sprint reports`: sprint-reports.html .. _`talks and related projects`: extradoc.html .. _`license`: ../../LICENSE -.. _`Nightly compliance test runs for compiled pypy-c`: http://www.strakt.com/~pedronis/pypy-c-test/ +.. _`Nightly compliance test runs for compiled pypy-c`: http://www2.openend.se/~pedronis/pypy-c-test/ .. _`compliance test status`: http://codespeak.net/~hpk/pypy-testresult/ .. _`PyPy statistics`: http://codespeak.net/~hpk/pypy-stat/ .. _`object spaces`: objspace.html +.. _`object optimizations`: object-optimizations.html .. _`translation`: translation.html .. _`dynamic-language translation`: dynamic-language-translation.html .. _`low-level encapsulation`: low-level-encapsulation.html .. _`translation aspects`: translation-aspects.html +.. _`configuration documentation`: config/ .. _`coding guide`: coding-guide.html .. _`architecture`: architecture.html .. _`JavaScript backend` : js/using.html @@ -145,6 +153,7 @@ .. _`theory`: theory.html .. _`bytecode interpreter`: interpreter.html .. _`EU reports`: index-report.html +.. _`Technical reports`: index-report.html .. _`on Linux`: http://wyvern.cs.uni-duesseldorf.de/pypytest/summary.html .. _`on Windows`: http://scottdial.com/pypytest/ .. _`on built pypy-c`: http://wyvern.cs.uni-duesseldorf.de/~fijal/pypy-c-tests/ @@ -170,8 +179,12 @@ `doc/`_ text versions of PyPy developer documentation +`doc/config/`_ documentation for the numerous translation options + `doc/discussion/`_ drafts of ideas and documentation +``doc/*/`` other specific documentation topics or tools + `interpreter/`_ `bytecode interpreter`_ and related objects (frames, functions, modules,...) @@ -184,6 +197,8 @@ `jit/codegen/`_ `jit backends`_ for different architectures +`jit/goal/`_ the translation targets that produce a PyPy with a JIT_ + `jit/hintannotator/`_ the `hint-annotator`_ that analyzes an interpreter `jit/timeshifter/`_ the `timeshifter`_ that turns an interpreter into a JIT compiler @@ -200,12 +215,14 @@ `lib/`_ PyPy's wholesale reimplementations of CPython modules_ and experimental new application-level modules -`lib/test2/`_ tests running at interp-level against the reimplementations +`lib/app_test/`_ tests for the reimplementations, running on top of CPython + +`lib/distributed/`_ distributed execution prototype, based on `transparent proxies`_ `module/`_ contains `mixed modules`_ implementing core modules with both application and interpreter level code. Not all are finished and working. Use the ``--withmod-xxx`` - options of `translate.py`_. + or ``--allworkingmodules`` translation options. `objspace/`_ `object space`_ implementations @@ -220,11 +237,13 @@ `objspace/logic.py`_ the `logic object space`_, providing Prolog-like logic variables +`objspace/cpy/`_ an object space supporting the `extension compiler`_ + `objspace/flow/`_ the FlowObjSpace_ implementing `abstract interpretation` `objspace/std/`_ the StdObjSpace_ implementing CPython's objects and types -`rlib/`_ a "standard library" for RPython_ programs +`rlib/`_ a `"standard library"`_ for RPython_ programs `rpython/`_ the `RPython Typer`_ @@ -232,8 +251,7 @@ `rpython/ootypesystem/`_ the `object-oriented type system`_ for OO backends -`rpython/memory/`_ experimental garbage collector construction - framework +`rpython/memory/`_ the garbage collector construction framework `tool/`_ various utilities and hacks used from various places @@ -242,17 +260,12 @@ `tool/pytest/`_ support code for our `testing methods`_ -`tool/tb_server/`_ a somewhat outdated http-server for presenting - tracebacks in a helpful manner - `translator/`_ translation_ backends and support code `translator/backendopt/`_ general optimizations that run before a backend generates code `translator/c/`_ the `GenC backend`_, producing C code from an - RPython program (generally via the RTyper) - -`translator/lisp/`_ the `Common Lisp backend`_ (incomplete) + RPython program (generally via the rtyper_) `translator/cli/`_ the `CLI backend`_ for `.NET`_ (Microsoft CLR or Mono_) @@ -262,6 +275,8 @@ `translator/jvm/`_ the Java backend (in-progress) +`translator/lisp/`_ the `Common Lisp backend`_ (incomplete) + `translator/llvm/`_ contains the `LLVM backend`_ producing LLVM assembler from fully annotated RPython programs @@ -269,7 +284,8 @@ `translator/stackless/`_ the `Stackless Transform`_ -`translator/tool/`_ helper tools for translation +`translator/tool/`_ helper tools for translation, including the Pygame + `graph viewer`_ ``*/test/`` many directories have a test subdirectory containing test modules (see `Testing in PyPy`_) @@ -291,6 +307,7 @@ .. _`taint object space`: objspace-proxies.html#taint .. _`thunk object space`: objspace-proxies.html#thunk .. _`logic object space`: objspace-proxies.html#logic +.. _`transparent proxies`: objspace-proxies.html#tproxy .. _`What PyPy can do for your objects`: objspace-proxies.html .. _`Stackless and coroutines`: stackless.html .. _StdObjSpace: objspace.html#the-standard-object-space @@ -308,6 +325,7 @@ .. _`extension compiler`: extcompiler.html .. _`py.py`: getting-started.html#main-entry-point .. _`translatorshell.py`: getting-started.html#try-out-the-translator +.. _JIT: jit.html .. _`JIT Generation in PyPy`: jit.html .. _`just-in-time compiler generator`: jit.html .. _`jit backends`: jit.html#backends @@ -321,6 +339,8 @@ .. _`translate.py`: getting-started.html#translating-the-pypy-interpreter .. _`.NET`: http://www.microsoft.com/net/ .. _Mono: http://www.mono-project.com/ +.. _`"standard library"`: rlib.html +.. _`graph viewer`: getting-started.html#try-out-the-translator .. include:: _ref.txt Modified: pypy/branch/ast-experiments/pypy/doc/js/todo.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/js/todo.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/js/todo.txt Mon Feb 26 08:45:45 2007 @@ -19,17 +19,16 @@ * Support bound methods as arguments for callbacks. - Idea is to provide following: + - if you pass a bound method to a callback, this method is called + with previously bound self - - if you pass a bound method to a callback, this method is called - with previously bound self - - if you provide an unbound method for a callback, this is an error, - unless class is proper to the callback object (or high level class - apropriate for that DOM object), in which case a bound method is - called with apropriate self. + - if you provide an unbound method for a callback, this is an error, + unless class is proper to the callback object (or high level class + apropriate for that DOM object), in which case a bound method is + called with apropriate self. - I'm quite sure this can be done using RPython, but I'm totally unsure - how much effort this will require :-) (as usuall) + - I'm quite sure this can be done using RPython, but I'm totally unsure + how much effort this will require :-) (as usuall) * Cleanup of parent namespace (put all builtin functions into it's own namespace?) Modified: pypy/branch/ast-experiments/pypy/doc/js/using.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/js/using.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/js/using.txt Mon Feb 26 08:45:45 2007 @@ -16,7 +16,7 @@ The JavaScript backend lets you write `RPython`_ source code which gets translated into JavaScript and executed in a browser. The resulting -JavaScript code should not depend on a browser (this is backend +JavaScript code should not depend on a browser (this is a backend responsibility) and should integrate as much as possible with a web server. @@ -27,10 +27,10 @@ ---------------- You can use a JavaScript backend in many different ways. One of those is -to simply run `jscompile`_ from bin directory with module name and a -list of functions to get your functions compiled. Another way is to use -rpython2javascript from `js.main`_ which allows your javascript to be -generated on-the-fly (e.g. when serving a web page). +to simply run `jscompile`_ from the 'bin' directory with a module name and a +list of functions, this makes that the listed functions get compiled. Another +way is to use the rpython2javascript function from `js.main`_ to generate +your javascript on-the-fly (e.g. when serving a web page). .. _`jscompile`: http://codespeak.net/svn/pypy/dist/pypy/bin/jscompile.py .. _`js.main`: http://codespeak.net/svn/pypy/dist/pypy/translator/js/main.py @@ -70,16 +70,6 @@ .. _`MochiKit`: http://www.mochikit.com/ .. _`rpython2javascript`: -Web server integration: ------------------------ - -There is an `example`_ of using this toolkit with BaseHTTPServer from -the standard python library. Web server integration is simple - you can -compile any RPython function at runtime and provide it to client as -a JavaScript file. - -.. _`example`: http://codespeak.net/svn/pypy/dist/pypy/translator/js/demo/jsdemo/example.py - Easy AJAX: ---------- @@ -88,22 +78,24 @@ To achieve this, you must tell PyPy that *these* particular method calls need to be rendered in this way. -First you must subclass BasicExternal from `bltregistry`_ and provide -instance of it to RPython code (as global variable or any other way). -Then you need to set class instance's `_render_xmlhttp` to `True`, to -tell the JS backend to render it using xmlhttp communication. Because -the web server code does not need to be rpython, you have to supply some -way of telling PyPy what types can be returned out of it. This is done -using the decorator `@described(retval = )` from -`bltregistry`_. For example you may provide:: +To achieve this, first you must subclass BasicExternal from `bltregistry`_ and +provide an instance of it to RPython code (for instance as global variable). +Then you need to set class instance's `_render_xmlhttp` to `True`, to tell the +JS backend to render it using xmlhttp communication. Because the web server +code does not need to be rpython, you have to supply some way of telling PyPy +what types can be returned out of it. This is done using the decorator +`@callback(retval = )` from `bltregistry`_. For example you may +provide:: + + from pypy.translator.js.lib.support import callback - @described(retval = {str:str}) + @callback(retval = {str:str}) def some_fun(self, some_arg = 3): .... -to tell compiler that this function will return mapping from string to -string and will take integer as an argument. You can simply specify the -arguments using keyword arguments with an example, or pass an args +The decorator tells the compiler that this function will return mapping from +string to string and will take integer as an argument. You can simply specify +the arguments using keyword arguments with an example, or pass an args dictionary to the described decorator. Then you must supply a method which returns JSON data in the server @@ -121,18 +113,21 @@ On the server side:: - from pypy.rpython.ootypesystem.bltregistry import BasicExternal, described + from pypy.rpython.ootypesystem.bltregistry import BasicExternal + from pypy.translator.js.lib.support import callback class PingHandler(BasicExternal): _render_xmlhttp = True - @described(retval={str:str}) + @callback(retval={str:str}) def ping(self, ping_str="aa"): return dict(response="PONG: %s" % ping_str) ping_handler = PingHandler() -This uses the BasicExternal class and the described decorator to let PyPy know how to deal with the input and output of the methods. You then need an instance of the class to pass to other parts of the RPython code. +This uses the BasicExternal class and the described decorator to let PyPy know +how to deal with the input and output of the methods. Now you can use an +instance of this class to pass to other parts of the RPython code. On the client you call the ping_handler.ping method with a callback:: @@ -170,6 +165,6 @@ working copy on-line right now, sorry) and a simple example of JS a `console`_. There is also a simple `django ping example`_. -.. _`here`: http://codespeak.net/svn/pypy/dist/pypy/translator/js/examples/start_bnb.py +.. _`here`: http://codespeak.net/svn/pypy/dist/pypy/translator/js/examples/bnb/start_bnb.py .. _`console`: http://codespeak.net/svn/pypy/dist/pypy/translator/js/examples/console.py -.. _`django ping example`: http://codespeak.net/svn/pypy/dist/pypy/translator/js/demo/jsdemo/djangoping +.. _`django ping example`: http://codespeak.net/svn/pypy/dist/pypy/translator/js/examples/djangoping Modified: pypy/branch/ast-experiments/pypy/doc/js/webapps_with_pypy.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/js/webapps_with_pypy.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/js/webapps_with_pypy.txt Mon Feb 26 08:45:45 2007 @@ -18,11 +18,14 @@ too much of anything in the (rather daunting) PyPy codebase besides the useful bits for web application development. +Note that this document describes APIs that are not mature and will change in +the near future. + PyPy features for web developers --------------------------------- Of course the 'killer feature' of PyPy for web application developers is the -ability to convert somewhat restricted Python code (aka RPython) into +ability to convert somewhat restricted Python code (aka `RPython`_) into JavaScript code. Unlike other libraries that perform similar functionality, PyPy really interprets the code, and produces 'lower level' JavaScript code, so it implements Python core language features like list comprehensions, and @@ -30,16 +33,17 @@ This particulary means that when a program is in RPython, you can run it on top of Python interpreter with the same results as translated to JS version. -However, mostly for demonstration purposes, some other interesting code is -available in the PyPy code package that may help developing web apps. The most -interesting of these I think is a library that transparently makes server-side -functionality available to client-side code, using XMLHttpRequest. This code -lives in a module in pypy/translator/js/examples that's called 'server.py', and -uses a library in pypy/translator/js called 'commproxy.py'. - -Note that the 'server.py' library currently is usable, but not complete: I -assume there will be quite some development and refinement later. This may mean -that certain things in this document are outdated. +However, there is some other interesting code available in the PyPy package +that may help developing web apps. The most interesting of these I think is a +library that transparently makes server-side functionality available to +client-side code, using XMLHttpRequest. This code lives in a module in +pypy/translator/js/examples that's called 'server.py', and uses a library in +pypy/translator/js called 'commproxy.py'. + +Note that the 'server.py' library currently is usable, but not complete nor +stable: I assume there will be quite some development and refinement later. +This may mean that certain things in this document are outdated. There +might be even a strong API rewrite at some point. Layers ------- @@ -72,7 +76,7 @@ exposed functions only support common datatypes (ints, strings, lists of ints, etc.) for arguments and return values, and have to have those - arguments and return values 'described' so that the rtyper system can + arguments and return values 'described' so that the annotator system can discover how they should be exposed, and so that the (transparently used) XMLHttpRequest handler and JSON serializer know how they should be treated @@ -87,6 +91,155 @@ Writing a simple application ----------------------------- -XXX hands-on guide to writing guestbook or something +To explain what needs to be done to write an application using all this, I +decided to add the (almost mandatory) classic guestbook example. To show off +the transparent XMLHttpRequest stuff, I chose to do one that stays on-screen +when adding a message, so there's no screen refresh, but apart from that it's +a very basic, simple guestbook. Of course the script is still too much code to +fit in this document nicely, so I placed it in some nice files: on for +`the server-side code`_ and one for `the client-side`_. Let's examine the +server side first. + +guestbook.py +++++++++++++ + +If you examine the code, you will see 2 classes, one function and some code +in the usual "if __name__ == '__main__'" block. The latter bit starts the +webserver, passing one of the classes (Handler) as a handler to a +BaseHTTPServer, which in turn uses the function (guestbook_client) to produce +JavaScript, and the class (ExportedMethods) to serve 'AJAX' methods from. + +This will be what a general PyPy web application (using commproxy) will look +like: a set of HTTP methods (web pages and scripts) on a Handler class, a set +of 'RPC' methods on an ExportedMethods class, a main loop and perhaps some +helper functionality (e.g. to convert RPython to JS). Let's examine the two +classes in more detail. + +Handler +~~~~~~~ + +The Handler class is a normal BaseHTTPRequestHandler subclass, but with some +pre-defined HTTP handlers (do_GET et al) that dispatch actual content +generation to user-defined methods. If a '/' path is requested from the server, +a method called 'index' is called, else the path is split on slashes, and the +first bit, with dots replaced by underscores, is used to find a method, the +other parts passed to that method as arguments. So calling '/foo.bar/baz' will +result in the method 'foo_bar' getting called with argument 'baz'. + +Note that a method needs to have an attribute 'exposed' set to True to actually +expose the method, if this attribute is not set requesting the path will result +in a 404 error. Methods that aren't exposed can be used for internal purposes. + +There is some helper functionality, such as the Static class to serve static +files and directories, in the pypy/translator/js/lib/server.py. + +(Note that even though currently BaseHTTPServer is used to deal with HTTP, +this will likely change in the future, in favour of something like CherryPy.) + +ExportedMethods +~~~~~~~~~~~~~~~ + +The ExportedMethods class contains methods that are (through some magic) +exposed to the client side, in an RPC-like fashion. This is implemented using +XMLHttpRequest and JSON: when from the client-side a method is called here, +the arguments to the method will be serialized and sent to the server, the +method is called, the return value is serialized again and sent to the client, +where a callback (registered on calling the method) is called with the return +value as argument. Methods on ExportedMethods contain normal, unrestricted +Python code, but do need to have the arguments and return value described in +order for the proxy mechanism to deal with them. + +Let's take a look at the 'get_messages' method. The 'callback' decorator that +wraps it is used to tell the proxy mechanism what arguments and return value +is used (arguments can also be determined by examining the function signature, +so only have to be provided when the function signature doesn't describe +default values), using that decorator will mark the method for exposure. This +particular method does not have arguments passed to it from the client, but +does have a return value: a list of strings. + +The second message on this class, 'add_message', does have a set of arguments, +which both have a string value, both of which are described in the function +arguments (as default values). + +guestbook_client +~~~~~~~~~~~~~~~~ + +This function imports a Python (or RPython, actually) module and commands +PyPy to convert a set of functions in it to JavaScript. This is all you need +to do to get a conversion done, the function returns a string of directly +executable JavaScript with the functions made available under their original +name. + +guestbook_client.py ++++++++++++++++++++ + +This contains the client-side code. It contains a couple of functions to +display messages and add messages to the guestbook, all relatively simple, +but there are a couple of things that need explanation. + +First thing to notice is of course that the code is RPython. This allows PyPy +to translate it to JavaScript (and a lot of other things :), but does mean +there are some restrictions: RPython is less dynamic than normal Python. For +instance, you need to make sure that PyPy knows in advance of what types +variables are, so changing a variable type, or writing functions that allow +different types of variables (Python's 'duck typing') is not allowed. + +Another odd thing are the imports: these are ignored on the client. They +are only there to satisfy the RPython to JavaScript translator, and to allow +running the code as 'normal' Python, for instance when testing. Both the 'dom' +object, and 'exported_methods' are made available on the client by some +commproxy magic. + +In the functions, there are some other things to note. The 'exported_methods' +variable is a reference to the exported_methods instance in guestbook.py, but +because there's the commproxy between the client and server, the methods are +wrapped, and the signatures are changed. The methods all need an additional +argument, 'callback', when called from the client side, and rather than +returning the return value directly, this callback is called with the return +value as argument. + +Finishing up +++++++++++++ + +The previously described components together already make up a working web +application. If you run the 'guestbook.py' script, the main loop bit on the +bottom will be triggered, passing the Handler class to some BaseHTTPRequest +server, which will start waiting for a request. + +If a browser is pointed to http://localhost:8008/ (the root of the +application), the 'index' method will be called, which presents the HTML page +with the form. A script tag will make that the JavaScript is retrieved from the +server, which is built on-the-fly (if required) from the RPython +'guestbook_client.py' file. An 'onload' handler on the tag will trigger +the 'init_guestbook()' function in this JS, which in turn calls the server's +'exported_methods.get_messages()' function that provides the initial page +content. + +If the form is filled in and the 'submit' button pressed, the 'add_message()' +function is called, which gets the data from the form and calls the server's +'exported_methods.add_message()' function. This then returns a string version +of the message back to the client (to the '_add_message_callback' function) +where it is presented. + +All this code is written without having to care about XMLHttpRequest and +serialization, with a simple server-side interface, and in a testable manner. + +Conclusion +---------- + +Even though RPython is somewhat hard to debug sometimes, and the tools are +still a little rough around the edges sometimes, PyPy can already be a valuable +tool for web developers, with RPython to make code easier to write and test, +and the commproxy to help dealing with asynchronous server calls and +serialization. Do not expect that PyPy does not try to 'magically' make all web +development problems go away: you will still need to manually write +client-side code, and still need to take care for dealing with browsers and +such, except not in JavaScript but in RPython, and with the 'AJAX' stuff +nicely tucked away. There may be future developments that will provide +higher-level layers, and client-side widgets and such, but currently it's +still 'work as usual', but with somewhat nicer (we hope ;) tools. .. _`RPython`: ../coding-guide.html#restricted-python +.. _`the server-side code`: http://codespeak.net/svn/pypy/dist/pypy/translator/js/examples/guestbook.py +.. _`the client-side`: http://codespeak.net/svn/pypy/dist/pypy/translator/js/examples/guestbook_client.py + Modified: pypy/branch/ast-experiments/pypy/doc/js/whatis.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/js/whatis.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/js/whatis.txt Mon Feb 26 08:45:45 2007 @@ -1,6 +1,6 @@ -============================================ -What is pypy.js (JavaScript backend of pypy) -============================================ +============================================= +What is pypy.web (JavaScript backend of pypy) +============================================= Author: ======= @@ -10,50 +10,49 @@ Purpose: ======== -This document explains what pypy.js is and (just as important) what it is not. +This document explains what pypy.web is and (just as important) what it is not. What is it? ----------- -Pypy.js is mostly RPython to javascript converter. Nothing more, nothing -less. By `using`_ it you can write down RPython code (static enough subset -of python) which get translated into JavaScript and then run it in a browser. -As an addon you can get access to semi-transparent rendering of AJAX calls. - -This means that you might expect python semantics: ie. when trying to get -non-existing key from dictionary, you'll get KeyError, not undefined element. -If you prefer JavaScript semantics there is no point in using pypy.js, if -you instead prefer Python semantics this is a good point. Some of the -errors might appear at compile time (such as wrong number of arguments -to function, non-existing global variable, non-existing method call). - -This also means that you will get python features - such as multi-inheritance, -exception handling etc. But you'll not get python dynamic features - modifying -dict access etc. - -This also means that it is much easier to write code in pypy.js than in -JavaScript itself. The whole b'n'b demo is just about 250 lines of code, with -many AJAX calls. Imagine writing it in JavaScript. +Pypy.web is an RPython to JavaScript converter and a set of tools which +evolved during PyPy developement. By `using`_ it you can write RPython +code (a subset of Python static enough to compile), translate it into +JavaScript and then run it in a browser. As an add-on you can +semi-transparently make 'AJAX' (JavaScript to server) calls. + +RPython to JavaScript +--------------------- + +When writing RPython you can expect full Python semantics from code you write: +ie. when you're trying to get a non-existing key from a dictionary, you'll get +a KeyError, not an undefined element. Also things like Python's +object-orientation are fully supported. This in contrast to other efforts of +getting Python converted to JavaScript, which usually provide only a very small +subset of Python, and with JavaScript semantics. + +This means that you will get some Python features - such as exception handling, +list comprehensions, etc., but do understand that you will _not_ get some of +the more 'dynamic' features of Python - overloading operators, dynamic +modifications of \_\_dict\_\_ and such, because that will break RPython. + +Additional features +------------------- + +It is much easier to write code in pypy.web than in JavaScript itself. The +whole `b'n'b demo`_ is just about 250 lines of code, with many AJAX calls. +Imagine writing it in JavaScript, it would easily exceed the number of lines, +even with a nice library to handle the AJAX, and would almost certainly be less +elegant and readable. + +Errors may appear already at compile time (such as providing the wrong number +of arguments to a function, using a non-existing global variable, calling a +non-existing method). -We can say that pypy.js extends Mochikit's motto ("Makes JavaScript suck -less"), by "Makes JavaScript suck less, by not using it". +There are some facilities for testing your Python code (about to be translated +to a JavaScript) on top of Python. For further details see `testing`_ .. _`using`: using.html +.. _`b'n'b demo`: http://play1.codespeak.net:7070 +.. _`testing`: testing.html -What is it not? ---------------- - -Pypy.js is definitely not a browser-abstract library (with exceptions to -the semi-transparent AJAX calls, which are trying to be browser-independent). -Pypy.js is trying to expose the browser API as it comes, with all shortcomings. -If you need something like that you can expose any existing JS library -(there is an example with a few mochikit calls in modules). But it seems evident -that writing such a library on top of pypy.js sounds more interesting. - -Pypy.js is not a browser for python. Right now you cannot run your DOM-dependent -code on top of CPython (and this is unlikely to change in a future, because -we don't want to have just-another-browser-problem, do we?). Altough because -RPython is just subset of python, nothing stops you from separating code -DOM-dependent from other and running other part on top of CPython. Or, if you -really want to, from writing DOM library in CPython itself (just a library, no -mangling with compiler at all) which will allow you to run that code. Modified: pypy/branch/ast-experiments/pypy/doc/news.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/news.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/news.txt Mon Feb 26 08:45:45 2007 @@ -5,7 +5,7 @@ nonsense, isn't it? `more...`_ .. _Python: http://www.python.org/doc/current/ref/ref.html -.. _`more...`: http://codespeak.net/pypy/dist/pypy/doc/architecture.html#mission-statement +.. _`more...`: architecture.html#mission-statement The following is a list of planned PyPy events, most of which @@ -15,6 +15,26 @@ .. _`iCalendar format`: webcal://pypycal.sabi.net///calendars/PyPy.ics .. _eventhistory: eventhistory.html +PyPy 0.99.0: optimizations, backends, new object spaces and more +================================================================== + +We are proud to release PyPy 0.99.0, our fifth public release. See +the `release announcement `__ to read about the +many new features in this release. See also our detailed instructions on +how to `get started`_. *(February 17th, 2007)* + +.. _`get started`: getting-started.html + + +py lib 0.9.0: py.test, distributed execution, greenlets and more +================================================================== + +Our development support and testing library was publically released, see the +`0.9 release announcement `__ +and its extensive `online documentation `__. +(February 15th, 2007) + + PyPy Trillke Sprints upcoming, 25-28th Feb and 1-5th March 2007 ================================================================== Modified: pypy/branch/ast-experiments/pypy/doc/object-optimizations.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/object-optimizations.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/object-optimizations.txt Mon Feb 26 08:45:45 2007 @@ -31,6 +31,8 @@ perform repeated string additions in a loop without using the ``"".join(list_of_strings)`` pattern. +You can this feature enable with the :config:`objspace.std.withstrjoin` option. + string-slice objects -------------------- @@ -46,6 +48,8 @@ string. There is also a minimum number of characters below which being lazy is not saving any time over making the copy). +You can this feature enable with the :config:`objspace.std.withstrslice` option. + Integer optimizations ===================== @@ -57,6 +61,7 @@ time a new integer object is created it is checked whether the integer is small enough to be retrieved from the cache. +You can enable this feature with the :config:`objspace.std.withsmallint` option. integers as tagged pointers --------------------------- @@ -82,6 +87,8 @@ the whole information in the string-keyed dictionary is copied over into another RPython-dictionary, where arbitrary Python objects can be used as keys. +You can enable this feature with the :config:`objspace.std.withstrdict` option. + multi-dicts ----------- @@ -98,6 +105,9 @@ general representation that can store arbitrary keys). In addition there are more specialized dictionary implementations for various purposes (see below). +You can enable this feature with the :config:`objspace.std.withmultidict` +option. + sharing dicts ------------- @@ -116,6 +126,9 @@ dicts: the representation of the instance dict contains only a list of values. +You can enable this feature with the :config:`objspace.std.withsharingdict` +option. + builtin-shadowing ----------------- @@ -140,6 +153,10 @@ common case, the program didn't do any of these; the proper builtin can then be called without using any dictionary lookup at all. +You can enable this feature with the +:config:`objspace.opcodes.CALL_LIKELY_BUILTIN` option. + + List optimizations ================== @@ -155,6 +172,8 @@ created. This gives the memory and speed behaviour of ``xrange`` and the generality of use of ``range``, and makes ``xrange`` essentially useless. +You can enable this feature with the :config:`objspace.std.withrangelist` +option. multi-lists ----------- @@ -167,6 +186,9 @@ implement the same optimization is that range lists came earlier and that multi-lists are not tested that much so far). +You can enable this feature with the :config:`objspace.std.withmultilist` +option. + fast list slicing ------------------ @@ -178,6 +200,8 @@ list slice is only created lazily, that is when either the original list or the sliced list is mutated. +You can enable this feature with the :config:`objspace.std.withfastslice` +option. .. _`Neal Norwitz on pypy-dev`: http://codespeak.net/pipermail/pypy-dev/2005q4/002538.html @@ -199,6 +223,9 @@ shadowing the class attribute. If we know that there is no shadowing (since instance dict tells us that) we can save this lookup on the instance dictionary. +You can enable this feature with the :config:`objspace.std.withshadowtracking` +option. + Method caching -------------- @@ -212,3 +239,6 @@ lookup happens (this version is incremented every time the type or one of its base classes is changed). On subsequent lookups the cached version can be used, as long as the instance did not shadow any of its classes attributes. + +You can enable this feature with the :config:`objspace.std.withmethodcache` +option. Modified: pypy/branch/ast-experiments/pypy/doc/objspace-proxies.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/objspace-proxies.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/objspace-proxies.txt Mon Feb 26 08:45:45 2007 @@ -32,6 +32,9 @@ regular built-in objects (list objects, traceback objects, etc.), but completely under the control of the application. +Which object space to use can be chosen with :config:`objspace.name` option. + +.. _`Object Space`: objspace.html .. _thunk: @@ -120,7 +123,7 @@ with no initial value at all. It is possible to put a value into this object once, and only once, at any point in time. -This is not entierely unrelated to a lazily-computed object, except that +This is not entirely unrelated to a lazily-computed object, except that the object has no built-in knowledge about how it should compute itself. Trying to use such an object before it got a value results in a lock: the current thread is suspended, in the hope that another thread will @@ -157,7 +160,7 @@ other places merely pass it around, or do entirely unrelated things. Nevertheless, if a large application needs to be reviewed for security, -it must be entierely carefully checked, because it is possible that a +it must be entirely carefully checked, because it is possible that a bug at some apparently unrelated place could lead to a leak of sensitive information in a way that an external attacker could exploit. For example, if any part of the application provides web services, an @@ -451,15 +454,17 @@ Among the unique features of PyPy, there is as well the possibility of having multiple implementations of builtin types. Multiple performance -optimisations using this features are already implemented, some -hints are in the `Object Space`_ document. +optimisations using this features are already implemented, see the document +about `alternative object implementations`_. Transparent proxy are implementations of some (maybe all at some point) objects like functions, objects, lists etc. which forwards all operations performed on these object to app-level functions which have specific signatures. -.. _`Object Space`: objspace.html#object-types +To enable them, use the :config:`objspace.std.withtproxy` option. + +.. _`alternative object implementations`: object-optimizations.html Example: --------- @@ -510,6 +515,18 @@ does not show up at all (indeed the type is the only aspect of the instance that the controller cannot change). +Provided API: +------------- + +Transparent proxy provides two magic functions appearing in the pypymagic module. + +* `transparent_proxy` - a basic function to create proxy object. + +* `get_transparent_controller` - for some use-cases there is need to know + when an object is a transparent proxy. This function returns an original controller + (a callable) or None in case this is a normal Python object. This is + the only official way of distinguishing transparent objects from normal ones. + Further points of interest: --------------------------- @@ -541,8 +558,8 @@ frames. .. _`standard object space`: objspace.html#the-standard-object-space -.. _`proxy_helpers.py`: http://codespeak.net/svn/pypy/dist/pypy/objspace/std/proxy_helpers.py -.. _`proxyobject.py`: http://codespeak.net/svn/pypy/dist/pypy/objspace/std/proxyobject.py -.. _`transparent.py`: http://codespeak.net/svn/pypy/dist/pypy/objspace/std/transparent.py +.. _`proxy_helpers.py`: ../../pypy/objspace/std/proxy_helpers.py +.. _`proxyobject.py`: ../../pypy/objspace/std/proxyobject.py +.. _`transparent.py`: ../../pypy/objspace/std/transparent.py .. include:: _ref.txt Modified: pypy/branch/ast-experiments/pypy/doc/objspace.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/objspace.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/objspace.txt Mon Feb 26 08:45:45 2007 @@ -58,6 +58,8 @@ The sources of PyPy contain the various object spaces in the directory `objspace/`_. +To choose which object space to use, use the :config:`objspace.name` option. + .. _`application-level`: coding-guide.html#application-level .. _`interpreter-level`: coding-guide.html#interpreter-level .. _`in another document`: translation.html Modified: pypy/branch/ast-experiments/pypy/doc/rctypes.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/rctypes.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/rctypes.txt Mon Feb 26 08:45:45 2007 @@ -414,7 +414,7 @@ * ``getitem()`` and ``setitem()`` - called when the RPython program uses the ``[ ]`` notation to index the full Python object -If necessary, the controller can also choose to entierely override the +If necessary, the controller can also choose to entirely override the default annotating and rtyping behavior and insert its own. This is useful for cases where the method cannot be implemented in RPython, e.g. in the presence of a polymorphic operation that would cause the Modified: pypy/branch/ast-experiments/pypy/doc/rlib.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/rlib.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/rlib.txt Mon Feb 26 08:45:45 2007 @@ -139,7 +139,11 @@ =========== The rsocket_ module contains an RPython implementation of the functionality of -the socket standard library with a slightly different interface. +the socket standard library with a slightly different interface. The +difficulty with the Python socket API is that addresses are not "well-typed" +objects: dependending on the address family they are tuples, or strings, and +so on, which is not suitable for RPython. Instead, ``rsocket`` contains +a hierarchy of Address classes, in a typical static-OO-programming style. .. _rsocket: ../../pypy/rlib/rsocket.py Modified: pypy/branch/ast-experiments/pypy/doc/statistic/loc.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/statistic/loc.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/statistic/loc.txt Mon Feb 26 08:45:45 2007 @@ -1,571 +1,1256 @@ Lines of Code in the pypy subtree date, lines of code, lines of testcode -2006/07/17, 243883, 61480 -2006/07/16, 243621, 61344 -2006/07/15, 243520, 61313 -2006/07/14, 243459, 61314 -2006/07/13, 243406, 61287 -2006/07/12, 243281, 61279 -2006/07/11, 242885, 60796 -2006/07/10, 242273, 60532 -2006/07/09, 242229, 60524 -2006/07/08, 241573, 60173 -2006/07/07, 239546, 59615 -2006/07/06, 238884, 59396 -2006/07/05, 238901, 59013 -2006/07/04, 238724, 59012 -2006/07/03, 238674, 59009 -2006/07/02, 238651, 59001 -2006/07/01, 238361, 58943 -2006/06/30, 238742, 58961 -2006/06/29, 238832, 58938 -2006/06/28, 238484, 58830 -2006/06/27, 238361, 58778 -2006/06/26, 238162, 58755 -2006/06/25, 237964, 58689 -2006/06/24, 237586, 58460 -2006/06/23, 237265, 58460 -2006/06/22, 237228, 58454 -2006/06/21, 236934, 58324 -2006/06/20, 237711, 58324 -2006/06/19, 237290, 58140 -2006/06/18, 237243, 57759 -2006/06/17, 237227, 57705 -2006/06/16, 237223, 57674 -2006/06/15, 237010, 57438 -2006/06/14, 236747, 57335 -2006/06/13, 236849, 57211 -2006/06/12, 237246, 57071 -2006/06/11, 236558, 56800 -2006/06/10, 236447, 56788 -2006/06/09, 236391, 56722 -2006/06/08, 237731, 58790 -2006/06/07, 237402, 58537 -2006/06/06, 236730, 58474 -2006/06/05, 236286, 58331 -2006/06/04, 236020, 58196 -2006/06/03, 236072, 57355 -2006/06/02, 235690, 57191 -2006/05/31, 235493, 57122 -2006/05/30, 235501, 57122 -2006/05/29, 204409, 57115 -2006/05/28, 203670, 55592 -2006/05/27, 203653, 55592 -2006/05/26, 203563, 55563 -2006/05/25, 203490, 55570 -2006/05/24, 203342, 55383 -2006/05/23, 199431, 55391 -2006/05/22, 199114, 55577 -2006/05/21, 199040, 55475 -2006/05/20, 198903, 55211 -2006/05/19, 197404, 55047 -2006/05/18, 197223, 54967 -2006/05/17, 197172, 55029 -2006/05/16, 196171, 54954 -2006/05/15, 195827, 54685 -2006/05/14, 195622, 54424 -2006/05/13, 196169, 54314 -2006/05/12, 195535, 54202 -2006/05/11, 195221, 54028 -2006/05/10, 194921, 53800 -2006/05/09, 194384, 53587 -2006/05/08, 194325, 53503 -2006/05/07, 194263, 53544 -2006/05/06, 194029, 53366 -2006/05/05, 193577, 53008 -2006/05/04, 193297, 52720 -2006/05/03, 193237, 52548 -2006/05/02, 192950, 52435 -2006/05/01, 192740, 52245 -2006/04/30, 192740, 52241 -2006/04/29, 192654, 52220 -2006/04/28, 192251, 51836 -2006/04/27, 191806, 51553 -2006/04/26, 191265, 51180 -2006/04/25, 191060, 50946 -2006/04/24, 190581, 50716 -2006/04/23, 190100, 50476 -2006/04/22, 189708, 50343 -2006/04/21, 189444, 50233 -2006/04/20, 189386, 50060 -2006/04/19, 188764, 50000 -2006/04/18, 188368, 49760 -2006/04/17, 188185, 49343 -2006/04/16, 188073, 49083 -2006/04/15, 187874, 49072 -2006/04/14, 187650, 48936 -2006/04/13, 187417, 48900 -2006/04/12, 187328, 48773 -2006/04/11, 187071, 48645 -2006/04/10, 186785, 48474 -2006/04/09, 186394, 48077 -2006/04/08, 178733, 47684 -2006/04/07, 178276, 47631 -2006/04/06, 177675, 47389 -2006/04/05, 178170, 47256 -2006/04/04, 176373, 47399 -2006/04/03, 175795, 47186 -2006/04/02, 175537, 47085 -2006/04/01, 175211, 46910 -2006/03/31, 174915, 46889 -2006/03/30, 174706, 46787 -2006/03/29, 174706, 46762 -2006/03/28, 174663, 46741 -2006/03/27, 174514, 46658 -2006/03/26, 174271, 46600 -2006/03/25, 174223, 46600 -2006/03/24, 174140, 46532 -2006/03/23, 173493, 46142 -2006/03/22, 172896, 45937 -2006/03/21, 172152, 45725 -2006/03/20, 171933, 45506 -2006/03/19, 171607, 45205 -2006/03/18, 171465, 45202 -2006/03/17, 171385, 45125 -2006/03/16, 171176, 44945 -2006/03/15, 170968, 44841 -2006/03/14, 170944, 44877 -2006/03/13, 170830, 44738 -2006/03/12, 170626, 44743 -2006/03/11, 170597, 44743 -2006/03/10, 170589, 44743 -2006/03/09, 170579, 44855 -2006/03/08, 170180, 44731 -2006/03/07, 170046, 44647 -2006/03/06, 170008, 44611 -2006/03/04, 169917, 44512 -2006/03/03, 169915, 44512 -2006/03/02, 169723, 44499 -2006/03/01, 169535, 44112 -2006/02/28, 169197, 43619 -2006/02/27, 169940, 43442 -2006/02/26, 169558, 43279 -2006/02/25, 169557, 43279 -2006/02/23, 169557, 43279 -2006/02/22, 169433, 43239 -2006/02/21, 169602, 43297 -2006/02/20, 169263, 43201 -2006/02/19, 168953, 43173 -2006/02/18, 168844, 43089 -2006/02/17, 168836, 43089 -2006/02/16, 168628, 42835 -2006/02/15, 168112, 42671 -2006/02/14, 168068, 42354 -2006/02/13, 167901, 42278 -2006/02/12, 167741, 41981 -2006/02/11, 167719, 41992 -2006/02/10, 167651, 41888 -2006/02/09, 167396, 41812 -2006/02/08, 167122, 41723 -2006/02/07, 166496, 41367 -2006/02/06, 166453, 41209 -2006/02/05, 166436, 41110 -2006/02/04, 166270, 40962 -2006/02/03, 166074, 40861 -2006/02/02, 165996, 40725 -2006/02/01, 165903, 40680 -2006/01/31, 165833, 40588 -2006/01/30, 165580, 40016 -2006/01/29, 165580, 40015 -2006/01/28, 165022, 39852 -2006/01/27, 165729, 39552 -2006/01/26, 164445, 39306 -2006/01/25, 163208, 38818 -2006/01/24, 162825, 38485 -2006/01/23, 162130, 38129 -2006/01/22, 161327, 37820 -2006/01/21, 161311, 37789 -2006/01/20, 161285, 37794 -2006/01/19, 161141, 37707 -2006/01/18, 160809, 37566 -2006/01/17, 160737, 37562 -2006/01/16, 160714, 37551 -2006/01/15, 160640, 37439 -2006/01/14, 160642, 37353 -2006/01/13, 160359, 37217 -2006/01/12, 160335, 37215 -2006/01/11, 160307, 37098 -2006/01/10, 160237, 37028 -2006/01/09, 159988, 36799 -2006/01/08, 159964, 36760 -2006/01/07, 159822, 36617 -2006/01/06, 159735, 36497 -2006/01/05, 159787, 36462 -2006/01/04, 159796, 36423 -2006/01/02, 159692, 36336 -2005/12/31, 159549, 36333 -2005/12/30, 159520, 36330 -2005/12/29, 159455, 36319 -2005/12/27, 159374, 36285 -2005/12/25, 159321, 36247 -2005/12/24, 159321, 36197 -2005/12/23, 159305, 36195 -2005/12/22, 159276, 36124 -2005/12/21, 159197, 36060 -2005/12/20, 159100, 36030 -2005/12/19, 159083, 36018 -2005/12/18, 159070, 35868 -2005/12/17, 158902, 35713 -2005/12/16, 158822, 35712 -2005/12/15, 158751, 35651 -2005/12/14, 158266, 35238 -2005/12/13, 158273, 35108 -2005/12/12, 157583, 35018 -2005/12/11, 157466, 35017 -2005/12/10, 157305, 34891 -2005/12/09, 156931, 34791 -2005/12/08, 156568, 33832 -2005/12/07, 154963, 33506 -2005/12/06, 154069, 33216 -2005/12/05, 154085, 33187 -2005/12/04, 154104, 33187 -2005/12/03, 153937, 33205 -2005/12/02, 153897, 33205 -2005/12/01, 153738, 33186 -2005/11/30, 153293, 33011 -2005/11/29, 153246, 33011 -2005/11/28, 153190, 33011 -2005/11/27, 152884, 32862 -2005/11/25, 152830, 32830 -2005/11/23, 152830, 32830 -2005/11/23, 152830, 32830 -2005/11/22, 152844, 32830 -2005/11/21, 152822, 32825 -2005/11/19, 152702, 32718 -2005/11/18, 152704, 32718 -2005/11/17, 152702, 32718 -2005/11/16, 152126, 32718 -2005/11/15, 152151, 32690 -2005/11/14, 152151, 32690 -2005/11/13, 152123, 32696 -2005/11/12, 152031, 32696 -2005/11/11, 152031, 32696 -2005/11/10, 151995, 32548 -2005/11/09, 152051, 32550 -2005/11/08, 152062, 32545 -2005/11/07, 152059, 32545 -2005/11/06, 152076, 32545 -2005/11/05, 152018, 32514 -2005/11/04, 151923, 32514 -2005/11/03, 151918, 32514 -2005/11/02, 151918, 32514 -2005/11/01, 151913, 32508 -2005/10/31, 151905, 32496 -2005/10/30, 151701, 32470 -2005/10/29, 151768, 32470 -2005/10/28, 151704, 32470 -2005/10/27, 151521, 32461 -2005/10/26, 156875, 32344 -2005/10/25, 156761, 31982 -2005/10/24, 156358, 31940 -2005/10/23, 156153, 31954 -2005/10/22, 156124, 31942 -2005/10/21, 156006, 31832 -2005/10/20, 155670, 31818 -2005/10/19, 155548, 31764 -2005/10/18, 155323, 31407 -2005/10/17, 155558, 31306 -2005/10/16, 155503, 31283 -2005/10/15, 155217, 31128 -2005/10/14, 154456, 30886 -2005/10/13, 153234, 30314 -2005/10/12, 153415, 30315 -2005/10/11, 152893, 30132 -2005/10/10, 152248, 29917 -2005/10/09, 150340, 28002 -2005/10/08, 150336, 28002 -2005/10/07, 150310, 27981 -2005/10/06, 150147, 27867 -2005/10/05, 161650, 28403 -2005/10/04, 161652, 28325 -2005/10/03, 161470, 28231 -2005/10/02, 161405, 28148 -2005/10/01, 161217, 28060 -2005/09/30, 161908, 28024 -2005/09/29, 161926, 27969 -2005/09/28, 161945, 27912 -2005/09/27, 161746, 27929 -2005/09/26, 161707, 27865 -2005/09/25, 161178, 27660 -2005/09/24, 161159, 27660 -2005/09/23, 161014, 27616 -2005/09/22, 160766, 27591 -2005/09/21, 160716, 27585 -2005/09/20, 160520, 27565 -2005/09/19, 160423, 27449 -2005/09/18, 160256, 27417 -2005/09/17, 160147, 27417 -2005/09/16, 160250, 27355 -2005/09/15, 160186, 27308 -2005/09/14, 160100, 27289 -2005/09/13, 160295, 27222 -2005/09/12, 159914, 27003 -2005/09/11, 159590, 26842 -2005/09/10, 159474, 26604 -2005/09/09, 159532, 26410 -2005/09/08, 159095, 26194 -2005/09/07, 159089, 26078 -2005/09/06, 158929, 26044 -2005/09/05, 153175, 25883 -2005/09/04, 152749, 25883 -2005/09/03, 152637, 25829 -2005/09/02, 152608, 25829 -2005/09/01, 152432, 25673 -2005/08/31, 152475, 25673 -2005/08/30, 152432, 25655 -2005/08/29, 152082, 25747 -2005/08/28, 151807, 25680 -2005/08/27, 151828, 25688 -2005/08/26, 151296, 25435 -2005/08/25, 150138, 25151 -2005/08/24, 150268, 24873 -2005/08/23, 149698, 24405 -2005/08/22, 149110, 24116 -2005/08/20, 148620, 23925 -2005/08/19, 148620, 23925 -2005/08/18, 147807, 23409 -2005/08/17, 147700, 23385 -2005/08/16, 147613, 23353 -2005/08/15, 147602, 23349 -2005/08/14, 147325, 23329 -2005/08/13, 147307, 23316 -2005/08/12, 147266, 23259 -2005/08/11, 146795, 23113 -2005/08/10, 146311, 22828 -2005/08/09, 145674, 21822 -2005/08/08, 145076, 21661 -2005/08/07, 144812, 21489 -2005/08/06, 144699, 21466 -2005/08/05, 144471, 21098 -2005/08/04, 144278, 20895 -2005/08/03, 143636, 20718 -2005/08/02, 141678, 19969 -2005/07/31, 140413, 19866 -2005/07/30, 140023, 19365 -2005/07/29, 139511, 19128 -2005/07/28, 139093, 18793 -2005/07/27, 135175, 18670 -2005/07/26, 134555, 18519 -2005/07/25, 133921, 18324 -2005/07/24, 133359, 18035 -2005/07/23, 133322, 18020 -2005/07/22, 133289, 18016 -2005/07/21, 133068, 17799 -2005/07/20, 132758, 17419 -2005/07/19, 132611, 17276 -2005/07/18, 135877, 17663 -2005/07/15, 135695, 17468 -2005/07/14, 135576, 17401 -2005/07/13, 135456, 17254 -2005/07/12, 134835, 17106 -2005/07/11, 134472, 16944 -2005/07/10, 134279, 16770 -2005/07/09, 134189, 16711 -2005/07/07, 134141, 16707 -2005/07/06, 133732, 16589 -2005/07/05, 132622, 16446 -2005/07/04, 127161, 16176 -2005/07/03, 126972, 16148 -2005/07/02, 114021, 15697 -2005/07/01, 114035, 15625 -2005/06/30, 113952, 15603 -2005/06/29, 113952, 15603 -2005/06/28, 113886, 15562 -2005/06/26, 113883, 15561 -2005/06/25, 113704, 15474 -2005/06/24, 113296, 15214 -2005/06/23, 114363, 15004 -2005/06/22, 113623, 14689 -2005/06/21, 113628, 14678 -2005/06/20, 113060, 14432 -2005/06/19, 112774, 14332 -2005/06/18, 112462, 14266 -2005/06/17, 111660, 14165 -2005/06/16, 111272, 13979 -2005/06/15, 111031, 13891 -2005/06/14, 111088, 13725 -2005/06/13, 112895, 13446 -2005/06/12, 112856, 13332 -2005/06/11, 112825, 13178 -2005/06/10, 112796, 13151 -2005/06/09, 112505, 13115 -2005/06/08, 113246, 12999 -2005/06/07, 104662, 12955 -2005/06/06, 104657, 12995 -2005/06/05, 103949, 12880 -2005/06/04, 102228, 13525 -2005/06/03, 101734, 13461 -2005/06/02, 101619, 13444 -2005/06/01, 101442, 13353 -2005/05/31, 100942, 13201 -2005/05/30, 100321, 13014 -2005/05/29, 100002, 12811 -2005/05/28, 99760, 12742 -2005/05/27, 99874, 12742 -2005/05/26, 99681, 12701 -2005/05/25, 99295, 12693 -2005/05/24, 99080, 12693 -2005/05/23, 98647, 12664 -2005/05/22, 73426, 12608 -2005/05/21, 73363, 12587 -2005/05/20, 71816, 12433 -2005/05/19, 71673, 12429 -2005/05/18, 79865, 12413 -2005/05/17, 66595, 13184 -2005/05/16, 66562, 13121 -2005/05/15, 66548, 13088 -2005/05/14, 64917, 12761 -2005/05/13, 64811, 12749 -2005/05/12, 64790, 12735 -2005/05/11, 64484, 12685 -2005/05/10, 64144, 12557 -2005/05/09, 63755, 12352 -2005/05/08, 63690, 12349 -2005/05/07, 63552, 12329 -2005/05/06, 63489, 12329 -2005/05/05, 63428, 12267 -2005/05/04, 63289, 12171 -2005/05/03, 63010, 12163 -2005/05/02, 62628, 12096 -2005/05/01, 62128, 11466 -2005/04/30, 63937, 16140 -2005/04/29, 63797, 15974 -2005/04/28, 61815, 15250 -2005/04/27, 61763, 15262 -2005/04/26, 60919, 15192 -2005/04/25, 60595, 15369 -2005/04/24, 58807, 14955 -2005/04/23, 58565, 14939 -2005/04/22, 58565, 14939 -2005/04/21, 58521, 14898 -2005/04/20, 58504, 14881 -2005/04/19, 59131, 14097 -2005/04/18, 59087, 14047 -2005/04/17, 59013, 14000 -2005/04/16, 59050, 13979 -2005/04/15, 58914, 13931 -2005/04/14, 58819, 13856 -2005/04/13, 58464, 13699 -2005/04/12, 58127, 13668 -2005/04/11, 57717, 13522 -2005/04/10, 57578, 13545 -2005/04/09, 57270, 13538 -2005/04/08, 57306, 13520 -2005/04/07, 56983, 13422 -2005/04/06, 56885, 13380 -2005/04/05, 56748, 13356 -2005/04/04, 56579, 13340 -2005/04/03, 56272, 13325 -2005/04/02, 56072, 13325 -2005/04/01, 55751, 13280 -2005/03/31, 54997, 13276 -2005/03/30, 54890, 13167 -2005/03/29, 54788, 13157 -2005/03/28, 54272, 13111 -2005/03/27, 54216, 13108 -2005/03/24, 54198, 13096 -2005/03/23, 54091, 13093 -2005/03/22, 54019, 15607 -2005/03/21, 50164, 15056 -2005/03/20, 50569, 15353 -2005/03/19, 48756, 11768 -2005/03/17, 48791, 11755 -2005/03/15, 48683, 11755 -2005/03/14, 48645, 11755 -2005/03/13, 48629, 11754 -2005/03/12, 48605, 11671 -2005/03/11, 48566, 11653 -2005/03/10, 48463, 11638 -2005/03/06, 47912, 11638 -2005/03/05, 47888, 11628 -2005/03/04, 47719, 11596 -2005/03/03, 47863, 11666 -2005/03/02, 47765, 11661 -2005/03/01, 47635, 11565 -2005/02/28, 47752, 11643 -2005/02/27, 47624, 11627 -2005/02/26, 47624, 11627 -2005/02/25, 47623, 11627 -2005/02/24, 47429, 11567 -2005/02/23, 47309, 11563 -2005/02/22, 47252, 11557 -2005/02/21, 47207, 11362 -2005/02/19, 47139, 11363 -2005/02/18, 46949, 11283 -2005/02/17, 46971, 11167 -2005/02/16, 46912, 11167 -2005/02/15, 46912, 11167 -2005/02/14, 46513, 11092 -2005/02/13, 46454, 11085 -2005/02/13, 46454, 11085 -2005/02/13, 46454, 11085 -2005/02/11, 43929, 11085 -2005/02/10, 43918, 11075 -2005/02/09, 37442, 11055 -2005/02/08, 37341, 11046 -2005/02/07, 37299, 11031 -2005/02/06, 37347, 11064 -2005/02/05, 36551, 10929 -2005/02/04, 36471, 10929 -2005/02/03, 37045, 10890 -2005/02/02, 36931, 10843 -2005/02/01, 36390, 10292 -2005/01/31, 35541, 10266 -2005/01/30, 35430, 10266 -2005/01/29, 35440, 10266 -2005/01/28, 35443, 9696 -2005/01/27, 31118, 9024 -2005/01/26, 33547, 9492 -2005/01/25, 33281, 9335 -2005/01/24, 32679, 8707 -2005/01/23, 32486, 8707 -2005/01/22, 32108, 8555 -2005/01/20, 32091, 8560 -2005/01/19, 32110, 8543 -2005/01/18, 32110, 8166 -2005/01/17, 32110, 8166 -2005/01/16, 32108, 8165 -2005/01/15, 32108, 8154 -2005/01/14, 32103, 8154 -2005/01/13, 32095, 8154 -2005/01/12, 32119, 8145 -2005/01/11, 30569, 8097 -2005/01/10, 30702, 8130 -2005/01/09, 30701, 8248 -2005/01/08, 30701, 8256 -2005/01/03, 30565, 8352 -2005/01/02, 30565, 8357 -2005/01/01, 30565, 8357 -2004/12/30, 30860, 8378 -2004/12/27, 30860, 8375 -2004/12/24, 30812, 8383 -2004/12/22, 30939, 8352 -2004/12/20, 30881, 8352 -2004/12/19, 30881, 8352 -2004/12/18, 30760, 8352 -2004/12/17, 30748, 8342 -2004/12/16, 30679, 8332 -2004/12/13, 30652, 8332 -2004/12/10, 30631, 8332 -2004/12/09, 30622, 8318 -2004/12/08, 30490, 8273 -2004/12/07, 30489, 8273 -2004/12/06, 30465, 8242 -2004/12/04, 30404, 8242 -2004/11/30, 30261, 8242 -2004/11/29, 30175, 8232 -2004/11/28, 30151, 8115 -2004/11/27, 30150, 8115 -2004/11/25, 30148, 8115 -2004/11/24, 30139, 8115 +2003-02-19, 1436, 0 +2003-02-20, 1603, 114 +2003-02-21, 2637, 401 +2003-02-22, 2921, 121 +2003-02-23, 3674, 969 +2003-02-24, 3674, 969 +2003-02-25, 3808, 998 +2003-02-26, 3808, 998 +2003-02-27, 3808, 998 +2003-02-28, 3847, 1054 +2003-03-01, 3854, 1056 +2003-03-03, 3865, 1114 +2003-03-04, 3865, 1116 +2003-03-18, 3865, 1116 +2003-04-06, 3865, 1116 +2003-04-11, 3865, 1116 +2003-04-18, 3892, 1221 +2003-04-19, 3943, 1273 +2003-05-22, 3943, 1273 +2003-05-25, 3943, 1273 +2003-05-26, 4239, 1414 +2003-05-27, 4714, 1668 +2003-05-28, 5603, 1847 +2003-05-29, 5735, 1883 +2003-05-30, 6515, 2380 +2003-05-31, 6927, 2393 +2003-06-01, 7144, 2396 +2003-06-02, 7152, 2400 +2003-06-05, 7195, 2400 +2003-06-06, 7212, 2400 +2003-06-07, 7215, 2400 +2003-06-08, 7228, 2390 +2003-06-09, 7230, 2390 +2003-06-13, 7356, 2387 +2003-06-14, 7436, 2387 +2003-06-15, 7436, 2387 +2003-06-16, 7558, 2411 +2003-06-17, 7568, 2411 +2003-06-18, 7708, 2465 +2003-06-19, 7796, 2460 +2003-06-20, 7794, 2467 +2003-06-21, 7823, 2479 +2003-06-22, 9536, 2608 +2003-06-23, 10196, 3153 +2003-06-24, 10675, 3428 +2003-06-28, 11165, 3571 +2003-06-29, 11173, 3579 +2003-06-30, 11173, 3579 +2003-07-01, 11336, 3597 +2003-07-02, 11344, 3597 +2003-07-03, 11344, 3597 +2003-07-04, 11344, 3597 +2003-07-06, 11354, 3597 +2003-07-07, 11354, 3597 +2003-07-08, 11544, 3621 +2003-07-10, 11544, 3621 +2003-07-12, 11544, 3621 +2003-07-13, 11544, 3621 +2003-07-14, 11617, 3625 +2003-07-15, 11617, 3625 +2003-07-16, 11617, 3625 +2003-07-17, 11617, 3625 +2003-07-18, 11617, 3625 +2003-07-19, 11617, 3625 +2003-07-24, 11617, 3625 +2003-07-26, 11617, 3625 +2003-07-27, 11617, 3625 +2003-07-28, 11617, 3625 +2003-07-29, 11617, 3625 +2003-07-30, 11617, 3625 +2003-07-31, 11617, 3625 +2003-08-01, 11617, 3625 +2003-08-02, 11617, 3625 +2003-08-06, 11617, 3625 +2003-08-07, 11617, 3625 +2003-08-09, 11617, 3625 +2003-08-10, 11617, 3625 +2003-08-17, 11617, 3625 +2003-08-24, 11617, 3625 +2003-08-25, 11617, 3625 +2003-09-02, 11617, 3625 +2003-09-07, 11617, 3625 +2003-09-08, 11617, 3625 +2003-09-09, 11617, 3625 +2003-09-10, 11617, 3625 +2003-09-12, 11617, 3625 +2003-09-13, 11617, 3625 +2003-09-14, 11617, 3625 +2003-09-15, 11617, 3625 +2003-09-16, 11617, 3625 +2003-09-17, 11617, 3625 +2003-09-18, 11954, 3536 +2003-09-19, 11976, 3541 +2003-09-20, 11976, 3541 +2003-09-21, 11976, 3541 +2003-09-22, 11976, 3541 +2003-09-23, 12024, 3671 +2003-09-25, 12024, 3671 +2003-09-26, 12024, 3671 +2003-09-28, 12024, 3671 +2003-09-29, 12024, 3677 +2003-09-30, 12393, 3760 +2003-10-01, 12900, 3965 +2003-10-02, 13241, 4310 +2003-10-03, 13241, 4310 +2003-10-04, 13310, 4356 +2003-10-05, 12443, 4223 +2003-10-06, 12415, 4223 +2003-10-07, 12415, 4223 +2003-10-08, 12417, 4223 +2003-10-09, 12417, 4223 +2003-10-10, 12875, 4431 +2003-10-11, 12884, 4452 +2003-10-12, 12970, 4492 +2003-10-13, 12984, 4492 +2003-10-14, 12984, 4492 +2003-10-15, 12974, 4492 +2003-10-16, 13051, 4492 +2003-10-17, 13094, 4521 +2003-10-18, 13131, 4561 +2003-10-20, 13131, 4561 +2003-10-21, 13131, 4561 +2003-10-23, 13147, 4570 +2003-10-24, 13268, 4413 +2003-10-25, 13276, 4416 +2003-10-26, 13372, 4409 +2003-10-27, 13641, 4403 +2003-10-28, 13699, 4409 +2003-10-29, 13850, 4419 +2003-10-30, 13848, 4431 +2003-10-31, 13854, 4431 +2003-11-03, 13704, 4437 +2003-11-04, 13704, 4437 +2003-11-05, 13711, 4437 +2003-11-10, 13711, 4437 +2003-11-11, 13872, 4634 +2003-11-13, 13872, 4634 +2003-11-14, 13872, 4634 +2003-11-17, 13872, 4634 +2003-11-18, 13850, 4682 +2003-11-19, 13954, 4508 +2003-11-20, 14086, 4555 +2003-11-21, 14226, 4565 +2003-11-22, 14231, 4565 +2003-11-24, 14170, 4620 +2003-11-25, 14170, 4620 +2003-11-26, 14120, 4624 +2003-11-27, 14543, 4673 +2003-11-28, 14546, 4673 +2003-11-29, 14546, 4673 +2003-11-30, 15350, 4695 +2003-12-01, 15350, 4695 +2003-12-02, 15350, 4695 +2003-12-03, 15350, 4695 +2003-12-04, 15350, 4695 +2003-12-08, 15350, 4695 +2003-12-09, 15352, 4695 +2003-12-10, 15352, 4695 +2003-12-11, 15352, 4695 +2003-12-12, 15352, 4695 +2003-12-13, 15352, 4695 +2003-12-15, 15474, 4695 +2003-12-16, 16321, 4701 +2003-12-17, 17469, 4878 +2003-12-18, 17793, 5121 +2003-12-19, 19327, 5002 +2003-12-20, 19795, 5058 +2003-12-21, 20048, 5121 +2003-12-22, 20062, 5145 +2003-12-23, 20118, 5156 +2003-12-24, 20232, 5178 +2003-12-27, 20232, 5178 +2003-12-28, 20232, 5178 +2003-12-29, 20232, 5178 +2003-12-31, 20232, 5178 +2004-01-01, 20404, 5292 +2004-01-02, 20418, 5292 +2004-01-05, 20418, 5292 +2004-01-06, 20283, 5284 +2004-01-07, 20283, 5284 +2004-01-08, 20284, 5284 +2004-01-09, 20351, 5284 +2004-01-10, 20351, 5284 +2004-01-11, 20350, 5284 +2004-01-12, 20356, 5284 +2004-01-13, 20356, 5284 +2004-01-14, 20356, 5284 +2004-01-15, 20356, 5284 +2004-01-16, 20356, 5284 +2004-01-17, 20356, 5284 +2004-01-18, 20356, 5284 +2004-01-19, 20360, 5284 +2004-01-20, 20360, 5284 +2004-01-21, 20360, 5284 +2004-01-22, 20360, 5284 +2004-01-23, 20360, 5284 +2004-01-26, 20360, 5284 +2004-01-27, 20360, 5284 +2004-01-28, 20360, 5284 +2004-01-29, 20360, 5284 +2004-01-30, 20360, 5284 +2004-02-02, 20360, 5284 +2004-02-03, 20360, 5284 +2004-02-04, 20360, 5284 +2004-02-05, 20360, 5284 +2004-02-07, 20360, 5284 +2004-02-08, 20360, 5284 +2004-02-09, 20360, 5284 +2004-02-10, 20360, 5284 +2004-02-11, 20360, 5284 +2004-02-12, 20380, 5284 +2004-02-13, 20380, 5284 +2004-02-14, 20380, 5284 +2004-02-15, 20380, 5284 +2004-02-16, 20372, 5284 +2004-02-19, 20442, 5289 +2004-02-20, 20442, 5289 +2004-02-21, 20442, 5289 +2004-02-23, 20442, 5289 +2004-02-24, 20442, 5289 +2004-02-25, 20442, 5289 +2004-02-26, 20442, 5289 +2004-02-27, 20442, 5289 +2004-02-28, 20442, 5289 +2004-02-29, 20442, 5289 +2004-03-01, 20442, 5289 +2004-03-02, 20442, 5289 +2004-03-03, 20442, 5289 +2004-03-04, 20442, 5289 +2004-03-05, 20442, 5289 +2004-03-06, 20442, 5289 +2004-03-07, 20442, 5289 +2004-03-08, 20442, 5289 +2004-03-09, 20442, 5289 +2004-03-10, 20442, 5289 +2004-03-11, 20442, 5289 +2004-03-12, 20442, 5289 +2004-03-13, 20442, 5289 +2004-03-14, 20442, 5289 +2004-03-16, 20442, 5289 +2004-03-17, 20442, 5289 +2004-03-18, 20442, 5289 +2004-03-19, 20442, 5289 +2004-03-21, 20442, 5289 +2004-03-22, 20442, 5289 +2004-03-23, 20442, 5289 +2004-03-24, 21127, 5289 +2004-03-25, 21128, 5289 +2004-03-26, 21128, 5289 +2004-03-28, 21128, 5289 +2004-03-29, 20587, 5289 +2004-03-30, 20587, 5289 +2004-03-31, 20587, 5289 +2004-04-01, 20587, 5289 +2004-04-02, 20587, 5289 +2004-04-03, 20587, 5289 +2004-04-04, 20587, 5289 +2004-04-05, 20587, 5289 +2004-04-06, 20587, 5289 +2004-04-07, 20587, 5289 +2004-04-08, 20587, 5289 +2004-04-09, 20587, 5289 +2004-04-10, 20587, 5289 +2004-04-11, 20587, 5289 +2004-04-13, 20587, 5289 +2004-04-14, 20587, 5289 +2004-04-15, 20587, 5289 +2004-04-16, 20587, 5289 +2004-04-17, 20587, 5289 +2004-04-18, 20587, 5289 +2004-04-19, 20587, 5289 +2004-04-20, 20587, 5289 +2004-04-21, 20587, 5289 +2004-04-22, 20587, 5289 +2004-04-23, 20587, 5289 +2004-04-24, 20587, 5289 +2004-04-25, 20587, 5289 +2004-04-26, 20587, 5289 +2004-04-27, 20587, 5289 +2004-04-28, 20587, 5289 +2004-04-29, 20587, 5289 +2004-04-30, 20587, 5289 +2004-05-01, 20587, 5289 +2004-05-02, 20587, 5289 +2004-05-03, 20587, 5289 +2004-05-04, 20587, 5289 +2004-05-05, 20587, 5289 +2004-05-06, 20587, 5289 +2004-05-07, 20890, 5143 +2004-05-08, 21079, 5148 +2004-05-09, 21165, 5166 +2004-05-10, 21150, 5166 +2004-05-11, 21150, 5166 +2004-05-12, 21508, 5171 +2004-05-13, 21508, 5171 +2004-05-14, 21508, 5171 +2004-05-15, 21508, 5171 +2004-05-16, 21508, 5171 +2004-05-17, 21508, 5171 +2004-05-18, 21508, 5171 +2004-05-19, 21508, 5171 +2004-05-20, 21508, 5171 +2004-05-21, 21508, 5171 +2004-05-22, 21537, 5199 +2004-05-23, 21537, 5199 +2004-05-24, 21537, 5199 +2004-05-25, 21537, 5199 +2004-05-26, 21537, 5199 +2004-05-27, 21537, 5199 +2004-05-28, 21673, 5214 +2004-05-29, 21673, 5215 +2004-05-30, 21673, 5215 +2004-05-31, 21673, 5215 +2004-06-01, 21848, 5308 +2004-06-02, 22297, 5451 +2004-06-03, 22297, 5474 +2004-06-04, 22310, 5491 +2004-06-05, 22551, 5508 +2004-06-06, 22480, 5496 +2004-06-07, 23177, 5557 +2004-06-08, 23177, 5557 +2004-06-09, 23177, 5557 +2004-06-10, 23181, 5554 +2004-06-11, 24001, 5609 +2004-06-12, 24124, 5618 +2004-06-13, 24341, 5677 +2004-06-15, 24370, 5691 +2004-06-16, 24078, 5704 +2004-06-17, 24218, 5720 +2004-06-18, 24217, 5723 +2004-06-19, 24217, 5723 +2004-06-20, 24217, 5723 +2004-06-21, 24217, 5723 +2004-06-22, 24607, 5723 +2004-06-23, 24607, 5723 +2004-06-24, 24609, 5723 +2004-06-25, 24740, 5751 +2004-06-26, 24865, 5810 +2004-06-27, 24939, 5906 +2004-06-28, 25972, 5974 +2004-06-29, 25986, 5984 +2004-06-30, 25841, 5986 +2004-07-01, 25840, 5986 +2004-07-02, 25937, 5986 +2004-07-03, 25738, 5986 +2004-07-04, 25475, 5986 +2004-07-05, 25475, 5986 +2004-07-06, 25264, 6712 +2004-07-07, 25259, 6780 +2004-07-08, 25259, 6780 +2004-07-09, 25258, 6780 +2004-07-10, 25262, 6799 +2004-07-11, 25262, 6799 +2004-07-12, 25266, 6802 +2004-07-13, 25161, 6825 +2004-07-14, 25161, 6834 +2004-07-15, 25172, 6846 +2004-07-16, 24911, 6757 +2004-07-17, 23902, 6689 +2004-07-21, 23902, 6689 +2004-07-22, 23941, 6690 +2004-07-23, 23971, 6680 +2004-07-24, 24148, 6687 +2004-07-25, 24200, 6687 +2004-07-26, 24354, 6717 +2004-07-27, 24354, 6717 +2004-07-28, 24527, 6755 +2004-07-29, 24527, 6755 +2004-07-30, 24527, 6755 +2004-07-31, 24527, 6755 +2004-08-01, 24527, 6755 +2004-08-02, 24527, 6755 +2004-08-03, 24527, 6755 +2004-08-04, 24527, 6755 +2004-08-05, 24527, 6755 +2004-08-06, 24527, 6755 +2004-08-07, 24527, 6755 +2004-08-08, 24527, 6755 +2004-08-09, 24527, 6755 +2004-08-10, 24527, 6755 +2004-08-11, 24527, 6755 +2004-08-12, 24527, 6755 +2004-08-13, 24527, 6758 +2004-08-14, 24796, 6758 +2004-08-15, 24803, 6758 +2004-08-16, 25070, 6758 +2004-08-17, 25079, 6758 +2004-08-18, 25122, 6758 +2004-08-19, 25122, 6758 +2004-08-20, 25122, 6758 +2004-08-21, 25122, 6758 +2004-08-22, 25122, 6758 +2004-08-23, 25122, 6758 +2004-08-24, 25426, 6758 +2004-08-25, 25426, 6758 +2004-08-26, 25426, 6758 +2004-08-27, 25426, 6758 +2004-08-30, 25426, 6758 +2004-08-31, 25426, 6758 +2004-09-01, 25426, 6758 +2004-09-02, 25426, 6758 +2004-09-03, 25426, 6758 +2004-09-04, 25426, 6758 +2004-09-06, 25426, 6758 +2004-09-07, 26640, 6881 +2004-09-08, 26640, 6881 +2004-09-09, 26840, 6882 +2004-09-10, 26934, 6882 +2004-09-11, 27425, 6889 +2004-09-12, 27401, 6889 +2004-09-13, 27401, 6889 +2004-09-14, 27401, 6889 +2004-09-15, 27401, 6889 +2004-09-16, 27401, 6889 +2004-09-17, 27401, 6889 +2004-09-18, 27401, 6889 +2004-09-19, 27401, 6889 +2004-09-20, 27401, 6889 +2004-09-21, 27401, 6889 +2004-09-22, 27720, 6889 +2004-09-23, 27720, 6889 +2004-09-24, 27720, 6889 +2004-09-25, 27855, 6909 +2004-09-26, 27855, 6909 +2004-09-27, 27855, 6909 +2004-09-28, 27855, 6909 +2004-09-29, 27855, 6909 +2004-09-30, 27855, 6909 +2004-10-01, 27855, 6909 +2004-10-02, 27855, 6909 +2004-10-03, 27855, 6909 +2004-10-04, 27855, 6909 +2004-10-05, 27855, 6909 +2004-10-06, 27855, 6909 +2004-10-07, 27855, 6909 +2004-10-08, 27855, 6909 +2004-10-09, 27855, 6909 +2004-10-10, 25999, 6909 +2004-10-11, 26069, 6913 +2004-10-13, 26069, 6913 +2004-10-14, 26069, 6913 +2004-10-15, 26129, 6917 +2004-10-16, 26129, 6917 +2004-10-17, 26129, 6917 +2004-10-18, 26129, 6917 +2004-10-19, 26147, 6917 +2004-10-20, 26147, 6917 +2004-10-21, 26147, 6917 +2004-10-22, 26147, 6917 +2004-10-23, 26147, 6917 +2004-10-24, 26147, 6917 +2004-10-25, 26147, 6917 +2004-10-26, 26147, 6917 +2004-10-27, 26147, 6917 +2004-10-28, 26147, 6917 +2004-10-29, 26147, 6917 +2004-10-30, 26147, 6917 +2004-10-31, 26147, 6917 +2004-11-01, 26147, 6917 +2004-11-02, 26147, 6917 +2004-11-03, 26147, 6917 +2004-11-04, 26147, 6917 +2004-11-05, 26147, 6917 +2004-11-06, 26147, 6917 +2004-11-08, 26147, 6917 +2004-11-09, 26147, 6917 +2004-11-10, 26147, 6917 +2004-11-11, 26160, 6917 +2004-11-12, 26170, 6917 +2004-11-14, 26169, 6917 +2004-11-15, 26168, 6917 +2004-11-16, 25751, 6829 +2004-11-17, 26131, 6844 +2004-11-18, 26504, 6927 +2004-11-19, 27590, 7162 +2004-11-20, 28246, 7206 +2004-11-21, 29449, 7880 +2004-11-22, 29516, 7927 2004/11/23, 30041, 8108 -2004/11/22, 29505, 8005 -2004/11/21, 29516, 7927 -2004/11/20, 29449, 7880 -2004/11/19, 28244, 7206 -2004/11/18, 27590, 7162 -2004/11/17, 26504, 6927 -2004/11/16, 26131, 6829 -2004/11/15, 25751, 6829 -2004/11/12, 26169, 6917 -2004/11/11, 26170, 6917 +2004/11/24, 30139, 8115 +2004/11/25, 30148, 8115 +2004/11/27, 30150, 8115 +2004/11/28, 30151, 8115 +2004/11/29, 30175, 8232 +2004/11/30, 30261, 8242 +2004/12/04, 30404, 8242 +2004/12/06, 30465, 8242 +2004/12/07, 30489, 8273 +2004/12/08, 30490, 8273 +2004/12/09, 30622, 8318 +2004/12/10, 30631, 8332 +2004/12/13, 30652, 8332 +2004/12/16, 30679, 8332 +2004/12/17, 30748, 8342 +2004/12/18, 30760, 8352 +2004/12/19, 30881, 8352 +2004/12/20, 30881, 8352 +2004/12/22, 30939, 8352 +2004/12/24, 30812, 8383 +2004/12/27, 30860, 8375 +2004/12/30, 30860, 8378 +2005/01/01, 30565, 8357 +2005/01/02, 30565, 8357 +2005/01/03, 30565, 8352 +2005/01/08, 30701, 8256 +2005/01/09, 30701, 8248 +2005/01/10, 30702, 8130 +2005/01/11, 30569, 8097 +2005/01/12, 32119, 8145 +2005/01/13, 32095, 8154 +2005/01/14, 32103, 8154 +2005/01/15, 32108, 8154 +2005/01/16, 32108, 8165 +2005/01/17, 32110, 8166 +2005/01/18, 32110, 8166 +2005/01/19, 32110, 8543 +2005/01/20, 32091, 8560 +2005/01/22, 32108, 8555 +2005/01/23, 32486, 8707 +2005/01/24, 32679, 8707 +2005/01/25, 33281, 9335 +2005/01/26, 33547, 9492 +2005/01/27, 31118, 9024 +2005/01/28, 35443, 9696 +2005/01/29, 35440, 10266 +2005/01/30, 35430, 10266 +2005/01/31, 35541, 10266 +2005/02/01, 36390, 10292 +2005/02/02, 36931, 10843 +2005/02/03, 37045, 10890 +2005/02/04, 36471, 10929 +2005/02/05, 36551, 10929 +2005/02/06, 37347, 11064 +2005/02/07, 37299, 11031 +2005/02/08, 37341, 11046 +2005/02/09, 37442, 11055 +2005/02/10, 43918, 11075 +2005/02/11, 43929, 11085 +2005/02/13, 46454, 11085 +2005/02/13, 46454, 11085 +2005/02/13, 46454, 11085 +2005/02/14, 46513, 11092 +2005/02/15, 46912, 11167 +2005/02/16, 46912, 11167 +2005/02/17, 46971, 11167 +2005/02/18, 46949, 11283 +2005/02/19, 47139, 11363 +2005/02/21, 47207, 11362 +2005/02/22, 47252, 11557 +2005/02/23, 47309, 11563 +2005/02/24, 47429, 11567 +2005/02/25, 47623, 11627 +2005/02/26, 47624, 11627 +2005/02/27, 47624, 11627 +2005/02/28, 47752, 11643 +2005/03/01, 47635, 11565 +2005/03/02, 47765, 11661 +2005/03/03, 47863, 11666 +2005/03/04, 47719, 11596 +2005/03/05, 47888, 11628 +2005/03/06, 47912, 11638 +2005/03/10, 48463, 11638 +2005/03/11, 48566, 11653 +2005/03/12, 48605, 11671 +2005/03/13, 48629, 11754 +2005/03/14, 48645, 11755 +2005/03/15, 48683, 11755 +2005/03/17, 48791, 11755 +2005/03/19, 48756, 11768 +2005/03/20, 50569, 15353 +2005/03/21, 50164, 15056 +2005/03/22, 54019, 15607 +2005/03/23, 54091, 13093 +2005/03/24, 54198, 13096 +2005/03/27, 54216, 13108 +2005/03/28, 54272, 13111 +2005/03/29, 54788, 13157 +2005/03/30, 54890, 13167 +2005/03/31, 54997, 13276 +2005/04/01, 55751, 13280 +2005/04/02, 56072, 13325 +2005/04/03, 56272, 13325 +2005/04/04, 56579, 13340 +2005/04/05, 56748, 13356 +2005/04/06, 56885, 13380 +2005/04/07, 56983, 13422 +2005/04/08, 57306, 13520 +2005/04/09, 57270, 13538 +2005/04/10, 57578, 13545 +2005/04/11, 57717, 13522 +2005/04/12, 58127, 13668 +2005/04/13, 58464, 13699 +2005/04/14, 58819, 13856 +2005/04/15, 58914, 13931 +2005/04/16, 59050, 13979 +2005/04/17, 59013, 14000 +2005/04/18, 59087, 14047 +2005/04/19, 59131, 14097 +2005/04/20, 58504, 14881 +2005/04/21, 58521, 14898 +2005/04/22, 58565, 14939 +2005/04/23, 58565, 14939 +2005/04/24, 58807, 14955 +2005/04/25, 60595, 15369 +2005/04/26, 60919, 15192 +2005/04/27, 61763, 15262 +2005/04/28, 61815, 15250 +2005/04/29, 63797, 15974 +2005/04/30, 63937, 16140 +2005/05/01, 62128, 11466 +2005/05/02, 62628, 12096 +2005/05/03, 63010, 12163 +2005/05/04, 63289, 12171 +2005/05/05, 63428, 12267 +2005/05/06, 63489, 12329 +2005/05/07, 63552, 12329 +2005/05/08, 63690, 12349 +2005/05/09, 63755, 12352 +2005/05/10, 64144, 12557 +2005/05/11, 64484, 12685 +2005/05/12, 64790, 12735 +2005/05/13, 64811, 12749 +2005/05/14, 64917, 12761 +2005/05/15, 66548, 13088 +2005/05/16, 66562, 13121 +2005/05/17, 66595, 13184 +2005/05/18, 79865, 12413 +2005/05/19, 71673, 12429 +2005/05/20, 71816, 12433 +2005/05/21, 73363, 12587 +2005/05/22, 73426, 12608 +2005/05/23, 98647, 12664 +2005/05/24, 99080, 12693 +2005/05/25, 99295, 12693 +2005/05/26, 99681, 12701 +2005/05/27, 99874, 12742 +2005/05/28, 99760, 12742 +2005/05/29, 100002, 12811 +2005/05/30, 100321, 13014 +2005/05/31, 100942, 13201 +2005/06/01, 101442, 13353 +2005/06/02, 101619, 13444 +2005/06/03, 101734, 13461 +2005/06/04, 102228, 13525 +2005/06/05, 103949, 12880 +2005/06/06, 104657, 12995 +2005/06/07, 104662, 12955 +2005/06/08, 113246, 12999 +2005/06/09, 112505, 13115 +2005/06/10, 112796, 13151 +2005/06/11, 112825, 13178 +2005/06/12, 112856, 13332 +2005/06/13, 112895, 13446 +2005/06/14, 111088, 13725 +2005/06/15, 111031, 13891 +2005/06/16, 111272, 13979 +2005/06/17, 111660, 14165 +2005/06/18, 112462, 14266 +2005/06/19, 112774, 14332 +2005/06/20, 113060, 14432 +2005/06/21, 113628, 14678 +2005/06/22, 113623, 14689 +2005/06/23, 114363, 15004 +2005/06/24, 113296, 15214 +2005/06/25, 113704, 15474 +2005/06/26, 113883, 15561 +2005/06/28, 113886, 15562 +2005/06/29, 113952, 15603 +2005/06/30, 113952, 15603 +2005/07/01, 114035, 15625 +2005/07/02, 114021, 15697 +2005/07/03, 126972, 16148 +2005/07/04, 127161, 16176 +2005/07/05, 132622, 16446 +2005/07/06, 133732, 16589 +2005/07/07, 134141, 16707 +2005/07/09, 134189, 16711 +2005/07/10, 134279, 16770 +2005/07/11, 134472, 16944 +2005/07/12, 134835, 17106 +2005/07/13, 135456, 17254 +2005/07/14, 135576, 17401 +2005/07/15, 135695, 17468 +2005/07/18, 135877, 17663 +2005/07/19, 132611, 17276 +2005/07/20, 132758, 17419 +2005/07/21, 133068, 17799 +2005/07/22, 133289, 18016 +2005/07/23, 133322, 18020 +2005/07/24, 133359, 18035 +2005/07/25, 133921, 18324 +2005/07/26, 134555, 18519 +2005/07/27, 135175, 18670 +2005/07/28, 139093, 18793 +2005/07/29, 139511, 19128 +2005/07/30, 140023, 19365 +2005/07/31, 140413, 19866 +2005/08/02, 141678, 19969 +2005/08/03, 143636, 20718 +2005/08/04, 144278, 20895 +2005/08/05, 144471, 21098 +2005/08/06, 144699, 21466 +2005/08/07, 144812, 21489 +2005/08/08, 145076, 21661 +2005/08/09, 145674, 21822 +2005/08/10, 146311, 22828 +2005/08/11, 146795, 23113 +2005/08/12, 147266, 23259 +2005/08/13, 147307, 23316 +2005/08/14, 147325, 23329 +2005/08/15, 147602, 23349 +2005/08/16, 147613, 23353 +2005/08/17, 147700, 23385 +2005/08/18, 147807, 23409 +2005/08/19, 148620, 23925 +2005/08/20, 148620, 23925 +2005/08/22, 149110, 24116 +2005/08/23, 149698, 24405 +2005/08/24, 150268, 24873 +2005/08/25, 150138, 25151 +2005/08/26, 151296, 25435 +2005/08/27, 151828, 25688 +2005/08/28, 151807, 25680 +2005/08/29, 152082, 25747 +2005/08/30, 152432, 25655 +2005/08/31, 152475, 25673 +2005/09/01, 152432, 25673 +2005/09/02, 152608, 25829 +2005/09/03, 152637, 25829 +2005/09/04, 152749, 25883 +2005/09/05, 153175, 25883 +2005/09/06, 158929, 26044 +2005/09/07, 159089, 26078 +2005/09/08, 159095, 26194 +2005/09/09, 159532, 26410 +2005/09/10, 159474, 26604 +2005/09/11, 159590, 26842 +2005/09/12, 159914, 27003 +2005/09/13, 160295, 27222 +2005/09/14, 160100, 27289 +2005/09/15, 160186, 27308 +2005/09/16, 160250, 27355 +2005/09/17, 160147, 27417 +2005/09/18, 160256, 27417 +2005/09/19, 160423, 27449 +2005/09/20, 160520, 27565 +2005/09/21, 160716, 27585 +2005/09/22, 160766, 27591 +2005/09/23, 161014, 27616 +2005/09/24, 161159, 27660 +2005/09/25, 161178, 27660 +2005/09/26, 161707, 27865 +2005/09/27, 161746, 27929 +2005/09/28, 161945, 27912 +2005/09/29, 161926, 27969 +2005/09/30, 161908, 28024 +2005/10/01, 161217, 28060 +2005/10/02, 161405, 28148 +2005/10/03, 161470, 28231 +2005/10/04, 161652, 28325 +2005/10/05, 161650, 28403 +2005/10/06, 150147, 27867 +2005/10/07, 150310, 27981 +2005/10/08, 150336, 28002 +2005/10/09, 150340, 28002 +2005/10/10, 152248, 29917 +2005/10/11, 152893, 30132 +2005/10/12, 153415, 30315 +2005/10/13, 153234, 30314 +2005/10/14, 154456, 30886 +2005/10/15, 155217, 31128 +2005/10/16, 155503, 31283 +2005/10/17, 155558, 31306 +2005/10/18, 155323, 31407 +2005/10/19, 155548, 31764 +2005/10/20, 155670, 31818 +2005/10/21, 156006, 31832 +2005/10/22, 156124, 31942 +2005/10/23, 156153, 31954 +2005/10/24, 156358, 31940 +2005/10/25, 156761, 31982 +2005/10/26, 156875, 32344 +2005/10/27, 151521, 32461 +2005/10/28, 151704, 32470 +2005/10/29, 151768, 32470 +2005/10/30, 151701, 32470 +2005/10/31, 151905, 32496 +2005/11/01, 151913, 32508 +2005/11/02, 151918, 32514 +2005/11/03, 151918, 32514 +2005/11/04, 151923, 32514 +2005/11/05, 152018, 32514 +2005/11/06, 152076, 32545 +2005/11/07, 152059, 32545 +2005/11/08, 152062, 32545 +2005/11/09, 152051, 32550 +2005/11/10, 151995, 32548 +2005/11/11, 152031, 32696 +2005/11/12, 152031, 32696 +2005/11/13, 152123, 32696 +2005/11/14, 152151, 32690 +2005/11/15, 152151, 32690 +2005/11/16, 152126, 32718 +2005/11/17, 152702, 32718 +2005/11/18, 152704, 32718 +2005/11/19, 152702, 32718 +2005/11/21, 152822, 32825 +2005/11/22, 152844, 32830 +2005/11/23, 152830, 32830 +2005/11/23, 152830, 32830 +2005/11/25, 152830, 32830 +2005/11/27, 152884, 32862 +2005/11/28, 153190, 33011 +2005/11/29, 153246, 33011 +2005/11/30, 153293, 33011 +2005/12/01, 153738, 33186 +2005/12/02, 153897, 33205 +2005/12/03, 153937, 33205 +2005/12/04, 154104, 33187 +2005/12/05, 154085, 33187 +2005/12/06, 154069, 33216 +2005/12/07, 154963, 33506 +2005/12/08, 156568, 33832 +2005/12/09, 156931, 34791 +2005/12/10, 157305, 34891 +2005/12/11, 157466, 35017 +2005/12/12, 157583, 35018 +2005/12/13, 158273, 35108 +2005/12/14, 158266, 35238 +2005/12/15, 158751, 35651 +2005/12/16, 158822, 35712 +2005/12/17, 158902, 35713 +2005/12/18, 159070, 35868 +2005/12/19, 159083, 36018 +2005/12/20, 159100, 36030 +2005/12/21, 159197, 36060 +2005/12/22, 159276, 36124 +2005/12/23, 159305, 36195 +2005/12/24, 159321, 36197 +2005/12/25, 159321, 36247 +2005/12/27, 159374, 36285 +2005/12/29, 159455, 36319 +2005/12/30, 159520, 36330 +2005/12/31, 159549, 36333 +2006/01/02, 159692, 36336 +2006/01/04, 159796, 36423 +2006/01/05, 159787, 36462 +2006/01/06, 159735, 36497 +2006/01/07, 159822, 36617 +2006/01/08, 159964, 36760 +2006/01/09, 159988, 36799 +2006/01/10, 160237, 37028 +2006/01/11, 160307, 37098 +2006/01/12, 160335, 37215 +2006/01/13, 160359, 37217 +2006/01/14, 160642, 37353 +2006/01/15, 160640, 37439 +2006/01/16, 160714, 37551 +2006/01/17, 160737, 37562 +2006/01/18, 160809, 37566 +2006/01/19, 161141, 37707 +2006/01/20, 161285, 37794 +2006/01/21, 161311, 37789 +2006/01/22, 161327, 37820 +2006/01/23, 162130, 38129 +2006/01/24, 162825, 38485 +2006/01/25, 163208, 38818 +2006/01/26, 164445, 39306 +2006/01/27, 165729, 39552 +2006/01/28, 165022, 39852 +2006/01/29, 165580, 40015 +2006/01/30, 165580, 40016 +2006/01/31, 165833, 40588 +2006/02/01, 165903, 40680 +2006/02/02, 165996, 40725 +2006/02/03, 166074, 40861 +2006/02/04, 166270, 40962 +2006/02/05, 166436, 41110 +2006/02/06, 166453, 41209 +2006/02/07, 166496, 41367 +2006/02/08, 167122, 41723 +2006/02/09, 167396, 41812 +2006/02/10, 167651, 41888 +2006/02/11, 167719, 41992 +2006/02/12, 167741, 41981 +2006/02/13, 167901, 42278 +2006/02/14, 168068, 42354 +2006/02/15, 168112, 42671 +2006/02/16, 168628, 42835 +2006/02/17, 168836, 43089 +2006/02/18, 168844, 43089 +2006/02/19, 168953, 43173 +2006/02/20, 169263, 43201 +2006/02/21, 169602, 43297 +2006/02/22, 169433, 43239 +2006/02/23, 169557, 43279 +2006/02/25, 169557, 43279 +2006/02/26, 169558, 43279 +2006/02/27, 169940, 43442 +2006/02/28, 169197, 43619 +2006/03/01, 169535, 44112 +2006/03/02, 169723, 44499 +2006/03/03, 169915, 44512 +2006/03/04, 169917, 44512 +2006/03/06, 170008, 44611 +2006/03/07, 170046, 44647 +2006/03/08, 170180, 44731 +2006/03/09, 170579, 44855 +2006/03/10, 170589, 44743 +2006/03/11, 170597, 44743 +2006/03/12, 170626, 44743 +2006/03/13, 170830, 44738 +2006/03/14, 170944, 44877 +2006/03/15, 170968, 44841 +2006/03/16, 171176, 44945 +2006/03/17, 171385, 45125 +2006/03/18, 171465, 45202 +2006/03/19, 171607, 45205 +2006/03/20, 171933, 45506 +2006/03/21, 172152, 45725 +2006/03/22, 172896, 45937 +2006/03/23, 173493, 46142 +2006/03/24, 174140, 46532 +2006/03/25, 174223, 46600 +2006/03/26, 174271, 46600 +2006/03/27, 174514, 46658 +2006/03/28, 174663, 46741 +2006/03/29, 174706, 46762 +2006/03/30, 174706, 46787 +2006/03/31, 174915, 46889 +2006/04/01, 175211, 46910 +2006/04/02, 175537, 47085 +2006/04/03, 175795, 47186 +2006/04/04, 176373, 47399 +2006/04/05, 178170, 47256 +2006/04/06, 177675, 47389 +2006/04/07, 178276, 47631 +2006/04/08, 178733, 47684 +2006/04/09, 186394, 48077 +2006/04/10, 186785, 48474 +2006/04/11, 187071, 48645 +2006/04/12, 187328, 48773 +2006/04/13, 187417, 48900 +2006/04/14, 187650, 48936 +2006/04/15, 187874, 49072 +2006/04/16, 188073, 49083 +2006/04/17, 188185, 49343 +2006/04/18, 188368, 49760 +2006/04/19, 188764, 50000 +2006/04/20, 189386, 50060 +2006/04/21, 189444, 50233 +2006/04/22, 189708, 50343 +2006/04/23, 190100, 50476 +2006/04/24, 190581, 50716 +2006/04/25, 191060, 50946 +2006/04/26, 191265, 51180 +2006/04/27, 191806, 51553 +2006/04/28, 192251, 51836 +2006/04/29, 192654, 52220 +2006/04/30, 192740, 52241 +2006/05/01, 192740, 52245 +2006/05/02, 192950, 52435 +2006/05/03, 193237, 52548 +2006/05/04, 193297, 52720 +2006/05/05, 193577, 53008 +2006/05/06, 194029, 53366 +2006/05/07, 194263, 53544 +2006/05/08, 194325, 53503 +2006/05/09, 194384, 53587 +2006/05/10, 194921, 53800 +2006/05/11, 195221, 54028 +2006/05/12, 195535, 54202 +2006/05/13, 196169, 54314 +2006/05/14, 195622, 54424 +2006/05/15, 195827, 54685 +2006/05/16, 196171, 54954 +2006/05/17, 197172, 55029 +2006/05/18, 197223, 54967 +2006/05/19, 197404, 55047 +2006/05/20, 198903, 55211 +2006/05/21, 199040, 55475 +2006/05/22, 199114, 55577 +2006/05/23, 199431, 55391 +2006/05/24, 203342, 55383 +2006/05/25, 203490, 55570 +2006/05/26, 203563, 55563 +2006/05/27, 203653, 55592 +2006/05/28, 203670, 55592 +2006/05/29, 204409, 57115 +2006/05/30, 235501, 57122 +2006/05/31, 235493, 57122 +2006/06/02, 235690, 57191 +2006/06/03, 236072, 57355 +2006/06/04, 236020, 58196 +2006/06/05, 236286, 58331 +2006/06/06, 236730, 58474 +2006/06/07, 237402, 58537 +2006/06/08, 237731, 58790 +2006/06/09, 236391, 56722 +2006/06/10, 236447, 56788 +2006/06/11, 236558, 56800 +2006/06/12, 237246, 57071 +2006/06/13, 236849, 57211 +2006/06/14, 236747, 57335 +2006/06/15, 237010, 57438 +2006/06/16, 237223, 57674 +2006/06/17, 237227, 57705 +2006/06/18, 237243, 57759 +2006/06/19, 237290, 58140 +2006/06/20, 237711, 58324 +2006/06/21, 236934, 58324 +2006/06/22, 237228, 58454 +2006/06/23, 237265, 58460 +2006/06/24, 237586, 58460 +2006/06/25, 237964, 58689 +2006/06/26, 238162, 58755 +2006/06/27, 238361, 58778 +2006/06/28, 238484, 58830 +2006/06/29, 238832, 58938 +2006/06/30, 238742, 58961 +2006/07/01, 238361, 58943 +2006/07/02, 238651, 59001 +2006/07/03, 238674, 59009 +2006/07/04, 238724, 59012 +2006/07/05, 238901, 59013 +2006/07/06, 238884, 59396 +2006/07/07, 239546, 59615 +2006/07/08, 241573, 60173 +2006/07/09, 242229, 60524 +2006/07/10, 242273, 60532 +2006/07/11, 242885, 60796 +2006/07/12, 243281, 61279 +2006/07/13, 243406, 61287 +2006/07/14, 243459, 61314 +2006/07/15, 243520, 61313 +2006/07/16, 243621, 61344 +2006/07/17, 243883, 61480 +2006-07-17, 243621, 61344 +2006-07-18, 243886, 61525 +2006-07-19, 244520, 61568 +2006-07-20, 244866, 61922 +2006-07-21, 244969, 61966 +2006-07-22, 245046, 62020 +2006-07-23, 245229, 62043 +2006-07-24, 245421, 62142 +2006-07-25, 245618, 62211 +2006-07-26, 245251, 62324 +2006-07-27, 245921, 62650 +2006-07-28, 246016, 62694 +2006-07-29, 249837, 62836 +2006-07-30, 249901, 62893 +2006-07-31, 249933, 62894 +2006-08-01, 250022, 62941 +2006-08-02, 250276, 63020 +2006-08-03, 248113, 62052 +2006-08-04, 248192, 62110 +2006-08-05, 249951, 62532 +2006-08-06, 250333, 62659 +2006-08-07, 250401, 62670 +2006-08-08, 252585, 63100 +2006-08-09, 252849, 63027 +2006-08-10, 253370, 63137 +2006-08-11, 253464, 63219 +2006-08-12, 253592, 63309 +2006-08-13, 253597, 63309 +2006-08-14, 253600, 63309 +2006-08-15, 253707, 63375 +2006-08-16, 254098, 63549 +2006-08-17, 254591, 63698 +2006-08-18, 254640, 63783 +2006-08-19, 254723, 63783 +2006-08-20, 254707, 63789 +2006-08-21, 254932, 64065 +2006-08-22, 254820, 63836 +2006-08-23, 255008, 63958 +2006-08-24, 255255, 64074 +2006-08-25, 255383, 64175 +2006-08-26, 255553, 64197 +2006-08-27, 255283, 64604 +2006-08-28, 255368, 64660 +2006-08-29, 255368, 64660 +2006-08-30, 256002, 64772 +2006-08-31, 255939, 64828 +2006-09-01, 256059, 64897 +2006-09-02, 256072, 64896 +2006-09-03, 256651, 65050 +2006-09-04, 256654, 65213 +2006-09-05, 256678, 65296 +2006-09-06, 256933, 65562 +2006-09-07, 257168, 65707 +2006-09-08, 257380, 65826 +2006-09-09, 257996, 66107 +2006-09-10, 258138, 66194 +2006-09-11, 258419, 66313 +2006-09-12, 258503, 66321 +2006-09-13, 258624, 66365 +2006-09-14, 258625, 66401 +2006-09-15, 258783, 66509 +2006-09-16, 258785, 66512 +2006-09-17, 258806, 66519 +2006-09-18, 258424, 66766 +2006-09-19, 258438, 66797 +2006-09-20, 258438, 66797 +2006-09-21, 258436, 66851 +2006-09-22, 258059, 67034 +2006-09-23, 258667, 67089 +2006-09-24, 258792, 67181 +2006-09-25, 258793, 67181 +2006-09-26, 258797, 67221 +2006-09-27, 258858, 67228 +2006-09-28, 259082, 67296 +2006-09-29, 258980, 67013 +2006-09-30, 258822, 67973 +2006-10-01, 258935, 68062 +2006-10-02, 259055, 68084 +2006-10-03, 259204, 68209 +2006-10-04, 296696, 68497 +2006-10-05, 298069, 68956 +2006-10-06, 298223, 69071 +2006-10-07, 298327, 69155 +2006-10-08, 298428, 69175 +2006-10-09, 298430, 69177 +2006-10-10, 297621, 69224 +2006-10-11, 296425, 68673 +2006-10-12, 294584, 68892 +2006-10-13, 294744, 68942 +2006-10-14, 295543, 68963 +2006-10-15, 295543, 68963 +2006-10-16, 295732, 68963 +2006-10-17, 295851, 69007 +2006-10-18, 296612, 69393 +2006-10-19, 296832, 69369 +2006-10-20, 297146, 69404 +2006-10-21, 297332, 69565 +2006-10-22, 298113, 69570 +2006-10-23, 298120, 69570 +2006-10-24, 298222, 69603 +2006-10-25, 298556, 69777 +2006-10-26, 298706, 69813 +2006-10-27, 298766, 70013 +2006-10-28, 298359, 69758 +2006-10-29, 298359, 69758 +2006-10-30, 298357, 69735 +2006-10-31, 299054, 69842 +2006-11-01, 300281, 69956 +2006-11-02, 300230, 69927 +2006-11-03, 300443, 70008 +2006-11-04, 300886, 70417 +2006-11-05, 301166, 70513 +2006-11-06, 301201, 70616 +2006-11-07, 300495, 69816 +2006-11-08, 300804, 70084 +2006-11-09, 300878, 70257 +2006-11-10, 301106, 70340 +2006-11-11, 301302, 70392 +2006-11-12, 301728, 70598 +2006-11-13, 314202, 72483 +2006-11-14, 314394, 72265 +2006-11-15, 314736, 72346 +2006-11-16, 315160, 72531 +2006-11-17, 315070, 72670 +2006-11-18, 315097, 72705 +2006-11-19, 315261, 72795 +2006-11-20, 315333, 72837 +2006-11-21, 315777, 72949 +2006-11-22, 316130, 73006 +2006-11-23, 316162, 73035 +2006-11-24, 316338, 73248 +2006-11-25, 316378, 73355 +2006-11-26, 316415, 73366 +2006-11-27, 316532, 73366 +2006-11-28, 318388, 73700 +2006-11-29, 318515, 73704 +2006-11-30, 318645, 73752 +2006-12-01, 318816, 73833 +2006-12-02, 318840, 73899 +2006-12-03, 318845, 73899 +2006-12-04, 318930, 73941 +2006-12-05, 319614, 73996 +2006-12-06, 319623, 74108 +2006-12-07, 319828, 74140 +2006-12-08, 320019, 74173 +2006-12-09, 320215, 74192 +2006-12-10, 320927, 74430 +2006-12-11, 320937, 74505 +2006-12-12, 321194, 74652 +2006-12-13, 321238, 74723 +2006-12-14, 321114, 74849 +2006-12-15, 321900, 75884 +2006-12-16, 322135, 76292 +2006-12-17, 322261, 76341 +2006-12-18, 322384, 76348 +2006-12-19, 322382, 76315 +2006-12-20, 322718, 76471 +2006-12-21, 322961, 76259 +2006-12-22, 323044, 76354 +2006-12-23, 323068, 76392 +2006-12-24, 323117, 76424 +2006-12-25, 323123, 76420 +2006-12-26, 323108, 76427 +2006-12-27, 321740, 76431 +2006-12-28, 321872, 76671 +2006-12-29, 322115, 76909 +2006-12-30, 322246, 76916 +2006-12-31, 322288, 77018 +2007-01-01, 322277, 77019 +2007-01-02, 322403, 77007 +2007-01-03, 322478, 77390 +2007-01-04, 322672, 77448 +2007-01-05, 322736, 77448 +2007-01-06, 322746, 77448 +2007-01-07, 322751, 77449 +2007-01-08, 322751, 77449 +2007-01-09, 323243, 77508 +2007-01-10, 323870, 77955 +2007-01-11, 324115, 78315 +2007-01-12, 324587, 78684 +2007-01-13, 325435, 79072 +2007-01-14, 325840, 79048 +2007-01-15, 327282, 79265 +2007-01-16, 327409, 79308 +2007-01-17, 327661, 79392 +2007-01-18, 327683, 79412 +2007-01-19, 327710, 79413 +2007-01-20, 327918, 79523 +2007-01-21, 328238, 79543 +2007-01-22, 328265, 79543 +2007-01-23, 328471, 79704 +2007-01-24, 328920, 79596 +2007-01-25, 329021, 79667 +2007-01-26, 329599, 79832 +2007-01-27, 329913, 80096 +2007-01-28, 329973, 80135 +2007-01-29, 330044, 80152 +2007-01-30, 330947, 80359 +2007-01-31, 331201, 80459 +2007-02-01, 331558, 80704 +2007-02-02, 331301, 80417 +2007-02-03, 331338, 80446 +2007-02-04, 331374, 80467 +2007-02-05, 331386, 80467 +2007-02-06, 332398, 80586 +2007-02-07, 332416, 80605 +2007-02-08, 332417, 80637 +2007-02-09, 332470, 80667 +2007-02-10, 332813, 80738 +2007-02-11, 332829, 80737 +2007-02-12, 333328, 80848 +2007-02-13, 333567, 81010 +2007-02-14, 333735, 81254 +2007-02-15, 334047, 81257 +2007-02-16, 333963, 81385 +2007-02-17, 335704, 81385 +2007-02-18, 335734, 81378 Modified: pypy/branch/ast-experiments/pypy/doc/statistic/number_files.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/statistic/number_files.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/statistic/number_files.txt Mon Feb 26 08:45:45 2007 @@ -1,570 +1,1253 @@ Number of files in the pypy subtree date, number of files, number of testfiles -2006/07/17, 1044, 408 -2006/07/16, 1043, 408 -2006/07/15, 1042, 407 -2006/07/14, 1041, 407 -2006/07/13, 1040, 407 -2006/07/12, 1039, 407 -2006/07/11, 1036, 406 -2006/07/10, 1038, 403 -2006/07/09, 1038, 403 -2006/07/08, 1036, 402 -2006/07/07, 1031, 393 -2006/07/06, 1020, 386 -2006/07/05, 1016, 384 -2006/07/04, 1015, 384 -2006/07/03, 1015, 384 -2006/07/02, 1015, 384 -2006/07/01, 1012, 384 -2006/06/30, 1012, 384 -2006/06/29, 1019, 384 -2006/06/28, 1018, 381 -2006/06/27, 1017, 381 -2006/06/26, 1017, 381 -2006/06/25, 1016, 380 -2006/06/24, 1013, 378 -2006/06/23, 1011, 378 -2006/06/22, 1011, 378 -2006/06/21, 1003, 377 -2006/06/20, 1007, 377 -2006/06/19, 1007, 377 -2006/06/18, 1007, 377 -2006/06/17, 1007, 377 -2006/06/16, 1007, 377 -2006/06/15, 1006, 375 -2006/06/14, 1005, 371 -2006/06/13, 1004, 371 -2006/06/12, 1010, 371 -2006/06/11, 1005, 369 -2006/06/10, 1004, 369 -2006/06/09, 1004, 369 -2006/06/08, 1021, 386 -2006/06/07, 1019, 385 -2006/06/06, 1010, 384 -2006/06/05, 1003, 381 -2006/06/04, 998, 379 -2006/06/03, 990, 374 -2006/06/02, 988, 374 -2006/05/31, 982, 372 -2006/05/30, 982, 372 -2006/05/29, 981, 372 -2006/05/28, 977, 362 -2006/05/27, 977, 362 -2006/05/26, 976, 362 -2006/05/25, 976, 361 -2006/05/24, 976, 361 -2006/05/23, 975, 359 -2006/05/22, 974, 359 -2006/05/21, 974, 359 -2006/05/20, 972, 358 -2006/05/19, 961, 357 -2006/05/18, 960, 356 -2006/05/17, 962, 357 -2006/05/16, 952, 357 -2006/05/15, 952, 357 -2006/05/14, 952, 356 -2006/05/13, 957, 356 -2006/05/12, 957, 356 -2006/05/11, 955, 355 -2006/05/10, 955, 355 -2006/05/09, 950, 354 -2006/05/08, 949, 353 -2006/05/07, 950, 353 -2006/05/06, 950, 353 -2006/05/05, 949, 351 -2006/05/04, 948, 351 -2006/05/03, 949, 350 -2006/05/02, 949, 349 -2006/05/01, 948, 347 -2006/04/30, 948, 347 -2006/04/29, 946, 347 -2006/04/28, 945, 345 -2006/04/27, 943, 342 -2006/04/26, 943, 339 -2006/04/25, 940, 338 -2006/04/24, 935, 336 -2006/04/23, 930, 333 -2006/04/22, 927, 328 -2006/04/21, 924, 326 -2006/04/20, 919, 325 -2006/04/19, 910, 323 -2006/04/18, 900, 321 -2006/04/17, 900, 320 -2006/04/16, 897, 319 -2006/04/15, 896, 318 -2006/04/14, 887, 316 -2006/04/13, 884, 316 -2006/04/12, 880, 315 -2006/04/11, 878, 313 -2006/04/10, 878, 312 -2006/04/09, 875, 309 -2006/04/08, 854, 308 -2006/04/07, 852, 308 -2006/04/06, 848, 305 -2006/04/05, 853, 305 -2006/04/04, 846, 305 -2006/04/03, 842, 305 -2006/04/02, 840, 304 -2006/04/01, 829, 302 -2006/03/31, 821, 301 -2006/03/30, 820, 300 -2006/03/29, 820, 300 -2006/03/28, 818, 300 -2006/03/27, 815, 299 -2006/03/26, 814, 299 -2006/03/25, 813, 299 -2006/03/24, 813, 297 -2006/03/23, 809, 295 -2006/03/22, 806, 294 -2006/03/21, 792, 292 -2006/03/20, 792, 292 -2006/03/19, 788, 291 -2006/03/18, 786, 291 -2006/03/17, 786, 291 -2006/03/16, 785, 290 -2006/03/15, 784, 290 -2006/03/14, 784, 289 -2006/03/13, 784, 289 -2006/03/12, 781, 288 -2006/03/11, 781, 288 -2006/03/10, 781, 288 -2006/03/09, 781, 288 -2006/03/08, 778, 287 -2006/03/07, 777, 287 -2006/03/06, 777, 287 -2006/03/04, 776, 287 -2006/03/03, 776, 287 -2006/03/02, 776, 287 -2006/03/01, 775, 287 -2006/02/28, 766, 284 -2006/02/27, 764, 283 -2006/02/26, 762, 282 -2006/02/25, 762, 282 -2006/02/23, 762, 282 -2006/02/22, 761, 281 -2006/02/21, 761, 281 -2006/02/20, 760, 279 -2006/02/19, 760, 279 -2006/02/18, 759, 279 -2006/02/17, 759, 279 -2006/02/16, 759, 278 -2006/02/15, 756, 276 -2006/02/14, 756, 275 -2006/02/13, 755, 275 -2006/02/12, 755, 275 -2006/02/11, 754, 275 -2006/02/10, 754, 275 -2006/02/09, 754, 275 -2006/02/08, 753, 275 -2006/02/07, 749, 274 -2006/02/06, 749, 271 -2006/02/05, 749, 270 -2006/02/04, 749, 270 -2006/02/03, 747, 269 -2006/02/02, 747, 268 -2006/02/01, 746, 268 -2006/01/31, 746, 268 -2006/01/30, 745, 265 -2006/01/29, 745, 265 -2006/01/28, 744, 265 -2006/01/27, 746, 266 -2006/01/26, 735, 264 -2006/01/25, 731, 261 -2006/01/24, 725, 257 -2006/01/23, 721, 255 -2006/01/22, 715, 253 -2006/01/21, 715, 253 -2006/01/20, 715, 253 -2006/01/19, 714, 252 -2006/01/18, 713, 251 -2006/01/17, 713, 251 -2006/01/16, 713, 251 -2006/01/15, 713, 251 -2006/01/14, 713, 250 -2006/01/13, 712, 249 -2006/01/12, 712, 249 -2006/01/11, 712, 249 -2006/01/10, 712, 249 -2006/01/09, 711, 248 -2006/01/08, 711, 248 -2006/01/07, 711, 248 -2006/01/06, 711, 247 -2006/01/05, 710, 247 -2006/01/04, 710, 247 -2006/01/02, 710, 247 -2005/12/31, 708, 247 -2005/12/30, 708, 247 -2005/12/29, 706, 247 -2005/12/27, 704, 246 -2005/12/25, 704, 246 -2005/12/24, 704, 246 -2005/12/23, 704, 246 -2005/12/22, 704, 245 -2005/12/21, 704, 245 -2005/12/20, 704, 243 -2005/12/19, 704, 243 -2005/12/18, 704, 243 -2005/12/17, 704, 243 -2005/12/16, 703, 243 -2005/12/15, 703, 243 -2005/12/14, 700, 240 -2005/12/13, 700, 239 -2005/12/12, 699, 239 -2005/12/11, 699, 239 -2005/12/10, 698, 240 -2005/12/09, 698, 240 -2005/12/08, 694, 237 -2005/12/07, 694, 235 -2005/12/06, 690, 233 -2005/12/05, 690, 233 -2005/12/04, 690, 233 -2005/12/03, 690, 233 -2005/12/02, 690, 233 -2005/12/01, 689, 232 -2005/11/30, 687, 233 -2005/11/29, 686, 233 -2005/11/28, 685, 233 -2005/11/27, 683, 232 -2005/11/25, 683, 232 -2005/11/23, 683, 232 -2005/11/22, 683, 232 -2005/11/21, 683, 232 -2005/11/19, 683, 232 -2005/11/18, 683, 232 -2005/11/17, 683, 232 -2005/11/16, 682, 232 -2005/11/15, 683, 232 -2005/11/14, 683, 232 -2005/11/13, 683, 232 -2005/11/12, 683, 232 -2005/11/11, 683, 232 -2005/11/10, 683, 231 -2005/11/09, 681, 231 -2005/11/08, 681, 231 -2005/11/07, 681, 231 -2005/11/06, 681, 231 -2005/11/05, 681, 231 -2005/11/04, 681, 231 -2005/11/03, 681, 231 -2005/11/02, 681, 231 -2005/11/01, 681, 231 -2005/10/31, 681, 231 -2005/10/30, 681, 231 -2005/10/29, 684, 231 -2005/10/28, 684, 231 -2005/10/27, 684, 230 -2005/10/26, 697, 230 -2005/10/25, 697, 229 -2005/10/24, 698, 229 -2005/10/23, 698, 230 -2005/10/22, 698, 230 -2005/10/21, 698, 230 -2005/10/20, 696, 230 -2005/10/19, 696, 230 -2005/10/18, 695, 229 -2005/10/17, 693, 228 -2005/10/16, 693, 228 -2005/10/15, 688, 226 -2005/10/14, 681, 224 -2005/10/13, 662, 217 -2005/10/12, 663, 217 -2005/10/11, 657, 216 -2005/10/10, 652, 216 -2005/10/09, 629, 201 -2005/10/08, 629, 201 -2005/10/07, 629, 201 -2005/10/06, 629, 200 -2005/10/05, 648, 202 -2005/10/04, 650, 202 -2005/10/03, 648, 201 -2005/10/02, 647, 201 -2005/10/01, 643, 199 -2005/09/30, 644, 200 -2005/09/29, 645, 199 -2005/09/28, 645, 199 -2005/09/27, 645, 200 -2005/09/26, 641, 199 -2005/09/25, 638, 195 -2005/09/24, 638, 195 -2005/09/23, 638, 196 -2005/09/22, 637, 196 -2005/09/21, 636, 196 -2005/09/20, 635, 196 -2005/09/19, 635, 196 -2005/09/18, 632, 196 -2005/09/17, 631, 196 -2005/09/16, 631, 196 -2005/09/15, 631, 196 -2005/09/14, 629, 196 -2005/09/13, 629, 196 -2005/09/12, 623, 192 -2005/09/11, 623, 192 -2005/09/10, 623, 192 -2005/09/09, 625, 192 -2005/09/08, 622, 191 -2005/09/07, 647, 191 -2005/09/06, 646, 191 -2005/09/05, 631, 191 -2005/09/04, 630, 191 -2005/09/03, 630, 191 -2005/09/02, 630, 191 -2005/09/01, 630, 190 -2005/08/31, 630, 190 -2005/08/30, 630, 190 -2005/08/29, 630, 190 -2005/08/28, 630, 190 -2005/08/27, 630, 190 -2005/08/26, 626, 188 -2005/08/25, 625, 187 -2005/08/24, 633, 187 -2005/08/23, 630, 185 -2005/08/22, 626, 182 -2005/08/20, 623, 181 -2005/08/19, 623, 181 -2005/08/18, 608, 176 -2005/08/17, 607, 176 -2005/08/16, 607, 176 -2005/08/15, 606, 175 -2005/08/14, 605, 175 -2005/08/13, 605, 175 -2005/08/12, 605, 175 -2005/08/11, 605, 175 -2005/08/10, 601, 173 -2005/08/09, 596, 171 -2005/08/08, 594, 171 -2005/08/07, 591, 169 -2005/08/06, 590, 169 -2005/08/05, 589, 168 -2005/08/04, 588, 167 -2005/08/03, 583, 167 -2005/08/02, 574, 165 -2005/07/31, 573, 164 -2005/07/30, 571, 161 -2005/07/29, 565, 157 -2005/07/28, 557, 156 -2005/07/27, 544, 155 -2005/07/26, 541, 154 -2005/07/25, 534, 154 -2005/07/24, 527, 149 -2005/07/23, 527, 149 -2005/07/22, 527, 149 -2005/07/21, 527, 148 -2005/07/20, 526, 144 -2005/07/19, 523, 144 -2005/07/18, 541, 149 -2005/07/15, 538, 148 -2005/07/14, 537, 148 -2005/07/13, 536, 148 -2005/07/12, 536, 148 -2005/07/11, 535, 148 -2005/07/10, 535, 148 -2005/07/09, 531, 147 -2005/07/07, 531, 147 -2005/07/06, 528, 143 -2005/07/05, 524, 141 -2005/07/04, 507, 141 -2005/07/03, 507, 141 -2005/07/02, 472, 138 -2005/07/01, 472, 137 -2005/06/30, 471, 137 -2005/06/29, 471, 137 -2005/06/28, 470, 137 -2005/06/26, 470, 137 -2005/06/25, 470, 137 -2005/06/24, 469, 136 -2005/06/23, 473, 135 -2005/06/22, 472, 134 -2005/06/21, 472, 134 -2005/06/20, 470, 134 -2005/06/19, 468, 133 -2005/06/18, 466, 131 -2005/06/17, 455, 130 -2005/06/16, 455, 130 -2005/06/15, 456, 130 -2005/06/14, 457, 130 -2005/06/13, 474, 127 -2005/06/12, 474, 126 -2005/06/11, 473, 126 -2005/06/10, 473, 125 -2005/06/09, 472, 124 -2005/06/08, 471, 125 -2005/06/07, 469, 124 -2005/06/06, 469, 124 -2005/06/05, 462, 122 -2005/06/04, 459, 123 -2005/06/03, 458, 122 -2005/06/02, 458, 122 -2005/06/01, 457, 121 -2005/05/31, 457, 120 -2005/05/30, 454, 118 -2005/05/29, 453, 114 -2005/05/28, 452, 114 -2005/05/27, 452, 114 -2005/05/26, 448, 114 -2005/05/25, 448, 114 -2005/05/24, 446, 114 -2005/05/23, 440, 113 -2005/05/22, 434, 113 -2005/05/21, 436, 113 -2005/05/20, 425, 112 -2005/05/19, 425, 112 -2005/05/18, 426, 112 -2005/05/17, 385, 115 -2005/05/16, 385, 115 -2005/05/15, 386, 115 -2005/05/14, 375, 114 -2005/05/13, 375, 114 -2005/05/12, 374, 113 -2005/05/11, 372, 111 -2005/05/10, 371, 110 -2005/05/09, 368, 108 -2005/05/08, 367, 108 -2005/05/07, 367, 107 -2005/05/06, 367, 107 -2005/05/05, 367, 107 -2005/05/04, 366, 106 -2005/05/03, 366, 106 -2005/05/02, 364, 105 -2005/05/01, 357, 104 -2005/04/30, 368, 113 -2005/04/29, 368, 112 -2005/04/28, 365, 110 -2005/04/27, 365, 110 -2005/04/26, 363, 110 -2005/04/25, 342, 129 -2005/04/24, 327, 104 -2005/04/23, 325, 104 -2005/04/22, 325, 104 -2005/04/21, 325, 104 -2005/04/20, 325, 103 -2005/04/19, 326, 101 -2005/04/18, 326, 101 -2005/04/17, 326, 101 -2005/04/16, 323, 100 -2005/04/15, 322, 100 -2005/04/14, 321, 100 -2005/04/13, 317, 97 -2005/04/12, 316, 97 -2005/04/11, 313, 96 -2005/04/10, 311, 97 -2005/04/09, 310, 97 -2005/04/08, 310, 97 -2005/04/07, 310, 97 -2005/04/06, 310, 97 -2005/04/05, 310, 97 -2005/04/04, 310, 97 -2005/04/03, 309, 97 -2005/04/02, 305, 97 -2005/04/01, 297, 97 -2005/03/31, 291, 97 -2005/03/30, 290, 97 -2005/03/29, 290, 97 -2005/03/28, 289, 96 -2005/03/27, 289, 96 -2005/03/24, 289, 96 -2005/03/23, 289, 96 -2005/03/22, 288, 97 -2005/03/21, 276, 95 -2005/03/20, 272, 94 -2005/03/19, 267, 90 -2005/03/17, 266, 90 -2005/03/15, 265, 90 -2005/03/14, 265, 90 -2005/03/13, 265, 90 -2005/03/12, 265, 90 -2005/03/11, 265, 90 -2005/03/10, 265, 90 -2005/03/06, 264, 90 -2005/03/05, 264, 90 -2005/03/04, 264, 90 -2005/03/03, 264, 90 -2005/03/02, 264, 90 -2005/03/01, 263, 90 -2005/02/28, 263, 90 -2005/02/27, 262, 90 -2005/02/26, 262, 90 -2005/02/25, 262, 90 -2005/02/24, 261, 89 -2005/02/23, 259, 89 -2005/02/22, 259, 89 -2005/02/21, 259, 88 -2005/02/19, 259, 88 -2005/02/18, 244, 88 -2005/02/17, 244, 87 -2005/02/16, 244, 87 -2005/02/15, 244, 87 -2005/02/14, 243, 87 -2005/02/13, 243, 87 -2005/02/13, 243, 87 -2005/02/13, 243, 87 -2005/02/11, 242, 87 -2005/02/10, 242, 86 -2005/02/09, 240, 85 -2005/02/08, 240, 85 -2005/02/07, 240, 85 -2005/02/06, 239, 85 -2005/02/05, 231, 84 -2005/02/04, 231, 84 -2005/02/03, 232, 83 -2005/02/02, 232, 83 -2005/02/01, 231, 82 -2005/01/31, 228, 82 -2005/01/30, 228, 82 -2005/01/29, 228, 82 -2005/01/28, 232, 80 -2005/01/27, 211, 79 -2005/01/26, 225, 80 -2005/01/25, 225, 80 -2005/01/24, 224, 78 -2005/01/23, 224, 78 -2005/01/22, 224, 78 -2005/01/20, 224, 78 -2005/01/19, 224, 78 -2005/01/18, 224, 77 -2005/01/17, 224, 77 -2005/01/16, 224, 77 -2005/01/15, 224, 77 -2005/01/14, 224, 77 -2005/01/13, 224, 77 -2005/01/12, 224, 77 -2005/01/11, 218, 76 -2005/01/10, 218, 76 -2005/01/09, 218, 76 -2005/01/08, 218, 76 -2005/01/03, 218, 76 -2005/01/02, 218, 76 -2005/01/01, 218, 76 -2004/12/30, 218, 76 -2004/12/27, 218, 76 -2004/12/24, 218, 76 -2004/12/22, 218, 75 -2004/12/20, 218, 75 -2004/12/19, 218, 75 -2004/12/18, 217, 75 -2004/12/17, 217, 75 -2004/12/16, 217, 74 -2004/12/13, 216, 74 -2004/12/10, 216, 74 -2004/12/09, 216, 74 -2004/12/08, 216, 74 -2004/12/07, 216, 74 -2004/12/06, 216, 73 -2004/12/04, 216, 73 -2004/11/30, 214, 73 -2004/11/29, 213, 73 -2004/11/28, 213, 72 -2004/11/27, 213, 72 -2004/11/25, 213, 72 -2004/11/24, 213, 72 -2004/11/23, 211, 72 -2004/11/22, 210, 71 -2004/11/21, 210, 71 -2004/11/20, 210, 71 -2004/11/19, 208, 69 -2004/11/18, 208, 69 -2004/11/17, 204, 67 -2004/11/16, 201, 66 -2004/11/15, 203, 67 +2003-02-19, 8, 0 +2003-02-20, 10, 1 +2003-02-21, 29, 5 +2003-02-22, 30, 4 +2003-02-23, 49, 12 +2003-02-24, 49, 12 +2003-02-25, 48, 12 +2003-02-26, 48, 12 +2003-02-27, 48, 12 +2003-02-28, 48, 12 +2003-03-01, 48, 12 +2003-03-03, 48, 13 +2003-03-04, 48, 13 +2003-03-18, 48, 13 +2003-04-06, 48, 13 +2003-04-11, 48, 13 +2003-04-18, 48, 14 +2003-04-19, 48, 15 +2003-05-22, 48, 15 +2003-05-25, 48, 15 +2003-05-26, 52, 19 +2003-05-27, 59, 26 +2003-05-28, 70, 27 +2003-05-29, 71, 26 +2003-05-30, 75, 37 +2003-05-31, 87, 37 +2003-06-01, 92, 37 +2003-06-02, 92, 37 +2003-06-05, 92, 37 +2003-06-06, 93, 37 +2003-06-07, 93, 37 +2003-06-08, 92, 37 +2003-06-09, 92, 37 +2003-06-13, 92, 37 +2003-06-14, 93, 37 +2003-06-15, 93, 37 +2003-06-16, 94, 37 +2003-06-17, 94, 37 +2003-06-18, 94, 37 +2003-06-19, 92, 37 +2003-06-20, 92, 37 +2003-06-21, 92, 37 +2003-06-22, 98, 40 +2003-06-23, 102, 42 +2003-06-24, 103, 43 +2003-06-28, 104, 43 +2003-06-29, 104, 43 +2003-06-30, 104, 43 +2003-07-01, 104, 43 +2003-07-02, 104, 43 +2003-07-03, 104, 43 +2003-07-04, 104, 43 +2003-07-06, 104, 43 +2003-07-07, 104, 43 +2003-07-08, 106, 43 +2003-07-10, 106, 43 +2003-07-12, 106, 43 +2003-07-13, 106, 43 +2003-07-14, 106, 43 +2003-07-15, 106, 43 +2003-07-16, 106, 43 +2003-07-17, 106, 43 +2003-07-18, 106, 43 +2003-07-19, 106, 43 +2003-07-24, 106, 43 +2003-07-26, 106, 43 +2003-07-27, 106, 43 +2003-07-28, 106, 43 +2003-07-29, 106, 43 +2003-07-30, 106, 43 +2003-07-31, 106, 43 +2003-08-01, 106, 43 +2003-08-02, 106, 43 +2003-08-06, 106, 43 +2003-08-07, 106, 43 +2003-08-09, 106, 43 +2003-08-10, 106, 43 +2003-08-17, 106, 43 +2003-08-24, 106, 43 +2003-08-25, 106, 43 +2003-09-02, 106, 43 +2003-09-07, 106, 43 +2003-09-08, 106, 43 +2003-09-09, 106, 43 +2003-09-10, 106, 43 +2003-09-12, 106, 43 +2003-09-13, 106, 43 +2003-09-14, 106, 43 +2003-09-15, 106, 43 +2003-09-16, 106, 43 +2003-09-17, 106, 43 +2003-09-18, 108, 42 +2003-09-19, 108, 42 +2003-09-20, 108, 42 +2003-09-21, 108, 42 +2003-09-22, 108, 42 +2003-09-23, 108, 46 +2003-09-25, 108, 46 +2003-09-26, 108, 46 +2003-09-28, 108, 46 +2003-09-29, 108, 46 +2003-09-30, 118, 48 +2003-10-01, 121, 49 +2003-10-02, 124, 53 +2003-10-03, 124, 53 +2003-10-04, 124, 53 +2003-10-05, 118, 52 +2003-10-06, 118, 52 +2003-10-07, 118, 52 +2003-10-08, 118, 52 +2003-10-09, 118, 52 +2003-10-10, 122, 53 +2003-10-11, 123, 54 +2003-10-12, 123, 54 +2003-10-13, 123, 54 +2003-10-14, 123, 54 +2003-10-15, 123, 54 +2003-10-16, 124, 54 +2003-10-17, 125, 54 +2003-10-18, 126, 54 +2003-10-20, 126, 54 +2003-10-21, 126, 54 +2003-10-23, 126, 54 +2003-10-24, 127, 54 +2003-10-25, 127, 54 +2003-10-26, 130, 54 +2003-10-27, 131, 53 +2003-10-28, 131, 53 +2003-10-29, 131, 53 +2003-10-30, 131, 53 +2003-10-31, 131, 53 +2003-11-03, 130, 53 +2003-11-04, 130, 53 +2003-11-05, 130, 53 +2003-11-10, 130, 53 +2003-11-11, 131, 54 +2003-11-13, 131, 54 +2003-11-14, 131, 54 +2003-11-17, 131, 54 +2003-11-18, 131, 55 +2003-11-19, 131, 54 +2003-11-20, 131, 54 +2003-11-21, 131, 54 +2003-11-22, 131, 54 +2003-11-24, 130, 55 +2003-11-25, 130, 55 +2003-11-26, 129, 55 +2003-11-27, 133, 55 +2003-11-28, 133, 55 +2003-11-29, 133, 55 +2003-11-30, 140, 55 +2003-12-01, 140, 55 +2003-12-02, 140, 55 +2003-12-03, 140, 55 +2003-12-04, 140, 55 +2003-12-08, 140, 55 +2003-12-09, 140, 55 +2003-12-10, 140, 55 +2003-12-11, 140, 55 +2003-12-12, 140, 55 +2003-12-13, 140, 55 +2003-12-15, 140, 55 +2003-12-16, 145, 55 +2003-12-17, 147, 56 +2003-12-18, 149, 57 +2003-12-19, 156, 57 +2003-12-20, 159, 58 +2003-12-21, 161, 58 +2003-12-22, 161, 58 +2003-12-23, 161, 58 +2003-12-24, 162, 58 +2003-12-27, 162, 58 +2003-12-28, 162, 58 +2003-12-29, 162, 58 +2003-12-31, 162, 58 +2004-01-01, 165, 59 +2004-01-02, 165, 59 +2004-01-05, 165, 59 +2004-01-06, 160, 59 +2004-01-07, 160, 59 +2004-01-08, 160, 59 +2004-01-09, 161, 59 +2004-01-10, 161, 59 +2004-01-11, 161, 59 +2004-01-12, 161, 59 +2004-01-13, 161, 59 +2004-01-14, 161, 59 +2004-01-15, 161, 59 +2004-01-16, 161, 59 +2004-01-17, 161, 59 +2004-01-18, 161, 59 +2004-01-19, 161, 59 +2004-01-20, 161, 59 +2004-01-21, 161, 59 +2004-01-22, 161, 59 +2004-01-23, 161, 59 +2004-01-26, 161, 59 +2004-01-27, 161, 59 +2004-01-28, 161, 59 +2004-01-29, 161, 59 +2004-01-30, 161, 59 +2004-02-02, 161, 59 +2004-02-03, 161, 59 +2004-02-04, 161, 59 +2004-02-05, 161, 59 +2004-02-07, 161, 59 +2004-02-08, 161, 59 +2004-02-09, 161, 59 +2004-02-10, 161, 59 +2004-02-11, 161, 59 +2004-02-12, 161, 59 +2004-02-13, 161, 59 +2004-02-14, 161, 59 +2004-02-15, 161, 59 +2004-02-16, 161, 59 +2004-02-19, 161, 59 +2004-02-20, 161, 59 +2004-02-21, 161, 59 +2004-02-23, 161, 59 +2004-02-24, 161, 59 +2004-02-25, 161, 59 +2004-02-26, 161, 59 +2004-02-27, 161, 59 +2004-02-28, 161, 59 +2004-02-29, 161, 59 +2004-03-01, 161, 59 +2004-03-02, 161, 59 +2004-03-03, 161, 59 +2004-03-04, 161, 59 +2004-03-05, 161, 59 +2004-03-06, 161, 59 +2004-03-07, 161, 59 +2004-03-08, 161, 59 +2004-03-09, 161, 59 +2004-03-10, 161, 59 +2004-03-11, 161, 59 +2004-03-12, 161, 59 +2004-03-13, 161, 59 +2004-03-14, 161, 59 +2004-03-16, 161, 59 +2004-03-17, 161, 59 +2004-03-18, 161, 59 +2004-03-19, 161, 59 +2004-03-21, 161, 59 +2004-03-22, 161, 59 +2004-03-23, 161, 59 +2004-03-24, 162, 59 +2004-03-25, 162, 59 +2004-03-26, 162, 59 +2004-03-28, 162, 59 +2004-03-29, 161, 59 +2004-03-30, 161, 59 +2004-03-31, 161, 59 +2004-04-01, 161, 59 +2004-04-02, 161, 59 +2004-04-03, 161, 59 +2004-04-04, 161, 59 +2004-04-05, 161, 59 +2004-04-06, 161, 59 +2004-04-07, 161, 59 +2004-04-08, 161, 59 +2004-04-09, 161, 59 +2004-04-10, 161, 59 +2004-04-11, 161, 59 +2004-04-13, 161, 59 +2004-04-14, 161, 59 +2004-04-15, 161, 59 +2004-04-16, 161, 59 +2004-04-17, 161, 59 +2004-04-18, 161, 59 +2004-04-19, 161, 59 +2004-04-20, 161, 59 +2004-04-21, 161, 59 +2004-04-22, 161, 59 +2004-04-23, 161, 59 +2004-04-24, 161, 59 +2004-04-25, 161, 59 +2004-04-26, 161, 59 +2004-04-27, 161, 59 +2004-04-28, 161, 59 +2004-04-29, 161, 59 +2004-04-30, 161, 59 +2004-05-01, 161, 59 +2004-05-02, 161, 59 +2004-05-03, 161, 59 +2004-05-04, 161, 59 +2004-05-05, 161, 59 +2004-05-06, 161, 59 +2004-05-07, 164, 59 +2004-05-08, 165, 59 +2004-05-09, 165, 59 +2004-05-10, 165, 59 +2004-05-11, 165, 59 +2004-05-12, 167, 59 +2004-05-13, 167, 59 +2004-05-14, 167, 59 +2004-05-15, 167, 59 +2004-05-16, 167, 59 +2004-05-17, 167, 59 +2004-05-18, 167, 59 +2004-05-19, 167, 59 +2004-05-20, 167, 59 +2004-05-21, 167, 59 +2004-05-22, 167, 59 +2004-05-23, 167, 59 +2004-05-24, 167, 59 +2004-05-25, 167, 59 +2004-05-26, 167, 59 +2004-05-27, 167, 59 +2004-05-28, 168, 59 +2004-05-29, 168, 59 +2004-05-30, 168, 59 +2004-05-31, 168, 59 +2004-06-01, 176, 61 +2004-06-02, 188, 63 +2004-06-03, 188, 63 +2004-06-04, 188, 63 +2004-06-05, 190, 63 +2004-06-06, 190, 63 +2004-06-07, 195, 64 +2004-06-08, 195, 64 +2004-06-09, 195, 64 +2004-06-10, 195, 64 +2004-06-11, 198, 64 +2004-06-12, 198, 64 +2004-06-13, 199, 64 +2004-06-15, 199, 64 +2004-06-16, 184, 65 +2004-06-17, 185, 64 +2004-06-18, 185, 64 +2004-06-19, 185, 64 +2004-06-20, 185, 64 +2004-06-21, 185, 64 +2004-06-22, 186, 64 +2004-06-23, 186, 64 +2004-06-24, 186, 64 +2004-06-25, 186, 64 +2004-06-26, 187, 64 +2004-06-27, 188, 65 +2004-06-28, 195, 67 +2004-06-29, 195, 67 +2004-06-30, 195, 67 +2004-07-01, 195, 67 +2004-07-02, 196, 67 +2004-07-03, 195, 67 +2004-07-04, 194, 67 +2004-07-05, 194, 67 +2004-07-06, 195, 69 +2004-07-07, 195, 69 +2004-07-08, 195, 69 +2004-07-09, 195, 69 +2004-07-10, 195, 69 +2004-07-11, 195, 69 +2004-07-12, 198, 69 +2004-07-13, 198, 69 +2004-07-14, 198, 69 +2004-07-15, 198, 69 +2004-07-16, 198, 68 +2004-07-17, 192, 66 +2004-07-21, 192, 66 +2004-07-22, 192, 66 +2004-07-23, 192, 66 +2004-07-24, 194, 66 +2004-07-25, 195, 66 +2004-07-26, 195, 66 +2004-07-27, 195, 66 +2004-07-28, 197, 67 +2004-07-29, 197, 67 +2004-07-30, 197, 67 +2004-07-31, 197, 67 +2004-08-01, 197, 67 +2004-08-02, 197, 67 +2004-08-03, 197, 67 +2004-08-04, 197, 67 +2004-08-05, 197, 67 +2004-08-06, 197, 67 +2004-08-07, 197, 67 +2004-08-08, 197, 67 +2004-08-09, 197, 67 +2004-08-10, 197, 67 +2004-08-11, 197, 67 +2004-08-12, 197, 67 +2004-08-13, 197, 67 +2004-08-14, 198, 67 +2004-08-15, 198, 67 +2004-08-16, 199, 67 +2004-08-17, 199, 67 +2004-08-18, 199, 67 +2004-08-19, 199, 67 +2004-08-20, 199, 67 +2004-08-21, 199, 67 +2004-08-22, 199, 67 +2004-08-23, 199, 67 +2004-08-24, 200, 67 +2004-08-25, 200, 67 +2004-08-26, 200, 67 +2004-08-27, 200, 67 +2004-08-30, 200, 67 +2004-08-31, 200, 67 +2004-09-01, 200, 67 +2004-09-02, 200, 67 +2004-09-03, 200, 67 +2004-09-04, 200, 67 +2004-09-06, 200, 67 +2004-09-07, 205, 68 +2004-09-08, 205, 68 +2004-09-09, 206, 68 +2004-09-10, 207, 68 +2004-09-11, 207, 68 +2004-09-12, 207, 68 +2004-09-13, 207, 68 +2004-09-14, 207, 68 +2004-09-15, 207, 68 +2004-09-16, 207, 68 +2004-09-17, 207, 68 +2004-09-18, 207, 68 +2004-09-19, 207, 68 +2004-09-20, 207, 68 +2004-09-21, 207, 68 +2004-09-22, 207, 68 +2004-09-23, 207, 68 +2004-09-24, 207, 68 +2004-09-25, 207, 68 +2004-09-26, 207, 68 +2004-09-27, 207, 68 +2004-09-28, 207, 68 +2004-09-29, 207, 68 +2004-09-30, 207, 68 +2004-10-01, 207, 68 +2004-10-02, 207, 68 +2004-10-03, 207, 68 +2004-10-04, 207, 68 +2004-10-05, 207, 68 +2004-10-06, 207, 68 +2004-10-07, 207, 68 +2004-10-08, 207, 68 +2004-10-09, 207, 68 +2004-10-10, 202, 68 +2004-10-11, 202, 68 +2004-10-13, 202, 68 +2004-10-14, 202, 68 +2004-10-15, 202, 68 +2004-10-16, 202, 68 +2004-10-17, 202, 68 +2004-10-18, 202, 68 +2004-10-19, 202, 68 +2004-10-20, 202, 68 +2004-10-21, 202, 68 +2004-10-22, 202, 68 +2004-10-23, 202, 68 +2004-10-24, 202, 68 +2004-10-25, 202, 68 +2004-10-26, 202, 68 +2004-10-27, 202, 68 +2004-10-28, 202, 68 +2004-10-29, 202, 68 +2004-10-30, 202, 68 +2004-10-31, 202, 68 +2004-11-01, 202, 68 +2004-11-02, 202, 68 +2004-11-03, 202, 68 +2004-11-04, 202, 68 +2004-11-05, 202, 68 +2004-11-06, 202, 68 +2004-11-08, 202, 68 +2004-11-09, 202, 68 +2004-11-10, 202, 68 +2004-11-11, 202, 68 2004/11/12, 202, 68 -2004/11/11, 202, 68 +2004/11/15, 203, 67 +2004/11/16, 201, 66 +2004/11/17, 204, 67 +2004/11/18, 208, 69 +2004/11/19, 208, 69 +2004/11/20, 210, 71 +2004/11/21, 210, 71 +2004/11/22, 210, 71 +2004/11/23, 211, 72 +2004/11/24, 213, 72 +2004/11/25, 213, 72 +2004/11/27, 213, 72 +2004/11/28, 213, 72 +2004/11/29, 213, 73 +2004/11/30, 214, 73 +2004/12/04, 216, 73 +2004/12/06, 216, 73 +2004/12/07, 216, 74 +2004/12/08, 216, 74 +2004/12/09, 216, 74 +2004/12/10, 216, 74 +2004/12/13, 216, 74 +2004/12/16, 217, 74 +2004/12/17, 217, 75 +2004/12/18, 217, 75 +2004/12/19, 218, 75 +2004/12/20, 218, 75 +2004/12/22, 218, 75 +2004/12/24, 218, 76 +2004/12/27, 218, 76 +2004/12/30, 218, 76 +2005/01/01, 218, 76 +2005/01/02, 218, 76 +2005/01/03, 218, 76 +2005/01/08, 218, 76 +2005/01/09, 218, 76 +2005/01/10, 218, 76 +2005/01/11, 218, 76 +2005/01/12, 224, 77 +2005/01/13, 224, 77 +2005/01/14, 224, 77 +2005/01/15, 224, 77 +2005/01/16, 224, 77 +2005/01/17, 224, 77 +2005/01/18, 224, 77 +2005/01/19, 224, 78 +2005/01/20, 224, 78 +2005/01/22, 224, 78 +2005/01/23, 224, 78 +2005/01/24, 224, 78 +2005/01/25, 225, 80 +2005/01/26, 225, 80 +2005/01/27, 211, 79 +2005/01/28, 232, 80 +2005/01/29, 228, 82 +2005/01/30, 228, 82 +2005/01/31, 228, 82 +2005/02/01, 231, 82 +2005/02/02, 232, 83 +2005/02/03, 232, 83 +2005/02/04, 231, 84 +2005/02/05, 231, 84 +2005/02/06, 239, 85 +2005/02/07, 240, 85 +2005/02/08, 240, 85 +2005/02/09, 240, 85 +2005/02/10, 242, 86 +2005/02/11, 242, 87 +2005/02/13, 243, 87 +2005/02/13, 243, 87 +2005/02/13, 243, 87 +2005/02/14, 243, 87 +2005/02/15, 244, 87 +2005/02/16, 244, 87 +2005/02/17, 244, 87 +2005/02/18, 244, 88 +2005/02/19, 259, 88 +2005/02/21, 259, 88 +2005/02/22, 259, 89 +2005/02/23, 259, 89 +2005/02/24, 261, 89 +2005/02/25, 262, 90 +2005/02/26, 262, 90 +2005/02/27, 262, 90 +2005/02/28, 263, 90 +2005/03/01, 263, 90 +2005/03/02, 264, 90 +2005/03/03, 264, 90 +2005/03/04, 264, 90 +2005/03/05, 264, 90 +2005/03/06, 264, 90 +2005/03/10, 265, 90 +2005/03/11, 265, 90 +2005/03/12, 265, 90 +2005/03/13, 265, 90 +2005/03/14, 265, 90 +2005/03/15, 265, 90 +2005/03/17, 266, 90 +2005/03/19, 267, 90 +2005/03/20, 272, 94 +2005/03/21, 276, 95 +2005/03/22, 288, 97 +2005/03/23, 289, 96 +2005/03/24, 289, 96 +2005/03/27, 289, 96 +2005/03/28, 289, 96 +2005/03/29, 290, 97 +2005/03/30, 290, 97 +2005/03/31, 291, 97 +2005/04/01, 297, 97 +2005/04/02, 305, 97 +2005/04/03, 309, 97 +2005/04/04, 310, 97 +2005/04/05, 310, 97 +2005/04/06, 310, 97 +2005/04/07, 310, 97 +2005/04/08, 310, 97 +2005/04/09, 310, 97 +2005/04/10, 311, 97 +2005/04/11, 313, 96 +2005/04/12, 316, 97 +2005/04/13, 317, 97 +2005/04/14, 321, 100 +2005/04/15, 322, 100 +2005/04/16, 323, 100 +2005/04/17, 326, 101 +2005/04/18, 326, 101 +2005/04/19, 326, 101 +2005/04/20, 325, 103 +2005/04/21, 325, 104 +2005/04/22, 325, 104 +2005/04/23, 325, 104 +2005/04/24, 327, 104 +2005/04/25, 342, 129 +2005/04/26, 363, 110 +2005/04/27, 365, 110 +2005/04/28, 365, 110 +2005/04/29, 368, 112 +2005/04/30, 368, 113 +2005/05/01, 357, 104 +2005/05/02, 364, 105 +2005/05/03, 366, 106 +2005/05/04, 366, 106 +2005/05/05, 367, 107 +2005/05/06, 367, 107 +2005/05/07, 367, 107 +2005/05/08, 367, 108 +2005/05/09, 368, 108 +2005/05/10, 371, 110 +2005/05/11, 372, 111 +2005/05/12, 374, 113 +2005/05/13, 375, 114 +2005/05/14, 375, 114 +2005/05/15, 386, 115 +2005/05/16, 385, 115 +2005/05/17, 385, 115 +2005/05/18, 426, 112 +2005/05/19, 425, 112 +2005/05/20, 425, 112 +2005/05/21, 436, 113 +2005/05/22, 434, 113 +2005/05/23, 440, 113 +2005/05/24, 446, 114 +2005/05/25, 448, 114 +2005/05/26, 448, 114 +2005/05/27, 452, 114 +2005/05/28, 452, 114 +2005/05/29, 453, 114 +2005/05/30, 454, 118 +2005/05/31, 457, 120 +2005/06/01, 457, 121 +2005/06/02, 458, 122 +2005/06/03, 458, 122 +2005/06/04, 459, 123 +2005/06/05, 462, 122 +2005/06/06, 469, 124 +2005/06/07, 469, 124 +2005/06/08, 471, 125 +2005/06/09, 472, 124 +2005/06/10, 473, 125 +2005/06/11, 473, 126 +2005/06/12, 474, 126 +2005/06/13, 474, 127 +2005/06/14, 457, 130 +2005/06/15, 456, 130 +2005/06/16, 455, 130 +2005/06/17, 455, 130 +2005/06/18, 466, 131 +2005/06/19, 468, 133 +2005/06/20, 470, 134 +2005/06/21, 472, 134 +2005/06/22, 472, 134 +2005/06/23, 473, 135 +2005/06/24, 469, 136 +2005/06/25, 470, 137 +2005/06/26, 470, 137 +2005/06/28, 470, 137 +2005/06/29, 471, 137 +2005/06/30, 471, 137 +2005/07/01, 472, 137 +2005/07/02, 472, 138 +2005/07/03, 507, 141 +2005/07/04, 507, 141 +2005/07/05, 524, 141 +2005/07/06, 528, 143 +2005/07/07, 531, 147 +2005/07/09, 531, 147 +2005/07/10, 535, 148 +2005/07/11, 535, 148 +2005/07/12, 536, 148 +2005/07/13, 536, 148 +2005/07/14, 537, 148 +2005/07/15, 538, 148 +2005/07/18, 541, 149 +2005/07/19, 523, 144 +2005/07/20, 526, 144 +2005/07/21, 527, 148 +2005/07/22, 527, 149 +2005/07/23, 527, 149 +2005/07/24, 527, 149 +2005/07/25, 534, 154 +2005/07/26, 541, 154 +2005/07/27, 544, 155 +2005/07/28, 557, 156 +2005/07/29, 565, 157 +2005/07/30, 571, 161 +2005/07/31, 573, 164 +2005/08/02, 574, 165 +2005/08/03, 583, 167 +2005/08/04, 588, 167 +2005/08/05, 589, 168 +2005/08/06, 590, 169 +2005/08/07, 591, 169 +2005/08/08, 594, 171 +2005/08/09, 596, 171 +2005/08/10, 601, 173 +2005/08/11, 605, 175 +2005/08/12, 605, 175 +2005/08/13, 605, 175 +2005/08/14, 605, 175 +2005/08/15, 606, 175 +2005/08/16, 607, 176 +2005/08/17, 607, 176 +2005/08/18, 608, 176 +2005/08/19, 623, 181 +2005/08/20, 623, 181 +2005/08/22, 626, 182 +2005/08/23, 630, 185 +2005/08/24, 633, 187 +2005/08/25, 625, 187 +2005/08/26, 626, 188 +2005/08/27, 630, 190 +2005/08/28, 630, 190 +2005/08/29, 630, 190 +2005/08/30, 630, 190 +2005/08/31, 630, 190 +2005/09/01, 630, 190 +2005/09/02, 630, 191 +2005/09/03, 630, 191 +2005/09/04, 630, 191 +2005/09/05, 631, 191 +2005/09/06, 646, 191 +2005/09/07, 647, 191 +2005/09/08, 622, 191 +2005/09/09, 625, 192 +2005/09/10, 623, 192 +2005/09/11, 623, 192 +2005/09/12, 623, 192 +2005/09/13, 629, 196 +2005/09/14, 629, 196 +2005/09/15, 631, 196 +2005/09/16, 631, 196 +2005/09/17, 631, 196 +2005/09/18, 632, 196 +2005/09/19, 635, 196 +2005/09/20, 635, 196 +2005/09/21, 636, 196 +2005/09/22, 637, 196 +2005/09/23, 638, 196 +2005/09/24, 638, 195 +2005/09/25, 638, 195 +2005/09/26, 641, 199 +2005/09/27, 645, 200 +2005/09/28, 645, 199 +2005/09/29, 645, 199 +2005/09/30, 644, 200 +2005/10/01, 643, 199 +2005/10/02, 647, 201 +2005/10/03, 648, 201 +2005/10/04, 650, 202 +2005/10/05, 648, 202 +2005/10/06, 629, 200 +2005/10/07, 629, 201 +2005/10/08, 629, 201 +2005/10/09, 629, 201 +2005/10/10, 652, 216 +2005/10/11, 657, 216 +2005/10/12, 663, 217 +2005/10/13, 662, 217 +2005/10/14, 681, 224 +2005/10/15, 688, 226 +2005/10/16, 693, 228 +2005/10/17, 693, 228 +2005/10/18, 695, 229 +2005/10/19, 696, 230 +2005/10/20, 696, 230 +2005/10/21, 698, 230 +2005/10/22, 698, 230 +2005/10/23, 698, 230 +2005/10/24, 698, 229 +2005/10/25, 697, 229 +2005/10/26, 697, 230 +2005/10/27, 684, 230 +2005/10/28, 684, 231 +2005/10/29, 684, 231 +2005/10/30, 681, 231 +2005/10/31, 681, 231 +2005/11/01, 681, 231 +2005/11/02, 681, 231 +2005/11/03, 681, 231 +2005/11/04, 681, 231 +2005/11/05, 681, 231 +2005/11/06, 681, 231 +2005/11/07, 681, 231 +2005/11/08, 681, 231 +2005/11/09, 681, 231 +2005/11/10, 683, 231 +2005/11/11, 683, 232 +2005/11/12, 683, 232 +2005/11/13, 683, 232 +2005/11/14, 683, 232 +2005/11/15, 683, 232 +2005/11/16, 682, 232 +2005/11/17, 683, 232 +2005/11/18, 683, 232 +2005/11/19, 683, 232 +2005/11/21, 683, 232 +2005/11/22, 683, 232 +2005/11/23, 683, 232 +2005/11/25, 683, 232 +2005/11/27, 683, 232 +2005/11/28, 685, 233 +2005/11/29, 686, 233 +2005/11/30, 687, 233 +2005/12/01, 689, 232 +2005/12/02, 690, 233 +2005/12/03, 690, 233 +2005/12/04, 690, 233 +2005/12/05, 690, 233 +2005/12/06, 690, 233 +2005/12/07, 694, 235 +2005/12/08, 694, 237 +2005/12/09, 698, 240 +2005/12/10, 698, 240 +2005/12/11, 699, 239 +2005/12/12, 699, 239 +2005/12/13, 700, 239 +2005/12/14, 700, 240 +2005/12/15, 703, 243 +2005/12/16, 703, 243 +2005/12/17, 704, 243 +2005/12/18, 704, 243 +2005/12/19, 704, 243 +2005/12/20, 704, 243 +2005/12/21, 704, 245 +2005/12/22, 704, 245 +2005/12/23, 704, 246 +2005/12/24, 704, 246 +2005/12/25, 704, 246 +2005/12/27, 704, 246 +2005/12/29, 706, 247 +2005/12/30, 708, 247 +2005/12/31, 708, 247 +2006/01/02, 710, 247 +2006/01/04, 710, 247 +2006/01/05, 710, 247 +2006/01/06, 711, 247 +2006/01/07, 711, 248 +2006/01/08, 711, 248 +2006/01/09, 711, 248 +2006/01/10, 712, 249 +2006/01/11, 712, 249 +2006/01/12, 712, 249 +2006/01/13, 712, 249 +2006/01/14, 713, 250 +2006/01/15, 713, 251 +2006/01/16, 713, 251 +2006/01/17, 713, 251 +2006/01/18, 713, 251 +2006/01/19, 714, 252 +2006/01/20, 715, 253 +2006/01/21, 715, 253 +2006/01/22, 715, 253 +2006/01/23, 721, 255 +2006/01/24, 725, 257 +2006/01/25, 731, 261 +2006/01/26, 735, 264 +2006/01/27, 746, 266 +2006/01/28, 744, 265 +2006/01/29, 745, 265 +2006/01/30, 745, 265 +2006/01/31, 746, 268 +2006/02/01, 746, 268 +2006/02/02, 747, 268 +2006/02/03, 747, 269 +2006/02/04, 749, 270 +2006/02/05, 749, 270 +2006/02/06, 749, 271 +2006/02/07, 749, 274 +2006/02/08, 753, 275 +2006/02/09, 754, 275 +2006/02/10, 754, 275 +2006/02/11, 754, 275 +2006/02/12, 755, 275 +2006/02/13, 755, 275 +2006/02/14, 756, 275 +2006/02/15, 756, 276 +2006/02/16, 759, 278 +2006/02/17, 759, 279 +2006/02/18, 759, 279 +2006/02/19, 760, 279 +2006/02/20, 760, 279 +2006/02/21, 761, 281 +2006/02/22, 761, 281 +2006/02/23, 762, 282 +2006/02/25, 762, 282 +2006/02/26, 762, 282 +2006/02/27, 764, 283 +2006/02/28, 766, 284 +2006/03/01, 775, 287 +2006/03/02, 776, 287 +2006/03/03, 776, 287 +2006/03/04, 776, 287 +2006/03/06, 777, 287 +2006/03/07, 777, 287 +2006/03/08, 778, 287 +2006/03/09, 781, 288 +2006/03/10, 781, 288 +2006/03/11, 781, 288 +2006/03/12, 781, 288 +2006/03/13, 784, 289 +2006/03/14, 784, 289 +2006/03/15, 784, 290 +2006/03/16, 785, 290 +2006/03/17, 786, 291 +2006/03/18, 786, 291 +2006/03/19, 788, 291 +2006/03/20, 792, 292 +2006/03/21, 792, 292 +2006/03/22, 806, 294 +2006/03/23, 809, 295 +2006/03/24, 813, 297 +2006/03/25, 813, 299 +2006/03/26, 814, 299 +2006/03/27, 815, 299 +2006/03/28, 818, 300 +2006/03/29, 820, 300 +2006/03/30, 820, 300 +2006/03/31, 821, 301 +2006/04/01, 829, 302 +2006/04/02, 840, 304 +2006/04/03, 842, 305 +2006/04/04, 846, 305 +2006/04/05, 853, 305 +2006/04/06, 848, 305 +2006/04/07, 852, 308 +2006/04/08, 854, 308 +2006/04/09, 875, 309 +2006/04/10, 878, 312 +2006/04/11, 878, 313 +2006/04/12, 880, 315 +2006/04/13, 884, 316 +2006/04/14, 887, 316 +2006/04/15, 896, 318 +2006/04/16, 897, 319 +2006/04/17, 900, 320 +2006/04/18, 900, 321 +2006/04/19, 910, 323 +2006/04/20, 919, 325 +2006/04/21, 924, 326 +2006/04/22, 927, 328 +2006/04/23, 930, 333 +2006/04/24, 935, 336 +2006/04/25, 940, 338 +2006/04/26, 943, 339 +2006/04/27, 943, 342 +2006/04/28, 945, 345 +2006/04/29, 946, 347 +2006/04/30, 948, 347 +2006/05/01, 948, 347 +2006/05/02, 949, 349 +2006/05/03, 949, 350 +2006/05/04, 948, 351 +2006/05/05, 949, 351 +2006/05/06, 950, 353 +2006/05/07, 950, 353 +2006/05/08, 949, 353 +2006/05/09, 950, 354 +2006/05/10, 955, 355 +2006/05/11, 955, 355 +2006/05/12, 957, 356 +2006/05/13, 957, 356 +2006/05/14, 952, 356 +2006/05/15, 952, 357 +2006/05/16, 952, 357 +2006/05/17, 962, 357 +2006/05/18, 960, 356 +2006/05/19, 961, 357 +2006/05/20, 972, 358 +2006/05/21, 974, 359 +2006/05/22, 974, 359 +2006/05/23, 975, 359 +2006/05/24, 976, 361 +2006/05/25, 976, 361 +2006/05/26, 976, 362 +2006/05/27, 977, 362 +2006/05/28, 977, 362 +2006/05/29, 981, 372 +2006/05/30, 982, 372 +2006/05/31, 982, 372 +2006/06/02, 988, 374 +2006/06/03, 990, 374 +2006/06/04, 998, 379 +2006/06/05, 1003, 381 +2006/06/06, 1010, 384 +2006/06/07, 1019, 385 +2006/06/08, 1021, 386 +2006/06/09, 1004, 369 +2006/06/10, 1004, 369 +2006/06/11, 1005, 369 +2006/06/12, 1010, 371 +2006/06/13, 1004, 371 +2006/06/14, 1005, 371 +2006/06/15, 1006, 375 +2006/06/16, 1007, 377 +2006/06/17, 1007, 377 +2006/06/18, 1007, 377 +2006/06/19, 1007, 377 +2006/06/20, 1007, 377 +2006/06/21, 1003, 377 +2006/06/22, 1011, 378 +2006/06/23, 1011, 378 +2006/06/24, 1013, 378 +2006/06/25, 1016, 380 +2006/06/26, 1017, 381 +2006/06/27, 1017, 381 +2006/06/28, 1018, 381 +2006/06/29, 1019, 384 +2006/06/30, 1012, 384 +2006/07/01, 1012, 384 +2006/07/02, 1015, 384 +2006/07/03, 1015, 384 +2006/07/04, 1015, 384 +2006/07/05, 1016, 384 +2006/07/06, 1020, 386 +2006/07/07, 1031, 393 +2006/07/08, 1036, 402 +2006/07/09, 1038, 403 +2006/07/10, 1038, 403 +2006/07/11, 1036, 406 +2006/07/12, 1039, 407 +2006/07/13, 1040, 407 +2006/07/14, 1041, 407 +2006/07/15, 1042, 407 +2006/07/16, 1043, 408 +2006/07/17, 1044, 408 +2006-07-18, 1044, 408 +2006-07-19, 1044, 408 +2006-07-20, 1043, 409 +2006-07-21, 1045, 409 +2006-07-22, 1045, 409 +2006-07-23, 1045, 409 +2006-07-24, 1046, 409 +2006-07-25, 1046, 410 +2006-07-26, 1046, 410 +2006-07-27, 1063, 415 +2006-07-28, 1065, 415 +2006-07-29, 1068, 416 +2006-07-30, 1068, 416 +2006-07-31, 1068, 416 +2006-08-01, 1071, 416 +2006-08-02, 1073, 416 +2006-08-03, 1061, 412 +2006-08-04, 1062, 413 +2006-08-05, 1067, 414 +2006-08-06, 1067, 414 +2006-08-07, 1067, 414 +2006-08-08, 1080, 418 +2006-08-09, 1081, 420 +2006-08-10, 1085, 421 +2006-08-11, 1087, 423 +2006-08-12, 1088, 423 +2006-08-13, 1088, 423 +2006-08-14, 1088, 423 +2006-08-15, 1088, 423 +2006-08-16, 1089, 424 +2006-08-17, 1091, 424 +2006-08-18, 1091, 424 +2006-08-19, 1091, 424 +2006-08-20, 1091, 424 +2006-08-21, 1091, 424 +2006-08-22, 1091, 424 +2006-08-23, 1092, 425 +2006-08-24, 1096, 425 +2006-08-25, 1097, 426 +2006-08-26, 1102, 426 +2006-08-27, 1107, 427 +2006-08-28, 1108, 427 +2006-08-29, 1108, 427 +2006-08-30, 1109, 427 +2006-08-31, 1109, 431 +2006-09-01, 1113, 432 +2006-09-02, 1113, 432 +2006-09-03, 1116, 433 +2006-09-04, 1118, 435 +2006-09-05, 1118, 435 +2006-09-06, 1119, 436 +2006-09-07, 1119, 437 +2006-09-08, 1119, 438 +2006-09-09, 1121, 441 +2006-09-10, 1121, 441 +2006-09-11, 1122, 442 +2006-09-12, 1122, 442 +2006-09-13, 1122, 444 +2006-09-14, 1122, 444 +2006-09-15, 1123, 445 +2006-09-16, 1123, 445 +2006-09-17, 1123, 445 +2006-09-18, 1124, 447 +2006-09-19, 1124, 447 +2006-09-20, 1124, 447 +2006-09-21, 1124, 447 +2006-09-22, 1123, 447 +2006-09-23, 1124, 448 +2006-09-24, 1124, 448 +2006-09-25, 1124, 448 +2006-09-26, 1124, 448 +2006-09-27, 1124, 448 +2006-09-28, 1124, 448 +2006-09-29, 1119, 448 +2006-09-30, 1117, 448 +2006-10-01, 1117, 448 +2006-10-02, 1118, 448 +2006-10-03, 1118, 448 +2006-10-04, 1121, 449 +2006-10-05, 1128, 456 +2006-10-06, 1130, 456 +2006-10-07, 1130, 456 +2006-10-08, 1130, 456 +2006-10-09, 1130, 456 +2006-10-10, 1132, 462 +2006-10-11, 1124, 457 +2006-10-12, 1129, 458 +2006-10-13, 1129, 458 +2006-10-14, 1134, 458 +2006-10-15, 1134, 458 +2006-10-16, 1138, 458 +2006-10-17, 1139, 459 +2006-10-18, 1143, 457 +2006-10-19, 1145, 457 +2006-10-20, 1146, 458 +2006-10-21, 1146, 458 +2006-10-22, 1150, 459 +2006-10-23, 1150, 459 +2006-10-24, 1151, 459 +2006-10-25, 1151, 460 +2006-10-26, 1151, 461 +2006-10-27, 1151, 461 +2006-10-28, 1150, 460 +2006-10-29, 1150, 460 +2006-10-30, 1150, 460 +2006-10-31, 1162, 463 +2006-11-01, 1168, 466 +2006-11-02, 1167, 464 +2006-11-03, 1171, 466 +2006-11-04, 1171, 467 +2006-11-05, 1175, 467 +2006-11-06, 1175, 472 +2006-11-07, 1172, 470 +2006-11-08, 1174, 472 +2006-11-09, 1175, 473 +2006-11-10, 1175, 473 +2006-11-11, 1174, 473 +2006-11-12, 1178, 473 +2006-11-13, 1219, 488 +2006-11-14, 1220, 488 +2006-11-15, 1221, 489 +2006-11-16, 1221, 490 +2006-11-17, 1221, 490 +2006-11-18, 1221, 490 +2006-11-19, 1223, 491 +2006-11-20, 1225, 492 +2006-11-21, 1226, 493 +2006-11-22, 1226, 493 +2006-11-23, 1226, 493 +2006-11-24, 1229, 494 +2006-11-25, 1229, 494 +2006-11-26, 1229, 494 +2006-11-27, 1230, 494 +2006-11-28, 1230, 495 +2006-11-29, 1232, 495 +2006-11-30, 1233, 495 +2006-12-01, 1235, 495 +2006-12-02, 1235, 495 +2006-12-03, 1235, 495 +2006-12-04, 1235, 495 +2006-12-05, 1245, 500 +2006-12-06, 1246, 501 +2006-12-07, 1246, 501 +2006-12-08, 1246, 501 +2006-12-09, 1247, 501 +2006-12-10, 1254, 501 +2006-12-11, 1254, 506 +2006-12-12, 1254, 506 +2006-12-13, 1254, 506 +2006-12-14, 1258, 507 +2006-12-15, 1265, 512 +2006-12-16, 1267, 514 +2006-12-17, 1268, 514 +2006-12-18, 1268, 514 +2006-12-19, 1268, 513 +2006-12-20, 1268, 513 +2006-12-21, 1271, 512 +2006-12-22, 1271, 513 +2006-12-23, 1271, 513 +2006-12-24, 1271, 513 +2006-12-25, 1271, 513 +2006-12-26, 1270, 513 +2006-12-27, 1269, 513 +2006-12-28, 1271, 513 +2006-12-29, 1272, 514 +2006-12-30, 1273, 514 +2006-12-31, 1273, 514 +2007-01-01, 1273, 514 +2007-01-02, 1276, 513 +2007-01-03, 1277, 515 +2007-01-04, 1276, 515 +2007-01-05, 1278, 515 +2007-01-06, 1278, 515 +2007-01-07, 1278, 515 +2007-01-08, 1278, 515 +2007-01-09, 1283, 516 +2007-01-10, 1283, 517 +2007-01-11, 1284, 522 +2007-01-12, 1285, 525 +2007-01-13, 1292, 531 +2007-01-14, 1292, 531 +2007-01-15, 1296, 533 +2007-01-16, 1300, 533 +2007-01-17, 1301, 533 +2007-01-18, 1301, 533 +2007-01-19, 1301, 533 +2007-01-20, 1301, 533 +2007-01-21, 1301, 533 +2007-01-22, 1301, 533 +2007-01-23, 1303, 534 +2007-01-24, 1308, 535 +2007-01-25, 1309, 535 +2007-01-26, 1311, 535 +2007-01-27, 1315, 538 +2007-01-28, 1316, 538 +2007-01-29, 1316, 538 +2007-01-30, 1318, 539 +2007-01-31, 1318, 540 +2007-02-01, 1319, 541 +2007-02-02, 1315, 538 +2007-02-03, 1315, 538 +2007-02-04, 1318, 538 +2007-02-05, 1318, 538 +2007-02-06, 1320, 539 +2007-02-07, 1320, 539 +2007-02-08, 1320, 539 +2007-02-09, 1320, 539 +2007-02-10, 1321, 540 +2007-02-11, 1321, 540 +2007-02-12, 1329, 540 +2007-02-13, 1333, 542 +2007-02-14, 1336, 544 +2007-02-15, 1341, 544 +2007-02-16, 1332, 546 +2007-02-17, 1350, 546 +2007-02-18, 1350, 546 Modified: pypy/branch/ast-experiments/pypy/doc/statistic/post.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/statistic/post.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/statistic/post.txt Mon Feb 26 08:45:45 2007 @@ -42,3 +42,10 @@ 2006-4,138,961 2006-5,67,609 2006-6,38,757 +2006-7, 111, 687 +2006-8, 60, 506 +2006-9, 11, 436 +2006-10, 27, 521 +2006-11, 32, 659 +2006-12, 57, 514 +2007-1, 37, 742 Modified: pypy/branch/ast-experiments/pypy/doc/statistic/release_dates.csv ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/statistic/release_dates.csv (original) +++ pypy/branch/ast-experiments/pypy/doc/statistic/release_dates.csv Mon Feb 26 08:45:45 2007 @@ -5,3 +5,5 @@ 2005-08-28,"PyPy 0.7.0" 2005-11-03,"PyPy 0.8.0" 2006-06-25,"PyPy 0.9.0" +2006-06-25,"PyPy 0.9.0" +2007-02-17,"PyPy 0.99.0" Modified: pypy/branch/ast-experiments/pypy/doc/statistic/sprint_dates.csv ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/statistic/sprint_dates.csv (original) +++ pypy/branch/ast-experiments/pypy/doc/statistic/sprint_dates.csv Mon Feb 26 08:45:45 2007 @@ -20,3 +20,7 @@ "Japan",2006-04-23,2006-04-29 "Duesseldorf",2006-06-02,2006-06-09 "Europython/Genf",2006-07-06,2006-07-09 +"Limerick",2006-08-21,2006-08-27 +"Duesseldorf",2006-10-30,2006-11-05 +"Leysin",2007-01-08,2007-01-14 +"Hildesheim",2007-03-01,2007-03-05 Modified: pypy/branch/ast-experiments/pypy/doc/statistic/statistic_irc_log.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/statistic/statistic_irc_log.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/statistic/statistic_irc_log.txt Mon Feb 26 08:45:45 2007 @@ -510,3 +510,221 @@ 2006-07-15, 180, 16 2006-07-16, 175, 14 2006-07-17, 526, 20 +2006-07-18, 421, 19 +2006-07-19, 607, 20 +2006-07-20, 575, 38 +2006-07-21, 369, 31 +2006-07-22, 293, 13 +2006-07-23, 449, 18 +2006-07-24, 1042, 23 +2006-07-25, 749, 25 +2006-07-26, 348, 22 +2006-07-27, 938, 22 +2006-07-28, 660, 19 +2006-07-29, 350, 19 +2006-07-30, 773, 12 +2006-07-31, 266, 18 +2006-08-01, 561, 26 +2006-08-02, 438, 20 +2006-08-03, 562, 22 +2006-08-04, 431, 20 +2006-08-05, 57, 13 +2006-08-06, 182, 19 +2006-08-07, 719, 22 +2006-08-08, 321, 21 +2006-08-09, 328, 15 +2006-08-10, 153, 23 +2006-08-11, 374, 14 +2006-08-12, 213, 16 +2006-08-13, 43, 9 +2006-08-14, 296, 15 +2006-08-15, 301, 19 +2006-08-16, 278, 18 +2006-08-17, 120, 19 +2006-08-18, 74, 23 +2006-08-19, 0, 9 +2006-08-20, 116, 13 +2006-08-21, 130, 23 +2006-08-22, 84, 21 +2006-08-23, 85, 22 +2006-08-24, 138, 21 +2006-08-25, 44, 23 +2006-08-26, 130, 16 +2006-08-27, 97, 21 +2006-08-28, 101, 35 +2006-08-29, 806, 23 +2006-08-30, 596, 26 +2006-08-31, 537, 24 +2006-09-01, 102, 17 +2006-09-02, 162, 15 +2006-09-03, 15, 10 +2006-09-04, 179, 22 +2006-09-05, 169, 16 +2006-09-06, 422, 22 +2006-09-07, 564, 27 +2006-09-08, 157, 19 +2006-09-09, 198, 11 +2006-09-10, 206, 10 +2006-09-11, 294, 21 +2006-09-12, 310, 21 +2006-09-13, 290, 19 +2006-09-14, 313, 26 +2006-09-15, 340, 25 +2006-09-16, 342, 20 +2006-09-17, 398, 16 +2006-09-18, 411, 19 +2006-09-19, 178, 23 +2006-09-20, 471, 18 +2006-09-21, 164, 23 +2006-09-22, 217, 22 +2006-09-23, 220, 11 +2006-09-24, 126, 8 +2006-09-25, 346, 20 +2006-09-26, 117, 17 +2006-09-27, 298, 22 +2006-09-28, 722, 24 +2006-09-29, 515, 26 +2006-09-30, 106, 21 +2006-10-01, 145, 18 +2006-10-02, 564, 18 +2006-10-03, 466, 32 +2006-10-04, 873, 31 +2006-10-05, 709, 28 +2006-10-06, 600, 23 +2006-10-07, 86, 16 +2006-10-08, 278, 15 +2006-10-09, 659, 29 +2006-10-10, 945, 24 +2006-10-11, 966, 20 +2006-10-12, 887, 26 +2006-10-13, 249, 24 +2006-10-14, 10, 15 +2006-10-15, 34, 19 +2006-10-16, 709, 23 +2006-10-17, 410, 23 +2006-10-18, 501, 25 +2006-10-19, 552, 29 +2006-10-20, 109, 18 +2006-10-21, 380, 14 +2006-10-22, 66, 13 +2006-10-23, 133, 17 +2006-10-24, 162, 15 +2006-10-25, 84, 14 +2006-10-26, 149, 13 +2006-10-27, 359, 13 +2006-10-28, 252, 18 +2006-10-29, 170, 18 +2006-10-30, 62, 20 +2006-10-31, 286, 23 +2006-11-01, 188, 20 +2006-11-02, 291, 35 +2006-11-03, 212, 19 +2006-11-04, 166, 24 +2006-11-05, 131, 24 +2006-11-06, 405, 24 +2006-11-07, 802, 30 +2006-11-08, 1229, 26 +2006-11-09, 1277, 27 +2006-11-10, 331, 24 +2006-11-11, 450, 19 +2006-11-12, 330, 17 +2006-11-13, 781, 18 +2006-11-14, 535, 25 +2006-11-15, 574, 17 +2006-11-16, 340, 19 +2006-11-17, 522, 20 +2006-11-18, 114, 14 +2006-11-19, 238, 16 +2006-11-20, 211, 25 +2006-11-21, 475, 26 +2006-11-22, 173, 16 +2006-11-23, 513, 24 +2006-11-24, 683, 20 +2006-11-25, 151, 15 +2006-11-26, 196, 30 +2006-11-27, 370, 22 +2006-11-28, 336, 22 +2006-11-29, 379, 28 +2006-11-30, 727, 24 +2006-12-01, 628, 19 +2006-12-02, 204, 12 +2006-12-03, 437, 14 +2006-12-04, 491, 25 +2006-12-05, 361, 22 +2006-12-06, 410, 25 +2006-12-07, 536, 23 +2006-12-08, 255, 22 +2006-12-09, 151, 41 +2006-12-10, 52, 12 +2006-12-11, 704, 32 +2006-12-12, 472, 25 +2006-12-13, 521, 29 +2006-12-14, 201, 23 +2006-12-15, 538, 27 +2006-12-16, 282, 18 +2006-12-17, 111, 14 +2006-12-18, 177, 18 +2006-12-19, 381, 20 +2006-12-20, 399, 25 +2006-12-21, 397, 26 +2006-12-22, 240, 41 +2006-12-23, 15, 16 +2006-12-24, 15, 10 +2006-12-25, 82, 10 +2006-12-26, 3, 12 +2006-12-27, 256, 18 +2006-12-28, 220, 19 +2006-12-29, 103, 16 +2006-12-30, 285, 12 +2006-12-31, 548, 17 +2007-01-01, 544, 14 +2007-01-02, 263, 15 +2007-01-03, 631, 18 +2007-01-04, 297, 12 +2007-01-05, 392, 17 +2007-01-06, 103, 14 +2007-01-07, 53, 12 +2007-01-08, 232, 28 +2007-01-09, 98, 32 +2007-01-10, 183, 27 +2007-01-11, 162, 27 +2007-01-12, 694, 24 +2007-01-13, 246, 24 +2007-01-14, 81, 26 +2007-01-15, 327, 27 +2007-01-16, 799, 22 +2007-01-17, 222, 22 +2007-01-18, 158, 23 +2007-01-19, 819, 27 +2007-01-20, 226, 18 +2007-01-21, 117, 17 +2007-01-22, 490, 27 +2007-01-23, 279, 27 +2007-01-24, 374, 21 +2007-01-25, 449, 20 +2007-01-26, 321, 18 +2007-01-27, 156, 13 +2007-01-28, 376, 14 +2007-01-29, 427, 21 +2007-01-30, 715, 22 +2007-01-31, 624, 30 +2007-02-01, 446, 20 +2007-02-02, 248, 25 +2007-02-03, 437, 16 +2007-02-04, 256, 19 +2007-02-05, 473, 19 +2007-02-06, 198, 16 +2007-02-07, 439, 35 +2007-02-08, 472, 17 +2007-02-09, 803, 24 +2007-02-10, 274, 23 +2007-02-11, 622, 18 +2007-02-12, 786, 23 +2007-02-13, 1172, 25 +2007-02-14, 1101, 28 +2007-02-15, 1236, 23 +2007-02-16, 793, 23 +2007-02-17, 1399, 22 +2007-02-18, 636, 18 +2007-02-19, 761, 28 +2007-02-20, 414, 23 Modified: pypy/branch/ast-experiments/pypy/doc/statistic/subscribers.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/statistic/subscribers.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/statistic/subscribers.txt Mon Feb 26 08:45:45 2007 @@ -929,3 +929,169 @@ 2006/07/14, 310, 56 2006/07/15, 310, 56 2006/07/16, 310, 56 +2006-07-17, 293, 55 +2006-07-19, 293, 55 +2006-07-20, 294, 56 +2006-07-21, 294, 56 +2006-07-23, 294, 56 +2006-07-24, 295, 56 +2006-07-25, 293, 56 +2006-07-26, 292, 56 +2006-07-27, 290, 56 +2006-07-30, 290, 56 +2006-07-31, 290, 56 +2006-08-01, 291, 56 +2006-08-02, 290, 56 +2006-08-03, 290, 56 +2006-08-04, 290, 56 +2006-08-05, 290, 56 +2006-08-07, 290, 56 +2006-08-09, 290, 56 +2006-08-10, 290, 56 +2006-08-11, 291, 56 +2006-08-12, 291, 56 +2006-08-15, 291, 56 +2006-08-16, 291, 56 +2006-08-17, 292, 56 +2006-08-19, 293, 56 +2006-08-21, 294, 56 +2006-08-22, 293, 56 +2006-08-23, 293, 56 +2006-08-24, 293, 56 +2006-08-25, 296, 58 +2006-08-26, 297, 57 +2006-08-29, 297, 57 +2006-08-30, 297, 57 +2006-08-31, 297, 57 +2006-09-01, 297, 57 +2006-09-02, 297, 57 +2006-09-03, 297, 57 +2006-09-05, 297, 57 +2006-09-06, 297, 57 +2006-09-07, 297, 57 +2006-09-08, 297, 58 +2006-09-11, 298, 58 +2006-09-12, 298, 58 +2006-09-13, 298, 58 +2006-09-14, 301, 58 +2006-09-15, 301, 58 +2006-09-16, 302, 58 +2006-09-17, 303, 58 +2006-09-18, 303, 58 +2006-09-19, 304, 58 +2006-09-20, 305, 58 +2006-09-22, 305, 58 +2006-09-23, 306, 58 +2006-09-25, 306, 58 +2006-09-26, 306, 58 +2006-09-27, 306, 58 +2006-09-28, 306, 58 +2006-09-29, 307, 58 +2006-09-30, 308, 58 +2006-10-01, 308, 58 +2006-10-02, 308, 58 +2006-10-03, 309, 58 +2006-10-04, 309, 57 +2006-10-05, 310, 57 +2006-10-06, 312, 57 +2006-10-07, 312, 57 +2006-10-10, 313, 57 +2006-10-11, 313, 57 +2006-10-12, 313, 57 +2006-10-13, 313, 57 +2006-10-14, 313, 57 +2006-10-16, 315, 57 +2006-10-17, 316, 57 +2006-10-18, 316, 57 +2006-10-19, 316, 57 +2006-10-20, 316, 57 +2006-10-21, 316, 57 +2006-10-23, 316, 57 +2006-10-24, 317, 57 +2006-10-25, 317, 57 +2006-10-26, 317, 57 +2006-10-28, 317, 57 +2006-10-29, 317, 57 +2006-10-30, 318, 57 +2006-10-31, 317, 57 +2006-11-02, 318, 57 +2006-11-03, 318, 57 +2006-11-04, 318, 57 +2006-11-06, 318, 56 +2006-11-07, 318, 56 +2006-11-08, 318, 56 +2006-11-09, 319, 56 +2006-11-10, 319, 56 +2006-11-11, 319, 56 +2006-11-13, 320, 56 +2006-11-14, 320, 56 +2006-11-15, 320, 56 +2006-11-16, 321, 56 +2006-11-17, 320, 56 +2006-11-21, 320, 56 +2006-11-22, 321, 56 +2006-11-24, 320, 56 +2006-11-25, 322, 56 +2006-11-27, 322, 56 +2006-11-28, 323, 56 +2006-11-29, 322, 56 +2006-11-30, 322, 56 +2006-12-01, 322, 55 +2006-12-04, 322, 55 +2006-12-05, 323, 55 +2006-12-06, 322, 55 +2006-12-08, 323, 55 +2006-12-10, 323, 55 +2006-12-11, 323, 55 +2006-12-14, 323, 55 +2006-12-19, 323, 55 +2006-12-21, 323, 55 +2006-12-24, 323, 55 +2006-12-27, 323, 55 +2006-12-28, 323, 55 +2006-12-29, 324, 55 +2006-12-30, 324, 55 +2006-12-31, 323, 55 +2007-01-02, 322, 55 +2007-01-03, 322, 55 +2007-01-04, 322, 55 +2007-01-05, 322, 55 +2007-01-07, 322, 55 +2007-01-08, 321, 55 +2007-01-09, 322, 55 +2007-01-11, 322, 55 +2007-01-12, 322, 55 +2007-01-14, 322, 55 +2007-01-15, 322, 55 +2007-01-16, 323, 55 +2007-01-18, 324, 55 +2007-01-19, 324, 55 +2007-01-22, 324, 55 +2007-01-23, 324, 56 +2007-01-24, 324, 56 +2007-01-25, 324, 56 +2007-01-26, 323, 56 +2007-01-27, 322, 56 +2007-01-28, 322, 56 +2007-01-29, 322, 56 +2007-01-30, 322, 55 +2007-01-31, 321, 55 +2007-02-01, 321, 55 +2007-02-02, 321, 55 +2007-02-03, 321, 55 +2007-02-04, 321, 55 +2007-02-05, 320, 55 +2007-02-06, 320, 55 +2007-02-07, 321, 55 +2007-02-08, 321, 55 +2007-02-09, 322, 55 +2007-02-10, 322, 55 +2007-02-11, 322, 55 +2007-02-12, 322, 55 +2007-02-13, 322, 55 +2007-02-14, 322, 55 +2007-02-15, 322, 55 +2007-02-16, 323, 55 +2007-02-17, 324, 56 +2007-02-18, 323, 56 +2007-02-19, 324, 56 Modified: pypy/branch/ast-experiments/pypy/doc/tool/makecontributor.py ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/tool/makecontributor.py (original) +++ pypy/branch/ast-experiments/pypy/doc/tool/makecontributor.py Mon Feb 26 08:45:45 2007 @@ -25,9 +25,15 @@ import uconf # http://codespeak.net/svn/uconf/dist/uconf +# Authors that don't want to be listed +excluded = set("anna gintas ignas".split()) +cutoff = 5 # cutoff for authors in the LICENSE file +mark = False for author, count in items: - #user = uconf.system.User(author) - #realname = user.realname - #print "%5d" % count, " ", realname, "<%s>" % email - print count, " ", author - + user = uconf.system.User(author) + realname = user.realname.strip() + if not mark and count < cutoff: + mark = True + print '-'*60 + print " ", realname + #print count, " ", author Modified: pypy/branch/ast-experiments/pypy/doc/translation.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/translation.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/translation.txt Mon Feb 26 08:45:45 2007 @@ -91,18 +91,18 @@ stages. .. _`SSA`: http://en.wikipedia.org/wiki/Static_single_assignment_form -.. _`translator.py`: http://codespeak.net/pypy/dist/pypy/translator/translator.py +.. _`translator.py`: ../../pypy/translator/translator.py .. _`play around`: getting-started.html#trying-out-the-translator .. _`Flow Object Space`: objspace.html#the-flow-object-space .. _`control flow graph`: objspace.html#the-flow-model -.. _`Common Lisp`: http://codespeak.net/pypy/dist/pypy/translator/lisp/ -.. _Pyrex: http://codespeak.net/pypy/dist/pypy/translator/pyrex/ -.. _JavaScript: http://codespeak.net/pypy/dist/pypy/translator/js/ -.. _Squeak: http://codespeak.net/pypy/dist/pypy/translator/squeak/ -.. _CLI: http://codespeak.net/pypy/dist/pypy/translator/cli/ +.. _`Common Lisp`: ../../pypy/translator/lisp/ +.. _Pyrex: ../../pypy/translator/pyrex/ +.. _JavaScript: ../../pypy/translator/js/ +.. _Squeak: ../../pypy/translator/squeak/ +.. _CLI: ../../pypy/translator/cli/ .. _graph: image/translation.pdf .. _`interactive interface`: getting-started.html#try-out-the-translator -.. _`translatorshell.py`: http://codespeak.net/pypy/dist/pypy/bin/translatorshell.py +.. _`translatorshell.py`: ../../pypy/bin/translatorshell.py .. _`flow model`: @@ -537,6 +537,7 @@ "explodes" objects and thus saves one allocation in this simple (but quite common) situation. + Escape Analysis and Stack Allocation ++++++++++++++++++++++++++++++++++++ @@ -570,13 +571,16 @@ likely. Also objects that have a finalizer cannot be allocated on the stack, since the finalizer might resurrect the object. -The resulting performance improvements by this optimization were quite -poor. We think that this is due to the fact that the Boehm garbage +The resulting performance improvements by this optimization were not as big +we hoped. We think that this is due to the fact that the Boehm garbage collector becomes slower when the stack is bigger, thus compensating any speed improvement achieved by having faster allocation. We did not implement stack allocation with any of the other GCs that PyPy can use. +Enable this optimization with :config:`translation.backendopt.heap2stack`. + + The Stackless Transform ----------------------- @@ -587,6 +591,8 @@ implement `coroutines, greenlets and tasklets`_ as an application level feature for the Standard Interpreter. +Enable the stackless transformation with :config:`translation.stackless`. + .. _`coroutines, greenlets and tasklets`: stackless.html .. _`preparing the graphs for source generation`: @@ -643,9 +649,12 @@ on flexibility and robustness, not performance. For a quite detailed description of how memory management and garbage collection -are performed in PyPy, see the `EU report`_ about this topic (section 4.2). +are performed in PyPy, see the `Technical report`_ about this topic (section 4.2). -.. _`EU report`: http://codespeak.net/pypy/extradoc/eu-report/D07.1_Massive_Parallelism_and_Translation_Aspects-2006-12-15.pdf +You can choose which garbage collection strategy to use with +:config:`translation.gc`. + +.. _`Technical report`: http://codespeak.net/pypy/extradoc/eu-report/D07.1_Massive_Parallelism_and_Translation_Aspects-2006-12-15.pdf .. _C: .. _GenC: @@ -689,6 +698,8 @@ .. _LLVM: +Use the :config:`translation.backend` option to choose which backend to use. + The LLVM Back-End ----------------- @@ -731,7 +742,7 @@ The Object-Oriented backends target platforms that are less C-like and support classes, instance etc. If such a platform is targetted, the `OO type system` is -used while rtyping. Of the OO backends, currently only genclr can translate the +used while rtyping. Of the OO backends, currently only gencli can translate the full PyPy, but the Java backend is getting close. .. _`oo type system`: rtyper.html#oo-type @@ -848,6 +859,13 @@ External Function Calls ======================= +*Warning* This approach while is still used at the moment by PyPy to +expose native operations (like ``os.read``, ``os.write``) is going to be +phased out. It has shown to be too cumbersome in practice. An approach +based on `rctypes`_ should replace it. + +.. _rctypes: rctypes.html + There are some functions that we don't want to implement in Python for various reasons (e.g. if they need to make calls into the OS). These can be implemented by writing backend code by hand that either implements the Modified: pypy/branch/ast-experiments/pypy/doc/video-index.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/video-index.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/video-index.txt Mon Feb 26 08:45:45 2007 @@ -43,8 +43,8 @@ If you need another license, don't hesitate to contact us. -Trailer: PyPy at the PyCon --------------------------- +Trailer: PyPy at the PyCon 2006 +------------------------------- 130mb: http://codespeak.net/download/pypy/video/pycon-trailer.avi.torrent @@ -57,7 +57,7 @@ :alt: Trailer PyPy at PyCon :align: left -This trailer shows the PyPy team at the PyCon, a behind-the-scenes at sprints, talks and everywhere else. +This trailer shows the PyPy team at the PyCon 2006, a behind-the-scenes at sprints, talks and everywhere else. PAL, 9 min, DivX AVI @@ -75,7 +75,7 @@ :alt: Interview with Tim Peters :align: left -Interview with CPython core developer Tim Peters at this years PyCon, Dallas, US. 2.3.2006 +Interview with CPython core developer Tim Peters at PyCon 2006, Dallas, US. (2006-03-02) PAL, 23 min, DivX AVI @@ -95,7 +95,7 @@ :alt: Interview with Bob Ippolito :align: left -What do you think about PyPy? Interview with American software developer Bob Ippolito at this years PyCon, Dallas, US. 1.3.2006 +What do you think about PyPy? Interview with American software developer Bob Ippolito at tPyCon 2006, Dallas, US. (2006-03-01) PAL 8 min, DivX AVI @@ -112,10 +112,10 @@ .. image:: image/introductory-talk-pycon.jpg :scale: 100 - :alt: Introductory talk at PyCon + :alt: Introductory talk at PyCon 2006 :align: left -This introductory talk is given by core developers Michael Hudson and Christian Tismer at the PyCon, Dallas, US. 26.2.2006 +This introductory talk is given by core developers Michael Hudson and Christian Tismer at PyCon 2006, Dallas, US. (2006-02-26) PAL, 28 min, divx AVI @@ -138,7 +138,7 @@ :alt: Agile talk :align: left -Core developer Holger Krekel and project manager Beatrice During are giving a talk on the agile open source methods used in the PyPy project at the PyCon, Dallas, US. 26.2.2006 +Core developer Holger Krekel and project manager Beatrice During are giving a talk on the agile open source methods used in the PyPy project at PyCon 2006, Dallas, US. (2006-02-26) PAL, 26 min, divx AVI @@ -161,7 +161,7 @@ :alt: Architecture session :align: left -This architecture session is given by core developers Holger Krekel and Armin Rigo at the PyCon, Dallas, US. 26.2.2006 +This architecture session is given by core developers Holger Krekel and Armin Rigo at PyCon 2006, Dallas, US. (2006-02-26) PAL, 48 min, divx AVI @@ -184,7 +184,7 @@ :alt: Sprint Tutorial :align: left -Sprint tutorial by core developer Michael Hudson at the PyCon sprint, Dallas, US. 27.2.2006 +Sprint tutorial by core developer Michael Hudson at PyCon 2006, Dallas, US. (2006-02-27) PAL, 44 min, divx AVI Modified: pypy/branch/ast-experiments/pypy/doc/windows.txt ============================================================================== --- pypy/branch/ast-experiments/pypy/doc/windows.txt (original) +++ pypy/branch/ast-experiments/pypy/doc/windows.txt Mon Feb 26 08:45:45 2007 @@ -112,6 +112,6 @@ .. _`Boehm collector suite`: http://www.hpl.hp.com/personal/Hans_Boehm/gc/gc_source/gc.tar.gz -.. _gc_patch_windows.py: http://codespeak.net/pypy/dist/pypy/translator/goal/win32/gc_patch_windows.py +.. _gc_patch_windows.py: ../../pypy/translator/goal/win32/gc_patch_windows.py .. _`gc-windows.zip`: http://codespeak.net/~antocuni/gc-windows.zip Modified: pypy/branch/ast-experiments/pypy/jit/codegen/llvm/rgenop.py ============================================================================== --- pypy/branch/ast-experiments/pypy/jit/codegen/llvm/rgenop.py (original) +++ pypy/branch/ast-experiments/pypy/jit/codegen/llvm/rgenop.py Mon Feb 26 08:45:45 2007 @@ -729,6 +729,7 @@ try: funcsig = self.rgenop.funcsig[gv_fnptr.get_integer_value()] except KeyError: + funcsig = 'TODO: funcsig here' py.test.skip('call an address directly not supported yet') args_gv2 = [] for v in args_gv: Modified: pypy/branch/ast-experiments/pypy/lang/automata/test/test_dfa.py ============================================================================== --- pypy/branch/ast-experiments/pypy/lang/automata/test/test_dfa.py (original) +++ pypy/branch/ast-experiments/pypy/lang/automata/test/test_dfa.py Mon Feb 26 08:45:45 2007 @@ -2,13 +2,6 @@ from pypy import conftest from pypy.rpython.test.test_llinterp import interpret -from pypy.translator.translator import graphof -from pypy.jit.timeshifter.test.test_timeshift import hannotate -from pypy.jit.timeshifter.hrtyper import HintRTyper -from pypy.jit.timeshifter.test.test_timeshift import P_NOVIRTUAL -from pypy.rpython.llinterp import LLInterpreter -from pypy.objspace.flow.model import checkgraph -from pypy.rlib.objectmodel import hint from pypy.lang.automata.dfa import * Modified: pypy/branch/ast-experiments/pypy/lang/js/driver.py ============================================================================== --- pypy/branch/ast-experiments/pypy/lang/js/driver.py (original) +++ pypy/branch/ast-experiments/pypy/lang/js/driver.py Mon Feb 26 08:45:45 2007 @@ -5,6 +5,7 @@ import py import os import sys +from subprocess import * pwd = path.local(__file__) shell = pwd.dirpath('test', 'ecma', 'shell.js') @@ -22,10 +23,12 @@ results = open('results.txt', 'w') for f in pwd.dirpath('test', 'ecma').visit(filter): print f.basename - stdout = os.popen('./js_interactive.py -n -f %s -f %s'%(shell.strpath,f.strpath), 'r') + cmd = './js_interactive.py -n -f %s -f %s'%(shell, f) + p = Popen(cmd, shell=True, stdout=PIPE) + passed = 0 total = 0 - for line in stdout.readlines(): + for line in p.stdout.readlines(): if "PASSED!" in line: passed += 1 total += 1 @@ -34,6 +37,3 @@ results.write('%s passed %s of %s tests\n'%(f.basename, passed, total)) results.flush() - - - Modified: pypy/branch/ast-experiments/pypy/lang/js/interpreter.py ============================================================================== --- pypy/branch/ast-experiments/pypy/lang/js/interpreter.py (original) +++ pypy/branch/ast-experiments/pypy/lang/js/interpreter.py Mon Feb 26 08:45:45 2007 @@ -62,6 +62,7 @@ class UnaryOp(Expression): def from_tree(self, t): self.expr = get_obj(t, '0') + self.postfix = bool(get_string(t, 'postfix')) class BinaryOp(Expression): def from_tree(self, t): @@ -79,6 +80,17 @@ def decision(self, ctx, op1, op2): raise NotImplementedError +class BinaryBitwiseOp(BinaryOp): + def eval(self, ctx): + s5 = self.left.eval(ctx).GetValue().ToInt32() + s6 = self.right.eval(ctx).GetValue().ToInt32() + if DEBUG: + print "bitwisecomp, op1 and op2 ", s2, s4 + return self.decision(ctx, s5, s6) + + def decision(self, ctx, op1, op2): + raise NotImplementedError + class BinaryLogicOp(BinaryOp): pass @@ -150,7 +162,7 @@ class Interpreter(object): """Creates a js interpreter""" def __init__(self): - w_Global = W_Object() + w_Global = W_Object(Class="global") ctx = global_context(w_Global) w_ObjPrototype = W_Object(Prototype=None, Class='Object') @@ -174,6 +186,8 @@ w_Global.Put('Math', w_math) w_math.Put('abs', W_Builtin(absjs, Class='function')) w_math.Put('floor', W_Builtin(floorjs, Class='function')) + w_math.Put('E', W_Number(math.e)) + w_math.Put('PI', W_Number(math.pi)) w_Global.Put('String', W_Builtin(stringjs, Class='String')) @@ -234,15 +248,27 @@ v3 = self.right.eval(ctx).GetValue() op = self.value if op == "=": - v1.PutValue(v3, ctx) + val = v3 elif op == "*": - v1.PutValue(Mult().mathop(ctx, v1.GetValue(), v3), ctx) + val = Mult().mathop(ctx, v1.GetValue(), v3) elif op == "+": - v1.PutValue(Plus().mathop(ctx, v1.GetValue(), v3), ctx) + val = Plus().mathop(ctx, v1.GetValue(), v3) + elif op == "/": + val = Div().mathop(ctx, v1.GetValue(), v3) + elif op == "%": + val = Mod().mathop(ctx, v1.GetValue(), v3) + elif op == "&": + val = BitwiseAnd().mathop(ctx, v1.GetValue(), v3) + elif op == "|": + val = BitwiseOR().mathop(ctx, v1.GetValue(), v3) + elif op == "^": + val = BitwiseXOR().mathop(ctx, v1.GetValue(), v3) else: print op raise NotImplementedError() - return v3 + + v1.PutValue(val, ctx) + return val class Block(Statement): opcode = 'BLOCK' @@ -262,6 +288,32 @@ else: raise e +class BitwiseAnd(BinaryBitwiseOp): + opcode = 'BITWISE_AND' + + def decision(self, ctx, op1, op2): + return W_Number(op1&op2) + +class BitwiseNot(UnaryOp): + opcode = 'BITWISE_NOT' + + def eval(self, ctx): + op1 = self.expr.eval(ctx).GetValue().ToInt32() + return W_Number(~op1) + + +class BitwiseOR(BinaryBitwiseOp): + opcode = 'BITWISE_OR' + + def decision(self, ctx, op1, op2): + return W_Number(op1|op2) + +class BitwiseXOR(BinaryBitwiseOp): + opcode = 'BITWISE_XOR' + + def decision(self, ctx, op1, op2): + return W_Number(op1^op2) + class Unconditional(Statement): def from_tree(self, t): pieces = get_string(t, 'target').split(',') @@ -511,6 +563,17 @@ name = op1.ToString() return W_Boolean(op2.HasProperty(name)) +class Delete(UnaryOp): + opcode = 'DELETE' + + def eval(self, ctx): + r1 = self.expr.eval(ctx) + if not isinstance(r1, W_Reference): + return W_Boolean(True) + r3 = r1.GetBase() + r4 = r1.GetPropertyName() + return W_Boolean(r3.Delete(r4)) + class Increment(UnaryOp): opcode = 'INCREMENT' @@ -520,7 +583,26 @@ x = val.ToNumber() resl = Plus().mathop(ctx, W_Number(x), W_Number(1)) thing.PutValue(resl, ctx) - return val + if self.postfix: + return val + else: + return resl + + +class Decrement(UnaryOp): + opcode = 'DECREMENT' + + def eval(self, ctx): + thing = self.expr.eval(ctx) + val = thing.GetValue() + x = val.ToNumber() + resl = Plus().mathop(ctx, W_Number(x), W_Number(-1)) + thing.PutValue(resl, ctx) + if self.postfix: + return val + else: + return resl + class Index(BinaryOp): opcode = 'INDEX' @@ -807,14 +889,22 @@ self.expr.eval(ctx) return w_Undefined -class While(Statement): - opcode = 'WHILE' - +class WhileBase(Statement): def from_tree(self, t): self.condition = get_obj(t, 'condition') self.body = get_obj(t, 'body') +class Do(WhileBase): + opcode = 'DO' + def execute(self, ctx): + try: + self.body.execute(ctx) + except ExecutionReturned, e: + if e.type == 'break': + return + elif e.type == 'continue': + pass while self.condition.eval(ctx).ToBoolean(): try: self.body.execute(ctx) @@ -823,7 +913,44 @@ break elif e.type == 'continue': continue + +class While(WhileBase): + opcode = 'WHILE' + + def execute(self, ctx): + while self.condition.eval(ctx).ToBoolean(): + try: + self.body.execute(ctx) + except ExecutionReturned, e: + if e.type == 'break': + break + elif e.type == 'continue': + continue + +class ForIn(Statement): + opcode = 'FOR_IN' + + def from_tree(self, t): + self.object = get_obj(t, 'object') + self.body = get_obj(t, 'body') + self.iterator = get_obj(t, 'iterator') + def execute(self, ctx): + obj = self.object.eval(ctx).GetValue().ToObject() + for prop in obj.propdict.values(): + if prop.de: + continue + iterator = self.iterator.eval(ctx) + print prop.name + iterator.PutValue(prop.value, ctx) + try: + result = self.body.execute(ctx) + except ExecutionReturned, e: + if e.type == 'break': + break + elif e.type == 'continue': + continue + class For(Statement): opcode = 'FOR' @@ -926,3 +1053,16 @@ else: raise NotImplementedError("Dont know how to handle %s" % opcode) +def wrap_arguments(pyargs): + "receives a list of arguments and wrap then in their js equivalents" + res = [] + for arg in pyargs: + if isinstance(arg, W_Root): + res.append(arg) + elif isinstance(arg, str): + res.append(W_String(arg)) + elif isinstance(arg, int) or isinstance(arg, float) or isinstance(arg, long): + res.append(W_Number(arg)) + elif isinstance(arg, bool): + res.append(W_Boolean(arg)) + return res \ No newline at end of file Modified: pypy/branch/ast-experiments/pypy/lang/js/js_interactive.py ============================================================================== --- pypy/branch/ast-experiments/pypy/lang/js/js_interactive.py (original) +++ pypy/branch/ast-experiments/pypy/lang/js/js_interactive.py Mon Feb 26 08:45:45 2007 @@ -156,4 +156,6 @@ print res if __name__ == "__main__": + import py + py.test.config.parse([]) sys.exit(main()) Modified: pypy/branch/ast-experiments/pypy/lang/js/jsobj.py ============================================================================== --- pypy/branch/ast-experiments/pypy/lang/js/jsobj.py (original) +++ pypy/branch/ast-experiments/pypy/lang/js/jsobj.py Mon Feb 26 08:45:45 2007 @@ -5,18 +5,20 @@ class SeePage(NotImplementedError): pass -class ExecutionReturned(Exception): +class JsBaseExcept(Exception): pass + +class ExecutionReturned(JsBaseExcept): def __init__(self, type='normal', value=None, identifier=None): self.type = type self.value = value self.identifier = identifier -class ThrowException(Exception): +class ThrowException(JsBaseExcept): def __init__(self, exception): self.exception = exception self.args = self.exception -class JsTypeError(Exception): +class JsTypeError(JsBaseExcept): pass Infinity = 1e300 * 1e300 @@ -59,6 +61,9 @@ def ToNumber(self): return NaN + def ToInt32(self): + return 0 + def Get(self, P): raise NotImplementedError @@ -122,7 +127,7 @@ Value=w_Undefined, callfunc=None): self.propdict = {} self.propdict['prototype'] = Property('prototype', w_Undefined, - dd=True) + dd=True, de=True) self.Prototype = Prototype self.Class = Class self.callfunc = callfunc @@ -189,7 +194,7 @@ if self.Prototype is None: return False return self.Prototype.HasProperty(P) - def Delete(P): + def Delete(self, P): if P in self.propdict: if self.propdict[P].dd: return False del self.propdict[P] @@ -237,7 +242,7 @@ Value=w_Undefined, callfunc=None): W_PrimitiveObject.__init__(self, ctx, Prototype, Class, Value, callfunc) - self.propdict['toString'] = Property('toString', W_Builtin(str_builtin)) + self.propdict['toString'] = Property('toString', W_Builtin(str_builtin), de=True) class W_Builtin(W_PrimitiveObject): @@ -281,13 +286,13 @@ Value=w_Undefined, callfunc=None): W_PrimitiveObject.__init__(self, ctx, Prototype, Class, Value, callfunc) toString = W_Builtin(array_str_builtin) - self.Put('toString', toString) + self.Put('toString', toString, de=True) self.Put('length', W_Number(0)) self.array = [] self.set_builtin_call(arraycallbi) - - - def Put(self, P, V): + + def Put(self, P, V, dd=False, + ro=False, de=False, it=False): try: x = int(P) # print "puting", V, 'in', x @@ -299,11 +304,7 @@ self.array[x]= V except ValueError: - if not self.CanPut(P): return - if P in self.propdict: - self.propdict[P].value = V - else: - self.propdict[P] = Property(P, V) + super(W_Array, self).Put(P, V, dd, ro, de, it) def Get(self, P): try: @@ -393,6 +394,9 @@ def type(self): return 'number' + + def ToInt32(self): + return int(self.floatval) class W_List(W_Root): def __init__(self, list_w): @@ -493,6 +497,7 @@ if self.base is None: base = ctx.scope[-1] base.Put(self.property_name, w) + return w def GetBase(self): return self.base Modified: pypy/branch/ast-experiments/pypy/lang/js/test/ecma/shell.js ============================================================================== --- pypy/branch/ast-experiments/pypy/lang/js/test/ecma/shell.js (original) +++ pypy/branch/ast-experiments/pypy/lang/js/test/ecma/shell.js Mon Feb 26 08:45:45 2007 @@ -50,7 +50,7 @@ var PASSED = " PASSED!" var FAILED = " FAILED! expected: "; -var DEBUG = false; +var DEBUG = true; var DESCRIPTION; var EXPECTED; @@ -124,23 +124,23 @@ } function test() { - for ( tc=0; tc < testcases.length; tc++ ) { - // temporary hack to work around some unknown issue in 1.7 - try - { - testcases[tc].passed = writeTestCaseResult( - testcases[tc].expect, - testcases[tc].actual, - testcases[tc].description +" = "+ testcases[tc].actual ); - testcases[tc].reason += ( testcases[tc].passed ) ? "" : "wrong value "; - } - catch(e) - { - print('test(): empty testcase for tc = ' + tc + ' ' + e); - } - } - stopTest(); - return ( testcases ); + // for ( tc=0; tc < testcases.length; tc++ ) { + // // temporary hack to work around some unknown issue in 1.7 + // try + // { + // testcases[tc].passed = writeTestCaseResult( + // testcases[tc].expect, + // testcases[tc].actual, + // testcases[tc].description +" = "+ testcases[tc].actual ); + // testcases[tc].reason += ( testcases[tc].passed ) ? "" : "wrong value "; + // } + // catch(e) + // { + // print('test(): empty testcase for tc = ' + tc + ' ' + e); + // } + // } + // stopTest(); + return testcases.length } /* @@ -193,6 +193,16 @@ * document.write. */ +function run_test(tc) { + // try { + getTestCaseResult(testcases[tc].expect, testcases[tc].actual) + testcases[tc].reason += ( testcases[tc].passed ) ? "" : "wrong value "; + return testcases[tc].passed? 1:0; + // } + // catch(e) { + // return -1; + // } +} function writeTestCaseResult( expect, actual, string ) { var passed = getTestCaseResult( expect, actual ); writeFormattedResult( expect, actual, string, passed ); Modified: pypy/branch/ast-experiments/pypy/lang/js/test/test_interp.py ============================================================================== --- pypy/branch/ast-experiments/pypy/lang/js/test/test_interp.py (original) +++ pypy/branch/ast-experiments/pypy/lang/js/test/test_interp.py Mon Feb 26 08:45:45 2007 @@ -454,3 +454,19 @@ def test_unary_plus(self): self.assert_prints("print(+1)", ['1']) + + def test_delete(self): + self.assert_prints(""" + var x = {} + x.y = 1; + delete x.y + print(x.y) + """, ['undefined']) + + def test_forin(self): + self.assert_prints(""" + var x = {a:5} + for(y in x){ + print(y) + } + """, ['5',]) Modified: pypy/branch/ast-experiments/pypy/lib/distributed/__init__.py ============================================================================== --- pypy/branch/ast-experiments/pypy/lib/distributed/__init__.py (original) +++ pypy/branch/ast-experiments/pypy/lib/distributed/__init__.py Mon Feb 26 08:45:45 2007 @@ -1,2 +1,6 @@ -from protocol import RemoteProtocol, test_env, remote_loop +try: + from protocol import RemoteProtocol, test_env, remote_loop +except ImportError: + # UGH. This is needed for tests + pass Modified: pypy/branch/ast-experiments/pypy/lib/distributed/objkeeper.py ============================================================================== --- pypy/branch/ast-experiments/pypy/lib/distributed/objkeeper.py (original) +++ pypy/branch/ast-experiments/pypy/lib/distributed/objkeeper.py Mon Feb 26 08:45:45 2007 @@ -26,8 +26,6 @@ return len(self.exported_objects) - 1 def ignore(self, key, value): - #key not in ('__dict__', '__weakref__', '__class__', '__new__', - # '__base__', '__flags__', '__mro__', '__bases__')] if key in ('__dict__', '__weakref__', '__class__', '__new__'): return True if isinstance(value, GetSetDescriptor): @@ -39,8 +37,6 @@ return self.exported_types[tp] except KeyError: print "Registering type %s as %s" % (tp, self.exported_types_id) - if str(tp).find('getset') != -1: - import pdb;pdb.set_trace() self.exported_types[tp] = self.exported_types_id tp_id = self.exported_types_id self.exported_types_id += 1 @@ -60,14 +56,11 @@ if '__doc__' in _dict: d['__doc__'] = protocol.unwrap(_dict['__doc__']) tp = type(_name, (object,), d) + # Make sure we cannot instantiate the remote type self.remote_types[type_id] = tp for key, value in _dict.items(): if key != '__doc__': - try: - setattr(tp, key, protocol.unwrap(value)) - except TypeError: - # XXX this stays here for debugging reasons - import pdb;pdb.set_trace() + setattr(tp, key, protocol.unwrap(value)) def get_type(self, id): return self.remote_types[id] Modified: pypy/branch/ast-experiments/pypy/lib/distributed/protocol.py ============================================================================== --- pypy/branch/ast-experiments/pypy/lib/distributed/protocol.py (original) +++ pypy/branch/ast-experiments/pypy/lib/distributed/protocol.py Mon Feb 26 08:45:45 2007 @@ -39,7 +39,7 @@ from pypymagic import transparent_proxy as proxy from pypymagic import get_transparent_controller except ImportError: - raise ImportError("Cannot work without transparent proxy functional") + raise ImportError("Cannot work without transparent proxy functionality") from distributed.objkeeper import ObjKeeper import sys @@ -49,9 +49,11 @@ """ TODO list: -1. Add some garbage collection -2. Add caching of objects that are presented (even on name level) -3. Add exceptions, frames and error handling +1. Garbage collection - we would like probably to use weakrefs, but + since they're not perfectly working in pypy, let's leave it alone for now +2. Some error handling - exceptions are working, there are still some + applications where it all explodes. +3. Support inheritance and recursive types """ from pypymagic import pypy_repr Modified: pypy/branch/ast-experiments/pypy/lib/distributed/test/test_distributed.py ============================================================================== --- pypy/branch/ast-experiments/pypy/lib/distributed/test/test_distributed.py (original) +++ pypy/branch/ast-experiments/pypy/lib/distributed/test/test_distributed.py Mon Feb 26 08:45:45 2007 @@ -197,3 +197,14 @@ #assert tb.tb_next is None else: raise AssertionError("Did not raise") + + def test_instantiate_remote_type(self): + skip("Land of infinite recursion") + from distributed import test_env + + class C: + pass + + protocol = test_env({'C':C}) + xC = protocol.get_remote('C') + xC() Modified: pypy/branch/ast-experiments/pypy/lib/pyontology/pyontology.py ============================================================================== --- pypy/branch/ast-experiments/pypy/lib/pyontology/pyontology.py (original) +++ pypy/branch/ast-experiments/pypy/lib/pyontology/pyontology.py Mon Feb 26 08:45:45 2007 @@ -1,10 +1,15 @@ -import autopath -from rdflib import Graph, URIRef, BNode, Literal as rdflib_literal -from logilab.constraint import Repository -from logilab.constraint.fd import FiniteDomain as fd +#import autopath +try: + from cslib import Repository + from cslib.fd import FiniteDomain as fd + print 'using pypy.lib.cslib' +except ImportError: + print 'using logilab.constraint' + from logilab.constraint import Repository + from logilab.constraint.fd import FiniteDomain as fd from logilab.constraint.propagation import AbstractDomain, AbstractConstraint,\ - ConsistencyFailure -from pypy.lib.pyontology.sparql_grammar import SPARQLGrammar as SP + ConsistencyFailure +from pyontology.sparql_grammar import SPARQLGrammar as SP # name clash ? from constraint_classes import * Solver = MySolver Expression = MyExpression @@ -16,6 +21,9 @@ py.log.setconsumer("Pyontology", None) #py.log.setconsumer("Pyontology", ansi_log) +from rdflib import Graph, URIRef, BNode, Literal as rdflib_literal + + namespaces = { 'rdf' : 'http://www.w3.org/1999/02/22-rdf-syntax-ns', 'rdfs' : 'http://www.w3.org/2000/01/rdf-schema', Modified: pypy/branch/ast-experiments/pypy/lib/pyontology/test/test_ontology.py ============================================================================== --- pypy/branch/ast-experiments/pypy/lib/pyontology/test/test_ontology.py (original) +++ pypy/branch/ast-experiments/pypy/lib/pyontology/test/test_ontology.py Mon Feb 26 08:45:45 2007 @@ -1,747 +1,803 @@ # tests for the Ontology class +import autopath import py +from pypy.conftest import gettestobjspace try: - import logilab.constraint + #import logilab.constraint import rdflib except ImportError: import py - py.test.skip("Logilab.constraint and/or rdflib not installed") + py.test.skip("rdflib not installed") -from pypy.lib.pyontology.pyontology import * # Ontology, ClassDomain, SubClassConstraint +#from pypy.lib.pyontology.pyontology import * # Ontology, ClassDomain, SubClassConstraint from rdflib import Graph, URIRef, BNode UR = URIRef -def rdf_list(ont, name, data): - owllist = URIRef(name) - obj = URIRef(namespaces['rdf']+'#List') - ont.type(owllist, obj) - own =owllist - for i,dat in enumerate(data[:-1]): - next = BNode( name + str(i)) - next,i,dat,own - ont.first(own, dat) - ont.type(next, obj) - ont.rest(own, next) - own = next - ont.first(own, data[-1]) - ont.rest(own, URIRef(namespaces['rdf']+'#nil')) - return owllist - -def test_equivalentProperty_inconst(): - O = Ontology() - O.add_file("testinconst.rdf") - O.attach_fd() - raises(ConsistencyFailure, O.consistency) - -def test_XMLSchema_string(): - O = Ontology() - a = URIRef(u'A') - p = URIRef(u'P') - prop = URIRef(namespaces['rdf']+'#Property') - xml_string_uri = URIRef(namespaces['xmlschema']+"#string") - O.type(p, prop) - O.consider_triple((a, p, rdflib_literal("ddd", datatype=xml_string_uri))) - O.range(p, xml_string_uri) - O.consistency() - -def test_XMLSchema_string_fail(): -# py.test.skip("WIP") - O = Ontology() - a = URIRef(u'A') - p = URIRef(u'P') - prop = URIRef(namespaces['rdf']+'#Property') - xml_string_uri = URIRef(namespaces['xmlschema']+"#string") - xml_int_uri= URIRef(namespaces['xmlschema']+"#integer") - O.type(p, prop) - O.consider_triple((a, p, rdflib_literal(2, datatype = xml_int_uri))) - O.range(p, xml_string_uri) - raises(ConsistencyFailure, O.consistency) - -def test_makevar(): - O = Ontology() - var = URIRef(u'http://www.w3.org/2002/03owlt/unionOf/premises004#A-and-B') - name = O.make_var(ClassDomain, var) - cod = name+' = 1' - exec cod - assert O.make_var(None, var) in locals() - assert isinstance(O.variables[name], ClassDomain) - -def test_subClassof(): - O = Ontology() - a = URIRef(u'A') - b = URIRef(u'B') - c = URIRef(u'C') - O.subClassOf(b, a) - O.subClassOf(c, b) - obj = URIRef(namespaces['owl']+'#Class') - O.type(a,obj) - O.consistency() - O.subClassOf(c, a) - O.consistency() - -def test_subClassof2(): - O = Ontology() - a = URIRef(u'A') - b = URIRef(u'B') - c = URIRef(u'C') - d = URIRef(u'D') - O.subClassOf(b, a) - O.subClassOf(c, b) - obj = URIRef(namespaces['owl']+'#Class') - O.type(a,obj) - O.type(d,c) - O.consistency() - d_indi = O.mangle_name(d) - assert Individual(d_indi, d) in O.variables[O.mangle_name(a)].getValues() - O.subClassOf(c, a) - O.consistency() - -def test_addvalue(): - O = Ontology() - a = O.make_var(Property, URIRef('a')) - O.variables[a].addValue('key', 42) - assert ('key', 42) in O.variables[a] - O.variables[a].addValue('key', 43) - assert list(O.variables[a].getValues()) == [('key', 42), ('key', 43)] - -def no_test_ClassDomain(): - a = ClassDomain() - cls = 1 - b = ClassDomain('B',[],[a]) - assert b in b - assert a in b - -def test_subClassconstraint(): - a = ClassDomain('A') - b = ClassDomain('B') - c = ClassDomain('C') - con = SubClassConstraint('b','a') - con2 = SubClassConstraint('c','b') - indi = URIRef('indi') - c.setValues([Individual('indi_',indi)]) - con.narrow({'a': a, 'b': b, 'c': c}) - con2.narrow({'a': a, 'b': b, 'c': c}) - con.narrow({'a': a, 'b': b, 'c': c}) - assert Individual('indi_', indi) in a - -def test_subClassconstraintMulti(): - a = ClassDomain('A') - b = ClassDomain('B') - c = ClassDomain('C') - indi = URIRef('indi') - c.setValues([Individual('indi_',indi)]) - con = SubClassConstraint('c','a') - con2 = SubClassConstraint('c','b') - con.narrow({'a': a, 'b': b, 'c': c}) - con2.narrow({'a': a, 'b': b, 'c': c}) - assert Individual('indi_', indi) in a - assert Individual('indi_', indi) in b - -def test_subClassconstraintMulti2(): - a = ClassDomain('A') - b = ClassDomain('B') - c = ClassDomain('C') - indi = URIRef('indi') - c.setValues([Individual('indi_',indi)]) - con = SubClassConstraint('c','a') - con2 = SubClassConstraint('c','b') - con3 = SubClassConstraint('a','c') - con.narrow({'a': a, 'b': b, 'c': c}) - con2.narrow({'a': a, 'b': b, 'c': c}) - con3.narrow({'a': a, 'b': b, 'c': c}) - assert Individual('indi_', indi) in a - assert Individual('indi_', indi) in b - assert Individual('indi_', indi) in c - -def test_equivalentClass(): - O = Ontology() - a = O.make_var(ClassDomain,URIRef('A')) - b = O.make_var(ClassDomain,URIRef('B')) - c = O.make_var(ClassDomain,URIRef('C')) - O.equivalentClass(c, a) - O.equivalentClass(c, b) - A = O.make_var(ClassDomain, a) - B = O.make_var(ClassDomain, b) - assert O.variables[A].values == O.variables[B].values - -def test_type(): - sub = URIRef('a') - pred = URIRef('type') - obj = URIRef('o') - O = Ontology() - O.make_var(ClassDomain, obj) - O.type(sub, obj) - O.type(obj, namespaces['owl']+"#Class") - - assert list(O.variables[O.make_var(None, obj)].getValues())[0].__class__ == Individual - -# test for multiple types -# test for type hierarchy - -def test_ObjectProperty(): - sub = URIRef('a') - obj = URIRef(namespaces['owl']+'#ObjectProperty') - O = Ontology() - O.type(sub, obj) - assert O.variables[O.make_var(None, sub)].__class__ == ObjectProperty - -def test_range(): - O = Ontology() - sub = URIRef('a') - obj = URIRef('b') - O.variables['b_'] = ClassDomain(values=[1,2,3,4]) - O.range(sub, obj) - sub = URIRef('a') - pred = URIRef('type') - obj = URIRef(namespaces['owl']+'#ObjectProperty') - O.type(sub, obj) - #assert len(O.constraints) == 1 - O.constraints[0].narrow(O.variables) - -def test_merge(): - O = Ontology() - sub = URIRef('a') - obj = URIRef('b') - O.variables['b_'] = ClassDomain(values=[1,2,3,4]) - O.range(sub, obj) - obj = URIRef('c') - O.variables['c_'] = ClassDomain(values=[3,4,5,6]) - O.range(sub, obj) - sub = URIRef('a') - pred = URIRef('type') - obj = URIRef(namespaces['owl']+'#ObjectProperty') - O.type(sub, obj) - #assert len(O.constraints) == 2 - O.consistency() - -def test_domain(): - O = Ontology() - sub = URIRef('a') - obj = URIRef('b') - O.variables['b_'] = ClassDomain('b') - O.domain(sub, obj) - sub = URIRef('a') - pred = URIRef('type') - obj = URIRef(namespaces['owl']+'#ObjectProperty') - O.type(sub, obj) - #assert len(O.constraints) == 1 - O.constraints[0].narrow(O.variables) - -def test_domain_merge(): - O = Ontology() - sub = URIRef('a') - obj = URIRef('b') - O.variables['b_'] = ClassDomain('b') - O.domain(sub, obj) - obj = URIRef('c') - O.variables['c_'] = ClassDomain('c') - O.domain(sub, obj) - obj = URIRef(namespaces['owl']+'#ObjectProperty') - O.type(sub, obj) - - #assert len(O.constraints) == 2 - for con in O.constraints: - con.narrow(O.variables) - assert O.variables['a_'].size() == 0 - -def test_subproperty(): - O = Ontology() - sub = URIRef('a') - obj = URIRef(namespaces['owl']+'#ObjectProperty') - O.type(sub, obj) - b = URIRef('b') - O.type(b, obj) - O.variables['a_'].setValues([('individ_',42)]) - O.subPropertyOf(sub, b) - O.consistency() - for val in O.variables['a_'].getValues(): - assert val in O.variables['b_'] - -def test_functionalproperty(): - - O = Ontology() - #Make functional property - sub = URIRef('p') - obj = URIRef(namespaces['owl']+'#FunctionalProperty') - O.type(sub, obj) - #Make class - sub = URIRef('c') - obj = URIRef(namespaces['owl']+'#Class') - O.type(sub, obj) - #Make individual with a value of the property - sub = URIRef('individ') - obj = URIRef('c') - O.type(sub, obj) - O.variables['p_'].setValues([('individ',42)]) - #add another valueof the property - O.variables['p_'].addValue('individ',43) - py.test.raises(ConsistencyFailure, O.consistency ) - #check that consistency raises - -def test_inversefunctionalproperty(): - - O = Ontology() - #Make functional property - sub = URIRef('p') - obj = URIRef(namespaces['owl']+'#InverseFunctionalProperty') - O.type(sub, obj) - #Make class - sub = URIRef('c') - obj = URIRef(namespaces['owl']+'#Class') - O.type(sub, obj) - #Make individual with a value of the property - sub = URIRef('individ') - obj = URIRef('c') - O.type(sub, obj) - O.variables['p_'].setValues([('individ_',42)]) - #assert len(O.constraints) == 2 - #add another individual with the same value for the property - sub = URIRef('individ2') - obj = URIRef('c') - O.type(sub, obj) - py.test.raises(ConsistencyFailure, O.variables['p_'].setValues, [('individ_',42),('individ2_',42)]) - -def test_Transitiveproperty(): - O = Ontology() - #Make functional property - subreg = URIRef('subRegionOf') - obj = URIRef(namespaces['owl']+'#TransitiveProperty') - O.type(subreg, obj) - #Make class - sub = URIRef('c') - obj = URIRef(namespaces['owl']+'#Class') - O.type(sub, obj) - #Make individual with a value of the property - it = URIRef('Italy') - obj = URIRef('c') - O.type(it, obj) - tus = URIRef('Tuscanny') - O.type(tus, obj) - chi = URIRef('Chianti') - O.type(chi, obj) -# O.variables['subRegionOf_'].setValues([('Italy_','Tuscanny_'),('Tuscanny_','Chianti_')]) - O.consider_triple((tus, subreg, it)) - O.consider_triple((chi, subreg, tus)) - O.consistency() - assert Individual('Italy_', it) in O.variables['subRegionOf_'].getValuesPrKey(Individual('Chianti',chi)) - -def test_symmetricproperty(): - O = Ontology() - #Make functional property - sub = URIRef('friend') - obj = URIRef(namespaces['owl']+'#SymmetricProperty') - O.type(sub, obj) - assert O.variables[O.make_var(None, sub)].__class__.__name__=='SymmetricProperty' - #Make class - sub = URIRef('c') - obj = URIRef(namespaces['owl']+'#Class') - O.type(sub, obj) - #Make individual with a value of the property - sub = URIRef('Bob') - obj = URIRef('c') - O.type(sub, obj) - sub = URIRef('Alice') - O.type(sub, obj) - O.variables['friend_'].setValues([('Bob_','Alice_')]) - O.consistency() - assert ('Alice_', 'Bob_') in O.variables['friend_'] - -def test_inverseof(): - O = Ontology() - own = URIRef('owner') - obj = URIRef(namespaces['owl']+'#ObjectProperty') - O.type(own, obj) - owned = URIRef('ownedby') - obj = URIRef(namespaces['owl']+'#ObjectProperty') - O.type(owned, obj) - #Make class - sub = URIRef('c') - obj = URIRef(namespaces['owl']+'#Class') - O.type(sub, obj) - #Make individual with a property value - sub = URIRef('Bob') - obj = URIRef('c') - O.type(sub, obj) - sub = URIRef('Fiat') - obj = URIRef('car') - O.type(sub, obj) - O.variables['owner_'].setValues([('Bob_','Fiat_')]) - O.inverseOf(own, owned) - O.consistency() - assert ('Fiat_','Bob_') in O.variables['ownedby_'] - -def test_hasvalue(): - # py.test.skip("") - O = Ontology() - cls = URIRef('class') - obj = URIRef(namespaces['owl']+'#Thing') - O.type(cls, obj) - restrict = BNode('anon1') - obj = URIRef(namespaces['owl']+'#Restriction') - O.type(restrict, obj) - p = URIRef('p') - obj = URIRef(namespaces['owl']+'#ObjectProperty') - O.type(p, obj) - O.consider_triple((cls, p, 2)) - O.onProperty(restrict,p) - O.consider_triple((cls, p, 1)) - O.hasValue(restrict, 2) -# O.type(2, URIRef(namespaces['owl']+'#Thing')) -# O.type(1, URIRef(namespaces['owl']+'#Thing')) - - cls2 = URIRef('class2') - obj = URIRef(namespaces['owl']+'#Thing') - O.type(cls2, obj) - O.subClassOf(cls2,restrict) - O.variables[O.make_var(None, cls2)].finish(O.variables, O.constraints) - O.consistency() - assert cls in O.variables[O.make_var(None, cls2)] -# py.test.raises(ConsistencyFailure, O.consistency) - -def test_List(): - py.test.skip("Need to be rewritten using RDF-XML") - O = Ontology() - own = URIRef('favlist') - obj = URIRef(namespaces['rdf']+'#List') - O.type(own, obj) - O.first(own, 0) - O.rest(own, URIRef('1')) - O.first( URIRef('1'), 1) - O.rest( URIRef('1'), URIRef('2')) - O.first( URIRef('2'), 2) - O.rest( URIRef('2'), URIRef(namespaces['rdf']+'#nil')) - O.flatten_rdf_list(own) - O.consistency() - assert list(O.rep._domains['favlist_'].getValues()) == [0,1,2] - -def test_oneofclassenumeration(): - O = Ontology() - restrict = BNode('anon') - own = [UR('first'), UR('second'), UR('third')] - O.oneOf(restrict, own) - O.type(restrict, UR(namespaces['owl']+'#Class')) - O.consistency() - assert O.rep._domains[restrict].size()== 3 - assert set(O.rep._domains[restrict].getValues()) == set(own) - -def test_unification_of_two_oneofclassenumeration(): - O = Ontology() - restrict = BNode('anon') - own = [UR('first'), UR('second'), UR('third')] - for i in own: - O.type(i,UR(namespaces['owl']+'#Thing')) - O.oneOf(restrict, own) - restrict1 = BNode('anon1') - own = [UR('second'), UR('third'), UR('first')] - O.oneOf(restrict1, own) - O.type(UR('test'), UR(namespaces['owl']+'#Thing')) - O.type(UR('test'), restrict) - O.type(UR('test'), restrict1) - O.consistency() - assert O.rep._domains[restrict].size() == 3 - assert set(O.rep._domains[restrict].getValues()) == set(own) - - -def test_oneofdatarange(): - O = Ontology() - restrict = BNode('anon') - own = ['1','2','3'] - O.oneOf(restrict, own) - O.type(restrict, UR(namespaces['owl']+'#DataRange')) - O.consistency() - assert O.rep._domains[restrict].size() == 3 - assert set(O.rep._domains[restrict].getValues()) == set(own) - -def test_somevaluesfrom_datarange(): - py.test.skip("reconsider if the test is correct - make it simpler") - O = Ontology() - datarange = BNode('anon') - own = ['1','2','3'] - O.oneOf(datarange, own) - O.type(datarange, namespaces['owl']+'#DataRange') - restrict = BNode('anon1') - obj = URIRef(namespaces['owl']+'#Restriction') - O.type(restrict, obj) - p = URIRef('p') - obj = URIRef(namespaces['owl']+'#ObjectProperty') - O.type(p, obj) - cls = URIRef('class') - obj = URIRef(namespaces['owl']+'#Class') - O.type(cls, obj) - O.variables['p_'].setValues([(cls,'1')]) - O.onProperty(restrict,p) - O.someValuesFrom(restrict, datarange) - O.subClassOf(cls,restrict) - O.consistency() - assert cls in O.variables[O.make_var(None, cls)] - -def test_allvaluesfrom_datarange(): - py.test.skip("") - O = Ontology() - datarange = BNode('anon') - own = ['1','2','3'] - O.oneOf(datarange, own) - O.type(datarange, namespaces['owl']+'#DataRange') - restrict = BNode('anon1') - obj = URIRef(namespaces['owl']+'#Restriction') - O.type(restrict, obj) - p = URIRef('p') - obj = URIRef(namespaces['owl']+'#ObjectProperty') - O.type(p, obj) - cls = URIRef('class') - O.variables['p_'].setValues([(cls,'1'),(cls,'2'),(cls,'3')]) - obj = URIRef(namespaces['owl']+'#Class') - O.type(cls, obj) - O.onProperty(restrict,p) - O.allValuesFrom(restrict, datarange) - O.subClassOf(cls,restrict) - assert cls in O.variables[O.make_var(None, cls)] - -def test_unionof(): - #py.test.skip("Rewrite the test") - O = Ontology() - cls = BNode('anon') - own1 = BNode('liist1') - own2 = BNode('liist2') - list1 = ['1', '2', '3'] - list2 = ['3', '4', '5'] - own = [own1, own2] - O.oneOf( own1, list1) - O.oneOf( own2, list2) - O.unionOf(cls, own) - O.type(cls, namespaces['owl']+'#Class') - O.consistency() - res = list(O.rep._domains[cls].getValues()) - res.sort() - assert set(res) == set([Individual(x,x) for x in ['1', '2', '3', '4', '5']]) - -def test_intersectionof(): - py.test.skip("Rewrite the test") - O = Ontology() - cls = BNode('anon') - O.intersectionOf(cls, [['1','2','3'],['3','4','5']]) - O.type(cls, namespaces['owl']+'#Class') - O.consistency() - assert list(O.rep._domains[cls].getValues()) == ['3'] - -def test_differentfrom(): - O = Ontology() - cls = BNode('anon') - own1 = BNode('liist1') - own2 = BNode('liist2') - O.differentFrom(cls, own1) - O.differentFrom(own1, own2) - O.differentFrom(cls, own2) - O.differentFrom(own2,cls) - O.type(cls, UR(namespaces['owl']+'#Thing')) - O.type(own1, UR(namespaces['owl']+'#Thing')) - O.type(own2, UR(namespaces['owl']+'#Thing')) - O.consistency() - #assert len(O.rep._constraints) == 4 - -def test_differentfromconsistency(): - O = Ontology() - cls = BNode('anon') - O.differentFrom(cls, cls) - O.type(cls, UR(namespaces['owl']+'#Thing')) - py.test.raises(ConsistencyFailure, O.consistency) - -def test_sameas(): - O = Ontology() - cls = BNode('anon') - own1 = BNode('liist1') - own2 = BNode('liist2') - O.sameAs(cls, own1) - O.sameAs(own1, own2) - O.sameAs(cls, own2) - O.type(cls, UR(namespaces['owl']+'#Thing')) - O.type(own1, UR(namespaces['owl']+'#Thing')) - O.type(own2, UR(namespaces['owl']+'#Thing')) - sub = URIRef('a') - obj = URIRef(namespaces['owl']+'#ObjectProperty') - O.type(sub, obj) - O.variables[O.make_var(None,sub)].setValues([(cls,'1')]) - O.consistency() - assert ('liist1','1') in O.rep._domains[O.make_var(None,sub)] - -def test_sameasconsistency(): - O = Ontology() - cls = BNode('anon') - own1 = BNode('liist1') - O.sameAs(cls, own1) - O.type(cls, UR(namespaces['owl']+'#Thing')) - O.type(own1, UR(namespaces['owl']+'#Thing')) - sub = URIRef('a') - obj = URIRef(namespaces['owl']+'#ObjectProperty') - O.type(sub, obj) - O.variables[O.make_var(None,sub)].setValues([(cls,'1'), (own1,'2')]) - py.test.raises(ConsistencyFailure, O.consistency) - - -def test_terminology_cardinality(): - # Modeled after one of the standard tests (approved/maxCardinality) - # 'cls' by subclassing two maxCardinality restrictions becomes the set of - # individuals satisfying both restriction, ie having exactly 2 values of - # predicate p - cls = URIRef('cls') - O = Ontology() - O.add((cls, UR(namespaces['rdf']+'#type'), UR(namespaces['owl']+'#Class'))) - p = O.make_var(Property,URIRef('p')) - p = URIRef('p') - O.add((p, UR(namespaces['rdf']+'#type'), UR(namespaces['owl']+'#ObjectProperty'))) - - restr = BNode('anon') - O.add((restr, UR(namespaces['rdf']+'#type'), UR(namespaces['owl']+'#Restriction') )) - O.add((restr, UR(namespaces['owl']+'#onProperty'), p )) - O.add((cls, UR(namespaces['rdfs']+'#subClassOf'),restr )) - O.add((restr, UR(namespaces['owl']+'#maxCardinality'), 2 )) - - restr2 = BNode('anon2') - O.add((restr2, UR(namespaces['rdf']+'#type'), UR(namespaces['owl']+'#Restriction') )) - O.add((restr2, UR(namespaces['owl']+'#onProperty'), p )) - O.add((cls, UR(namespaces['rdfs']+'#subClassOf'),restr2 )) - O.add((restr2, UR(namespaces['owl']+'#minCardinality'), 3 )) - O.attach_fd() - for var in O.variables.values(): - var.finish(O.variables, O.constraints) - py.test.raises(ConsistencyFailure, O.consistency) - -def test_terminology_subclassof_cardinality(): - cls = URIRef('cls') - cls2 = URIRef('cls2') - O = Ontology() - O.add((cls, UR(namespaces['rdfs']+'#type'), UR(namespaces['owl']+'#Class'))) - O.add((cls2, UR(namespaces['rdfs']+'#type'), UR(namespaces['owl']+'#Class'))) - p = O.make_var(Property,URIRef('p')) - p = URIRef('p') - O.add((p, UR(namespaces['rdfs']+'#type'), UR(namespaces['owl']+'#ObjectProperty'))) - - restr = BNode('anon') - O.add((restr, UR(namespaces['rdfs']+'#type'), UR(namespaces['owl']+'#Restriction'))) - O.add((restr, UR(namespaces['rdfs']+'#onProperty'), p )) - O.add((cls, UR(namespaces['rdfs']+'#subClassOf'),restr )) - O.add((restr, UR(namespaces['rdfs']+'#maxCardinality'), 2 )) - - restr2 = BNode('anon2') - O.add((restr2, UR(namespaces['rdfs']+'#type'), UR(namespaces['owl']+'#Restriction'))) - O.add((restr2, UR(namespaces['rdfs']+'#onProperty'), p )) - O.add((cls, UR(namespaces['rdfs']+'#subClassOf'),restr2 )) - O.add((restr2, UR(namespaces['rdfs']+'#minCardinality'), 3 )) - O.add((cls2, UR(namespaces['rdfs']+'#subClassOf'), cls )) - O.attach_fd() - for var in O.variables.values(): - var.finish(O.variables, O.constraints) - py.test.raises(ConsistencyFailure, O.consistency) - -def test_add_file(): - O = Ontology() - O.add_file('premises001.rdf') - trip = list(O.graph.triples((None,)*3)) -# O.attach_fd() - ll = len(O.variables) - l = len(trip) - O.add_file('conclusions001.rdf') - O.attach_fd() - lll = len(O.variables) - assert len(list(O.graph.triples((None,)*3))) > l - -def test_more_cardinality(): - O = Ontology() - O.add_file('premises003.rdf') - trip = list(O.graph.triples((None,)*3)) - # O.attach_fd() - ll = len(O.variables) - l = len(trip) - O.add_file('conclusions003.rdf') - O.attach_fd() - O.consistency() - lll = len(O.variables) - assert len(list(O.graph.triples((None,)*3))) > l - -def test_import(): - O = Ontology() - s = URIRef('s') - O.imports(s,URIRef('http://www.w3.org/2002/03owlt/imports/support001-A')) - -def test_complementof(): - O = Ontology() - a_cls = URIRef('a') - b_cls = URIRef('b') - O.type(a_cls, URIRef(namespaces['owl']+'#Class')) - O.type(b_cls, URIRef(namespaces['owl']+'#Class')) - O.oneOf(a_cls, [URIRef('i1'), URIRef('i2'), URIRef('i3'), URIRef('i4')]) - for i in ['i1', 'i2', 'i3', 'i4']: - O.type(URIRef(i), URIRef(namespaces['owl']+'#Thing')) - O.type(URIRef('i5'), URIRef(namespaces['owl']+'#Thing')) - O.complementOf(b_cls, a_cls) - O.consistency() - assert list(O.variables[O.make_var(None, b_cls)].getValues()) == ['i5'] - -def test_complementof_raise(): - O = Ontology() - a_cls = URIRef('a') - b_cls = URIRef('b') - O.type(a_cls, URIRef(namespaces['owl']+'#Class')) - O.type(b_cls, URIRef(namespaces['owl']+'#Class')) - O.oneOf(a_cls, [URIRef('i1'), URIRef('i2'), URIRef('i3'), URIRef('i4')]) - for i in ['i1', 'i2', 'i3', 'i4']: - O.type(URIRef(i), URIRef(namespaces['owl']+'#Thing')) - O.type(URIRef('i5'), URIRef(namespaces['owl']+'#Thing')) - O.type(URIRef('i4'), b_cls) - O.type(URIRef('i4'), a_cls) - O.complementOf(b_cls, a_cls) - # The above ontology states that 'b' is complement of 'a'. But that leads - # to an inconsistency as 'i4' is of type 'a' and 'b' - raises(ConsistencyFailure, O.consistency) - -def test_class_promotion(): - O = Ontology() - a_cls = URIRef('a') - O.type(a_cls, URIRef(namespaces['owl']+'#Class')) - - assert isinstance(O.variables['a_'], ClassDomain) - O.type(a_cls, URIRef(namespaces['owl']+'#Restriction')) - assert isinstance(O.variables['a_'], Restriction) - -def test_class_demotion(): - O = Ontology() - a_cls = URIRef('a') - O.type(a_cls, URIRef(namespaces['owl']+'#Restriction')) - O.variables[O.make_var(None, a_cls)].property = "SomeProp" - assert isinstance(O.variables['a_'], Restriction) - - O.type(a_cls, URIRef(namespaces['owl']+'#Class')) - - assert isinstance(O.variables['a_'], Restriction) - assert O.variables[O.make_var(None, a_cls)].property == "SomeProp" - -def test_property_to_objectproperty(): - O = Ontology() - a_cls = URIRef('a') - O.type(a_cls, URIRef(namespaces['rdf']+'#Property')) - assert isinstance(O.variables['a_'], Property) - O.type(a_cls, URIRef(namespaces['owl']+'#ObjectProperty')) - assert isinstance(O.variables['a_'], Property) - - O.type(a_cls, URIRef(namespaces['rdf']+'#Property')) - - assert isinstance(O.variables['a_'], ObjectProperty) - -def test_individual(): - # test comparison (unknown, equal, different) - O = Ontology() - first = URIRef('first') - second = URIRef('second') - O.type(first, URIRef(namespaces['owl']+'#Thing')) - assert isinstance(list(O.variables['owl_Thing'].getValues())[0], Individual) - -def test_recording_of_properties(): - O = Ontology() - first = URIRef('first') - second = URIRef('second') -# O.type(first, URIRef(namespaces['owl']+'#SymmetricProperty')) - O.consider_triple((first, URIRef(namespaces['rdf']+'#type'), URIRef(namespaces['owl']+'#SymmetricProperty'))) - assert isinstance(O.variables['first_'], SymmetricProperty) - assert 'first_' in O.variables['owl_ObjectProperty'] #.getValues() - assert 'first_' in O.variables['rdf_Property'] # .getValues() + +class TestAppOntology: + + def setup_class(cls): + space = gettestobjspace(usemodules=('_cslib',)) + cls.space = space + + def rdf_list(self, ont, name, data): + owllist = URIRef(name) + obj = URIRef(namespaces['rdf']+'#List') + ont.type(owllist, obj) + own =owllist + for i,dat in enumerate(data[:-1]): + next = BNode( name + str(i)) + next,i,dat,own + ont.first(own, dat) + ont.type(next, obj) + ont.rest(own, next) + own = next + ont.first(own, data[-1]) + ont.rest(own, URIRef(namespaces['rdf']+'#nil')) + return owllist + + def test_equivalentProperty_inconst(self): + from pypy.lib.pyontology.pyontology import * + O = Ontology() + O.add_file("testinconst.rdf") + O.attach_fd() + raises(ConsistencyFailure, O.consistency) + + def test_XMLSchema_string(self): + from pypy.lib.pyontology.pyontology import * + O = Ontology() + a = URIRef(u'A') + p = URIRef(u'P') + prop = URIRef(namespaces['rdf']+'#Property') + xml_string_uri = URIRef(namespaces['xmlschema']+"#string") + O.type(p, prop) + O.consider_triple((a, p, rdflib_literal("ddd", datatype=xml_string_uri))) + O.range(p, xml_string_uri) + O.consistency() + + def test_XMLSchema_string_fail(self): + # py.test.skip("WIP") + from pypy.lib.pyontology.pyontology import * + O = Ontology() + a = URIRef(u'A') + p = URIRef(u'P') + prop = URIRef(namespaces['rdf']+'#Property') + xml_string_uri = URIRef(namespaces['xmlschema']+"#string") + xml_int_uri= URIRef(namespaces['xmlschema']+"#integer") + O.type(p, prop) + O.consider_triple((a, p, rdflib_literal(2, datatype = xml_int_uri))) + O.range(p, xml_string_uri) + raises(ConsistencyFailure, O.consistency) + + def test_makevar(self): + from pypy.lib.pyontology.pyontology import * + O = Ontology() + var = URIRef(u'http://www.w3.org/2002/03owlt/unionOf/premises004#A-and-B') + name = O.make_var(ClassDomain, var) + cod = name+' = 1' + exec cod + assert O.make_var(None, var) in locals() + assert isinstance(O.variables[name], ClassDomain) + + def test_subClassof(self): + from pypy.lib.pyontology.pyontology import * + O = Ontology() + a = URIRef(u'A') + b = URIRef(u'B') + c = URIRef(u'C') + O.subClassOf(b, a) + O.subClassOf(c, b) + obj = URIRef(namespaces['owl']+'#Class') + O.type(a,obj) + O.consistency() + O.subClassOf(c, a) + O.consistency() + + def test_subClassof2(self): + from pypy.lib.pyontology.pyontology import * + O = Ontology() + a = URIRef(u'A') + b = URIRef(u'B') + c = URIRef(u'C') + d = URIRef(u'D') + O.subClassOf(b, a) + O.subClassOf(c, b) + obj = URIRef(namespaces['owl']+'#Class') + O.type(a,obj) + O.type(d,c) + O.consistency() + d_indi = O.mangle_name(d) + assert Individual(d_indi, d) in O.variables[O.mangle_name(a)].getValues() + O.subClassOf(c, a) + O.consistency() + + def test_addvalue(self): + from pypy.lib.pyontology.pyontology import * + O = Ontology() + a = O.make_var(Property, URIRef('a')) + O.variables[a].addValue('key', 42) + assert ('key', 42) in O.variables[a] + O.variables[a].addValue('key', 43) + assert list(O.variables[a].getValues()) == [('key', 42), ('key', 43)] + + def no_test_ClassDomain(self): + from pypy.lib.pyontology.pyontology import * + a = ClassDomain() + cls = 1 + b = ClassDomain('B',[],[a]) + assert b in b + assert a in b + + def test_subClassconstraint(self): + from pypy.lib.pyontology.pyontology import * + a = ClassDomain('A') + b = ClassDomain('B') + c = ClassDomain('C') + con = SubClassConstraint('b','a') + con2 = SubClassConstraint('c','b') + indi = URIRef('indi') + c.setValues([Individual('indi_',indi)]) + con.narrow({'a': a, 'b': b, 'c': c}) + con2.narrow({'a': a, 'b': b, 'c': c}) + con.narrow({'a': a, 'b': b, 'c': c}) + assert Individual('indi_', indi) in a + + def test_subClassconstraintMulti(self): + from pypy.lib.pyontology.pyontology import * + a = ClassDomain('A') + b = ClassDomain('B') + c = ClassDomain('C') + indi = URIRef('indi') + c.setValues([Individual('indi_',indi)]) + con = SubClassConstraint('c','a') + con2 = SubClassConstraint('c','b') + con.narrow({'a': a, 'b': b, 'c': c}) + con2.narrow({'a': a, 'b': b, 'c': c}) + assert Individual('indi_', indi) in a + assert Individual('indi_', indi) in b + + def test_subClassconstraintMulti2(self): + from pypy.lib.pyontology.pyontology import * + a = ClassDomain('A') + b = ClassDomain('B') + c = ClassDomain('C') + indi = URIRef('indi') + c.setValues([Individual('indi_',indi)]) + con = SubClassConstraint('c','a') + con2 = SubClassConstraint('c','b') + con3 = SubClassConstraint('a','c') + con.narrow({'a': a, 'b': b, 'c': c}) + con2.narrow({'a': a, 'b': b, 'c': c}) + con3.narrow({'a': a, 'b': b, 'c': c}) + assert Individual('indi_', indi) in a + assert Individual('indi_', indi) in b + assert Individual('indi_', indi) in c + + def test_equivalentClass(self): + from pypy.lib.pyontology.pyontology import * + O = Ontology() + a = O.make_var(ClassDomain,URIRef('A')) + b = O.make_var(ClassDomain,URIRef('B')) + c = O.make_var(ClassDomain,URIRef('C')) + O.equivalentClass(c, a) + O.equivalentClass(c, b) + A = O.make_var(ClassDomain, a) + B = O.make_var(ClassDomain, b) + assert O.variables[A].values == O.variables[B].values + + def test_type(self): + from pypy.lib.pyontology.pyontology import * + sub = URIRef('a') + pred = URIRef('type') + obj = URIRef('o') + O = Ontology() + O.make_var(ClassDomain, obj) + O.type(sub, obj) + O.type(obj, namespaces['owl']+"#Class") + + assert list(O.variables[O.make_var(None, obj)].getValues())[0].__class__ == Individual + + # test for multiple types + # test for type hierarchy + + def test_ObjectProperty(self): + from pypy.lib.pyontology.pyontology import * + sub = URIRef('a') + obj = URIRef(namespaces['owl']+'#ObjectProperty') + O = Ontology() + O.type(sub, obj) + assert O.variables[O.make_var(None, sub)].__class__ == ObjectProperty + + def test_range(self): + from pypy.lib.pyontology.pyontology import * + O = Ontology() + sub = URIRef('a') + obj = URIRef('b') + O.variables['b_'] = ClassDomain(values=[1,2,3,4]) + O.range(sub, obj) + sub = URIRef('a') + pred = URIRef('type') + obj = URIRef(namespaces['owl']+'#ObjectProperty') + O.type(sub, obj) + #assert len(O.constraints) == 1 + O.constraints[0].narrow(O.variables) + + def test_merge(self): + from pypy.lib.pyontology.pyontology import * + O = Ontology() + sub = URIRef('a') + obj = URIRef('b') + O.variables['b_'] = ClassDomain(values=[1,2,3,4]) + O.range(sub, obj) + obj = URIRef('c') + O.variables['c_'] = ClassDomain(values=[3,4,5,6]) + O.range(sub, obj) + sub = URIRef('a') + pred = URIRef('type') + obj = URIRef(namespaces['owl']+'#ObjectProperty') + O.type(sub, obj) + #assert len(O.constraints) == 2 + O.consistency() + + def test_domain(self): + from pypy.lib.pyontology.pyontology import * + O = Ontology() + sub = URIRef('a') + obj = URIRef('b') + O.variables['b_'] = ClassDomain('b') + O.domain(sub, obj) + sub = URIRef('a') + pred = URIRef('type') + obj = URIRef(namespaces['owl']+'#ObjectProperty') + O.type(sub, obj) + #assert len(O.constraints) == 1 + O.constraints[0].narrow(O.variables) + + def test_domain_merge(self): + from pypy.lib.pyontology.pyontology import * + O = Ontology() + sub = URIRef('a') + obj = URIRef('b') + O.variables['b_'] = ClassDomain('b') + O.domain(sub, obj) + obj = URIRef('c') + O.variables['c_'] = ClassDomain('c') + O.domain(sub, obj) + obj = URIRef(namespaces['owl']+'#ObjectProperty') + O.type(sub, obj) + + #assert len(O.constraints) == 2 + for con in O.constraints: + con.narrow(O.variables) + assert O.variables['a_'].size() == 0 + + def test_subproperty(self): + from pypy.lib.pyontology.pyontology import * + O = Ontology() + sub = URIRef('a') + obj = URIRef(namespaces['owl']+'#ObjectProperty') + O.type(sub, obj) + b = URIRef('b') + O.type(b, obj) + O.variables['a_'].setValues([('individ_',42)]) + O.subPropertyOf(sub, b) + O.consistency() + for val in O.variables['a_'].getValues(): + assert val in O.variables['b_'] + + def test_functionalproperty(self): + from pypy.lib.pyontology.pyontology import * + O = Ontology() + #Make functional property + sub = URIRef('p') + obj = URIRef(namespaces['owl']+'#FunctionalProperty') + O.type(sub, obj) + #Make class + sub = URIRef('c') + obj = URIRef(namespaces['owl']+'#Class') + O.type(sub, obj) + #Make individual with a value of the property + sub = URIRef('individ') + obj = URIRef('c') + O.type(sub, obj) + O.variables['p_'].setValues([('individ',42)]) + #add another valueof the property + O.variables['p_'].addValue('individ',43) + py.test.raises(ConsistencyFailure, O.consistency ) + #check that consistency raises + + def test_inversefunctionalproperty(self): + from pypy.lib.pyontology.pyontology import * + O = Ontology() + #Make functional property + sub = URIRef('p') + obj = URIRef(namespaces['owl']+'#InverseFunctionalProperty') + O.type(sub, obj) + #Make class + sub = URIRef('c') + obj = URIRef(namespaces['owl']+'#Class') + O.type(sub, obj) + #Make individual with a value of the property + sub = URIRef('individ') + obj = URIRef('c') + O.type(sub, obj) + O.variables['p_'].setValues([('individ_',42)]) + #assert len(O.constraints) == 2 + #add another individual with the same value for the property + sub = URIRef('individ2') + obj = URIRef('c') + O.type(sub, obj) + py.test.raises(ConsistencyFailure, O.variables['p_'].setValues, [('individ_',42),('individ2_',42)]) + + def test_Transitiveproperty(self): + from pypy.lib.pyontology.pyontology import * + O = Ontology() + #Make functional property + subreg = URIRef('subRegionOf') + obj = URIRef(namespaces['owl']+'#TransitiveProperty') + O.type(subreg, obj) + #Make class + sub = URIRef('c') + obj = URIRef(namespaces['owl']+'#Class') + O.type(sub, obj) + #Make individual with a value of the property + it = URIRef('Italy') + obj = URIRef('c') + O.type(it, obj) + tus = URIRef('Tuscanny') + O.type(tus, obj) + chi = URIRef('Chianti') + O.type(chi, obj) + # O.variables['subRegionOf_'].setValues([('Italy_','Tuscanny_'),('Tuscanny_','Chianti_')]) + O.consider_triple((tus, subreg, it)) + O.consider_triple((chi, subreg, tus)) + O.consistency() + assert Individual('Italy_', it) in O.variables['subRegionOf_'].getValuesPrKey(Individual('Chianti',chi)) + + def test_symmetricproperty(self): + from pypy.lib.pyontology.pyontology import * + O = Ontology() + #Make functional property + sub = URIRef('friend') + obj = URIRef(namespaces['owl']+'#SymmetricProperty') + O.type(sub, obj) + assert O.variables[O.make_var(None, sub)].__class__.__name__=='SymmetricProperty' + #Make class + sub = URIRef('c') + obj = URIRef(namespaces['owl']+'#Class') + O.type(sub, obj) + #Make individual with a value of the property + sub = URIRef('Bob') + obj = URIRef('c') + O.type(sub, obj) + sub = URIRef('Alice') + O.type(sub, obj) + O.variables['friend_'].setValues([('Bob_','Alice_')]) + O.consistency() + assert ('Alice_', 'Bob_') in O.variables['friend_'] + + def test_inverseof(self): + from pypy.lib.pyontology.pyontology import * + O = Ontology() + own = URIRef('owner') + obj = URIRef(namespaces['owl']+'#ObjectProperty') + O.type(own, obj) + owned = URIRef('ownedby') + obj = URIRef(namespaces['owl']+'#ObjectProperty') + O.type(owned, obj) + #Make class + sub = URIRef('c') + obj = URIRef(namespaces['owl']+'#Class') + O.type(sub, obj) + #Make individual with a property value + sub = URIRef('Bob') + obj = URIRef('c') + O.type(sub, obj) + sub = URIRef('Fiat') + obj = URIRef('car') + O.type(sub, obj) + O.variables['owner_'].setValues([('Bob_','Fiat_')]) + O.inverseOf(own, owned) + O.consistency() + assert ('Fiat_','Bob_') in O.variables['ownedby_'] + + def test_hasvalue(self): + # py.test.skip("") + from pypy.lib.pyontology.pyontology import * + O = Ontology() + cls = URIRef('class') + obj = URIRef(namespaces['owl']+'#Thing') + O.type(cls, obj) + restrict = BNode('anon1') + obj = URIRef(namespaces['owl']+'#Restriction') + O.type(restrict, obj) + p = URIRef('p') + obj = URIRef(namespaces['owl']+'#ObjectProperty') + O.type(p, obj) + O.consider_triple((cls, p, 2)) + O.onProperty(restrict,p) + O.consider_triple((cls, p, 1)) + O.hasValue(restrict, 2) + # O.type(2, URIRef(namespaces['owl']+'#Thing')) + # O.type(1, URIRef(namespaces['owl']+'#Thing')) + + cls2 = URIRef('class2') + obj = URIRef(namespaces['owl']+'#Thing') + O.type(cls2, obj) + O.subClassOf(cls2,restrict) + O.variables[O.make_var(None, cls2)].finish(O.variables, O.constraints) + O.consistency() + assert cls in O.variables[O.make_var(None, cls2)] + # py.test.raises(ConsistencyFailure, O.consistency) + + def test_List(self): + py.test.skip("Need to be rewritten using RDF-XML") + from pypy.lib.pyontology.pyontology import * + O = Ontology() + own = URIRef('favlist') + obj = URIRef(namespaces['rdf']+'#List') + O.type(own, obj) + O.first(own, 0) + O.rest(own, URIRef('1')) + O.first( URIRef('1'), 1) + O.rest( URIRef('1'), URIRef('2')) + O.first( URIRef('2'), 2) + O.rest( URIRef('2'), URIRef(namespaces['rdf']+'#nil')) + O.flatten_rdf_list(own) + O.consistency() + assert list(O.rep._domains['favlist_'].getValues()) == [0,1,2] + + def test_oneofclassenumeration(self): + from pypy.lib.pyontology.pyontology import * + O = Ontology() + restrict = BNode('anon') + own = [UR('first'), UR('second'), UR('third')] + O.oneOf(restrict, own) + O.type(restrict, UR(namespaces['owl']+'#Class')) + O.consistency() + assert O.rep._domains[restrict].size()== 3 + assert set(O.rep._domains[restrict].getValues()) == set(own) + + def test_unification_of_two_oneofclassenumeration(self): + from pypy.lib.pyontology.pyontology import * + O = Ontology() + restrict = BNode('anon') + own = [UR('first'), UR('second'), UR('third')] + for i in own: + O.type(i,UR(namespaces['owl']+'#Thing')) + O.oneOf(restrict, own) + restrict1 = BNode('anon1') + own = [UR('second'), UR('third'), UR('first')] + O.oneOf(restrict1, own) + O.type(UR('test'), UR(namespaces['owl']+'#Thing')) + O.type(UR('test'), restrict) + O.type(UR('test'), restrict1) + O.consistency() + assert O.rep._domains[restrict].size() == 3 + assert set(O.rep._domains[restrict].getValues()) == set(own) + + + def test_oneofdatarange(self): + from pypy.lib.pyontology.pyontology import * + O = Ontology() + restrict = BNode('anon') + own = ['1','2','3'] + O.oneOf(restrict, own) + O.type(restrict, UR(namespaces['owl']+'#DataRange')) + O.consistency() + assert O.rep._domains[restrict].size() == 3 + assert set(O.rep._domains[restrict].getValues()) == set(own) + + def test_somevaluesfrom_datarange(self): + py.test.skip("reconsider if the test is correct - make it simpler") + from pypy.lib.pyontology.pyontology import * + O = Ontology() + datarange = BNode('anon') + own = ['1','2','3'] + O.oneOf(datarange, own) + O.type(datarange, namespaces['owl']+'#DataRange') + restrict = BNode('anon1') + obj = URIRef(namespaces['owl']+'#Restriction') + O.type(restrict, obj) + p = URIRef('p') + obj = URIRef(namespaces['owl']+'#ObjectProperty') + O.type(p, obj) + cls = URIRef('class') + obj = URIRef(namespaces['owl']+'#Class') + O.type(cls, obj) + O.variables['p_'].setValues([(cls,'1')]) + O.onProperty(restrict,p) + O.someValuesFrom(restrict, datarange) + O.subClassOf(cls,restrict) + O.consistency() + assert cls in O.variables[O.make_var(None, cls)] + + def test_allvaluesfrom_datarange(self): + py.test.skip("") + from pypy.lib.pyontology.pyontology import * + O = Ontology() + datarange = BNode('anon') + own = ['1','2','3'] + O.oneOf(datarange, own) + O.type(datarange, namespaces['owl']+'#DataRange') + restrict = BNode('anon1') + obj = URIRef(namespaces['owl']+'#Restriction') + O.type(restrict, obj) + p = URIRef('p') + obj = URIRef(namespaces['owl']+'#ObjectProperty') + O.type(p, obj) + cls = URIRef('class') + O.variables['p_'].setValues([(cls,'1'),(cls,'2'),(cls,'3')]) + obj = URIRef(namespaces['owl']+'#Class') + O.type(cls, obj) + O.onProperty(restrict,p) + O.allValuesFrom(restrict, datarange) + O.subClassOf(cls,restrict) + assert cls in O.variables[O.make_var(None, cls)] + + def test_unionof(self): + #py.test.skip("Rewrite the test") + from pypy.lib.pyontology.pyontology import * + O = Ontology() + cls = BNode('anon') + own1 = BNode('liist1') + own2 = BNode('liist2') + list1 = ['1', '2', '3'] + list2 = ['3', '4', '5'] + own = [own1, own2] + O.oneOf( own1, list1) + O.oneOf( own2, list2) + O.unionOf(cls, own) + O.type(cls, namespaces['owl']+'#Class') + O.consistency() + res = list(O.rep._domains[cls].getValues()) + res.sort() + assert set(res) == set([Individual(x,x) for x in ['1', '2', '3', '4', '5']]) + + def test_intersectionof(self): + py.test.skip("Rewrite the test") + from pypy.lib.pyontology.pyontology import * + O = Ontology() + cls = BNode('anon') + O.intersectionOf(cls, [['1','2','3'],['3','4','5']]) + O.type(cls, namespaces['owl']+'#Class') + O.consistency() + assert list(O.rep._domains[cls].getValues()) == ['3'] + + def test_differentfrom(self): + from pypy.lib.pyontology.pyontology import * + O = Ontology() + cls = BNode('anon') + own1 = BNode('liist1') + own2 = BNode('liist2') + O.differentFrom(cls, own1) + O.differentFrom(own1, own2) + O.differentFrom(cls, own2) + O.differentFrom(own2,cls) + O.type(cls, UR(namespaces['owl']+'#Thing')) + O.type(own1, UR(namespaces['owl']+'#Thing')) + O.type(own2, UR(namespaces['owl']+'#Thing')) + O.consistency() + #assert len(O.rep._constraints) == 4 + + def test_differentfromconsistency(self): + from pypy.lib.pyontology.pyontology import * + O = Ontology() + cls = BNode('anon') + O.differentFrom(cls, cls) + O.type(cls, UR(namespaces['owl']+'#Thing')) + py.test.raises(ConsistencyFailure, O.consistency) + + def test_sameas(self): + from pypy.lib.pyontology.pyontology import * + O = Ontology() + cls = BNode('anon') + own1 = BNode('liist1') + own2 = BNode('liist2') + O.sameAs(cls, own1) + O.sameAs(own1, own2) + O.sameAs(cls, own2) + O.type(cls, UR(namespaces['owl']+'#Thing')) + O.type(own1, UR(namespaces['owl']+'#Thing')) + O.type(own2, UR(namespaces['owl']+'#Thing')) + sub = URIRef('a') + obj = URIRef(namespaces['owl']+'#ObjectProperty') + O.type(sub, obj) + O.variables[O.make_var(None,sub)].setValues([(cls,'1')]) + O.consistency() + assert ('liist1','1') in O.rep._domains[O.make_var(None,sub)] + + def test_sameasconsistency(self): + from pypy.lib.pyontology.pyontology import * + O = Ontology() + cls = BNode('anon') + own1 = BNode('liist1') + O.sameAs(cls, own1) + O.type(cls, UR(namespaces['owl']+'#Thing')) + O.type(own1, UR(namespaces['owl']+'#Thing')) + sub = URIRef('a') + obj = URIRef(namespaces['owl']+'#ObjectProperty') + O.type(sub, obj) + O.variables[O.make_var(None,sub)].setValues([(cls,'1'), (own1,'2')]) + py.test.raises(ConsistencyFailure, O.consistency) + + + def test_terminology_cardinality(self): + # Modeled after one of the standard tests (approved/maxCardinality) + # 'cls' by subclassing two maxCardinality restrictions becomes the set of + # individuals satisfying both restriction, ie having exactly 2 values of + # predicate p + from pypy.lib.pyontology.pyontology import * + cls = URIRef('cls') + O = Ontology() + O.add((cls, UR(namespaces['rdf']+'#type'), UR(namespaces['owl']+'#Class'))) + p = O.make_var(Property,URIRef('p')) + p = URIRef('p') + O.add((p, UR(namespaces['rdf']+'#type'), UR(namespaces['owl']+'#ObjectProperty'))) + + restr = BNode('anon') + O.add((restr, UR(namespaces['rdf']+'#type'), UR(namespaces['owl']+'#Restriction') )) + O.add((restr, UR(namespaces['owl']+'#onProperty'), p )) + O.add((cls, UR(namespaces['rdfs']+'#subClassOf'),restr )) + O.add((restr, UR(namespaces['owl']+'#maxCardinality'), 2 )) + + restr2 = BNode('anon2') + O.add((restr2, UR(namespaces['rdf']+'#type'), UR(namespaces['owl']+'#Restriction') )) + O.add((restr2, UR(namespaces['owl']+'#onProperty'), p )) + O.add((cls, UR(namespaces['rdfs']+'#subClassOf'),restr2 )) + O.add((restr2, UR(namespaces['owl']+'#minCardinality'), 3 )) + O.attach_fd() + for var in O.variables.values(): + var.finish(O.variables, O.constraints) + py.test.raises(ConsistencyFailure, O.consistency) + + def test_terminology_subclassof_cardinality(self): + from pypy.lib.pyontology.pyontology import * + cls = URIRef('cls') + cls2 = URIRef('cls2') + O = Ontology() + O.add((cls, UR(namespaces['rdfs']+'#type'), UR(namespaces['owl']+'#Class'))) + O.add((cls2, UR(namespaces['rdfs']+'#type'), UR(namespaces['owl']+'#Class'))) + p = O.make_var(Property,URIRef('p')) + p = URIRef('p') + O.add((p, UR(namespaces['rdfs']+'#type'), UR(namespaces['owl']+'#ObjectProperty'))) + + restr = BNode('anon') + O.add((restr, UR(namespaces['rdfs']+'#type'), UR(namespaces['owl']+'#Restriction'))) + O.add((restr, UR(namespaces['rdfs']+'#onProperty'), p )) + O.add((cls, UR(namespaces['rdfs']+'#subClassOf'),restr )) + O.add((restr, UR(namespaces['rdfs']+'#maxCardinality'), 2 )) + + restr2 = BNode('anon2') + O.add((restr2, UR(namespaces['rdfs']+'#type'), UR(namespaces['owl']+'#Restriction'))) + O.add((restr2, UR(namespaces['rdfs']+'#onProperty'), p )) + O.add((cls, UR(namespaces['rdfs']+'#subClassOf'),restr2 )) + O.add((restr2, UR(namespaces['rdfs']+'#minCardinality'), 3 )) + O.add((cls2, UR(namespaces['rdfs']+'#subClassOf'), cls )) + O.attach_fd() + for var in O.variables.values(): + var.finish(O.variables, O.constraints) + py.test.raises(ConsistencyFailure, O.consistency) + + def test_add_file(self): + from pypy.lib.pyontology.pyontology import * + O = Ontology() + O.add_file('premises001.rdf') + trip = list(O.graph.triples((None,)*3)) + # O.attach_fd() + ll = len(O.variables) + l = len(trip) + O.add_file('conclusions001.rdf') + O.attach_fd() + lll = len(O.variables) + assert len(list(O.graph.triples((None,)*3))) > l + + def test_more_cardinality(self): + from pypy.lib.pyontology.pyontology import * + O = Ontology() + O.add_file('premises003.rdf') + trip = list(O.graph.triples((None,)*3)) + # O.attach_fd() + ll = len(O.variables) + l = len(trip) + O.add_file('conclusions003.rdf') + O.attach_fd() + O.consistency() + lll = len(O.variables) + assert len(list(O.graph.triples((None,)*3))) > l + + def test_import(self): + from pypy.lib.pyontology.pyontology import * + O = Ontology() + s = URIRef('s') + O.imports(s,URIRef('http://www.w3.org/2002/03owlt/imports/support001-A')) + + def test_complementof(self): + from pypy.lib.pyontology.pyontology import * + O = Ontology() + a_cls = URIRef('a') + b_cls = URIRef('b') + O.type(a_cls, URIRef(namespaces['owl']+'#Class')) + O.type(b_cls, URIRef(namespaces['owl']+'#Class')) + O.oneOf(a_cls, [URIRef('i1'), URIRef('i2'), URIRef('i3'), URIRef('i4')]) + for i in ['i1', 'i2', 'i3', 'i4']: + O.type(URIRef(i), URIRef(namespaces['owl']+'#Thing')) + O.type(URIRef('i5'), URIRef(namespaces['owl']+'#Thing')) + O.complementOf(b_cls, a_cls) + O.consistency() + assert list(O.variables[O.make_var(None, b_cls)].getValues()) == ['i5'] + + def test_complementof_raise(self): + from pypy.lib.pyontology.pyontology import * + O = Ontology() + a_cls = URIRef('a') + b_cls = URIRef('b') + O.type(a_cls, URIRef(namespaces['owl']+'#Class')) + O.type(b_cls, URIRef(namespaces['owl']+'#Class')) + O.oneOf(a_cls, [URIRef('i1'), URIRef('i2'), URIRef('i3'), URIRef('i4')]) + for i in ['i1', 'i2', 'i3', 'i4']: + O.type(URIRef(i), URIRef(namespaces['owl']+'#Thing')) + O.type(URIRef('i5'), URIRef(namespaces['owl']+'#Thing')) + O.type(URIRef('i4'), b_cls) + O.type(URIRef('i4'), a_cls) + O.complementOf(b_cls, a_cls) + # The above ontology states that 'b' is complement of 'a'. But that leads + # to an inconsistency as 'i4' is of type 'a' and 'b' + raises(ConsistencyFailure, O.consistency) + + def test_class_promotion(self): + from pypy.lib.pyontology.pyontology import * + O = Ontology() + a_cls = URIRef('a') + O.type(a_cls, URIRef(namespaces['owl']+'#Class')) + + assert isinstance(O.variables['a_'], ClassDomain) + O.type(a_cls, URIRef(namespaces['owl']+'#Restriction')) + assert isinstance(O.variables['a_'], Restriction) + + def test_class_demotion(self): + from pypy.lib.pyontology.pyontology import * + O = Ontology() + a_cls = URIRef('a') + O.type(a_cls, URIRef(namespaces['owl']+'#Restriction')) + O.variables[O.make_var(None, a_cls)].property = "SomeProp" + assert isinstance(O.variables['a_'], Restriction) + + O.type(a_cls, URIRef(namespaces['owl']+'#Class')) + + assert isinstance(O.variables['a_'], Restriction) + assert O.variables[O.make_var(None, a_cls)].property == "SomeProp" + + def test_property_to_objectproperty(self): + from pypy.lib.pyontology.pyontology import * + O = Ontology() + a_cls = URIRef('a') + O.type(a_cls, URIRef(namespaces['rdf']+'#Property')) + assert isinstance(O.variables['a_'], Property) + O.type(a_cls, URIRef(namespaces['owl']+'#ObjectProperty')) + assert isinstance(O.variables['a_'], Property) + + O.type(a_cls, URIRef(namespaces['rdf']+'#Property')) + + assert isinstance(O.variables['a_'], ObjectProperty) + + def test_individual(self): + # test comparison (unknown, equal, different) + from pypy.lib.pyontology.pyontology import * + O = Ontology() + first = URIRef('first') + second = URIRef('second') + O.type(first, URIRef(namespaces['owl']+'#Thing')) + assert isinstance(list(O.variables['owl_Thing'].getValues())[0], Individual) + + def test_recording_of_properties(self): + from pypy.lib.pyontology.pyontology import * + O = Ontology() + first = URIRef('first') + second = URIRef('second') + # O.type(first, URIRef(namespaces['owl']+'#SymmetricProperty')) + O.consider_triple((first, URIRef(namespaces['rdf']+'#type'), URIRef(namespaces['owl']+'#SymmetricProperty'))) + assert isinstance(O.variables['first_'], SymmetricProperty) + assert 'first_' in O.variables['owl_ObjectProperty'] #.getValues() + assert 'first_' in O.variables['rdf_Property'] # .getValues() Modified: pypy/branch/ast-experiments/pypy/module/_stackless/interp_greenlet.py ============================================================================== --- pypy/branch/ast-experiments/pypy/module/_stackless/interp_greenlet.py (original) +++ pypy/branch/ast-experiments/pypy/module/_stackless/interp_greenlet.py Mon Feb 26 08:45:45 2007 @@ -73,16 +73,12 @@ _get_state = staticmethod(_get_state) def hello(self): - print "hello ", id(self), self.subctx.framestack.items - print syncstate.things_to_do, syncstate.temp_exc ec = self.space.getexecutioncontext() self.subctx.enter(ec) def goodbye(self): ec = self.space.getexecutioncontext() self.subctx.leave(ec) - print "goodbye", id(self), self.subctx.framestack.items - print syncstate.things_to_do, syncstate.temp_exc def w_getcurrent(space): return space.wrap(AppGreenlet._get_state(space).current) Modified: pypy/branch/ast-experiments/pypy/module/crypt/interp_crypt.py ============================================================================== --- pypy/branch/ast-experiments/pypy/module/crypt/interp_crypt.py (original) +++ pypy/branch/ast-experiments/pypy/module/crypt/interp_crypt.py Mon Feb 26 08:45:45 2007 @@ -8,10 +8,16 @@ class CConfig: _includes_ = ('unistd.h',) - cryptlib = ctypes_platform.Library('crypt') + if sys.platform != 'darwin': + cryptlib = ctypes_platform.Library('crypt') globals().update(ctypes_platform.configure(CConfig)) +if sys.platform == 'darwin': + dllname = find_library('c') + assert dllname is not None + cryptlib = cdll.LoadLibrary(dllname) + c_crypt = cryptlib.crypt c_crypt.argtypes = [c_char_p, c_char_p] c_crypt.restype = c_char_p Modified: pypy/branch/ast-experiments/pypy/module/sys/version.py ============================================================================== --- pypy/branch/ast-experiments/pypy/module/sys/version.py (original) +++ pypy/branch/ast-experiments/pypy/module/sys/version.py Mon Feb 26 08:45:45 2007 @@ -8,10 +8,12 @@ CPYTHON_VERSION = (2, 4, 1, "alpha", 42) CPYTHON_API_VERSION = 1012 -PYPY_VERSION = (0, 9, 0, "alpha", '?') +PYPY_VERSION = (0, 99, 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] +SVN_URL = "$HeadURL$"[10:-28] + +REV = "$LastChangedRevision$"[22:-2] # ____________________________________________________________ @@ -62,7 +64,7 @@ "Return the last-changed svn revision number." # NB. we hack the number directly out of the .svn directory to avoid # to depend on an external 'svn' executable in the path. - rev = 0 + rev = int(REV) try: f = open(os.path.join(autopath.pypydir, '.svn', 'format'), 'r') format = int(f.readline().strip()) Modified: pypy/branch/ast-experiments/pypy/objspace/std/stringobject.py ============================================================================== --- pypy/branch/ast-experiments/pypy/objspace/std/stringobject.py (original) +++ pypy/branch/ast-experiments/pypy/objspace/std/stringobject.py Mon Feb 26 08:45:45 2007 @@ -647,7 +647,6 @@ # cannot return w_self, in case it is a subclass of str return space.wrap(input) - result = [] buf = [' '] * width if len(input) > 0 and (input[0] == '+' or input[0] == '-'): buf[0] = input[0] Modified: pypy/branch/ast-experiments/pypy/objspace/taint.py ============================================================================== --- pypy/branch/ast-experiments/pypy/objspace/taint.py (original) +++ pypy/branch/ast-experiments/pypy/objspace/taint.py Mon Feb 26 08:45:45 2007 @@ -129,7 +129,7 @@ unwrap_spec=[gateway.ObjSpace, gateway.W_Root, 'args_w']) def taint_atomic(space, w_callable): - meth = Method(space, space.wrap(app_taint_atomic_function), + meth = Method(space, space.w_fn_taint_atomic_function, w_callable, space.type(w_callable)) return space.wrap(meth) app_taint_atomic = gateway.interp2app(taint_atomic) @@ -194,6 +194,7 @@ self.wrap(app_is_tainted)) self.setattr(w_pypymagic, self.wrap('untaint'), self.wrap(app_untaint)) + self.w_fn_taint_atomic_function = self.wrap(app_taint_atomic_function) self.setattr(w_pypymagic, self.wrap('taint_atomic'), self.wrap(app_taint_atomic)) self.setattr(w_pypymagic, self.wrap('TaintError'), Modified: pypy/branch/ast-experiments/pypy/objspace/thunk.py ============================================================================== --- pypy/branch/ast-experiments/pypy/objspace/thunk.py (original) +++ pypy/branch/ast-experiments/pypy/objspace/thunk.py Mon Feb 26 08:45:45 2007 @@ -97,7 +97,7 @@ app_become = gateway.interp2app(become) def lazy(space, w_callable): - meth = Method(space, space.wrap(app_thunk), + meth = Method(space, space.w_fn_thunk, w_callable, space.type(w_callable)) return space.wrap(meth) app_lazy = gateway.interp2app(lazy) @@ -173,8 +173,9 @@ space = std.Space(*args, **kwds) patch_space_in_place(space, 'thunk', proxymaker) w_pypymagic = space.getbuiltinmodule("pypymagic") + space.w_fn_thunk = space.wrap(app_thunk) space.setattr(w_pypymagic, space.wrap('thunk'), - space.wrap(app_thunk)) + space.w_fn_thunk) space.setattr(w_pypymagic, space.wrap('is_thunk'), space.wrap(app_is_thunk)) space.setattr(w_pypymagic, space.wrap('become'), Modified: pypy/branch/ast-experiments/pypy/rpython/extfunc.py ============================================================================== --- pypy/branch/ast-experiments/pypy/rpython/extfunc.py (original) +++ pypy/branch/ast-experiments/pypy/rpython/extfunc.py Mon Feb 26 08:45:45 2007 @@ -68,3 +68,11 @@ FunEntry.__name__ = export_name else: FunEntry.__name__ = function.func_name + +def is_external(func): + if getattr(func.value._callable, 'suggested_primitive', False): + return True + if hasattr(func.value, '_entry'): + if isinstance(func.value._entry, ExtFuncEntry): + return True + return False Modified: pypy/branch/ast-experiments/pypy/rpython/lltypesystem/lltype.py ============================================================================== --- pypy/branch/ast-experiments/pypy/rpython/lltypesystem/lltype.py (original) +++ pypy/branch/ast-experiments/pypy/rpython/lltypesystem/lltype.py Mon Feb 26 08:45:45 2007 @@ -643,6 +643,11 @@ return Void # maybe if tp is int: return Signed + if tp is long: + if -maxint-1 <= val <= maxint: + return Signed + else: + return SignedLongLong if tp is bool: return Bool if issubclass(tp, base_int): Modified: pypy/branch/ast-experiments/pypy/rpython/memory/gctransform/framework.py ============================================================================== --- pypy/branch/ast-experiments/pypy/rpython/memory/gctransform/framework.py (original) +++ pypy/branch/ast-experiments/pypy/rpython/memory/gctransform/framework.py Mon Feb 26 08:45:45 2007 @@ -146,19 +146,36 @@ self.frameworkgc_setup_ptr = getfn(frameworkgc_setup, [], annmodel.s_None) - if StackRootIterator.push_root is None: - self.push_root_ptr = None - else: + if StackRootIterator.need_root_stack: + self.pop_root_ptr = getfn(StackRootIterator.pop_root, [], + annmodel.s_None, + inline = True) self.push_root_ptr = getfn(StackRootIterator.push_root, [annmodel.SomeAddress()], annmodel.s_None, inline = True) - if StackRootIterator.pop_root is None: - self.pop_root_ptr = None + self.incr_stack_ptr = getfn(StackRootIterator.incr_stack, + [annmodel.SomeInteger()], + annmodel.SomeAddress(), + inline = True) + self.decr_stack_ptr = getfn(StackRootIterator.decr_stack, + [annmodel.SomeInteger()], + annmodel.s_None, + inline = True) + self.save_addr_ptr = getfn(StackRootIterator.save_addr, + [annmodel.SomeAddress(), + annmodel.SomeInteger(), + annmodel.SomeAddress()], + annmodel.s_None, + inline = True) else: - self.pop_root_ptr = getfn(StackRootIterator.pop_root, [], - annmodel.s_None, - inline = True) + self.push_root_ptr = None + self.pop_root_ptr = None + self.incr_stack_ptr = None + self.decr_stack_ptr = None + self.save_addr_ptr = None + + classdef = bk.getuniqueclassdef(GCClass) s_gc = annmodel.SomeInstance(classdef) @@ -243,6 +260,22 @@ i += 1 setup_root_stack = staticmethod(setup_root_stack) + need_root_stack = True + + def incr_stack(n): + top = gcdata.root_stack_top + gcdata.root_stack_top = top + n*sizeofaddr + return top + incr_stack = staticmethod(incr_stack) + + def save_addr(top, k, addr): + top.address[k] = addr + save_addr = staticmethod(save_addr) + + def decr_stack(n): + gcdata.root_stack_top -= n*sizeofaddr + decr_stack = staticmethod(decr_stack) + def push_root(addr): top = gcdata.root_stack_top top.address[0] = addr @@ -554,18 +587,24 @@ if self.push_root_ptr is None: return livevars = [var for var in self.livevars if not var_ispyobj(var)] - for var in livevars: + c_len = rmodel.inputconst(lltype.Signed, len(livevars) ) + base_addr = hop.genop("direct_call", [self.incr_stack_ptr, c_len ], + resulttype=llmemory.Address) + for k,var in enumerate(livevars): + c_k = rmodel.inputconst(lltype.Signed, k) v_adr = gen_cast(hop.llops, llmemory.Address, var) - hop.genop("direct_call", [self.push_root_ptr, v_adr]) + hop.genop("direct_call", [self.save_addr_ptr, base_addr, c_k, v_adr]) def pop_roots(self, hop): if self.pop_root_ptr is None: return livevars = [var for var in self.livevars if not var_ispyobj(var)] - for var in livevars[::-1]: - # XXX specific to non-moving collectors - hop.genop("direct_call", [self.pop_root_ptr]) - #hop.genop("gc_reload_possibly_moved", [var]) + c_len = rmodel.inputconst(lltype.Signed, len(livevars) ) + hop.genop("direct_call", [self.decr_stack_ptr, c_len ] ) +## for var in livevars[::-1]: +## # XXX specific to non-moving collectors +## hop.genop("direct_call", [self.pop_root_ptr]) +## #hop.genop("gc_reload_possibly_moved", [var]) # XXX copied and modified from lltypelayout.py def offsets_to_gc_pointers(TYPE): Modified: pypy/branch/ast-experiments/pypy/rpython/memory/gctransform/stacklessframework.py ============================================================================== --- pypy/branch/ast-experiments/pypy/rpython/memory/gctransform/stacklessframework.py (original) +++ pypy/branch/ast-experiments/pypy/rpython/memory/gctransform/stacklessframework.py Mon Feb 26 08:45:45 2007 @@ -61,8 +61,7 @@ pass setup_root_stack = staticmethod(setup_root_stack) - push_root = None - pop_root = None + need_root_stack = False def __init__(self): frame = llmemory.cast_ptr_to_adr(stack_capture()) Modified: pypy/branch/ast-experiments/pypy/rpython/rfloat.py ============================================================================== --- pypy/branch/ast-experiments/pypy/rpython/rfloat.py (original) +++ pypy/branch/ast-experiments/pypy/rpython/rfloat.py Mon Feb 26 08:45:45 2007 @@ -110,6 +110,10 @@ def get_ll_eq_function(self): return None + get_ll_gt_function = get_ll_eq_function + get_ll_lt_function = get_ll_eq_function + get_ll_ge_function = get_ll_eq_function + get_ll_le_function = get_ll_eq_function def get_ll_hash_function(self): return ll_hash_float Modified: pypy/branch/ast-experiments/pypy/rpython/rint.py ============================================================================== --- pypy/branch/ast-experiments/pypy/rpython/rint.py (original) +++ pypy/branch/ast-experiments/pypy/rpython/rint.py Mon Feb 26 08:45:45 2007 @@ -222,6 +222,13 @@ raise TyperError("not an integer: %r" % (value,)) def get_ll_eq_function(self): + return None + get_ll_gt_function = get_ll_eq_function + get_ll_lt_function = get_ll_eq_function + get_ll_ge_function = get_ll_eq_function + get_ll_le_function = get_ll_eq_function + + def get_ll_ge_function(self): return None def get_ll_hash_function(self): Modified: pypy/branch/ast-experiments/pypy/rpython/rmodel.py ============================================================================== --- pypy/branch/ast-experiments/pypy/rpython/rmodel.py (original) +++ pypy/branch/ast-experiments/pypy/rpython/rmodel.py Mon Feb 26 08:45:45 2007 @@ -272,6 +272,9 @@ v_iter, = hop.inputargs(self) return v_iter + def rtype_method_next(self, hop): + return self.rtype_next(hop) + class __extend__(annmodel.SomeIterator): # NOTE: SomeIterator is for iterators over any container, not just list Modified: pypy/branch/ast-experiments/pypy/rpython/rtuple.py ============================================================================== --- pypy/branch/ast-experiments/pypy/rpython/rtuple.py (original) +++ pypy/branch/ast-experiments/pypy/rpython/rtuple.py Mon Feb 26 08:45:45 2007 @@ -22,6 +22,7 @@ _gen_eq_function_cache = {} +_gen_cmp_function_cache = {} _gen_hash_function_cache = {} _gen_str_function_cache = {} @@ -46,6 +47,49 @@ _gen_eq_function_cache[key] = ll_eq return ll_eq +import os +def gen_cmp_function(items_r, op_funcs, eq_funcs, strict): + """generates <= and >= comparison ll_op for tuples + cmp_funcs is a tuple of (strict_comp, equality) functions + works for != with strict==True + """ + cmp_funcs = zip(op_funcs,eq_funcs) + autounrolling_funclist = unrolling_iterable(enumerate(cmp_funcs)) + key = tuple(cmp_funcs), strict + try: + return _gen_cmp_function_cache[key] + except KeyError: + def ll_cmp(t1, t2): + cmp_res = True + for i, (cmpfn, eqfn) in autounrolling_funclist: + attrname = 'item%d' % i + item1 = getattr(t1, attrname) + item2 = getattr(t2, attrname) + cmp_res = cmpfn(item1, item2) + if cmp_res: + # a strict compare is true we shortcut + return True + eq_res = eqfn(item1, item2) + if not eq_res: + # not strict and not equal we fail + return False + # Everything's equal here + if strict: + return False + else: + return True + _gen_cmp_function_cache[key] = ll_cmp + return ll_cmp + +def gen_gt_function(items_r, strict): + gt_funcs = [r_item.get_ll_gt_function() or operator.gt for r_item in items_r] + eq_funcs = [r_item.get_ll_eq_function() or operator.eq for r_item in items_r] + return gen_cmp_function( items_r, gt_funcs, eq_funcs, strict ) + +def gen_lt_function(items_r, strict): + lt_funcs = [r_item.get_ll_lt_function() or operator.lt for r_item in items_r] + eq_funcs = [r_item.get_ll_eq_function() or operator.eq for r_item in items_r] + return gen_cmp_function( items_r, lt_funcs, eq_funcs, strict ) def gen_hash_function(items_r): # based on CPython @@ -166,8 +210,20 @@ def get_ll_eq_function(self): return gen_eq_function(self.items_r) + def get_ll_ge_function(self): + return gen_gt_function(self.items_r, False) + + def get_ll_gt_function(self): + return gen_gt_function(self.items_r, True) + + def get_ll_le_function(self): + return gen_lt_function(self.items_r, False) + + def get_ll_lt_function(self): + return gen_lt_function(self.items_r, True) + def get_ll_hash_function(self): - return gen_hash_function(self.items_r) + return gen_hash_function(self.items_r) ll_str = property(gen_str_function) @@ -241,6 +297,30 @@ ll_eq = r_tup1.get_ll_eq_function() return hop.gendirectcall(ll_eq, v_tuple1, v_tuple2) + def rtype_ge((r_tup1, r_tup2), hop): + # XXX assumes that r_tup2 is convertible to r_tup1 + v_tuple1, v_tuple2 = hop.inputargs(r_tup1, r_tup1) + ll_ge = r_tup1.get_ll_ge_function() + return hop.gendirectcall(ll_ge, v_tuple1, v_tuple2) + + def rtype_gt((r_tup1, r_tup2), hop): + # XXX assumes that r_tup2 is convertible to r_tup1 + v_tuple1, v_tuple2 = hop.inputargs(r_tup1, r_tup1) + ll_gt = r_tup1.get_ll_gt_function() + return hop.gendirectcall(ll_gt, v_tuple1, v_tuple2) + + def rtype_le((r_tup1, r_tup2), hop): + # XXX assumes that r_tup2 is convertible to r_tup1 + v_tuple1, v_tuple2 = hop.inputargs(r_tup1, r_tup1) + ll_le = r_tup1.get_ll_le_function() + return hop.gendirectcall(ll_le, v_tuple1, v_tuple2) + + def rtype_lt((r_tup1, r_tup2), hop): + # XXX assumes that r_tup2 is convertible to r_tup1 + v_tuple1, v_tuple2 = hop.inputargs(r_tup1, r_tup1) + ll_lt = r_tup1.get_ll_lt_function() + return hop.gendirectcall(ll_lt, v_tuple1, v_tuple2) + def rtype_ne(tup1tup2, hop): v_res = tup1tup2.rtype_eq(hop) return hop.genop('bool_not', [v_res], resulttype=Bool) Modified: pypy/branch/ast-experiments/pypy/rpython/test/test_rlist.py ============================================================================== --- pypy/branch/ast-experiments/pypy/rpython/test/test_rlist.py (original) +++ pypy/branch/ast-experiments/pypy/rpython/test/test_rlist.py Mon Feb 26 08:45:45 2007 @@ -283,6 +283,35 @@ res = self.interpret(dummyfn, []) assert res == 25 + def test_iterate_next(self): + def dummyfn(): + total = 0 + it = iter([1, 3, 5, 7, 9]) + while 1: + try: + x = it.next() + except StopIteration: + break + total += x + return total + res = self.interpret(dummyfn, []) + assert res == 25 + def dummyfn(): + total = 0 + l = [1, 3, 5, 7] + l.append(9) + it = iter(l) + while 1: + try: + x = it.next() + except StopIteration: + break + total += x + return total + res = self.interpret(dummyfn, []) + assert res == 25 + + def test_recursive(self): def dummyfn(N): l = [] Modified: pypy/branch/ast-experiments/pypy/rpython/test/test_rtuple.py ============================================================================== --- pypy/branch/ast-experiments/pypy/rpython/test/test_rtuple.py (original) +++ pypy/branch/ast-experiments/pypy/rpython/test/test_rtuple.py Mon Feb 26 08:45:45 2007 @@ -280,6 +280,51 @@ res = self.interpret(f, [2]) assert res is True + TUPLES = [ + ((1,2), (2,3), -1), + ((1,2), (1,3), -1), + ((1,2), (1,1), 1), + ((1,2), (1,2), 0), + ((1.,2.),(2.,3.), -1), + ((1.,2.),(1.,3.), -1), + ((1.,2.),(1.,1.), 1), + ((1.,2.),(1.,2.), 0), + ((1,2.),(2,3.), -1), + ((1,2.),(1,3.), -1), + ((1,2.),(1,1.), 1), + ((1,2.),(1,2.), 0), +## ((1,"def"),(1,"abc"), -1), +## ((1.,"abc"),(1.,"abc"), 0), + ] + + def test_tuple_comparison(self): + def f_lt( a, b, c, d ): + return (a,b) < (c,d) + def f_le( a, b, c, d ): + return (a,b) <= (c,d) + def f_gt( a, b, c, d ): + return (a,b) > (c,d) + def f_ge( a, b, c, d ): + return (a,b) >= (c,d) + def test_lt( a,b,c,d,resu ): + res = self.interpret(f_lt,[a,b,c,d]) + assert res == (resu == -1), "Error (%s,%s)<(%s,%s) is %s(%s)" % (a,b,c,d,res,resu) + def test_le( a,b,c,d,resu ): + res = self.interpret(f_le,[a,b,c,d]) + assert res == (resu <= 0), "Error (%s,%s)<=(%s,%s) is %s(%s)" % (a,b,c,d,res,resu) + def test_gt( a,b,c,d,resu ): + res = self.interpret(f_gt,[a,b,c,d]) + assert res == ( resu == 1 ), "Error (%s,%s)>(%s,%s) is %s(%s)" % (a,b,c,d,res,resu) + def test_ge( a,b,c,d,resu ): + res = self.interpret(f_ge,[a,b,c,d]) + assert res == ( resu >= 0 ), "Error (%s,%s)>=(%s,%s) is %s(%s)" % (a,b,c,d,res,resu) + + for (a,b),(c,d),resu in self.TUPLES: + yield test_lt, a,b,c,d, resu + yield test_gt, a,b,c,d, resu + yield test_le, a,b,c,d, resu + yield test_ge, a,b,c,d, resu + def test_tuple_hash(self): def f(n): return hash((n, 6)) == hash((3, n*2)) Modified: pypy/branch/ast-experiments/pypy/tool/build/build.py ============================================================================== --- pypy/branch/ast-experiments/pypy/tool/build/build.py (original) +++ pypy/branch/ast-experiments/pypy/tool/build/build.py Mon Feb 26 08:45:45 2007 @@ -167,3 +167,9 @@ return (self.normalized_rev >= comparerev - self.revrange and self.normalized_rev <= comparerev + self.revrange) + def __eq__(self, other): + return isinstance(other, self.__class__) and repr(self) == repr(other) + + def __ne__(self, other): + return not self.__eq__(other) + Modified: pypy/branch/ast-experiments/pypy/tool/build/metaserver.py ============================================================================== --- pypy/branch/ast-experiments/pypy/tool/build/metaserver.py (original) +++ pypy/branch/ast-experiments/pypy/tool/build/metaserver.py Mon Feb 26 08:45:45 2007 @@ -169,6 +169,14 @@ finally: self._queuelock.release() + def status(self): + # XXX temporary + in_progress = len([b for b in self._builders if b.busy_on]) + return {'in_progress': in_progress, + 'queued': len(self._queued), + 'waiting': len(self._waiting), + 'done': len(self._done)} + def _cleanup_builders(self): self._queuelock.acquire() try: Modified: pypy/branch/ast-experiments/pypy/tool/build/test/test_metaserver.py ============================================================================== --- pypy/branch/ast-experiments/pypy/tool/build/test/test_metaserver.py (original) +++ pypy/branch/ast-experiments/pypy/tool/build/test/test_metaserver.py Mon Feb 26 08:45:45 2007 @@ -157,3 +157,23 @@ assert not bp1.check() assert bp2.check() +def test_status(): + return + temppath = py.test.ensuretemp('test_status') + config = Container(projectname='test', buildpath=temppath) + svr = metaserver.MetaServer(config, FakeChannel()) + svr._done.append('y') + svr._done.append('z') + svr._queued.append('spam') + svr._queued.append('spam') + svr._queued.append('eggs') + bs = FakeBuildserver({}) + bs.busy_on = 'foo' + svr._builders.append(bs) + assert svr.status() == { + 'done': 2, + 'queued': 3, + 'waiting': 0, + 'in_progress': 1, + } + Modified: pypy/branch/ast-experiments/pypy/tool/makerelease.py ============================================================================== --- pypy/branch/ast-experiments/pypy/tool/makerelease.py (original) +++ pypy/branch/ast-experiments/pypy/tool/makerelease.py Mon Feb 26 08:45:45 2007 @@ -1,15 +1,17 @@ - +import autopath import py log = py.log.Producer("log") logexec = py.log.Producer("exec") -BASEURL = "file:///svn/pypy/release/0.9.x" +import os + +BASEURL = "file:///svn/pypy/release/0.99.x" DDIR = py.path.local('/www/codespeak.net/htdocs/download/pypy') def usage(): - print "usage: %s versionbasename" %(py.std.sys.argv[0]) + print "usage: %s [-tag .] versionbasename" %(py.std.sys.argv[0]) raise SystemExit, 1 def cexec(cmd): @@ -70,16 +72,46 @@ %(lineend, BASEURL, target)) assert target.check(dir=1) +def build_html(target): + docdir = target.join('pypy').join('doc') + old = docdir.chdir() + try: + # Generate the html files. + cmd = "python2.4 ../test_all.py" + logexec(cmd) + r = os.system(cmd) + if r: + raise SystemExit, -1 + # Remove any .pyc files created in the process + target.chdir() + out = cexec("find . -name '*.pyc' -print0 | xargs -0 -r rm") + finally: + old.chdir() + if __name__ == '__main__': argc = len(py.std.sys.argv) if argc <= 1: usage() - ver = py.std.sys.argv[1] + + j = 1 + if py.std.sys.argv[1] == '-tag': + micro = py.std.sys.argv[2] + assert micro.startswith('.') + NEWURL = BASEURL.replace('.x', micro) + r = os.system("svn cp %s %s" % (BASEURL, NEWURL)) + if r: + raise SystemExit, -1 + BASEURL = NEWURL + j = 3 + + ver = py.std.sys.argv[j] + assert ver.startswith('pypy-') tmpdir = py.path.local("/tmp/pypy-release") target = tmpdir.join(ver) forced_export(BASEURL, target, lineend="LF") + build_html(target) target_targz = maketargz(target) assert target_targz.check(file=1) copydownload(target_targz) @@ -89,6 +121,7 @@ copydownload(target_tarbzip) forced_export(BASEURL, target, lineend="CRLF") + build_html(target) target_zip = makezip(target) assert target_zip.check(file=1) copydownload(target_zip) Modified: pypy/branch/ast-experiments/pypy/tool/option.py ============================================================================== --- pypy/branch/ast-experiments/pypy/tool/option.py (original) +++ pypy/branch/ast-experiments/pypy/tool/option.py Mon Feb 26 08:45:45 2007 @@ -5,13 +5,17 @@ from pypy.config.config import Config, OptionDescription, to_optparse from py.compat import optparse +extra_useage = """For detailed descriptions of all the options see +http://codespeak.net/pypy/dist/pypy/doc/config/commandline.html""" + def run_tb_server(option, opt, value, parser): from pypy.tool import tb_server tb_server.start() def get_standard_options(): config = get_pypy_config() - parser = to_optparse(config, useoptions=["objspace.*"]) + parser = to_optparse(config, useoptions=["objspace.*"], + extra_useage=extra_useage) parser.add_option( '-H', action="callback", callback=run_tb_server, Modified: pypy/branch/ast-experiments/pypy/tool/statistic_over_time.py ============================================================================== --- pypy/branch/ast-experiments/pypy/tool/statistic_over_time.py (original) +++ pypy/branch/ast-experiments/pypy/tool/statistic_over_time.py Mon Feb 26 08:45:45 2007 @@ -3,11 +3,6 @@ import datetime import time -try: - path = py.path.svnwc(py.std.sys.argv[1]) -except IndexError: - path = py.path.svnwc() - URL = "http://codespeak.net/svn/pypy/dist" tempdir = py.path.svnwc(py.test.ensuretemp("pypy-dist")) Modified: pypy/branch/ast-experiments/pypy/translator/c/src/signals.h ============================================================================== --- pypy/branch/ast-experiments/pypy/translator/c/src/signals.h (original) +++ pypy/branch/ast-experiments/pypy/translator/c/src/signals.h Mon Feb 26 08:45:45 2007 @@ -54,12 +54,30 @@ void pypysig_ignore(int signum) { +#ifdef SA_RESTART + /* assume sigaction exists */ + struct sigaction context; + context.sa_handler = SIG_IGN; + sigemptyset(&context.sa_mask); + context.sa_flags = 0; + sigaction(signum, &context, NULL); +#else signal(signum, SIG_IGN); +#endif } void pypysig_default(int signum) { +#ifdef SA_RESTART + /* assume sigaction exists */ + struct sigaction context; + context.sa_handler = SIG_DFL; + sigemptyset(&context.sa_mask); + context.sa_flags = 0; + sigaction(signum, &context, NULL); +#else signal(signum, SIG_DFL); +#endif } static void signal_setflag_handler(int signum) @@ -71,7 +89,16 @@ void pypysig_setflag(int signum) { +#ifdef SA_RESTART + /* assume sigaction exists */ + struct sigaction context; + context.sa_handler = signal_setflag_handler; + sigemptyset(&context.sa_mask); + context.sa_flags = 0; + sigaction(signum, &context, NULL); +#else signal(signum, signal_setflag_handler); +#endif } int pypysig_poll(void) Modified: pypy/branch/ast-experiments/pypy/translator/cli/test/runtest.py ============================================================================== --- pypy/branch/ast-experiments/pypy/translator/cli/test/runtest.py (original) +++ pypy/branch/ast-experiments/pypy/translator/cli/test/runtest.py Mon Feb 26 08:45:45 2007 @@ -251,9 +251,9 @@ if self._func is fn and self._ann == ann: return self._cli_func else: + self._cli_func = compile_function(fn, ann) self._func = fn self._ann = ann - self._cli_func = compile_function(fn, ann) return self._cli_func def _skip_win(self, reason): Modified: pypy/branch/ast-experiments/pypy/translator/goal/app_main.py ============================================================================== --- pypy/branch/ast-experiments/pypy/translator/goal/app_main.py (original) +++ pypy/branch/ast-experiments/pypy/translator/goal/app_main.py Mon Feb 26 08:45:45 2007 @@ -6,6 +6,7 @@ -i inspect interactively after running script -O dummy optimization flag for compatibility with C Python -c CMD program passed in as CMD (terminates option list) + -S do not 'import site' on initialization -u unbuffered binary stdout and stderr -h, --help show this help message and exit --version print the PyPy version @@ -172,6 +173,7 @@ go_interactive = False run_command = False + import_site = True i = 0 while i < len(argv): arg = argv[i] @@ -198,6 +200,8 @@ elif arg == '-h' or arg == '--help': print_help() return 0 + elif arg == '-S': + import_site = False elif arg == '--': i += 1 break # terminates option list @@ -214,6 +218,13 @@ mainmodule = type(sys)('__main__') sys.modules['__main__'] = mainmodule + if import_site: + try: + import site + except: + print >> sys.stderr, "import site' failed" + + # set up the Ctrl-C => KeyboardInterrupt signal handler, if the # signal module is available try: Modified: pypy/branch/ast-experiments/pypy/translator/goal/bench-cronjob.py ============================================================================== --- pypy/branch/ast-experiments/pypy/translator/goal/bench-cronjob.py (original) +++ pypy/branch/ast-experiments/pypy/translator/goal/bench-cronjob.py Mon Feb 26 08:45:45 2007 @@ -169,18 +169,18 @@ def main(backends=[]): if backends == []: #_ prefix means target specific option, # prefix to outcomment backends = [backend.strip() for backend in """ - llvm--_objspace-std-withstrdict + llvm--_objspace-std-withmultidict llvm--_objspace-opcodes-CALL_LIKELY_BUILTIN c c--gc=framework - c--thread--_objspace-std-withstrdict--profopt='-c "from richards import *;main(iterations=1)"' + c--thread--_objspace-std-withmultidict--profopt='-c "from richards import *;main(iterations=1)"' c--stackless c--stackless--profopt='-c "from richards import *;main(iterations=1)"' - c--stackless--_objspace-std-withstrdict--profopt='-c "from richards import *;main(iterations=1)"' + c--stackless--_objspace-std-withmultidict--profopt='-c "from richards import *;main(iterations=1)"' c--profopt='-c "from richards import *;main(iterations=1)"' c--profopt='-c "from richards import *;main(iterations=1)"'--_objspace-opcodes-CALL_LIKELY_BUILTIN - c--_objspace-std-withstrdict--profopt='-c "from richards import *;main(iterations=1)"' - c--gc=framework--_objspace-std-withstrdict--profopt='-c "from richards import *;main(iterations=1)"' + c--_objspace-std-withmultidict--profopt='-c "from richards import *;main(iterations=1)"' + c--gc=framework--_objspace-std-withmultidict--profopt='-c "from richards import *;main(iterations=1)"' cli """.split('\n') if backend.strip() and not backend.strip().startswith('#')] print time.ctime() Modified: pypy/branch/ast-experiments/pypy/translator/goal/targetjsstandalone.py ============================================================================== --- pypy/branch/ast-experiments/pypy/translator/goal/targetjsstandalone.py (original) +++ pypy/branch/ast-experiments/pypy/translator/goal/targetjsstandalone.py Mon Feb 26 08:45:45 2007 @@ -4,7 +4,6 @@ import sys from pypy.rlib.streamio import open_file_as_stream -from pypy.lang.js.interpreter import Interpreter from pypy.lang.js.interpreter import * from pypy.lang.js.jsobj import ExecutionReturned Modified: pypy/branch/ast-experiments/pypy/translator/goal/translate.py ============================================================================== --- pypy/branch/ast-experiments/pypy/translator/goal/translate.py (original) +++ pypy/branch/ast-experiments/pypy/translator/goal/translate.py Mon Feb 26 08:45:45 2007 @@ -166,6 +166,8 @@ if 'print_help' in targetspec_dic: print "\n\nTarget specific help:\n\n" targetspec_dic['print_help'](config) + print "\n\nFor detailed descriptions of the command line options see" + print "http://codespeak.net/pypy/dist/pypy/doc/config/commandline.html" sys.exit(0) return targetspec_dic, translateconfig, config, args Modified: pypy/branch/ast-experiments/pypy/translator/js/commproxy.py ============================================================================== --- pypy/branch/ast-experiments/pypy/translator/js/commproxy.py (original) +++ pypy/branch/ast-experiments/pypy/translator/js/commproxy.py Mon Feb 26 08:45:45 2007 @@ -14,17 +14,15 @@ str = "" for(i in data) { if (data[i]) { - if (str.length == 0) { - str += "?"; - } else { + if (str.length != 0) { str += "&"; } - str += i + "=" + data[i].toString(); + str += escape(i) + "=" + escape(data[i].toString()); } } //logDebug('%(call)s'+str); x.open("GET", '%(call)s' + str, true); - //x.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); + x.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); x.onreadystatechange = function () { %(real_callback)s(x, callback) }; //x.setRequestHeader("Connection", "close"); //x.send(data); @@ -45,7 +43,7 @@ } else { str += "&"; } - str += i + "=" + data[i].toString(); + str += escape(i) + "=" + escape(data[i].toString()); } } //logDebug('%(call)s'+str); @@ -131,6 +129,8 @@ METHOD_BODY = globals()[self.method + "_METHOD_BODY"] if USE_MOCHIKIT and self.use_xml: assert 0, "Cannot use mochikit and xml requests at the same time" + if USE_MOCHIKIT and self.method == "POST": + assert 0, "Cannot use mochikit with POST method" if USE_MOCHIKIT: ilasm.codegenerator.write(MOCHIKIT_BODY % {'class':self.name, 'method':url,\ 'args':','.join(real_args), 'data':data, 'call':method_name}) Modified: pypy/branch/ast-experiments/pypy/translator/js/examples/bnb/bnb.py ============================================================================== --- pypy/branch/ast-experiments/pypy/translator/js/examples/bnb/bnb.py (original) +++ pypy/branch/ast-experiments/pypy/translator/js/examples/bnb/bnb.py Mon Feb 26 08:45:45 2007 @@ -73,13 +73,13 @@ host = 'localhost' try: port = re.findall('value=".*"', urllib.urlopen('http://%s:8000' % host).read())[0] + port = int(port[7:-1]) except IOError: log("ERROR: Can't connect to BnB server on %s:8000" % host) - sys.exit() +# sys.exit() except IndexError: log("ERROR: Connected to BnB server but unable to detect a running game") - sys.exit() - port = int(port[7:-1]) +# sys.exit() #def _close(self, sessionid): # if sessionid in self._serverMessage: Modified: pypy/branch/ast-experiments/pypy/translator/js/examples/bnb/data/bnb.html ============================================================================== --- pypy/branch/ast-experiments/pypy/translator/js/examples/bnb/data/bnb.html (original) +++ pypy/branch/ast-experiments/pypy/translator/js/examples/bnb/data/bnb.html Mon Feb 26 08:45:45 2007 @@ -4,7 +4,7 @@ Bub'n'bros - + Modified: pypy/branch/ast-experiments/pypy/translator/js/examples/bnb/servermessage.py ============================================================================== --- pypy/branch/ast-experiments/pypy/translator/js/examples/bnb/servermessage.py (original) +++ pypy/branch/ast-experiments/pypy/translator/js/examples/bnb/servermessage.py Mon Feb 26 08:45:45 2007 @@ -1,5 +1,4 @@ from msgstruct import * -import PIL.Image from zlib import decompressobj, decompress from urllib import quote from os.path import exists @@ -93,6 +92,7 @@ return fn(bitmap_code, data_or_fileid, *rest) def def_bitmap1(self, bitmap_code, data, *rest): + import PIL.Image if len(rest) == 0: colorkey = None else: @@ -163,6 +163,8 @@ fileid, position, size, gfx_bitmap_filename)) def def_icon(self, bitmap_code, icon_code, x,y,w,h, *rest): + import PIL.Image + #log('def_icon bitmap_code=%s, icon_code=%s, x=%s, y=%s, w=%s, h=%s, alpha=%s' %\ # (bitmap_code, icon_code, x,y,w,h, rest) #ignore alpha (bubbles) Modified: pypy/branch/ast-experiments/pypy/translator/js/examples/data/index.html ============================================================================== --- pypy/branch/ast-experiments/pypy/translator/js/examples/data/index.html (original) +++ pypy/branch/ast-experiments/pypy/translator/js/examples/data/index.html Mon Feb 26 08:45:45 2007 @@ -6,19 +6,27 @@ +

Note: this demos are set up on the replicable xen instance, but + please do not vandalise the machine, otherwise we would be forced to + take it down

This site presents various demos and tutorials about pypy.js

Remote terminal:

-

Fully ANSI-complaint remote terminal session: - Launch one for me - Source +

Fully ANSI-complaint remote terminal session: + Take a look +

+

Bub'n'Bros JavaScript version

+

+ This is a working b'n'b client. It's kind of slow (blame lousy browsers), + but usable. WARNING! If you're using the firebug, please disable it, + it's a great tool, but chockes a bit on this demo
+ Demo

Modified: pypy/branch/ast-experiments/pypy/translator/js/examples/over_client.py ============================================================================== --- pypy/branch/ast-experiments/pypy/translator/js/examples/over_client.py (original) +++ pypy/branch/ast-experiments/pypy/translator/js/examples/over_client.py Mon Feb 26 08:45:45 2007 @@ -11,3 +11,8 @@ def launch_console(): exported_methods.launch_console(callback) + +def bnb_redirect(): + loc = dom.window.location + new_loc = loc.protocol + "//" + loc.hostname + ":7070" + loc.assign(new_loc) Modified: pypy/branch/ast-experiments/pypy/translator/js/examples/overmind.py ============================================================================== --- pypy/branch/ast-experiments/pypy/translator/js/examples/overmind.py (original) +++ pypy/branch/ast-experiments/pypy/translator/js/examples/overmind.py Mon Feb 26 08:45:45 2007 @@ -14,11 +14,11 @@ import os import py -FUNCTION_LIST = ['launch_console'] +FUNCTION_LIST = ['launch_console', 'bnb_redirect'] TIMEOUT = 300 pids = [] -def launch_console_in_new_thread(): +def launch_console_in_new_prcess(): from pypy.translator.js.examples import pythonconsole httpd = server.create_server(server_address=('', 0), handler=pythonconsole.RequestHandler, @@ -37,7 +37,7 @@ if we want to make this multiplayer, we need additional locking XXX """ - return launch_console_in_new_thread() + return launch_console_in_new_prcess() exported_methods = ExportedMethods() @@ -49,6 +49,7 @@ static_dir = str(py.path.local(__file__).dirpath().join("data")) index = server.Static() console = server.Static(os.path.join(static_dir, "launcher.html")) + terminal = server.Static(os.path.join(static_dir, "terminal.html")) exported_methods = exported_methods def source_js(self): @@ -60,6 +61,17 @@ return "text/javascript", source source_js.exposed = True + def bnb(self): + return ''' + + + + + + + ''' + bnb.exposed = True + if __name__ == '__main__': try: addr = ('', 8008) Modified: pypy/branch/ast-experiments/pypy/translator/js/examples/pythonconsole.py ============================================================================== --- pypy/branch/ast-experiments/pypy/translator/js/examples/pythonconsole.py (original) +++ pypy/branch/ast-experiments/pypy/translator/js/examples/pythonconsole.py Mon Feb 26 08:45:45 2007 @@ -17,7 +17,7 @@ from pypy.translator.js import commproxy from pypy.rpython.extfunc import _callable -from pypy.translator.js.demo.jsdemo import support +from pypy.translator.js.lib import support from pypy.translator.js.lib import server commproxy.USE_MOCHIKIT = True @@ -30,8 +30,8 @@ Example - +

Console

Modified: pypy/branch/ast-experiments/pypy/translator/js/lib/support.py ============================================================================== --- pypy/branch/ast-experiments/pypy/translator/js/lib/support.py (original) +++ pypy/branch/ast-experiments/pypy/translator/js/lib/support.py Mon Feb 26 08:45:45 2007 @@ -23,3 +23,23 @@ return func return decorator + +import sys, new +from pypy.translator.js.main import rpython2javascript + +def js_source(functions, use_pdb=True): + mod = new.module('_js_src') + function_names = [] + for func in functions: + name = func.__name__ + if hasattr(mod, name): + raise ValueError("exported function name %r is duplicated" + % (name,)) + mod.__dict__[name] = func + function_names.append(name) + sys.modules['_js_src'] = mod + try: + return rpython2javascript(mod, function_names, use_pdb=use_pdb) + finally: + del sys.modules['_js_src'] + Modified: pypy/branch/ast-experiments/pypy/translator/js/main.py ============================================================================== --- pypy/branch/ast-experiments/pypy/translator/js/main.py (original) +++ pypy/branch/ast-experiments/pypy/translator/js/main.py Mon Feb 26 08:45:45 2007 @@ -14,6 +14,7 @@ from pypy.config.config import OptionDescription, BoolOption, StrOption from pypy.config.config import Config, to_optparse import py +import sys js_optiondescr = OptionDescription("jscompile", "", [ BoolOption("view", "View flow graphs", @@ -44,16 +45,29 @@ [:func_data.func_code.co_argcount]) def rpython2javascript_main(argv, jsconfig): - if len(argv) < 2: + if len(argv) == 0: print "usage: module " - import sys sys.exit(0) module_name = argv[0] - if module_name.endswith('.py'): - module_name = module_name[:-3] - function_names = argv[1:] - mod = __import__(module_name, None, None, ["Module"]) + if not module_name.endswith('.py'): + module_name += ".py" + mod = py.path.local(module_name).pyimport() + if len(argv) == 1: + function_names = [] + for function_name in dir(mod): + function = getattr(mod, function_name) + if callable(function) and getattr(function, '_client', False): + function_names.append( function_name ) + if not function_names: + print "Cannot find any function with _client=True in %s"\ + % module_name + sys.exit(1) + else: + function_names = argv[1:] source = rpython2javascript(mod, function_names, jsconfig=jsconfig) + if not source: + print "Exiting, source not generated" + sys.exit(1) open(jsconfig.output, "w").write(source) print "Written file %s" % jsconfig.output Modified: pypy/branch/ast-experiments/pypy/translator/js/modules/dom.py ============================================================================== --- pypy/branch/ast-experiments/pypy/translator/js/modules/dom.py (original) +++ pypy/branch/ast-experiments/pypy/translator/js/modules/dom.py Mon Feb 26 08:45:45 2007 @@ -715,12 +715,6 @@ 'shiftKey': bool, }) -# XXX: Right now this is only way to get it rendered -setTimeout.suggested_primitive = True - -# the following code wraps minidom nodes with Node classes, and makes -# sure all methods on the nodes return wrapped nodes - class _FunctionWrapper(object): """makes sure function return values are wrapped if appropriate""" def __init__(self, callable): Modified: pypy/branch/ast-experiments/pypy/translator/js/modules/mochikit.py ============================================================================== --- pypy/branch/ast-experiments/pypy/translator/js/modules/mochikit.py (original) +++ pypy/branch/ast-experiments/pypy/translator/js/modules/mochikit.py Mon Feb 26 08:45:45 2007 @@ -2,6 +2,8 @@ """ mochikit wrappers """ +from pypy.rpython.extfunc import register_external + def createLoggingPane(var): pass createLoggingPane.suggested_primitive = True @@ -34,4 +36,5 @@ def escapeHTML(data): return data -escapeHTML.suggested_primitive = True +register_external(escapeHTML, args=[str], result=str) + Modified: pypy/branch/ast-experiments/pypy/translator/js/test/test_main.py ============================================================================== --- pypy/branch/ast-experiments/pypy/translator/js/test/test_main.py (original) +++ pypy/branch/ast-experiments/pypy/translator/js/test/test_main.py Mon Feb 26 08:45:45 2007 @@ -2,15 +2,22 @@ """ tests of rpython2javascript function """ -from pypy.translator.js.main import rpython2javascript +from pypy.translator.js.main import rpython2javascript, rpython2javascript_main,\ + js_optiondescr from pypy.translator.js import conftest from pypy.rpython.ootypesystem.bltregistry import BasicExternal, described import py import sys +from pypy.tool.udir import udir +from pypy.config.config import Config, to_optparse + #if not conftest.option.browser: # py.test.skip("Works only in browser (right now?)") +def setup_module(mod): + mod.jsconfig = Config(js_optiondescr) + class A(BasicExternal): def method(self, a={'a':'a'}): pass @@ -31,3 +38,32 @@ def test_module_none(): assert rpython2javascript(None, "fff") + +class TestJsMain(object): + def _test_not_raises(self, mod_file, args_rest=[]): + try: + rpython2javascript_main([str(mod_file)] + args_rest, + jsconfig) + except SystemExit: + py.test.fail("Exited") + + def _test_raises(self, mod_file, args_rest): + py.test.raises(SystemExit, rpython2javascript_main, + [str(mod_file)] + args_rest, jsconfig) + + def test_main_one(self): + udir.ensure("js_one.py").write(py.code.Source(""" + def f(): + pass + f._client = True + """)) + self._test_not_raises(udir.join("js_one.py")) + + def test_main_two(self): + udir.ensure("js_two.py").write(py.code.Source(""" + def f(): + pass + """)) + self._test_not_raises(udir.join("js_two.py"), ["f"]) + self._test_raises(udir.join("js_two.py"), []) + Modified: pypy/branch/ast-experiments/pypy/translator/llvm/buildllvm.py ============================================================================== --- pypy/branch/ast-experiments/pypy/translator/llvm/buildllvm.py (original) +++ pypy/branch/ast-experiments/pypy/translator/llvm/buildllvm.py Mon Feb 26 08:45:45 2007 @@ -15,13 +15,23 @@ return False return True -def _exe_version(exe): - v = os.popen(exe + ' -version 2>&1').read() - v = ''.join([c for c in v if c.isdigit()]) - v = int(v) / 10.0 +def _exe_version(exe, cache={}): + try: + v = cache[exe] + except KeyError: + v = os.popen(exe + ' -version 2>&1').read() + v = ''.join([c for c in v if c.isdigit()]) + v = int(v) / 10.0 + cache[exe] = v return v -llvm_version = _exe_version('llvm-as') +llvm_version = lambda: _exe_version('llvm-as') + +def postfix(): + if llvm_version() >= 2.0: + return '.i32' + else: + return '' def _exe_version2(exe): v = os.popen(exe + ' --version 2>&1').read() @@ -31,8 +41,8 @@ v = float(major) + float(minor) / 10.0 return v -gcc_version = _exe_version2('gcc') -llvm_gcc_version = _exe_version2('llvm-gcc') +gcc_version = lambda: _exe_version2('gcc') +llvm_gcc_version = lambda: _exe_version2('llvm-gcc') def optimizations(simple, use_gcc): @@ -86,7 +96,7 @@ # run llvm assembler and optimizer simple_optimizations = not optimize opts = optimizations(simple_optimizations, use_gcc) - if llvm_version < 2.0: + if llvm_version() < 2.0: cmds = ["llvm-as < %s.ll | opt %s -f -o %s.bc" % (b, opts, b)] else: #we generate 1.x .ll files, so upgrade these first cmds = ["llvm-upgrade < %s.ll | llvm-as | opt %s -f -o %s.bc" % (b, opts, b)] Modified: pypy/branch/ast-experiments/pypy/translator/llvm/externs2ll.py ============================================================================== --- pypy/branch/ast-experiments/pypy/translator/llvm/externs2ll.py (original) +++ pypy/branch/ast-experiments/pypy/translator/llvm/externs2ll.py Mon Feb 26 08:45:45 2007 @@ -11,8 +11,6 @@ from pypy.tool.udir import udir -_llvm_gcc_version = None - support_functions = [ "%raisePyExc_IOError", "%raisePyExc_ValueError", @@ -40,7 +38,7 @@ plain = filename[:-2] includes = get_incdirs() - if llvm_gcc_version < 4.0: + if llvm_gcc_version() < 4.0: emit_llvm = '' else: emit_llvm = '-emit-llvm -O3' Modified: pypy/branch/ast-experiments/pypy/translator/llvm/gc.py ============================================================================== --- pypy/branch/ast-experiments/pypy/translator/llvm/gc.py (original) +++ pypy/branch/ast-experiments/pypy/translator/llvm/gc.py Mon Feb 26 08:45:45 2007 @@ -5,11 +5,7 @@ from pypy.translator.llvm.log import log log = log.gc -from pypy.translator.llvm.buildllvm import llvm_version -if llvm_version >= 2.0: - postfix = '.i32' -else: - postfix = '' +from pypy.translator.llvm.buildllvm import postfix def have_boehm(): import distutils.sysconfig @@ -157,7 +153,7 @@ # malloc_size is unsigned right now codewriter.malloc(targetvar, "sbyte", size) - codewriter.call(None, 'void', '%llvm.memset' + postfix, + codewriter.call(None, 'void', '%llvm.memset' + postfix(), ['sbyte*', 'ubyte', uword, uword], [targetvar, 0, size, boundary_size], cconv='ccc') @@ -210,7 +206,7 @@ codewriter.call(targetvar, 'sbyte*', fnname, [word], [sizei]) if atomic: - codewriter.call(None, 'void', '%llvm.memset' + postfix, + codewriter.call(None, 'void', '%llvm.memset' + postfix(), ['sbyte*', 'ubyte', uword, uword], [targetvar, 0, size, boundary_size], cconv='ccc') Modified: pypy/branch/ast-experiments/pypy/translator/llvm/genllvm.py ============================================================================== --- pypy/branch/ast-experiments/pypy/translator/llvm/genllvm.py (original) +++ pypy/branch/ast-experiments/pypy/translator/llvm/genllvm.py Mon Feb 26 08:45:45 2007 @@ -18,7 +18,7 @@ from pypy.translator.llvm.gc import GcPolicy from pypy.translator.llvm.log import log from pypy import conftest -from pypy.translator.llvm.buildllvm import llvm_is_on_path +from pypy.translator.llvm.buildllvm import llvm_is_on_path, postfix class GenLLVM(object): # see create_codewriter() below @@ -119,6 +119,7 @@ def _set_wordsize(self, s): s = s.replace('UWORD', self.db.get_machine_uword()) s = s.replace( 'WORD', self.db.get_machine_word()) + s = s.replace('POSTFIX', postfix()) return s def write_headers(self, codewriter): Modified: pypy/branch/ast-experiments/pypy/translator/llvm/module/support.py ============================================================================== --- pypy/branch/ast-experiments/pypy/translator/llvm/module/support.py (original) +++ pypy/branch/ast-experiments/pypy/translator/llvm/module/support.py Mon Feb 26 08:45:45 2007 @@ -1,8 +1,3 @@ -from pypy.translator.llvm.buildllvm import llvm_version -if llvm_version >= 2.0: - postfix = '.i32' -else: - postfix = '' extdeclarations = """ %last_exception_type = internal global %RPYTHON_EXCEPTION_VTABLE* null @@ -12,7 +7,6 @@ declare ccc void %llvm.memsetPOSTFIX(sbyte*, ubyte, UWORD, UWORD) declare ccc void %llvm.memcpyPOSTFIX(sbyte*, sbyte*, UWORD, UWORD) """ -extdeclarations = extdeclarations.replace('POSTFIX', postfix) extfunctions = """ internal fastcc sbyte* %RPyString_AsString(%RPyString* %structstring) { @@ -84,7 +78,6 @@ } """ -extfunctions = extfunctions.replace('POSTFIX', postfix) from sys import maxint if maxint != 2**31-1: Modified: pypy/branch/ast-experiments/pypy/translator/llvm/test/runtest.py ============================================================================== --- pypy/branch/ast-experiments/pypy/translator/llvm/test/runtest.py (original) +++ pypy/branch/ast-experiments/pypy/translator/llvm/test/runtest.py Mon Feb 26 08:45:45 2007 @@ -32,15 +32,17 @@ if not llvm_is_on_path(): py.test.skip("could not find one of llvm-as or llvm-gcc") return False - if llvm_version < MINIMUM_LLVM_VERSION: + llvm_ver = llvm_version() + if llvm_ver < MINIMUM_LLVM_VERSION: py.test.skip("llvm version not up-to-date (found " - "%.1f, should be >= %.1f)" % (llvm_version, MINIMUM_LLVM_VERSION)) + "%.1f, should be >= %.1f)" % (llvm_ver, MINIMUM_LLVM_VERSION)) return False return True def gcc3_test(): - if int(gcc_version) != 3: - py.test.skip("test required gcc version 3 (found version %.1f)" % gcc_version) + gcc_ver = gcc_version() + if int(gcc_ver) != 3: + py.test.skip("test required gcc version 3 (found version %.1f)" % gcc_ver) return False return True Modified: pypy/branch/ast-experiments/pypy/translator/oosupport/metavm.py ============================================================================== --- pypy/branch/ast-experiments/pypy/translator/oosupport/metavm.py (original) +++ pypy/branch/ast-experiments/pypy/translator/oosupport/metavm.py Mon Feb 26 08:45:45 2007 @@ -13,6 +13,7 @@ from pypy.rpython.ootypesystem import ootype from pypy.rpython.ootypesystem.bltregistry import ExternalType +from pypy.rpython.extfunc import ExtFuncEntry, is_external class Generator(object): @@ -324,7 +325,8 @@ class _CallDispatcher(_GeneralDispatcher): def render(self, generator, op): func = op.args[0] - if getattr(func.value._callable, 'suggested_primitive', False): + # XXX we need to sort out stuff here at some point + if is_external(func): func_name = func.value._name.split("__")[0] try: return self.builtins.builtin_map[func_name](generator, op) From cfbolz at codespeak.net Mon Feb 26 10:47:42 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 26 Feb 2007 10:47:42 +0100 (CET) Subject: [pypy-svn] r39400 - pypy/extradoc/sprintinfo/trillke-2007 Message-ID: <20070226094742.D5D6910063@code0.codespeak.net> Author: cfbolz Date: Mon Feb 26 10:47:40 2007 New Revision: 39400 Added: pypy/extradoc/sprintinfo/trillke-2007/eu-planning.txt Log: (all): planning for today Added: pypy/extradoc/sprintinfo/trillke-2007/eu-planning.txt ============================================================================== --- (empty file) +++ pypy/extradoc/sprintinfo/trillke-2007/eu-planning.txt Mon Feb 26 10:47:40 2007 @@ -0,0 +1,23 @@ +======================================= +EU admin/report writing sprint planning +======================================= + +people present: Holger, Lene, Anto, Samuele, Arre, Bea, Carl Friedrich, Guido + + + * D2.1 (Holger at the beginning, Guido) + * D14.2 (Lene at the beginning) + * Management report, periodic activity report, D01.X (Lene, Bea) + * final activity report, brainstorming (Lene, Bea, Holger) + * D12.1 discussion (Anto, Arre, Samuele, Holger) + * D13.1 (Guido, Carl Friedrich) + * finalize D7.1 (Carl Friedrich) + +Todo: +===== + + * discuss external reviewers + * discuss D10.1 and D11.1 + * statistic session + * strategy discussion about D14.4 + * the "avoid and abolish redundancy"-discussion From fijal at codespeak.net Mon Feb 26 11:52:35 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 26 Feb 2007 11:52:35 +0100 (CET) Subject: [pypy-svn] r39408 - pypy/extradoc/talk/rupy2007 Message-ID: <20070226105235.56C6210144@code0.codespeak.net> Author: fijal Date: Mon Feb 26 11:52:31 2007 New Revision: 39408 Added: pypy/extradoc/talk/rupy2007/ pypy/extradoc/talk/rupy2007/abstract.txt Log: Add proposed abstract Added: pypy/extradoc/talk/rupy2007/abstract.txt ============================================================================== --- (empty file) +++ pypy/extradoc/talk/rupy2007/abstract.txt Mon Feb 26 11:52:31 2007 @@ -0,0 +1,6 @@ +Title: PyPy, the implementation of Python in Python +Abstract: We'd like to present the PyPy project, which is both +very very flexible compiler toolchain, which translates restricted subset +of python to variety of languages (C, LLVM, CLI, JVM, JavaScript...) and +implementation of a Python interpreter, with many novel features, including +Psyco-style specializing JIT, stackless-like coroutines and many others. From fijal at codespeak.net Mon Feb 26 12:21:14 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 26 Feb 2007 12:21:14 +0100 (CET) Subject: [pypy-svn] r39409 - in pypy/dist/pypy/rpython: . test Message-ID: <20070226112114.686BE1010F@code0.codespeak.net> Author: fijal Date: Mon Feb 26 12:21:12 2007 New Revision: 39409 Modified: pypy/dist/pypy/rpython/extfunc.py pypy/dist/pypy/rpython/test/test_extfunc.py Log: Add a possibility to specify None as args, which does not enforce arguments for external functions. Note that than this is backend responsibility for caring about arguments. Modified: pypy/dist/pypy/rpython/extfunc.py ============================================================================== --- pypy/dist/pypy/rpython/extfunc.py (original) +++ pypy/dist/pypy/rpython/extfunc.py Mon Feb 26 12:21:12 2007 @@ -5,6 +5,7 @@ from pypy.annotation.model import unionof from pypy.annotation.signature import annotation from pypy.annotation import model as annmodel +import py class _callable(object): """ A way to specify the callable annotation, but deferred until @@ -25,16 +26,21 @@ class ExtFuncEntry(ExtRegistryEntry): def compute_result_annotation(self, *args_s): - assert len(args_s) == len(self.signature_args),\ - "Argument number mismatch" - for arg, expected in zip(args_s, self.signature_args): - arg = unionof(arg, expected) - assert expected.contains(arg) + if self.signature_args is not None: + assert len(args_s) == len(self.signature_args),\ + "Argument number mismatch" + for arg, expected in zip(args_s, self.signature_args): + arg = unionof(arg, expected) + assert expected.contains(arg) return self.signature_result def specialize_call(self, hop): rtyper = hop.rtyper - args_r = [rtyper.getrepr(s_arg) for s_arg in self.signature_args] + if self.signature_args is None: + iter_args = hop.args_s + else: + iter_args = self.signature_args + args_r = [rtyper.getrepr(s_arg) for s_arg in iter_args] args_ll = [r_arg.lowleveltype for r_arg in args_r] r_result = rtyper.getrepr(self.signature_result) ll_result = r_result.lowleveltype @@ -56,7 +62,10 @@ class FunEntry(ExtFuncEntry): _about_ = function - signature_args = [annotation(arg) for arg in args] + if args is None: + signature_args = None + else: + signature_args = [annotation(arg) for arg in args] signature_result = annotation(result) name=export_name if llimpl: Modified: pypy/dist/pypy/rpython/test/test_extfunc.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_extfunc.py (original) +++ pypy/dist/pypy/rpython/test/test_extfunc.py Mon Feb 26 12:21:12 2007 @@ -1,5 +1,6 @@ -from pypy.rpython.extfunc import ExtFuncEntry, _callable, register_external +from pypy.rpython.extfunc import ExtFuncEntry, _callable, register_external,\ + is_external from pypy.annotation import model as annmodel from pypy.annotation.annrpython import RPythonAnnotator from pypy.annotation.policy import AnnotatorPolicy @@ -113,3 +114,28 @@ # Not a very good assertion, but at least it means _something_ happened. assert isinstance(s, annmodel.SomeInteger) + +def function_withspecialcase(arg): + return repr(arg) +register_external(function_withspecialcase, args=None, result=str) + +def test_register_external_specialcase(): + def f(): + x = function_withspecialcase + return x(33) + x("aaa") + x([]) + "\n" + + policy = AnnotatorPolicy() + policy.allow_someobjects = False + a = RPythonAnnotator(policy=policy) + s = a.build_types(f, []) + assert isinstance(s, annmodel.SomeString) + +#def test_is_external(): +# assert is_external(BTestFuncEntry) +# def f(): +# pass +# assert not is_external(f) +# f.suggested_primitive = True +# assert is_external(f) +# f.suggested_primitive = False +# assert not is_external(f) From fijal at codespeak.net Mon Feb 26 12:31:44 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 26 Feb 2007 12:31:44 +0100 (CET) Subject: [pypy-svn] r39413 - pypy/dist/pypy/translator/js/modules Message-ID: <20070226113144.62B211014F@code0.codespeak.net> Author: fijal Date: Mon Feb 26 12:31:42 2007 New Revision: 39413 Modified: pypy/dist/pypy/translator/js/modules/mochikit.py Log: Killed suggested_primitive Modified: pypy/dist/pypy/translator/js/modules/mochikit.py ============================================================================== --- pypy/dist/pypy/translator/js/modules/mochikit.py (original) +++ pypy/dist/pypy/translator/js/modules/mochikit.py Mon Feb 26 12:31:42 2007 @@ -6,35 +6,32 @@ def createLoggingPane(var): pass -createLoggingPane.suggested_primitive = True +register_external(createLoggingPane, args=[bool]) def log(data): - pass -log.suggested_primitive = True -log._annspecialcase_ = "specialize:argtype(0)" + print data +register_external(log, args=None) def logDebug(data): - pass -logDebug.suggested_primitive = True -logDebug._annspecialcase_ = "specialize:argtype(0)" + print "D:", data +register_external(logDebug, args=None) def logWarning(data): - pass -logWarning.suggested_primitive = True -logWarning._annspecialcase_ = "specialize:argtype(0)" - + print "Warning:", data +register_external(logWarning, args=None) def logError(data): - pass -logError.suggested_primitive = True -logError._annspecialcase_ = "specialize:argtype(0)" + print "ERROR:", data +register_external(logError, args=None) def logFatal(data): - pass -logFatal.suggested_primitive = True -logFatal._annspecialcase_ = "specialize:argtype(0)" + print "FATAL:", data +register_external(logFatal, args=None) def escapeHTML(data): return data register_external(escapeHTML, args=[str], result=str) +def serializeJSON(data): + pass +register_external(serializeJSON, args=None, result=str) From fijal at codespeak.net Mon Feb 26 12:32:16 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 26 Feb 2007 12:32:16 +0100 (CET) Subject: [pypy-svn] r39414 - pypy/dist/pypy/rpython Message-ID: <20070226113216.7FF2910154@code0.codespeak.net> Author: fijal Date: Mon Feb 26 12:32:14 2007 New Revision: 39414 Modified: pypy/dist/pypy/rpython/extfunc.py Log: Make default result type None (not sure if this will stay) Modified: pypy/dist/pypy/rpython/extfunc.py ============================================================================== --- pypy/dist/pypy/rpython/extfunc.py (original) +++ pypy/dist/pypy/rpython/extfunc.py Mon Feb 26 12:32:14 2007 @@ -57,7 +57,7 @@ hop.exception_is_here() return hop.genop('direct_call', vlist, r_result) -def register_external(function, args, result, export_name=None, +def register_external(function, args, result=None, export_name=None, llimpl=None, ooimpl=None): class FunEntry(ExtFuncEntry): From santagada at codespeak.net Mon Feb 26 14:32:06 2007 From: santagada at codespeak.net (santagada at codespeak.net) Date: Mon, 26 Feb 2007 14:32:06 +0100 (CET) Subject: [pypy-svn] r39426 - pypy/dist/pypy/lang/js Message-ID: <20070226133206.BD9001014D@code0.codespeak.net> Author: santagada Date: Mon Feb 26 14:32:04 2007 New Revision: 39426 Modified: pypy/dist/pypy/lang/js/interpreter.py pypy/dist/pypy/lang/js/js_interactive.py pypy/dist/pypy/lang/js/jsobj.py pypy/dist/pypy/lang/js/jsparser.py Log: stripped of regexes on jsparser.py, better handling of exceptions on the interactive parser, a rpython modification (super is not rpython), and a cleanup of the exception trace string Modified: pypy/dist/pypy/lang/js/interpreter.py ============================================================================== --- pypy/dist/pypy/lang/js/interpreter.py (original) +++ pypy/dist/pypy/lang/js/interpreter.py Mon Feb 26 14:32:04 2007 @@ -774,7 +774,7 @@ if isinstance(e, ExecutionReturned) and e.type == 'return': return e.value else: - print "exeception in line: %s, %s - %s"%(node.lineno, node.value, self) + print "exeception in line: %s, on: %s"%(node.lineno, node.value) raise class Semicolon(Statement): Modified: pypy/dist/pypy/lang/js/js_interactive.py ============================================================================== --- pypy/dist/pypy/lang/js/js_interactive.py (original) +++ pypy/dist/pypy/lang/js/js_interactive.py Mon Feb 26 14:32:04 2007 @@ -8,7 +8,7 @@ import sys import getopt from pypy.lang.js.interpreter import * -from pypy.lang.js.jsobj import W_Builtin, W_String, ThrowException +from pypy.lang.js.jsobj import W_Builtin, W_String, ThrowException, w_Undefined from pypy.lang.js import jsparser import os import cmd @@ -93,7 +93,16 @@ interp.w_Global.Put('load', W_Builtin(loadjs)) interp.w_Global.Put('trace', W_Builtin(tracejs)) for filename in filenames: - loadjs(interp.global_context, [W_String(filename)], None) + try: + loadjs(interp.global_context, [W_String(filename)], None) + # XXX we should catch more stuff here, like not implemented + # and such + except (jsparser.JsSyntaxError, ThrowException), e: + if isinstance(e, jsparser.JsSyntaxError): + print "\nSyntax error!" + elif isinstance(e, ThrowException): + print "\nJS Exception thrown!" + return #while interactive: # res = interp.run(load_source(raw_input("js-pypy> "))) @@ -152,8 +161,8 @@ return finally: self.reset() - if res is not None: - print res + if res is not None or res is not w_Undefined: + print res.GetValue().ToString() if __name__ == "__main__": import py Modified: pypy/dist/pypy/lang/js/jsobj.py ============================================================================== --- pypy/dist/pypy/lang/js/jsobj.py (original) +++ pypy/dist/pypy/lang/js/jsobj.py Mon Feb 26 14:32:04 2007 @@ -304,7 +304,7 @@ self.array[x]= V except ValueError: - super(W_Array, self).Put(P, V, dd, ro, de, it) + W_Builtin.Put(self, P, V, dd=dd, ro=ro, de=de, it=it) def Get(self, P): try: Modified: pypy/dist/pypy/lang/js/jsparser.py ============================================================================== --- pypy/dist/pypy/lang/js/jsparser.py (original) +++ pypy/dist/pypy/lang/js/jsparser.py Mon Feb 26 14:32:04 2007 @@ -15,11 +15,21 @@ class JsSyntaxError(Exception): pass -singlequote = re.compile(r"(? Author: afayolle Date: Mon Feb 26 15:06:33 2007 New Revision: 39432 Added: pypy/dist/pypy/doc/config/objspace.usemodules.dyngram.txt - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/doc/config/objspace.usemodules.dyngram.txt pypy/dist/pypy/interpreter/pyparser/asthelper.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/interpreter/pyparser/asthelper.py pypy/dist/pypy/interpreter/pyparser/test/expressions.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/interpreter/pyparser/test/expressions.py pypy/dist/pypy/interpreter/pyparser/test/test_parser.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/interpreter/pyparser/test/test_parser.py pypy/dist/pypy/module/dyngram/ (props changed) - copied from r39399, pypy/branch/ast-experiments/pypy/module/dyngram/ pypy/dist/pypy/module/recparser/hooksamples/ - copied from r39399, pypy/branch/ast-experiments/pypy/module/recparser/hooksamples/ pypy/dist/pypy/module/recparser/test/test_dyn_grammarrules.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/module/recparser/test/test_dyn_grammarrules.py pypy/dist/pypy/rpython/rslice.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/rpython/rslice.py pypy/dist/pypy/translator/goal/targetebnfparser.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/goal/targetebnfparser.py pypy/dist/pypy/translator/js/ - copied from r39399, pypy/branch/ast-experiments/pypy/translator/js/ pypy/dist/pypy/translator/js/__init__.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/__init__.py pypy/dist/pypy/translator/js/_class.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/_class.py pypy/dist/pypy/translator/js/asmgen.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/asmgen.py pypy/dist/pypy/translator/js/autopath.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/autopath.py pypy/dist/pypy/translator/js/commproxy.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/commproxy.py pypy/dist/pypy/translator/js/conftest.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/conftest.py pypy/dist/pypy/translator/js/database.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/database.py pypy/dist/pypy/translator/js/examples/ - copied from r39399, pypy/branch/ast-experiments/pypy/translator/js/examples/ pypy/dist/pypy/translator/js/examples/__init__.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/examples/__init__.py pypy/dist/pypy/translator/js/examples/autopath.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/examples/autopath.py pypy/dist/pypy/translator/js/examples/bnb/ - copied from r39399, pypy/branch/ast-experiments/pypy/translator/js/examples/bnb/ pypy/dist/pypy/translator/js/examples/bnb/__init__.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/examples/bnb/__init__.py pypy/dist/pypy/translator/js/examples/bnb/autopath.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/examples/bnb/autopath.py pypy/dist/pypy/translator/js/examples/bnb/bnb.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/examples/bnb/bnb.py pypy/dist/pypy/translator/js/examples/bnb/data/ - copied from r39399, pypy/branch/ast-experiments/pypy/translator/js/examples/bnb/data/ pypy/dist/pypy/translator/js/examples/bnb/data/bnb.html - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/examples/bnb/data/bnb.html pypy/dist/pypy/translator/js/examples/bnb/data/images/ - copied from r39399, pypy/branch/ast-experiments/pypy/translator/js/examples/bnb/data/images/ pypy/dist/pypy/translator/js/examples/bnb/msgstruct.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/examples/bnb/msgstruct.py pypy/dist/pypy/translator/js/examples/bnb/servermessage.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/examples/bnb/servermessage.py pypy/dist/pypy/translator/js/examples/bnb/start_bnb.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/examples/bnb/start_bnb.py pypy/dist/pypy/translator/js/examples/console/ - copied from r39399, pypy/branch/ast-experiments/pypy/translator/js/examples/console/ pypy/dist/pypy/translator/js/examples/console/__init__.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/examples/console/__init__.py pypy/dist/pypy/translator/js/examples/console/client.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/examples/console/client.py pypy/dist/pypy/translator/js/examples/console/console.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/examples/console/console.py pypy/dist/pypy/translator/js/examples/console/data/ - copied from r39399, pypy/branch/ast-experiments/pypy/translator/js/examples/console/data/ pypy/dist/pypy/translator/js/examples/console/data/console.html - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/examples/console/data/console.html pypy/dist/pypy/translator/js/examples/console/test/ - copied from r39399, pypy/branch/ast-experiments/pypy/translator/js/examples/console/test/ pypy/dist/pypy/translator/js/examples/console/test/test_console.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/examples/console/test/test_console.py pypy/dist/pypy/translator/js/examples/data/ - copied from r39399, pypy/branch/ast-experiments/pypy/translator/js/examples/data/ pypy/dist/pypy/translator/js/examples/data/index.html - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/examples/data/index.html pypy/dist/pypy/translator/js/examples/data/launcher.html - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/examples/data/launcher.html pypy/dist/pypy/translator/js/examples/djangoping/ - copied from r39399, pypy/branch/ast-experiments/pypy/translator/js/examples/djangoping/ pypy/dist/pypy/translator/js/examples/djangoping/__init__.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/examples/djangoping/__init__.py pypy/dist/pypy/translator/js/examples/djangoping/client.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/examples/djangoping/client.py pypy/dist/pypy/translator/js/examples/djangoping/manage.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/examples/djangoping/manage.py pypy/dist/pypy/translator/js/examples/djangoping/settings.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/examples/djangoping/settings.py pypy/dist/pypy/translator/js/examples/djangoping/templates/ - copied from r39399, pypy/branch/ast-experiments/pypy/translator/js/examples/djangoping/templates/ pypy/dist/pypy/translator/js/examples/djangoping/templates/index.html - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/examples/djangoping/templates/index.html pypy/dist/pypy/translator/js/examples/djangoping/test/ - copied from r39399, pypy/branch/ast-experiments/pypy/translator/js/examples/djangoping/test/ pypy/dist/pypy/translator/js/examples/djangoping/test/test_build.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/examples/djangoping/test/test_build.py pypy/dist/pypy/translator/js/examples/djangoping/urls.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/examples/djangoping/urls.py pypy/dist/pypy/translator/js/examples/djangoping/views.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/examples/djangoping/views.py pypy/dist/pypy/translator/js/examples/guestbook.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/examples/guestbook.py pypy/dist/pypy/translator/js/examples/guestbook_client.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/examples/guestbook_client.py pypy/dist/pypy/translator/js/examples/over_client.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/examples/over_client.py pypy/dist/pypy/translator/js/examples/overmind.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/examples/overmind.py pypy/dist/pypy/translator/js/examples/pythonconsole.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/examples/pythonconsole.py pypy/dist/pypy/translator/js/examples/serialise.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/examples/serialise.py pypy/dist/pypy/translator/js/examples/test/ - copied from r39399, pypy/branch/ast-experiments/pypy/translator/js/examples/test/ pypy/dist/pypy/translator/js/examples/test/__init__.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/examples/test/__init__.py pypy/dist/pypy/translator/js/examples/test/test_examples.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/examples/test/test_examples.py pypy/dist/pypy/translator/js/function.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/function.py pypy/dist/pypy/translator/js/helper.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/helper.py pypy/dist/pypy/translator/js/js.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/js.py pypy/dist/pypy/translator/js/jsbuiltin.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/jsbuiltin.py pypy/dist/pypy/translator/js/json.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/json.py pypy/dist/pypy/translator/js/jssrc/ - copied from r39399, pypy/branch/ast-experiments/pypy/translator/js/jssrc/ pypy/dist/pypy/translator/js/jssrc/misc.js - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/jssrc/misc.js pypy/dist/pypy/translator/js/jts.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/jts.py pypy/dist/pypy/translator/js/lib/ - copied from r39399, pypy/branch/ast-experiments/pypy/translator/js/lib/ pypy/dist/pypy/translator/js/lib/__init__.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/lib/__init__.py pypy/dist/pypy/translator/js/lib/server.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/lib/server.py pypy/dist/pypy/translator/js/lib/support.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/lib/support.py pypy/dist/pypy/translator/js/lib/test/ - copied from r39399, pypy/branch/ast-experiments/pypy/translator/js/lib/test/ pypy/dist/pypy/translator/js/lib/test/__init__.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/lib/test/__init__.py pypy/dist/pypy/translator/js/lib/test/test_server.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/lib/test/test_server.py pypy/dist/pypy/translator/js/lib/test/test_support.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/lib/test/test_support.py pypy/dist/pypy/translator/js/lib/test/test_url.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/lib/test/test_url.py pypy/dist/pypy/translator/js/lib/url.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/lib/url.py pypy/dist/pypy/translator/js/log.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/log.py pypy/dist/pypy/translator/js/main.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/main.py pypy/dist/pypy/translator/js/metavm.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/metavm.py pypy/dist/pypy/translator/js/modules/ - copied from r39399, pypy/branch/ast-experiments/pypy/translator/js/modules/ pypy/dist/pypy/translator/js/modules/__init__.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/modules/__init__.py pypy/dist/pypy/translator/js/modules/dom.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/modules/dom.py pypy/dist/pypy/translator/js/modules/mochikit.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/modules/mochikit.py pypy/dist/pypy/translator/js/modules/test/ - copied from r39399, pypy/branch/ast-experiments/pypy/translator/js/modules/test/ pypy/dist/pypy/translator/js/modules/test/__init__.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/modules/test/__init__.py pypy/dist/pypy/translator/js/modules/test/html/ - copied from r39399, pypy/branch/ast-experiments/pypy/translator/js/modules/test/html/ pypy/dist/pypy/translator/js/modules/test/html/anim.html - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/modules/test/html/anim.html pypy/dist/pypy/translator/js/modules/test/html/test.html - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/modules/test/html/test.html pypy/dist/pypy/translator/js/modules/test/test_dom.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/modules/test/test_dom.py pypy/dist/pypy/translator/js/modules/test/test_mochikit.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/modules/test/test_mochikit.py pypy/dist/pypy/translator/js/opcodes.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/opcodes.py pypy/dist/pypy/translator/js/support.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/support.py pypy/dist/pypy/translator/js/test/ - copied from r39399, pypy/branch/ast-experiments/pypy/translator/js/test/ pypy/dist/pypy/translator/js/test/__init__.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/test/__init__.py pypy/dist/pypy/translator/js/test/browsertest.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/test/browsertest.py pypy/dist/pypy/translator/js/test/runtest.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/test/runtest.py pypy/dist/pypy/translator/js/test/test_basicexternal.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/test/test_basicexternal.py pypy/dist/pypy/translator/js/test/test_bltn.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/test/test_bltn.py pypy/dist/pypy/translator/js/test/test_class.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/test/test_class.py pypy/dist/pypy/translator/js/test/test_exc_operation.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/test/test_exc_operation.py pypy/dist/pypy/translator/js/test/test_exception.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/test/test_exception.py pypy/dist/pypy/translator/js/test/test_extfunc.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/test/test_extfunc.py pypy/dist/pypy/translator/js/test/test_jseval.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/test/test_jseval.py pypy/dist/pypy/translator/js/test/test_loops.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/test/test_loops.py pypy/dist/pypy/translator/js/test/test_main.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/test/test_main.py pypy/dist/pypy/translator/js/test/test_rclass.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/test/test_rclass.py pypy/dist/pypy/translator/js/test/test_rdict.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/test/test_rdict.py pypy/dist/pypy/translator/js/test/test_rlist.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/test/test_rlist.py pypy/dist/pypy/translator/js/test/test_rpbc.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/test/test_rpbc.py pypy/dist/pypy/translator/js/test/test_rsnippet.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/test/test_rsnippet.py pypy/dist/pypy/translator/js/test/test_rsnippet1.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/test/test_rsnippet1.py pypy/dist/pypy/translator/js/test/test_runtest.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/test/test_runtest.py pypy/dist/pypy/translator/js/test/test_seq.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/test/test_seq.py pypy/dist/pypy/translator/js/test/test_snippet.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/test/test_snippet.py pypy/dist/pypy/translator/js/test/test_typed.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/test/test_typed.py pypy/dist/pypy/translator/js/test/tgtest.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/test/tgtest.py pypy/dist/pypy/translator/js/tester.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/tester.py pypy/dist/pypy/translator/js/turbogears/ - copied from r39399, pypy/branch/ast-experiments/pypy/translator/js/turbogears/ pypy/dist/pypy/translator/js/turbogears/__init__.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/turbogears/__init__.py pypy/dist/pypy/translator/js/turbogears/commandjs.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/turbogears/commandjs.py pypy/dist/pypy/translator/js/turbogears/setup.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/turbogears/setup.py pypy/dist/pypy/translator/js/turbogears/templateplugin.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/turbogears/templateplugin.py pypy/dist/pypy/translator/js/turbogears/upload.sh - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/turbogears/upload.sh pypy/dist/pypy/translator/js/turbogears/widgets.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/turbogears/widgets.py pypy/dist/pypy/translator/js/tutorial/ - copied from r39399, pypy/branch/ast-experiments/pypy/translator/js/tutorial/ pypy/dist/pypy/translator/js/tutorial/__init__.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/tutorial/__init__.py pypy/dist/pypy/translator/js/tutorial/step1.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/tutorial/step1.py pypy/dist/pypy/translator/js/tutorial/step2.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/tutorial/step2.py pypy/dist/pypy/translator/js/tutorial/step3.py - copied unchanged from r39399, pypy/branch/ast-experiments/pypy/translator/js/tutorial/step3.py Modified: pypy/dist/pypy/config/pypyoption.py pypy/dist/pypy/interpreter/astcompiler/ast.py pypy/dist/pypy/interpreter/astcompiler/ast.txt pypy/dist/pypy/interpreter/astcompiler/astgen.py pypy/dist/pypy/interpreter/pycompiler.py pypy/dist/pypy/interpreter/pyparser/astbuilder.py pypy/dist/pypy/interpreter/pyparser/ebnfgrammar.py pypy/dist/pypy/interpreter/pyparser/ebnflexer.py pypy/dist/pypy/interpreter/pyparser/ebnfparse.py pypy/dist/pypy/interpreter/pyparser/grammar.py pypy/dist/pypy/interpreter/pyparser/pysymbol.py pypy/dist/pypy/interpreter/pyparser/pythonlexer.py pypy/dist/pypy/interpreter/pyparser/pythonparse.py pypy/dist/pypy/interpreter/pyparser/pythonutil.py pypy/dist/pypy/interpreter/pyparser/pytoken.py pypy/dist/pypy/interpreter/pyparser/syntaxtree.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_lookahead.py pypy/dist/pypy/interpreter/pyparser/test/test_pytokenizer.py pypy/dist/pypy/interpreter/pyparser/test/test_samples.py pypy/dist/pypy/interpreter/pyparser/tuplebuilder.py pypy/dist/pypy/interpreter/stablecompiler/transformer.py pypy/dist/pypy/module/recparser/__init__.py pypy/dist/pypy/module/recparser/codegen.py pypy/dist/pypy/module/recparser/compat.py pypy/dist/pypy/module/recparser/pyparser.py pypy/dist/pypy/module/recparser/test/test_parser.py pypy/dist/pypy/module/symbol/__init__.py pypy/dist/pypy/translator/tool/make_dot.py Log: Merge ast-experiments branch in the trunk svn merge -r 22393:39399 svn+ssh://codespeak.net/svn/pypy/branch/ast-experiments Modified: pypy/dist/pypy/config/pypyoption.py ============================================================================== --- pypy/dist/pypy/config/pypyoption.py (original) +++ pypy/dist/pypy/config/pypyoption.py Mon Feb 26 15:06:33 2007 @@ -24,7 +24,7 @@ working_modules = default_modules.copy() working_modules.update(dict.fromkeys( ["rsocket", "unicodedata", "mmap", "fcntl", "rctime", "select", - "crypt", "signal", + "crypt", "signal", "dyngram", ] )) Modified: pypy/dist/pypy/interpreter/astcompiler/ast.py ============================================================================== --- pypy/dist/pypy/interpreter/astcompiler/ast.py (original) +++ pypy/dist/pypy/interpreter/astcompiler/ast.py Mon Feb 26 15:06:33 2007 @@ -30,6 +30,7 @@ def __init__(self, lineno = -1): self.lineno = lineno self.filename = "" + self.parent = None #self.scope = None def getChildren(self): @@ -61,6 +62,12 @@ def descr_repr( self, space ): return space.wrap( self.__repr__() ) + def fget_parent(space, self): + return space.wrap(self.parent) + + def fset_parent(space, self, w_parent): + self.parent = space.interp_w(Node, w_parent, can_be_None=False) + def descr_getChildNodes( self, space ): lst = self.getChildNodes() return space.newlist( [ space.wrap( it ) for it in lst ] ) @@ -84,6 +91,7 @@ mutate = interp2app(descr_node_mutate, unwrap_spec=[ ObjSpace, W_Root, W_Root ] ), lineno = interp_attrproperty('lineno', cls=Node), filename = interp_attrproperty('filename', cls=Node), + parent=GetSetProperty(Node.fget_parent, Node.fset_parent), ) Node.typedef.acceptable_as_base_class = False @@ -363,6 +371,15 @@ del self.nodes[:] for w_itm in space.unpackiterable(w_arg): self.nodes.append( space.interp_w(Node, w_itm)) + def descr_insert_after(space, self, node, w_added_nodes): + added_nodes = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_added_nodes)] + index = self.nodes.index(node) + 1 + self.nodes[index:index] = added_nodes + + def descr_insert_before(space, self, node, w_added_nodes): + added_nodes = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_added_nodes)] + index = self.nodes.index(node) + self.nodes[index:index] = added_nodes def descr_And_new(space, w_subtype, w_nodes, lineno=-1): self = space.allocate_instance(And, w_subtype) @@ -391,6 +408,8 @@ accept=interp2app(descr_And_accept, unwrap_spec=[ObjSpace, W_Root, W_Root] ), mutate=interp2app(descr_And_mutate, unwrap_spec=[ObjSpace, W_Root, W_Root] ), nodes=GetSetProperty(And.fget_nodes, And.fset_nodes ), + insert_after=interp2app(And.descr_insert_after.im_func, unwrap_spec=[ObjSpace, And, Node, W_Root]), + insert_before=interp2app(And.descr_insert_before.im_func, unwrap_spec=[ObjSpace, And, Node, W_Root]), ) And.typedef.acceptable_as_base_class = False @@ -536,6 +555,15 @@ del self.nodes[:] for w_itm in space.unpackiterable(w_arg): self.nodes.append( space.interp_w(Node, w_itm)) + def descr_insert_after(space, self, node, w_added_nodes): + added_nodes = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_added_nodes)] + index = self.nodes.index(node) + 1 + self.nodes[index:index] = added_nodes + + def descr_insert_before(space, self, node, w_added_nodes): + added_nodes = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_added_nodes)] + index = self.nodes.index(node) + self.nodes[index:index] = added_nodes def descr_AssList_new(space, w_subtype, w_nodes, lineno=-1): self = space.allocate_instance(AssList, w_subtype) @@ -564,6 +592,8 @@ accept=interp2app(descr_AssList_accept, unwrap_spec=[ObjSpace, W_Root, W_Root] ), mutate=interp2app(descr_AssList_mutate, unwrap_spec=[ObjSpace, W_Root, W_Root] ), nodes=GetSetProperty(AssList.fget_nodes, AssList.fset_nodes ), + insert_after=interp2app(AssList.descr_insert_after.im_func, unwrap_spec=[ObjSpace, AssList, Node, W_Root]), + insert_before=interp2app(AssList.descr_insert_before.im_func, unwrap_spec=[ObjSpace, AssList, Node, W_Root]), ) AssList.typedef.acceptable_as_base_class = False @@ -671,6 +701,15 @@ del self.nodes[:] for w_itm in space.unpackiterable(w_arg): self.nodes.append( space.interp_w(Node, w_itm)) + def descr_insert_after(space, self, node, w_added_nodes): + added_nodes = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_added_nodes)] + index = self.nodes.index(node) + 1 + self.nodes[index:index] = added_nodes + + def descr_insert_before(space, self, node, w_added_nodes): + added_nodes = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_added_nodes)] + index = self.nodes.index(node) + self.nodes[index:index] = added_nodes def descr_AssTuple_new(space, w_subtype, w_nodes, lineno=-1): self = space.allocate_instance(AssTuple, w_subtype) @@ -699,6 +738,8 @@ accept=interp2app(descr_AssTuple_accept, unwrap_spec=[ObjSpace, W_Root, W_Root] ), mutate=interp2app(descr_AssTuple_mutate, unwrap_spec=[ObjSpace, W_Root, W_Root] ), nodes=GetSetProperty(AssTuple.fget_nodes, AssTuple.fset_nodes ), + insert_after=interp2app(AssTuple.descr_insert_after.im_func, unwrap_spec=[ObjSpace, AssTuple, Node, W_Root]), + insert_before=interp2app(AssTuple.descr_insert_before.im_func, unwrap_spec=[ObjSpace, AssTuple, Node, W_Root]), ) AssTuple.typedef.acceptable_as_base_class = False @@ -820,6 +861,15 @@ del self.nodes[:] for w_itm in space.unpackiterable(w_arg): self.nodes.append( space.interp_w(Node, w_itm)) + def descr_insert_after(space, self, node, w_added_nodes): + added_nodes = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_added_nodes)] + index = self.nodes.index(node) + 1 + self.nodes[index:index] = added_nodes + + def descr_insert_before(space, self, node, w_added_nodes): + added_nodes = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_added_nodes)] + index = self.nodes.index(node) + self.nodes[index:index] = added_nodes def fget_expr( space, self): return space.wrap(self.expr) def fset_expr( space, self, w_arg): @@ -858,6 +908,8 @@ accept=interp2app(descr_Assign_accept, unwrap_spec=[ObjSpace, W_Root, W_Root] ), mutate=interp2app(descr_Assign_mutate, unwrap_spec=[ObjSpace, W_Root, W_Root] ), nodes=GetSetProperty(Assign.fget_nodes, Assign.fset_nodes ), + insert_after=interp2app(Assign.descr_insert_after.im_func, unwrap_spec=[ObjSpace, Assign, Node, W_Root]), + insert_before=interp2app(Assign.descr_insert_before.im_func, unwrap_spec=[ObjSpace, Assign, Node, W_Root]), expr=GetSetProperty(Assign.fget_expr, Assign.fset_expr ), ) Assign.typedef.acceptable_as_base_class = False @@ -1100,6 +1152,15 @@ del self.nodes[:] for w_itm in space.unpackiterable(w_arg): self.nodes.append( space.interp_w(Node, w_itm)) + def descr_insert_after(space, self, node, w_added_nodes): + added_nodes = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_added_nodes)] + index = self.nodes.index(node) + 1 + self.nodes[index:index] = added_nodes + + def descr_insert_before(space, self, node, w_added_nodes): + added_nodes = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_added_nodes)] + index = self.nodes.index(node) + self.nodes[index:index] = added_nodes def descr_Bitand_new(space, w_subtype, w_nodes, lineno=-1): self = space.allocate_instance(Bitand, w_subtype) @@ -1128,6 +1189,8 @@ accept=interp2app(descr_Bitand_accept, unwrap_spec=[ObjSpace, W_Root, W_Root] ), mutate=interp2app(descr_Bitand_mutate, unwrap_spec=[ObjSpace, W_Root, W_Root] ), nodes=GetSetProperty(Bitand.fget_nodes, Bitand.fset_nodes ), + insert_after=interp2app(Bitand.descr_insert_after.im_func, unwrap_spec=[ObjSpace, Bitand, Node, W_Root]), + insert_before=interp2app(Bitand.descr_insert_before.im_func, unwrap_spec=[ObjSpace, Bitand, Node, W_Root]), ) Bitand.typedef.acceptable_as_base_class = False @@ -1166,6 +1229,15 @@ del self.nodes[:] for w_itm in space.unpackiterable(w_arg): self.nodes.append( space.interp_w(Node, w_itm)) + def descr_insert_after(space, self, node, w_added_nodes): + added_nodes = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_added_nodes)] + index = self.nodes.index(node) + 1 + self.nodes[index:index] = added_nodes + + def descr_insert_before(space, self, node, w_added_nodes): + added_nodes = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_added_nodes)] + index = self.nodes.index(node) + self.nodes[index:index] = added_nodes def descr_Bitor_new(space, w_subtype, w_nodes, lineno=-1): self = space.allocate_instance(Bitor, w_subtype) @@ -1194,6 +1266,8 @@ accept=interp2app(descr_Bitor_accept, unwrap_spec=[ObjSpace, W_Root, W_Root] ), mutate=interp2app(descr_Bitor_mutate, unwrap_spec=[ObjSpace, W_Root, W_Root] ), nodes=GetSetProperty(Bitor.fget_nodes, Bitor.fset_nodes ), + insert_after=interp2app(Bitor.descr_insert_after.im_func, unwrap_spec=[ObjSpace, Bitor, Node, W_Root]), + insert_before=interp2app(Bitor.descr_insert_before.im_func, unwrap_spec=[ObjSpace, Bitor, Node, W_Root]), ) Bitor.typedef.acceptable_as_base_class = False @@ -1232,6 +1306,15 @@ del self.nodes[:] for w_itm in space.unpackiterable(w_arg): self.nodes.append( space.interp_w(Node, w_itm)) + def descr_insert_after(space, self, node, w_added_nodes): + added_nodes = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_added_nodes)] + index = self.nodes.index(node) + 1 + self.nodes[index:index] = added_nodes + + def descr_insert_before(space, self, node, w_added_nodes): + added_nodes = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_added_nodes)] + index = self.nodes.index(node) + self.nodes[index:index] = added_nodes def descr_Bitxor_new(space, w_subtype, w_nodes, lineno=-1): self = space.allocate_instance(Bitxor, w_subtype) @@ -1260,6 +1343,8 @@ accept=interp2app(descr_Bitxor_accept, unwrap_spec=[ObjSpace, W_Root, W_Root] ), mutate=interp2app(descr_Bitxor_mutate, unwrap_spec=[ObjSpace, W_Root, W_Root] ), nodes=GetSetProperty(Bitxor.fget_nodes, Bitxor.fset_nodes ), + insert_after=interp2app(Bitxor.descr_insert_after.im_func, unwrap_spec=[ObjSpace, Bitxor, Node, W_Root]), + insert_before=interp2app(Bitxor.descr_insert_before.im_func, unwrap_spec=[ObjSpace, Bitxor, Node, W_Root]), ) Bitxor.typedef.acceptable_as_base_class = False @@ -1834,6 +1919,15 @@ del self.nodes[:] for w_itm in space.unpackiterable(w_arg): self.nodes.append( space.interp_w(Node, w_itm)) + def descr_insert_after(space, self, node, w_added_nodes): + added_nodes = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_added_nodes)] + index = self.nodes.index(node) + 1 + self.nodes[index:index] = added_nodes + + def descr_insert_before(space, self, node, w_added_nodes): + added_nodes = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_added_nodes)] + index = self.nodes.index(node) + self.nodes[index:index] = added_nodes def descr_Decorators_new(space, w_subtype, w_nodes, lineno=-1): self = space.allocate_instance(Decorators, w_subtype) @@ -1862,6 +1956,8 @@ accept=interp2app(descr_Decorators_accept, unwrap_spec=[ObjSpace, W_Root, W_Root] ), mutate=interp2app(descr_Decorators_mutate, unwrap_spec=[ObjSpace, W_Root, W_Root] ), nodes=GetSetProperty(Decorators.fget_nodes, Decorators.fset_nodes ), + insert_after=interp2app(Decorators.descr_insert_after.im_func, unwrap_spec=[ObjSpace, Decorators, Node, W_Root]), + insert_before=interp2app(Decorators.descr_insert_before.im_func, unwrap_spec=[ObjSpace, Decorators, Node, W_Root]), ) Decorators.typedef.acceptable_as_base_class = False @@ -3544,6 +3640,15 @@ del self.nodes[:] for w_itm in space.unpackiterable(w_arg): self.nodes.append( space.interp_w(Node, w_itm)) + def descr_insert_after(space, self, node, w_added_nodes): + added_nodes = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_added_nodes)] + index = self.nodes.index(node) + 1 + self.nodes[index:index] = added_nodes + + def descr_insert_before(space, self, node, w_added_nodes): + added_nodes = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_added_nodes)] + index = self.nodes.index(node) + self.nodes[index:index] = added_nodes def descr_List_new(space, w_subtype, w_nodes, lineno=-1): self = space.allocate_instance(List, w_subtype) @@ -3572,6 +3677,8 @@ accept=interp2app(descr_List_accept, unwrap_spec=[ObjSpace, W_Root, W_Root] ), mutate=interp2app(descr_List_mutate, unwrap_spec=[ObjSpace, W_Root, W_Root] ), nodes=GetSetProperty(List.fget_nodes, List.fset_nodes ), + insert_after=interp2app(List.descr_insert_after.im_func, unwrap_spec=[ObjSpace, List, Node, W_Root]), + insert_before=interp2app(List.descr_insert_before.im_func, unwrap_spec=[ObjSpace, List, Node, W_Root]), ) List.typedef.acceptable_as_base_class = False @@ -4172,6 +4279,15 @@ del self.nodes[:] for w_itm in space.unpackiterable(w_arg): self.nodes.append( space.interp_w(Node, w_itm)) + def descr_insert_after(space, self, node, w_added_nodes): + added_nodes = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_added_nodes)] + index = self.nodes.index(node) + 1 + self.nodes[index:index] = added_nodes + + def descr_insert_before(space, self, node, w_added_nodes): + added_nodes = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_added_nodes)] + index = self.nodes.index(node) + self.nodes[index:index] = added_nodes def descr_Or_new(space, w_subtype, w_nodes, lineno=-1): self = space.allocate_instance(Or, w_subtype) @@ -4200,6 +4316,8 @@ accept=interp2app(descr_Or_accept, unwrap_spec=[ObjSpace, W_Root, W_Root] ), mutate=interp2app(descr_Or_mutate, unwrap_spec=[ObjSpace, W_Root, W_Root] ), nodes=GetSetProperty(Or.fget_nodes, Or.fset_nodes ), + insert_after=interp2app(Or.descr_insert_after.im_func, unwrap_spec=[ObjSpace, Or, Node, W_Root]), + insert_before=interp2app(Or.descr_insert_before.im_func, unwrap_spec=[ObjSpace, Or, Node, W_Root]), ) Or.typedef.acceptable_as_base_class = False @@ -4350,6 +4468,15 @@ del self.nodes[:] for w_itm in space.unpackiterable(w_arg): self.nodes.append( space.interp_w(Node, w_itm)) + def descr_insert_after(space, self, node, w_added_nodes): + added_nodes = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_added_nodes)] + index = self.nodes.index(node) + 1 + self.nodes[index:index] = added_nodes + + def descr_insert_before(space, self, node, w_added_nodes): + added_nodes = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_added_nodes)] + index = self.nodes.index(node) + self.nodes[index:index] = added_nodes def fget_dest( space, self): if self.dest is None: return space.w_None @@ -4392,6 +4519,8 @@ accept=interp2app(descr_Print_accept, unwrap_spec=[ObjSpace, W_Root, W_Root] ), mutate=interp2app(descr_Print_mutate, unwrap_spec=[ObjSpace, W_Root, W_Root] ), nodes=GetSetProperty(Print.fget_nodes, Print.fset_nodes ), + insert_after=interp2app(Print.descr_insert_after.im_func, unwrap_spec=[ObjSpace, Print, Node, W_Root]), + insert_before=interp2app(Print.descr_insert_before.im_func, unwrap_spec=[ObjSpace, Print, Node, W_Root]), dest=GetSetProperty(Print.fget_dest, Print.fset_dest ), ) Print.typedef.acceptable_as_base_class = False @@ -4439,6 +4568,15 @@ del self.nodes[:] for w_itm in space.unpackiterable(w_arg): self.nodes.append( space.interp_w(Node, w_itm)) + def descr_insert_after(space, self, node, w_added_nodes): + added_nodes = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_added_nodes)] + index = self.nodes.index(node) + 1 + self.nodes[index:index] = added_nodes + + def descr_insert_before(space, self, node, w_added_nodes): + added_nodes = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_added_nodes)] + index = self.nodes.index(node) + self.nodes[index:index] = added_nodes def fget_dest( space, self): if self.dest is None: return space.w_None @@ -4481,6 +4619,8 @@ accept=interp2app(descr_Printnl_accept, unwrap_spec=[ObjSpace, W_Root, W_Root] ), mutate=interp2app(descr_Printnl_mutate, unwrap_spec=[ObjSpace, W_Root, W_Root] ), nodes=GetSetProperty(Printnl.fget_nodes, Printnl.fset_nodes ), + insert_after=interp2app(Printnl.descr_insert_after.im_func, unwrap_spec=[ObjSpace, Printnl, Node, W_Root]), + insert_before=interp2app(Printnl.descr_insert_before.im_func, unwrap_spec=[ObjSpace, Printnl, Node, W_Root]), dest=GetSetProperty(Printnl.fget_dest, Printnl.fset_dest ), ) Printnl.typedef.acceptable_as_base_class = False @@ -4856,6 +4996,15 @@ del self.nodes[:] for w_itm in space.unpackiterable(w_arg): self.nodes.append( space.interp_w(Node, w_itm)) + def descr_insert_after(space, self, node, w_added_nodes): + added_nodes = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_added_nodes)] + index = self.nodes.index(node) + 1 + self.nodes[index:index] = added_nodes + + def descr_insert_before(space, self, node, w_added_nodes): + added_nodes = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_added_nodes)] + index = self.nodes.index(node) + self.nodes[index:index] = added_nodes def descr_Sliceobj_new(space, w_subtype, w_nodes, lineno=-1): self = space.allocate_instance(Sliceobj, w_subtype) @@ -4884,6 +5033,8 @@ accept=interp2app(descr_Sliceobj_accept, unwrap_spec=[ObjSpace, W_Root, W_Root] ), mutate=interp2app(descr_Sliceobj_mutate, unwrap_spec=[ObjSpace, W_Root, W_Root] ), nodes=GetSetProperty(Sliceobj.fget_nodes, Sliceobj.fset_nodes ), + insert_after=interp2app(Sliceobj.descr_insert_after.im_func, unwrap_spec=[ObjSpace, Sliceobj, Node, W_Root]), + insert_before=interp2app(Sliceobj.descr_insert_before.im_func, unwrap_spec=[ObjSpace, Sliceobj, Node, W_Root]), ) Sliceobj.typedef.acceptable_as_base_class = False @@ -4922,6 +5073,15 @@ del self.nodes[:] for w_itm in space.unpackiterable(w_arg): self.nodes.append( space.interp_w(Node, w_itm)) + def descr_insert_after(space, self, node, w_added_nodes): + added_nodes = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_added_nodes)] + index = self.nodes.index(node) + 1 + self.nodes[index:index] = added_nodes + + def descr_insert_before(space, self, node, w_added_nodes): + added_nodes = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_added_nodes)] + index = self.nodes.index(node) + self.nodes[index:index] = added_nodes def descr_Stmt_new(space, w_subtype, w_nodes, lineno=-1): self = space.allocate_instance(Stmt, w_subtype) @@ -4950,6 +5110,8 @@ accept=interp2app(descr_Stmt_accept, unwrap_spec=[ObjSpace, W_Root, W_Root] ), mutate=interp2app(descr_Stmt_mutate, unwrap_spec=[ObjSpace, W_Root, W_Root] ), nodes=GetSetProperty(Stmt.fget_nodes, Stmt.fset_nodes ), + insert_after=interp2app(Stmt.descr_insert_after.im_func, unwrap_spec=[ObjSpace, Stmt, Node, W_Root]), + insert_before=interp2app(Stmt.descr_insert_before.im_func, unwrap_spec=[ObjSpace, Stmt, Node, W_Root]), ) Stmt.typedef.acceptable_as_base_class = False @@ -5352,6 +5514,15 @@ del self.nodes[:] for w_itm in space.unpackiterable(w_arg): self.nodes.append( space.interp_w(Node, w_itm)) + def descr_insert_after(space, self, node, w_added_nodes): + added_nodes = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_added_nodes)] + index = self.nodes.index(node) + 1 + self.nodes[index:index] = added_nodes + + def descr_insert_before(space, self, node, w_added_nodes): + added_nodes = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_added_nodes)] + index = self.nodes.index(node) + self.nodes[index:index] = added_nodes def descr_Tuple_new(space, w_subtype, w_nodes, lineno=-1): self = space.allocate_instance(Tuple, w_subtype) @@ -5380,6 +5551,8 @@ accept=interp2app(descr_Tuple_accept, unwrap_spec=[ObjSpace, W_Root, W_Root] ), mutate=interp2app(descr_Tuple_mutate, unwrap_spec=[ObjSpace, W_Root, W_Root] ), nodes=GetSetProperty(Tuple.fget_nodes, Tuple.fset_nodes ), + insert_after=interp2app(Tuple.descr_insert_after.im_func, unwrap_spec=[ObjSpace, Tuple, Node, W_Root]), + insert_before=interp2app(Tuple.descr_insert_before.im_func, unwrap_spec=[ObjSpace, Tuple, Node, W_Root]), ) Tuple.typedef.acceptable_as_base_class = False Modified: pypy/dist/pypy/interpreter/astcompiler/ast.txt ============================================================================== --- pypy/dist/pypy/interpreter/astcompiler/ast.txt (original) +++ pypy/dist/pypy/interpreter/astcompiler/ast.txt Mon Feb 26 15:06:33 2007 @@ -71,7 +71,7 @@ CallFunc: node, args!, star_args& = None, dstar_args& = None Keyword: name*str, expr Subscript: expr, flags*int, sub -Ellipsis: +Ellipsis: Sliceobj: nodes! Slice: expr, flags*int, lower&, upper& Assert: test, fail& @@ -318,6 +318,7 @@ self.lineno = lineno return space.wrap(self) + def descr_Compare_mutate(space, w_self, w_visitor): w_expr = space.getattr(w_self, space.wrap("expr")) w_new_expr = space.call_method(w_expr, "mutate", w_visitor) @@ -337,6 +338,31 @@ return space.call_method(w_visitor, "visitCompare", w_self) +def descr_Compare_mutate(space, w_self, w_visitor): + w_expr = space.getattr(w_self, space.wrap("expr")) + w_mutate_expr = space.getattr(w_expr, space.wrap("mutate")) + w_mutate_expr_args = Arguments(space, [ w_visitor ]) + w_new_expr = space.call_args(w_mutate_expr, w_mutate_expr_args) + space.setattr(w_self, space.wrap("expr"), w_new_expr) + + w_list = space.getattr(w_self, space.wrap("ops")) + list_w = space.unpackiterable(w_list) + newlist_w = [] + for w_item in list_w: + w_opname, w_node = space.unpackiterable(w_item, 2) + + w_node_mutate = space.getattr(w_node, space.wrap("mutate")) + w_node_mutate_args = Arguments(space, [ w_visitor ]) + w_newnode = space.call_args(w_node_mutate, w_node_mutate_args) + + newlist_w.append(space.newtuple([w_opname, w_newnode])) + w_newlist = space.newlist(newlist_w) + space.setattr(w_self, space.wrap("ops"), w_newlist) + w_visitCompare = space.getattr(w_visitor, space.wrap("visitCompare")) + w_visitCompare_args = Arguments(space, [ w_self ]) + return space.call_args(w_visitCompare, w_visitCompare_args) + + def descr_Dict_new(space, w_subtype, w_items, lineno=-1): self = space.allocate_instance(Dict, w_subtype) items = [] Modified: pypy/dist/pypy/interpreter/astcompiler/astgen.py ============================================================================== --- pypy/dist/pypy/interpreter/astcompiler/astgen.py (original) +++ pypy/dist/pypy/interpreter/astcompiler/astgen.py Mon Feb 26 15:06:33 2007 @@ -319,6 +319,40 @@ print >> buf, " self.%s[:] = newlist"%(argname) print >> buf, " return visitor.visit%s(self)" % self.name + def _gen_insertnodes_func(self, buf): + print >> buf, " def descr_insert_after(space, self, node, w_added_nodes):" + print >> buf, " added_nodes = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_added_nodes)]" + print >> buf, " index = self.nodes.index(node) + 1" + print >> buf, " self.nodes[index:index] = added_nodes" + print >> buf + print >> buf, " def descr_insert_before(space, self, node, w_added_nodes):" + print >> buf, " added_nodes = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_added_nodes)]" + print >> buf, " index = self.nodes.index(node)" + print >> buf, " self.nodes[index:index] = added_nodes" + + + def _gen_mutate(self, buf): + print >> buf, " def mutate(self, visitor):" + if len(self.argnames) != 0: + for argname in self.argnames: + if argname in self.mutate_nodes: + for line in self.mutate_nodes[argname]: + if line.strip(): + print >> buf, ' ' + line + elif self.argprops[argname] == P_NODE: + print >> buf, " self.%s = self.%s.mutate(visitor)" % (argname,argname) + elif self.argprops[argname] == P_NONE: + print >> buf, " if self.%s is not None:" % (argname,) + print >> buf, " self.%s = self.%s.mutate(visitor)" % (argname,argname) + elif self.argprops[argname] == P_NESTED: + print >> buf, " newlist = []" + print >> buf, " for n in self.%s:"%(argname) + print >> buf, " item = n.mutate(visitor)" + print >> buf, " if item is not None:" + print >> buf, " newlist.append(item)" + print >> buf, " self.%s[:] = newlist"%(argname) + print >> buf, " return visitor.visit%s(self)" % self.name + def _gen_fget_func(self, buf, attr, prop ): # FGET print >> buf, " def fget_%s( space, self):" % attr @@ -370,6 +404,8 @@ if "fset_%s" % attr not in self.additional_methods: self._gen_fset_func( buf, attr, prop ) + if prop[attr] == P_NESTED and attr == 'nodes': + self._gen_insertnodes_func(buf) def _gen_descr_mutate(self, buf): if self.applevel_mutate: @@ -426,6 +462,9 @@ print >> buf, " mutate=interp2app(descr_%s_mutate, unwrap_spec=[ObjSpace, W_Root, W_Root] )," % self.name for attr in self.argnames: print >> buf, " %s=GetSetProperty(%s.fget_%s, %s.fset_%s )," % (attr,self.name,attr,self.name,attr) + if self.argprops[attr] == P_NESTED and attr == "nodes": + print >> buf, " insert_after=interp2app(%s.descr_insert_after.im_func, unwrap_spec=[ObjSpace, %s, Node, W_Root])," % (self.name, self.name) + print >> buf, " insert_before=interp2app(%s.descr_insert_before.im_func, unwrap_spec=[ObjSpace, %s, Node, W_Root])," % (self.name, self.name) print >> buf, " )" print >> buf, "%s.typedef.acceptable_as_base_class = False" % self.name @@ -660,6 +699,7 @@ def __init__(self, lineno = -1): self.lineno = lineno self.filename = "" + self.parent = None #self.scope = None def getChildren(self): @@ -691,6 +731,12 @@ def descr_repr( self, space ): return space.wrap( self.__repr__() ) + def fget_parent(space, self): + return space.wrap(self.parent) + + def fset_parent(space, self, w_parent): + self.parent = space.interp_w(Node, w_parent, can_be_None=False) + def descr_getChildNodes( self, space ): lst = self.getChildNodes() return space.newlist( [ space.wrap( it ) for it in lst ] ) @@ -714,10 +760,13 @@ mutate = interp2app(descr_node_mutate, unwrap_spec=[ ObjSpace, W_Root, W_Root ] ), lineno = interp_attrproperty('lineno', cls=Node), filename = interp_attrproperty('filename', cls=Node), + parent=GetSetProperty(Node.fget_parent, Node.fset_parent), ) Node.typedef.acceptable_as_base_class = False +Node.typedef.acceptable_as_base_class = False + class EmptyNode(Node): def accept(self, visitor): return visitor.visitEmptyNode(self) Modified: pypy/dist/pypy/interpreter/pycompiler.py ============================================================================== --- pypy/dist/pypy/interpreter/pycompiler.py (original) +++ pypy/dist/pypy/interpreter/pycompiler.py Mon Feb 26 15:06:33 2007 @@ -189,6 +189,7 @@ warnings.warn_explicit = old_warn_explicit + ######## class PythonAstCompiler(PyCodeCompiler): """Uses the stdlib's python implementation of compiler @@ -198,6 +199,13 @@ of incomplete inputs (e.g. we shouldn't re-compile from sracth the whole source after having only added a new '\n') """ + def __init__(self, space): + from pyparser.pythonparse import PYTHON_PARSER + PyCodeCompiler.__init__(self, space) + self.parser = PYTHON_PARSER + self.additional_rules = {} + + def compile(self, source, filename, mode, flags): from pyparser.error import SyntaxError from pypy.interpreter import astcompiler @@ -205,15 +213,18 @@ from pypy.interpreter.astcompiler.pycodegen import InteractiveCodeGenerator from pypy.interpreter.astcompiler.pycodegen import ExpressionCodeGenerator from pypy.interpreter.astcompiler.ast import Node - from pyparser.pythonutil import AstBuilder, PYTHON_PARSER, TARGET_DICT + from pyparser.astbuilder import AstBuilder from pypy.interpreter.pycode import PyCode + from pypy.interpreter.function import Function flags |= stdlib___future__.generators.compiler_flag # always on (2.2 compat) space = self.space try: - builder = AstBuilder(space=space) - target_rule = TARGET_DICT[mode] - PYTHON_PARSER.parse_source(source, target_rule, builder, flags) + builder = AstBuilder(self.parser, space=space) + for rulename, buildfunc in self.additional_rules.iteritems(): + assert isinstance(buildfunc, Function) + builder.user_build_rules[rulename] = buildfunc + self.parser.parse_source(source, mode, builder, flags) ast_tree = builder.rule_stack[-1] encoding = builder.source_encoding except SyntaxError, e: @@ -251,4 +262,29 @@ def install_compiler_hook(space, w_callable): # if not space.get( w_callable ): # raise OperationError( space.w_TypeError( space.wrap( "must have a callable" ) ) - space.default_compiler.w_compile_hook = w_callable + space.default_compiler.w_compile_hook = w_callable + +def insert_grammar_rule(space, w_rule, w_buildfuncs): + """inserts new grammar rules to the default compiler""" + from pypy.interpreter import function + rule = space.str_w(w_rule) + #buildfuncs_w = w_buildfuncs.content + buildfuncs = {} + #for w_name, w_func in buildfuncs_w.iteritems(): + # buildfuncs[space.str_w(w_name)] = space.unwrap(w_func) + w_iter = space.iter(w_buildfuncs) + while 1: + try: + w_key = space.next(w_iter) + w_func = space.getitem(w_buildfuncs, w_key) + buildfuncs[space.str_w(w_key)] = space.interp_w(function.Function, w_func) + except OperationError, e: + if not e.match(space, space.w_StopIteration): + raise + break + space.default_compiler.additional_rules = buildfuncs + space.default_compiler.parser.insert_rule(rule) + +# XXX cyclic import +#from pypy.interpreter.baseobjspace import ObjSpace +#insert_grammar_rule.unwrap_spec = [ObjSpace, str, dict] Modified: pypy/dist/pypy/interpreter/pyparser/astbuilder.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/astbuilder.py (original) +++ pypy/dist/pypy/interpreter/pyparser/astbuilder.py Mon Feb 26 15:06:33 2007 @@ -1,518 +1,18 @@ """This module provides the astbuilder class which is to be used -by GrammarElements to directly build the AST during parsing +by GrammarElements to directly build the AS during parsing without going through the nested tuples step """ from grammar import BaseGrammarBuilder, AbstractContext + +from pypy.interpreter.function import Function from pypy.interpreter.astcompiler import ast, consts -from pypy.interpreter.pyparser import pythonparse -import pypy.interpreter.pyparser.pytoken as tok +# from pypy.interpreter.pyparser import pythonparse +#import pypy.interpreter.pyparser.pytoken as tok from pypy.interpreter.pyparser.error import SyntaxError from pypy.interpreter.pyparser.parsestring import parsestr - -sym = pythonparse.PYTHON_PARSER.symbols - -DEBUG_MODE = 0 - -### Parsing utilites ################################################# -def parse_except_clause(tokens): - """parses 'except' [test [',' test]] ':' suite - and returns a 4-tuple : (tokens_read, expr1, expr2, except_body) - """ - lineno = tokens[0].lineno - clause_length = 1 - # Read until end of except clause (bound by following 'else', - # or 'except' or end of tokens) - while clause_length < len(tokens): - token = tokens[clause_length] - if isinstance(token, TokenObject) and \ - (token.get_value() == 'except' or token.get_value() == 'else'): - break - clause_length += 1 - if clause_length == 3: - # case 'except: body' - return (3, None, None, tokens[2]) - elif clause_length == 4: - # case 'except Exception: body': - return (4, tokens[1], None, tokens[3]) - else: - # case 'except Exception, exc: body' - return (6, tokens[1], to_lvalue(tokens[3], consts.OP_ASSIGN), tokens[5]) - - -def parse_dotted_names(tokens): - """parses NAME('.' NAME)* and returns full dotted name - - this function doesn't assume that the list ends after the - last 'NAME' element - """ - first = tokens[0] - assert isinstance(first, TokenObject) - name = first.get_value() - l = len(tokens) - index = 1 - for index in range(1, l, 2): - token = tokens[index] - assert isinstance(token, TokenObject) - if token.name != tok.DOT: - break - token = tokens[index+1] - assert isinstance(token, TokenObject) - name += '.' - value = token.get_value() - name += value - return (index, name) - -def parse_argument(tokens): - """parses function call arguments""" - l = len(tokens) - index = 0 - arguments = [] - last_token = None - building_kw = False - kw_built = False - stararg_token = None - dstararg_token = None - while index < l: - cur_token = tokens[index] - if not isinstance(cur_token, TokenObject): - index += 1 - if not building_kw: - arguments.append(cur_token) - else: - last_token = arguments.pop() - assert isinstance(last_token, ast.Name) # used by rtyper - arguments.append(ast.Keyword(last_token.varname, cur_token, last_token.lineno)) - building_kw = False - kw_built = True - continue - elif cur_token.name == tok.COMMA: - index += 1 - continue - elif cur_token.name == tok.EQUAL: - index += 1 - building_kw = True - continue - elif cur_token.name == tok.STAR or cur_token.name == tok.DOUBLESTAR: - index += 1 - if cur_token.name == tok.STAR: - stararg_token = tokens[index] - index += 1 - if index >= l: - break - index += 2 # Skip COMMA and DOUBLESTAR - dstararg_token = tokens[index] - break - elif cur_token.get_value() == 'for': - if len(arguments) != 1: - raise SyntaxError("invalid syntax", cur_token.lineno, - cur_token.col) - expr = arguments[0] - genexpr_for = parse_genexpr_for(tokens[index:]) - genexpr_for[0].is_outmost = True - gexp = ast.GenExpr(ast.GenExprInner(expr, genexpr_for, expr.lineno), expr.lineno) - arguments[0] = gexp - break - return arguments, stararg_token, dstararg_token - - -def parse_fpdef(tokens, index): - """fpdef: fpdef: NAME | '(' fplist ')' - fplist: fpdef (',' fpdef)* [','] - - This intend to be a RPYTHON compliant implementation of _parse_fpdef, - but it can't work with the default compiler. - We switched to use astcompiler module now - """ - nodes = [] - comma = False - while True: - token = tokens[index] - index += 1 - assert isinstance(token, TokenObject) - if token.name == tok.LPAR: # nested item - index, node = parse_fpdef(tokens, index) - elif token.name == tok.RPAR: # end of current nesting - break - else: # name - val = token.get_value() - node = ast.AssName(val, consts.OP_ASSIGN, token.lineno) - nodes.append(node) - - token = tokens[index] - index += 1 - assert isinstance(token, TokenObject) - if token.name == tok.COMMA: - comma = True - else: - assert token.name == tok.RPAR - break - if len(nodes) == 1 and not comma: - node = nodes[0] - else: - node = ast.AssTuple(nodes, token.lineno) - return index, node - -def parse_arglist(tokens): - """returns names, defaults, flags""" - l = len(tokens) - index = 0 - defaults = [] - names = [] - flags = 0 - first_with_default = -1 - while index < l: - cur_token = tokens[index] - index += 1 - if not isinstance(cur_token, TokenObject): - # XXX: think of another way to write this test - defaults.append(cur_token) - if first_with_default == -1: - first_with_default = len(names) - 1 - elif cur_token.name == tok.COMMA: - # We could skip test COMMA by incrementing index cleverly - # but we might do some experiment on the grammar at some point - continue - elif cur_token.name == tok.LPAR: - index, node = parse_fpdef(tokens, index) - names.append(node) - elif cur_token.name == tok.STAR or cur_token.name == tok.DOUBLESTAR: - if cur_token.name == tok.STAR: - cur_token = tokens[index] - assert isinstance(cur_token, TokenObject) - index += 1 - if cur_token.name == tok.NAME: - val = cur_token.get_value() - names.append( ast.AssName( val, consts.OP_ASSIGN ) ) - flags |= consts.CO_VARARGS - index += 1 - if index >= l: - break - else: - # still more tokens to read - cur_token = tokens[index] - index += 1 - else: - raise SyntaxError("incomplete varags", cur_token.lineno, - cur_token.col) - assert isinstance(cur_token, TokenObject) - if cur_token.name != tok.DOUBLESTAR: - raise SyntaxError("Unexpected token", cur_token.lineno, - cur_token.col) - cur_token = tokens[index] - index += 1 - assert isinstance(cur_token, TokenObject) - if cur_token.name == tok.NAME: - val = cur_token.get_value() - names.append( ast.AssName( val, consts.OP_ASSIGN ) ) - flags |= consts.CO_VARKEYWORDS - index += 1 - else: - raise SyntaxError("incomplete varags", cur_token.lineno, - cur_token.col) - if index < l: - token = tokens[index] - raise SyntaxError("unexpected token" , token.lineno, - token.col) - elif cur_token.name == tok.NAME: - val = cur_token.get_value() - names.append( ast.AssName( val, consts.OP_ASSIGN ) ) - - if first_with_default != -1: - num_expected_with_default = len(names) - first_with_default - if flags & consts.CO_VARKEYWORDS: - num_expected_with_default -= 1 - if flags & consts.CO_VARARGS: - num_expected_with_default -= 1 - if len(defaults) != num_expected_with_default: - raise SyntaxError('non-default argument follows default argument', - tokens[0].lineno, tokens[0].col) - return names, defaults, flags - - -def parse_listcomp(tokens): - """parses 'for j in k for i in j if i %2 == 0' and returns - a GenExprFor instance - XXX: refactor with listmaker ? - """ - list_fors = [] - ifs = [] - index = 0 - if tokens: - lineno = tokens[0].lineno - else: - lineno = -1 - while index < len(tokens): - token = tokens[index] - assert isinstance(token, TokenObject) # rtyper info + check - if token.get_value() == 'for': - index += 1 # skip 'for' - ass_node = to_lvalue(tokens[index], consts.OP_ASSIGN) - index += 2 # skip 'in' - iterables = [tokens[index]] - index += 1 - while index < len(tokens): - tok2 = tokens[index] - if not isinstance(tok2, TokenObject): - break - if tok2.name != tok.COMMA: - break - iterables.append(tokens[index+1]) - index += 2 - if len(iterables) == 1: - iterable = iterables[0] - else: - iterable = ast.Tuple(iterables, token.lineno) - while index < len(tokens): - token = tokens[index] - assert isinstance(token, TokenObject) # rtyper info - if token.get_value() == 'if': - ifs.append(ast.ListCompIf(tokens[index+1], token.lineno)) - index += 2 - else: - break - list_fors.append(ast.ListCompFor(ass_node, iterable, ifs, lineno)) - ifs = [] - else: - assert False, 'Unexpected token: expecting for in listcomp' - # - # Original implementation: - # - # if tokens[index].get_value() == 'for': - # index += 1 # skip 'for' - # ass_node = to_lvalue(tokens[index], consts.OP_ASSIGN) - # index += 2 # skip 'in' - # iterable = tokens[index] - # index += 1 - # while index < len(tokens) and tokens[index].get_value() == 'if': - # ifs.append(ast.ListCompIf(tokens[index+1])) - # index += 2 - # list_fors.append(ast.ListCompFor(ass_node, iterable, ifs)) - # ifs = [] - # else: - # raise ValueError('Unexpected token: %s' % tokens[index]) - return list_fors - - -def parse_genexpr_for(tokens): - """parses 'for j in k for i in j if i %2 == 0' and returns - a GenExprFor instance - XXX: if RPYTHON supports to pass a class object to a function, - we could refactor parse_listcomp and parse_genexpr_for, - and call : - - parse_listcomp(tokens, forclass=ast.GenExprFor, ifclass=...) - or: - - parse_listcomp(tokens, forclass=ast.ListCompFor, ifclass=...) - """ - genexpr_fors = [] - ifs = [] - index = 0 - if tokens: - lineno = tokens[0].lineno - else: - lineno = -1 - while index < len(tokens): - token = tokens[index] - assert isinstance(token, TokenObject) # rtyper info + check - if token.get_value() == 'for': - index += 1 # skip 'for' - ass_node = to_lvalue(tokens[index], consts.OP_ASSIGN) - index += 2 # skip 'in' - iterable = tokens[index] - index += 1 - while index < len(tokens): - token = tokens[index] - assert isinstance(token, TokenObject) # rtyper info - if token.get_value() == 'if': - ifs.append(ast.GenExprIf(tokens[index+1], token.lineno)) - index += 2 - else: - break - genexpr_fors.append(ast.GenExprFor(ass_node, iterable, ifs, lineno)) - ifs = [] - else: - raise SyntaxError('invalid syntax', - token.lineno, token.col) - return genexpr_fors - - -def get_docstring(builder,stmt): - """parses a Stmt node. - - If a docstring if found, the Discard node is **removed** - from and the docstring is returned. - - If no docstring is found, is left unchanged - and None is returned - """ - if not isinstance(stmt, ast.Stmt): - return None - doc = builder.wrap_none() - if len(stmt.nodes): - first_child = stmt.nodes[0] - if isinstance(first_child, ast.Discard): - expr = first_child.expr - if builder.is_basestring_const(expr): - # This *is* a docstring, remove it from stmt list - assert isinstance(expr, ast.Const) - del stmt.nodes[0] - doc = expr.value - return doc - - -def to_lvalue(ast_node, flags): - lineno = ast_node.lineno - if isinstance( ast_node, ast.Name ): - return ast.AssName(ast_node.varname, flags, lineno) - # return ast.AssName(ast_node.name, flags) - elif isinstance(ast_node, ast.Tuple): - nodes = [] - # FIXME: should ast_node.getChildren() but it's not annotable - # because of flatten() - for node in ast_node.nodes: - nodes.append(to_lvalue(node, flags)) - return ast.AssTuple(nodes, lineno) - elif isinstance(ast_node, ast.List): - nodes = [] - # FIXME: should ast_node.getChildren() but it's not annotable - # because of flatten() - for node in ast_node.nodes: - nodes.append(to_lvalue(node, flags)) - return ast.AssList(nodes, lineno) - elif isinstance(ast_node, ast.Getattr): - expr = ast_node.expr - assert isinstance(ast_node, ast.Getattr) - attrname = ast_node.attrname - return ast.AssAttr(expr, attrname, flags, lineno) - elif isinstance(ast_node, ast.Subscript): - ast_node.flags = flags - return ast_node - elif isinstance(ast_node, ast.Slice): - ast_node.flags = flags - return ast_node - else: - if isinstance(ast_node, ast.GenExpr): - raise SyntaxError("assign to generator expression not possible", - lineno, 0, '') - elif isinstance(ast_node, ast.ListComp): - raise SyntaxError("can't assign to list comprehension", - lineno, 0, '') - elif isinstance(ast_node, ast.CallFunc): - if flags == consts.OP_DELETE: - raise SyntaxError("can't delete function call", - lineno, 0, '') - else: - raise SyntaxError("can't assign to function call", - lineno, 0, '') - else: - raise SyntaxError("can't assign to non-lvalue", - lineno, 0, '') - -def is_augassign( ast_node ): - if ( isinstance( ast_node, ast.Name ) or - isinstance( ast_node, ast.Slice ) or - isinstance( ast_node, ast.Subscript ) or - isinstance( ast_node, ast.Getattr ) ): - return True - return False - -def get_atoms(builder, nb): - atoms = [] - i = nb - while i>0: - obj = builder.pop() - if isinstance(obj, BaseRuleObject): - i += obj.count - else: - atoms.append( obj ) - i -= 1 - atoms.reverse() - return atoms - -#def eval_string(value): -# """temporary implementation -# -# FIXME: need to be finished (check compile.c (parsestr) and -# stringobject.c (PyString_DecodeEscape()) for complete implementation) -# """ -# # return eval(value) -# if len(value) == 2: -# return '' -# result = '' -# length = len(value) -# quotetype = value[0] -# index = 1 -# while index < length and value[index] == quotetype: -# index += 1 -# if index == 6: -# # empty strings like """""" or '''''' -# return '' -# # XXX: is it RPYTHON to do this value[index:-index] -# chars = [char for char in value[index:len(value)-index]] -# result = ''.join(chars) -# result = result.replace('\\\\', '\\') -# d = {'\\b' : '\b', '\\f' : '\f', '\\t' : '\t', '\\n' : '\n', -# '\\r' : '\r', '\\v' : '\v', '\\a' : '\a', -# } -# for escaped, value in d.items(): -# result = result.replace(escaped, value) -# return result - - -## misc utilities, especially for power: rule -def reduce_callfunc(obj, arglist): - """generic factory for CallFunc nodes""" - assert isinstance(arglist, ArglistObject) - return ast.CallFunc(obj, arglist.arguments, - arglist.stararg, arglist.dstararg, arglist.lineno) - -def reduce_subscript(obj, subscript): - """generic factory for Subscript nodes""" - assert isinstance(subscript, SubscriptObject) - return ast.Subscript(obj, consts.OP_APPLY, subscript.value, subscript.lineno) - -def reduce_slice(obj, sliceobj): - """generic factory for Slice nodes""" - assert isinstance(sliceobj, SlicelistObject) - if sliceobj.fake_rulename == 'slice': - start = sliceobj.value[0] - end = sliceobj.value[1] - return ast.Slice(obj, consts.OP_APPLY, start, end, sliceobj.lineno) - else: - return ast.Subscript(obj, consts.OP_APPLY, ast.Sliceobj(sliceobj.value, - sliceobj.lineno), sliceobj.lineno) - -def parse_attraccess(tokens): - """parses token list like ['a', '.', 'b', '.', 'c', ...] - - and returns an ast node : ast.Getattr(Getattr(Name('a'), 'b'), 'c' ...) - """ - token = tokens[0] - # XXX HACK for when parse_attraccess is called from build_decorator - if isinstance(token, TokenObject): - val = token.get_value() - result = ast.Name(val, token.lineno) - else: - result = token - index = 1 - while index < len(tokens): - token = tokens[index] - if isinstance(token, TokenObject) and token.name == tok.DOT: - index += 1 - token = tokens[index] - assert isinstance(token, TokenObject) - result = ast.Getattr(result, token.get_value(), token.lineno) - elif isinstance(token, ArglistObject): - result = reduce_callfunc(result, token) - elif isinstance(token, SubscriptObject): - result = reduce_subscript(result, token) - elif isinstance(token, SlicelistObject): - result = reduce_slice(result, token) - else: - assert False, "Don't know how to handle index %s of %s" % (index, len(tokens)) - index += 1 - return result - +from pypy.interpreter.gateway import interp2app +from asthelper import * ## building functions helpers ## -------------------------- @@ -546,31 +46,31 @@ top = atoms[0] if isinstance(top, TokenObject): # assert isinstance(top, TokenObject) # rtyper - if top.name == tok.LPAR: + if top.name == builder.parser.tokens['LPAR']: if len(atoms) == 2: builder.push(ast.Tuple([], top.lineno)) else: builder.push( atoms[1] ) - elif top.name == tok.LSQB: + elif top.name == builder.parser.tokens['LSQB']: if len(atoms) == 2: 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: + elif top.name == builder.parser.tokens['LBRACE']: items = [] for index in range(1, len(atoms)-1, 4): # a : b , c : d # ^ +1 +2 +3 +4 items.append((atoms[index], atoms[index+2])) builder.push(ast.Dict(items, top.lineno)) - elif top.name == tok.NAME: + elif top.name == builder.parser.tokens['NAME']: val = top.get_value() builder.push( ast.Name(val, top.lineno) ) - elif top.name == tok.NUMBER: + elif top.name == builder.parser.tokens['NUMBER']: builder.push(ast.Const(builder.eval_number(top.get_value()), top.lineno)) - elif top.name == tok.STRING: + elif top.name == builder.parser.tokens['STRING']: # need to concatenate strings in atoms s = '' if len(atoms) == 1: @@ -586,7 +86,7 @@ accum.append(parsestr(builder.space, builder.source_encoding, token.get_value())) w_s = space.call_method(empty, 'join', space.newlist(accum)) builder.push(ast.Const(w_s, top.lineno)) - elif top.name == tok.BACKQUOTE: + elif top.name == builder.parser.tokens['BACKQUOTE']: builder.push(ast.Backquote(atoms[1], atoms[1].lineno)) else: raise SyntaxError("unexpected tokens", top.lineno, top.col) @@ -607,11 +107,11 @@ else: lineno = atoms[0].lineno token = atoms[-2] - if isinstance(token, TokenObject) and token.name == tok.DOUBLESTAR: - obj = parse_attraccess(slicecut(atoms, 0, -2)) + if isinstance(token, TokenObject) and token.name == builder.parser.tokens['DOUBLESTAR']: + obj = parse_attraccess(slicecut(atoms, 0, -2), builder) builder.push(ast.Power( obj, atoms[-1], lineno)) else: - obj = parse_attraccess(atoms) + obj = parse_attraccess(atoms, builder) builder.push(obj) def build_factor(builder, nb): @@ -622,11 +122,11 @@ token = atoms[0] lineno = token.lineno if isinstance(token, TokenObject): - if token.name == tok.PLUS: + if token.name == builder.parser.tokens['PLUS']: builder.push( ast.UnaryAdd( atoms[1], lineno) ) - if token.name == tok.MINUS: + if token.name == builder.parser.tokens['MINUS']: builder.push( ast.UnarySub( atoms[1], lineno) ) - if token.name == tok.TILDE: + if token.name == builder.parser.tokens['TILDE']: builder.push( ast.Invert( atoms[1], lineno) ) def build_term(builder, nb): @@ -637,13 +137,13 @@ right = atoms[i] op_node = atoms[i-1] assert isinstance(op_node, TokenObject) - if op_node.name == tok.STAR: + if op_node.name == builder.parser.tokens['STAR']: left = ast.Mul( left, right, left.lineno ) - elif op_node.name == tok.SLASH: + elif op_node.name == builder.parser.tokens['SLASH']: left = ast.Div( left, right, left.lineno ) - elif op_node.name == tok.PERCENT: + elif op_node.name == builder.parser.tokens['PERCENT']: left = ast.Mod( left, right, left.lineno ) - elif op_node.name == tok.DOUBLESLASH: + elif op_node.name == builder.parser.tokens['DOUBLESLASH']: left = ast.FloorDiv( left, right, left.lineno ) else: token = atoms[i-1] @@ -658,9 +158,9 @@ right = atoms[i] op_node = atoms[i-1] assert isinstance(op_node, TokenObject) - if op_node.name == tok.PLUS: + if op_node.name == builder.parser.tokens['PLUS']: left = ast.Add( left, right, left.lineno) - elif op_node.name == tok.MINUS: + elif op_node.name == builder.parser.tokens['MINUS']: left = ast.Sub( left, right, left.lineno) else: token = atoms[i-1] @@ -676,9 +176,9 @@ right = atoms[i] op_node = atoms[i-1] assert isinstance(op_node, TokenObject) - if op_node.name == tok.LEFTSHIFT: + if op_node.name == builder.parser.tokens['LEFTSHIFT']: left = ast.LeftShift( left, right, lineno ) - elif op_node.name == tok.RIGHTSHIFT: + elif op_node.name == builder.parser.tokens['RIGHTSHIFT']: left = ast.RightShift( left, right, lineno ) else: token = atoms[i-1] @@ -727,7 +227,7 @@ # 'is', 'is not', 'not' or 'not in' => tok.get_value() token = atoms[i] assert isinstance(token, TokenObject) - op_name = tok.tok_rpunct.get(token.name, token.get_value()) + op_name = builder.parser.tok_rvalues.get(token.name, token.get_value()) ops.append((op_name, atoms[i+1])) builder.push(ast.Compare(atoms[0], ops, atoms[0].lineno)) @@ -755,9 +255,9 @@ lineno = token.lineno assert isinstance(token, TokenObject) if token.get_value() == 'not': - builder.push(TokenObject(tok.NAME, 'not in', lineno)) + builder.push(TokenObject(builder.parser.tokens['NAME'], 'not in', lineno, builder.parser)) else: - builder.push(TokenObject(tok.NAME, 'is not', lineno)) + builder.push(TokenObject(builder.parser.tokens['NAME'], 'is not', lineno, builder.parser)) else: assert False, "TODO" # uh ? @@ -811,7 +311,7 @@ return op = atoms[1] assert isinstance(op, TokenObject) - if op.name == tok.EQUAL: + if op.name == builder.parser.tokens['EQUAL']: nodes = [] for i in range(0,l-2,2): lvalue = to_lvalue(atoms[i], consts.OP_ASSIGN) @@ -845,7 +345,7 @@ lineno = -1 for n in range(0,l,2): node = atoms[n] - if isinstance(node, TokenObject) and node.name == tok.NEWLINE: + if isinstance(node, TokenObject) and node.name == builder.parser.tokens['NEWLINE']: nodes.append(ast.Discard(ast.Const(builder.wrap_none()), node.lineno)) else: nodes.append(node) @@ -871,10 +371,10 @@ for node in atoms: if isinstance(node, ast.Stmt): stmts.extend(node.nodes) - elif isinstance(node, TokenObject) and node.name == tok.ENDMARKER: + elif isinstance(node, TokenObject) and node.name == builder.parser.tokens['ENDMARKER']: # XXX Can't we just remove the last element of the list ? break - elif isinstance(node, TokenObject) and node.name == tok.NEWLINE: + elif isinstance(node, TokenObject) and node.name == builder.parser.tokens['NEWLINE']: continue else: stmts.append(node) @@ -894,11 +394,12 @@ l = len(atoms) if l == 1 or l==2: atom0 = atoms[0] - if isinstance(atom0, TokenObject) and atom0.name == tok.NEWLINE: - atom0 = ast.Pass(atom0.lineno) + if isinstance(atom0, TokenObject) and atom0.name == builder.parser.tokens['NEWLINE']: + # atom0 = ast.Pass(atom0.lineno) # break test_astcompiler + atom0 = ast.Stmt([], atom0.lineno) # break test_astbuilder elif not isinstance(atom0, ast.Stmt): atom0 = ast.Stmt([atom0], atom0.lineno) - builder.push(ast.Module(builder.wrap_none(), atom0, atom0.lineno)) + builder.push(ast.Module(builder.space.w_None, atom0, atom0.lineno)) else: assert False, "Forbidden path" @@ -914,7 +415,7 @@ return items = [] token = atoms[1] - if isinstance(token, TokenObject) and token.name == tok.COMMA: + if isinstance(token, TokenObject) and token.name == builder.parser.tokens['COMMA']: for i in range(0, l, 2): # this is atoms not 1 items.append(atoms[i]) else: @@ -944,7 +445,7 @@ atoms = get_atoms(builder, nb) lineno = atoms[0].lineno code = atoms[-1] - names, defaults, flags = parse_arglist(slicecut(atoms, 1, -2)) + names, defaults, flags = parse_arglist(slicecut(atoms, 1, -2), builder) builder.push(ast.Lambda(names, defaults, flags, code, lineno)) def build_trailer(builder, nb): @@ -953,13 +454,13 @@ atoms = get_atoms(builder, nb) first_token = atoms[0] # Case 1 : '(' ... - if isinstance(first_token, TokenObject) and first_token.name == tok.LPAR: - if len(atoms) == 2: # and atoms[1].token == tok.RPAR: + if isinstance(first_token, TokenObject) and first_token.name == builder.parser.tokens['LPAR']: + if len(atoms) == 2: # and atoms[1].token == builder.parser.tokens['RPAR']: builder.push(ArglistObject([], None, None, first_token.lineno)) elif len(atoms) == 3: # '(' Arglist ')' # push arglist on the stack builder.push(atoms[1]) - elif isinstance(first_token, TokenObject) and first_token.name == tok.LSQB: + elif isinstance(first_token, TokenObject) and first_token.name == builder.parser.tokens['LSQB']: if len(atoms) == 3 and isinstance(atoms[1], SlicelistObject): builder.push(atoms[1]) else: @@ -994,6 +495,7 @@ else: assert False, "Trailer reducing implementation incomplete !" + def build_arglist(builder, nb): """ arglist: (argument ',')* ( '*' test [',' '**' test] | @@ -1002,7 +504,7 @@ [argument ','] ) """ atoms = get_atoms(builder, nb) - arguments, stararg, dstararg = parse_argument(atoms) + arguments, stararg, dstararg = parse_argument(atoms, builder) if atoms: lineno = atoms[0].lineno else: @@ -1010,16 +512,17 @@ builder.push(ArglistObject(arguments, stararg, dstararg, lineno)) + def build_subscript(builder, nb): """'.' '.' '.' | [test] ':' [test] [':' [test]] | test""" atoms = get_atoms(builder, nb) token = atoms[0] lineno = token.lineno - if isinstance(token, TokenObject) and token.name == tok.DOT: + if isinstance(token, TokenObject) and token.name == builder.parser.tokens['DOT']: # Ellipsis: builder.push(ast.Ellipsis(lineno)) elif len(atoms) == 1: - if isinstance(token, TokenObject) and token.name == tok.COLON: + if isinstance(token, TokenObject) and token.name == builder.parser.tokens['COLON']: sliceinfos = [None, None, None] builder.push(SlicelistObject('slice', sliceinfos, lineno)) else: @@ -1029,7 +532,7 @@ sliceinfos = [None, None, None] infosindex = 0 for token in atoms: - if isinstance(token, TokenObject) and token.name == tok.COLON: + if isinstance(token, TokenObject) and token.name == builder.parser.tokens['COLON']: infosindex += 1 else: sliceinfos[infosindex] = token @@ -1044,7 +547,6 @@ else: builder.push(SlicelistObject('slice', sliceinfos, lineno)) - def build_listmaker(builder, nb): """listmaker: test ( list_for | (',' test)* [','] )""" atoms = get_atoms(builder, nb) @@ -1055,7 +557,7 @@ if token.get_value() == 'for': # list comp expr = atoms[0] - list_for = parse_listcomp(atoms[1:]) + list_for = parse_listcomp(atoms[1:], builder) builder.push(ast.ListComp(expr, list_for, lineno)) return # regular list building (like in [1, 2, 3,]) @@ -1077,13 +579,15 @@ nodes = [] # remove '@', '(' and ')' from atoms and use parse_attraccess for token in atoms[1:]: - if isinstance(token, TokenObject) and \ - token.name in (tok.LPAR, tok.RPAR, tok.NEWLINE): + if isinstance(token, TokenObject) and ( + token.name == builder.parser.tokens['LPAR'] + or token.name == builder.parser.tokens['RPAR'] + or token.name == builder.parser.tokens['NEWLINE']): # skip those ones continue else: nodes.append(token) - obj = parse_attraccess(nodes) + obj = parse_attraccess(nodes, builder) builder.push(obj) def build_funcdef(builder, nb): @@ -1112,7 +616,7 @@ arglist = [] index = 3 arglist = slicecut(atoms, 3, -3) - names, default, flags = parse_arglist(arglist) + names, default, flags = parse_arglist(arglist, builder) funcname_token = atoms[1] assert isinstance(funcname_token, TokenObject) funcname = funcname_token.get_value() @@ -1293,7 +797,7 @@ while index < l: as_name = None # dotted name (a.b.c) - incr, name = parse_dotted_names(atoms[index:]) + incr, name = parse_dotted_names(atoms[index:], builder) index += incr # 'as' value if index < l: @@ -1310,11 +814,11 @@ while index 1: token = atoms[1] - if isinstance(token, TokenObject) and token.name == tok.RIGHTSHIFT: + if isinstance(token, TokenObject) and token.name == builder.parser.tokens['RIGHTSHIFT']: dest = atoms[2] # skip following comma start = 4 for index in range(start, l, 2): items.append(atoms[index]) last_token = atoms[-1] - if isinstance(last_token, TokenObject) and last_token.name == tok.COMMA: + if isinstance(last_token, TokenObject) and last_token.name == builder.parser.tokens['COMMA']: builder.push(ast.Print(items, dest, atoms[0].lineno)) else: builder.push(ast.Printnl(items, dest, atoms[0].lineno)) @@ -1464,8 +968,8 @@ """ atoms = get_atoms(builder, nb) - l = len(atoms) handlers = [] + l = len(atoms) else_ = None body = atoms[2] token = atoms[3] @@ -1545,133 +1049,6 @@ 'with_stmt' : build_with_stmt, } -# Build two almost identical ASTRULES dictionaries -ASTRULES = dict([(sym[key], value) for (key, value) in - ASTRULES_Template.iteritems() if key in sym]) -del ASTRULES_Template - -## Stack elements definitions ################################### - -class BaseRuleObject(ast.Node): - """Base class for unnamed rules""" - def __init__(self, count, lineno): - self.count = count - self.lineno = lineno # src.getline() - self.col = 0 # src.getcol() - - -class RuleObject(BaseRuleObject): - """A simple object used to wrap a rule or token""" - def __init__(self, name, count, lineno): - BaseRuleObject.__init__(self, count, lineno) - self.rulename = name - - def __str__(self): - return "" % (sym.sym_name[self.rulename], self.count) - - def __repr__(self): - return "" % (sym.sym_name[self.rulename], self.count) - - -class TempRuleObject(BaseRuleObject): - """used to keep track of how many items get_atom() should pop""" - - def __init__(self, name, count, lineno): - BaseRuleObject.__init__(self, count, lineno) - self.temp_rulename = name - - def __str__(self): - return "" % (self.temp_rulename, self.count) - - def __repr__(self): - return "" % (self.temp_rulename, self.count) - - -class TokenObject(ast.Node): - """A simple object used to wrap a rule or token""" - def __init__(self, name, value, lineno): - self.name = name - self.value = value - self.count = 0 - # self.line = 0 # src.getline() - self.col = 0 # src.getcol() - self.lineno = lineno - - def get_name(self): - return tok.tok_rpunct.get(self.name, - tok.tok_name.get(self.name, str(self.name))) - - def get_value(self): - value = self.value - if value is None: - value = '' - return value - - def __str__(self): - return "" % (self.get_name(), self.value) - - def __repr__(self): - return "" % (self.get_name(), self.value) - - -class ObjectAccessor(ast.Node): - """base class for ArglistObject, SubscriptObject and SlicelistObject - - FIXME: think about a more appropriate name - """ - -class ArglistObject(ObjectAccessor): - """helper class to build function's arg list - """ - def __init__(self, arguments, stararg, dstararg, lineno): - self.fake_rulename = 'arglist' - self.arguments = arguments - self.stararg = stararg - self.dstararg = dstararg - self.lineno = lineno - - def __str__(self): - return "" % self.value - - def __repr__(self): - return "" % self.value - -class SubscriptObject(ObjectAccessor): - """helper class to build subscript list - - self.value represents the __getitem__ argument - """ - def __init__(self, name, value, lineno): - self.fake_rulename = name - self.value = value - self.lineno = lineno - - def __str__(self): - return "" % self.value - - def __repr__(self): - return "" % self.value - -class SlicelistObject(ObjectAccessor): - """helper class to build slice objects - - self.value is a list [start, end, step] - self.fake_rulename can either be 'slice' or 'sliceobj' depending - on if a step is specfied or not (see Python's AST - for more information on that) - """ - def __init__(self, name, value, lineno): - self.fake_rulename = name - self.value = value - self.lineno = lineno - - def __str__(self): - return "" % self.value - - def __repr__(self): - return "" % self.value - - class AstBuilderContext(AbstractContext): """specific context management for AstBuidler""" def __init__(self, rule_stack): @@ -1681,97 +1058,87 @@ class AstBuilder(BaseGrammarBuilder): """A builder that directly produce the AST""" - def __init__(self, rules=None, debug=0, space=None): - BaseGrammarBuilder.__init__(self, rules, debug) + def __init__(self, parser, debug=0, space=None): + BaseGrammarBuilder.__init__(self, parser, debug) self.rule_stack = [] self.space = space self.source_encoding = None self.with_enabled = False + self.build_rules = ASTRULES_Template + self.user_build_rules = {} def enable_with(self): if self.with_enabled: return self.with_enabled = True - self.keywords.update({'with':None, 'as': None}) - + # XXX + # self.keywords.update({'with':None, 'as': None}) + def context(self): return AstBuilderContext(self.rule_stack) def restore(self, ctx): -## if DEBUG_MODE: -## print "Restoring context (%s)" % (len(ctx.rule_stack)) assert isinstance(ctx, AstBuilderContext) 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) def push(self, obj): self.rule_stack.append(obj) - if not isinstance(obj, RuleObject) and not isinstance(obj, TokenObject): -## if DEBUG_MODE: -## print "Pushed:", str(obj), len(self.rule_stack) - pass - elif isinstance(obj, TempRuleObject): -## if DEBUG_MODE: -## print "Pushed:", str(obj), len(self.rule_stack) - pass - # print "\t", self.rule_stack def push_tok(self, name, value, src ): - self.push( TokenObject( name, value, src._token_lnum ) ) + self.push( TokenObject( name, value, src._token_lnum, self.parser ) ) def push_rule(self, name, count, src ): - self.push( RuleObject( name, count, src._token_lnum ) ) + self.push( RuleObject( name, count, src._token_lnum, self.parser ) ) def alternative( self, rule, source ): # Do nothing, keep rule on top of the stack -## rule_stack = self.rule_stack[:] if rule.is_root(): -## if DEBUG_MODE: -## print "ALT:", sym.sym_name[rule.codename], self.rule_stack - builder_func = ASTRULES.get(rule.codename, None) - if builder_func: - builder_func(self, 1) + rulename = self.parser.sym_name[rule.codename] + # builder_func = ASTRULES.get(rule.codename, None) + w_func = self.user_build_rules.get(rulename, None) + # user defined (applevel) function + if w_func: + w_items = self.space.newlist( [self.space.wrap( it ) for it in get_atoms(self, 1)] ) + w_astnode = self.space.call_function(w_func, w_items) + astnode = self.space.interp_w(ast.Node, w_astnode, can_be_None=False) + self.push(astnode) else: -## if DEBUG_MODE: -## print "No reducing implementation for %s, just push it on stack" % ( -## sym.sym_name[rule.codename]) - self.push_rule(rule.codename, 1, source) + builder_func = self.build_rules.get(rulename, None) + if builder_func: + builder_func(self, 1) + else: + self.push_rule(rule.codename, 1, source) else: self.push_rule(rule.codename, 1, source) -## if DEBUG_MODE > 1: -## show_stack(rule_stack, self.rule_stack) -## x = raw_input("Continue ?") return True def sequence(self, rule, source, elts_number): """ """ -## rule_stack = self.rule_stack[:] if rule.is_root(): -## if DEBUG_MODE: -## print "SEQ:", sym.sym_name[rule.codename] - builder_func = ASTRULES.get(rule.codename, None) - if builder_func: - # print "REDUCING SEQUENCE %s" % sym.sym_name[rule.codename] - builder_func(self, elts_number) + rulename = self.parser.sym_name[rule.codename] + # builder_func = ASTRULES.get(rule.codename, None) + w_func = self.user_build_rules.get(rulename, None) + # user defined (applevel) function + if w_func: + w_items = self.space.newlist( [self.space.wrap( it ) for it in get_atoms(self, elts_number)] ) + w_astnode = self.space.call_function(w_func, w_items) + astnode = self.space.interp_w(ast.Node, w_astnode, can_be_None=False) + self.push(astnode) else: -## if DEBUG_MODE: -## print "No reducing implementation for %s, just push it on stack" % ( -## sym.sym_name[rule.codename]) - self.push_rule(rule.codename, elts_number, source) + builder_func = self.build_rules.get(rulename, None) + if builder_func: + builder_func(self, elts_number) + else: + self.push_rule(rule.codename, elts_number, source) else: self.push_rule(rule.codename, elts_number, source) -## if DEBUG_MODE > 1: -## show_stack(rule_stack, self.rule_stack) -## raw_input("Continue ?") return True def token(self, name, value, source): -## if DEBUG_MODE: -## print "TOK:", tok.tok_name[name], name, value self.push_tok(name, value, source) return True @@ -1799,7 +1166,7 @@ return space.call_function(f, space.wrap(value)) def is_basestring_const(self, expr): - if not isinstance(expr,ast.Const): + if not isinstance(expr, ast.Const): return False space = self.space return space.is_true(space.isinstance(expr.value,space.w_basestring)) Modified: pypy/dist/pypy/interpreter/pyparser/ebnfgrammar.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/ebnfgrammar.py (original) +++ pypy/dist/pypy/interpreter/pyparser/ebnfgrammar.py Mon Feb 26 15:06:33 2007 @@ -1,47 +1,18 @@ # This module contains the grammar parser # and the symbol mappings -from grammar import BaseGrammarBuilder, Alternative, Sequence, Token, \ - KleeneStar, GrammarElement, build_first_sets, EmptyToken +from grammar import Alternative, Sequence, Token, KleeneStar, \ + GrammarElement, Parser +class GrammarParser(Parser): + pass -sym_map = {} -sym_rmap = {} -_count = 0 - -def g_add_symbol( name ): - global _count - if name in sym_rmap: - return sym_rmap[name] - val = _count - _count += 1 - sym_map[val] = name - sym_rmap[name] = val - return val - - -tok_map = {} -tok_rmap = {} - -def g_add_token( **kwargs ): - global _count - assert len(kwargs) == 1 - sym, name = kwargs.popitem() - if name in tok_rmap: - return tok_rmap[name] - val = _count - _count += 1 - tok_map[val] = name - tok_rmap[name] = val - sym_map[val] = sym - sym_rmap[sym] = val - return val - -g_add_token( EOF='EOF' ) +GRAMMAR_GRAMMAR = GrammarParser() def grammar_grammar(): - """NOT RPYTHON (mostly because of g_add_token I suppose) + """ + (mostly because of g_add_token I suppose) Builds the grammar for the grammar file Here's the description of the grammar's grammar :: @@ -51,59 +22,56 @@ alternative: sequence ( '|' sequence )+ star: '*' | '+' - sequence: (SYMBOL star? | STRING | option | group star? )+ + sequence: (SYMBOL star? | STRING | option | group )+ option: '[' alternative ']' group: '(' alternative ')' star? """ - global sym_map - S = g_add_symbol - T = g_add_token + p = GRAMMAR_GRAMMAR + p.add_token('EOF','EOF') + # star: '*' | '+' - star = Alternative( S("star"), [Token(T(TOK_STAR='*')), Token(T(TOK_ADD='+'))] ) - star_opt = KleeneStar ( S("star_opt"), 0, 1, rule=star ) + star = p.Alternative_n( "star", [p.Token_n('TOK_STAR', '*'), p.Token_n('TOK_ADD', '+')] ) + star_opt = p.KleeneStar_n( "star_opt", 0, 1, rule=star ) # rule: SYMBOL ':' alternative - symbol = Sequence( S("symbol"), [Token(T(TOK_SYMBOL='SYMBOL')), star_opt] ) - symboldef = Token( T(TOK_SYMDEF="SYMDEF") ) - alternative = Sequence( S("alternative"), []) - rule = Sequence( S("rule"), [symboldef, alternative] ) + symbol = p.Sequence_n( "symbol", [p.Token_n('TOK_SYMBOL'), star_opt] ) + symboldef = p.Token_n( 'TOK_SYMDEF' ) + alternative = p.Sequence_n( "alternative", []) + rule = p.Sequence_n( "rule", [symboldef, alternative] ) # grammar: rule+ - grammar = KleeneStar( S("grammar"), _min=1, rule=rule ) + grammar = p.KleeneStar_n( "grammar", _min=1, rule=rule ) # alternative: sequence ( '|' sequence )* - sequence = KleeneStar( S("sequence"), 1 ) - seq_cont_list = Sequence( S("seq_cont_list"), [Token(T(TOK_BAR='|')), sequence] ) - sequence_cont = KleeneStar( S("sequence_cont"),0, rule=seq_cont_list ) - + sequence = p.KleeneStar_n( "sequence", 1 ) + seq_cont_list = p.Sequence_n( "seq_cont_list", [p.Token_n('TOK_BAR', '|'), sequence] ) + sequence_cont = p.KleeneStar_n( "sequence_cont",0, rule=seq_cont_list ) + alternative.args = [ sequence, sequence_cont ] # option: '[' alternative ']' - option = Sequence( S("option"), [Token(T(TOK_LBRACKET='[')), alternative, Token(T(TOK_RBRACKET=']'))] ) + option = p.Sequence_n( "option", [p.Token_n('TOK_LBRACKET', '['), alternative, p.Token_n('TOK_RBRACKET', ']')] ) # group: '(' alternative ')' - group = Sequence( S("group"), [Token(T(TOK_LPAR='(')), alternative, Token(T(TOK_RPAR=')')), star_opt] ) + group = p.Sequence_n( "group", [p.Token_n('TOK_LPAR', '('), alternative, p.Token_n('TOK_RPAR', ')'), star_opt] ) # sequence: (SYMBOL | STRING | option | group )+ - string = Token(T(TOK_STRING='STRING')) - alt = Alternative( S("sequence_alt"), [symbol, string, option, group] ) + string = p.Token_n('TOK_STRING') + alt = p.Alternative_n( "sequence_alt", [symbol, string, option, group] ) sequence.args = [ alt ] + p.root_rules['grammar'] = grammar + p.build_first_sets() + return p - rules = [ star, star_opt, symbol, alternative, rule, grammar, sequence, - seq_cont_list, sequence_cont, option, group, alt ] - build_first_sets( rules ) - return grammar - - -GRAMMAR_GRAMMAR = grammar_grammar() -for _sym, _value in sym_rmap.items(): - globals()[_sym] = _value +grammar_grammar() +for _sym, _value in GRAMMAR_GRAMMAR.symbols.items(): + assert not hasattr( GRAMMAR_GRAMMAR, _sym ), _sym + setattr(GRAMMAR_GRAMMAR, _sym, _value ) + +for _sym, _value in GRAMMAR_GRAMMAR.tokens.items(): + assert not hasattr( GRAMMAR_GRAMMAR, _sym ) + setattr(GRAMMAR_GRAMMAR, _sym, _value ) -# cleanup -del _sym -del _value del grammar_grammar -del g_add_symbol -del g_add_token Modified: pypy/dist/pypy/interpreter/pyparser/ebnflexer.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/ebnflexer.py (original) +++ pypy/dist/pypy/interpreter/pyparser/ebnflexer.py Mon Feb 26 15:06:33 2007 @@ -3,8 +3,8 @@ analyser in grammar.py """ -from grammar import TokenSource, Token -from ebnfgrammar import * +from grammar import TokenSource, Token, AbstractContext +from ebnfgrammar import GRAMMAR_GRAMMAR as G def match_symbol( input, start, stop ): @@ -15,6 +15,12 @@ idx+=1 return idx + +class GrammarSourceContext(AbstractContext): + def __init__(self, pos, peek): + self.pos = pos + self.peek = peek + class GrammarSource(TokenSource): """Fully RPython - see targetebnflexer.py The grammar tokenizer @@ -25,8 +31,9 @@ SYMBOL: a rule symbol usually appearing right of a SYMDEF tokens: '[', ']', '(' ,')', '*', '+', '|' """ - def __init__(self, inpstring ): - TokenSource.__init__(self) + def __init__(self, parser, inpstring): + # TokenSource.__init__(self) + self.parser = parser self.input = inpstring self.pos = 0 self.begin = 0 @@ -36,7 +43,7 @@ def context(self): """returns an opaque context object, used to backtrack to a well known position in the parser""" - return self.pos, self._peeked + return GrammarSourceContext( self.pos, self._peeked ) def offset(self, ctx=None): """Returns the current parsing position from the start @@ -44,14 +51,16 @@ if ctx is None: return self.pos else: - assert type(ctx)==int - return ctx + assert isinstance(ctx, GrammarSourceContext) + return ctx.pos def restore(self, ctx): """restore the context provided by context()""" - self.pos, self._peeked = ctx + assert isinstance( ctx, GrammarSourceContext ) + self.pos = ctx.pos + self._peeked = ctx.peek - def current_line(self): + def current_linesource(self): pos = idx = self.begin inp = self.input end = len(inp) @@ -65,7 +74,6 @@ def current_lineno(self): return self.current_line - def skip_empty_lines(self, input, start, end ): idx = start # assume beginning of a line @@ -117,17 +125,18 @@ # means backtracking more than one token # will re-tokenize the stream (but this is the # grammar lexer so we don't care really!) + _p = self.parser if self._peeked is not None: peeked = self._peeked self._peeked = None return peeked - + pos = self.pos inp = self.input end = len(self.input) pos = self.skip_empty_lines(inp,pos,end) if pos==end: - return Token(EOF, None) + return _p.build_token( _p.EOF, None) # at this point nextchar is not a white space nor \n nextchr = inp[pos] @@ -139,22 +148,22 @@ self.pos = npos _endpos = npos - 1 assert _endpos>=0 - return Token(TOK_STRING,inp[pos+1:_endpos]) + return _p.build_token( _p.TOK_STRING, inp[pos+1:_endpos]) else: npos = match_symbol( inp, pos, end) if npos!=pos: self.pos = npos if npos!=end and inp[npos]==":": self.pos += 1 - return Token(TOK_SYMDEF,inp[pos:npos]) + return _p.build_token( _p.TOK_SYMDEF, inp[pos:npos]) else: - return Token(TOK_SYMBOL,inp[pos:npos]) - + return _p.build_token( _p.TOK_SYMBOL, inp[pos:npos]) + # we still have pos!=end here chr = inp[pos] if chr in "[]()*+|": self.pos = pos+1 - return Token(tok_rmap[chr], chr) + return _p.build_token( _p.tok_values[chr], chr) self.RaiseError( "Unknown token" ) def peek(self): Modified: pypy/dist/pypy/interpreter/pyparser/ebnfparse.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/ebnfparse.py (original) +++ pypy/dist/pypy/interpreter/pyparser/ebnfparse.py Mon Feb 26 15:06:33 2007 @@ -1,15 +1,31 @@ -#!/usr/bin/env python -from grammar import BaseGrammarBuilder, Alternative, Sequence, Token, \ - KleeneStar, GrammarElement, build_first_sets, EmptyToken -from ebnflexer import GrammarSource -import ebnfgrammar -from ebnfgrammar import GRAMMAR_GRAMMAR, sym_map -from syntaxtree import AbstractSyntaxVisitor -import pytoken -import pysymbol +from grammar import Token, GrammarProxy +from grammar import AbstractBuilder, AbstractContext + + +ORDA = ord("A") +ORDZ = ord("Z") +ORDa = ord("a") +ORDz = ord("z") +ORD0 = ord("0") +ORD9 = ord("9") +ORD_ = ord("_") + +def is_py_name( name ): + if len(name)<1: + return False + v = ord(name[0]) + if not (ORDA <= v <= ORDZ or + ORDa <= v <= ORDz or v == ORD_): + return False + for c in name: + v = ord(c) + if not (ORDA <= v <= ORDZ or + ORDa <= v <= ORDz or + ORD0 <= v <= ORD9 or + v == ORD_): + return False + return True -import re -py_name = re.compile(r"[a-zA-Z_][a-zA-Z0-9_]*", re.M) punct=['>=', '<>', '!=', '<', '>', '<=', '==', '\\*=', '//=', '%=', '^=', '<<=', '\\*\\*=', '\\', '=', @@ -18,19 +34,14 @@ '%', '<<', '//', '\\', '', '\n\\)', '\\(', ';', ':', '@', '\\[', '\\]', '`', '\\{', '\\}'] +TERMINALS = ['NAME', 'NUMBER', 'STRING', 'NEWLINE', 'ENDMARKER', + 'INDENT', 'DEDENT' ] -TERMINALS = [ - 'NAME', 'NUMBER', 'STRING', 'NEWLINE', 'ENDMARKER', - 'INDENT', 'DEDENT' ] - - -## Grammar Visitors ################################################## -# FIXME: parsertools.py ? parser/__init__.py ? class NameToken(Token): """A token that is not a keyword""" - def __init__(self, keywords=None ): - Token.__init__(self, pytoken.NAME) + def __init__(self, parser, keywords=None): + Token.__init__(self, parser, parser.tokens['NAME']) self.keywords = keywords def match(self, source, builder, level=0): @@ -47,224 +58,225 @@ ctx = source.context() tk = source.next() - if tk.codename==self.codename: - if tk.value not in builder.keywords: + if tk.codename == self.codename: + # XXX (adim): this is trunk's keyword management + # if tk.value not in builder.keywords: + if tk.value not in self.keywords: ret = builder.token( tk.codename, tk.value, source ) - return self.debug_return( ret, tk.codename, tk.value ) + return ret source.restore( ctx ) return 0 - + def match_token(self, builder, other): """special case of match token for tokens which are really keywords """ if not isinstance(other, Token): - raise RuntimeError("Unexpected token type %r" % other) - if other is EmptyToken: + raise RuntimeError("Unexpected token type") + if other is self.parser.EmptyToken: return False if other.codename != self.codename: return False - if other.value in builder.keywords: + # XXX (adim): this is trunk's keyword management + # if other.value in builder.keywords: + if other.value in self.keywords: return False return True - -def ebnf_handle_grammar(self, node): - for rule in node.nodes: - rule.visit(self) - # the rules are registered already - # we do a pass through the variables to detect - # terminal symbols from non terminals - for r in self.items: - for i,a in enumerate(r.args): - if a.codename in self.rules: - assert isinstance(a,Token) - r.args[i] = self.rules[a.codename] - if a.codename in self.terminals: - del self.terminals[a.codename] - # XXX .keywords also contains punctuations - self.terminals['NAME'].keywords = self.keywords - -def ebnf_handle_rule(self, node): - symdef = node.nodes[0].value - self.current_rule = symdef - self.current_subrule = 0 - alt = node.nodes[1] - rule = alt.visit(self) - if not isinstance(rule, Token): - rule.codename = self.symbols.add_symbol( symdef ) - self.rules[rule.codename] = rule - -def ebnf_handle_alternative(self, node): - items = [node.nodes[0].visit(self)] - items += node.nodes[1].visit(self) - if len(items) == 1 and not items[0].is_root(): - return items[0] - alt = Alternative(self.new_symbol(), items) - return self.new_item(alt) - -def ebnf_handle_sequence( self, node ): - """ """ - items = [] - for n in node.nodes: - items.append( n.visit(self) ) - if len(items)==1: - return items[0] - elif len(items)>1: - return self.new_item( Sequence( self.new_symbol(), items) ) - raise RuntimeError("Found empty sequence") - -def ebnf_handle_sequence_cont( self, node ): - """Returns a list of sequences (possibly empty)""" - return [n.visit(self) for n in node.nodes] - -def ebnf_handle_seq_cont_list(self, node): - return node.nodes[1].visit(self) - - -def ebnf_handle_symbol(self, node): - star_opt = node.nodes[1] - sym = node.nodes[0].value - terminal = self.terminals.get( sym, None ) - if not terminal: - tokencode = pytoken.tok_values.get( sym, None ) - if tokencode is None: - tokencode = self.symbols.add_symbol( sym ) - terminal = Token( tokencode ) - else: - terminal = Token( tokencode ) - self.terminals[sym] = terminal - - return self.repeat( star_opt, terminal ) - -def ebnf_handle_option( self, node ): - rule = node.nodes[1].visit(self) - return self.new_item( KleeneStar( self.new_symbol(), 0, 1, rule ) ) - -def ebnf_handle_group( self, node ): - rule = node.nodes[1].visit(self) - return self.repeat( node.nodes[3], rule ) - -def ebnf_handle_TOK_STRING( self, node ): - value = node.value - tokencode = pytoken.tok_punct.get( value, None ) - if tokencode is None: - if not py_name.match( value ): - raise RuntimeError("Unknown STRING value ('%s')" % value ) - # assume a keyword - tok = Token( pytoken.NAME, value ) - if value not in self.keywords: - self.keywords.append( value ) - else: - # punctuation - tok = Token( tokencode ) - return tok - -def ebnf_handle_sequence_alt( self, node ): - res = node.nodes[0].visit(self) - assert isinstance( res, GrammarElement ) - return res - -# This will setup a mapping between -# ebnf_handle_xxx functions and ebnfgrammar.xxx -ebnf_handles = {} -for name, value in globals().items(): - if name.startswith("ebnf_handle_"): - name = name[12:] - key = getattr(ebnfgrammar, name ) - ebnf_handles[key] = value - -def handle_unknown( self, node ): - raise RuntimeError("Unknown Visitor for %r" % node.name) - - -class EBNFVisitor(AbstractSyntaxVisitor): - - def __init__(self): - self.rules = {} - self.terminals = {} - self.current_rule = None +class EBNFBuilderContext(AbstractContext): + def __init__(self, stackpos, seqcounts, altcounts): + self.stackpos = stackpos + self.seqcounts = seqcounts + self.altcounts = altcounts + + +class EBNFBuilder(AbstractBuilder): + """Build a grammar tree""" + def __init__(self, gram_parser, dest_parser): + AbstractBuilder.__init__(self, dest_parser) + self.gram = gram_parser + self.rule_stack = [] + self.seqcounts = [] # number of items in the current sequence + self.altcounts = [] # number of sequence in the current alternative + self.curaltcount = 0 + self.curseqcount = 0 self.current_subrule = 0 + self.current_rule = -1 + self.current_rule_name = "" + self.tokens = {} self.keywords = [] - self.items = [] - self.terminals['NAME'] = NameToken() - self.symbols = pysymbol.SymbolMapper( pysymbol._cpython_symbols.sym_name ) + NAME = dest_parser.add_token('NAME') + # NAME = dest_parser.tokens['NAME'] + self.tokens[NAME] = NameToken(dest_parser, keywords=self.keywords) + + def context(self): + return EBNFBuilderContext(len(self.rule_stack), self.seqcounts, self.altcounts) + + def restore(self, ctx): + del self.rule_stack[ctx.stackpos:] + self.seqcounts = ctx.seqcounts + self.altcounts = ctx.altcounts def new_symbol(self): - rule_name = ":%s_%s" % (self.current_rule, self.current_subrule) + """Allocate and return a new (anonymous) grammar symbol whose + name is based on the current grammar rule being parsed""" + rule_name = ":" + self.current_rule_name + "_%d" % self.current_subrule self.current_subrule += 1 - symval = self.symbols.add_anon_symbol( rule_name ) - return symval + name_id = self.parser.add_anon_symbol( rule_name ) + return name_id - def new_item(self, itm): - self.items.append(itm) - return itm - - def visit_syntaxnode( self, node ): - visit_func = ebnf_handles.get( node.name, handle_unknown ) - return visit_func( self, node ) - - def visit_tokennode( self, node ): - return self.visit_syntaxnode( node ) - - def visit_tempsyntaxnode( self, node ): - return self.visit_syntaxnode( node ) - - - def repeat( self, star_opt, myrule ): - assert isinstance( myrule, GrammarElement ) - if star_opt.nodes: - rule_name = self.new_symbol() - tok = star_opt.nodes[0].nodes[0] - if tok.value == '+': - item = KleeneStar(rule_name, _min=1, rule=myrule) - return self.new_item(item) - elif tok.value == '*': - item = KleeneStar(rule_name, _min=0, rule=myrule) - return self.new_item(item) - else: - raise RuntimeError("Got symbol star_opt with value='%s'" - % tok.value) - return myrule + def new_rule(self, rule): + """A simple helper method that registers a new rule as 'known'""" + self.parser.all_rules.append(rule) + return rule + + def resolve_rules(self): + """Remove GrammarProxy objects""" + to_be_deleted = {} + for rule in self.parser.all_rules: + # for i, arg in enumerate(rule.args): + for i in range(len(rule.args)): + arg = rule.args[i] + if isinstance(arg, GrammarProxy): + real_rule = self.parser.root_rules[arg.codename] + if isinstance(real_rule, GrammarProxy): + # If we still have a GrammarProxy associated to this codename + # this means we have encountered a terminal symbol + to_be_deleted[ arg.codename ] = True + rule.args[i] = self.get_token( arg.codename ) + #print arg, "-> Token(",arg.rule_name,")" + else: + #print arg, "->", real_rule + rule.args[i] = real_rule + for codename in to_be_deleted.keys(): + del self.parser.root_rules[codename] + + def get_token(self, codename ): + """Returns a new or existing Token""" + if codename in self.tokens: + return self.tokens[codename] + token = self.tokens[codename] = self.parser.build_token(codename) + return token + + def get_symbolcode(self, name): + return self.parser.add_symbol( name ) + + def get_rule( self, name ): + if name in self.parser.tokens: + codename = self.parser.tokens[name] + return self.get_token( codename ) + codename = self.get_symbolcode( name ) + if codename in self.parser.root_rules: + return self.parser.root_rules[codename] + proxy = GrammarProxy( self.parser, name, codename ) + self.parser.root_rules[codename] = proxy + return proxy + def alternative(self, rule, source): + return True + def pop_rules( self, count ): + offset = len(self.rule_stack)-count + assert offset>=0 + rules = self.rule_stack[offset:] + del self.rule_stack[offset:] + return rules + + def sequence(self, rule, source, elts_number): + _rule = rule.codename + if _rule == self.gram.sequence: + if self.curseqcount==1: + self.curseqcount = 0 + self.curaltcount += 1 + return True + rules = self.pop_rules(self.curseqcount) + new_rule = self.parser.build_sequence( self.new_symbol(), rules ) + self.rule_stack.append( new_rule ) + self.curseqcount = 0 + self.curaltcount += 1 + elif _rule == self.gram.alternative: + if self.curaltcount == 1: + self.curaltcount = 0 + return True + rules = self.pop_rules(self.curaltcount) + new_rule = self.parser.build_alternative( self.new_symbol(), rules ) + self.rule_stack.append( new_rule ) + self.curaltcount = 0 + elif _rule == self.gram.group: + self.curseqcount += 1 + elif _rule == self.gram.option: + # pops the last alternative + rules = self.pop_rules( 1 ) + new_rule = self.parser.build_kleenestar( self.new_symbol(), _min=0, _max=1, rule=rules[0] ) + self.rule_stack.append( new_rule ) + self.curseqcount += 1 + elif _rule == self.gram.rule: + assert len(self.rule_stack)==1 + old_rule = self.rule_stack[0] + del self.rule_stack[0] + if isinstance(old_rule,Token): + # Wrap a token into an alternative + old_rule = self.parser.build_alternative( self.current_rule, [old_rule] ) + else: + # Make sure we use the codename from the named rule + old_rule.codename = self.current_rule + self.parser.root_rules[self.current_rule] = old_rule + self.current_subrule = 0 + return True + + def token(self, name, value, source): + if name == self.gram.TOK_STRING: + self.handle_TOK_STRING( name, value ) + self.curseqcount += 1 + elif name == self.gram.TOK_SYMDEF: + self.current_rule = self.get_symbolcode( value ) + self.current_rule_name = value + elif name == self.gram.TOK_SYMBOL: + rule = self.get_rule( value ) + self.rule_stack.append( rule ) + self.curseqcount += 1 + elif name == self.gram.TOK_STAR: + top = self.rule_stack[-1] + rule = self.parser.build_kleenestar( self.new_symbol(), _min=0, rule=top) + self.rule_stack[-1] = rule + elif name == self.gram.TOK_ADD: + top = self.rule_stack[-1] + rule = self.parser.build_kleenestar( self.new_symbol(), _min=1, rule=top) + self.rule_stack[-1] = rule + elif name == self.gram.TOK_BAR: + assert self.curseqcount == 0 + elif name == self.gram.TOK_LPAR: + self.altcounts.append( self.curaltcount ) + self.seqcounts.append( self.curseqcount ) + self.curseqcount = 0 + self.curaltcount = 0 + elif name == self.gram.TOK_RPAR: + assert self.curaltcount == 0 + self.curaltcount = self.altcounts.pop() + self.curseqcount = self.seqcounts.pop() + elif name == self.gram.TOK_LBRACKET: + self.altcounts.append( self.curaltcount ) + self.seqcounts.append( self.curseqcount ) + self.curseqcount = 0 + self.curaltcount = 0 + elif name == self.gram.TOK_RBRACKET: + assert self.curaltcount == 0 + assert self.curseqcount == 0 + self.curaltcount = self.altcounts.pop() + self.curseqcount = self.seqcounts.pop() + return True -def parse_grammar(stream): - """parses the grammar file - - stream : file-like object representing the grammar to parse - """ - source = GrammarSource(stream.read()) - builder = BaseGrammarBuilder() - result = GRAMMAR_GRAMMAR.match(source, builder) - node = builder.stack[-1] - vis = EBNFVisitor() - node.visit(vis) - return vis - -def parse_grammar_text(txt): - """parses a grammar input - - stream : file-like object representing the grammar to parse - """ - source = GrammarSource(txt) - builder = BaseGrammarBuilder() - result = GRAMMAR_GRAMMAR.match(source, builder) - node = builder.stack[-1] - vis = EBNFVisitor() - node.visit(vis) - return vis - -def target_parse_grammar_text(txt): - vis = parse_grammar_text(txt) - # do nothing - -from pprint import pprint -if __name__ == "__main__": - grambuild = parse_grammar(file('data/Grammar2.4')) - for i,r in enumerate(grambuild.items): - print "% 3d : %s" % (i, r) - pprint(grambuild.terminals.keys()) - pprint(grambuild.tokens) - print "|".join(grambuild.tokens.keys() ) + def handle_TOK_STRING( self, name, value ): + if value in self.parser.tok_values: + # punctuation + tokencode = self.parser.tok_values[value] + tok = self.parser.build_token( tokencode, None ) + else: + if not is_py_name(value): + raise RuntimeError("Unknown STRING value ('%s')" % value) + # assume a keyword + tok = self.parser.build_token( self.parser.tokens['NAME'], value) + if value not in self.keywords: + self.keywords.append(value) + self.rule_stack.append(tok) Modified: pypy/dist/pypy/interpreter/pyparser/grammar.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/grammar.py (original) +++ pypy/dist/pypy/interpreter/pyparser/grammar.py Mon Feb 26 15:06:33 2007 @@ -13,7 +13,8 @@ except ImportError: # allows standalone testing Wrappable = object - NULLTOKEN = None + NULLTOKEN = -1 # None + from syntaxtree import SyntaxNode, TempSyntaxNode, TokenNode @@ -28,6 +29,7 @@ else: return "["+str(codename)+"]" + #### Abstract interface for a lexer/tokenizer class TokenSource(object): """Abstract base class for a source tokenizer""" @@ -50,7 +52,7 @@ of the context""" return -1 - def current_line(self): + def current_linesource(self): """Returns the current line""" return "" @@ -71,7 +73,8 @@ def build_first_sets(rules): - """builds the real first tokens set for each rule in + """XXX : dead + builds the real first tokens set for each rule in Because a rule can be recursive (directly or indirectly), the *simplest* algorithm to build each first set is to recompute them @@ -100,17 +103,17 @@ restore states""" pass -class AbstractBuilder(object): +from pypy.interpreter.baseobjspace import Wrappable + + +class AbstractBuilder(Wrappable): """Abstract base class for builder objects""" - def __init__(self, rules=None, debug=0, symbols={} ): - # a dictionary of grammar rules for debug/reference - if rules is not None: - self.rules = rules - else: - self.rules = {} + def __init__(self, parser, debug=0 ): # This attribute is here for convenience self.debug = debug - self.symbols = symbols # mapping from codename to symbols + # the parser that represent the grammar used + assert isinstance( parser, Parser ) + self.parser = parser def context(self): """Return an opaque context object""" @@ -142,23 +145,22 @@ class BaseGrammarBuilder(AbstractBuilder): """Base/default class for a builder""" + # XXX (adim): this is trunk's keyword management keywords = None - def __init__(self, rules=None, debug=0, symbols={} ): - AbstractBuilder.__init__(self, rules, debug, symbols ) + def __init__(self, parser, debug=0 ): + AbstractBuilder.__init__(self, parser, debug ) # stacks contain different objects depending on the builder class # to be RPython they should not be defined in the base class self.stack = [] def context(self): """Returns the state of the builder to be restored later""" - #print "Save Stack:", self.stack return BaseGrammarBuilderContext(len(self.stack)) def restore(self, ctx): assert isinstance(ctx, BaseGrammarBuilderContext) del self.stack[ctx.stackpos:] - #print "Restore Stack:", self.stack - + def alternative(self, rule, source): # Do nothing, keep rule on top of the stack if rule.is_root(): @@ -208,10 +210,12 @@ """Base parser class""" symbols = {} # dirty trick to provide a symbols mapping while printing (and not putting it in every object) - - def __init__(self, codename): + + def __init__(self, parser, codename): # the rule name #assert type(codename)==int + assert isinstance(parser, Parser) + self.parser = parser self.codename = codename # integer mapping to either a token value or rule symbol value self.args = [] self.first_set = [] @@ -226,7 +230,6 @@ if self.codename >=0: return True return False - def match(self, source, builder, level=0): """Try to match a grammar rule @@ -249,17 +252,17 @@ pos1 = source.get_pos() in_first_set = self.match_first_set(builder, token) if not in_first_set: # and not EmptyToken in self.first_set: - if EmptyToken in self.first_set: + if self.parser.EmptyToken in self.first_set: ret = builder.sequence(self, source, 0 ) if self._trace: - self._debug_display(token, level, 'eee', builder.symbols) + self._debug_display(token, level, 'eee' ) return ret if self._trace: - self._debug_display(token, level, 'rrr', builder.symbols) + self._debug_display(token, level, 'rrr' ) return 0 elif self._trace: - self._debug_display(token, level, '>>>', builder.symbols) - + self._debug_display(token, level, '>>>') + res = self._match(source, builder, level) if self._trace: pos2 = source.get_pos() @@ -267,21 +270,20 @@ prefix = '+++' else: prefix = '---' - self._debug_display(token, level, prefix, builder.symbols) + self._debug_display(token, level, prefix) print ' '*level, prefix, " TEXT ='%s'" % ( source.get_source_text(pos1,pos2)) if res: print "*" * 50 return res - def _debug_display(self, token, level, prefix, symbols): + def _debug_display(self, token, level, prefix): """prints context debug informations""" prefix = '%s%s' % (' ' * level, prefix) print prefix, " RULE =", self print prefix, " TOKEN =", token print prefix, " FIRST SET =", self.first_set - - + def _match(self, source, builder, level=0): """Try to match a grammar rule @@ -295,7 +297,7 @@ returns None if no match or an object build by builder """ return 0 - + def parse(self, source): """Returns a simplified grammar if the rule matched at the source current context or None""" @@ -304,27 +306,35 @@ pass def __str__(self): - return self.display(0, GrammarElement.symbols ) + try: + return self.display(0) + except Exception, e: + import traceback + traceback.print_exc() def __repr__(self): - return self.display(0, GrammarElement.symbols ) + try: + return self.display(0) + except Exception, e: + import traceback + traceback.print_exc() - def display(self, level=0, symbols={}): + def display(self, level=0): """Helper function used to represent the grammar. mostly used for debugging the grammar itself""" return "GrammarElement" - def debug_return(self, ret, symbols, arg="" ): + def debug_return(self, ret, arg="" ): # FIXME: use a wrapper of match() methods instead of debug_return() # to prevent additional indirection even better a derived # Debugging builder class if ret and DEBUG > 0: print "matched %s (%s): %s" % (self.__class__.__name__, - arg, self.display(0, symbols=symbols) ) + arg, self.display(0) ) return ret - + def calc_first_set(self): """returns the list of possible next tokens *must* be implemented in subclasses @@ -337,7 +347,7 @@ token('NAME','x') matches token('NAME',None) """ for tk in self.first_set: - if tk.match_token( builder, other ): + if tk.match_token(builder, other): return True return False @@ -355,12 +365,28 @@ pass +class GrammarProxy(GrammarElement): + def __init__(self, parser, rule_name, codename=-1 ): + GrammarElement.__init__(self, parser, codename ) + self.rule_name = rule_name + self.object = None + + def display(self, level=0): + """Helper function used to represent the grammar. + mostly used for debugging the grammar itself""" + name = self.parser.symbol_repr(self.codename) + repr = "Proxy("+name + if self.object: + repr+=","+self.object.display(1) + repr += ")" + return repr + class Alternative(GrammarElement): """Represents an alternative in a grammar rule (as in S -> A | B | C)""" - def __init__(self, name, args): - GrammarElement.__init__(self, name ) + def __init__(self, parser, name, args): + GrammarElement.__init__(self, parser, name ) self.args = args self._reordered = False for i in self.args: @@ -371,14 +397,14 @@ returns the object built from the first rules that matches """ if DEBUG > 1: - print "try alt:", self.display(level, builder.symbols ) + print "try alt:", self.display(level) tok = source.peek() # Here we stop at the first match we should # try instead to get the longest alternative # to see if this solve our problems with infinite recursion for rule in self.args: if USE_LOOKAHEAD: - if not rule.match_first_set(builder, tok) and EmptyToken not in rule.first_set: + if not rule.match_first_set(builder, tok) and self.parser.EmptyToken not in rule.first_set: if self._trace: print "Skipping impossible rule: %s" % (rule,) continue @@ -388,15 +414,15 @@ return ret return 0 - def display(self, level=0, symbols={}): - name = get_symbol( self.codename, symbols ) + def display(self, level=0): + name = self.parser.symbol_repr( self.codename ) if level == 0: name = name + " -> " elif self.is_root(): return name else: name = "" - items = [ a.display(1,symbols) for a in self.args ] + items = [ a.display(1) for a in self.args ] return name+"(" + "|".join( items ) + ")" def calc_first_set(self): @@ -420,7 +446,7 @@ # is only needed for warning / debugging purposes tokens_set = [] for rule in self.args: - if EmptyToken in rule.first_set: + if self.parser.EmptyToken in rule.first_set: empty_set.append(rule) else: not_empty_set.append(rule) @@ -429,7 +455,7 @@ # It will check if a token is part of several first sets of # a same alternative for token in rule.first_set: - if token is not EmptyToken and token in tokens_set: + if token is not self.parser.EmptyToken and token in tokens_set: print "Warning, token %s in\n\t%s's first set is " \ " part of a previous rule's first set in " \ " alternative\n\t%s" % (token, rule, self) @@ -438,7 +464,11 @@ print "Warning: alternative %s has more than one rule " \ "matching Empty" % self self._reordered = True - self.args[:] = not_empty_set + # self.args[:] = not_empty_set + for elt in self.args[:]: + self.args.remove(elt) + for elt in not_empty_set: + self.args.append(elt) self.args.extend( empty_set ) def validate( self, syntax_node ): @@ -457,16 +487,17 @@ class Sequence(GrammarElement): """Reprensents a Sequence in a grammar rule (as in S -> A B C)""" - def __init__(self, name, args): - GrammarElement.__init__(self, name ) + def __init__(self, parser, name, args): + GrammarElement.__init__(self, parser, name ) self.args = args for i in self.args: assert isinstance( i, GrammarElement ) + def _match(self, source, builder, level=0): """matches all of the symbols in order""" if DEBUG > 1: - print "try seq:", self.display(0, builder.symbols ) + print "try seq:", self.display(0) ctx = source.context() bctx = builder.context() for rule in self.args: @@ -480,15 +511,15 @@ ret = builder.sequence(self, source, len(self.args)) return ret - def display(self, level=0, symbols={}): - name = get_symbol( self.codename, symbols ) + def display(self, level=0): + name = self.parser.symbol_repr( self.codename ) if level == 0: name = name + " -> " elif self.is_root(): return name else: name = "" - items = [a.display(1,symbols) for a in self.args] + items = [a.display(1) for a in self.args] return name + "(" + " ".join( items ) + ")" def calc_first_set(self): @@ -503,18 +534,18 @@ for rule in self.args: if not rule.first_set: break - if EmptyToken in self.first_set: - self.first_set.remove( EmptyToken ) + if self.parser.EmptyToken in self.first_set: + self.first_set.remove( self.parser.EmptyToken ) - # del self.first_set[EmptyToken] + # del self.first_set[self.parser.EmptyToken] # while we're in this loop, keep agregating possible tokens for t in rule.first_set: if t not in self.first_set: self.first_set.append(t) # self.first_set[t] = 1 - if EmptyToken not in rule.first_set: + if self.parser.EmptyToken not in rule.first_set: break - + def validate( self, syntax_node ): """validate a syntax tree/subtree from this grammar node""" if self.codename != syntax_node.name: @@ -530,13 +561,10 @@ - - - class KleeneStar(GrammarElement): """Represents a KleeneStar in a grammar rule as in (S -> A+) or (S -> A*)""" - def __init__(self, name, _min = 0, _max = -1, rule=None): - GrammarElement.__init__( self, name ) + def __init__(self, parser, name, _min = 0, _max = -1, rule=None): + GrammarElement.__init__( self, parser, name ) self.args = [rule] self.min = _min if _max == 0: @@ -544,8 +572,8 @@ self.max = _max self.star = "x" if self.min == 0: - self.first_set.append( EmptyToken ) - # self.first_set[EmptyToken] = 1 + self.first_set.append( self.parser.EmptyToken ) + # self.first_set[self.parser.EmptyToken] = 1 def _match(self, source, builder, level=0): """matches a number of times self.args[0]. the number must be @@ -553,8 +581,8 @@ represent infinity """ if DEBUG > 1: - print "try kle:", self.display(0,builder.symbols) - ctx = 0 + print "try kle:", self.display(0) + ctx = None bctx = None if self.min: ctx = source.context() @@ -576,14 +604,19 @@ ret = builder.sequence(self, source, rules) return ret - def display(self, level=0, symbols={}): - name = get_symbol( self.codename, symbols ) + def display(self, level=0): + name = self.parser.symbol_repr( self.codename ) if level==0: name = name + " -> " elif self.is_root(): return name else: name = "" + star = self.get_star() + s = self.args[0].display(1) + return name + "%s%s" % (s, star) + + def get_star(self): star = "{%d,%d}" % (self.min,self.max) if self.min==0 and self.max==1: star = "?" @@ -591,23 +624,21 @@ star = "*" elif self.min==1 and self.max==-1: star = "+" - s = self.args[0].display(1, symbols) - return name + "%s%s" % (s, star) - + return star def calc_first_set(self): """returns the list of possible next tokens if S -> A*: - LAH(S) = Union( LAH(A), EmptyToken ) + LAH(S) = Union( LAH(A), self.parser.EmptyToken ) if S -> A+: LAH(S) = LAH(A) """ rule = self.args[0] self.first_set = rule.first_set[:] # self.first_set = dict(rule.first_set) - if self.min == 0 and EmptyToken not in self.first_set: - self.first_set.append(EmptyToken) - # self.first_set[EmptyToken] = 1 + if self.min == 0 and self.parser.EmptyToken not in self.first_set: + self.first_set.append(self.parser.EmptyToken) + # self.first_set[self.parser.EmptyToken] = 1 def validate( self, syntax_node ): """validate a syntax tree/subtree from this grammar node""" @@ -626,8 +657,8 @@ class Token(GrammarElement): """Represents a Token in a grammar rule (a lexer token)""" - def __init__( self, codename, value = None): - GrammarElement.__init__( self, codename ) + def __init__(self, parser, codename, value=None): + GrammarElement.__init__(self, parser, codename) self.value = value self.first_set = [self] # self.first_set = {self: 1} @@ -643,9 +674,10 @@ else: # error unknown or negative integer """ - if (self.value is not None and builder.keywords is not None - and self.value not in builder.keywords): - return 0 + # XXX (adim): this is trunk's keyword management + # if (self.value is not None and builder.keywords is not None + # and self.value not in builder.keywords): + # return 0 ctx = source.context() tk = source.next() @@ -661,13 +693,12 @@ source.restore( ctx ) return 0 - def display(self, level=0, symbols={}): - name = get_symbol( self.codename, symbols ) + def display(self, level=0): + name = self.parser.symbol_repr( self.codename ) if self.value is None: return "<%s>" % name else: return "<%s>=='%s'" % (name, self.value) - def match_token(self, builder, other): """convenience '==' implementation, this is *not* a *real* equality test @@ -678,16 +709,17 @@ the comparison algorithm is similar to the one in match() """ if not isinstance(other, Token): - raise RuntimeError("Unexpected token type %r" % other) - if other is EmptyToken: - return False - if (self.value is not None and builder.keywords is not None - and self.value not in builder.keywords): + raise RuntimeError("Unexpected token type") + if other is self.parser.EmptyToken: return False - res = other.codename == self.codename and self.value in [None, other.value] + # XXX (adim): this is trunk's keyword management + # if (self.value is not None and builder.keywords is not None + # and self.value not in builder.keywords): + # return False + res = other.codename == self.codename and self.value in [None, other.value] #print "matching", self, other, res return res - + def __eq__(self, other): return self.codename == other.codename and self.value == other.value @@ -707,8 +739,154 @@ return False -EmptyToken = Token(NULLTOKEN, None) - - +class Parser(object): + def __init__(self): + pass + _anoncount = self._anoncount = -10 + _count = self._count = 0 + self.sym_name = {} # mapping symbol code -> symbol name + self.symbols = {} # mapping symbol name -> symbol code + self.tokens = { 'NULLTOKEN' : -1 } + self.EmptyToken = Token( self, -1, None ) + self.tok_name = {} + self.tok_values = {} + self.tok_rvalues = {} + self._ann_sym_count = -10 + self._sym_count = 0 + self.all_rules = [] + self.root_rules = {} + + def symbol_repr( self, codename ): + if codename in self.tok_name: + return self.tok_name[codename] + elif codename in self.sym_name: + return self.sym_name[codename] + return "%d" % codename + + def add_symbol( self, sym ): + # assert isinstance( sym, str ) + if not sym in self.symbols: + val = self._sym_count + self._sym_count += 1 + self.symbols[sym] = val + self.sym_name[val] = sym + return val + return self.symbols[ sym ] + + def add_anon_symbol( self, sym ): + # assert isinstance( sym, str ) + if not sym in self.symbols: + val = self._ann_sym_count + self._ann_sym_count -= 1 + self.symbols[sym] = val + self.sym_name[val] = sym + return val + return self.symbols[ sym ] + + def add_token( self, tok, value = None ): + # assert isinstance( tok, str ) + if not tok in self.tokens: + val = self._sym_count + self._sym_count += 1 + self.tokens[tok] = val + self.tok_name[val] = tok + if value is not None: + self.tok_values[value] = val + # XXX : this reverse mapping seemed only to be used + # because of pycodegen visitAugAssign + self.tok_rvalues[val] = value + return val + return self.tokens[ tok ] + + def load_symbols( self, symbols ): + for _value, _name in symbols.items(): + if _value < self._ann_sym_count: + self._ann_sym_count = _value - 1 + if _value > self._sym_count: + self._sym_count = _value + 1 + self.symbols[_name] = _value + self.sym_name[_value] = _name + + def build_first_sets(self): + """builds the real first tokens set for each rule in + + Because a rule can be recursive (directly or indirectly), the + *simplest* algorithm to build each first set is to recompute them + until Computation(N) = Computation(N-1), N being the number of rounds. + As an example, on Python2.3's grammar, we need 19 cycles to compute + full first sets. + """ + rules = self.all_rules + changed = True + while changed: + # loop while one first set is changed + changed = False + for rule in rules: + # For each rule, recompute first set + size = len(rule.first_set) + rule.calc_first_set() + new_size = len(rule.first_set) + if new_size != size: + changed = True + for r in rules: + assert len(r.first_set) > 0, "Error: ot Empty firstset for %s" % r + r.reorder_rule() + + + def build_alternative( self, name_id, args ): + # assert isinstance( name_id, int ) + assert isinstance(args, list) + alt = Alternative( self, name_id, args ) + self.all_rules.append( alt ) + return alt + + def Alternative_n(self, name, args ): + # assert isinstance(name, str) + name_id = self.add_symbol( name ) + return self.build_alternative( name_id, args ) + + def build_sequence( self, name_id, args ): + # assert isinstance( name_id, int ) + alt = Sequence( self, name_id, args ) + self.all_rules.append( alt ) + return alt + + def Sequence_n(self, name, args ): + # assert isinstance(name, str) + name_id = self.add_symbol( name ) + return self.build_sequence( name_id, args ) + + def build_kleenestar( self, name_id, _min = 0, _max = -1, rule = None ): + # assert isinstance( name_id, int ) + alt = KleeneStar( self, name_id, _min, _max, rule ) + self.all_rules.append( alt ) + return alt + def KleeneStar_n(self, name, _min = 0, _max = -1, rule = None ): + # assert isinstance(name, str) + name_id = self.add_symbol( name ) + return self.build_kleenestar( name_id, _min, _max, rule ) + + def Token_n(self, name, value = None ): + # assert isinstance( name, str) + # assert value is None or isinstance( value, str) + name_id = self.add_token( name, value ) + return self.build_token( name_id, value ) + + def build_token(self, name_id, value = None ): + # assert isinstance( name_id, int ) + # assert value is None or isinstance( value, str) + tok = Token( self, name_id, value ) + return tok + + + # Debugging functions + def show_rules(self, name): + import re + rex = re.compile(name) + rules =[] + for _name, _val in self.symbols.items(): + if rex.search(_name) and _val>=0: + rules.append(self.root_rules[_val]) + return rules Modified: pypy/dist/pypy/interpreter/pyparser/pysymbol.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/pysymbol.py (original) +++ pypy/dist/pypy/interpreter/pyparser/pysymbol.py Mon Feb 26 15:06:33 2007 @@ -5,6 +5,7 @@ # important here class SymbolMapper(object): + """XXX dead""" def __init__(self, sym_name=None ): _anoncount = self._anoncount = -10 _count = self._count = 0 @@ -22,7 +23,7 @@ self._count = _count def add_symbol( self, sym ): - assert type(sym)==str + # assert isinstance(sym, str) if not sym in self.sym_values: self._count += 1 val = self._count @@ -32,7 +33,7 @@ return self.sym_values[ sym ] def add_anon_symbol( self, sym ): - assert type(sym)==str + # assert isinstance(sym, str) if not sym in self.sym_values: self._anoncount -= 1 val = self._anoncount @@ -43,7 +44,7 @@ def __getitem__(self, sym ): """NOT RPYTHON""" - assert type(sym)==str + # assert isinstance(sym, str) return self.sym_values[ sym ] def __contains__(self, sym): @@ -57,6 +58,12 @@ # once loaded the grammar parser will fill the mappings with the # grammar symbols +# XXX: is this completly dead ? +## # prepopulate symbol table from symbols used by CPython +## for _value, _name in _cpython_symbols.sym_name.items(): +## globals()[_name] = _value + + def gen_symbol_file(fname): """ Generate a compatible symbol file for symbol.py, using the grammar that has Modified: pypy/dist/pypy/interpreter/pyparser/pythonlexer.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/pythonlexer.py (original) +++ pypy/dist/pypy/interpreter/pyparser/pythonlexer.py Mon Feb 26 15:06:33 2007 @@ -5,10 +5,10 @@ import sys from codeop import PyCF_DONT_IMPLY_DEDENT -from pypy.interpreter.pyparser.grammar import TokenSource, Token +from pypy.interpreter.pyparser.grammar import TokenSource, Token, AbstractContext, Parser from pypy.interpreter.pyparser.error import SyntaxError + import pytoken -from pytoken import NEWLINE # Don't import string for that ... NAMECHARS = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_' @@ -51,7 +51,7 @@ ################################################################################ from pypy.interpreter.pyparser import pytoken from pytokenize import tabsize, whiteSpaceDFA, triple_quoted, endDFAs, \ - single_quoted, pseudoDFA + single_quoted, pseudoDFA import automata @@ -62,7 +62,7 @@ SyntaxError.__init__(self, msg, lineno, offset, line) self.token_stack = token_stack -def generate_tokens(lines, flags): +def generate_tokens( parser, lines, flags): """ This is a rewrite of pypy.module.parser.pytokenize.generate_tokens since the original function is not RPYTHON (uses yield) @@ -91,6 +91,7 @@ #for line in lines: # print repr(line) #print '------------------- flags=%s ---->' % flags + assert isinstance( parser, Parser ) token_list = [] lnum = parenlev = continued = 0 namechars = NAMECHARS @@ -120,7 +121,7 @@ endmatch = endDFA.recognize(line) if endmatch >= 0: pos = end = endmatch - tok = Token(pytoken.STRING, contstr + line[:end]) + tok = parser.build_token(parser.tokens['STRING'], contstr + line[:end]) token_list.append((tok, line, lnum, pos)) last_comment = '' # token_list.append((STRING, contstr + line[:end], @@ -129,7 +130,7 @@ contline = None elif (needcont and not line.endswith('\\\n') and not line.endswith('\\\r\n')): - tok = Token(pytoken.ERRORTOKEN, contstr + line) + tok = parser.build_token(parser.tokens['ERRORTOKEN'], contstr + line) token_list.append((tok, line, lnum, pos)) last_comment = '' # token_list.append((ERRORTOKEN, contstr + line, @@ -155,10 +156,10 @@ if line[pos] in '#\r\n': # skip comments or blank lines if line[pos] == '#': - tok = Token(pytoken.COMMENT, line[pos:]) + tok = parser.build_token(parser.tokens['COMMENT'], line[pos:]) last_comment = line[pos:] else: - tok = Token(pytoken.NL, line[pos:]) + tok = parser.build_token(parser.tokens['NL'], line[pos:]) last_comment = '' # XXX Skip NL and COMMENT Tokens # token_list.append((tok, line, lnum, pos)) @@ -166,12 +167,12 @@ if column > indents[-1]: # count indents or dedents indents.append(column) - tok = Token(pytoken.INDENT, line[:pos]) + tok = parser.build_token(parser.tokens['INDENT'], line[:pos]) token_list.append((tok, line, lnum, pos)) last_comment = '' while column < indents[-1]: indents = indents[:-1] - tok = Token(pytoken.DEDENT, '') + tok = parser.build_token(parser.tokens['DEDENT'], '') token_list.append((tok, line, lnum, pos)) last_comment = '' else: # continued statement @@ -198,22 +199,22 @@ token, initial = line[start:end], line[start] if initial in numchars or \ (initial == '.' and token != '.'): # ordinary number - tok = Token(pytoken.NUMBER, token) + tok = parser.build_token(parser.tokens['NUMBER'], token) token_list.append((tok, line, lnum, pos)) last_comment = '' elif initial in '\r\n': if parenlev > 0: - tok = Token(pytoken.NL, token) + tok = parser.build_token(parser.tokens['NL'], token) last_comment = '' # XXX Skip NL else: - tok = Token(pytoken.NEWLINE, token) + tok = parser.build_token(parser.tokens['NEWLINE'], token) # XXX YUCK ! tok.value = last_comment token_list.append((tok, line, lnum, pos)) last_comment = '' elif initial == '#': - tok = Token(pytoken.COMMENT, token) + tok = parser.build_token(parser.tokens['COMMENT'], token) last_comment = token # XXX Skip # token_list.append((tok, line, lnum, pos)) # token_list.append((COMMENT, token, spos, epos, line)) @@ -223,7 +224,7 @@ if endmatch >= 0: # all on one line pos = endmatch token = line[start:pos] - tok = Token(pytoken.STRING, token) + tok = parser.build_token(parser.tokens['STRING'], token) token_list.append((tok, line, lnum, pos)) last_comment = '' else: @@ -240,11 +241,11 @@ contline = line break else: # ordinary string - tok = Token(pytoken.STRING, token) + tok = parser.build_token(parser.tokens['STRING'], token) token_list.append((tok, line, lnum, pos)) last_comment = '' elif initial in namechars: # ordinary name - tok = Token(pytoken.NAME, token) + tok = parser.build_token(parser.tokens['NAME'], token) token_list.append((tok, line, lnum, pos)) last_comment = '' elif initial == '\\': # continued stmt @@ -258,10 +259,11 @@ if parenlev < 0: raise TokenError("unmatched '%s'" % initial, line, (lnum-1, 0), token_list) - if token in pytoken.tok_punct: - tok = Token(pytoken.tok_punct[token]) + if token in parser.tok_values: + punct = parser.tok_values[token] + tok = parser.build_token(punct) else: - tok = Token(pytoken.OP, token) + tok = parser.build_token(parser.tokens['OP'], token) token_list.append((tok, line, lnum, pos)) last_comment = '' else: @@ -271,33 +273,39 @@ if start and inserts corresponding rules in the parser""" + # parse the ruledef(s) + source = GrammarSource(GRAMMAR_GRAMMAR, ruledef) + builder = ebnfparse.EBNFBuilder(GRAMMAR_GRAMMAR, dest_parser=self) + GRAMMAR_GRAMMAR.root_rules['grammar'].match(source, builder) + # remove proxy objects if any + builder.resolve_rules() + # update keywords + self.keywords.extend(builder.keywords) + # update old references in case an existing rule was modified + self.update_rules_references() + # recompute first sets + self.build_first_sets() + +def make_pyparser(version="2.4"): + parser = PythonParser() + return build_parser_for_version(version, parser=parser) + +PYTHON_PARSER = make_pyparser() + +def translation_target(grammardef): + parser = PythonParser() # predefined_symbols=symbol.sym_name) + source = GrammarSource(GRAMMAR_GRAMMAR, grammardef) + builder = ebnfparse.EBNFBuilder(GRAMMAR_GRAMMAR, dest_parser=parser) + GRAMMAR_GRAMMAR.root_rules['grammar'].match(source, builder) + builder.resolve_rules() + parser.build_first_sets() + parser.keywords = builder.keywords + return 0 + + +## XXX BROKEN +## def parse_grammar(space, w_src): +## """Loads the grammar using the 'dynamic' rpython parser""" +## src = space.str_w( w_src ) +## ebnfbuilder = ebnfparse.parse_grammar_text( src ) +## ebnfbuilder.resolve_rules() +## grammar.build_first_sets(ebnfbuilder.all_rules) +## return space.wrap( ebnfbuilder.root_rules ) def grammar_rules( space ): w_rules = space.newdict() - for key, value in PYTHON_PARSER.rules.iteritems(): + parser = make_pyparser() + for key, value in parser.rules.iteritems(): space.setitem(w_rules, space.wrap(key), space.wrap(value)) return w_rules - - -def make_rule( space, w_rule ): - rule = space.str_w( w_rule ) - Modified: pypy/dist/pypy/interpreter/pyparser/pythonutil.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/pythonutil.py (original) +++ pypy/dist/pypy/interpreter/pyparser/pythonutil.py Mon Feb 26 15:06:33 2007 @@ -1,17 +1,109 @@ -__all__ = ["python_parse", "pypy_parse"] +"""miscelanneous utility functions +XXX: svn mv pythonutil.py gramtools.py / parsertools.py +""" + +import sys +import os import parser -import pythonparse -from tuplebuilder import TupleBuilder -from astbuilder import AstBuilder - -PYTHON_PARSER = pythonparse.PYTHON_PARSER -TARGET_DICT = { - 'exec' : "file_input", - 'eval' : "eval_input", - 'single' : "single_input", - } +from pypy.interpreter.pyparser.grammar import Parser +from pypy.interpreter.pyparser.pytoken import setup_tokens +from pypy.interpreter.pyparser.ebnfgrammar import GRAMMAR_GRAMMAR +from pypy.interpreter.pyparser.ebnflexer import GrammarSource +from pypy.interpreter.pyparser.ebnfparse import EBNFBuilder + +from pypy.interpreter.pyparser.tuplebuilder import TupleBuilder + +PYTHON_VERSION = ".".join([str(i) for i in sys.version_info[:2]]) + +def dirname(filename): + """redefine dirname to avoid the need of os.path.split being rpython + """ + i = filename.rfind(os.sep) + 1 + assert i >= 0 + return filename[:i] + + +def get_grammar_file(version): + """returns the python grammar corresponding to our CPython version""" + if version == "native": + _ver = PYTHON_VERSION + elif version == "stable": + _ver = "_stablecompiler" + elif version in ("2.3","2.4","2.5a"): + _ver = version + else: + raise ValueError('no such grammar version: %s' % version) + # two osp.join to avoid TyperError: can only iterate over tuples of length 1 for now + # generated by call to osp.join(a, *args) + return os.path.join( dirname(__file__), + os.path.join("data", "Grammar" + _ver) ), _ver + + +def build_parser(gramfile, parser=None): + """reads a (EBNF) grammar definition and builds a parser for it""" + if parser is None: + parser = Parser() + setup_tokens(parser) + # XXX: clean up object dependencies + from pypy.rlib.streamio import open_file_as_stream + stream = open_file_as_stream(gramfile) + grammardef = stream.readall() + stream.close() + assert isinstance(grammardef, str) + source = GrammarSource(GRAMMAR_GRAMMAR, grammardef) + builder = EBNFBuilder(GRAMMAR_GRAMMAR, dest_parser=parser) + GRAMMAR_GRAMMAR.root_rules['grammar'].match(source, builder) + builder.resolve_rules() + parser.build_first_sets() + parser.keywords = builder.keywords + return parser + + +def build_parser_for_version(version, parser=None): + gramfile, _ = get_grammar_file(version) + return build_parser(gramfile, parser) + + +## XXX: the below code should probably go elsewhere + +## convenience functions for computing AST objects using recparser +def ast_from_input(input, mode, transformer, parser): + """converts a source input into an AST + + - input : the source to be converted + - mode : 'exec', 'eval' or 'single' + - transformer : the transfomer instance to use to convert + the nested tuples into the AST + XXX: transformer could be instantiated here but we don't want + here to explicitly import compiler or stablecompiler or + etc. This is to be fixed in a clean way + """ + builder = TupleBuilder(parser, lineno=True) + parser.parse_source(input, mode, builder) + tuples = builder.stack[-1].as_tuple(True) + return transformer.compile_node(tuples) + + +def pypy_parse(source, mode='exec', lineno=False): + from pypy.interpreter.pyparser.pythonparse import PythonParser, make_pyparser + from pypy.interpreter.pyparser.astbuilder import AstBuilder + # parser = build_parser_for_version("2.4", PythonParser()) + parser = make_pyparser('stable') + builder = TupleBuilder(parser) + parser.parse_source(source, mode, builder) + return builder.stack[-1].as_tuple(lineno) + + +def source2ast(source, mode='exec', version='2.4', space=None): + from pypy.interpreter.pyparser.pythonparse import PythonParser, make_pyparser + from pypy.interpreter.pyparser.astbuilder import AstBuilder + parser = make_pyparser(version) + builder = AstBuilder(parser, space=space) + parser.parse_source(source, mode, builder) + return builder.rule_stack[-1] + ## convenience functions around CPython's parser functions def python_parsefile(filename, lineno=False): @@ -32,7 +124,6 @@ tp = parser.suite(source) return parser.ast2tuple(tp, line_info=lineno) -## convenience functions around recparser functions def pypy_parsefile(filename, lineno=False): """parse using PyPy's parser module and return a tuple of three elements : @@ -48,105 +139,3 @@ source = pyf.read() pyf.close() return pypy_parse(source, 'exec', lineno) - -def internal_pypy_parse(source, mode='exec', lineno=False, flags=0, space=None, - parser = PYTHON_PARSER): - """This function has no other role than testing the parser's annotation - - annotateme() is basically the same code that pypy_parse(), but with the - following differences : - - - returns a tuplebuilder.StackElement instead of the *real* nested - tuples (StackElement is only a wrapper class around these tuples) - - """ - builder = TupleBuilder(parser.rules, lineno=False) - if space is not None: - builder.space = space - target_rule = TARGET_DICT[mode] - parser.parse_source(source, target_rule, builder, flags) - stack_element = builder.stack[-1] - return (builder.source_encoding, stack_element) - -def parse_result_to_nested_tuples(parse_result, lineno=False): - """NOT_RPYTHON""" - source_encoding, stack_element = parse_result - nested_tuples = stack_element.as_tuple(lineno) - return nested_tuples - -def pypy_parse(source, mode='exec', lineno=False, flags=0, parser = PYTHON_PARSER): - """ - NOT_RPYTHON ! - parse using PyPy's parser module and return - a tuple of three elements : - - The encoding declaration symbol or None if there were no encoding - statement - - The TupleBuilder's stack top element (instance of - tuplebuilder.StackElement which is a wrapper of some nested tuples - like those returned by the CPython's parser) - - The encoding string or None if there were no encoding statement - nested tuples - """ - source_encoding, stack_element = internal_pypy_parse(source, mode, lineno=lineno, - flags=lineno, parser = parser) - # convert the stack element into nested tuples (caution, the annotator - # can't follow this call) - return parse_result_to_nested_tuples((source_encoding, stack_element), lineno=lineno) - -## convenience functions for computing AST objects using recparser -def ast_from_input(input, mode, transformer, parser = PYTHON_PARSER): - """converts a source input into an AST - - - input : the source to be converted - - mode : 'exec', 'eval' or 'single' - - transformer : the transfomer instance to use to convert - the nested tuples into the AST - XXX: transformer could be instantiated here but we don't want - here to explicitly import compiler or stablecompiler or - etc. This is to be fixed in a clean way - """ - tuples = pypy_parse(input, mode, True, parser) - ast = transformer.compile_node(tuples) - return ast - -def target_ast_compile(space, input, mode): - from pypy.interpreter.astcompiler import ast, misc, pycodegen - builder = AstBuilder(rules=None, debug=0, space=space) - target = TARGET_DICT[mode] - PYTHON_PARSER.parse_source(input, target, builder) - ast_tree = builder.rule_stack[-1] - misc.set_filename("", ast_tree) - if mode=="single": - codegenerator = pycodegen.InteractiveCodeGenerator(space,ast_tree) - elif mode=="eval": - codegenerator = pycodegen.ExpressionCodeGenerator(space,ast_tree) - elif mode=="exec": - codegenerator = pycodegen.ModuleCodeGenerator(space,ast_tree) - else: - raise ValueError("incorrect mode") - code1 = codegenerator.getCode() - return code1 - - -def internal_pypy_parse_to_ast(source, mode='exec', lineno=False, flags=0): - builder = AstBuilder() - target_rule = TARGET_DICT[mode] - PYTHON_PARSER.parse_source(source, target_rule, builder, flags) - ast_tree = builder.rule_stack[-1] - return (builder.source_encoding, ast_tree) - - -if __name__ == "__main__": - import sys - if len(sys.argv) < 2: - print "python parse.py [-d N] test_file.py" - sys.exit(1) - if sys.argv[1] == "-d": - debug_level = int(sys.argv[2]) - test_file = sys.argv[3] - else: - test_file = sys.argv[1] - print "-"*20 - print - print "pyparse \n", pypy_parsefile(test_file) - print "parser \n", python_parsefile(test_file) Modified: pypy/dist/pypy/interpreter/pyparser/pytoken.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/pytoken.py (original) +++ pypy/dist/pypy/interpreter/pyparser/pytoken.py Mon Feb 26 15:06:33 2007 @@ -5,131 +5,77 @@ N_TOKENS = 0 -tok_name = {} -tok_values = {} +# This is used to replace None +NULLTOKEN = -1 -def add_token(name, value=None): - global N_TOKENS - if value is None: - value = N_TOKENS - N_TOKENS += 1 - _g = globals() - _g[name] = value - tok_name[value] = name - tok_values[name] = value +tok_name = {-1 : 'NULLTOKEN'} +tok_values = {'NULLTOKEN' : -1} -# This is used to replace None -add_token( 'NULLTOKEN', -1 ) +# tok_rpunct = {} +def setup_tokens( parser ): + # global tok_rpunct # For compatibility, this produces the same constant values as Python 2.4. -add_token( 'ENDMARKER' ) -add_token( 'NAME' ) -add_token( 'NUMBER' ) -add_token( 'STRING' ) -add_token( 'NEWLINE' ) -add_token( 'INDENT' ) -add_token( 'DEDENT' ) -add_token( 'LPAR' ) -add_token( 'RPAR' ) -add_token( 'LSQB' ) -add_token( 'RSQB' ) -add_token( 'COLON' ) -add_token( 'COMMA' ) -add_token( 'SEMI' ) -add_token( 'PLUS' ) -add_token( 'MINUS' ) -add_token( 'STAR' ) -add_token( 'SLASH' ) -add_token( 'VBAR' ) -add_token( 'AMPER' ) -add_token( 'LESS' ) -add_token( 'GREATER' ) -add_token( 'EQUAL' ) -add_token( 'DOT' ) -add_token( 'PERCENT' ) -add_token( 'BACKQUOTE' ) -add_token( 'LBRACE' ) -add_token( 'RBRACE' ) -add_token( 'EQEQUAL' ) -add_token( 'NOTEQUAL' ) -add_token( 'LESSEQUAL' ) -add_token( 'GREATEREQUAL' ) -add_token( 'TILDE' ) -add_token( 'CIRCUMFLEX' ) -add_token( 'LEFTSHIFT' ) -add_token( 'RIGHTSHIFT' ) -add_token( 'DOUBLESTAR' ) -add_token( 'PLUSEQUAL' ) -add_token( 'MINEQUAL' ) -add_token( 'STAREQUAL' ) -add_token( 'SLASHEQUAL' ) -add_token( 'PERCENTEQUAL' ) -add_token( 'AMPEREQUAL' ) -add_token( 'VBAREQUAL' ) -add_token( 'CIRCUMFLEXEQUAL' ) -add_token( 'LEFTSHIFTEQUAL' ) -add_token( 'RIGHTSHIFTEQUAL' ) -add_token( 'DOUBLESTAREQUAL' ) -add_token( 'DOUBLESLASH' ) -add_token( 'DOUBLESLASHEQUAL' ) -add_token( 'AT' ) -add_token( 'OP' ) -add_token( 'ERRORTOKEN' ) + parser.add_token( 'ENDMARKER' ) + parser.add_token( 'NAME' ) + parser.add_token( 'NUMBER' ) + parser.add_token( 'STRING' ) + parser.add_token( 'NEWLINE' ) + parser.add_token( 'INDENT' ) + parser.add_token( 'DEDENT' ) + parser.add_token( 'LPAR', "(" ) + parser.add_token( 'RPAR', ")" ) + parser.add_token( 'LSQB', "[" ) + parser.add_token( 'RSQB', "]" ) + parser.add_token( 'COLON', ":" ) + parser.add_token( 'COMMA', "," ) + parser.add_token( 'SEMI', ";" ) + parser.add_token( 'PLUS', "+" ) + parser.add_token( 'MINUS', "-" ) + parser.add_token( 'STAR', "*" ) + parser.add_token( 'SLASH', "/" ) + parser.add_token( 'VBAR', "|" ) + parser.add_token( 'AMPER', "&" ) + parser.add_token( 'LESS', "<" ) + parser.add_token( 'GREATER', ">" ) + parser.add_token( 'EQUAL', "=" ) + parser.add_token( 'DOT', "." ) + parser.add_token( 'PERCENT', "%" ) + parser.add_token( 'BACKQUOTE', "`" ) + parser.add_token( 'LBRACE', "{" ) + parser.add_token( 'RBRACE', "}" ) + parser.add_token( 'EQEQUAL', "==" ) + ne = parser.add_token( 'NOTEQUAL', "!=" ) + parser.tok_values["<>"] = ne + parser.add_token( 'LESSEQUAL', "<=" ) + parser.add_token( 'GREATEREQUAL', ">=" ) + parser.add_token( 'TILDE', "~" ) + parser.add_token( 'CIRCUMFLEX', "^" ) + parser.add_token( 'LEFTSHIFT', "<<" ) + parser.add_token( 'RIGHTSHIFT', ">>" ) + parser.add_token( 'DOUBLESTAR', "**" ) + parser.add_token( 'PLUSEQUAL', "+=" ) + parser.add_token( 'MINEQUAL', "-=" ) + parser.add_token( 'STAREQUAL', "*=" ) + parser.add_token( 'SLASHEQUAL', "/=" ) + parser.add_token( 'PERCENTEQUAL', "%=" ) + parser.add_token( 'AMPEREQUAL', "&=" ) + parser.add_token( 'VBAREQUAL', "|=" ) + parser.add_token( 'CIRCUMFLEXEQUAL', "^=" ) + parser.add_token( 'LEFTSHIFTEQUAL', "<<=" ) + parser.add_token( 'RIGHTSHIFTEQUAL', ">>=" ) + parser.add_token( 'DOUBLESTAREQUAL', "**=" ) + parser.add_token( 'DOUBLESLASH', "//" ) + parser.add_token( 'DOUBLESLASHEQUAL',"//=" ) + parser.add_token( 'AT', "@" ) + parser.add_token( 'OP' ) + parser.add_token( 'ERRORTOKEN' ) # extra PyPy-specific tokens -add_token( "COMMENT" ) -add_token( "NL" ) - -# a reverse mapping from internal tokens def to more pythonic tokens -tok_punct = { - "&" : AMPER, - "&=" : AMPEREQUAL, - "`" : BACKQUOTE, - "^" : CIRCUMFLEX, - "^=" : CIRCUMFLEXEQUAL, - ":" : COLON, - "," : COMMA, - "." : DOT, - "//" : DOUBLESLASH, - "//=" : DOUBLESLASHEQUAL, - "**" : DOUBLESTAR, - "**=" : DOUBLESTAREQUAL, - "==" : EQEQUAL, - "=" : EQUAL, - ">" : GREATER, - ">=" : GREATEREQUAL, - "{" : LBRACE, - "}" : RBRACE, - "<<" : LEFTSHIFT, - "<<=" : LEFTSHIFTEQUAL, - "<" : LESS, - "<=" : LESSEQUAL, - "(" : LPAR, - "[" : LSQB, - "-=" : MINEQUAL, - "-" : MINUS, - "!=" : NOTEQUAL, - "<>" : NOTEQUAL, - "%" : PERCENT, - "%=" : PERCENTEQUAL, - "+" : PLUS, - "+=" : PLUSEQUAL, - ")" : RBRACE, - ">>" : RIGHTSHIFT, - ">>=" : RIGHTSHIFTEQUAL, - ")" : RPAR, - "]" : RSQB, - ";" : SEMI, - "/" : SLASH, - "/=" : SLASHEQUAL, - "*" : STAR, - "*=" : STAREQUAL, - "~" : TILDE, - "|" : VBAR, - "|=" : VBAREQUAL, - "@": AT, - } -tok_rpunct = {} -for string, value in tok_punct.items(): - tok_rpunct[value] = string + parser.add_token( "COMMENT" ) + parser.add_token( "NL" ) + # tok_rpunct = parser.tok_values.copy() + # for _name, _value in parser.tokens.items(): + # globals()[_name] = _value + # setattr(parser, _name, _value) Modified: pypy/dist/pypy/interpreter/pyparser/syntaxtree.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/syntaxtree.py (original) +++ pypy/dist/pypy/interpreter/pyparser/syntaxtree.py Mon Feb 26 15:06:33 2007 @@ -5,7 +5,6 @@ # except ImportError: # # from pysymbol import sym_values # from pytoken import tok_values - from pypy.tool.uid import uid class AbstractSyntaxVisitor(object): Modified: pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py (original) +++ pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py Mon Feb 26 15:06:33 2007 @@ -2,7 +2,7 @@ from pypy.interpreter.pyparser import pythonparse from pypy.interpreter.pyparser.astbuilder import AstBuilder -from pypy.interpreter.pyparser.pythonutil import ast_from_input +from pypy.interpreter.pyparser.pythonutil import ast_from_input, build_parser_for_version from pypy.interpreter.stablecompiler.transformer import Transformer import pypy.interpreter.stablecompiler.ast as test_ast import pypy.interpreter.astcompiler.ast as ast_ast @@ -13,6 +13,9 @@ from pypy.interpreter.astcompiler import ast + +from expressions import TESTS, SINGLE_INPUTS, EXEC_INPUTS + def arglist_equal(left,right): """needs special case because we handle the argumentlist differently""" for l,r in zip(left,right): @@ -142,211 +145,13 @@ return False return True -EXPECTED = {} - -constants = [ - "0", - "7", - "-3", - "053", - "0x18", - "14L", - "1.0", - "3.9", - "-3.6", - "1.8e19", - "90000000000000", - "90000000000000.", - "3j" - ] - -expressions = [ - "x = a + 1", - "x = 1 - a", - "x = a * b", - "x = a ** 2", - "x = a / b", - "x = a & b", - "x = a | b", - "x = a ^ b", - "x = a // b", - "x = a * b + 1", - "x = a + 1 * b", - "x = a * b / c", - "x = a * (1 + c)", - "x, y, z = 1, 2, 3", - "x = 'a' 'b' 'c'", - "del foo", - "del foo[bar]", - "del foo.bar", - "l[0]", - "k[v,]", - "m[a,b]", - "a.b.c[d]", - "file('some.txt').read()", - "a[0].read()", - "a[1:1].read()", - "f('foo')('bar')('spam')", - "f('foo')('bar')('spam').read()[0]", - "a.b[0][0]", - "a.b[0][:]", - "a.b[0][::]", - "a.b[0][0].pop()[0].push('bar')('baz').spam", - "a.b[0].read()[1][2].foo().spam()[0].bar", - "a**2", - "a**2**2", - "a.b[0]**2", - "a.b[0].read()[1][2].foo().spam()[0].bar ** 2", - "l[start:end] = l2", - "l[::] = l2", - "a = `s`", - "a = `1 + 2 + f(3, 4)`", - "[a, b] = c", - "(a, b) = c", - "[a, (b,c), d] = e", - "a, (b, c), d = e", - ] - -# We do not export the following tests because we would have to implement 2.5 -# features in the stable compiler (other than just building the AST). -expressions_inbetweenversions = expressions + [ - #"1 if True else 2", # Disabled 2.5 syntax - #"1 if False else 2", - ] - -EXPECTED["k[v,]"] = ("Module(None, Stmt([Discard(Subscript(Name('k'), 2, " - "Tuple([Name('v')])))]))") -EXPECTED["m[a,b]"] = ("Module(None, Stmt([Discard(Subscript(Name('m'), 2, " - "Tuple([Name('a'), Name('b')])))]))") -EXPECTED["1 if True else 2"] = ("Module(None, Stmt([Discard(CondExpr(" - "Name('True'), Const(1), Const(2)))]))") -EXPECTED["1 if False else 2"] = ("Module(None, Stmt([Discard(CondExpr(" - "Name('False'), Const(1), Const(2)))]))") - -funccalls = [ - "l = func()", - "l = func(10)", - "l = func(10, 12, a, b=c, *args)", - "l = func(10, 12, a, b=c, **kwargs)", - "l = func(10, 12, a, b=c, *args, **kwargs)", - "l = func(10, 12, a, b=c)", - "e = l.pop(3)", - "e = k.l.pop(3)", - "simplefilter('ignore', category=PendingDeprecationWarning, append=1)", - """methodmap = dict(subdirs=phase4, - same_files=phase3, diff_files=phase3, funny_files=phase3, - common_dirs = phase2, common_files=phase2, common_funny=phase2, - common=phase1, left_only=phase1, right_only=phase1, - left_list=phase0, right_list=phase0)""", - "odata = b2a_qp(data, quotetabs = quotetabs, header = header)", - ] - -listmakers = [ - "l = []", - "l = [1, 2, 3]", - "l = [i for i in range(10)]", - "l = [i for i in range(10) if i%2 == 0]", - "l = [i for i in range(10) if i%2 == 0 or i%2 == 1]", - "l = [i for i in range(10) if i%2 == 0 and i%2 == 1]", - "l = [i for j in range(10) for i in range(j)]", - "l = [i for j in range(10) for i in range(j) if j%2 == 0]", - "l = [i for j in range(10) for i in range(j) if j%2 == 0 and i%2 == 0]", - "l = [(a, b) for (a,b,c) in l2]", - "l = [{a:b} for (a,b,c) in l2]", - "l = [i for j in k if j%2 == 0 if j*2 < 20 for i in j if i%2==0]", - ] - -genexps = [ - "l = (i for i in j)", - "l = (i for i in j if i%2 == 0)", - "l = (i for j in k for i in j)", - "l = (i for j in k for i in j if j%2==0)", - "l = (i for j in k if j%2 == 0 if j*2 < 20 for i in j if i%2==0)", - "l = (i for i in [ j*2 for j in range(10) ] )", - "l = [i for i in ( j*2 for j in range(10) ) ]", - "l = (i for i in [ j*2 for j in ( k*3 for k in range(10) ) ] )", - "l = [i for j in ( j*2 for j in [ k*3 for k in range(10) ] ) ]", - "l = f(i for i in j)", - ] - - -dictmakers = [ - "l = {a : b, 'c' : 0}", - "l = {}", - ] - -backtrackings = [ - "f = lambda x: x+1", - "f = lambda x,y: x+y", - "f = lambda x,y=1,z=t: x+y", - "f = lambda x,y=1,z=t,*args,**kwargs: x+y", - "f = lambda x,y=1,z=t,*args: x+y", - "f = lambda x,y=1,z=t,**kwargs: x+y", - "f = lambda: 1", - "f = lambda *args: 1", - "f = lambda **kwargs: 1", - ] +EXPECTED = { + "k[v,]" : "Module(None, Stmt([Discard(Subscript(Name('k'), 2, Tuple([Name('v')])))]))", + "m[a,b]" : "Module(None, Stmt([Discard(Subscript(Name('m'), 2, Tuple([Name('a'), Name('b')])))]))", -comparisons = [ - "a < b", - "a > b", - "a not in b", - "a is not b", - "a in b", - "a is b", - "3 < x < 5", - "(3 < x) < 5", - "a < b < c < d", - "(a < b) < (c < d)", - "a < (b < c) < d", - ] - -multiexpr = [ - 'a = b; c = d;', - 'a = b = c = d', - ] + "1 if True else 2" : "Module(None, Stmt([Discard(CondExpr(Name('True'), Const(1), Const(2)))]))", + "1 if False else 2" : "Module(None, Stmt([Discard(CondExpr(Name('False'), Const(1), Const(2)))]))", -attraccess = [ - 'a.b = 2', - 'x = a.b', - ] - -slices = [ - "l[:]", - "l[::]", - "l[1:2]", - "l[1:]", - "l[:2]", - "l[1::]", - "l[:1:]", - "l[::1]", - "l[1:2:]", - "l[:1:2]", - "l[1::2]", - "l[0:1:2]", - "a.b.l[:]", - "a.b.l[1:2]", - "a.b.l[1:]", - "a.b.l[:2]", - "a.b.l[0:1:2]", - "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, :]", - ] -EXPECTED.update({ "a[1:2:3, 100]": "Module(None, Stmt([Discard(Subscript(Name('a'), 2, Tuple([Sliceobj([Const(1), Const(2), Const(3)]), Const(100)])))]))", "a[:2:3, 100]": "Module(None, Stmt([Discard(Subscript(Name('a'), 2, Tuple([Sliceobj([Const(None), Const(2), Const(3)]), Const(100)])))]))", "a[1::3, 100,]": "Module(None, Stmt([Discard(Subscript(Name('a'), 2, Tuple([Sliceobj([Const(1), Const(None), Const(3)]), Const(100)])))]))", @@ -363,307 +168,10 @@ "a[100, 1:]": "Module(None, Stmt([Discard(Subscript(Name('a'), 2, Tuple([Const(100), Sliceobj([Const(1), Const(None)])])))]))", "a[100, :2,]": "Module(None, Stmt([Discard(Subscript(Name('a'), 2, Tuple([Const(100), Sliceobj([Const(None), Const(2)])])))]))", "a[100, :]": "Module(None, Stmt([Discard(Subscript(Name('a'), 2, Tuple([Const(100), Sliceobj([Const(None), Const(None)])])))]))", - }) - -imports = [ - 'import os', - 'import sys, os', - 'import os.path', - 'import os.path, sys', - 'import sys, os.path as osp', - 'import os.path as osp', - 'import os.path as osp, sys as _sys', - 'import a.b.c.d', - 'import a.b.c.d as abcd', - 'from os import path', - 'from os import path, system', - ] - -imports_newstyle = [ - 'from os import path, system', - 'from os import path as P, system as S', - 'from os import (path as P, system as S,)', - 'from os import *', - ] - -if_stmts = [ - "if a == 1: a+= 2", - """if a == 1: - a += 2 -elif a == 2: - a += 3 -else: - a += 4 -""", - "if a and not b == c: pass", - "if a and not not not b == c: pass", - "if 0: print 'foo'" - ] - -asserts = [ - 'assert False', - 'assert a == 1', - 'assert a == 1 and b == 2', - 'assert a == 1 and b == 2, "assertion failed"', - ] - -execs = [ - 'exec a', - 'exec "a=b+3"', - 'exec a in f()', - 'exec a in f(), g()', - ] - -prints = [ - 'print', - 'print a', - 'print a,', - 'print a, b', - 'print a, "b", c', - 'print >> err', - 'print >> err, "error"', - 'print >> err, "error",', - 'print >> err, "error", a', - ] - -globs = [ - 'global a', - 'global a,b,c', - ] - -raises_ = [ # NB. 'raises' creates a name conflict with py.test magic - 'raise', - 'raise ValueError', - 'raise ValueError("error")', - 'raise ValueError, "error"', - 'raise ValueError, "error", foo', - ] - -tryexcepts = [ - """try: - a - b -except: - pass -""", - """try: - a - b -except NameError: - pass -""", - """try: - a - b -except NameError, err: - pass -""", - """try: - a - b -except (NameError, ValueError): - pass -""", - """try: - a - b -except (NameError, ValueError), err: - pass -""", - """try: - a -except NameError, err: - pass -except ValueError, err: - pass -""", - """def f(): - try: - a - except NameError, err: - a = 1 - b = 2 - except ValueError, err: - a = 2 - return a -""" - """try: - a -except NameError, err: - a = 1 -except ValueError, err: - a = 2 -else: - a += 3 -""", - """try: - a -finally: - b -""", - """def f(): - try: - return a - finally: - a = 3 - return 1 -""", - - ] - -one_stmt_funcdefs = [ - "def f(): return 1", - "def f(x): return x+1", - "def f(x,y): return x+y", - "def f(x,y=1,z=t): return x+y", - "def f(x,y=1,z=t,*args,**kwargs): return x+y", - "def f(x,y=1,z=t,*args): return x+y", - "def f(x,y=1,z=t,**kwargs): return x+y", - "def f(*args): return 1", - "def f(**kwargs): return 1", - "def f(t=()): pass", - "def f(a, b, (c, d), e): pass", - "def f(a, b, (c, (d, e), f, (g, h))): pass", - "def f(a, b, (c, (d, e), f, (g, h)), i): pass", - "def f((a)): pass", - ] - -one_stmt_classdefs = [ - "class Pdb(bdb.Bdb, cmd.Cmd): pass", - ] - -docstrings = [ - '''def foo(): return 1''', - '''class Foo: pass''', - '''class Foo: "foo"''', - '''def foo(): - """foo docstring""" - return 1 -''', - '''def foo(): - """foo docstring""" - a = 1 - """bar""" - return a -''', - '''def foo(): - """doc"""; print 1 - a=1 -''', - '''"""Docstring""";print 1''', - ] - -returns = [ - 'def f(): return', - 'def f(): return 1', - 'def f(): return a.b', - 'def f(): return a', - 'def f(): return a,b,c,d', - #'return (a,b,c,d)', --- this one makes no sense, as far as I can tell - ] -augassigns = [ - 'a=1;a+=2', - 'a=1;a-=2', - 'a=1;a*=2', - 'a=1;a/=2', - 'a=1;a//=2', - 'a=1;a%=2', - 'a=1;a**=2', - 'a=1;a>>=2', - 'a=1;a<<=2', - 'a=1;a&=2', - 'a=1;a^=2', - 'a=1;a|=2', - - 'a=A();a.x+=2', - 'a=A();a.x-=2', - 'a=A();a.x*=2', - 'a=A();a.x/=2', - 'a=A();a.x//=2', - 'a=A();a.x%=2', - 'a=A();a.x**=2', - 'a=A();a.x>>=2', - 'a=A();a.x<<=2', - 'a=A();a.x&=2', - 'a=A();a.x^=2', - 'a=A();a.x|=2', - - 'a=A();a[0]+=2', - 'a=A();a[0]-=2', - 'a=A();a[0]*=2', - 'a=A();a[0]/=2', - 'a=A();a[0]//=2', - 'a=A();a[0]%=2', - 'a=A();a[0]**=2', - 'a=A();a[0]>>=2', - 'a=A();a[0]<<=2', - 'a=A();a[0]&=2', - 'a=A();a[0]^=2', - 'a=A();a[0]|=2', - - 'a=A();a[0:2]+=2', - 'a=A();a[0:2]-=2', - 'a=A();a[0:2]*=2', - 'a=A();a[0:2]/=2', - 'a=A();a[0:2]//=2', - 'a=A();a[0:2]%=2', - 'a=A();a[0:2]**=2', - 'a=A();a[0:2]>>=2', - 'a=A();a[0:2]<<=2', - 'a=A();a[0:2]&=2', - 'a=A();a[0:2]^=2', - 'a=A();a[0:2]|=2', - ] - -TESTS = [ - constants, - expressions_inbetweenversions, - augassigns, - comparisons, - funccalls, - backtrackings, - listmakers, - genexps, - dictmakers, - multiexpr, - attraccess, - slices, - imports, - imports_newstyle, - asserts, - execs, - prints, - globs, - raises_, - ] - -EXEC_INPUTS = [ - one_stmt_classdefs, - one_stmt_funcdefs, - if_stmts, - tryexcepts, - docstrings, - returns, - ] - -SINGLE_INPUTS = [ - one_stmt_funcdefs, - ['\t # hello\n', - 'print 6*7', - 'if 1: x\n', - 'x = 5', - 'x = 5 ', - '''"""Docstring""";print 1''', - '''"Docstring"''', - '''"Docstring" "\\x00"''', - ] -] - -TARGET_DICT = { - 'single' : 'single_input', - 'exec' : 'file_input', - 'eval' : 'eval_input', + # stablecompiler produces a Pass statement which does not seem very consistent + # (a module should only have a Stmt child) + "\t # hello\n": "Module(None, Stmt([]))", } @@ -705,39 +213,39 @@ builtin = dict(int=int, long=long, float=float, complex=complex) -def ast_parse_expr(expr, target='single'): - target = TARGET_DICT[target] - builder = AstBuilder(space=FakeSpace()) - pythonparse.PYTHON_PARSER.parse_source(expr, target, builder) - return builder - # Create parser from Grammar_stable, not current grammar. -stable_grammar, _ = pythonparse.get_grammar_file("stable") -stable_parser = pythonparse.python_grammar(stable_grammar) +stable_parser = pythonparse.make_pyparser('stable') +python_parser = pythonparse.make_pyparser() # 'native') # 2.5a') def tuple_parse_expr(expr, target='single'): t = Transformer("dummyfile") return ast_from_input(expr, target, t, stable_parser) -def check_expression(expr, target='single'): - r1 = ast_parse_expr(expr, target) +def source2ast(source, mode, space=FakeSpace()): + builder = AstBuilder(space=space, parser=python_parser) + python_parser.parse_source(source, mode, builder) + return builder.rule_stack[-1] + +def check_expression(expr, mode='single'): + pypy_ast = source2ast(expr, mode) try: - ast = EXPECTED[expr] + python_ast = EXPECTED[expr] except KeyError: # trust the stablecompiler's Transformer when no explicit result has # been provided (although trusting it is a foolish thing to do) - ast = tuple_parse_expr(expr, target) + python_ast = tuple_parse_expr(expr, mode) check_lineno = True else: - if isinstance(ast, str): - ast = eval(ast, ast_ast.__dict__) + if isinstance(python_ast, str): + python_ast = eval(python_ast, ast_ast.__dict__) check_lineno = False print "-" * 30 - print "ORIG :", ast + print "ORIG :", python_ast print - print "BUILT:", r1.rule_stack[-1] + print "BUILT:", pypy_ast print "-" * 30 - assert nodes_equal(ast, r1.rule_stack[-1], check_lineno), 'failed on %r' % (expr) + assert nodes_equal(python_ast, pypy_ast, check_lineno), 'failed on %r' % (expr) + def test_basic_astgen(): for family in TESTS: @@ -749,6 +257,7 @@ for expr in family: yield check_expression, expr, 'exec' + NEW_GRAMMAR_SNIPPETS = [ 'snippet_with_1.py', 'snippet_with_2.py', @@ -810,7 +319,7 @@ for snippet_name in LIBSTUFF: filepath = os.path.join(os.path.dirname(__file__), '../../../lib', snippet_name) source = file(filepath).read() - yield check_expression, source, 'exec' + yield check_expression, source, 'exec' # FIXME: find the sys' attribute that define this STDLIB_PATH = os.path.dirname(os.__file__) 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 Mon Feb 26 15:06:33 2007 @@ -1,4 +1,6 @@ +import sys import os + from pypy.interpreter.pyparser import pythonparse from pypy.interpreter.pyparser.astbuilder import AstBuilder from pypy.interpreter.pyparser.tuplebuilder import TupleBuilder @@ -11,93 +13,47 @@ from pypy.interpreter.astcompiler import ast, misc, pycodegen -from test_astbuilder import expressions, comparisons, funccalls, backtrackings,\ - listmakers, genexps, dictmakers, multiexpr, attraccess, slices, imports,\ - asserts, execs, prints, globs, raises_, imports_newstyle, augassigns, \ - if_stmts, one_stmt_classdefs, one_stmt_funcdefs, tryexcepts, docstrings, \ - returns, SNIPPETS, SINGLE_INPUTS, LIBSTUFF, constants - -from test_astbuilder import FakeSpace - - -TESTS = [ - constants, - expressions, - augassigns, - comparisons, - funccalls, - backtrackings, - listmakers, - dictmakers, - multiexpr, - genexps, - attraccess, - slices, - imports, - execs, - prints, - globs, - raises_, -# EXEC_INPUTS - one_stmt_classdefs, - one_stmt_funcdefs, - if_stmts, - tryexcepts, - docstrings, - returns, - ] +from test_astbuilder import SNIPPETS, LIBSTUFF, FakeSpace, source2ast +from expressions import PY23_TESTS, EXEC_INPUTS, SINGLE_INPUTS, OPTIONAL_TESTS + +TESTS = PY23_TESTS + EXEC_INPUTS + -import sys if sys.version_info[0]==2 and sys.version_info[1]>=4: # genexps and new style import don't work on python2.3 # TESTS.append(genexps) XXX: 2.4 optimizes bytecode so our comparison doesn't work - TESTS.append(imports_newstyle) - # assertions give different bytecode with 2.4 (optimize if __debug__) - TESTS.append(asserts) -TARGET_DICT = { - 'single' : 'single_input', - 'exec' : 'file_input', - 'eval' : 'eval_input', - } - -def ast_parse_expr(expr, target='single', space=FakeSpace()): - target = TARGET_DICT[target] - builder = AstBuilder(space=space) - pythonparse.PYTHON_PARSER.parse_source(expr, target, builder) - return builder.rule_stack[-1] + TESTS += OPTIONAL_TESTS -def compile_with_astcompiler(expr, target='exec', space=FakeSpace()): - ast = ast_parse_expr(expr, target='exec', space=space) # xxx exec: single not really tested, mumble +def compile_with_astcompiler(expr, mode='exec', space=FakeSpace()): + ast = source2ast(expr, mode, space) # xxx exec: single not really tested, mumble misc.set_filename('', ast) - if target == 'exec': + if mode == 'exec': Generator = pycodegen.ModuleCodeGenerator - elif target == 'single': + elif mode == 'single': Generator = pycodegen.InteractiveCodeGenerator - elif target == 'eval': + elif mode == 'eval': Generator = pycodegen.ExpressionCodeGenerator codegen = Generator(space, ast) rcode = codegen.getCode() return rcode - # Create parser from Grammar_stable, not current grammar. -stable_grammar, _ = pythonparse.get_grammar_file("stable") -stable_parser = pythonparse.python_grammar(stable_grammar) +stable_parser = pythonparse.make_pyparser('stable') -def compile_with_testcompiler(expr, target='exec', space=FakeSpace()): - target2 = TARGET_DICT['exec'] # xxx exec: single not really tested - builder = TupleBuilder() - stable_parser.parse_source(expr, target2, builder) +def compile_with_testcompiler(expr, mode='exec', space=FakeSpace()): + mode2 = 'exec' # xxx exec: single not really tested + builder = TupleBuilder(stable_parser) + stable_parser.parse_source(expr, mode2, 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': + if mode == 'exec': Generator = pycodegen.ModuleCodeGenerator - elif target == 'single': + elif mode == 'single': Generator = pycodegen.InteractiveCodeGenerator - elif target == 'eval': + elif mode == 'eval': Generator = pycodegen.ExpressionCodeGenerator codegen = Generator(ast) rcode = codegen.getCode() @@ -151,40 +107,27 @@ tuple(rcode.co_cellvars) ) return code -def check_compile(expr, target='exec', quiet=False, space=None): +def check_compile(expr, mode='exec', quiet=False, space=None): if not quiet: print "Compiling:", expr if space is None: space = std_space - ac_code = compile_with_astcompiler(expr, target=target, space=space) + ac_code = compile_with_astcompiler(expr, mode=mode, space=space) if expr == "k[v,]" or expr.startswith('"'): # module-level docstring py.test.skip('comparison skipped, bug in "reference stable compiler"') - sc_code = compile_with_testcompiler(expr, target=target) + sc_code = compile_with_testcompiler(expr, mode=mode) compare_code(ac_code, sc_code, space=space) -## def check_compile( expr ): -## space = FakeSpace() -## ast_tree = ast_parse_expr( expr, target='exec', space=space ) -## misc.set_filename("", ast_tree) -## print "Compiling:", expr -## print ast_tree -## codegenerator = pycodegen.ModuleCodeGenerator(space,ast_tree) -## rcode = codegenerator.getCode() -## code1 = to_code( rcode ) -## code2 = ast_compile( expr ) -## compare_code(code1,code2) def test_compile_argtuple_1(): - #py.test.skip('will be tested when more basic stuff will work') code = """def f( x, (y,z) ): print x,y,z """ check_compile( code ) def test_compile_argtuple_2(): - #py.test.skip('will be tested when more basic stuff will work') code = """def f( x, (y,(z,t)) ): print x,y,z,t """ @@ -192,14 +135,12 @@ def test_compile_argtuple_3(): - #py.test.skip('will be tested when more basic stuff will work') code = """def f( x, (y,(z,(t,u))) ): print x,y,z,t,u """ check_compile( code ) - def test_basic_astgen(): for family in TESTS: for expr in family: @@ -228,7 +169,7 @@ for snippet_name in LIBSTUFF: filepath = os.path.join(os.path.dirname(__file__), '../../../lib', snippet_name) source = file(filepath).read() - yield check_compile, source, 'exec' + yield check_compile, source, 'exec' def test_single_inputs(): Modified: pypy/dist/pypy/interpreter/pyparser/test/test_lookahead.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/test/test_lookahead.py (original) +++ pypy/dist/pypy/interpreter/pyparser/test/test_lookahead.py Mon Feb 26 15:06:33 2007 @@ -1,43 +1,37 @@ from pypy.interpreter.pyparser.grammar import Alternative, Sequence, KleeneStar, \ - Token, EmptyToken, build_first_sets + Token, Parser class TestLookAheadBasics: def setup_method(self, method): - self.count = 0 - self.tok1 = Token(self.nextid(), 'foo') - self.tok2 = Token(self.nextid(), 'bar') - self.tok3 = Token(self.nextid(), 'foobar') + self.parser = Parser() + self.tok1 = self.parser.Token_n("t1", 'foo') + self.tok2 = self.parser.Token_n("t2", 'bar') + self.tok3 = self.parser.Token_n("t3", 'foobar') self.tokens = [self.tok1, self.tok2, self.tok3] - build_first_sets(self.tokens) - - def nextid(self): - self.count+=1 - return self.count + self.parser.build_first_sets() def test_basic_token(self): assert self.tok1.first_set == [self.tok1] - def test_basic_alternative(self): - alt = Alternative(self.nextid(), self.tokens) - build_first_sets([alt]) + alt = self.parser.Alternative_n("a1t", self.tokens) + self.parser.build_first_sets() assert alt.first_set == self.tokens def test_basic_sequence(self): - seq = Sequence(self.nextid(), self.tokens) - build_first_sets([seq]) + seq = self.parser.Sequence_n("seq", self.tokens) + self.parser.build_first_sets() assert seq.first_set == [self.tokens[0]] def test_basic_kleenstar(self): tok1, tok2, tok3 = self.tokens - kstar = KleeneStar(self.nextid(), 1, 3, tok1) - build_first_sets([kstar]) - assert kstar.first_set == [tok1] - kstar = KleeneStar(self.nextid(), 0, 3, tok1) - build_first_sets([kstar]) - assert kstar.first_set == [tok1, EmptyToken] + kstar1 = self.parser.KleeneStar_n("k", 1, 3, tok1) + kstar2 = self.parser.KleeneStar_n("k2", 0, 3, tok1) + self.parser.build_first_sets() + assert kstar1.first_set == [tok1] + assert kstar2.first_set == [tok1, self.parser.EmptyToken] def test_maybe_empty_sequence(self): @@ -45,11 +39,11 @@ ==> S.first_set = [tok1, tok2, EmptyToken] """ tok1, tok2, tok3 = self.tokens - k1 = KleeneStar(self.nextid(), 0, 2, tok1) - k2 = KleeneStar(self.nextid(), 0, 2, tok2) - seq = Sequence(self.nextid(), [k1, k2]) - build_first_sets([k1, k2, seq]) - assert seq.first_set == [tok1, tok2, EmptyToken] + k1 = self.parser.KleeneStar_n( "k1", 0, 2, tok1) + k2 = self.parser.KleeneStar_n("k2", 0, 2, tok2) + seq = self.parser.Sequence_n( "seq", [k1, k2]) + self.parser.build_first_sets() + assert seq.first_set == [tok1, tok2, self.parser.EmptyToken] def test_not_empty_sequence(self): @@ -57,41 +51,42 @@ ==> S.first_set = [tok1, tok2] """ tok1, tok2, tok3 = self.tokens - k1 = KleeneStar(self.nextid(), 0, 2, tok1) - k2 = KleeneStar(self.nextid(), 1, 2, tok2) - seq = Sequence(self.nextid(), [k1, k2]) - build_first_sets([k1, k2, seq]) + k1 = self.parser.KleeneStar_n("k1", 0, 2, tok1) + k2 = self.parser.KleeneStar_n("k2", 1, 2, tok2) + seq = self.parser.Sequence_n("seq", [k1, k2]) + self.parser.build_first_sets() assert seq.first_set == [tok1, tok2] -def test_token_comparison(): - assert Token(1, 'foo') == Token(1, 'foo') - assert Token(1, 'foo') != Token(2, 'foo') - assert Token(2, 'foo') != Token(2, None) + def test_token_comparison(self): + tok1 = self.parser.Token_n( "tok1", "foo" ) + tok1b = self.parser.Token_n( "tok1", "foo" ) + tok2 = self.parser.Token_n( "tok2", "foo" ) + tok3 = self.parser.Token_n( "tok2", None ) + assert tok1 == tok1b + assert tok1 != tok2 + assert tok2 != tok3 -LOW = 1 -CAP = 2 -R_A = 3 -R_B = 4 -R_C = 5 -R_k1 = 6 -R_k2 = 7 class TestLookAhead: def setup_method(self, method): - self.LOW = Token(LOW, 'low') - self.CAP = Token(CAP ,'cap') - self.A = Alternative(R_A, []) - k1 = KleeneStar(R_k1, 0, rule=self.LOW) - k2 = KleeneStar(R_k2, 0, rule=self.CAP) - self.B = Sequence(R_B, [k1, self.A]) - self.C = Sequence(R_C, [k2, self.A]) + p = self.parser = Parser() + self.LOW = p.Token_n( 'LOW', 'low') + self.CAP = p.Token_n( 'CAP' ,'cap') + self.A = p.Alternative_n( 'R_A', []) + k1 = p.KleeneStar_n( 'R_k1', 0, rule=self.LOW) + k2 = p.KleeneStar_n( 'R_k2', 0, rule=self.CAP) + self.B = p.Sequence_n( 'R_B', [k1, self.A]) + self.C = p.Sequence_n( 'R_C', [k2, self.A]) self.A.args = [self.B, self.C] - build_first_sets([self.A, self.B, self.C, self.LOW, self.CAP, k1, k2]) + p.build_first_sets() def test_S_first_set(self): - for s in [Token(LOW, 'low'), EmptyToken, Token(CAP, 'cap')]: + p = self.parser + LOW = p.tokens['LOW'] + CAP = p.tokens['CAP'] + for s in [Token(p, LOW, 'low'), p.EmptyToken, Token(p, CAP, 'cap')]: assert s in self.A.first_set assert s in self.B.first_set assert s in self.C.first_set Modified: pypy/dist/pypy/interpreter/pyparser/test/test_pytokenizer.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/test/test_pytokenizer.py (original) +++ pypy/dist/pypy/interpreter/pyparser/test/test_pytokenizer.py Mon Feb 26 15:06:33 2007 @@ -1,17 +1,26 @@ from pypy.interpreter.pyparser.pythonlexer import Source, TokenError, \ match_encoding_declaration from pypy.interpreter.pyparser.grammar import Token, GrammarElement -from pypy.interpreter.pyparser.pytoken import EQUAL, ENDMARKER, LSQB, MINUS, NAME, NEWLINE, NULLTOKEN, NUMBER, RSQB, STRING +from pypy.interpreter.pyparser.pythonparse import make_pyparser -from pypy.interpreter.pyparser.pytoken import tok_name, tok_punct -GrammarElement.symbols = tok_name +P = make_pyparser() +EQUAL = P.tokens['EQUAL'] +ENDMARKER = P.tokens['ENDMARKER'] +LSQB = P.tokens['LSQB'] +MINUS = P.tokens['MINUS'] +NAME = P.tokens['NAME'] +NEWLINE = P.tokens['NEWLINE'] +NULLTOKEN = P.tokens['NULLTOKEN'] +NUMBER = P.tokens['NUMBER'] +RSQB = P.tokens['RSQB'] +STRING = P.tokens['STRING'] def parse_source(source): """returns list of parsed tokens""" - lexer = Source(source.splitlines(True)) + lexer = Source( P, source.splitlines(True)) tokens = [] - last_token = Token(NULLTOKEN, None) + last_token = Token( P, NULLTOKEN, None) while last_token.codename != ENDMARKER: last_token = lexer.next() tokens.append(last_token) @@ -49,24 +58,24 @@ s = """['a' ]""" tokens = parse_source(s) - assert tokens[:4] == [Token(LSQB, None), Token(STRING, "'a'"), - Token(RSQB, None), Token(NEWLINE, '')] + assert tokens[:4] == [Token(P, LSQB, None), Token(P, STRING, "'a'"), + Token(P, RSQB, None), Token(P, NEWLINE, '')] def test_numbers(): """make sure all kind of numbers are correctly parsed""" for number in NUMBERS: - assert parse_source(number)[0] == Token(NUMBER, number) + assert parse_source(number)[0] == Token(P, NUMBER, number) neg = '-%s' % number - assert parse_source(neg)[:2] == [Token(MINUS, None), - Token(NUMBER, number)] + assert parse_source(neg)[:2] == [Token(P, MINUS, None), + Token(P, NUMBER, number)] for number in BAD_NUMBERS: - assert parse_source(number)[0] != Token(NUMBER, number) + assert parse_source(number)[0] != Token(P, NUMBER, number) def test_hex_number(): """basic pasrse""" tokens = parse_source("a = 0x12L") - assert tokens[:4] == [Token(NAME, 'a'), Token(EQUAL, None), - Token(NUMBER, '0x12L'), Token(NEWLINE, '')] + assert tokens[:4] == [Token(P, NAME, 'a'), Token(P, EQUAL, None), + Token(P, NUMBER, '0x12L'), Token(P, NEWLINE, '')] def test_punct(): """make sure each punctuation is correctly parsed""" @@ -81,7 +90,7 @@ tokens = [tok for tok, _, _, _ in error.token_stack] if prefix: tokens.pop(0) - assert tokens[0].codename == tok_punct[pstr] + assert tokens[0].codename == P.tok_values[pstr] def test_encoding_declarations_match(): 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 Mon Feb 26 15:06:33 2007 @@ -6,13 +6,12 @@ import py.test from pypy.interpreter.pyparser.pythonutil import python_parsefile, \ - pypy_parsefile, python_parse, pypy_parse + pypy_parsefile, pypy_parse, python_parse, get_grammar_file, PYTHON_VERSION from pypy.interpreter.pyparser import grammar from pypy.interpreter.pyparser.pythonlexer import TokenError -from pypy.interpreter.pyparser.pythonparse import PYTHON_VERSION, PYPY_VERSION grammar.DEBUG = False - +_, PYPY_VERSION = get_grammar_file("2.4") # these samples are skipped if the native version of Python does not match # the version of the grammar we use GRAMMAR_MISMATCH = PYTHON_VERSION != PYPY_VERSION Modified: pypy/dist/pypy/interpreter/pyparser/tuplebuilder.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/tuplebuilder.py (original) +++ pypy/dist/pypy/interpreter/pyparser/tuplebuilder.py Mon Feb 26 15:06:33 2007 @@ -1,6 +1,5 @@ -from grammar import AbstractBuilder, AbstractContext -from pytoken import tok_name, tok_rpunct, NEWLINE, INDENT, DEDENT, ENDMARKER +from grammar import AbstractBuilder, AbstractContext, Parser class StackElement: """wraps TupleBuilder's tuples""" @@ -53,16 +52,18 @@ class TupleBuilderContext(AbstractContext): def __init__(self, stackpos ): self.stackpos = stackpos - + class TupleBuilder(AbstractBuilder): """A builder that directly produce the AST""" - def __init__(self, rules=None, debug=0, lineno=True): - AbstractBuilder.__init__(self, rules, debug) + def __init__(self, parser, debug=0, lineno=True): + AbstractBuilder.__init__(self, parser, debug) # This attribute is here for convenience self.source_encoding = None self.lineno = lineno self.stack = [] + self.space_token = ( self.parser.tokens['NEWLINE'], self.parser.tokens['INDENT'], + self.parser.tokens['DEDENT'], self.parser.tokens['ENDMARKER'] ) def context(self): """Returns the state of the builder to be restored later""" @@ -80,7 +81,7 @@ nodes = expand_nodes( [self.stack[-1]] ) self.stack[-1] = NonTerminal( rule.codename, nodes ) return True - + def sequence(self, rule, source, elts_number): """ """ num = rule.codename @@ -97,8 +98,8 @@ def token(self, codename, value, source): lineno = source._token_lnum if value is None: - if codename not in ( NEWLINE, INDENT, DEDENT, ENDMARKER ): - value = tok_rpunct.get(codename, "unknown op") + if codename not in self.space_token: + value = self.parser.tok_rvalues.get(codename, "unknown op") else: value = '' self.stack.append( Terminal(codename, value, lineno) ) Modified: pypy/dist/pypy/interpreter/stablecompiler/transformer.py ============================================================================== --- pypy/dist/pypy/interpreter/stablecompiler/transformer.py (original) +++ pypy/dist/pypy/interpreter/stablecompiler/transformer.py Mon Feb 26 15:06:33 2007 @@ -26,9 +26,7 @@ # and replace OWNER, ORGANIZATION, and YEAR as appropriate. # make sure we import the parser with the correct grammar -from pypy.interpreter.pyparser import pythonparse - -import pypy.interpreter.pyparser.pythonparse as pythonparse +from pypy.interpreter.pyparser.pythonparse import make_pyparser from pypy.interpreter.stablecompiler.ast import * import parser @@ -36,15 +34,15 @@ import sys # Create parser from Grammar_stable, not current grammar. -stable_grammar, _ = pythonparse.get_grammar_file("stable") -stable_parser = pythonparse.python_grammar(stable_grammar) - -sym_name = stable_parser.symbols.sym_name +# stable_grammar, _ = pythonparse.get_grammar_file("stable") +# stable_parser = pythonparse.python_grammar(stable_grammar) +stable_parser = make_pyparser('stable') class symbol: pass - -for value, name in sym_name.iteritems(): +sym_name = {} +for name, value in stable_parser.symbols.items(): + sym_name[value] = name setattr(symbol, name, value) # transforming is requiring a lot of recursion depth so make sure we have enough @@ -58,6 +56,7 @@ from consts import CO_VARARGS, CO_VARKEYWORDS from consts import OP_ASSIGN, OP_DELETE, OP_APPLY + def parseFile(path): f = open(path, "U") # XXX The parser API tolerates files without a trailing newline, @@ -130,14 +129,15 @@ for value, name in sym_name.items(): if hasattr(self, name): self._dispatch[value] = getattr(self, name) - self._dispatch[token.NEWLINE] = self.com_NEWLINE - self._atom_dispatch = {token.LPAR: self.atom_lpar, - token.LSQB: self.atom_lsqb, - token.LBRACE: self.atom_lbrace, - token.BACKQUOTE: self.atom_backquote, - token.NUMBER: self.atom_number, - token.STRING: self.atom_string, - token.NAME: self.atom_name, + + self._dispatch[stable_parser.tokens['NEWLINE']] = self.com_NEWLINE + self._atom_dispatch = {stable_parser.tokens['LPAR']: self.atom_lpar, + stable_parser.tokens['LSQB']: self.atom_lsqb, + stable_parser.tokens['LBRACE']: self.atom_lbrace, + stable_parser.tokens['BACKQUOTE']: self.atom_backquote, + stable_parser.tokens['NUMBER']: self.atom_number, + stable_parser.tokens['STRING']: self.atom_string, + stable_parser.tokens['NAME']: self.atom_name, } self.encoding = None @@ -206,7 +206,7 @@ def single_input(self, node): # NEWLINE | simple_stmt | compound_stmt NEWLINE n = node[0][0] - if n != token.NEWLINE: + if n != stable_parser.tokens['NEWLINE']: stmt = self.com_stmt(node[0]) else: stmt = Pass() @@ -216,14 +216,13 @@ doc = self.get_docstring(nodelist, symbol.file_input) stmts = [] for node in nodelist: - if node[0] != token.ENDMARKER and node[0] != token.NEWLINE: + if node[0] != stable_parser.tokens['ENDMARKER'] and node[0] != stable_parser.tokens['NEWLINE']: self.com_append_stmt(stmts, node) if doc is not None: assert isinstance(stmts[0], Discard) assert isinstance(stmts[0].expr, Const) del stmts[0] - return Module(doc, Stmt(stmts)) def eval_input(self, nodelist): @@ -238,8 +237,8 @@ item = self.atom_name(nodelist) i = 1 while i < listlen: - assert nodelist[i][0] == token.DOT - assert nodelist[i + 1][0] == token.NAME + assert nodelist[i][0] == stable_parser.tokens['DOT'] + assert nodelist[i + 1][0] == stable_parser.tokens['NAME'] item = Getattr(item, nodelist[i + 1][1]) i += 2 @@ -248,14 +247,14 @@ def decorator(self, nodelist): # '@' dotted_name [ '(' [arglist] ')' ] assert len(nodelist) in (3, 5, 6) - assert nodelist[0][0] == token.AT - assert nodelist[-1][0] == token.NEWLINE + assert nodelist[0][0] == stable_parser.tokens['AT'] + assert nodelist[-1][0] == stable_parser.tokens['NEWLINE'] assert nodelist[1][0] == symbol.dotted_name funcname = self.decorator_name(nodelist[1][1:]) if len(nodelist) > 3: - assert nodelist[2][0] == token.LPAR + assert nodelist[2][0] == stable_parser.tokens['LPAR'] expr = self.com_call_function(funcname, nodelist[3]) else: expr = funcname @@ -328,7 +327,7 @@ # classdef: 'class' NAME ['(' testlist ')'] ':' suite name = nodelist[1][1] doc = self.get_docstring(nodelist[-1]) - if nodelist[2][0] == token.COLON: + if nodelist[2][0] == stable_parser.tokens['COLON']: bases = [] else: bases = self.com_bases(nodelist[3]) @@ -397,7 +396,7 @@ exprNode = self.lookup_node(en)(en[1:]) if len(nodelist) == 1: return Discard(exprNode, lineno=exprNode.lineno) - if nodelist[1][0] == token.EQUAL: + if nodelist[1][0] == stable_parser.tokens['EQUAL']: nodesl = [] for i in range(0, len(nodelist) - 2, 2): nodesl.append(self.com_assign(nodelist[i], OP_ASSIGN)) @@ -414,9 +413,9 @@ if len(nodelist) == 1: start = 1 dest = None - elif nodelist[1][0] == token.RIGHTSHIFT: + elif nodelist[1][0] == stable_parser.tokens['RIGHTSHIFT']: assert len(nodelist) == 3 \ - or nodelist[3][0] == token.COMMA + or nodelist[3][0] == stable_parser.tokens['COMMA'] dest = self.com_node(nodelist[2]) start = 4 else: @@ -424,7 +423,7 @@ start = 1 for i in range(start, len(nodelist), 2): items.append(self.com_node(nodelist[i])) - if nodelist[-1][0] == token.COMMA: + if nodelist[-1][0] == stable_parser.tokens['COMMA']: return Print(items, dest, lineno=nodelist[0][2]) return Printnl(items, dest, lineno=nodelist[0][2]) @@ -482,15 +481,15 @@ assert nodelist[1][0] == symbol.dotted_name assert nodelist[2][1] == 'import' fromname = self.com_dotted_name(nodelist[1]) - if nodelist[3][0] == token.STAR: + if nodelist[3][0] == stable_parser.tokens['STAR']: return From(fromname, [('*', None)], lineno=nodelist[0][2]) else: - if nodelist[3][0] == token.LPAR: + if nodelist[3][0] == stable_parser.tokens['LPAR']: node = nodelist[4] else: node = nodelist[3] - if node[-1][0] == token.COMMA: + if node[-1][0] == stable_parser.tokens['COMMA']: self.syntaxerror("trailing comma not allowed without surrounding parentheses", node) return From(fromname, self.com_import_as_names(node), lineno=nodelist[0][2]) @@ -608,6 +607,7 @@ return self.com_generator_expression(test, nodelist[1]) return self.testlist(nodelist) + def test(self, nodelist): # test: or_test ['if' or_test 'else' test] | lambdef if len(nodelist) == 1: @@ -618,8 +618,9 @@ return self.com_node(nodelist[0]) elif len(nodelist) == 5 and nodelist[1][0] =='if': # Here we implement conditional expressions - return ast.CondExpr(nodelist[2], nodelist[0], nodelist[4], - nodelist[1].lineno) + # XXX: CPython's nodename is IfExp, not CondExpr + return CondExpr(delist[2], nodelist[0], nodelist[4], + nodelist[1].lineno) else: return self.com_binary(Or, nodelist) @@ -634,6 +635,9 @@ assert len(nodelist) == 1 return self.com_node(nodelist[0]) + # XXX + # test = old_test + def or_test(self, nodelist): # or_test: and_test ('or' and_test)* return self.com_binary(Or, nodelist) @@ -658,7 +662,7 @@ # comp_op: '<' | '>' | '=' | '>=' | '<=' | '<>' | '!=' | '==' # | 'in' | 'not' 'in' | 'is' | 'is' 'not' n = nl[1] - if n[0] == token.NAME: + if n[0] == stable_parser.tokens['NAME']: type = n[1] if len(nl) == 3: if type == 'not': @@ -695,9 +699,9 @@ node = self.com_node(nodelist[0]) for i in range(2, len(nodelist), 2): right = self.com_node(nodelist[i]) - if nodelist[i-1][0] == token.LEFTSHIFT: + if nodelist[i-1][0] == stable_parser.tokens['LEFTSHIFT']: node = LeftShift([node, right], lineno=nodelist[1][2]) - elif nodelist[i-1][0] == token.RIGHTSHIFT: + elif nodelist[i-1][0] == stable_parser.tokens['RIGHTSHIFT']: node = RightShift([node, right], lineno=nodelist[1][2]) else: raise ValueError, "unexpected token: %s" % nodelist[i-1][0] @@ -707,9 +711,9 @@ node = self.com_node(nodelist[0]) for i in range(2, len(nodelist), 2): right = self.com_node(nodelist[i]) - if nodelist[i-1][0] == token.PLUS: + if nodelist[i-1][0] == stable_parser.tokens['PLUS']: node = Add([node, right], lineno=nodelist[1][2]) - elif nodelist[i-1][0] == token.MINUS: + elif nodelist[i-1][0] == stable_parser.tokens['MINUS']: node = Sub([node, right], lineno=nodelist[1][2]) else: raise ValueError, "unexpected token: %s" % nodelist[i-1][0] @@ -720,13 +724,13 @@ for i in range(2, len(nodelist), 2): right = self.com_node(nodelist[i]) t = nodelist[i-1][0] - if t == token.STAR: + if t == stable_parser.tokens['STAR']: node = Mul([node, right]) - elif t == token.SLASH: + elif t == stable_parser.tokens['SLASH']: node = Div([node, right]) - elif t == token.PERCENT: + elif t == stable_parser.tokens['PERCENT']: node = Mod([node, right]) - elif t == token.DOUBLESLASH: + elif t == stable_parser.tokens['DOUBLESLASH']: node = FloorDiv([node, right]) else: raise ValueError, "unexpected token: %s" % t @@ -738,11 +742,11 @@ t = elt[0] node = self.lookup_node(nodelist[-1])(nodelist[-1][1:]) # need to handle (unary op)constant here... - if t == token.PLUS: + if t == stable_parser.tokens['PLUS']: return UnaryAdd(node, lineno=elt[2]) - elif t == token.MINUS: + elif t == stable_parser.tokens['MINUS']: return UnarySub(node, lineno=elt[2]) - elif t == token.TILDE: + elif t == stable_parser.tokens['TILDE']: node = Invert(node, lineno=elt[2]) return node @@ -751,7 +755,7 @@ node = self.com_node(nodelist[0]) for i in range(1, len(nodelist)): elt = nodelist[i] - if elt[0] == token.DOUBLESTAR: + if elt[0] == stable_parser.tokens['DOUBLESTAR']: return Power([node, self.com_node(nodelist[i+1])], lineno=elt[2]) @@ -765,17 +769,17 @@ return n def atom_lpar(self, nodelist): - if nodelist[1][0] == token.RPAR: + if nodelist[1][0] == stable_parser.tokens['RPAR']: return Tuple(()) return self.com_node(nodelist[1]) def atom_lsqb(self, nodelist): - if nodelist[1][0] == token.RSQB: + if nodelist[1][0] == stable_parser.tokens['RSQB']: 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: + if nodelist[1][0] == stable_parser.tokens['RBRACE']: return Dict(()) return self.com_dictmaker(nodelist[1]) @@ -850,10 +854,10 @@ i = 0 while i < len(nodelist): node = nodelist[i] - if node[0] == token.STAR or node[0] == token.DOUBLESTAR: - if node[0] == token.STAR: + if node[0] == stable_parser.tokens['STAR'] or node[0] == stable_parser.tokens['DOUBLESTAR']: + if node[0] == stable_parser.tokens['STAR']: node = nodelist[i+1] - if node[0] == token.NAME: + if node[0] == stable_parser.tokens['NAME']: name = node[1] if name in names: self.syntaxerror("duplicate argument '%s' in function definition" % @@ -865,7 +869,7 @@ if i < len(nodelist): # should be DOUBLESTAR t = nodelist[i][0] - if t == token.DOUBLESTAR: + if t == stable_parser.tokens['DOUBLESTAR']: node = nodelist[i+1] else: raise ValueError, "unexpected token: %s" % t @@ -891,7 +895,7 @@ self.syntaxerror("non-default argument follows default argument",node) break - if nodelist[i][0] == token.EQUAL: + if nodelist[i][0] == stable_parser.tokens['EQUAL']: defaults.append(self.com_node(nodelist[i + 1])) i = i + 2 elif len(defaults): @@ -905,7 +909,7 @@ def com_fpdef(self, node): # fpdef: NAME | '(' fplist ')' - if node[1][0] == token.LPAR: + if node[1][0] == stable_parser.tokens['LPAR']: return self.com_fplist(node[2]) return node[1][1] @@ -922,7 +926,7 @@ # String together the dotted names and return the string name = "" for n in node: - if type(n) == type(()) and n[0] == 1: + if type(n) == type(()) and n[0] == stable_parser.tokens['NAME']: name = name + n[1] + '.' return name[:-1] @@ -933,7 +937,7 @@ if len(node) == 1: return dot, None assert node[1][1] == 'as' - assert node[2][0] == token.NAME + assert node[2][0] == stable_parser.tokens['NAME'] return dot, node[2][1] def com_dotted_as_names(self, node): @@ -947,11 +951,11 @@ def com_import_as_name(self, node): assert node[0] == symbol.import_as_name node = node[1:] - assert node[0][0] == token.NAME + assert node[0][0] == stable_parser.tokens['NAME'] if len(node) == 1: return node[0][1], None assert node[1][1] == 'as', node - assert node[2][0] == token.NAME + assert node[2][0] == stable_parser.tokens['NAME'] return node[0][1], node[2][1] def com_import_as_names(self, node): @@ -994,7 +998,7 @@ expr1 = expr2 = None clauses.append((expr1, expr2, self.com_node(nodelist[i+2]))) - if node[0] == token.NAME: + if node[0] == stable_parser.tokens['NAME']: elseNode = self.com_node(nodelist[i+2]) return TryExcept(self.com_node(nodelist[2]), clauses, elseNode, lineno=nodelist[0][2]) @@ -1038,7 +1042,7 @@ primary = self.com_node(node[1]) for i in range(2, len(node)-1): ch = node[i] - if ch[0] == token.DOUBLESTAR: + if ch[0] == stable_parser.tokens['DOUBLESTAR']: self.syntaxerror( "can't assign to operator", node) primary = self.com_apply_trailer(primary, ch) return self.com_assign_trailer(primary, node[-1], @@ -1046,16 +1050,16 @@ node = node[1] elif t == symbol.atom: t = node[1][0] - if t == token.LPAR: + if t == stable_parser.tokens['LPAR']: node = node[2] - if node[0] == token.RPAR: + if node[0] == stable_parser.tokens['RPAR']: self.syntaxerror( "can't assign to ()", node) - elif t == token.LSQB: + elif t == stable_parser.tokens['LSQB']: node = node[2] - if node[0] == token.RSQB: + if node[0] == stable_parser.tokens['RSQB']: self.syntaxerror( "can't assign to []", node) return self.com_assign_list(node, assigning) - elif t == token.NAME: + elif t == stable_parser.tokens['NAME']: if node[1][1] == "__debug__": self.syntaxerror( "can not assign to __debug__", node ) if node[1][1] == "None": @@ -1081,7 +1085,7 @@ if i + 1 < len(node): if node[i + 1][0] == symbol.list_for: self.syntaxerror( "can't assign to list comprehension", node) - assert node[i + 1][0] == token.COMMA, node[i + 1] + assert node[i + 1][0] == stable_parser.tokens['COMMA'], node[i + 1] assigns.append(self.com_assign(node[i], assigning)) return AssList(assigns, lineno=extractLineNo(node)) @@ -1090,11 +1094,11 @@ def com_assign_trailer(self, primary, node, assigning): t = node[1][0] - if t == token.DOT: + if t == stable_parser.tokens['DOT']: return self.com_assign_attr(primary, node[2], assigning) - if t == token.LSQB: + if t == stable_parser.tokens['LSQB']: return self.com_subscriptlist(primary, node[2], assigning) - if t == token.LPAR: + if t == stable_parser.tokens['LPAR']: if assigning==OP_DELETE: self.syntaxerror( "can't delete function call", node) else: @@ -1142,7 +1146,7 @@ assert len(nodelist[i:]) == 1 return self.com_list_comprehension(values[0], nodelist[i]) - elif nodelist[i][0] == token.COMMA: + elif nodelist[i][0] == stable_parser.tokens['COMMA']: continue values.append(self.com_node(nodelist[i])) return List(values, lineno=lineno) @@ -1241,29 +1245,29 @@ def com_apply_trailer(self, primaryNode, nodelist): t = nodelist[1][0] - if t == token.LPAR: + if t == stable_parser.tokens['LPAR']: return self.com_call_function(primaryNode, nodelist[2]) - if t == token.DOT: + if t == stable_parser.tokens['DOT']: return self.com_select_member(primaryNode, nodelist[2]) - if t == token.LSQB: + if t == stable_parser.tokens['LSQB']: return self.com_subscriptlist(primaryNode, nodelist[2], OP_APPLY) self.syntaxerror( 'unknown node type: %s' % t, nodelist[1]) def com_select_member(self, primaryNode, nodelist): - if nodelist[0] != token.NAME: + if nodelist[0] != stable_parser.tokens['NAME']: self.syntaxerror( "member must be a name", nodelist[0]) return Getattr(primaryNode, nodelist[1], lineno=nodelist[2]) def com_call_function(self, primaryNode, nodelist): - if nodelist[0] == token.RPAR: + if nodelist[0] == stable_parser.tokens['RPAR']: return CallFunc(primaryNode, [], lineno=extractLineNo(nodelist)) args = [] kw = 0 len_nodelist = len(nodelist) for i in range(1, len_nodelist, 2): node = nodelist[i] - if node[0] == token.STAR or node[0] == token.DOUBLESTAR: + if node[0] == stable_parser.tokens['STAR'] or node[0] == stable_parser.tokens['DOUBLESTAR']: break kw, result = self.com_argument(node, kw) @@ -1277,7 +1281,7 @@ else: # No broken by star arg, so skip the last one we processed. i = i + 1 - if i < len_nodelist and nodelist[i][0] == token.COMMA: + if i < len_nodelist and nodelist[i][0] == stable_parser.tokens['COMMA']: # need to accept an application that looks like "f(a, b,)" i = i + 1 star_node = dstar_node = None @@ -1285,11 +1289,11 @@ tok = nodelist[i] ch = nodelist[i+1] i = i + 3 - if tok[0]==token.STAR: + if tok[0]==stable_parser.tokens['STAR']: if star_node is not None: self.syntaxerror( 'already have the varargs indentifier', tok ) star_node = self.com_node(ch) - elif tok[0]==token.DOUBLESTAR: + elif tok[0]==stable_parser.tokens['DOUBLESTAR']: if dstar_node is not None: self.syntaxerror( 'already have the kwargs indentifier', tok ) dstar_node = self.com_node(ch) @@ -1308,9 +1312,9 @@ return 0, self.com_node(nodelist[1]) result = self.com_node(nodelist[3]) n = nodelist[1] - while len(n) == 2 and n[0] != token.NAME: + while len(n) == 2 and n[0] != stable_parser.tokens['NAME']: n = n[1] - if n[0] != token.NAME: + if n[0] != stable_parser.tokens['NAME']: self.syntaxerror( "keyword can't be an expression (%s)"%n[0], n) node = Keyword(n[1], result, lineno=n[2]) return 1, node @@ -1324,8 +1328,8 @@ # backwards compat slice for '[i:j]' if len(nodelist) == 2: sub = nodelist[1] - if (sub[1][0] == token.COLON or \ - (len(sub) > 2 and sub[2][0] == token.COLON)) and \ + if (sub[1][0] == stable_parser.tokens['COLON'] or \ + (len(sub) > 2 and sub[2][0] == stable_parser.tokens['COLON'])) and \ sub[-1][0] != symbol.sliceop: return self.com_slice(primary, sub, assigning) @@ -1339,9 +1343,9 @@ # slice_item: expression | proper_slice | ellipsis ch = node[1] t = ch[0] - if t == token.DOT and node[2][0] == token.DOT: + if t == stable_parser.tokens['DOT'] and node[2][0] == stable_parser.tokens['DOT']: return Ellipsis() - if t == token.COLON or len(node) > 2: + if t == stable_parser.tokens['COLON'] or len(node) > 2: return self.com_sliceobj(node) return self.com_node(ch) @@ -1357,7 +1361,7 @@ items = [] - if node[1][0] == token.COLON: + if node[1][0] == stable_parser.tokens['COLON']: items.append(Const(None)) i = 2 else: @@ -1385,7 +1389,7 @@ # short_slice: [lower_bound] ":" [upper_bound] lower = upper = None if len(node) == 3: - if node[1][0] == token.COLON: + if node[1][0] == stable_parser.tokens['COLON']: upper = self.com_node(node[2]) else: lower = self.com_node(node[1]) @@ -1412,7 +1416,7 @@ return self.get_docstring(sub) return None if n == symbol.atom: - if node[0][0] == token.STRING: + if node[0][0] == stable_parser.tokens['STRING']: s = '' for t in node: s = s + eval(t[1]) @@ -1449,13 +1453,13 @@ # comp_op: '<' | '>' | '=' | '>=' | '<=' | '<>' | '!=' | '==' # | 'in' | 'not' 'in' | 'is' | 'is' 'not' _cmp_types = { - token.LESS : '<', - token.GREATER : '>', - token.EQEQUAL : '==', - token.EQUAL : '==', - token.LESSEQUAL : '<=', - token.GREATEREQUAL : '>=', - token.NOTEQUAL : '!=', + stable_parser.tokens['LESS'] : '<', + stable_parser.tokens['GREATER'] : '>', + stable_parser.tokens['EQEQUAL'] : '==', + stable_parser.tokens['EQUAL'] : '==', + stable_parser.tokens['LESSEQUAL'] : '<=', + stable_parser.tokens['GREATEREQUAL'] : '>=', + stable_parser.tokens['NOTEQUAL'] : '!=', } _assign_types = [ @@ -1474,20 +1478,20 @@ symbol.factor, ] -import types -_names = {} -for k, v in sym_name.items(): - _names[k] = v -for k, v in token.tok_name.items(): - _names[k] = v - -def debug_tree(tree): - l = [] - for elt in tree: - if type(elt) == types.IntType: - l.append(_names.get(elt, elt)) - elif type(elt) == types.StringType: - l.append(elt) - else: - l.append(debug_tree(elt)) - return l +# import types +# _names = {} +# for k, v in sym_name.items(): +# _names[k] = v +# for k, v in token.tok_name.items(): +# _names[k] = v +# +# def debug_tree(tree): +# l = [] +# for elt in tree: +# if type(elt) == types.IntType: +# l.append(_names.get(elt, elt)) +# elif type(elt) == types.StringType: +# l.append(elt) +# else: +# l.append(debug_tree(elt)) +# return l Modified: pypy/dist/pypy/module/recparser/__init__.py ============================================================================== --- pypy/dist/pypy/module/recparser/__init__.py (original) +++ pypy/dist/pypy/module/recparser/__init__.py Mon Feb 26 15:06:33 2007 @@ -47,7 +47,6 @@ 'source2ast' : "pyparser.source2ast", 'decode_string_literal': 'pyparser.decode_string_literal', 'install_compiler_hook' : 'pypy.interpreter.pycompiler.install_compiler_hook', - 'rules' : 'pypy.interpreter.pyparser.pythonparse.grammar_rules', } # Automatically exports each AST class Modified: pypy/dist/pypy/module/recparser/codegen.py ============================================================================== --- pypy/dist/pypy/module/recparser/codegen.py (original) +++ pypy/dist/pypy/module/recparser/codegen.py Mon Feb 26 15:06:33 2007 @@ -54,7 +54,7 @@ def get_size(self): s = 0 - for i in insns: + for i in self.insns: s += i.size() return s Modified: pypy/dist/pypy/module/recparser/compat.py ============================================================================== --- pypy/dist/pypy/module/recparser/compat.py (original) +++ pypy/dist/pypy/module/recparser/compat.py Mon Feb 26 15:06:33 2007 @@ -1,12 +1,17 @@ """Compatibility layer for CPython's parser module""" -from pythonparse import parse_python_source -from pythonutil import PYTHON_PARSER +from pypy.interpreter.pyparser.tuplebuilder import TupleBuilder +from pythonparse import make_pyparser +from pythonutil import pypy_parse +import symbol # XXX use PYTHON_PARSER.symbols ? from compiler import transformer, compile as pycompile +PYTHON_PARSER = make_pyparser() + def suite( source ): strings = [line+'\n' for line in source.split('\n')] - builder = parse_python_source( strings, PYTHON_PARSER, "file_input" ) + builder = TupleBuilder(PYTHON_PARSER) + PYTHON_PARSER.parse_source(source, 'exec', builder) nested_tuples = builder.stack[-1].as_tuple() if builder.source_encoding is not None: return (symbol.encoding_decl, nested_tuples, builder.source_encoding) @@ -16,7 +21,8 @@ def expr( source ): strings = [line+'\n' for line in source.split('\n')] - builder = parse_python_source( strings, PYTHON_PARSER, "eval_input" ) + builder = TupleBuilder(PYTHON_PARSER) + PYTHON_PARSER.parse_source(source, 'eval', builder) nested_tuples = builder.stack[-1].as_tuple() if builder.source_encoding is not None: return (symbol.encoding_decl, nested_tuples, builder.source_encoding) Modified: pypy/dist/pypy/module/recparser/pyparser.py ============================================================================== --- pypy/dist/pypy/module/recparser/pyparser.py (original) +++ pypy/dist/pypy/module/recparser/pyparser.py Mon Feb 26 15:06:33 2007 @@ -8,11 +8,13 @@ from pypy.interpreter.typedef import interp_attrproperty, GetSetProperty from pypy.interpreter.pycode import PyCode from pypy.interpreter.pyparser.syntaxtree import TokenNode, SyntaxNode, AbstractSyntaxVisitor -from pypy.interpreter.pyparser.pythonutil import PYTHON_PARSER +from pypy.interpreter.pyparser.pythonparse import make_pyparser from pypy.interpreter.pyparser.error import SyntaxError from pypy.interpreter.pyparser import grammar, symbol, pytoken from pypy.interpreter.argument import Arguments +# backward compat (temp) +PYTHON_PARSER = make_pyparser() __all__ = [ "ASTType", "STType", "suite", "expr" ] @@ -43,14 +45,17 @@ def visit_tokennode( self, node ): space = self.space + tokens = space.default_compiler.parser.tokens num = node.name lineno = node.lineno if node.value is not None: val = node.value else: - if num not in ( pytoken.NEWLINE, pytoken.INDENT, - pytoken.DEDENT, pytoken.ENDMARKER ): - val = pytoken.tok_rpunct[num] + if num != tokens['NEWLINE'] and \ + num != tokens['INDENT'] and \ + num != tokens['DEDENT'] and \ + num != tokens['ENDMARKER']: + val = space.default_compiler.parser.tok_rvalues[num] else: val = node.value or '' if self.line_info: @@ -145,11 +150,11 @@ totuple = interp2app(STType.descr_totuple), ) -def parse_python_source(space, source, goal): - builder = grammar.BaseGrammarBuilder(debug=False, rules=PYTHON_PARSER.rules) +def parse_python_source(space, source, mode): + builder = grammar.BaseGrammarBuilder(debug=False, parser=PYTHON_PARSER) builder.space = space try: - PYTHON_PARSER.parse_source(source, goal, builder ) + PYTHON_PARSER.parse_source(source, mode, builder ) return builder.stack[-1] except SyntaxError, e: raise OperationError(space.w_SyntaxError, @@ -157,14 +162,14 @@ def suite( space, source ): # make the annotator life easier (don't use str.splitlines()) - syntaxtree = parse_python_source( space, source, "file_input" ) + syntaxtree = parse_python_source( space, source, "exec" ) return space.wrap( STType(space, syntaxtree) ) suite.unwrap_spec = [ObjSpace, str] def expr( space, source ): # make the annotator life easier (don't use str.splitlines()) - syntaxtree = parse_python_source( space, source, "eval_input" ) + syntaxtree = parse_python_source( space, source, "eval" ) return space.wrap( STType(space, syntaxtree) ) expr.unwrap_spec = [ObjSpace, str] @@ -180,7 +185,7 @@ items = space.unpackiterable( w_sequence ) nodetype = space.int_w( items[0] ) is_syntax = True - if nodetype>=0 and nodetype=0 and nodetype < pytoken.N_TOKENS: is_syntax = False if is_syntax: nodes = [] @@ -201,11 +206,8 @@ def source2ast(space, source): - from pypy.interpreter.pyparser.pythonutil import AstBuilder, PYTHON_PARSER - builder = AstBuilder(space=space) - PYTHON_PARSER.parse_source(source, 'file_input', builder) - ast_tree = builder.rule_stack[-1] - return space.wrap(ast_tree) + from pypy.interpreter.pyparser.pythonutil import source2ast + return space.wrap(source2ast(source, 'exec', space=space)) source2ast.unwrap_spec = [ObjSpace, str] Modified: pypy/dist/pypy/module/recparser/test/test_parser.py ============================================================================== --- pypy/dist/pypy/module/recparser/test/test_parser.py (original) +++ pypy/dist/pypy/module/recparser/test/test_parser.py Mon Feb 26 15:06:33 2007 @@ -15,3 +15,8 @@ def test_enc_minimal(self): import parser parser.suite("# -*- coding: koi8-u -*-*\ngreat()") + + def test_simple_ass_totuple(self): + import parser + parser.suite("a = 3").totuple() + Modified: pypy/dist/pypy/module/symbol/__init__.py ============================================================================== --- pypy/dist/pypy/module/symbol/__init__.py (original) +++ pypy/dist/pypy/module/symbol/__init__.py Mon Feb 26 15:06:33 2007 @@ -12,19 +12,19 @@ class Module(MixedModule): - """Non-terminal symbols of Python grammar.""" - - appleveldefs = {} - interpleveldefs = {} # see below + """Non-terminal symbols of Python grammar.""" + appleveldefs = {} + interpleveldefs = {} # see below # Export the values from our custom symbol module. # Skip negative values (the corresponding symbols are not visible in # pure Python). -from pypy.interpreter.pyparser.pythonparse import PYTHON_PARSER +from pypy.interpreter.pyparser.pythonparse import make_pyparser +parser = make_pyparser() sym_name = {} -for val, name in PYTHON_PARSER.symbols.sym_name.items(): +for name, val in parser.symbols.items(): if val >= 0: Module.interpleveldefs[name] = 'space.wrap(%d)' % val sym_name[val] = name 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 Mon Feb 26 15:06:33 2007 @@ -49,9 +49,9 @@ def leave_subgraph(self): self.emit("}") - def emit_edge(self, name1, name2, label="", - style="dashed", - color="black", + def emit_edge(self, name1, name2, label="", + style="dashed", + color="black", dir="forward", weight="5", ): From arigo at codespeak.net Tue Feb 27 09:16:48 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 27 Feb 2007 09:16:48 +0100 (CET) Subject: [pypy-svn] r39481 - pypy/dist/pypy/objspace/std Message-ID: <20070227081648.47BEE10187@code0.codespeak.net> Author: arigo Date: Tue Feb 27 09:16:46 2007 New Revision: 39481 Modified: pypy/dist/pypy/objspace/std/dictmultiobject.py Log: Kill line computing unused value. Modified: pypy/dist/pypy/objspace/std/dictmultiobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/dictmultiobject.py (original) +++ pypy/dist/pypy/objspace/std/dictmultiobject.py Tue Feb 27 09:16:46 2007 @@ -806,7 +806,6 @@ assert isinstance(implementation, SharedDictImplementation) for key, index in self.iterator: if index >= 0: - w_value = implementation.entries[index] return self.space.wrap(key) else: return None From arigo at codespeak.net Tue Feb 27 09:20:54 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 27 Feb 2007 09:20:54 +0100 (CET) Subject: [pypy-svn] r39482 - in pypy/dist: lib-python/modified-2.4.1 pypy/config pypy/interpreter pypy/interpreter/astcompiler pypy/interpreter/test Message-ID: <20070227082054.5AD3810196@code0.codespeak.net> Author: arigo Date: Tue Feb 27 09:20:52 2007 New Revision: 39482 Added: pypy/dist/pypy/interpreter/callmethod.py (contents, props changed) pypy/dist/pypy/interpreter/test/test_callmethod.py (contents, props changed) Modified: pypy/dist/lib-python/modified-2.4.1/opcode.py pypy/dist/pypy/config/pypyoption.py pypy/dist/pypy/interpreter/astcompiler/pyassem.py pypy/dist/pypy/interpreter/astcompiler/pycodegen.py pypy/dist/pypy/interpreter/baseobjspace.py Log: Two bytecodes to try to speed up method calls. See callmethod.py for a description. The goal is to avoid creating the bound method object in the common case. Only works for keyword-less, *arg-less, **arg-less calls so far but it would be easy to extend. Modified: pypy/dist/lib-python/modified-2.4.1/opcode.py ============================================================================== --- pypy/dist/lib-python/modified-2.4.1/opcode.py (original) +++ pypy/dist/lib-python/modified-2.4.1/opcode.py Tue Feb 27 09:20:52 2007 @@ -189,5 +189,7 @@ # pypy modification, experimental bytecode def_op('CALL_LIKELY_BUILTIN', 144) # #args + (#kwargs << 8) +def_op('LOOKUP_METHOD', 145) # Index in name list +def_op('CALL_METHOD', 146) # #args not including 'self' del def_op, name_op, jrel_op, jabs_op Modified: pypy/dist/pypy/config/pypyoption.py ============================================================================== --- pypy/dist/pypy/config/pypyoption.py (original) +++ pypy/dist/pypy/config/pypyoption.py Tue Feb 27 09:20:52 2007 @@ -58,7 +58,10 @@ BoolOption("CALL_LIKELY_BUILTIN", "emit a special bytecode for likely calls to builtin functions", default=False, requires=[("objspace.usepycfiles", False), - ("objspace.std.withmultidict", True)]) + ("objspace.std.withmultidict", True)]), + BoolOption("CALL_METHOD", "emit a special bytecode for expr.name()", + default=False, + requires=[("objspace.usepycfiles", False)]), ]), BoolOption("nofaking", "disallow faking in the object space", Modified: pypy/dist/pypy/interpreter/astcompiler/pyassem.py ============================================================================== --- pypy/dist/pypy/interpreter/astcompiler/pyassem.py (original) +++ pypy/dist/pypy/interpreter/astcompiler/pyassem.py Tue Feb 27 09:20:52 2007 @@ -745,6 +745,7 @@ _convert_LOAD_GLOBAL = _convert_NAME _convert_STORE_GLOBAL = _convert_NAME _convert_DELETE_GLOBAL = _convert_NAME + _convert_LOOKUP_METHOD = _convert_NAME def _convert_DEREF(self, inst): assert isinstance(inst, InstrName) @@ -938,6 +939,8 @@ return depth_CALL_FUNCTION(argc)-1 def depth_CALL_FUNCTION_VAR_KW(argc): return depth_CALL_FUNCTION(argc)-2 +def depth_CALL_METHOD(argc): + return -argc-1 def depth_MAKE_FUNCTION(argc): return -argc def depth_MAKE_CLOSURE(argc): @@ -1039,6 +1042,7 @@ 'SETUP_FINALLY': 3, 'FOR_ITER': 1, 'WITH_CLEANUP': 3, + 'LOOKUP_METHOD': 1, } # use pattern match patterns = [ Modified: pypy/dist/pypy/interpreter/astcompiler/pycodegen.py ============================================================================== --- pypy/dist/pypy/interpreter/astcompiler/pycodegen.py (original) +++ pypy/dist/pypy/interpreter/astcompiler/pycodegen.py Tue Feb 27 09:20:52 2007 @@ -1008,11 +1008,13 @@ self.emit('EXEC_STMT') def visitCallFunc(self, node): + self.set_lineno(node) if self.emit_builtin_call(node): return + if self.emit_method_call(node): + return pos = 0 kw = 0 - self.set_lineno(node) node.node.accept( self ) for arg in node.args: arg.accept( self ) @@ -1029,18 +1031,20 @@ opcode = callfunc_opcode_info[ have_star*2 + have_dstar] self.emitop_int(opcode, kw << 8 | pos) - def emit_builtin_call(self, node): - if not self.space.config.objspace.opcodes.CALL_LIKELY_BUILTIN: - return False + def check_simple_call_args(self, node): if node.star_args is not None or node.dstar_args is not None: return False - pos = 0 # check for kw args for arg in node.args: if isinstance(arg, ast.Keyword): return False - else: - pos = pos + 1 + return True + + def emit_builtin_call(self, node): + if not self.space.config.objspace.opcodes.CALL_LIKELY_BUILTIN: + return False + if not self.check_simple_call_args(node): + return False func = node.node if not isinstance(func, ast.Name): return False @@ -1054,10 +1058,25 @@ and index != -1): for arg in node.args: arg.accept(self) - self.emitop_int("CALL_LIKELY_BUILTIN", index << 8 | pos) + self.emitop_int("CALL_LIKELY_BUILTIN", index << 8 | len(node.args)) return True return False + def emit_method_call(self, node): + if not self.space.config.objspace.opcodes.CALL_METHOD: + return False + meth = node.node + if not isinstance(meth, ast.Getattr): + return False + if not self.check_simple_call_args(node): + return False + meth.expr.accept(self) + self.emitop('LOOKUP_METHOD', self.mangle(meth.attrname)) + for arg in node.args: + arg.accept(self) + self.emitop_int('CALL_METHOD', len(node.args)) + return True + def visitPrint(self, node): self.set_lineno(node) if node.dest: Modified: pypy/dist/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/dist/pypy/interpreter/baseobjspace.py (original) +++ pypy/dist/pypy/interpreter/baseobjspace.py Tue Feb 27 09:20:52 2007 @@ -179,6 +179,8 @@ # import extra modules for side-effects, possibly based on config import pypy.interpreter.nestedscope # register *_DEREF bytecodes + if self.config.objspace.opcodes.CALL_METHOD: + import pypy.interpreter.callmethod # register *_METHOD bytecodes self.interned_strings = {} self.pending_actions = [] Added: pypy/dist/pypy/interpreter/callmethod.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/interpreter/callmethod.py Tue Feb 27 09:20:52 2007 @@ -0,0 +1,63 @@ +""" +Two bytecodes to speed up method calls. Here is how a method call looks +like: (on the left, without the new bytecodes; on the right, with them) + + + LOAD_ATTR name LOOKUP_METHOD name + + ... ... + + CALL_FUNCTION n CALL_METHOD n +""" + +from pypy.interpreter import pyframe, function + + +class __extend__(pyframe.PyFrame): + + def LOOKUP_METHOD(f, nameindex, *ignored): + # stack before after + # -------------- --fast-method----fallback-case------------ + # + # w_object None + # w_object => w_function w_boundmethod_or_whatever + # (more stuff) (more stuff) (more stuff) + # + # NB. this assumes a space based on pypy.objspace.descroperation. + space = f.space + w_obj = f.popvalue() + w_name = f.getname_w(nameindex) + w_typ = space.type(w_obj) + w_src, w_dummy = space.lookup_in_type_where(w_typ, '__getattribute__') + w_value = None + if space.is_w(w_src, space.w_object): + name = space.str_w(w_name) + w_descr = space.lookup(w_obj, name) + descr = space.interpclass_w(w_descr) + if descr is None: + # this handles directly the common case + # module.function(args..) + w_value = w_obj.getdictvalue(space, w_name) + elif type(descr) is function.Function: + w_value = w_obj.getdictvalue_attr_is_in_class(space, w_name) + if w_value is None: + # fast method path: a function object in the class, + # nothing in the instance + f.pushvalue(w_descr) + f.pushvalue(w_obj) + return + if w_value is None: + w_value = space.getattr(w_obj, w_name) + f.pushvalue(w_value) + f.pushvalue(None) + + def CALL_METHOD(f, nargs, *ignored): + # 'nargs' is the argument count excluding the implicit 'self' + w_self = f.peekvalue(nargs) + w_callable = f.peekvalue(nargs + 1) + try: + n = nargs + (w_self is not None) + w_result = f.space.call_valuestack(w_callable, n, f) + finally: + f.dropvalues(nargs + 2) + f.pushvalue(w_result) Added: pypy/dist/pypy/interpreter/test/test_callmethod.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/interpreter/test/test_callmethod.py Tue Feb 27 09:20:52 2007 @@ -0,0 +1,105 @@ +from pypy.conftest import gettestobjspace + + +class AppTestCallMethod: + # The exec hacking is needed to have the code snippets compiled + # by our own compiler, not CPython's + + def setup_class(cls): + cls.space = gettestobjspace(**{"objspace.opcodes.CALL_METHOD": True}) + + def test_call_method(self): + exec """if 1: + class C(object): + def m(*args, **kwds): + return args, kwds + sm = staticmethod(m) + cm = classmethod(m) + + c = C() + assert c.m() == ((c,), {}) + assert c.sm() == ((), {}) + assert c.cm() == ((C,), {}) + assert c.m(5) == ((c, 5), {}) + assert c.sm(6) == ((6,), {}) + assert c.cm(7) == ((C, 7), {}) + assert c.m(5, x=3) == ((c, 5), {'x': 3}) + assert c.m(*range(5)) == ((c, 0, 1, 2, 3, 4), {}) + assert c.m(**{'u': 4}) == ((c,), {'u': 4}) + """ + + def test_call_attribute(self): + exec """if 1: + class C(object): + def m(*args, **kwds): + return args, kwds + def myfunc(*args): + return args + + c = C() + c.m = c.m2 = myfunc + assert c.m() == () + assert c.m(5, 2) == (5, 2) + assert c.m2(4) == (4,) + assert c.m2("h", "e", "l", "l", "o") == tuple("hello") + """ + + def test_call_module(self): + exec """if 1: + import sys + try: + sys.exit(5) + except SystemExit, e: + assert e.args == (5,) + else: + raise Exception, "did not raise?" + """ + + def test_custom_getattr(self): + exec """if 1: + class C(object): + def __getattr__(self, name): + if name == 'bla': + return myfunc + raise AttributeError + def myfunc(*args): + return args + + c = C() + assert c.bla(1, 2, 3) == (1, 2, 3) + """ in {} + + def test_custom_getattribute(self): + exec """if 1: + class C(object): + def __getattribute__(self, name): + if name == 'bla': + return myfunc + raise AttributeError + def bla(self): + Boom + def myfunc(*args): + return args + + c = C() + assert c.bla(1, 2, 3) == (1, 2, 3) + """ in {} + + def test_builtin(self): + exec """if 1: + class C(object): + foobar = len + c = C() + assert c.foobar("hello") == 5 + """ + + def test_attributeerror(self): + exec """if 1: + assert 5 .__add__(6) == 11 + try: + 6 .foobar(7) + except AttributeError: + pass + else: + raise Exception("did not raise?") + """ From arigo at codespeak.net Tue Feb 27 12:01:42 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 27 Feb 2007 12:01:42 +0100 (CET) Subject: [pypy-svn] r39485 - pypy/dist/pypy/config Message-ID: <20070227110142.A164A1016D@code0.codespeak.net> Author: arigo Date: Tue Feb 27 12:01:40 2007 New Revision: 39485 Modified: pypy/dist/pypy/config/pypyoption.py Log: Success: CALL_METHOD benchmarks give impressively good results together with method caching. richards is only 1.7x slower than on CPython. Modified: pypy/dist/pypy/config/pypyoption.py ============================================================================== --- pypy/dist/pypy/config/pypyoption.py (original) +++ pypy/dist/pypy/config/pypyoption.py Tue Feb 27 12:01:40 2007 @@ -193,6 +193,7 @@ "enable all thought-to-be-working optimizations", default=False, suggests=[("objspace.opcodes.CALL_LIKELY_BUILTIN", True), + ("objspace.opcodes.CALL_METHOD", True), ("translation.withsmallfuncsets", 5), ("translation.profopt", "-c 'from richards import main;main(); from test import pystone; pystone.main()'"), From cfbolz at codespeak.net Tue Feb 27 12:14:29 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Tue, 27 Feb 2007 12:14:29 +0100 (CET) Subject: [pypy-svn] r39486 - pypy/extradoc/sprintinfo/trillke-2007 Message-ID: <20070227111429.0FDCE1017D@code0.codespeak.net> Author: cfbolz Date: Tue Feb 27 12:14:26 2007 New Revision: 39486 Modified: pypy/extradoc/sprintinfo/trillke-2007/eu-planning.txt Log: (all): puh, long planning session Modified: pypy/extradoc/sprintinfo/trillke-2007/eu-planning.txt ============================================================================== --- pypy/extradoc/sprintinfo/trillke-2007/eu-planning.txt (original) +++ pypy/extradoc/sprintinfo/trillke-2007/eu-planning.txt Tue Feb 27 12:14:26 2007 @@ -21,3 +21,92 @@ * statistic session * strategy discussion about D14.4 * the "avoid and abolish redundancy"-discussion + + ++=======+====================+==============+==============+===================================+ +|Report | Responsible Person | draft date | interim date | status | ++=======+====================+==============+==============+===================================+ +|TD01.2 | Management | | 31.03. final | almost finished | +|TD01.3 | Management | | | | +|TD01.4 | Management | | | | ++-------+--------------------+--------------+--------------+-----------------------------------+ +|TD02.1 | Holger | 21.2. | 10.03. | in progress | ++-------+--------------------+--------------+--------------+-----------------------------------+ +|TD02.2 | Holger | 20.2. | 10.03. | not started | ++-------+--------------------+--------------+--------------+-----------------------------------+ +| D02.3 | Holger | 01.3. | 10.03. | draft published | ++-------+--------------------+--------------+--------------+-----------------------------------+ +| D03.1 | Armin | | 10.03. | draft published | ++-------+--------------------+--------------+--------------+-----------------------------------+ +| D06.1 | CF, AR | 10.3. | 31.03. | outline | ++-------+--------------------+--------------+--------------+-----------------------------------+ +| D07.1 | Carl Friedrich | | 28.02. final | done | ++-------+--------------------+--------------+--------------+-----------------------------------+ +|TD08.1 | Samuele | | 30.04. | dependant on 1.0 release | ++-------+--------------------+--------------+--------------+-----------------------------------+ +| D08.2 | Samuele | | 30.04. | draft published | ++-------+--------------------+--------------+--------------+-----------------------------------+ +| D09.1 | Stephan | | 23.03. | nearly finished, dfki app missing | ++-------+--------------------+--------------+--------------+-----------------------------------+ +| D10.1 | Adrien | 2.2. | 31.03. | draft-like version there | ++-------+--------------------+--------------+--------------+-----------------------------------+ +|TD11.1 | Alexandre | 15.2. | 31.03. | draft-like version there | ++-------+--------------------+--------------+--------------+-----------------------------------+ +| D12.1 | Arre | 28.2. | 10.03. | outline + started a bit | ++-------+--------------------+--------------+--------------+-----------------------------------+ +| D13.1 | Carl Friedrich | | 31.03. | draft published | ++-------+--------------------+--------------+--------------+-----------------------------------+ +|TD14.2 | Bea | | 28.02. | nearly finished | ++-------+--------------------+--------------+--------------+-----------------------------------+ +| D14.4 | Holger | 20.3. | 30.04. | not started | ++-------+--------------------+--------------+--------------+-----------------------------------+ +|TD14.5 | Bea | | 10.03. | significantly started | ++-------+--------------------+--------------+--------------+-----------------------------------+ + +Promised in amendment 5 +================================ + + * wp3 interim: november 2006 + * wp6 interim: november 2006 + * wp7: october 2006 + * wp8 interim: december 2006 + + +Potential external reviewers +============================ + + ++=======+==========================================+============================+ +|Report | Reviewer ideas | internal reviewers | ++=======+==========================================+============================+ +| D02.1 | | | ++-------+------------------------------------------+----------------------------+ +| D02.2 | | | ++-------+------------------------------------------+----------------------------+ +| D02.3 | HP, Grig Gheorghiu | | ++-------+------------------------------------------+----------------------------+ +| D03.1 | Georg Brandl? Thomas Heller? | | ++-------+------------------------------------------+----------------------------+ +| D06.1 | Martijn Faassen, ??? | | ++-------+------------------------------------------+----------------------------+ +| D08.1 | maybe not needed | | ++-------+------------------------------------------+----------------------------+ +| D08.2 | Michael Franz, Michael Leuschel | | ++-------+------------------------------------------+----------------------------+ +| D09.1 | already reviewed | | ++-------+------------------------------------------+----------------------------+ +| D10.1 | | | ++-------+------------------------------------------+----------------------------+ +| D11.1 | | | ++-------+------------------------------------------+----------------------------+ +| D12.1 | different reviewers? Matthias Schunter? | | ++-------+------------------------------------------+----------------------------+ +| D13.1 | Martijn Faassen?, Andrea Glorioso? | | ++-------+------------------------------------------+----------------------------+ +| D14.2 | Steve Holden (confirmed) | | ++-------+------------------------------------------+----------------------------+ +| D14.4 | ??? | | ++-------+------------------------------------------+----------------------------+ +| D14.5 | Gabriela Avram | | ++-------+------------------------------------------+----------------------------+ + From arigo at codespeak.net Tue Feb 27 13:37:17 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 27 Feb 2007 13:37:17 +0100 (CET) Subject: [pypy-svn] r39496 - in pypy: eu-tracking/minute extradoc/sprintinfo/trillke-2007 Message-ID: <20070227123717.7BEFA10167@code0.codespeak.net> Author: arigo Date: Tue Feb 27 13:37:15 2007 New Revision: 39496 Added: pypy/eu-tracking/minute/trillke-2007-planning.txt - copied unchanged from r39494, pypy/extradoc/sprintinfo/trillke-2007/eu-planning.txt Removed: pypy/extradoc/sprintinfo/trillke-2007/eu-planning.txt Log: Moved. From santagada at codespeak.net Tue Feb 27 14:47:22 2007 From: santagada at codespeak.net (santagada at codespeak.net) Date: Tue, 27 Feb 2007 14:47:22 +0100 (CET) Subject: [pypy-svn] r39503 - in pypy/dist/pypy/lang/js: . test/ecma Message-ID: <20070227134722.660741014B@code0.codespeak.net> Author: santagada Date: Tue Feb 27 14:47:20 2007 New Revision: 39503 Modified: pypy/dist/pypy/lang/js/js_interactive.py pypy/dist/pypy/lang/js/jsobj.py pypy/dist/pypy/lang/js/test/ecma/conftest.py Log: made the ecma tests run again Modified: pypy/dist/pypy/lang/js/js_interactive.py ============================================================================== --- pypy/dist/pypy/lang/js/js_interactive.py (original) +++ pypy/dist/pypy/lang/js/js_interactive.py Tue Feb 27 14:47:20 2007 @@ -157,12 +157,15 @@ if isinstance(e, jsparser.JsSyntaxError): print "\nSyntax error!" elif isinstance(e, ThrowException): - print "\nJS Exception thrown!" + print e.exception.ToString() return finally: self.reset() - if res is not None or res is not w_Undefined: - print res.GetValue().ToString() + if (res is not None) and (res is not w_Undefined): + try: + print res.GetValue().ToString() + except ThrowException, e: + print e.exception.ToString() if __name__ == "__main__": import py Modified: pypy/dist/pypy/lang/js/jsobj.py ============================================================================== --- pypy/dist/pypy/lang/js/jsobj.py (original) +++ pypy/dist/pypy/lang/js/jsobj.py Tue Feb 27 14:47:20 2007 @@ -15,8 +15,7 @@ class ThrowException(JsBaseExcept): def __init__(self, exception): - self.exception = exception - self.args = self.exception + self.exception = self.args = exception class JsTypeError(JsBaseExcept): pass Modified: pypy/dist/pypy/lang/js/test/ecma/conftest.py ============================================================================== --- pypy/dist/pypy/lang/js/test/ecma/conftest.py (original) +++ pypy/dist/pypy/lang/js/test/ecma/conftest.py Tue Feb 27 14:47:20 2007 @@ -5,14 +5,16 @@ from py.__.test.outcome import Failed, ExceptionFailure import pypy.lang.js as js -js.jsobj.DEBUG = True +js.jsobj.DEBUG = False rootdir = py.magic.autopath().dirpath() exclusionlist = ['shell.js', 'browser.js'] class JSDirectory(py.test.collect.Directory): - def filefilter(self, path): + def filefilter(self, path): + if not py.test.config.option.ecma: + return False if path.check(file=1): return (path.basename not in exclusionlist) and (path.ext == '.js') @@ -85,5 +87,4 @@ def _getpathlineno(self): return self.parent.parent.fspath, 0 -if py.test.config.option.ecma: - Directory = JSDirectory +Directory = JSDirectory From arigo at codespeak.net Wed Feb 28 10:48:14 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 28 Feb 2007 10:48:14 +0100 (CET) Subject: [pypy-svn] r39556 - pypy/dist/pypy/doc Message-ID: <20070228094814.3D89210137@code0.codespeak.net> Author: arigo Date: Wed Feb 28 10:48:12 2007 New Revision: 39556 Modified: pypy/dist/pypy/doc/extcompiler.txt Log: Small updates and XXX fixes. Modified: pypy/dist/pypy/doc/extcompiler.txt ============================================================================== --- pypy/dist/pypy/doc/extcompiler.txt (original) +++ pypy/dist/pypy/doc/extcompiler.txt Wed Feb 28 10:48:12 2007 @@ -11,10 +11,15 @@ **WARNING: this is beta software, APIs and details may change.** -The documentation corresponds to release 0.9. The extension compiler +The documentation corresponds to release 0.99. The extension compiler has not been extensively tested and polished so far, so bugs and rough edges are likely. +The final version of the Technical Report D03.1 also describes the +extension compiler's goals in more details and presents an overview of +its implementation +(http://codespeak.net/pypy/dist/pypy/doc/index-report.html). + .. _introduction: @@ -28,7 +33,8 @@ PyPy the greatest drawback of hard-coded C external modules is that low-level details like multithreading (e.g. locks) and memory management must be explicitly written in such a language, which would prevent the -same module from being used in several different versions of pypy-c. +same module from being used in several differently-compiled versions of +``pypy-c``. PyPy provides instead a generic way to write modules for all Python implementations: the so-called *mixed module* approach. A single mixed @@ -70,7 +76,7 @@ * run it with PyPy on top of CPython. Example:: $ python pypy/bin/py.py --usemodules=_demo - PyPy 0.9.0 in StdObjSpace on top of Python 2.4.4c0 (startuptime: 2.47 secs) + PyPy 0.99.0 in StdObjSpace on top of Python 2.4.3 >>>> import _demo >>>> _demo.measuretime(10000, long) [ignore output here] @@ -81,11 +87,11 @@ $ cd pypy/translator/goal $ python translate.py targetpypystandalone --usemodules=_demo - [wait for 1/2 to 1 hour] + [wait for 30 minutes] [translation:info] created: ./pypy-c (Pbd) $ ./pypy-c - Python 2.4.1 (pypy 0.9.0 build 28xxx) on linux2 + Python 2.4.1 (pypy 0.9.0 build xxxxx) on linux2 Type "help", "copyright", "credits" or "license" for more information. (InteractiveConsole) >>>> import _demo @@ -169,8 +175,22 @@ app-level will pass all the provided arguments as wrapped objects to the interp-level function. Alternatively, the interp-level function can have an ``unwrap_spec`` attribute that declares what type of arguments -it expects (XXX this is not documented in detail so far; grep for -examples...). +it expects. The ``unwrap_spec`` is a list of specifiers, one per +argument; the specifiers can be one of the following strings or objects +(to be imported from `pypy/interpreter/gateway.py`_): + +* ``ObjSpace``: used to specify the space argument. +* ``W_Root``: for wrapped arguments to keep wrapped. +* ``str``: check that the argument is a string, and unwrap it. +* ``int``: check that the argument is an integer, and unwrap it. +* ``float``: check that the argument is a float, and unwrap it. +* ``"self"``: for methods of Wrappable subclasses, the unwrapped self. +* *Wrappable-subcls*: an instance of the given Wrappable subclass, unwrapped. +* ``Arguments``: an instance of ``pypy.interpreter.argument.Arguments`` + collecting the rest of the positional and keyword arguments. +* ``"args_w"``: the rest of the positional arguments as list of wrapped objects. +* ``"w_args"``: the rest of the positional arguments as a single wrapped tuple. +* *(function, cls)*: use function to check/unwrap argument of type cls. There are two ways to export types. The first is to write the type at app-level, as a regular class. You can then call interp-level functions @@ -272,10 +292,4 @@ .. _`installation notes`: rctypes.html#installation -Implementation of the ext compiler ------------------------------------------------ - -XXX no documentation available yet, see `pypy/objspace/cpy`_. - - .. include:: _ref.txt From auc at codespeak.net Wed Feb 28 14:07:58 2007 From: auc at codespeak.net (auc at codespeak.net) Date: Wed, 28 Feb 2007 14:07:58 +0100 (CET) Subject: [pypy-svn] r39567 - in pypy/dist/pypy: config lib/constraint module/cclp module/cclp/constraint module/cclp/constraint/test objspace objspace/cclp objspace/constraint objspace/test rlib/cslib Message-ID: <20070228130758.53FBA1013A@code0.codespeak.net> Author: auc Date: Wed Feb 28 14:07:55 2007 New Revision: 39567 Added: pypy/dist/pypy/module/cclp/ pypy/dist/pypy/module/cclp/__init__.py (contents, props changed) pypy/dist/pypy/module/cclp/constraint/ pypy/dist/pypy/module/cclp/constraint/__init__.py (contents, props changed) pypy/dist/pypy/module/cclp/constraint/btree.py (contents, props changed) pypy/dist/pypy/module/cclp/constraint/constraint.py (contents, props changed) pypy/dist/pypy/module/cclp/constraint/distributor.py (contents, props changed) pypy/dist/pypy/module/cclp/constraint/domain.py (contents, props changed) pypy/dist/pypy/module/cclp/constraint/test/ pypy/dist/pypy/module/cclp/constraint/test/problem.py (contents, props changed) pypy/dist/pypy/module/cclp/constraint/test/test_btree.py (contents, props changed) pypy/dist/pypy/module/cclp/constraint/test/test_constraint.py (contents, props changed) pypy/dist/pypy/module/cclp/constraint/test/test_fd.py (contents, props changed) pypy/dist/pypy/module/cclp/constraint/variable.py (contents, props changed) pypy/dist/pypy/module/cclp/cspace.py (contents, props changed) pypy/dist/pypy/module/cclp/global_state.py (contents, props changed) pypy/dist/pypy/module/cclp/interp_var.py (contents, props changed) pypy/dist/pypy/module/cclp/misc.py (contents, props changed) pypy/dist/pypy/module/cclp/scheduler.py (contents, props changed) pypy/dist/pypy/module/cclp/thread.py (contents, props changed) pypy/dist/pypy/module/cclp/thunk.py (contents, props changed) pypy/dist/pypy/module/cclp/types.py (contents, props changed) pypy/dist/pypy/module/cclp/variable.py (contents, props changed) Removed: pypy/dist/pypy/objspace/cclp/ pypy/dist/pypy/objspace/constraint/ Modified: pypy/dist/pypy/config/pypyoption.py pypy/dist/pypy/lib/constraint/examples.py pypy/dist/pypy/lib/constraint/solver.py pypy/dist/pypy/objspace/logic.py pypy/dist/pypy/objspace/test/test_logicobjspace.py pypy/dist/pypy/rlib/cslib/rdomain.py Log: moving most logic object space stuff to module Modified: pypy/dist/pypy/config/pypyoption.py ============================================================================== --- pypy/dist/pypy/config/pypyoption.py (original) +++ pypy/dist/pypy/config/pypyoption.py Wed Feb 28 14:07:55 2007 @@ -41,6 +41,7 @@ "thunk": [("objspace.geninterp", False)], "logic": [("objspace.geninterp", False), ("objspace.usemodules._stackless", True), + ("objspace.usemodules.cclp", True), ("translation.gc", 'framework'), ], }, Modified: pypy/dist/pypy/lib/constraint/examples.py ============================================================================== --- pypy/dist/pypy/lib/constraint/examples.py (original) +++ pypy/dist/pypy/lib/constraint/examples.py Wed Feb 28 14:07:55 2007 @@ -1,3 +1,4 @@ +from cclp import tell, distribute, make_expression, all_diff # Queens Modified: pypy/dist/pypy/lib/constraint/solver.py ============================================================================== --- pypy/dist/pypy/lib/constraint/solver.py (original) +++ pypy/dist/pypy/lib/constraint/solver.py Wed Feb 28 14:07:55 2007 @@ -22,22 +22,23 @@ def collect(space): sp_stack.appendleft(space) - print "ready to find solution ..." + #print "ready to find solution ..." while sp_stack: space = sp_stack.pop() - print ' '*len(sp_stack), "ask [depth = %s]" % len(sp_stack) + #print ' '*len(sp_stack), "ask [depth = %s]" % len(sp_stack) status = space.ask() if status == 1: - print ' '*len(sp_stack), "solution !" + #print ' '*len(sp_stack), "solution !" yield space.merge() elif status > 1: - print ' '*len(sp_stack), "%s branches ..." % status + #print ' '*len(sp_stack), "%s branches ..." % status for i in xrange(status): clone = space.clone() clone.commit(status-i) collect(clone) elif status == 0: - print ' '*len(sp_stack), "dead-end" + pass + #print ' '*len(sp_stack), "dead-end" solve = lazily_iter_solve_all Added: pypy/dist/pypy/module/cclp/__init__.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/cclp/__init__.py Wed Feb 28 14:07:55 2007 @@ -0,0 +1,33 @@ +# Package initialisation +from pypy.interpreter.mixedmodule import MixedModule + +class Module(MixedModule): + """ + This module implements concurrent constraint logic programming for applications. + """ + + appleveldefs = { + } + + interpleveldefs = { + 'switch_debug_info':'misc.switch_debug_info', + + 'future':'thread.future', + 'stacklet':'thread.stacklet', + 'this_thread':'thread.this_thread', + + 'sched_info':'scheduler.sched_info', + 'schedule':'scheduler.schedule', + 'reset_scheduler':'scheduler.reset_scheduler', + + 'newspace':'cspace.newspace', + 'choose':'cspace.choose', + 'tell':'cspace.tell', + + 'distribute':'constraint.distributor.distribute', + + 'make_expression':'constraint.constraint.make_expression', + 'all_diff': 'constraint.constraint.make_alldistinct' + + } + Added: pypy/dist/pypy/module/cclp/constraint/__init__.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/cclp/constraint/__init__.py Wed Feb 28 14:07:55 2007 @@ -0,0 +1 @@ +# pass Added: pypy/dist/pypy/module/cclp/constraint/btree.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/cclp/constraint/btree.py Wed Feb 28 14:07:55 2007 @@ -0,0 +1,75 @@ +from pypy.interpreter import baseobjspace + +class Found(Exception): pass + +class BTree(object): + """binary tree""" + + def __init__(self): + self.leaf = True + + def _populate(self, key, val): + self.leaf = False + self.key = key + self.val = val + self.left = BTree() + self.right = BTree() + + def add(self, key, val): + assert isinstance(key, int) + assert isinstance(val, baseobjspace.W_Root) + if self.leaf: + self._populate(key, val) + else: + if key > self.key: + self.right.add(key, val) + else: + self.left.add(key, val) + + def _in(self, key): + if self.leaf: + return False + if self.key == key: raise Found + self.left._in(key) + self.right._in(key) + + def __contains__(self, key): + if self.leaf: return False + if self.key == key: return True + try: + self._in(key) + self._in(key) + return False + except Found: + return True + + def _infixly(self, output, ret=0): + """depending on the value of ret: + 0 : keys + 1 : values + 2 : both (items) + """ + if self.leaf: return + self.left._infixly(output, ret) + if ret == 0: + output.append(self.key) + elif ret == 1: + output.append(self.val) + else: + output.append((self.key, self.val)) + self.right._infixly(output, ret) + + def keys(self): + out = [] + self._infixly(out, ret=0) + return out + + def values(self): + out = [] + self._infixly(out, ret=1) + return out + + def items(self): + out = [] + self._infixly(out, ret=2) + return out Added: pypy/dist/pypy/module/cclp/constraint/constraint.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/cclp/constraint/constraint.py Wed Feb 28 14:07:55 2007 @@ -0,0 +1,317 @@ +from pypy.rlib.objectmodel import we_are_translated +from pypy.interpreter.error import OperationError +from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter import baseobjspace, typedef, gateway +from pypy.interpreter.gateway import interp2app +from pypy.interpreter.function import Function + +from pypy.objspace.std.listobject import W_ListObject +from pypy.objspace.std.stringobject import W_StringObject +from pypy.objspace.std.dictobject import W_DictObject + +from pypy.module.cclp.types import W_Constraint, W_AbstractDomain, W_Root, \ + W_CVar as W_Variable + +from pypy.objspace.std.model import StdObjSpaceMultiMethod + +from pypy.module.cclp.constraint.btree import BTree +#from pypy.objspace.constraint.util import sort + +all_mms = {} + + +class W_AbstractConstraint(W_Constraint): + + def __init__(self, object_space, w_variables): + """variables is a list of variables which appear in the formula""" + W_Constraint.__init__(self, object_space) + assert isinstance(w_variables, W_ListObject) + assert self._space.is_true(self._space.ge(self._space.len(w_variables), + self._space.newint(1))) + self._names_to_vars = {} + for var in w_variables.wrappeditems: + self._names_to_vars[var.name_w()] = var + self._variables = w_variables.wrappeditems #unwrap once ... + + def w_affected_variables(self): + """ Return a list of all variables affected by this constraint """ + return self._space.newlist(self._variables) + + def affected_variables(self): + return self._variables + + def w_revise(self): + return self._space.newbool(self.revise()) + +W_AbstractConstraint.typedef = typedef.TypeDef( + "W_AbstractConstraint", + W_Constraint.typedef, + affected_variables = interp2app(W_AbstractConstraint.w_affected_variables), + revise = interp2app(W_AbstractConstraint.w_revise)) + + + +from pypy.module.__builtin__.compiling import eval as ev +def make_filter__List_String(object_space, w_variables, w_formula): + """NOT RPYTHON""" + assert isinstance(w_variables, W_ListObject) + assert isinstance(w_formula, W_StringObject) + items = object_space.unpackiterable(w_variables) + for it in items: + assert isinstance(it, W_Variable) + var_ids = ','.join([var.name_w() + for var in items]) + func_head = 'lambda ' + var_ids + ':' + expr = func_head + object_space.str_w(w_formula) + func_obj = ev(object_space, object_space.wrap(expr), object_space.newdict(), + object_space.newdict()) + assert isinstance(func_obj, Function) + return func_obj + +make_filter_mm = StdObjSpaceMultiMethod('make_filter', 2) +make_filter_mm.register(make_filter__List_String, W_ListObject, W_StringObject) +all_mms['make_filter'] = make_filter_mm + +class Quadruple(W_Root): + def __init__(self, zero, one, two, three): + self.zero = zero + self.one = one + self.two = two + self.three = three + +class W_Expression(W_AbstractConstraint): + """A constraint represented as a python expression.""" + + def __init__(self, object_space, w_variables, w_formula): + """variables is a list of variables which appear in the formula + formula is a python expression that will be evaluated as a boolean""" + W_AbstractConstraint.__init__(self, object_space, w_variables) + self.formula = self._space.str_w(w_formula) + # self.filter_func is a function taking keyword arguments and returning a boolean + self.filter_func = self._space.make_filter(w_variables, w_formula) + + def copy(self): + if we_are_translated(): + raise NotImplementedError + else: + newvars = [var.copy(self._space) for var in self._variables] + const = W_Expression(self._space, self._space.newlist(newvars), self._space.wrap(self.formula)) + return const + + def _init_result_cache(self): + """key = (variable,value), value = [has_success,has_failure]""" + result_cache = self._space.newdict() + for var in self._variables: + assert isinstance(var, W_Variable) + result_cache.content[var.w_name()] = self._space.newdict() + return result_cache + + def _assign_values(self): + kwargs = self._space.newdict() + variables = BTree() + for variable in self._variables: + assert isinstance(variable, W_Variable) + domain = variable.w_dom + assert isinstance(domain, W_AbstractDomain) + values = domain.get_values() + assert isinstance(values, list) + ds = domain.size() + assert isinstance(ds, int) + w_name = variable.w_name() + lval = len(values) + variables.add(ds, Quadruple(w_name, values, 0, lval)) + # was meant to be: + #variables.append((domain.size(), + # [w_name, values, 0, len(values)])) + first_value = values[0] + assert isinstance(first_value, W_Root) + kwargs.content[variable.w_name()] = first_value + # get sorted variables to instanciate those with fewer possible values first + variables = variables.values() + self._assign_values_state = variables + return kwargs + + def _next_value(self, kwargs): + + # try to instanciate the next variable + variables = self._assign_values_state + + for curr in variables: + assert isinstance(curr, Quadruple) + w_name = curr.zero + dom_values = curr.one + dom_index = curr.two + dom_len = curr.three + assert isinstance(w_name, W_StringObject) + assert isinstance(dom_values, list) + assert isinstance(dom_index, int) + assert isinstance(dom_len, int) + if dom_index < dom_len: + kwargs.content[w_name] = dom_values[dom_index] + curr.two = dom_index + 1 + break + else: + curr.two = 0 + kwargs.content[w_name] = dom_values[0] + else: + # it's over + raise StopIteration + return kwargs + + def revise(self): + """generic propagation algorithm for n-ary expressions""" + sp = self._space + maybe_entailed = True + ffunc = self.filter_func + result_cache = self._init_result_cache() + assert isinstance(result_cache, W_DictObject) + + kwargs = self._assign_values() + assert isinstance(kwargs, W_DictObject) + while 1: + try: + kwargs = self._next_value(kwargs) + assert isinstance(kwargs, W_DictObject) + except StopIteration: + break + if maybe_entailed: + for varname, val in kwargs.content.iteritems(): + val_dict = result_cache.content[varname] + assert isinstance(val_dict, W_DictObject) + if val not in val_dict.content: + break + else: + continue + if sp.is_true(sp.call(sp.wrap(ffunc), + sp.newlist([]), kwargs)): + for var, val in kwargs.content.items(): + var_dict = result_cache.content[var] + assert isinstance(var_dict, W_DictObject) + var_dict.content[val] = sp.w_True + else: + maybe_entailed = False + + try: + for varname, keep in result_cache.content.items(): + var = self._names_to_vars[sp.str_w(varname)] + assert isinstance(var, W_Variable) + assert isinstance(keep, W_DictObject) + domain = var.w_dom + assert isinstance(domain, W_AbstractDomain) + domain.remove_values([val + for val in domain._values.content.keys() + if val not in keep.content]) + except KeyError: + # There are no more value in result_cache + pass + + return maybe_entailed + + + def __repr__(self): + return '<%s>' % self.formula + +W_Expression.typedef = typedef.TypeDef("W_Expression", + W_AbstractConstraint.typedef, + revise = interp2app(W_Expression.w_revise)) + + + +def make_expression(space, w_variables, w_formula): + """create a new constraint of type Expression or BinaryExpression + The chosen class depends on the number of variables in the constraint""" + assert isinstance(w_variables, W_ListObject) + assert isinstance(w_formula, W_StringObject) + assert len(w_variables.wrappeditems) > 0 + return W_Expression(space, w_variables, w_formula) +make_expression.unwrap_spec = [baseobjspace.ObjSpace, + baseobjspace.W_Root, + baseobjspace.W_Root] + + +class W_AllDistinct(W_AbstractConstraint): + """Contraint: all values must be distinct""" + + def __init__(self, object_space, w_variables): + W_AbstractConstraint.__init__(self, object_space, w_variables) + # worst case complexity + #self.__cost = len(w_variables.wrappeditems) * (len(w_variables.wrappeditems) - 1) / 2 + + def copy(self): + if we_are_translated(): + raise NotImplementedError + else: + newvars = [var.copy(self._space) for var in self._variables] + const = W_AllDistinct(self._space, self._space.newlist(newvars)) + return const + + def revise(self): + _spc = self._space + + ord_vars = BTree() + for var in self._variables: + assert isinstance(var, W_Variable) + dom = var.w_dom + assert isinstance(dom, W_AbstractDomain) + sz = dom.size() + ord_vars.add(sz, var) + variables = ord_vars.values() + + # if a domain has a size of 1, + # then the value must be removed from the other domains + for var in variables: + assert isinstance(var, W_Variable) + dom = var.w_dom + assert isinstance(dom, W_AbstractDomain) + if dom.size() == 1: + #print "AllDistinct removes values" + for _var in variables: + assert isinstance(_var, W_Variable) + _dom = _var.w_dom + assert isinstance(_dom, W_AbstractDomain) + if not _var._same_as(var): + try: + _dom.remove_value(dom.get_values()[0]) + except KeyError, e: + # we ignore errors caused by the removal of + # non existing values + pass + + # if there are less values than variables, the constraint fails + values = {} + for var in variables: + assert isinstance(var, W_Variable) + dom = var.w_dom + assert isinstance(dom, W_AbstractDomain) + for val in dom.w_get_values().wrappeditems: + values[val] = 0 + + if len(values) < len(variables): + #print "AllDistinct failed" + raise OperationError(_spc.w_RuntimeError, + _spc.wrap("ConsistencyFailure")) + + # the constraint is entailed if all domains have a size of 1 + for var in variables: + assert isinstance(var, W_Variable) + dom = var.w_dom + assert isinstance(dom, W_AbstractDomain) + if not dom.size() == 1: + return False + + # Question : did we *really* completely check + # our own alldistinctness predicate ? + #print "All distinct entailed" + return True + +W_AllDistinct.typedef = typedef.TypeDef( + "W_AllDistinct", W_AbstractConstraint.typedef, + revise = interp2app(W_AllDistinct.w_revise)) + +#function bolted into the space to serve as constructor +def make_alldistinct(object_space, w_variables): + assert isinstance(w_variables, W_ListObject) + assert len(w_variables.wrappeditems) > 0 + return object_space.wrap(W_AllDistinct(object_space, w_variables)) +make_alldistinct.unwrap_spec = [baseobjspace.ObjSpace, + baseobjspace.W_Root] Added: pypy/dist/pypy/module/cclp/constraint/distributor.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/cclp/constraint/distributor.py Wed Feb 28 14:07:55 2007 @@ -0,0 +1,151 @@ +import math + +from pypy.interpreter.error import OperationError +from pypy.interpreter import baseobjspace, typedef +from pypy.interpreter.gateway import interp2app + +from pypy.objspace.std.intobject import W_IntObject +from pypy.objspace.std.stringobject import W_StringObject + +from pypy.module.cclp.types import W_AbstractDistributor, ConsistencyError +from pypy.module.cclp.misc import w, get_current_cspace + +def distribute(space, w_strategy): + assert isinstance(w_strategy, W_StringObject) + strat = space.str_w(w_strategy) + cspace = get_current_cspace(space) + dist = None + if strat == 'dichotomy': + dist = make_split_distributor(space, space.newint(2)) + else: + raise OperationError(space.w_RuntimeError, + space.wrap("please pick a strategy in (naive, dichotomy)")) + + cspace.distributor = dist + # constraint distributor thread main loop + cspace.wait_stable() + if not dist.distributable(): + return + while 1: + choice = cspace.choose(dist.fanout()) + if dist.distributable(): + dist.w_distribute(choice) + # propagators laucnhed + else: + if cspace._failed: + raise ConsistencyError + break +distribute.unwrap_spec = [baseobjspace.ObjSpace, + baseobjspace.W_Root] + + +class W_Distributor(W_AbstractDistributor): + """_distribute is left unimplemented.""" + + def w_fanout(self): + return self._space.newint(self._fanout) + + def fanout(self): + return self._fanout + + def _find_smallest_domain(self): + """returns the variable having the smallest domain. + (or one of such variables if there is a tie) + """ + vars_ = [var for var in self._cspace._store.values() + if var.w_dom.size() > 1] + best = vars_[0] + for var in vars_: + if var.w_dom.size() < best.w_dom.size(): + best = var + return best + + def distributable(self): + for var in self._cspace._store.values(): + if var.w_dom.size() > 1: + return True + return False + + def w_distribute(self, w_choice): + assert isinstance(w_choice, W_IntObject) + self.distribute(self._space.int_w(w_choice) -1) + + def distribute(self, choice): + assert isinstance(choice, int) + variable = self.find_distribution_variable() + domain = variable.w_dom + self._do_distribute(domain, choice) + + def find_distribution_variable(self): + return self._find_smallest_domain() + + def _do_distribute(self, domain, choice): + """remove values from domain depending on choice""" + raise NotImplementedError + +W_Distributor.typedef = typedef.TypeDef("W_Distributor", + W_AbstractDistributor.typedef, + fanout = interp2app(W_Distributor.w_fanout), + distribute = interp2app(W_Distributor.w_distribute)) + + +class W_NaiveDistributor(W_Distributor): + """distributes domains by splitting the smallest domain in 2 new domains + The first new domain has a size of one, + and the second has all the other values""" + + + def _do_distribute(self, domain, choice): + values = domain.get_values() + #assert len(values) > 0 + if choice == 0: + domain.remove_values(values[1:]) + else: + domain.w_remove_value(values[0]) #XXX w ? not w ? + +W_NaiveDistributor.typedef = typedef.TypeDef( + "W_NaiveDistributor", + W_Distributor.typedef) + +def make_naive_distributor(object_space, fanout=2): + if not isinstance(fanout, int): + raise OperationError(object_space.w_RuntimeError, + object_space.wrap("fanout must be a positive integer")) + return W_NaiveDistributor(object_space, fanout) +app_make_naive_distributor = interp2app(make_naive_distributor, + unwrap_spec = [baseobjspace.ObjSpace, int]) + + +class W_SplitDistributor(W_Distributor): + """distributes domains by splitting the smallest domain in + nb_subspaces equal parts or as equal as possible. + If nb_subspaces is 0, then the smallest domain is split in + domains of size 1""" + + def _subdomains(self): + """returns the min number of partitions + for a domain to be distributed""" + to_split = self._find_smallest_domain() + if self._fanout > 0: + return min(self._fanout, to_split.w_dom.size()) + else: + return to_split.w_dom.size() + + def _do_distribute(self, domain, choice): + values = domain.get_values() + subdoms = self._subdomains() + nb_elts = max(subdoms, len(values)) / float(subdoms) + start, end = (int(math.floor(choice * nb_elts)), + int(math.floor((choice + 1) * nb_elts))) + lv = len(values) + assert start >= 0 + assert start <= lv + domain.remove_values(values[:start]) + assert end >= 0 + assert end <= lv + domain.remove_values(values[end:]) + +def make_split_distributor(space, w_fanout): + return W_SplitDistributor(space, space.int_w(w_fanout)) +app_make_split_distributor = interp2app(make_split_distributor) + Added: pypy/dist/pypy/module/cclp/constraint/domain.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/cclp/constraint/domain.py Wed Feb 28 14:07:55 2007 @@ -0,0 +1,165 @@ +from pypy.interpreter.error import OperationError + +from pypy.interpreter import typedef, gateway, baseobjspace +from pypy.interpreter.gateway import interp2app + +from pypy.objspace.std.listobject import W_ListObject, W_TupleObject +from pypy.objspace.std.intobject import W_IntObject + +from pypy.objspace.std.model import StdObjSpaceMultiMethod + +from pypy.module.cclp.types import W_AbstractDomain, W_Var, W_Root, ConsistencyError +from pypy.module.cclp.interp_var import interp_bind, interp_free + +all_mms = {} + + +class W_FiniteDomain(W_AbstractDomain): + """ + Variable Domain with a finite set of possible values + """ + + def __init__(self, space, w_values): + """values is a list of values in the domain + This class uses a dictionnary to make sure that there are + no duplicate values""" + W_AbstractDomain.__init__(self, space) + #XXX a pure dict used to work there (esp. in revise) + assert isinstance(w_values, W_ListObject) + self._values = space.newdict() + self.set_values(w_values) + + def copy(self): + return W_FiniteDomain(self._space, self.w_get_values()) + + def clear_change(self): + "create a fresh change synchonizer" + assert not interp_free(self._changed) + self._changed = W_Var(self._space) + + def give_synchronizer(self): + return self._changed + + + def contains(self, w_val): + sp = self._space + assert isinstance(w_val, W_Root) + return sp.is_true(sp.contains(self._values, w_val)) + __contains__ = contains + + def _value_removed(self): + "The implementation of remove_value should call this method" + #atomic + interp_bind(self._changed, self._space.w_True) + self.clear_change() + #/atomic + + if self.size() == 0: + raise ConsistencyError, "tried to make a domain empty" + + def set_values(self, w_values): + """XXX Objects in the value set can't be unwrapped unless we + specialize on specific types - this will need specialization + of revise & friends + """ + for w_v in w_values.wrappeditems: + self._space.setitem(self._values, w_v, self._space.w_True) + + def w_remove_value(self, w_value): + try: + self.remove_value(w_value) + except ConsistencyError: + raise OperationError(self._space.w_ConsistencyError, + self._space.wrap("tried to empty a domain")) + + def remove_value(self, w_value): + """Remove value of domain and check for consistency""" + assert isinstance(w_value, baseobjspace.W_Root) + del self._values.content[w_value] + self._value_removed() + + def w_remove_values(self, w_values): + """Remove values of domain and check for consistency""" + assert isinstance(w_values, W_ListObject) + try: + self.remove_values(w_values.wrappeditems) + except KeyError: + raise OperationError(self._space.w_RuntimeError, + self._space.wrap("attempt to remove unkown value from domain")) + + def remove_values(self, values): + assert isinstance(values, list) + if len(values) > 0: + for w_val in values: + del self._values.content[w_val] + self._value_removed() + + def w_size(self): + return self._space.newint(self.size()) + + def size(self): + """computes the size of a finite domain""" + l = self._space.len(self._values) + assert isinstance(l, W_IntObject) + return l.intval + __len__ = size + + def w_get_values(self): + """return all the values in the domain + in an indexable sequence""" + return self._space.newlist(self.get_values()) + + def get_values(self): + return [x for x in self._values.content.keys()] + + def __repr__(self): + return '' % str(self.w_get_values()) + + def __eq__(self, w_other): + if not isinstance(w_other, W_FiniteDomain): + return self._space.newbool(False) + return self._space.newbool(self._space.eq_w(self._values, w_other._values)) + + def __ne__(self, w_other): + if not isinstance(w_other, W_FiniteDomain): + return self._space.newbool(True) + if self._space.eq_w(self._values, w_other._values): + return self._space.newbool(False) + return self._space.newbool(True) + + + + +# function bolted into the space to serve as constructor +def make_fd(space, w_values): + assert isinstance(w_values, W_ListObject) + return W_FiniteDomain(space, w_values) +app_make_fd = gateway.interp2app(make_fd) + + +def intersection(space, w_fd1, w_fd2): + return space.intersection(w_fd1, w_fd2) +app_intersection = gateway.interp2app(intersection) + + +def intersection__FiniteDomain_FiniteDomain(space, w_fd1, w_fd2): + w_v1 = w_fd1._values.content + res = [w_v for w_v in w_fd2._values.content + if w_v in w_v1] + return make_fd(space, space.newlist(res)) + +intersection_mm = StdObjSpaceMultiMethod('intersection', 2) +intersection_mm.register(intersection__FiniteDomain_FiniteDomain, + W_FiniteDomain, W_FiniteDomain) +all_mms['intersection'] = intersection_mm + +W_FiniteDomain.typedef = typedef.TypeDef( + "W_FiniteDomain", + W_AbstractDomain.typedef, + remove_value = interp2app(W_FiniteDomain.w_remove_value), + remove_values = interp2app(W_FiniteDomain.w_remove_values), + get_values = interp2app(W_FiniteDomain.w_get_values), + __eq__ = interp2app(W_FiniteDomain.__eq__), + __ne__ = interp2app(W_FiniteDomain.__ne__), + size = interp2app(W_FiniteDomain.w_size)) + Added: pypy/dist/pypy/module/cclp/constraint/test/problem.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/cclp/constraint/test/problem.py Wed Feb 28 14:07:55 2007 @@ -0,0 +1,44 @@ + + +def conference_scheduling(): + + dom_values = [(room,slot) + for room in ('room A','room B','room C') + for slot in ('day 1 AM','day 1 PM','day 2 AM', + 'day 2 PM')] + + variables = {} + for v in ('c01','c02','c03','c04','c05', 'c06','c07','c08','c09','c10'): + variables[v] = domain(dom_values, v) + + for conf in ('c03','c04','c05','c06'): + v = variables[conf] + tell(make_expression([v], "%s[0] == 'room C'" % conf)) + + for conf in ('c01','c05','c10'): + v = variables[conf] + tell(make_expression([v], "%s[1].startswith('day 1')" % conf)) + + for conf in ('c02','c03','c04','c09'): + v = variables[conf] + tell(make_expression([v], "%s[1].startswith('day 2')" % conf)) + + groups = (('c01','c02','c03','c10'), + ('c02','c06','c08','c09'), + ('c03','c05','c06','c07'), + ('c01','c03','c07','c08')) + + for group in groups: + for conf1 in group: + for conf2 in group: + if conf2 > conf1: + v1, v2 = variables[conf1], variables[conf2] + tell(make_expression([v1, v2], '%s[1] != %s[1]'% (conf1, conf2))) + + + tell(all_diff(variables.values())) + + distribute('dichotomy') + + return variables.values() + Added: pypy/dist/pypy/module/cclp/constraint/test/test_btree.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/cclp/constraint/test/test_btree.py Wed Feb 28 14:07:55 2007 @@ -0,0 +1,17 @@ +class TestBTree(object): + + def test_everything_at_once(self): + from pypy.objspace.constraint.btree import BTree + b = BTree() + l = [(-1, 'egg'), (-7, 'spam'), (3, 'bacon'), + (99, 'ham'), (77, 'cheese'), (7, 'tomato'), + (5, 'chicken'), (9, 'noodles')] + for k, v in l: b.add(k, v) + assert 77 in b + assert 66 not in b + assert b.values() == ['spam', 'egg', 'bacon', 'chicken', + 'tomato', 'noodles', 'cheese', 'ham'] + assert b.keys() == [-7, -1, 3, 5, 7, 9, 77, 99] + assert b.items() == [(-7, 'spam'), (-1, 'egg'), (3, 'bacon'), + (5, 'chicken'), (7, 'tomato'), (9, 'noodles'), + (77, 'cheese'), (99, 'ham')] Added: pypy/dist/pypy/module/cclp/constraint/test/test_constraint.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/cclp/constraint/test/test_constraint.py Wed Feb 28 14:07:55 2007 @@ -0,0 +1,79 @@ +from pypy.conftest import gettestobjspace +from py.test import skip + +class AppTest_AllDistinct(object): + + def setup_class(cls): + cls.space = gettestobjspace('logic', usemodules=('_stackless', )) + + + def test_instantiate(self): + + def in_space(): + v1 = domain([1, 2], 'v1') + v2 = domain([1, 2], 'v2') + cstr = all_diff([v1, v2]) + variables = cstr.affected_variables() + assert variables is not None + assert len(variables) == 2 + + newspace(in_space) + + def test_revise(self): + def in_space(): + v1 = domain([1, 2], 'v1') + v2 = domain([1, 2], 'v2') + cstr = all_diff([v1, v2]) + assert name_of(v1) == 'v1' + assert name_of(v2) == 'v2' + raises(TypeError, name_of, 42) + assert cstr.revise() == False # not entailed + + v3 = domain([1], 'v3') + v4 = domain([2], 'v4') + cstr = all_diff([v3, v4]) + assert cstr.revise() == True # entailed + + v5 = domain([1], 'v5') + v6 = domain([1], 'v6') + cstr = all_diff([v5, v6]) + raises(Exception, cstr.revise) + + v7 = domain([1, 2], 'v7') + v8 = domain([1, 2], 'v8') + cstr = all_diff([v2, v7, v8]) + raises(Exception, cstr.revise) + + v9 = domain([1], 'v9') + v10= domain([1, 2], 'v10') + cstr = all_diff([v9, v10]) + assert cstr.revise() == True + assert domain_of(v10).get_values() == [2] + + newspace(in_space) + + +class AppTest_Expression(object): + + def setup_class(cls): + cls.space = gettestobjspace('logic', usemodules=('_stackless', )) + + def test_instantiate(self): + + def in_space(): + v1 = domain([1, 2], 'v1') + cstr = make_expression([v1], '2*v1==2') + assert str(cstr).startswith(' 0: + if w_inter_dom.__len__() == 1: + w_value = w_inter_dom.get_values()[0] + _assign_aliases(space, w_cvar1, w_value) + _assign_aliases(space, w_cvar2, w_value) + else: + w_cvar1.w_dom = w_cvar2.w_dom = w_inter_dom + _alias(space, w_cvar1, w_cvar2) + else: + raise_unification_failure(space, "incompatible domains") + +def bind__CVar_Var(space, w_cvar, w_var): + if space.is_true(space.is_bound(w_var)): + return bind__CVar_Root(space, w_cvar, w_var) + return bind__Var_Var(space, w_cvar, w_var) + + +bind_mm.register(bind__CVar_CVar, W_CVar, W_CVar) +bind_mm.register(bind__CVar_Root, W_CVar, W_Root) +bind_mm.register(bind__CVar_Var, W_CVar, W_Var) Added: pypy/dist/pypy/module/cclp/cspace.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/cclp/cspace.py Wed Feb 28 14:07:55 2007 @@ -0,0 +1,237 @@ +from pypy.rlib.objectmodel import we_are_translated +from pypy.interpreter import baseobjspace, gateway, argument, typedef +from pypy.interpreter.function import Function +from pypy.interpreter.pycode import PyCode + +from pypy.interpreter.error import OperationError + +from pypy.objspace.std.intobject import W_IntObject +from pypy.objspace.std.listobject import W_ListObject, W_TupleObject + +from pypy.module._stackless.interp_coroutine import AbstractThunk + +from pypy.module.cclp.misc import get_current_cspace, w +from pypy.module.cclp.thunk import CSpaceThunk, PropagatorThunk +from pypy.module.cclp.global_state import sched +from pypy.module.cclp.variable import newvar +from pypy.module.cclp.types import ConsistencyError, Solution, W_Var, \ + W_CVar, W_AbstractDomain, W_AbstractDistributor, SpaceCoroutine +from pypy.module.cclp.interp_var import interp_bind, interp_free +from pypy.module.cclp.constraint.distributor import distribute +from pypy.module.cclp.scheduler import W_ThreadGroupScheduler +from pypy.module._stackless.clonable import AppClonableCoroutine +from pypy.module._stackless.coroutine import AppCoroutine +from pypy.rlib.rgc import gc_clone + + + + +def newspace(space, w_callable, __args__): + "application level creation of a new computation space" + args = __args__.normalize() + dist_thread = SpaceCoroutine(space) + thunk = CSpaceThunk(space, w_callable, args, dist_thread) + dist_thread.bind(thunk) + dist_thread.hello_local_pool() + try: + w_space = W_CSpace(space, dist_thread) + finally: + dist_thread.goodbye_local_pool() + if not we_are_translated(): + w("NEWSPACE, (distributor) thread", + str(id(dist_thread)), "for", str(w_callable.name)) + return w_space +newspace.unwrap_spec=[baseobjspace.ObjSpace, + baseobjspace.W_Root, + argument.Arguments] + +def choose(space, w_n): + if not isinstance(w_n, W_IntObject): + raise OperationError(space.w_TypeError, + space.wrap('choose only accepts an integer.')) + n = space.int_w(w_n) + if n < 2: + raise OperationError(space.w_ValueError, + space.wrap("choose takes an int > 1")) + # XXX sanity check for 1 <= n <= last_choice + cspace = get_current_cspace(space) + if not isinstance(cspace, W_CSpace): + raise OperationError(space.w_TypeError, + space.wrap('choose does not work from within ' + 'the top-level computatoin space.')) + if not interp_free(cspace._finished): + raise OperationError(space.w_RuntimeError, + space.wrap("this space is finished")) + try: + return cspace.choose(n) + except ConsistencyError: + raise OperationError(space.w_ConsistencyError, + space.wrap("this space is failed")) +choose.unwrap_spec = [baseobjspace.ObjSpace, + baseobjspace.W_Root] + +from pypy.module.cclp.constraint import constraint + +def tell(space, w_constraint): + if not isinstance(w_constraint, constraint.W_AbstractConstraint): + raise OperationError(space.w_TypeError, + space.wrap('Tell only accepts object of ' + '(sub-)types Constraint.')) + get_current_cspace(space).tell(w_constraint) +tell.unwrap_spec = [baseobjspace.ObjSpace, + baseobjspace.W_Root] + + +class W_CSpace(W_ThreadGroupScheduler): + + def __init__(self, space, dist_thread): + W_ThreadGroupScheduler.__init__(self, space) + dist_thread._cspace = self + self._init_head(dist_thread) + self.main_thread = dist_thread + sched.uler.add_new_group(self) + self.distributor = None # dist instance != thread + # choice mgmt + self._choices = newvar(space) + self._committed = newvar(space) + # status, merging + self._solution = newvar(space) + self._failed = False + self._merged = False + self._finished = newvar(space) + # constraint store ... + self._store = {} # name -> var + +## def hello(self): +## self.main_thread.hello_local_pool() + +## def goodbye(self): +## self.main_thread.goodbye_local_pool() + + def register_var(self, cvar): + self._store[cvar.name] = cvar + + def w_clone(self): + cl_thread = self.main_thread._clone() + cl_thread._cspace.finalize_cloning( self, cl_thread ) + cl_thread._cspace.main_thread = cl_thread + sched.uler.add_new_group(cl_thread._cspace) + return self.space.wrap(cl_thread._cspace) + + def finalize_cloning(self, orig_cspace, cl_thread ): + # We need to walk all threads references from this cloned + # space and replace + # 1. our cloned thread get's a new thread ID + orig_tid = orig_cspace.main_thread.tid + sched.uler.register_thread( cl_thread ) + self.main_thread = cl_thread + # walk the thread ring buffer to replace the cloned threads + cl_thread._cspace._init_head( cl_thread ) # XXX enough for now with only one thread + self.replace_thread( orig_tid, cl_thread ) + + def report_bad_state_to_applevel(self): + if not interp_free(self._finished): + raise OperationError(self.space.w_RuntimeError, + self.space.wrap("space is finished")) + + def w_ask(self): + try: + self.report_bad_state_to_applevel() + except: # we're dead, let's avoid wait_stable ... + return self._choices + self.wait_stable() + self.space.wait(self._choices) + choices = self._choices.w_bound_to + self.main_thread.hello_local_pool() + self._choices = newvar(self.space) + self.main_thread.goodbye_local_pool() + assert isinstance(choices, W_IntObject) + self._last_choice = self.space.int_w(choices) + return choices + + def choose(self, n): + # solver probably asks + self.wait_stable() + if self._failed: #XXX set by any propagator while we were not looking + raise ConsistencyError + assert interp_free(self._choices) + assert interp_free(self._committed) + # XXX we wrap it a bit prematurely, so as to satisfy + # type requirements (logic variables do not support rpython types) + interp_bind(self._choices, self.space.wrap(n)) # unblock the solver + # now we wait on a solver commit + self.space.wait(self._committed) + committed = self._committed.w_bound_to + self._committed = newvar(self.space) + return committed + + def w_commit(self, w_n): + self.report_bad_state_to_applevel() + assert isinstance(w_n, W_IntObject) + n = w_n.intval + assert interp_free(self._committed) + if n < 1 or n > self._last_choice: + raise OperationError(self.space.w_ValueError, + self.space.wrap("need 0 thread set + self._asking[top_level_space] = {} # XXX + # variables suspension lists + self._tl_blocked = {} # set of spaces + self._tl_blocked_on = {} # var -> spaces + self._tl_blocked_byneed = {} # var -> spaces + self.next_tid = 1 # 0 is reserved for untracked threads + self.threads = {} # id->thread mapping + + def get_new_tid(self): + # XXX buggy if it overflows + tid = self.next_tid + self.next_tid += 1 + return tid + + def register_thread(self, thread): + if thread.tid==0: + thread.tid = self.get_new_tid() + self.threads[thread.tid] = thread +## else: +## assert thread.tid in self.threads, "Thread already registered" + + def _chain_insert(self, group): + assert isinstance(group, W_ThreadGroupScheduler), "type error" + assert isinstance(group._next, W_ThreadGroupScheduler), "type error" + assert isinstance(group._prev, W_ThreadGroupScheduler), "type error" + r = self._head + l = r._prev + l._next = group + r._prev = group + group._prev = l + group._next = r + + + def schedule(self): + running = self._head + to_be_run = self._select_next() + if not isinstance(to_be_run, W_ThreadGroupScheduler): + w("Aaarg something wrong in top level schedule") + assert False, "type error" + #w(".. SWITCHING (spaces)", str(id(get_current_cspace(self.space))), "=>", str(id(to_be_run))) + self._switch_count += 1 + if to_be_run != running: + running.goodbye() + to_be_run.hello() + to_be_run.schedule() + + def _select_next(self): + to_be_run = self._head + sentinel = to_be_run + while to_be_run.is_blocked(): + # check stability + asking status, give a chance to run + if to_be_run.is_runnable(): + break + to_be_run = to_be_run._next + assert isinstance(to_be_run, W_ThreadGroupScheduler), "type error" + if to_be_run == sentinel: + reset_scheduler(self.space) + w(".. SCHEDULER reinitialized") + raise OperationError(self.space.w_AllBlockedError, + self.space.wrap("can't schedule, probable deadlock in sight")) + self._head = to_be_run + return to_be_run + + + def add_new_group(self, group): + "insert 'group' at end of running queue" + assert isinstance(group, W_ThreadGroupScheduler), "type error" + w(".. ADDING group : %d" % id(group)) + self._asking[group] = {} + self._chain_insert(group) + + + def remove_group(self, group): + assert isinstance(group, W_ThreadGroupScheduler), "type error" + w(".. REMOVING group %d" % id(group) ) + l = group._prev + r = group._next + l._next = r + r._prev = l + self._head = r + if r == group: + # IS AN ERROR + if not we_are_translated(): + import traceback + traceback.print_exc() + raise OperationError(self.space.w_RuntimeError, + self.space.wrap("BUG in remove_group")) + group._next = group._prev = None + # unblock all threads asking stability of this group + for th in self._asking[group]: + del th._cspace._blocked[th] + th._cspace.blocked_count -= 1 + del self._asking[group] + + def add_to_blocked_on(self, w_var): + assert isinstance(w_var, W_Var), "type error" + thread = AppCoroutine.w_getcurrent(self.space) + get_current_cspace(self.space).add_to_blocked_on(w_var, thread) + + def unblock_on(self, w_var): + #XXX optimize me + curr = stop = self._head + while 1: + curr.unblock_on(w_var) + curr = curr._next + if curr == stop: + break + + #XXX sync the un/block byneed stuff with above, later + def add_to_blocked_byneed(self, w_var): + assert isinstance(w_var, W_Var), "type error" + thread = AppCoroutine.w_getcurrent(self.space) + get_current_cspace(self.space).add_to_blocked_byneed(w_var, thread) + + def unblock_byneed_on(self, w_var): + get_current_cspace(self.space).unblock_byneed(w_var) + + # delegated to thread group + def add_new_thread(self, thread): + tg = get_current_cspace(self.space) + tg.add_new_thread(thread) + + def remove_thread(self, thread): + tg = get_current_cspace(self.space) + tg.remove_thread(thread) + + def trace_vars(self, thread, lvars): + tg = get_current_cspace(self.space) + tg.trace_vars(thread, lvars) + + def dirty_traced_vars(self, thread, failed_value): + tg = get_current_cspace(self.space) + tg.dirty_traced_vars(thread, failed_value) + + def wait_stable(self): + tg = get_current_cspace(self.space) + tg.wait_stable() + + # statistics + def sched_info(self): + s = self.space + si = self.space.setitem + w_all = s.newdict() + si(w_all, s.newint(id(self._head)), self._head.group_info()) + assert isinstance(self._head, W_ThreadGroupScheduler), "type error" + curr = self._head._next + while curr != self._head: + assert isinstance(curr, W_ThreadGroupScheduler), "type error" + si(w_all, s.newint(id(curr)), curr.group_info()) + curr = curr._next + si(w_all, s.wrap('blocked'), self.w_blocked()) + si(w_all, s.wrap('blocked_on'), self.w_blocked_on()) + si(w_all, s.wrap('blocked_byneed'), self.w_blocked_byneed()) + return w_all + + def all_blocked(self): + curr = stop = self._head + blist = [] + while 1: + blist.extend(curr._blocked.keys()) + curr = curr._next + if curr == stop: + break + return blist + + def w_blocked(self): + s = self.space + + w_b = W_ListObject([s.newint(id(th)) + for th in self.all_blocked()]) + return w_b + + def all_blocked_on(self): + curr = stop = self._head + blist = [] + while 1: + blist.extend(curr._blocked_on.items()) + curr = curr._next + if curr == stop: + break + return blist + + def w_blocked_on(self): + s = self.space + si = s.setitem + w_bo = s.newdict() + for var, thl in self.all_blocked_on(): + w_l = W_ListObject([s.newint(id(th)) + for th in thl]) + si(w_bo, s.wrap(var.__repr__()), w_l) + return w_bo + + def all_blocked_byneed(self): + curr = stop = self._head + blist = [] + while 1: + blist.extend(curr._blocked_byneed.items()) + curr = curr._next + if curr == stop: + break + return blist + + def w_blocked_byneed(self): + s = self.space + si = s.setitem + w_bb = s.newdict() + for var, thl in self.all_blocked_byneed(): + w_l = W_ListObject([s.newint(id(th)) + for th in thl]) + si(w_bb, s.wrap(var.__repr__()), w_l) + return w_bb + + +#-- Thread Group scheduler -------------------------------------- + + +class W_ThreadGroupScheduler(baseobjspace.Wrappable): + + def __init__(self, space): + self.space = space + self._pool = None + self._switch_count = 0 + self._traced = {} # thread -> vars + self.thread_count = 1 + self.blocked_count = 0 + self._head = None + self._next = self + self._prev = self + # accounting for blocked stuff + self._blocked = {} # thread -> True + self._blocked_on = {} + self._blocked_byneed = {} + + def _init_head(self, thread): + "sets the initial ring head" + assert isinstance(thread, AppCoroutine), "type error" + self._head = thread + thread._next = thread._prev = thread + sched.uler.register_thread( thread ) + w("HEAD (main) THREAD = ", str(id(self._head))) + + + def replace_thread( self, orig_tid, cl_thread ): + # walk the list of _blocked threads: + for th in self._blocked: + if th.tid == orig_tid: + del self._blocked[th] + self._blocked[cl_thread] = True + + # walk the mappings var->threads + for w_var in self._blocked_on: + threads = self._blocked_on[w_var] + for k in range(len(threads)): + if threads[k].tid == orig_tid: + threads[k] = cl_thread + + for w_var in self._blocked_byneed: + threads = self._blocked_byneed[w_var] + for k in range(len(threads)): + if threads[k].tid == orig_tid: + threads[k] = cl_thread + + # handled traced thread + for th in self._traced.keys(): + if th.tid == orig_tid: + lvars = self._traced[th] + del self._traced[th] + self._traced[cl_thread] = lvars + + + def _chain_insert(self, thread): + assert isinstance(thread, AppCoroutine), "type error" + assert isinstance(thread._next, AppCoroutine), "type error" + assert isinstance(thread._prev, AppCoroutine), "type error" + r = self._head + l = r._prev + l._next = thread + r._prev = thread + thread._prev = l + thread._next = r + sched.uler.register_thread( thread ) + + def hello(self): + pass + + def goodbye(self): + pass + + def register_var(self, var): + space = self.space + raise OperationError(space.w_AssertionError, + space.wrap('You cannot create a constraint variable ' + 'in the top-level computation space.')) + + def is_blocked(self): + return self.thread_count == self.blocked_count + + def is_failed(self): + return False + + def is_stable(self): + # second approx. + return self.is_blocked() or self.is_failed() + + def is_runnable(self): + if not self.is_stable(): + return True + asking_from_within = [th for th in sched.uler._asking[self] + if th._cspace == self] + return len(asking_from_within) + + def wait_stable(self): + w("WAIT_STABLE on space %d from space %d" % (id(self), + id(get_current_cspace(self.space)))) + if self.is_stable(): + return + curr = AppCoroutine.w_getcurrent(self.space) + if not isinstance(curr, AppCoroutine): + w("current coro is not an AppCoroutine ???") + assert False, "type error" + asking = sched.uler._asking + if self in asking: + asking[self][curr] = True + else: + asking[self] = {curr:True} + curr._cspace._blocked[curr] = True #XXX semantics please ? + curr._cspace.blocked_count += 1 + w("About to reschedule") + sched.uler.schedule() + w("Resuming %d" % id(self) ) + + def schedule(self): + to_be_run = self._select_next() + if to_be_run == AppCoroutine.w_getcurrent(self.space): + return + assert isinstance(to_be_run, AppCoroutine), "type error" + #w(".. SWITCHING (treads)", str(id(AppCoroutine.w_getcurrent(self.space))), "=>", str(id(to_be_run))) + self._switch_count += 1 + to_be_run.w_switch() + + def _select_next(self): + to_be_run = self._head._next + sentinel = to_be_run + while to_be_run in self._blocked: + if self.is_stable() and to_be_run in sched.uler._asking[self]: + for th in sched.uler._asking[self]: + del th._cspace._blocked[th] + th._cspace.blocked_count -= 1 + sched.uler._asking[self] = {} + break + assert isinstance(to_be_run, AppCoroutine), "type error" + to_be_run = to_be_run._next + if to_be_run == sentinel: + if not we_are_translated(): + import pdb + pdb.set_trace() + self._head = to_be_run + return to_be_run + + def add_to_blocked_on(self, w_var, thread): + w(".. we BLOCK thread", str(id(thread)), "on var", w_var.__repr__()) + assert isinstance(thread, AppCoroutine), "type error" + assert thread not in self._blocked + if w_var in self._blocked_on: + blocked = self._blocked_on[w_var] + else: + blocked = [] + self._blocked_on[w_var] = blocked + blocked.append(thread) + self._blocked[thread] = True + # stability, accounting, etc + self._post_blocking(thread) + + def unblock_on(self, w_var): + assert isinstance(w_var, W_Var), "type error" + blocked = [] + if w_var in self._blocked_on: + blocked = self._blocked_on[w_var] + del self._blocked_on[w_var] + else: + return + w(".. we UNBLOCK threads dependants of var", w_var.__repr__(), + str([id(thr) for thr in blocked])) + for thr in blocked: + del self._blocked[thr] + thr._cspace.blocked_count -= 1 + + def add_to_blocked_byneed(self, w_var, thread): + assert isinstance(thread, AppCoroutine), "type error" + if w_var in self._blocked_byneed: + blocked = self._blocked_byneed[w_var] + else: + blocked = [] + self._blocked_byneed[w_var] = blocked + blocked.append(thread) + self._blocked[thread] = True + self._post_blocking(thread) + + def unblock_byneed(self, w_var): + assert isinstance(w_var, W_Var), "type error" + blocked = [] + for w_alias in aliases(self.space, w_var): + if w_alias in self._blocked_byneed: + blocked += self._blocked_byneed[w_alias] + del self._blocked_byneed[w_alias] + w_alias.needed = True + if not blocked: + return + w(".. we UNBLOCK BYNEED dependants of var", w_var.__repr__(), + str([id(thr) for thr in blocked])) + for thr in blocked: + del self._blocked[thr] + thr._cspace.blocked_count -= 1 + + def _post_blocking(self, thread): + # check that those asking for stability in the home space + # of the thread can be unblocked + home = thread._cspace + home.blocked_count += 1 + if home.is_stable(): + v('(post-blocking) may UNBLOCK asker: ') + for th in sched.uler._asking[home].keys(): + # these asking threads must be unblocked, in their + # respective home spaces + # was: del sched.uler._blocked[th] + v(' ', str(id(th))) + del th._cspace._blocked[th] + th._cspace.blocked_count -= 1 + w('') + sched.uler._asking[home] = {} + + + + def add_new_thread(self, thread): + "insert 'thread' at end of running queue" + w(".. ADDING thread %d to group %d" % ( id(thread), id(self))) + assert isinstance(thread, AppCoroutine), "type error" + self._chain_insert(thread) + self.thread_count += 1 + + def remove_thread(self, thread): + assert isinstance(thread, AppCoroutine) + w(".. REMOVING thread %d" % id(thread)) + assert thread not in thread._cspace._blocked + try: + del self._traced[thread] + except KeyError: + w(".. removing non-traced thread") + l = thread._prev + r = thread._next + l._next = r + r._prev = l + self._head = r + if r == thread: + # that means thread was the last one + # the group is about to die + pass + thread._next = thread._prev = None + self.thread_count -= 1 + if self.thread_count == 0: + sched.uler.remove_group(self) + + # Logic Variables tracing, "accelerates" exception propagation + # amongst threads + def trace_vars(self, thread, lvars): + assert isinstance(thread, AppCoroutine), "type error" + assert isinstance(lvars, list), "type error" + #w(".. TRACING logic vars.", str(lvars), "for", str(id(thread))) + #assert not self._traced.has_key(thread) doesn't translate + self._traced[thread] = lvars + + def dirty_traced_vars(self, thread, failed_value): + assert isinstance(thread, AppCoroutine) + assert isinstance(failed_value, W_FailedValue) + #w(".. DIRTYING traced vars") + for w_var in self._traced[thread]: + if self.space.is_true(self.space.is_free(w_var)): + self.space.bind(w_var, failed_value) + + def w_threads(self): + s = self.space + thl = [s.newint(id(self._head))] + assert isinstance(self._head, AppCoroutine) + curr = self._head._next + while curr != self._head: + assert isinstance(curr, AppCoroutine) + thl.append(s.newint(id(curr))) + curr = curr._next + w_t = W_ListObject(thl) + return w_t + + def w_asking(self): + asking = sched.uler._asking.get(self, None) + if not asking: + return self.space.w_None + return W_ListObject([self.space.newint(id(th)) + for th in asking.keys()]) + + def group_info(self): + s = self + si = self.space.setitem + sw = self.space.wrap + w_ret = self.space.newdict() + si(w_ret, sw('switches'), self.space.newint(s._switch_count)) + si(w_ret, sw('threads'), s.w_threads()) + si(w_ret, sw('asking'), s.w_asking()) + return w_ret + +#-- Misc -------------------------------------------------- +def reset_scheduler(space): + tg = W_ThreadGroupScheduler(space) + sched.uler = TopLevelScheduler(space, tg) + tg._init_head(sched.main_thread) +reset_scheduler.unwrap_spec = [baseobjspace.ObjSpace] + +def sched_info(space): + return sched.uler.sched_info() +sched_info.unwrap_spec = [baseobjspace.ObjSpace] + +def schedule(space): + "useful til we get preemtive scheduling deep into the vm" + sched.uler.schedule() +schedule.unwrap_spec = [baseobjspace.ObjSpace] Added: pypy/dist/pypy/module/cclp/thread.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/cclp/thread.py Wed Feb 28 14:07:55 2007 @@ -0,0 +1,51 @@ +from pypy.interpreter import gateway, baseobjspace, argument +from pypy.rlib.objectmodel import we_are_translated + +from pypy.module.cclp.types import W_Var, W_Future, W_FailedValue +from pypy.module.cclp.misc import w, v, AppCoroutine, get_current_cspace +from pypy.module.cclp.thunk import FutureThunk, ProcedureThunk +from pypy.module.cclp.global_state import sched + + +#-- Future -------------------------------------------------- + +def future(space, w_callable, __args__): + """returns a future result""" + #XXX we could be much more lazy wrt coro creation + args = __args__.normalize() + coro = AppCoroutine(space) + coro._next = coro._prev = coro + w_Future = W_Future(space) + thunk = FutureThunk(space, w_callable, args, w_Future, coro) + coro.bind(thunk) + coro._cspace = get_current_cspace(space) + if not we_are_translated(): + w("FUTURE", str(id(coro)), "for", str(w_callable.name)) + sched.uler.add_new_thread(coro) + return w_Future +future.unwrap_spec= [baseobjspace.ObjSpace, + baseobjspace.W_Root, + argument.Arguments] + +#-- plain Coroutine ----------------------------------------- + +def stacklet(space, w_callable, __args__): + """returns a coroutine object""" + args = __args__.normalize() + coro = AppCoroutine(space) + coro._next = coro._prev = coro + thunk = ProcedureThunk(space, w_callable, args, coro) + coro.bind(thunk) + coro._cspace = get_current_cspace(space) + if not we_are_translated(): + w("STACKLET", str(id(coro)), "for", str(w_callable.name)) + sched.uler.add_new_thread(coro) + sched.uler.schedule() + return coro +stacklet.unwrap_spec=[baseobjspace.ObjSpace, + baseobjspace.W_Root, + argument.Arguments] + +def this_thread(space): + return AppCoroutine.w_getcurrent(space) +this_thread.unwrap_spec = [baseobjspace.ObjSpace] Added: pypy/dist/pypy/module/cclp/thunk.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/cclp/thunk.py Wed Feb 28 14:07:55 2007 @@ -0,0 +1,167 @@ +from pypy.module._stackless.coroutine import _AppThunk, AppCoroutine +from pypy.module._stackless.interp_coroutine import AbstractThunk + +from pypy.module.cclp.misc import w +from pypy.module.cclp.global_state import sched +from pypy.module.cclp.types import W_Var, W_CVar, W_Future, W_FailedValue, \ + ConsistencyError, Solution, W_AbstractDomain, SpaceCoroutine +from pypy.module.cclp.interp_var import interp_wait, interp_entail, \ + interp_bind, interp_free, interp_wait_or + +from pypy.objspace.std.listobject import W_ListObject +from pypy.objspace.std.listobject import W_TupleObject +from pypy.rlib.objectmodel import we_are_translated + +def logic_args(args): + "returns logic vars found in unpacked normalized args" + assert isinstance(args, tuple) + pos = args[0] or [] # pos is not an empty tuple but None + kwa = args[1] + pos_l = [arg for arg in pos + if isinstance(arg, W_Var)] + kwa_l = [arg for arg in kwa.keys() + if isinstance(arg, W_Var)] + return pos_l + kwa_l + +#-- Thunk ----------------------------------------- + + +class ProcedureThunk(_AppThunk): + "used by thread.stacklet" + def __init__(self, space, w_callable, args, coro): + _AppThunk.__init__(self, space, coro.costate, w_callable, args) + self._coro = coro + + def call(self): + w(".! initial (returnless) thunk CALL in", str(id(self._coro))) + sched.uler.trace_vars(self._coro, logic_args(self.args.unpack())) + try: + try: + _AppThunk.call(self) + except Exception, exc: + w(".! exceptional EXIT of procedure", str(id(self._coro)), "with", str(exc)) + sched.uler.dirty_traced_vars(self._coro, W_FailedValue(exc)) + else: + w(".! clean EXIT of procedure", str(id(self._coro))) + finally: + sched.uler.remove_thread(self._coro) + sched.uler.schedule() + + +class FutureThunk(_AppThunk): + def __init__(self, space, w_callable, args, w_Result, coro): + _AppThunk.__init__(self, space, coro.costate, w_callable, args) + self.w_Result = w_Result + self._coro = coro + + def call(self): + w(".! initial thunk CALL in", str(id(self._coro))) + sched.uler.trace_vars(self._coro, logic_args(self.args.unpack())) + try: + try: + _AppThunk.call(self) + except Exception, exc: + w(".! exceptional EXIT of future", str(id(self._coro)), "with", str(exc)) + failed_val = W_FailedValue(exc) + self.space.bind(self.w_Result, failed_val) + sched.uler.dirty_traced_vars(self._coro, failed_val) + else: + w(".! clean EXIT of future", str(id(self._coro)), + "-- setting future result", str(self.w_Result), "to", + str(self.costate.w_tempval)) + self.space.unify(self.w_Result, self.costate.w_tempval) + finally: + sched.uler.remove_thread(self._coro) + sched.uler.schedule() + +class CSpaceThunk(_AppThunk): + "for a constraint script/logic program" + def __init__(self, space, w_callable, args, coro): + _AppThunk.__init__(self, space, coro.costate, w_callable, args) + #self._coro = coro + + def call(self): + space = self.space + coro = AppCoroutine.w_getcurrent(space) + assert isinstance(coro, SpaceCoroutine) + cspace = coro._cspace + w("-- initial DISTRIBUTOR thunk CALL in", str(id(coro))) + sched.uler.trace_vars(coro, logic_args(self.args.unpack())) + try: + try: + try: + _AppThunk.call(self) + finally: + coro = AppCoroutine.w_getcurrent(space) + assert isinstance(coro, SpaceCoroutine) + cspace = coro._cspace + except ConsistencyError, exc: + w("-- EXIT of DISTRIBUTOR, space is FAILED", str(id(coro)), "with", str(exc)) + failed_value = W_FailedValue(exc) + interp_bind(cspace._solution, failed_value) + except Exception, exc: + # maybe app_level let something buble up ... + w("-- exceptional EXIT of DISTRIBUTOR", str(id(coro)), "with", str(exc)) + failed_value = W_FailedValue(exc) + sched.uler.dirty_traced_vars(coro, failed_value) + interp_bind(cspace._solution, failed_value) + cspace.fail() + else: + w("-- clean EXIT of DISTRIBUTOR (success)", str(id(coro))) + sol = cspace._solution + assert isinstance(sol, W_Var) + if interp_free(sol): # returning from a constraint/logic script + interp_bind(sol, self.costate.w_tempval) + outcome = sol.w_bound_to + if not (isinstance(outcome, W_ListObject) or \ + isinstance(outcome, W_TupleObject)): + w("WARNING: return value type of the script was not a list or tuple, we fail the space.") + cspace.fail() + return + assert interp_free(cspace._choices) + interp_bind(cspace._choices, space.wrap(1)) + finally: + interp_bind(cspace._finished, self.space.w_True) + sched.uler.remove_thread(coro) + sched.uler.schedule() + + +class PropagatorThunk(AbstractThunk): + def __init__(self, space, w_constraint, coro): + self.space = space + self.coro = coro # XXX remove me + self.const = w_constraint + + def call(self): + #coro = AppCoroutine.w_getcurrent(self.space) + try: + cspace = self.coro._cspace + try: + while 1: + entailed = self.const.revise() + if entailed: + break + # we will block on domains being pruned + wait_list = [] + _vars = self.const._variables + assert isinstance(_vars, list) + for var in _vars: + assert isinstance(var, W_CVar) + dom = var.w_dom + assert isinstance(dom, W_AbstractDomain) + wait_list.append(dom.give_synchronizer()) + #or the cspace being dead + wait_list.append(cspace._finished) + interp_wait_or(self.space, wait_list) + if not interp_free(cspace._finished): + break + except ConsistencyError: + cspace.fail() + except Exception: # rpython doesn't like just except:\n ... + if not we_are_translated(): + import traceback + traceback.print_exc() + finally: + sched.uler.remove_thread(self.coro) + sched.uler.schedule() + Added: pypy/dist/pypy/module/cclp/types.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/cclp/types.py Wed Feb 28 14:07:55 2007 @@ -0,0 +1,199 @@ +from pypy.interpreter import baseobjspace, gateway, typedef +from pypy.interpreter.error import OperationError +from pypy.module._stackless.clonable import AppClonableCoroutine + +from pypy.module.cclp.misc import w, AppCoroutine, get_current_cspace +from pypy.module.cclp.global_state import sched + +from pypy.rlib.rgc import gc_swap_pool, gc_clone +from pypy.rlib.objectmodel import we_are_translated + +W_Root = baseobjspace.W_Root + +#-- Variables types ---------------------------------------- + +class W_Var(W_Root): + def __init__(w_self, space): + # ring of aliases or bound value + w_self.w_bound_to = w_self + w_self.entails = {} + # byneed flag + w_self.needed = False + + def __repr__(w_self): + if isinstance(w_self.w_bound_to, W_Var): + return '' % id(w_self) + return '<%s@%x>' % (w_self.w_bound_to, + id(w_self)) + + def _same_as(w_self, w_var): + assert isinstance(w_var, W_Var) + return w_self is w_var + __str__ = __repr__ + + +class W_Future(W_Var): + "a read-only-by-its-consummer variant of logic. var" + def __init__(w_self, space): + W_Var.__init__(w_self, space) + w_self._client = AppCoroutine.w_getcurrent(space) + w("FUT", str(w_self)) + + +class W_CVar(W_Var): + def __init__(self, space, w_dom, w_name): + assert isinstance(w_dom, W_AbstractDomain) + W_Var.__init__(self, space) + self.w_dom = w_dom + self.name = space.str_w(w_name) + self.w_nam = w_name + get_current_cspace(space).register_var(self) + + def copy(self, space): + return W_CVar(space, self.w_dom.copy(), self.w_nam) + + def name_w(self): + return self.name + + def w_name(self): + return self.w_nam + +def domain_of(space, w_v): + if not isinstance(w_v, W_CVar): + raise OperationError(space.w_TypeError, + space.wrap("domain_of takes a constraint variable")) + return w_v.w_dom +app_domain_of = gateway.interp2app(domain_of) + +def name_of(space, w_v): + if not isinstance(w_v, W_CVar): + raise OperationError(space.w_TypeError, + space.wrap("name_of takes a constraint variable")) + return w_v.w_name() +app_name_of = gateway.interp2app(name_of) + +#-- Exception types ---------------------------------------- + +class W_FailedValue(W_Root): + """wraps an exception raised in some coro, to be re-raised in + some dependant coro sometime later + """ + def __init__(w_self, exc): + w_self.exc = exc + +class ConsistencyError(Exception): pass + +class Solution(Exception): pass + +#-- Constraint --------------------------------------------- + +class W_Constraint(baseobjspace.Wrappable): + def __init__(self, object_space): + self._space = object_space + +W_Constraint.typedef = typedef.TypeDef("W_Constraint") + +class W_AbstractDomain(baseobjspace.Wrappable): + """Implements the functionnality related to the changed flag. + Can be used as a starting point for concrete domains""" + + def __init__(self, space): + self._space = space + self._changed = W_Var(self._space) + + def give_synchronizer(self): + pass + + def get_values(self): + pass + + def remove_values(self, values): + assert isinstance(values, list) + + def size(self): + pass + +W_AbstractDomain.typedef = typedef.TypeDef("W_AbstractDomain") + +class W_AbstractDistributor(baseobjspace.Wrappable): + + def __init__(self, space, fanout): + assert isinstance(fanout, int) + self._space = space + self._fanout = fanout + self._cspace = get_current_cspace(space) + +W_AbstractDistributor.typedef = typedef.TypeDef("W_AbstractDistributor") + +#-- Space Coroutine ---------------------- + + +class SpaceCoroutine(AppClonableCoroutine): + def __init__(self, space, state=None): + AppClonableCoroutine.__init__(self, space, state) + self._cspace = None + self._next = self._prev = None + + def _clone(self): + if not we_are_translated(): + raise NotImplementedError + + space = self.space + costate = self.costate + if costate.current is self: + raise OperationError(space.w_RuntimeError, + space.wrap("clone() cannot clone the " + "current coroutine" + "; use fork() instead")) + copy = SpaceCoroutine(space, state=costate) + + # This part is a copy of InterpClonableMixin.clone_into + # we can't use it because extradata as a different signature + # see the comments there for explanations + # ---------------------------------------------------------- + copy.parent = self.parent + self.hello_local_pool() + data = (self.frame, self.subctx, self._cspace) + self.goodbye_local_pool() + # clone! + data, copy.local_pool = gc_clone(data, self.local_pool) + copy.frame, copy.subctx, copy._cspace = data + return copy + + #XXX idea for future : + # only call AppCoroutine.hello() there + # do main_thread.hello|goodbye_local_pool when switching spaces + # we will need to clone the other coros stackframes and + # restuff these into fresh AppCoroutine shells + # (because AppCoros have finalizers, hence are not cloned) + def hello(self): + w('Hello coro %d' % id(self) ) + AppClonableCoroutine.hello(self) + + def goodbye(self): + w('Bye coro %d' % id(self)) + AppClonableCoroutine.goodbye(self) + + +#-- Misc --------------------------------------------------- + +def deref(space, w_var): + "gets the value/next alias of a variable" + assert isinstance(w_var, W_Var) + return w_var.w_bound_to + +def aliases(space, w_var): + """return the aliases of a var, including itself""" + assert isinstance(w_var, W_Var) + assert isinstance(w_var.w_bound_to, W_Var) + al = [] + w_curr = w_var + while 1: + w_next = w_curr.w_bound_to + assert isinstance(w_next, W_Var) + al.append(w_curr) + if space.is_true(space.is_nb_(w_next, w_var)): + break + w_curr = w_next + return al + Added: pypy/dist/pypy/module/cclp/variable.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/cclp/variable.py Wed Feb 28 14:07:55 2007 @@ -0,0 +1,423 @@ +from pypy.interpreter import gateway, baseobjspace +from pypy.interpreter.error import OperationError +from pypy.objspace.std.model import StdObjSpaceMultiMethod +from pypy.objspace.std.listobject import W_ListObject, W_TupleObject +from pypy.objspace.std.dictobject import W_DictObject +from pypy.objspace.std.stringobject import W_StringObject + +from pypy.module.cclp.misc import w, v, AppCoroutine +from pypy.module.cclp.global_state import sched +from pypy.module.cclp.types import deref, W_Var, W_CVar, W_Future, W_FailedValue + +from pypy.rlib.objectmodel import we_are_translated + +W_Root = baseobjspace.W_Root +all_mms = {} + +def newvar(space): + w_v = W_Var(space) + w("VAR", w_v.__repr__()) + return w_v +app_newvar = gateway.interp2app(newvar) + + +#-- Wait ------------------------------------------------- + +def wait__Root(space, w_obj): + return w_obj + +def wait__Var(space, w_var): + #w("###:wait", str(id(AppCoroutine.w_getcurrent(space)))) + if space.is_true(space.is_free(w_var)): + sched.uler.unblock_byneed_on(w_var) + sched.uler.add_to_blocked_on(w_var) + sched.uler.schedule() + assert space.is_true(space.is_bound(w_var)) + w_ret = w_var.w_bound_to + if isinstance(w_ret, W_FailedValue): + w(".. reraising Failed Value") + raise w_ret.exc + return w_ret + +def wait(space, w_obj): + if not we_are_translated(): + assert isinstance(w_obj, W_Root) + return space.wait(w_obj) +app_wait = gateway.interp2app(wait) + +wait_mm = StdObjSpaceMultiMethod('wait', 1) +wait_mm.register(wait__Var, W_Var) +wait_mm.register(wait__Root, W_Root) +all_mms['wait'] = wait_mm + +#-- Wait_needed -------------------------------------------- + +def wait_needed__Var(space, w_var): + #w(":wait_needed", str(id(AppCoroutine.w_getcurrent(space)))) + if space.is_true(space.is_free(w_var)): + if w_var.needed: + return + sched.uler.add_to_blocked_byneed(w_var) + sched.uler.schedule() + else: + raise OperationError(space.w_TypeError, + space.wrap("wait_needed only supported on unbound variables")) + +def wait_needed(space, w_var): + assert isinstance(w_var, W_Var) + return space.wait_needed(w_var) +app_wait_needed = gateway.interp2app(wait_needed) + + +wait_needed_mm = StdObjSpaceMultiMethod('wait_needed', 1) +wait_needed_mm.register(wait_needed__Var, W_Var) +all_mms['wait_needed'] = wait_needed_mm + + +#-- PREDICATES (is_bound, is_free, is_aliased, alias_of) --------- + +def is_aliased(space, w_var): # XXX: this appear(ed) to block (long ago) + assert isinstance(w_var, W_Var) + if space.is_true(space.is_nb_(deref(space, w_var), w_var)): + return space.newbool(False) + return space.newbool(True) +app_is_aliased = gateway.interp2app(is_aliased) + +def is_free(space, w_obj): + assert isinstance(w_obj, W_Root) + return space.is_free(w_obj) +app_is_free = gateway.interp2app(is_free) + +def is_free__Root(space, w_obj): + return space.newbool(False) + +def is_free__Var(space, w_var): + return space.newbool(isinstance(w_var.w_bound_to, W_Var)) + +is_free_mm = StdObjSpaceMultiMethod('is_free', 1) +is_free_mm.register(is_free__Root, W_Root) +is_free_mm.register(is_free__Var, W_Var) +all_mms['is_free'] = is_free_mm + +def is_bound(space, w_obj): + assert isinstance(w_obj, W_Root) + return space.is_bound(w_obj) +app_is_bound = gateway.interp2app(is_bound) + +def is_bound__Root(space, w_obj): + return space.newbool(True) + +def is_bound__Var(space, w_var): + return space.newbool(not isinstance(w_var.w_bound_to, W_Var)) + +is_bound_mm = StdObjSpaceMultiMethod('is_bound', 1) +is_bound_mm.register(is_bound__Root, W_Root) +is_bound_mm.register(is_bound__Var, W_Var) +all_mms['is_bound'] = is_bound_mm + + +def alias_of(space, w_var1, w_var2): + assert isinstance(w_var1, W_Var) + assert isinstance(w_var2, W_Var) + if not (space.is_true(space.is_free(w_var1)) and \ + space.is_true(space.is_free(w_var2))): + raise OperationError(space.w_LogicError, + space.wrap("don't call alias_of on bound variables")) + w_curr = w_var1 + while 1: + w_next = w_curr.w_bound_to + assert isinstance(w_next, W_Var) + if w_next is w_var2: + return space.newbool(True) + if w_next is w_var1: + break + w_curr = w_next + return space.newbool(False) +app_alias_of = gateway.interp2app(alias_of) + +#-- HELPERS ---------------------- + +def get_ring_tail(space, w_start): + "returns the last var of a ring of aliases" + assert isinstance(w_start, W_Var) + w_curr = w_start + while 1: + w_next = w_curr.w_bound_to + assert isinstance(w_next, W_Var) + if space.is_true(space.is_nb_(w_next, w_start)): + return w_curr + w_curr = w_next + + +def raise_unification_failure(space, comment="Unification failure"): + """raises a specific exception for bind/unify + should fail the current comp. space at some point""" + raise OperationError(space.w_UnificationError, + space.wrap(comment)) + +# to signal a future binding exception +def raise_future_binding(space): + raise OperationError(space.w_FutureBindingError, + space.wrap("This future is read-only for you, pal")) + + +#-- BIND, ENTAIL---------------------------- + +def bind(space, w_var, w_obj): + """1. aliasing of unbound variables + 2. assign bound var to unbound var + 3. assign value to unbound var + """ + v(" :bind") + assert isinstance(w_var, W_Var) + assert isinstance(w_obj, W_Root) + space.bind(w_var, w_obj) +app_bind = gateway.interp2app(bind) + +def entail(space, w_v1, w_v2): + "X -> Y" + assert isinstance(w_v1, W_Var) + assert isinstance(w_v2, W_Var) + space.entail(w_v1, w_v2) +app_entail = gateway.interp2app(entail) + + +def bind__Var_Root(space, w_var, w_obj): + #w("var val", str(id(w_var))) + # 3. var and value + if space.is_true(space.is_free(w_var)): + return _assign_aliases(space, w_var, w_obj) + if space.is_true(space.eq(w_var.w_bound_to, w_obj)): + return + raise OperationError(space.w_RebindingError, + space.wrap("Cannot bind twice but two identical values")) + +def bind__Future_Root(space, w_fut, w_obj): + #v("future val", str(id(w_fut))) + if w_fut._client == AppCoroutine.w_getcurrent(space): + raise_future_binding(space) + return bind__Var_Root(space, w_fut, w_obj) # call-next-method ? + +def bind__Var_Var(space, w_v1, w_v2): + #w("var var") + if space.is_true(space.is_bound(w_v1)): + if space.is_true(space.is_bound(w_v2)): + # we allow re-binding to same value, see 3. + return unify(space, + deref(space, w_v1), + deref(space, w_v2)) + # 2. a (obj unbound, var bound) + return _assign_aliases(space, w_v2, deref(space, w_v1)) + elif space.is_true(space.is_bound(w_v2)): + # 2. b (var unbound, obj bound) + return _assign_aliases(space, w_v1, deref(space, w_v2)) + else: # 1. both are unbound + return _alias(space, w_v1, w_v2) + +def bind__Future_Var(space, w_fut, w_var): + #v("future var") + if w_fut._client == AppCoroutine.w_getcurrent(space): + raise_future_binding(space) + return bind__Var_Var(space, w_fut, w_var) + + +def bind__Var_Future(space, w_var, w_fut): + if space.is_true(space.is_bound(w_fut)): #XXX write a test for me ! + return bind__Var_Root(space, w_var, deref(space, w_fut)) + if w_fut._client == AppCoroutine.w_getcurrent(space): + raise_future_binding(space) + return bind__Var_Var(space, w_var, w_fut) #and for me ... + + +bind_mm = StdObjSpaceMultiMethod('bind', 2) +bind_mm.register(bind__Var_Root, W_Var, W_Root) +bind_mm.register(bind__Var_Var, W_Var, W_Var) +bind_mm.register(bind__Future_Root, W_Future, W_Root) +bind_mm.register(bind__Future_Var, W_Future, W_Var) +bind_mm.register(bind__Var_Future, W_Var, W_Future) +all_mms['bind'] = bind_mm + + +def entail__Var_Var(space, w_v1, w_v2): + #w(" :entail Var Var") + if space.is_true(space.is_bound(w_v1)): + if space.is_true(space.is_bound(w_v2)): + return unify(space, + deref(space, w_v1), + deref(space, w_v2)) + return _assign_aliases(space, w_v2, deref(space, w_v1)) + else: + return _entail(space, w_v1, w_v2) + +entail_mm = StdObjSpaceMultiMethod('entail', 2) +entail_mm.register(entail__Var_Var, W_Var, W_Var) +all_mms['entail'] = entail_mm + +def _entail(space, w_v1, w_v2): + assert isinstance(w_v1, W_Var) + assert isinstance(w_v2, W_Var) + w_v1.entails[w_v2] = True + return space.w_None + +def _assign_aliases(space, w_var, w_val): + #w(" :assign") + assert isinstance(w_var, W_Var) + #assert isinstance(w_val, W_Root) + w_curr = w_var + while 1: + w_next = w_curr.w_bound_to + assert isinstance(w_next, W_Var) + _assign(space, w_curr, w_val) + # notify the blocked threads + sched.uler.unblock_on(w_curr) + if space.is_true(space.is_nb_(w_next, w_var)): + break + # switch to next + w_curr = w_next + _assign_entailed(space, w_var, w_val) + #w(" :assigned") + return space.w_None + +def _assign_entailed(space, w_var, w_val): + #w(" :assign entailed") + for var in w_var.entails: + if space.is_true(space.is_free(var)): + _assign_aliases(space, var, w_val) + else: + unify(space, deref(space, var), w_val) + +def _assign(space, w_var, w_val): + assert isinstance(w_var, W_Var) + if isinstance(w_var, W_CVar): + if not w_val in w_var.w_dom._values.content: + raise_unification_failure(space, "assignment out of domain") + w_var.w_bound_to = w_val + + +def _alias(space, w_v1, w_v2): + """appends one var to the alias chain of another + user must ensure freeness of both vars""" + assert isinstance(w_v1, W_Var) + assert isinstance(w_v2, W_Var) + #w(" :alias", str(id(w_v1)), str(id(w_v2))) + if space.is_true(space.is_nb_(w_v1, w_v2)): + return space.w_None + if space.is_true(is_aliased(space, w_v1)): + if space.is_true(is_aliased(space, w_v2)): + return _merge_aliases(space, w_v1, w_v2) + return _add_to_aliases(space, w_v1, w_v2) + if space.is_true(is_aliased(space, w_v2)): + return _add_to_aliases(space, w_v2, w_v1) + # we have two unaliased vars + w_v1.w_bound_to = w_v2 + w_v2.w_bound_to = w_v1 + return space.w_None + +def _add_to_aliases(space, w_v1, w_v2): + assert isinstance(w_v1, W_Var) + assert isinstance(w_v2, W_Var) + #w(" :add to aliases") + w_tail = w_v1.w_bound_to + w_v1.w_bound_to = w_v2 + w_v2.w_bound_to = w_tail + return space.w_None + +def _merge_aliases(space, w_v1, w_v2): + assert isinstance(w_v1, W_Var) + assert isinstance(w_v2, W_Var) + #w(" :merge aliases") + w_tail1 = get_ring_tail(space, w_v1) + w_tail2 = get_ring_tail(space, w_v2) + w_tail1.w_bound_to = w_v2 + w_tail2.w_bound_to = w_v1 + return space.w_None + +#-- UNIFY ------------------------- + +def unify(space, w_x, w_y): + assert isinstance(w_x, W_Root) + assert isinstance(w_y, W_Root) + #w(":unify ", str(id(w_x)), str(id(w_y))) + return space.unify(w_x, w_y) +app_unify = gateway.interp2app(unify) + +def unify__Root_Root(space, w_x, w_y): + if not space.eq_w(w_x, w_y): + w_d1 = w_x.getdict() #returns wrapped dict or unwrapped None ... + w_d2 = w_y.getdict() + if None in [w_d1, w_d2]: + raise_unification_failure(space, str(w_x) + " != " + str(w_y)) + else: + return unify__Dict_Dict(space, w_d1, w_d2) + return space.w_None + +def unify__Var_Var(space, w_x, w_y): + #w(":unify var var", str(id(w_x)), str(id(w_y))) + if space.is_true(space.is_bound(w_x)): + if space.is_true(space.is_bound(w_y)): + return space.unify(deref(space, w_x), + deref(space, w_y)) + return space.bind(w_y, w_x) + # binding or aliasing x & y + else: + return space.bind(w_x, w_y) + +def unify__Var_Root(space, w_x, w_y): + #w(" :unify var val", str(id(w_x)), str(w_y)) + if space.is_true(space.is_bound(w_x)): + return space.unify(deref(space, w_x), w_y) + return space.bind(w_x, w_y) + +def unify__Root_Var(space, w_x, w_y): + return space.unify(w_y, w_x) + +def unify__Tuple_Tuple(space, w_i1, w_i2): + if len(w_i1.wrappeditems) != len(w_i2.wrappeditems): + raise_unification_failure(space, "tuples of different lengths.") + idx, top = (-1, space.int_w(space.len(w_i1))-1) + while idx < top: + idx += 1 + w_xi = space.getitem(w_i1, space.newint(idx)) + w_yi = space.getitem(w_i2, space.newint(idx)) + if space.is_true(space.is_nb_(w_xi, w_yi)): + continue + unify(space, w_xi, w_yi) + return space.w_None + +def unify__List_List(space, w_i1, w_i2): + if len(w_i1.wrappeditems) != len(w_i2.wrappeditems): + raise_unification_failure(space, "lists of different lengths.") + idx, top = (-1, space.int_w(space.len(w_i1))-1) + while idx < top: + idx += 1 + w_xi = space.getitem(w_i1, space.newint(idx)) + w_yi = space.getitem(w_i2, space.newint(idx)) + if space.is_true(space.is_nb_(w_xi, w_yi)): + continue + unify(space, w_xi, w_yi) + return space.w_None + + +def unify__Dict_Dict(space, w_m1, w_m2): + assert isinstance(w_m1, W_DictObject) + assert isinstance(w_m2, W_DictObject) + #print " :unify mappings", w_m1, w_m2 + for w_xk in w_m1.content.keys(): + w_xi = space.getitem(w_m1, w_xk) + w_yi = space.getitem(w_m2, w_xk) + if space.is_true(space.is_nb_(w_xi, w_yi)): + continue + space.unify(w_xi, w_yi) + return space.w_None + + +unify_mm = StdObjSpaceMultiMethod('unify', 2) +unify_mm.register(unify__Root_Root, W_Root, W_Root) +unify_mm.register(unify__Var_Var, W_Var, W_Var) +unify_mm.register(unify__Var_Root, W_Var, W_Root) +unify_mm.register(unify__Root_Var, W_Root, W_Var) +unify_mm.register(unify__Tuple_Tuple, W_TupleObject, W_TupleObject) +unify_mm.register(unify__List_List, W_ListObject, W_ListObject) +unify_mm.register(unify__Dict_Dict, W_DictObject, W_DictObject) + +all_mms['unify'] = unify_mm Modified: pypy/dist/pypy/objspace/logic.py ============================================================================== --- pypy/dist/pypy/objspace/logic.py (original) +++ pypy/dist/pypy/objspace/logic.py Wed Feb 28 14:07:55 2007 @@ -10,48 +10,41 @@ #-- MISC ---------------------------------------------------- -from pypy.objspace.cclp.misc import app_interp_id, app_switch_debug_info, app_is_interpreted, w +from pypy.module.cclp.misc import app_interp_id #-- THREADING/COROUTINING ----------------------------------- -from pypy.objspace.cclp.thread import app_future, app_stacklet, app_this_thread - -from pypy.objspace.cclp.scheduler import TopLevelScheduler, app_sched_info, \ - app_schedule, app_reset_scheduler - -from pypy.objspace.cclp.global_state import sched +from pypy.module.cclp.scheduler import TopLevelScheduler +from pypy.module.cclp.global_state import sched #-- COMP. SPACE -------------------------------------------- -from pypy.objspace.cclp.space import app_newspace, app_choose, W_ThreadGroupScheduler, \ - W_CSpace, app_tell +from pypy.module.cclp.cspace import W_ThreadGroupScheduler, W_CSpace #-- VARIABLE ------------------------------------------------ -from pypy.objspace.cclp.variable import app_newvar, wait, app_wait, app_wait_needed, \ +from pypy.module.cclp.variable import app_newvar, wait, app_wait, app_wait_needed, \ app_is_aliased, app_is_free, app_is_bound, app_alias_of, alias_of, app_bind, \ app_unify, W_Var, W_CVar, W_Future, all_mms as variable_mms, app_entail -from pypy.objspace.cclp.constraint.variable import app_domain +from pypy.module.cclp.constraint.variable import app_domain -from pypy.objspace.cclp.types import app_domain_of, app_name_of, AppCoroutine +from pypy.module.cclp.types import app_domain_of, app_name_of, AppCoroutine all_mms.update(variable_mms) #-- CONSTRAINTS ---------------------------------------------- ## #------ domains ------------------ -from pypy.objspace.cclp.constraint import domain +from pypy.module.cclp.constraint import domain all_mms.update(domain.all_mms) W_FiniteDomain = domain.W_FiniteDomain ## # ---- constraints ---------------- -from pypy.objspace.cclp.constraint import constraint +from pypy.module.cclp.constraint import constraint all_mms.update(constraint.all_mms) -## #----- distributors --------------- -from pypy.objspace.cclp.constraint import distributor #-- SPACE HELPERS ------------------------------------- @@ -183,125 +176,101 @@ def Space(*args, **kwds): - # for now, always make up a wrapped StdObjSpace - from pypy.objspace import std - space = std.Space(*args, **kwds) - - # multimethods hack - space.model.typeorder[W_Var] = [(W_Var, None), (W_Root, None)] # None means no conversion - space.model.typeorder[W_Future] = [(W_Future, None), (W_Var, None), (W_Root, None)] - space.model.typeorder[W_CVar] = [(W_CVar, None), (W_Var, None), (W_Root, None)] - space.model.typeorder[W_FiniteDomain] = [(W_FiniteDomain, None), (W_Root, None)] - - for name in all_mms.keys(): - exprargs, expr, miniglobals, fallback = ( - all_mms[name].install_not_sliced(space.model.typeorder, baked_perform_call=False)) - func = stdtypedef.make_perform_trampoline('__mm_' + name, - exprargs, expr, miniglobals, - all_mms[name]) - # e.g. add(space, w_x, w_y) - def make_boundmethod(func=func): - def boundmethod(*args): - return func(space, *args) - return func_with_new_name(boundmethod, 'boundmethod_'+name) - boundmethod = make_boundmethod() - setattr(space, name, boundmethod) # store into 'space' instance - # /multimethods hack - - #-- variable ------- - space.setitem(space.builtin.w_dict, space.wrap('newvar'), - space.wrap(app_newvar)) - space.setitem(space.builtin.w_dict, space.wrap('domain'), - space.wrap(app_domain)) - space.setitem(space.builtin.w_dict, space.wrap('domain_of'), - space.wrap(app_domain_of)) - space.setitem(space.builtin.w_dict, space.wrap('name_of'), - space.wrap(app_name_of)) - space.setitem(space.builtin.w_dict, space.wrap('is_free'), - space.wrap(app_is_free)) - space.setitem(space.builtin.w_dict, space.wrap('is_bound'), - space.wrap(app_is_bound)) - space.setitem(space.builtin.w_dict, space.wrap('alias_of'), - space.wrap(app_alias_of)) - space.setitem(space.builtin.w_dict, space.wrap('is_aliased'), - space.wrap(app_is_aliased)) - space.setitem(space.builtin.w_dict, space.wrap('bind'), - space.wrap(app_bind)) - space.setitem(space.builtin.w_dict, space.wrap('entail'), - space.wrap(app_entail)) - space.setitem(space.builtin.w_dict, space.wrap('unify'), - space.wrap(app_unify)) - #-- domain ------- - space.setitem(space.builtin.w_dict, space.wrap('FiniteDomain'), - space.wrap(domain.app_make_fd)) - space.setitem(space.builtin.w_dict, space.wrap('intersection'), - space.wrap(domain.app_intersection)) - #-- constraints ---- - space.setitem(space.builtin.w_dict, space.wrap('make_expression'), - space.wrap(constraint.app_make_expression)) - space.setitem(space.builtin.w_dict, space.wrap('all_diff'), - space.wrap(constraint.app_make_alldistinct)) - #-- distributor -- - space.setitem(space.builtin.w_dict, space.wrap('distribute'), - space.wrap(distributor.app_distribute)) - #-- threading -- - space.setitem(space.builtin.w_dict, space.wrap('future'), - space.wrap(app_future)) - space.setitem(space.builtin.w_dict, space.wrap('stacklet'), - space.wrap(app_stacklet)) - space.setitem(space.builtin.w_dict, space.wrap('wait'), - space.wrap(app_wait)) - space.setitem(space.builtin.w_dict, space.wrap('wait_needed'), - space.wrap(app_wait_needed)) - space.setitem(space.builtin.w_dict, space.wrap('sched_info'), - space.wrap(app_sched_info)) - space.setitem(space.builtin.w_dict, space.wrap('schedule'), - space.wrap(app_schedule)) - space.setitem(space.builtin.w_dict, space.wrap('this_thread'), - space.wrap(app_this_thread)) - space.setitem(space.builtin.w_dict, space.wrap('reset_scheduler'), - space.wrap(app_reset_scheduler)) - #-- comp. spaces -- - space.setitem(space.builtin.w_dict, space.wrap('newspace'), - space.wrap(app_newspace)) - space.setitem(space.builtin.w_dict, space.wrap('choose'), - space.wrap(app_choose)) - space.setitem(space.builtin.w_dict, space.wrap('tell'), - space.wrap(app_tell)) - - #-- misc ----- - space.setitem(space.builtin.w_dict, space.wrap('interp_id'), - space.wrap(app_interp_id)) - space.setitem(space.builtin.w_dict, space.wrap('switch_debug_info'), - space.wrap(app_switch_debug_info)) - space.setitem(space.builtin.w_dict, space.wrap('is_interpreted'), - space.wrap(app_is_interpreted)) - - #-- path to the applevel modules -- - import pypy.objspace.constraint - import os - dir = os.path.dirname(pypy.objspace.cclp.constraint.__file__) - dir = os.path.join(dir, 'test') - space.call_method(space.sys.get('path'), 'append', space.wrap(dir)) - - # make sure that _stackless is imported - w_modules = space.getbuiltinmodule('_stackless') - # cleanup func called from space.finish() - def exitfunc(): - pass - - app_exitfunc = gateway.interp2app(exitfunc, unwrap_spec=[]) - space.setitem(space.sys.w_dict, space.wrap("exitfunc"), space.wrap(app_exitfunc)) - - # capture one non-blocking op - space.is_nb_ = space.is_ - - # do the magic - patch_space_in_place(space, 'logic', proxymaker) - # instantiate singleton scheduler - sched.main_thread = AppCoroutine.w_getcurrent(space) - tg = W_ThreadGroupScheduler(space) - tg._init_head(sched.main_thread) - sched.uler = TopLevelScheduler(space, tg) + try: + # for now, always make up a wrapped StdObjSpace + from pypy.objspace import std + space = std.Space(*args, **kwds) + + # multimethods hack + space.model.typeorder[W_Var] = [(W_Var, None), (W_Root, None)] # None means no conversion + space.model.typeorder[W_Future] = [(W_Future, None), (W_Var, None), (W_Root, None)] + space.model.typeorder[W_CVar] = [(W_CVar, None), (W_Var, None), (W_Root, None)] + space.model.typeorder[W_FiniteDomain] = [(W_FiniteDomain, None), (W_Root, None)] + + for name in all_mms.keys(): + exprargs, expr, miniglobals, fallback = ( + all_mms[name].install_not_sliced(space.model.typeorder, baked_perform_call=False)) + func = stdtypedef.make_perform_trampoline('__mm_' + name, + exprargs, expr, miniglobals, + all_mms[name]) + # e.g. add(space, w_x, w_y) + def make_boundmethod(func=func): + def boundmethod(*args): + return func(space, *args) + return func_with_new_name(boundmethod, 'boundmethod_'+name) + boundmethod = make_boundmethod() + setattr(space, name, boundmethod) # store into 'space' instance + # /multimethods hack + + #-- BUILTINS + #-- variable ------- + space.setitem(space.builtin.w_dict, space.wrap('newvar'), + space.wrap(app_newvar)) + space.setitem(space.builtin.w_dict, space.wrap('domain'), + space.wrap(app_domain)) + space.setitem(space.builtin.w_dict, space.wrap('domain_of'), + space.wrap(app_domain_of)) + space.setitem(space.builtin.w_dict, space.wrap('name_of'), + space.wrap(app_name_of)) + space.setitem(space.builtin.w_dict, space.wrap('is_free'), + space.wrap(app_is_free)) + space.setitem(space.builtin.w_dict, space.wrap('is_bound'), + space.wrap(app_is_bound)) + space.setitem(space.builtin.w_dict, space.wrap('alias_of'), + space.wrap(app_alias_of)) + space.setitem(space.builtin.w_dict, space.wrap('is_aliased'), + space.wrap(app_is_aliased)) + space.setitem(space.builtin.w_dict, space.wrap('bind'), + space.wrap(app_bind)) + space.setitem(space.builtin.w_dict, space.wrap('entail'), + space.wrap(app_entail)) + space.setitem(space.builtin.w_dict, space.wrap('unify'), + space.wrap(app_unify)) + #-- variables & threading -- + space.setitem(space.builtin.w_dict, space.wrap('wait'), + space.wrap(app_wait)) + space.setitem(space.builtin.w_dict, space.wrap('wait_needed'), + space.wrap(app_wait_needed)) + #-- domain ------- + space.setitem(space.builtin.w_dict, space.wrap('FiniteDomain'), + space.wrap(domain.app_make_fd)) + space.setitem(space.builtin.w_dict, space.wrap('intersection'), + space.wrap(domain.app_intersection)) + + #-- misc ----- + space.setitem(space.builtin.w_dict, space.wrap('interp_id'), + space.wrap(app_interp_id)) + + #-- path to the applevel modules -- + ## import pypy.objspace.constraint + ## import os + ## dir = os.path.dirname(pypy.module.cclp.constraint.__file__) + ## dir = os.path.join(dir, 'test') + ## space.call_method(space.sys.get('path'), 'append', space.wrap(dir)) + + # make sure that _stackless is imported + w_modules = space.getbuiltinmodule('_stackless') + # cleanup func called from space.finish() + def exitfunc(): + pass + + app_exitfunc = gateway.interp2app(exitfunc, unwrap_spec=[]) + space.setitem(space.sys.w_dict, space.wrap("exitfunc"), space.wrap(app_exitfunc)) + + # capture one non-blocking op + space.is_nb_ = space.is_ + + # do the magic + patch_space_in_place(space, 'logic', proxymaker) + # instantiate singleton scheduler + sched.main_thread = AppCoroutine.w_getcurrent(space) + tg = W_ThreadGroupScheduler(space) + sched.uler = TopLevelScheduler(space, tg) + tg._init_head(sched.main_thread) + + except: + import traceback + traceback.print_exc() + raise return space Modified: pypy/dist/pypy/objspace/test/test_logicobjspace.py ============================================================================== --- pypy/dist/pypy/objspace/test/test_logicobjspace.py (original) +++ pypy/dist/pypy/objspace/test/test_logicobjspace.py Wed Feb 28 14:07:55 2007 @@ -1,5 +1,5 @@ try: - from pypy.conftest import gettestobjspace + from pypy.conftest import gettestobjspace, option from py.test import skip except ImportError: pass @@ -15,7 +15,7 @@ class AppTest_Logic(object): def setup_class(cls): - cls.space = gettestobjspace('logic', usemodules=("_stackless",)) + cls.space = gettestobjspace('logic') def test_bind_var_val(self): X = newvar() @@ -253,9 +253,11 @@ class AppTest_LogicFutures(object): def setup_class(cls): - cls.space = gettestobjspace('logic', usemodules=("_stackless",)) + cls.space = gettestobjspace('logic') def test_future_value(self): + from cclp import future + def poop(X): return X + 1 @@ -279,6 +281,7 @@ bind(X, 42) def test_one_future_exception(self): + from cclp import future class FooException(Exception): pass def poop(X): @@ -295,6 +298,7 @@ assert False def test_exception_in_chain(self): + from cclp import future class FooException(Exception): pass def raise_foo(): @@ -318,6 +322,7 @@ assert False def test_exception_in_group(self): + from cclp import future class FooException(Exception): pass def loop_or_raise(Canary, crit, Bomb_signal): @@ -348,6 +353,7 @@ """check that a wait nested in a tree of threads works correctly """ + from cclp import future def sleep(X): wait(X) return X @@ -363,6 +369,7 @@ assert v == 42 def test_wait_needed(self): + from cclp import future X = newvar() def binder(V): @@ -379,6 +386,7 @@ assert X == 42 def test_eager_producer_consummer(self): + from cclp import stacklet def generate(n, limit, R): if n < limit: @@ -402,8 +410,37 @@ stacklet(generate, 0, 10, X) assert S == 45 + def test_problematic_eager_producer_consummer(self): + """ + straight from CRM + BUG:a way (not to) keep the generator live forever + """ + from cclp import future + + def generate(n, Xs): + Xr = newvar() + wait(Xs) + unify((n, Xr), Xs) + generate(n+1, Xr) + + def sum(Xs, a, limit): + if limit > 0: + X, Xr = newvar(), newvar() + unify((X, Xr), Xs) + return sum(Xr, a+X, limit-1) + else: + unify(None, Xs) # -> to release the generator + # with a unification error + # Oz code does not suffer from this + return a + + Xs = newvar() + S = future(sum, Xs, 0, 10) + future(generate, 0, Xs) + assert S == 45 def test_lazy_producer_consummer(self): + from cclp import future, stacklet, sched_info, reset_scheduler def lgenerate(n, L): """wait-needed version of generate""" @@ -443,6 +480,7 @@ assert len(sp_info['threads']) == 1 def test_wait_two(self): + from cclp import future, sched_info def sleep(X, Barrier): wait(X) @@ -468,6 +506,7 @@ assert len(sp_info['threads']) == 1 def test_fib(self): + from cclp import future def fib(X): if X<2: return 1 @@ -481,6 +520,7 @@ assert F == 89 def test_stacklet(self): + from cclp import stacklet, sched_info, reset_scheduler reset_scheduler() count = [0] @@ -508,37 +548,13 @@ assert len(sp_info['threads']) == 1 return assert False - - def test_nd_append(self): - skip("non determnistic choice: yet to come") - #from CTM p.639 - #write me correctly... - """ - def append(A, B, C): - choice: - unify(A, None) - unify(B, C) - or: - As, Bs, X = newvar(), newvar(), newvar() - unify(A, (X, As)) - unify(C, (X, Cs)) - append(As, B, Cs) - """ - from solver import solve - X, Y, S = newvar(), newvar(), newvar() - unify((X, Y), S) - - for sol in solve(lambda : append(X, Y, [1, 2, 3])): - assert sol in ((None, [1, 2, 3]), - ([1], [2, 3]), - ([1, 2], [3]), - ([1, 2, 3], None)) - + def test_stream_merger(self): """this is a little cheesy, due to threads not being preemptively scheduled """ + from cclp import future, stacklet, schedule def _sleep(X, Barrier): wait(X) @@ -592,6 +608,7 @@ def test_digital_logic(self): + from cclp import stacklet, reset_scheduler def print_stream(S): elts = [] @@ -656,9 +673,10 @@ class AppTest_CompSpace(object): def setup_class(cls): - cls.space = gettestobjspace('logic', usemodules=("_stackless",)) + cls.space = gettestobjspace('logic') def test_cvar(self): + from cclp import newspace def in_space(X): d = domain([1, 2, 4], '') @@ -712,6 +730,7 @@ wait(X) def test_ask_choose(self): + from cclp import stacklet, newspace, choose def chooser(X): choice = choose(3) @@ -728,6 +747,7 @@ assert X == 2 def test_more_ask_choose(self): + from cclp import stacklet, newspace, choose, sched_info def chooser(vec, X): for v in vec: @@ -753,7 +773,8 @@ def test_tell_ask_choose_commit(self): - from problem import conference_scheduling + from constraint.examples import conference_scheduling + from cclp import stacklet, newspace, choose, switch_debug_info def solve(spc, commitment, Sol): while 1: @@ -772,67 +793,14 @@ s = newspace(conference_scheduling) Solution = newvar() stacklet(solve, s, commit_to, Solution) -## if commit_to == 1: -## assert set(Solution) == set([('room A', 'day 1 AM'), -## ('room B', 'day 1 AM'), -## ('room B', 'day 2 PM'), -## ('room A', 'day 1 PM'), -## ('room A', 'day 2 AM'), -## ('room C', 'day 2 PM'), -## ('room C', 'day 2 AM'), -## ('room C', 'day 1 AM'), -## ('room C', 'day 1 PM'), -## ('room B', 'day 2 AM')]) -## else: -## assert set(Solution) == set([('room B', 'day 1 PM'), -## ('room A', 'day 1 PM'), -## ('room B', 'day 2 AM'), -## ('room B', 'day 1 AM'), -## ('room A', 'day 2 PM'), -## ('room C', 'day 2 AM'), -## ('room C', 'day 2 PM'), -## ('room C', 'day 1 PM'), -## ('room C', 'day 1 AM'), -## ('room B', 'day 2 PM')]) # well, depending on dict key linear order, we get different - # results - print Solution + # results -- possibly failed spaces + assert len(Solution) == 10 - - def test_default_solver(self): - if is_interpreted(): - skip("will loop infinitely (bug in space.clone())") - else: - skip("clone segfaults") - from constraint.examples import conference_scheduling - from constraint import solver - - s = newspace(conference_scheduling) - sols = set() - for sol in solver.solve(s): - sols.add(tuple(sol)) - print sol - assert len(sols) == 64 - - - def test_recomputing_solver(self): - skip("segfaulting") - if is_interpreted(): - skip("interpreted clone support still missing") - from problem import conference_scheduling - from constraint import solver - import sys - - s = newspace(conference_scheduling) - - sols = set() - for sol in solver.solve_recomputing(s, sys.maxint): - sols.add(tuple(sol)) - print sol - assert len(sols) == 64 def test_logic_program(self): + from cclp import newspace, choose def soft(): choice = choose(2) @@ -929,9 +897,16 @@ assert len(sols) == 2 + +class AppTest_CompSpaceCloning(object): + + def setup_class(cls): + if not option.runappdirect: + skip('pure pypy-logic test (try with _test_logic_build)') + cls.space = gettestobjspace('logic') + + def test_cloning_queens(self): - if is_interpreted(): - skip("no cloning feature") from constraint.examples import queens1, queens2 from constraint.solver import solve @@ -944,3 +919,79 @@ print sol #assert len(sols) == 2 + + def test_full_logic_program(self): + + from constraint.solver import solve + + def soft(): + choice = choose(2) + if choice == 1: + return 'beige' + else: + return 'coral' + + def hard(): + choice = choose(2) + if choice == 1: + return 'mauve' + else: + return 'ochre' + + def contrast(C1, C2): + choice = choose(2) + if choice == 1: + unify(C1, soft()) + unify(C2, hard()) + else: + unify(C1, hard()) + unify(C2, soft()) + + def suit(): + Shirt, Pants, Socks = newvar(), newvar(), newvar() + contrast(Shirt, Pants) + contrast(Pants, Socks) + if Shirt == Socks: fail() + return (Shirt, Pants, Socks) + + s = newspace(suit) + for sol in solve(s): + print sol + + def test_recomputing_solver(self): + from problem import conference_scheduling + from constraint import solver + import sys + + s = newspace(conference_scheduling) + + sols = set() + for sol in solver.solve_recomputing(s, sys.maxint): + sols.add(tuple(sol)) + print sol + assert len(sols) == 64 + + def test_nd_append(self): + skip('write me') + #from CTM p.639 + #write me correctly... + """ + def append(A, B, C): + choice: + unify(A, None) + unify(B, C) + or: + As, Bs, X = newvar(), newvar(), newvar() + unify(A, (X, As)) + unify(C, (X, Cs)) + append(As, B, Cs) + """ + from solver import solve + X, Y, S = newvar(), newvar(), newvar() + unify((X, Y), S) + + for sol in solve(lambda : append(X, Y, [1, 2, 3])): + assert sol in ((None, [1, 2, 3]), + ([1], [2, 3]), + ([1, 2], [3]), + ([1, 2, 3], None)) Modified: pypy/dist/pypy/rlib/cslib/rdomain.py ============================================================================== --- pypy/dist/pypy/rlib/cslib/rdomain.py (original) +++ pypy/dist/pypy/rlib/cslib/rdomain.py Wed Feb 28 14:07:55 2007 @@ -22,12 +22,12 @@ "The implementation of remove_value should call this method" if self.size() == 0: raise ConsistencyError, "tried to make a domain empty" + self._changed = True def remove_value(self, value): """Remove value of domain and check for consistency""" del self._values[value] self._value_removed() - self._changed = True def remove_values(self, values): assert isinstance(values, list) @@ -35,7 +35,6 @@ for val in values: del self._values[val] self._value_removed() - self._changed = True def size(self): """computes the size of a finite domain""" From mwh at codespeak.net Wed Feb 28 15:17:18 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Wed, 28 Feb 2007 15:17:18 +0100 (CET) Subject: [pypy-svn] r39576 - in pypy/extradoc/talk/sprint-introduction.key: . thumbs Message-ID: <20070228141718.8370B10120@code0.codespeak.net> Author: mwh Date: Wed Feb 28 15:17:17 2007 New Revision: 39576 Added: pypy/extradoc/talk/sprint-introduction.key/py-web1.tiff (contents, props changed) pypy/extradoc/talk/sprint-introduction.key/thumbs/mt0-4.tiff (contents, props changed) pypy/extradoc/talk/sprint-introduction.key/thumbs/mt0-6.tiff (contents, props changed) pypy/extradoc/talk/sprint-introduction.key/thumbs/mt0-8.tiff (contents, props changed) pypy/extradoc/talk/sprint-introduction.key/thumbs/st1-2.tiff (contents, props changed) pypy/extradoc/talk/sprint-introduction.key/thumbs/st11-2.tiff (contents, props changed) pypy/extradoc/talk/sprint-introduction.key/thumbs/st12-2.tiff (contents, props changed) pypy/extradoc/talk/sprint-introduction.key/thumbs/st12-3.tiff (contents, props changed) pypy/extradoc/talk/sprint-introduction.key/thumbs/st3-6.tiff (contents, props changed) pypy/extradoc/talk/sprint-introduction.key/thumbs/st3-7.tiff (contents, props changed) pypy/extradoc/talk/sprint-introduction.key/thumbs/st32.tiff (contents, props changed) pypy/extradoc/talk/sprint-introduction.key/thumbs/st33.tiff (contents, props changed) pypy/extradoc/talk/sprint-introduction.key/thumbs/st34.tiff (contents, props changed) pypy/extradoc/talk/sprint-introduction.key/thumbs/st35.tiff (contents, props changed) pypy/extradoc/talk/sprint-introduction.key/thumbs/st4.tiff (contents, props changed) pypy/extradoc/talk/sprint-introduction.key/thumbs/st5.tiff (contents, props changed) Log: yeah, so saving presentations as bundles isn't really subversion compatible then (though i don't think these files are at all vital, just cached thumbnails) Added: pypy/extradoc/talk/sprint-introduction.key/py-web1.tiff ============================================================================== Binary file. No diff available. Added: pypy/extradoc/talk/sprint-introduction.key/thumbs/mt0-4.tiff ============================================================================== Binary file. No diff available. Added: pypy/extradoc/talk/sprint-introduction.key/thumbs/mt0-6.tiff ============================================================================== Binary file. No diff available. Added: pypy/extradoc/talk/sprint-introduction.key/thumbs/mt0-8.tiff ============================================================================== Binary file. No diff available. Added: pypy/extradoc/talk/sprint-introduction.key/thumbs/st1-2.tiff ============================================================================== Binary file. No diff available. Added: pypy/extradoc/talk/sprint-introduction.key/thumbs/st11-2.tiff ============================================================================== Binary file. No diff available. Added: pypy/extradoc/talk/sprint-introduction.key/thumbs/st12-2.tiff ============================================================================== Binary file. No diff available. Added: pypy/extradoc/talk/sprint-introduction.key/thumbs/st12-3.tiff ============================================================================== Binary file. No diff available. Added: pypy/extradoc/talk/sprint-introduction.key/thumbs/st3-6.tiff ============================================================================== Binary file. No diff available. Added: pypy/extradoc/talk/sprint-introduction.key/thumbs/st3-7.tiff ============================================================================== Binary file. No diff available. Added: pypy/extradoc/talk/sprint-introduction.key/thumbs/st32.tiff ============================================================================== Binary file. No diff available. Added: pypy/extradoc/talk/sprint-introduction.key/thumbs/st33.tiff ============================================================================== Binary file. No diff available. Added: pypy/extradoc/talk/sprint-introduction.key/thumbs/st34.tiff ============================================================================== Binary file. No diff available. Added: pypy/extradoc/talk/sprint-introduction.key/thumbs/st35.tiff ============================================================================== Binary file. No diff available. Added: pypy/extradoc/talk/sprint-introduction.key/thumbs/st4.tiff ============================================================================== Binary file. No diff available. Added: pypy/extradoc/talk/sprint-introduction.key/thumbs/st5.tiff ============================================================================== Binary file. No diff available. From mwh at codespeak.net Wed Feb 28 15:18:19 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Wed, 28 Feb 2007 15:18:19 +0100 (CET) Subject: [pypy-svn] r39577 - pypy/extradoc/talk Message-ID: <20070228141819.7A1CE1013E@code0.codespeak.net> Author: mwh Date: Wed Feb 28 15:18:18 2007 New Revision: 39577 Added: pypy/extradoc/talk/sprint-introduction-2up.pdf (contents, props changed) Log: a version of the sprint-introduction as pdf with two slides per page Added: pypy/extradoc/talk/sprint-introduction-2up.pdf ============================================================================== Binary file. No diff available. From mwh at codespeak.net Wed Feb 28 15:19:57 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Wed, 28 Feb 2007 15:19:57 +0100 (CET) Subject: [pypy-svn] r39578 - in pypy/extradoc/talk/pycon2007: . pycon07.key pycon07.key/thumbs Message-ID: <20070228141957.E44161013A@code0.codespeak.net> Author: mwh Date: Wed Feb 28 15:19:55 2007 New Revision: 39578 Modified: pypy/extradoc/talk/pycon2007/pycon07.key/index.apxl.gz pypy/extradoc/talk/pycon2007/pycon07.key/thumbs/st23.tiff pypy/extradoc/talk/pycon2007/pycon07.pdf Log: the version of the talk as actually presented Modified: pypy/extradoc/talk/pycon2007/pycon07.key/index.apxl.gz ============================================================================== Binary files. No diff available. Modified: pypy/extradoc/talk/pycon2007/pycon07.key/thumbs/st23.tiff ============================================================================== Binary files. No diff available. Modified: pypy/extradoc/talk/pycon2007/pycon07.pdf ============================================================================== Binary files. No diff available. From cfbolz at codespeak.net Wed Feb 28 15:27:09 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 28 Feb 2007 15:27:09 +0100 (CET) Subject: [pypy-svn] r39579 - pypy/dist/pypy/doc Message-ID: <20070228142709.7978710151@code0.codespeak.net> Author: cfbolz Date: Wed Feb 28 15:27:07 2007 New Revision: 39579 Modified: pypy/dist/pypy/doc/getting-started.txt Log: (mwh, cfbolz): delete two comments lines that rest didn't agree were comments Modified: pypy/dist/pypy/doc/getting-started.txt ============================================================================== --- pypy/dist/pypy/doc/getting-started.txt (original) +++ pypy/dist/pypy/doc/getting-started.txt Wed Feb 28 15:27:07 2007 @@ -477,8 +477,6 @@ Please see the pypy/translator/js/test directory for example unittests. Here is a simple example to try:: -.. >>> from pypy.translator.interactive import Translation -.. >>> from pypy.translator.test import snippet >>> t = Translation(snippet.my_gcd) >>> a = t.annotate([int, int]) From cfbolz at codespeak.net Wed Feb 28 15:45:01 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 28 Feb 2007 15:45:01 +0100 (CET) Subject: [pypy-svn] r39582 - pypy/extradoc/eu-report Message-ID: <20070228144501.CD95E10156@code0.codespeak.net> Author: cfbolz Date: Wed Feb 28 15:44:57 2007 New Revision: 39582 Added: pypy/extradoc/eu-report/D14.2_Tutorials_and_Guide_Through_the_PyPy_Source_Code-interim-2007-02-28.pdf (contents, props changed) Log: 14.2 interim version Added: pypy/extradoc/eu-report/D14.2_Tutorials_and_Guide_Through_the_PyPy_Source_Code-interim-2007-02-28.pdf ============================================================================== Binary file. No diff available. From cfbolz at codespeak.net Wed Feb 28 16:01:29 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 28 Feb 2007 16:01:29 +0100 (CET) Subject: [pypy-svn] r39585 - pypy/extradoc/eu-report Message-ID: <20070228150129.8233E1014A@code0.codespeak.net> Author: cfbolz Date: Wed Feb 28 16:01:27 2007 New Revision: 39585 Added: pypy/extradoc/eu-report/D03.1_Extension_Compiler-interim-2007-02-28.pdf (contents, props changed) Log: publish 3.1 report Added: pypy/extradoc/eu-report/D03.1_Extension_Compiler-interim-2007-02-28.pdf ============================================================================== Binary file. No diff available. From cfbolz at codespeak.net Wed Feb 28 16:45:18 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 28 Feb 2007 16:45:18 +0100 (CET) Subject: [pypy-svn] r39589 - pypy/dist/pypy/doc Message-ID: <20070228154518.5297E10108@code0.codespeak.net> Author: cfbolz Date: Wed Feb 28 16:45:14 2007 New Revision: 39589 Modified: pypy/dist/pypy/doc/index-report.txt Log: add links to the 14.2 report and update the one about 3.1 Modified: pypy/dist/pypy/doc/index-report.txt ============================================================================== --- pypy/dist/pypy/doc/index-report.txt (original) +++ pypy/dist/pypy/doc/index-report.txt Wed Feb 28 16:45:14 2007 @@ -12,6 +12,14 @@ Reports of 2007 =============== +`D14.2 Tutorials and Guide Through the PyPy Source Code`_ is an interim version +of a report about the steps we have taken to make the project approachable for +newcomers. + +`D03.1 Extension Compiler`_ is an interim version of a report about +PyPy's extension compiler and RCTypes, as well as the effort to keep up with +CPython's changes. All feedback for it is very welcome. *(2007-02-28)* + `Draft D13.1 Build and Configuration Tool`_ is an interim version of a report about our build an configuration toolchain as well as the planned Debian packages. The report is still a draft, all feedback for it is welcome. @@ -28,11 +36,6 @@ .. _`py-lib`: http://codespeak.net/py/current/doc/ .. _`py.test`: http://codespeak.net/py/current/doc/test.html -`Draft D03.1 Extension Compiler`_ is an interim version of a report about -PyPy's extension compiler and RCTypes, as well as the effort to keep up with -CPython's changes. The report is still a draft, all feedback for it is very -welcome. *(2007-01-22)* - Reports of 2006 =============== @@ -96,7 +99,8 @@ .. _`Draft D09.1 Constraint Solving and Semantic Web`: http://codespeak.net/pypy/extradoc/eu-report/D09.1_Constraint_Solving_and_Semantic_Web-interim-2006-07-28.pdf .. _`D14.3 Report about Milestone/Phase 2`: http://codespeak.net/pypy/extradoc/eu-report/D14.3_Report_about_Milestone_Phase_2-final-2006-08-03.pdf .. _`PyPy's approach to virtual machine construction`: http://codespeak.net/svn/pypy/extradoc/talk/dls2006/pypy-vm-construction.pdf -.. _`Draft D03.1 Extension Compiler`: http://codespeak.net/pypy/extradoc/eu-report/D03.1_Extension_Compiler-interim-2007-01-22.pdf +.. _`D03.1 Extension Compiler`: http://codespeak.net/pypy/extradoc/eu-report/D03.1_Extension_Compiler-interim-2007-02-28.pdf .. _`Draft D02.3 Testing Tool`: http://codespeak.net/pypy/extradoc/eu-report/D02.3_Testing_Framework-interim-2007-01-28.pdf .. _`Draft D08.2 JIT Compiler Architecture`: http://codespeak.net/pypy/extradoc/eu-report/D08.2_JIT_Compiler_Architecture-interim-2007-01-28.pdf .. _`Draft D13.1 Build and Configuration Tool`: http://codespeak.net/pypy/extradoc/eu-report/D13.1_Build-_and_Configuration_Tool-interim-2006-02-01.pdf +.. _`D14.2 Tutorials and Guide Through the PyPy Source Code`: http://codespeak.net/pypy/extradoc/eu-report/D14.2_Tutorials_and_Guide_Through_the_PyPy_Source_Code-interim-2007-02-28.pdf From cfbolz at codespeak.net Wed Feb 28 16:48:58 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 28 Feb 2007 16:48:58 +0100 (CET) Subject: [pypy-svn] r39590 - pypy/extradoc/eu-report Message-ID: <20070228154858.0D59810125@code0.codespeak.net> Author: cfbolz Date: Wed Feb 28 16:48:56 2007 New Revision: 39590 Added: pypy/extradoc/eu-report/D09.1_Constraint_Solving_and_Semantic_Web-interim-2007-02-28.pdf Log: add 9.1 interim version Added: pypy/extradoc/eu-report/D09.1_Constraint_Solving_and_Semantic_Web-interim-2007-02-28.pdf ============================================================================== --- (empty file) +++ pypy/extradoc/eu-report/D09.1_Constraint_Solving_and_Semantic_Web-interim-2007-02-28.pdf Wed Feb 28 16:48:56 2007 @@ -0,0 +1,3885 @@ +%PDF-1.4 +5 0 obj +<< /S /GoTo /D (section.1) >> +endobj +8 0 obj +(Executive Summary) +endobj +9 0 obj +<< /S /GoTo /D (section.2) >> +endobj +12 0 obj +(Introduction) +endobj +13 0 obj +<< /S /GoTo /D (subsection.2.1) >> +endobj +16 0 obj +(Purpose of this Document) +endobj +17 0 obj +<< /S /GoTo /D (subsection.2.2) >> +endobj +20 0 obj +(Scope of this Document) +endobj +21 0 obj +<< /S /GoTo /D (subsection.2.3) >> +endobj +24 0 obj +(Related Documents) +endobj +25 0 obj +<< /S /GoTo /D (subsection.2.4) >> +endobj +28 0 obj +(Getting Started) +endobj +29 0 obj +<< /S /GoTo /D (section.3) >> +endobj +32 0 obj +(Concurrent Constraint and Logic Programming) +endobj +33 0 obj +<< /S /GoTo /D (subsection.3.1) >> +endobj +36 0 obj +(Motivation) +endobj +37 0 obj +<< /S /GoTo /D (subsection.3.2) >> +endobj +40 0 obj +(Logic Programming in Prolog) +endobj +41 0 obj +<< /S /GoTo /D (subsection.3.3) >> +endobj +44 0 obj +(Constraint Programming and MAC) +endobj +45 0 obj +<< /S /GoTo /D (subsection.3.4) >> +endobj +48 0 obj +(Limits of Prolog and MAC) +endobj +49 0 obj +<< /S /GoTo /D (subsection.3.5) >> +endobj +52 0 obj +(From Backtracking Engines to CCLP) +endobj +53 0 obj +<< /S /GoTo /D (subsection.3.6) >> +endobj +56 0 obj +(From CCLP to Oz to Python \(anecdotal bits\)) +endobj +57 0 obj +<< /S /GoTo /D (subsection.3.7) >> +endobj +60 0 obj +(Constraint Handling Rules) +endobj +61 0 obj +<< /S /GoTo /D (section.4) >> +endobj +64 0 obj +(Logic Programming in PyPy) +endobj +65 0 obj +<< /S /GoTo /D (subsection.4.1) >> +endobj +68 0 obj +(Basic Elements Serving Deterministic Logic Programming) +endobj +69 0 obj +<< /S /GoTo /D (subsection.4.2) >> +endobj +72 0 obj +(Threads and Dataflow Synchronization) +endobj +73 0 obj +<< /S /GoTo /D (subsection.4.3) >> +endobj +76 0 obj +(Table of Operators) +endobj +77 0 obj +<< /S /GoTo /D (subsection.4.4) >> +endobj +80 0 obj +(Implementation Aspects) +endobj +81 0 obj +<< /S /GoTo /D (section.5) >> +endobj +84 0 obj +(Programming With Search) +endobj +85 0 obj +<< /S /GoTo /D (subsection.5.1) >> +endobj +88 0 obj +(Non-Deterministic Logic Programs) +endobj +89 0 obj +<< /S /GoTo /D (subsection.5.2) >> +endobj +92 0 obj +(Constraint Programs) +endobj +93 0 obj +<< /S /GoTo /D (subsection.5.3) >> +endobj +96 0 obj +(Using the Constraint Engine) +endobj +97 0 obj +<< /S /GoTo /D (subsection.5.4) >> +endobj +100 0 obj +(Table of Operators) +endobj +101 0 obj +<< /S /GoTo /D (subsection.5.5) >> +endobj +104 0 obj +(Extending the Search Engine) +endobj +105 0 obj +<< /S /GoTo /D (subsection.5.6) >> +endobj +108 0 obj +(Implementation Aspects) +endobj +109 0 obj +<< /S /GoTo /D (subsection.5.7) >> +endobj +112 0 obj +(History of the Implementation, Credits) +endobj +113 0 obj +<< /S /GoTo /D (section.6) >> +endobj +116 0 obj +(Semantic Web: Reasoning in OWL) +endobj +117 0 obj +<< /S /GoTo /D (section.7) >> +endobj +120 0 obj +(Implementation of the OWL Reasoner) +endobj +121 0 obj +<< /S /GoTo /D (subsection.7.1) >> +endobj +124 0 obj +(Implementation of Builtin OWL Types) +endobj +125 0 obj +<< /S /GoTo /D (subsection.7.2) >> +endobj +128 0 obj +(Implementation of Builtin OWL Predicates) +endobj +129 0 obj +<< /S /GoTo /D (subsection.7.3) >> +endobj +132 0 obj +(Example of Using the OWL Reasoner) +endobj +133 0 obj +<< /S /GoTo /D (section.8) >> +endobj +136 0 obj +(Using the Results for Semantic Web Applications) +endobj +137 0 obj +<< /S /GoTo /D (subsection.8.1) >> +endobj +140 0 obj +(Searching the Language Technology World) +endobj +141 0 obj +<< /S /GoTo /D (subsection.8.2) >> +endobj +144 0 obj +(Assessing Benefits) +endobj +145 0 obj +<< /S /GoTo /D (section.9) >> +endobj +148 0 obj +(Conclusion) +endobj +149 0 obj +<< /S /GoTo /D [150 0 R /Fit ] >> +endobj +154 0 obj << +/Length 1114 +/Filter /FlateDecode +>> +stream +x??V?r?6??+??gBo?9~?J?????$Y@$????#???HQ??v??B pxqp??$!? c?8V"?CD?E??-????\".d 'V#?1????1R? + ?????+7E?0?vV??? +??a ?G?P?A F?_?_?8??{>b??I#?A??_??p ???60>vG? ??'1"?0???a?c???D8G3 +y??8????2@??Wt??!?8?D #&z]?/??wT?#)A??&??p?-?_.f??eD????c?????Cp???$"?i?4?3 at E ?,??Q)??'(Q?z?2lMa?????????I? L GSqv?M?B??Z?0X?F?%??4F??.+?.y????mw???gn~f??x@?v?????u??u????c??n7U]???3?QU'-???U?x?Ma?vd??????7?L???z?????hJ7ZT]?{??????)|t8??#???N?>l???????U?c??z ????_???+?MM1?/?C?'??a?bN?y?:??Oq ?b?r?J?N?^?nUdM3?f??Y??U??z?\?f?[??? J8???U(??:\??n_K???I[?i?? ??O??r?????[?Yz??? ?-N???_?? n??endstream +endobj +150 0 obj << +/Type /Page +/Contents 154 0 R +/Resources 153 0 R +/MediaBox [0 0 595.2757 841.8898] +/Parent 161 0 R +>> endobj +151 0 obj << +/Type /XObject +/Subtype /Image +/Width 149 +/Height 110 +/BitsPerComponent 8 +/ColorSpace [/Indexed /DeviceRGB 63 162 0 R] +/Length 1649 +/Filter /FlateDecode +>> +stream +x???m[?:???BjmjZ????e???v?]Q????Ih??$!Dv?s]<~??-7O??????S???????Oi?}?tjru???uTE?L??~?s ?@?_?"T??????? ?r?????]??V? 0?7$??,????B??^??>a???s/???T??!D1?J???+5@ ? +??B?????Zu&k?*T?????A?????@Q?X?'f????Q??5("B??RV?{|???|?P?y*s~????a?X7&In?3TO??kJ#Ty??l??s?G? (Ju?k???GTP?f[?????4?tD?UZ?a#?LFi?Z??s!R-???&F??;5V?? ????`U??0?m+P%?*Q2lQuP??%??)f6n? +s????1D ??|z|J?????U??aYN?5?T?R?[APSh?Q????#J *??1?P?r?*F)A???:??J?(%??A (?C?b??5???B?????Rs*?? ?TPa????lT)%?6c?(?? (?n-?A??{????#??w????'42jI?d??oL??q?!75J8i?6?x??Y?F?????s4?"wt????????MZHt??{????(?L?????d??a??? ???ne8?:3HL ?D?G|*?M??????I??wW;??0?#???!8"?????R????+?Q%6*u?r??h? ???T?*0By? +? ?t)1??=7?????;???t'w*T????\VuRe?sV??L??&????KJ]??,??2#q$?8?????Uo??P}????b{???d6??w4T=?o??%_(??,???$?zX???R\???2?J????&?H?>??N?#?1}?$??2?e? ???FoH?Q{=??#V??f??????7 ?????+?Pd ????L????]?????????l??F?t?{ xD;`?J?T???m???M?????} ? u???|??bqw????.Z???|?;?gyY?d??????77?????e&8?Q,?:?e???^?\?A%ow?2??c?1??? j??N.&~>??=?t?a~6?"?????4???j??????w@?U?????:??@?YJ?? +5s=??0??5&PVE?f?|&???????|*?m??Q???????????????????????;E?ZEz?)?~?n&"F????r?W????g?:2(A ??^ad=?tx??????????W?endstream +endobj +162 0 obj << +/Length 203 +/Filter /FlateDecode +>> +stream +x?????/?&T??:??^???????k????????????pK???????S&?Z????D?????-???????????????|?? +???_7??O??-???ph??wWO????b:?h ???????????}?|???????????u*????????{??????{Y?????x??,??s?4??????(u[endstream +endobj +152 0 obj << +/Type /XObject +/Subtype /Form +/FormType 1 +/PTEX.FileName (../img/ist-norm.pdf) +/PTEX.PageNumber 1 +/PTEX.InfoDict 163 0 R +/Matrix [1.00000000 0.00000000 0.00000000 1.00000000 0.00000000 0.00000000] +/BBox [0.00000000 0.00000000 385.00000000 199.00000000] +/Resources << +/ProcSet [ /PDF ] +/ExtGState << +/R4 164 0 R +>>>> +/Length 165 0 R +/Filter /FlateDecode +>> +stream +x?u}[?%?????&?????aO??{l???????2W?66????zS_???_??? +?????????????????????????}??u????????(?u|???????/+?o?(???????R??R?)??????????j?w???(???????s??fF5???&)g?+??????1??3v&^?'G??YX/?????/??_????>???n>G????^z|?u?B?a???h p|?????|?%??!?? +?g???,`?>?O??c?????~??[]?c| ?????7?t????)/?????k?? ????y3???q???????T?4??]????zO????fl?l?*???o ^??n?]??#???Qvh.???KOM [??N??>?i?z???????M??d<]j?s????k??????"m??j??^k?<.|????~? v?p??kn??E?s???-? +?n??g?~??^x???w?]p??X?~Xvj????????????4q?p~???8 +??|G?}j????c?pw>%?%?iR????l?g_????,!?????????O??V?7????Q?[??"_,?????????!?/??,BS?zL=?5_??t?P?1???5?.???g???>cN??b??)Z???x???kK?????l?Gw??!? ?3?]??#??s??????&?4??+{??x???Eo??w?S?dw?y?@????(;L??F?U?{D????|?)??H ?t86^???????*Y?h?NN??????VN{#W??OM+2???a?????:???????z?{?Ys?_???l?X#??\?0?$???B?h????D???~nIx4??/?h?E??? %????}?????? ?gR??` nI?3?$??l?? zK{(O???? ?Q???????g0?????(lI9?%???s?~OH???y??????NHn?a?????????Hc<~?????8??s?xU?VJ?jS?l?X]s%/????K}??????bs??????Au}?lnh????????m'{??u???~:kS??n<[??*?g?]???fj?????????w????????????????-??I??[???? ??.C? >?{??X?????sk*??J???A???E??1??P???????9n???jT$???:?? g??<]/??"???IQ???8?}??!?|????-v'?,a +rC? ?8?????+??T?? ?????3P>??y(?paKIB]???tThWV??7?n???B?\?R?$??,??sv??|?n????Y,?* +????V???-???????_??s%?a?}???? U?'??zA9H#??C8y? ??$P$??????bI????t??d??.??? +?/?_ ?(2?B?w?'??????^C?N????S?????c?:`????z_?????\(8!?Q??X_?sP?^wm??????\?e????bS'aK???C???h?p?$?.8?^?aj?J\-_???????4j????}}????????&?&!?L??\?=_???By??? ???o4?,?z???5????i???jnM ?dsA???!??\.?~!C????&????&|??4?;.?`???G?^???X=???X????R????}y:[???j?/?Z??H???/L{1 ????X??k?Z?V???t??'3???Ax???B?,? G??N? ???????;?????F? ??re$a?8????O8?}K-?l??Y?????8/??9?9x?#???D?6[?.Xc8??????????Jp???@8?5;??M??N????????{??R(??M?G?????Lf???"/Be???0??-??A????|?GK?8?CI???+???X?q?r?+ ??T(LX?? ??!?&V?????v?????s?P?j?Q??L?L??st?????u???3?s????%????F???? ???tA??#3??W8??0??G???? ?=-????t???2?mI8NJ??l)?? +M?y?*Q?BB??L,?? ?=??/?????)_?????6?:O? ??yDn???!4???????{???vyl?????????/`?Uzf? +? j_M?-:??f?}?????????????{??4??K4V??????s??dK????v_Wg?"????-&??|???!?`f???????v????`???2??? +??]???m.A??U?VM???????i????? ????%????q.d?????????l???????ms R?????m/??B?6 ?'??????? ?H???v?f?J?>????C???C6 ????6 ?z??V???d? ?"?>??'?????:5??88S?? 7?????A?? ?jO#`K?z???w??G??????b????W?u>2??g?X??*???d?3?'S?P??[??????6t??(j?|???lp)=O?K2Gru??w???(?hR ????????W???K?g?Q???/?j?????E??I????rf?sN??a1??x??H?7?'=V??* ?????+!?I ?B??f`?Tnl??z?|????$<N$E?????G\?B??K?z?????G?M???R?RS???%??\?S?}?? ???N???EdA?.?? +?`?Eh?4????&A?tx?"`????r_WNVo?[?S ?p???!?z?0-?K???O??~??S??;??? ?&N? 9?XC????S? ???j~A$??????? ??V?Lg? ?Y?1?5?n?Oj????et(? Z?7W?@ _?>? +?????????????HVD????b???????????^mz -f?!mE@?b| ?8?@?t!?%?????????SU????(\?K???>?to?E?*+? Y +M??D??0?????:?WD?C%??@7;? + g??I?????m??*H!????X'C???{????ib??????RKE????X?B W? G;k?O ?{?B%?R??}??:?v???B8?q???q'???PYtY9?Dn$l&?x??*????????x??dBD at .??j??S? +??5??6Fg?&???????8????????/, ?????6?T?4i?L?v?????U>/h??????G +pW?4?{2???9????B?t????U?????? ??`?qc???JP??~~A+??k ???????l,??2??O?? ??_8/????v&??? 8=?O?\:???.6??Q??n?H$?v?%{ %???i?8??&???3??7????????q??T????8???D#??t[iai?X??b?.:]????????1??.?E?*$ ??\*{?L??W?#????] ????+J4h(???Fs??N??}B]??? ????n [?H?????(?I!??)??S?e?????????w????|C?>R?7d#;?????./?q?b?R;O???!?|.?? ???c???? +?v F??5A???O?P????? ? ????\`}?%*?$????9Z'bQ:???o?Q???CQ?a?A9?{o@????l ??=,???K@????j?,?F']?Lx+???&6?S???[Th?`?????????d.?3>??f???b@??%C?????%F?h?/pV5?@% +?X%[? ?X?x??d?2_Hp?"> ]aX.0S?Z???6???????? L?F?'?o@?U?>??`????H?9?l????U?q???:??f?????/?????@??#=?e?lG7i"? ,?>5?`?|\?%?5sm??5??1P??O?j!F?W?W???????`7?????s??OHY?:?c|Kb2??@ ??m?*Pq??z?!4^??? 9?????/?zrt?T????A6??C?Le%???UJ:h?? ???`2?? +??x?s&?Y?d)Y ??A6:??EKy?8???V@F]?Pg??7??????F????@???$?2?? l???c!e????uF\?????aM?R????<T?%?p?`??F??jh?`I??m?kD?c?+?#? ?1??K??????MtW???it?n?v??=? ^?Q?J???z}????8??M?j??:?;6?2????CHS?8?7li~?1??P?5?o?u?m?I'?!?fIE??????????????k-???#???M?????????? J;B?d?r:5$Lf?$3???n?B+gL6??z?0[??(?a??? ?O??????????/=? +ppk??S?O?(0?0?U?"???]??6F???????2?????XQ? ?^%?]2Rxz??]?S????pe?p?x!k???M??w/?B?!??2?vD??(?}+ ?v?R?)$p?S%?D[?LDf???Q8?x?E)????d??7???F?@??????????F??????2 ?UB??????l +?R?>????/?Pxb"?l??=J??5%???O=(??2?.R?I||A?*RN?o???? e???v???S??????9Z?xg??23?$8???X??M?`??????I?F?? ?4???Pn??????-x8?Z$7b5q???Lp?Hx~?r(???]?d?w?+#??ad??:Fx?XIZ?(f?????OW???9d|}??????????|N???~????O N?? ?j=?=??km]??PI8????k???~H8S$al1? I???????C~?K???fH????^???/h>?7@??br?S?I +?c??B??!)????]X??????????T??+&???? Sk-B???CPn"??9#??_?gpX ?\~??f????0????????E?`?g???a ??????o???Q??7???dr|?{2 ?V?!i?????u!}T?/????S ?N/?J?I?Syl?K???C{ ?Q????]?? +???J|?jFg??~??~?3t???HY4?k;??]z???H?D8&V?`93?J.e?#&;??????????<,??qF?rR??P????? m/??[?"?OH?%?KA??;?6.;? ??U?????c?sw?.????`}?hQ?D??}????????????8??a????4x4??y??N??U?A ?.?fFeF??=x> ???%`9N??G7??S?N??`*$????N???Om??W????r$??T{?o-?D??c??a????)F +BFt?1~d?? ?3a????f5/?p????2y7?>1??< ??#????_????????_?Y???2????X??[i??8? ? F??????.??,@^??b:?Mz)????e?'6?HGz@??t????9c???a&??v?~?v?:??H???bFc^;??+"??}???UO????g???7?I?.sP?vZ????M*:??????0???x:C???:J??vB???]??T)hjE?9n?v?:P8?em?? $G??'???bxD S?????!?{@Y??j???I ???*c??2Y??&d]%?C?4??D???.???}0?UqB?;?y?/??+???Vx?? ?d^O??]?w?Hyin?O????b?/????8?#Q?k?j9??U?`X????qwd?????>?`pB?W?>??F??W?>S??? X?d? r?7?+?L??????B-rm??E??????|?H+Y#E^Eq?L?=?? ?\A*D<)?,????5????(???L)?a+???*X?j?????? ?????????a[????,b????? ?u#X???G??? =??N???f/??%?&~ *?????.????qR???H /?N??Lb{p??????u?G^??????Q?$?i???1.??iD0a?????(E?2?b,1b?QBh>???V??????]0?H??-?|?@o???_|f?A\j?yb???????$?u ??^?pv;/??V ??rb?O??{3gB=?5????,???????Dh???#?qK?H?Gm?Rc?K????:?????&2?????h?E? ??f?????+7???????????d??$?",?9???[x??X?70?G?"??????>FZ??i?I???|c?Wt|}?-3??9?????K??$0xU:????u!?? S?????-P?3?.B?E?,]?Dj?.???j=?G?d???w?x`???y??Q??????]?? ?q??b?????e????b??H^p?T?%(9???r!?C????n6?d??3$p?K?`H??5??Z??~4????`~L??\???z?i|??(???-{??f5?q ???_??K #???????????Y???=O???4 +]5U???????}Mj??+?s39~???? +^y ???/e?? ???sF??%????b?1?*?&??0?? +???d????~M?\|H???_D?s^y??p?a?o??H?)???}????TtR_????Vf?#'?a??R?fC?p????b?-??6Am???*?????0??q???N??d???o? ?Y?_??>??C????N??`?%?> +endobj +164 0 obj +<< +/Type /ExtGState +/Name /R4 +/TR /Identity +/OPM 1 +/SM 0.02 +>> +endobj +165 0 obj +10833 +endobj +155 0 obj << +/D [150 0 R /XYZ 74.4095 753.1919 null] +>> endobj +156 0 obj << +/D [150 0 R /XYZ 74.4095 735.2591 null] +>> endobj +157 0 obj << +/D [150 0 R /XYZ 74.4095 735.2591 null] +>> endobj +153 0 obj << +/Font << /F26 160 0 R >> +/XObject << /Im1 151 0 R /Im2 152 0 R >> +/ProcSet [ /PDF /Text /ImageC /ImageI ] +>> endobj +168 0 obj << +/Length 1711 +/Filter /FlateDecode +>> +stream +x??ZKs?6??W?H?T@??[b?m???C39$9@,??C!)???]<(BRM?C???@`??v???E??cQ?'?K???????X?y'4w??-fOn??#?4????`& ??% ??????????W? ?? ???z5 ????ik???i{W??Y?6?\?ZY???R????Q_.?>-^>? ??? ??9??a???????????bo 8N??% +?Z?R???[??N|??k?F???1??? ??cN?F???^?????????o???J??????????0?? T??% U#z_??w?????f!??.?/w?4S??pp;z' ?Q?}p?`??+Y7?+???Y?d??`???????"?/a??9U??B??MX?uaS??)8O??????? +2j? 6?|?4?]D?/P#?0?-5r??8?R??p??T??X{j?`????aD?L???Z[U#?a?L????(??".?W?:??p??O????????I?6?8??V?^????[!j?$J????Rs?h????????(?o57?u-?Bm?96??w? 8???]?X?V??G#?0?????Q?=?\???~&??pks?-s??????(?l????G?????K??0?Y?? pp#Q]`??H???dG?dL??3??]?f2?#F???p??????C????l???8??????8A&??qc?^ ??????!H2LG?d??????[8???v?O??v?1??????6?? ??e?5????w????? ??r!?V??A:Lf???C??????m??$s|#???A6?j?b?8?=?~O??{??q?{N`_??w? tvXu9???r9rDPW?C\????? B???z?"?05O0?ryq????? ?P{.?X?-3L??a?(??.?%,?Yq?'???Fld????R?9?????????z??C???*q?`????T?8T?R???f?]??- %Ag???A?:)(????????*j? +?<?vS?Z??:5?`??| :i`??hh/?mkj?????U???3???t?VT ?j?b??BC? ?i????4SQu????]?H??I?"???J?!k7F@???*?????Vhn?k{?M????uT????U??9u???????t???6?\?Z???????}??*um???:t???6k??4zE +i?E??h%???S???????????14?2#C???)k??g???l??#<5?????Jc> endobj +173 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [98.1105 751.264 110.0657 767.2042] +/Subtype /Link +/A << /S /GoTo /D (page.27) >> +>> endobj +169 0 obj << +/D [167 0 R /XYZ 74.4095 753.1919 null] +>> endobj +174 0 obj << +/D [167 0 R /XYZ 74.4095 710.7978 null] +>> endobj +175 0 obj << +/D [167 0 R /XYZ 74.4095 698.8426 null] +>> endobj +176 0 obj << +/D [167 0 R /XYZ 74.4095 528.615 null] +>> endobj +166 0 obj << +/Font << /F26 160 0 R /F31 172 0 R >> +/XObject << /Im1 151 0 R >> +/ProcSet [ /PDF /Text /ImageC /ImageI ] +>> endobj +180 0 obj << +/Length 2641 +/Filter /FlateDecode +>> +stream +x??\Mw????Wpi????????I?6=i?&~'?? Ffm?Z?+?m?_?@A?(l??:Y???g.??????G2??:?$S?*??f????7 b1?t?^^-^?1??4??5S1%?Q??R8???:?|?|\????????????W?v_???????X?????t??k?j?)??z???i)?Y?y???w/?0?i??!`????????%???? tqq?G? ,T&?)n~hG??????????>??G%??????F????[???bgCO?}?b?9C????H*????F?q?[T??y?????s???/?nH??Z???~??? ??? M!%9????_pvm?????F?.z?????N?1?)at????XcR?q4???m???????I3(X@~??x??????Y-`|v?W?z???vJ??HC +k2$????yJ???Q?{?@???D?ck?R? t?A9????R|?b?y???`-??+?z?????\???Ef?f??X???T4???=S?? D;,??VB????j?????&??P?^??????????>?R?he?&?-?/7??D???9???5?e???B?\?)?????????o?L?2?X????[?~S???H}??]???b? ????d?????RHK???Nb?)d???B??Il 2??o??MmH????yn?~f???e??m?o6`????t??q????U7??p??nv?f??4P?LTfv?!?h??`?G7?.mrN???O??~ jc?w?Wf?XL??AT?!???????)?f?????d?)E?&?????"???HH?(?*?@?P?#[ ??????v'1?s???Q Cn?y?t??|sQh?P??d???c?????4fb???C?;?9"B?cgq??0?(\%???)????n[Y???~??{]?????O+????W?????d?r??"YH)???`N??????S[????z[k?H??:??f?F?&jh???:eWKM???w?!???]QW??svS?B????1????6K?j@?t??J?D d?ID?Z??2\????????Gu:v?????n???d+?????*?*b8?B???[i???o3 ???:?T(??T????Rb???.??mu?@?(i?H1? ????, ?MLU ?Y?vsl?RH?T?[ ??l??G?Z?>??\?.??`H??Cu?u???~??o???[??M??44?$Y??-iQ ??D?<)?? ?p U0????X!?????S'z???????h??????vt???c?X???? >??Z+??=v?????jD?N????N????????^? ?)???au '`e*T"???D??U??C?'?Z?A F8??R,?u~6???*q??Q?b??????. +??wQ?N?uR?P??????\9|?z??V?9???U@?zT?Vw???zo????gm?j?~??Uw?r???j?x?>J??uw?2??D ?$??Z+??G)???m="$?5?p[??????&??~?????W??????w?=y?Ds?=d2qO???????);???c?I?>????p9T????kM4??u7g??????aX??G?>?J??2???m?*brt? ?@?s?6\?- +?????U??`?S???~???2? #z4?(?YT?7UB????^???9 \l????? ???E???N|???:U????tk???ci2??O??,d5q????V(?R??B1 +T?(??R!?u?V[??,W???ud~?]4*?o???^N?YW?Y?67?-???bH?igE(j???E?Z1??4????TeN???? +???U??endstream +endobj +179 0 obj << +/Type /Page +/Contents 180 0 R +/Resources 178 0 R +/MediaBox [0 0 595.2757 841.8898] +/Parent 161 0 R +/Annots [ 182 0 R 184 0 R 185 0 R 186 0 R 187 0 R 188 0 R 189 0 R 190 0 R 191 0 R 192 0 R 193 0 R 194 0 R 195 0 R 196 0 R 197 0 R 198 0 R 199 0 R 200 0 R 201 0 R 202 0 R 203 0 R 204 0 R 205 0 R 206 0 R 207 0 R 208 0 R 209 0 R 210 0 R 211 0 R 212 0 R 213 0 R 214 0 R 215 0 R ] +>> endobj +182 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [98.1105 751.264 110.0657 767.2042] +/Subtype /Link +/A << /S /GoTo /D (page.27) >> +>> endobj +184 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [73.4132 678.8235 180.8397 690.3402] +/Subtype /Link +/A << /S /GoTo /D (section.1) >> +>> endobj +185 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [73.4132 654.0759 147.9033 663.3809] +/Subtype /Link +/A << /S /GoTo /D (section.2) >> +>> endobj +186 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [88.3572 634.1602 228.2412 646.17] +/Subtype /Link +/A << /S /GoTo /D (subsection.2.1) >> +>> endobj +187 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [88.3572 616.9393 217.7109 628.9492] +/Subtype /Link +/A << /S /GoTo /D (subsection.2.2) >> +>> endobj +188 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [88.3572 602.3137 199.5891 611.7283] +/Subtype /Link +/A << /S /GoTo /D (subsection.2.3) >> +>> endobj +189 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [88.3572 582.4977 180.3611 594.5075] +/Subtype /Link +/A << /S /GoTo /D (subsection.2.4) >> +>> endobj +190 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [73.4132 555.5732 304.5347 567.3141] +/Subtype /Link +/A << /S /GoTo /D (section.3) >> +>> endobj +191 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [88.3572 540.6886 162.2693 549.7993] +/Subtype /Link +/A << /S /GoTo /D (subsection.3.1) >> +>> endobj +192 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [88.3572 520.8725 244.4106 532.8823] +/Subtype /Link +/A << /S /GoTo /D (subsection.3.2) >> +>> endobj +193 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [88.3572 503.6517 269.9747 515.6615] +/Subtype /Link +/A << /S /GoTo /D (subsection.3.3) >> +>> endobj +194 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [88.3572 486.4308 230.3337 498.4407] +/Subtype /Link +/A << /S /GoTo /D (subsection.3.4) >> +>> endobj +195 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [88.3572 469.21 274.1888 481.2198] +/Subtype /Link +/A << /S /GoTo /D (subsection.3.5) >> +>> endobj +196 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [88.3572 451.9892 307.6329 463.999] +/Subtype /Link +/A << /S /GoTo /D (subsection.3.6) >> +>> endobj +197 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [88.3572 434.7683 231.7281 446.7782] +/Subtype /Link +/A << /S /GoTo /D (subsection.3.7) >> +>> endobj +198 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [73.4132 407.8439 217.9401 419.3606] +/Subtype /Link +/A << /S /GoTo /D (section.4) >> +>> endobj +199 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [88.3572 390.364 368.2446 402.3739] +/Subtype /Link +/A << /S /GoTo /D (subsection.4.1) >> +>> endobj +200 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [88.3572 373.1432 286.0843 385.153] +/Subtype /Link +/A << /S /GoTo /D (subsection.4.2) >> +>> endobj +201 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [88.3572 355.9224 194.7074 367.9322] +/Subtype /Link +/A << /S /GoTo /D (subsection.4.3) >> +>> endobj +202 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [88.3572 338.7015 221.1776 350.7114] +/Subtype /Link +/A << /S /GoTo /D (subsection.4.4) >> +>> endobj +203 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [73.4132 311.7771 210.6376 323.518] +/Subtype /Link +/A << /S /GoTo /D (section.5) >> +>> endobj +204 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [88.3572 294.2972 267.7826 306.0032] +/Subtype /Link +/A << /S /GoTo /D (subsection.5.1) >> +>> endobj +205 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [88.3572 277.0764 205.0786 288.7823] +/Subtype /Link +/A << /S /GoTo /D (subsection.5.2) >> +>> endobj +206 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [88.3572 259.8555 238.2934 271.8654] +/Subtype /Link +/A << /S /GoTo /D (subsection.5.3) >> +>> endobj +207 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [88.3572 242.6347 194.7074 254.6445] +/Subtype /Link +/A << /S /GoTo /D (subsection.5.4) >> +>> endobj +208 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [88.3572 225.4139 239.778 237.4237] +/Subtype /Link +/A << /S /GoTo /D (subsection.5.5) >> +>> endobj +209 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [88.3572 208.193 221.1776 220.2029] +/Subtype /Link +/A << /S /GoTo /D (subsection.5.6) >> +>> endobj +210 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [88.3572 190.9722 284.7087 202.982] +/Subtype /Link +/A << /S /GoTo /D (subsection.5.7) >> +>> endobj +211 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [73.4132 164.0478 247.6491 175.7886] +/Subtype /Link +/A << /S /GoTo /D (section.6) >> +>> endobj +212 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [73.4132 136.8643 264.1269 148.6052] +/Subtype /Link +/A << /S /GoTo /D (section.7) >> +>> endobj +213 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [88.3572 119.3844 282.2282 131.3942] +/Subtype /Link +/A << /S /GoTo /D (subsection.7.1) >> +>> endobj +214 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [88.3572 102.1636 301.675 114.1734] +/Subtype /Link +/A << /S /GoTo /D (subsection.7.2) >> +>> endobj +215 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [88.3572 84.9427 277.6258 96.9526] +/Subtype /Link +/A << /S /GoTo /D (subsection.7.3) >> +>> endobj +181 0 obj << +/D [179 0 R /XYZ 74.4095 738.3126 null] +>> endobj +183 0 obj << +/D [179 0 R /XYZ 74.4095 699.4261 null] +>> endobj +178 0 obj << +/Font << /F26 160 0 R /F31 172 0 R >> +/XObject << /Im1 151 0 R >> +/ProcSet [ /PDF /Text /ImageC /ImageI ] +>> endobj +218 0 obj << +/Length 716 +/Filter /FlateDecode +>> +stream +x??V?n?0??+x???????4M???,.zHsPl?1 K?$????i?E?*z)?e?????E~i??in0?L???#hs_)???????]w?^^??**?pB?;?)???q??3?C??%\aj??X?%HY??s*v?p?w??D?U????V'?j??????(???M?[????9??l??? cY???7?C2S?:? N ?L?C8%8???M4?}qR?5?????$#?(5?3?S,)???jl93mF8?RR5c??[3???gE??>???'!?t'?^B&?@G???aG?w ??????wg????S?1????p????T?~?,TR??OS??j????[?d_????VP???a?um ?)a?i\??SW*?,?GSo?x??G6?endstream +endobj +217 0 obj << +/Type /Page +/Contents 218 0 R +/Resources 216 0 R +/MediaBox [0 0 595.2757 841.8898] +/Parent 161 0 R +/Annots [ 220 0 R 221 0 R 222 0 R 223 0 R 224 0 R ] +>> endobj +220 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [98.1105 751.264 110.0657 767.2042] +/Subtype /Link +/A << /S /GoTo /D (page.27) >> +>> endobj +221 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [73.4132 706.8705 314.8262 718.6114] +/Subtype /Link +/A << /S /GoTo /D (section.8) >> +>> endobj +222 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [88.3572 688.6787 302.1934 700.6886] +/Subtype /Link +/A << /S /GoTo /D (subsection.8.1) >> +>> endobj +223 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [88.3572 670.746 194.3388 682.7558] +/Subtype /Link +/A << /S /GoTo /D (subsection.8.2) >> +>> endobj +224 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [73.4132 645.5455 142.3642 654.8505] +/Subtype /Link +/A << /S /GoTo /D (section.9) >> +>> endobj +219 0 obj << +/D [217 0 R /XYZ 74.4095 738.3126 null] +>> endobj +216 0 obj << +/Font << /F26 160 0 R /F31 172 0 R >> +/XObject << /Im1 151 0 R >> +/ProcSet [ /PDF /Text /ImageC /ImageI ] +>> endobj +227 0 obj << +/Length 2290 +/Filter /FlateDecode +>> +stream +x??XKs?8??W?HWE4I???y??Tf??{k?( +??& ???_???EQ?x[:?n4?~|???????c?J/ ??H\??:?V?z??V>?l??f*???????2 +?w???sE??(u?? ?w??????p? B???R???b#|?y???o????w??????$?wLUUV?EN??.b???????/???i?????? ?-C???(???n?I +??d???H??"?????????f*o?}???V??'HM???hp??~?eQ???Nm7?????\6??BE???Ru+N???;???L????F?EV?Do????2?\??#/fW"u?*rB??b????z?P/??(?????g2?????? L?;&Ks{s?Q?W??? X?%UY?,?r??,8h??w43'?? ?}?n?=Or]?pqmNc(p?J=???DN?zv +??*?????u????Z2`-Vkb?'??p??s??`?A>+?j???`v?F??n?2H1?w?F]]4??;?& ;???;N?R??A F???]0??t???z??Oy#?X?? -8?)k =?????\W ?@?w??O?;???iQe"uc/?*?r???[???S??????s?T??????mt?^??5????&?0 +N +??N [n??G? R??`5L[??M?)f? ? ???P?d9?????mB2?8????h?G? -?m???????b}??,???m??n?o?B?y?39?23 >???L?6??????j[?8 ?n( ?X?zA??Js?-M??0O????D!?T??t?P?? [=H +????B?4????5?{TY?E??????B??????f?0?'?M?8G]Le?? +Y ??7N?7 G2->??-J??o?o?`?!????v`:???????1Z9??O[C??????b??;zd??D???=???LpO?M???????????#?? ?0?????<#(s?BA??Sw???;?@}?I ????Vc?E +?l??7 ???h??? ?O???&????? ^??y?????i??+'~??b?*???Oz^???M????[???nqM??";??K?\?{???!&tD0]??0A#??#@??????Q?(????h?:i???Ri? ,?E?5 C?????K?p??> endobj +229 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [98.1105 751.264 110.0657 767.2042] +/Subtype /Link +/A << /S /GoTo /D (page.27) >> +>> endobj +234 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 0] +/Rect [117.8762 252.8204 145.0342 263.56] +/Subtype /Link +/A << /S /GoTo /D (cite.SPQL) >> +>> endobj +228 0 obj << +/D [226 0 R /XYZ 74.4095 738.3126 null] +>> endobj +230 0 obj << +/D [226 0 R /XYZ 74.4095 720.3798 null] +>> endobj +6 0 obj << +/D [226 0 R /XYZ 74.4095 720.3798 null] +>> endobj +231 0 obj << +/D [226 0 R /XYZ 74.4095 572.3883 null] +>> endobj +10 0 obj << +/D [226 0 R /XYZ 74.4095 556.2125 null] +>> endobj +232 0 obj << +/D [226 0 R /XYZ 74.4095 524.5788 null] +>> endobj +14 0 obj << +/D [226 0 R /XYZ 74.4095 524.5788 null] +>> endobj +233 0 obj << +/D [226 0 R /XYZ 74.4095 465.8698 null] +>> endobj +18 0 obj << +/D [226 0 R /XYZ 74.4095 450.862 null] +>> endobj +235 0 obj << +/D [226 0 R /XYZ 74.4095 252.8503 null] +>> endobj +22 0 obj << +/D [226 0 R /XYZ 74.4095 237.8425 null] +>> endobj +236 0 obj << +/D [226 0 R /XYZ 74.4095 181.778 null] +>> endobj +26 0 obj << +/D [226 0 R /XYZ 74.4095 166.7703 null] +>> endobj +225 0 obj << +/Font << /F26 160 0 R /F31 172 0 R /F34 239 0 R >> +/XObject << /Im1 151 0 R >> +/ProcSet [ /PDF /Text /ImageC /ImageI ] +>> endobj +243 0 obj << +/Length 538 +/Filter /FlateDecode +>> +stream +x??SMo?@????#He=???c??j.MK9D9?P$ ??T??,?1NU??e???yog9?qjS?5??1????=?c??&9??9?????x??Ie??PL:?M?g?????ct???q"4D?????!?RWo]?Ur?u?^Ty?H????i????[e????f???z? ??@??#? ??e???????q?j?????v????9?}?'s???????0??Kr???x?`_x}D???????)(_g?m???i;Y/???)-???b+??sj`??????5?c??p?C9?Cp?}??uM??; ??? P?c?*????P? ???N???M ? ?'J????HI????,;?~???????\?3???Dn?h??vZ????*??????????(????nWS0??u?M??????Y??1wQ????-1N1??MKU?Z?/${|?R???[??|]%7?D4(??5}???aVoe???*??r?t|b?y??CM???+?T(c???5}?ui?g]Y????????p?T?C?? ?g?A??endstream +endobj +242 0 obj << +/Type /Page +/Contents 243 0 R +/Resources 241 0 R +/MediaBox [0 0 595.2757 841.8898] +/Parent 161 0 R +/Annots [ 245 0 R ] +>> endobj +245 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [98.1105 751.264 110.0657 767.2042] +/Subtype /Link +/A << /S /GoTo /D (page.27) >> +>> endobj +244 0 obj << +/D [242 0 R /XYZ 74.4095 738.3126 null] +>> endobj +241 0 obj << +/Font << /F26 160 0 R /F31 172 0 R /F34 239 0 R >> +/XObject << /Im1 151 0 R >> +/ProcSet [ /PDF /Text /ImageC /ImageI ] +>> endobj +248 0 obj << +/Length 3680 +/Filter /FlateDecode +>> +stream +x????????_?[?U1G??-???L?z?t???!?A???2????????l??W>? ? ????+??4\?A"_F?|??-60???o`Vh5??????????T$?/??A?(I?????????????????K????*?????j?&+???~?w?e??NVfT???+s?????^?????????HE@?[?? /b"3|??????NR`???E?"Q????L?1 ???m?Wcx????V?A???}??????????????????z?<&?>k??ebf??]0??@?i?H?I??????*P?"?qf?=?*???g???????>,~6? ?????D$? +x??{????(M???#?@?r?P**?b;?{??a?9???sr ?'?????: ?=???5(x???HM??i?U?s?u???zc????7M???:??"=_?a(????b?O,????????+?j^?????z?j?? ^??y?i;???>p T????l?u?????????o??'K?????G?u????;?6i?????H8t ??????7$???????Z??~u?9??Y??U??}?_ +?*i ?A +2??W':??e"i?8?7?????2?\fV?????-?z??6?.??)% ?F???`???$???_^? ???gnV?Hxa?.?$?J?;???_?\??x??????/xc??R??p?;?=?a*?D&S? ?s??/?J??????????:?/XH#??w7n??????A|>|??l;?]]dc?*E? 3????_??|k|]C???mF? no??{??6Cm g?z???????#???|???#Qi??????????(Q?n????TE?????9???,?I(?????dQ?}?? M?%?b?/?????V4???$?X?`"?LvB%?N??Ou ??g?? +;???????[pn2?!aL???+?[|??x???v?????a?:??f?o1??V??LVfG2E??6n?c??$z/?P??? w?v=? ?ik +????C??\s?????|?c?Cf7??.4?????Y??o?)???x?u?????hY??|????*+??????O?>P??#?H???N?Es??(??oY?0?????&?8?Ae?+??P?_????u#????????? B????wY???.'*?'{K????Qf2?A"P&??0?; ???;??(Qj?T?h?3 ` ??;v3?>?.???|?A?9F-?????t??e???C ???1??????f?>?? +C}Z?b??N?%?8????4<2?j???0??$K&BKC??????????J?3?? +Z????dq??5?????2cU]???kY?&Z???s??S???6 ?P?D??'?P?ad?c?????V\?(*?M??!????D????/??vC???????EI?6?Q?????X[????#??&;??__? +E?w^??P7?m?(??.?[$a?$??=&??^A~?????s????5???i??=l???}???g;?u\????i?? AH?0?._g?b??G???????qT W??? ??Uu?}???T?9????P?Vq?o?N?&Iw?c?m??,~4???Z?YO.O?g??$q.?L?*M.?; ??FPr???????Y????1????P??????#?9?????:`a??5k;{? o0??;?????g??X?1?&M?z?W??G??\?wzEid??8M??J3???4????Js??S??$??LH??=/??K~~{Y|S?Z??.??I?w?1??! ?????q?? ??$??Te?????8?j?wC?$?F??7?E?Q?-?(?7h??DF????9??i??n???n?pP?!??T??????(????$*??J08?C??c?Q??D???Y??e?? ??w????x??{n??D?ox??|????????a??yC? +_ ??d???~?????p ?km?*?tW~4cG;W`?A??3??p???|(?????9Xi?,??GvF?????M????d'h??w?\?h? ??S??3@?U??? OI???4?N?a??;w-`?oK???f<6?qc??????5????V?k??NP???L????:??????? #?nj?????xG?k???#?j?d?-?S??????????d .??H????cv???Q?OR?????]?>?X??J???H|?D?%???p??? ?ve????o??????????P?? ??, ?H?o ?e??J? ??_R?o?0T????J?p??$????}??]?w???s?:??|V??f.?cr????1???Y????=???m?;???e?v51?l?|?0?+]? +??P??????g??????N??6(?8i????ki?D??v??q??`rR???dJ*9????q_W?? ?Z??>[c??????.?-0??/?8?DHn Bg?A??/O??? ?V?X?E;???$??^?\??6s????9????qJ?9?D??????endstream +endobj +247 0 obj << +/Type /Page +/Contents 248 0 R +/Resources 246 0 R +/MediaBox [0 0 595.2757 841.8898] +/Parent 264 0 R +/Annots [ 250 0 R 253 0 R 254 0 R 255 0 R 256 0 R 257 0 R 258 0 R ] +>> endobj +250 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [98.1105 751.264 110.0657 767.2042] +/Subtype /Link +/A << /S /GoTo /D (page.27) >> +>> endobj +253 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 1] +/Rect [225.0626 584.8424 258.0884 596.8522] +/Subtype/Link/A<> +>> endobj +254 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 1] +/Rect [270.452 584.8424 297.9685 596.8522] +/Subtype/Link/A<> +>> endobj +255 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 1] +/Rect [396.2816 566.9096 521.8625 578.9195] +/Subtype/Link/A<> +>> endobj +256 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 0] +/Rect [237.4666 557.5497 268.5898 566.6604] +/Subtype /Link +/A << /S /GoTo /D (cite.ECP94) >> +>> endobj +257 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 1] +/Rect [295.3147 554.9545 464.6502 566.9643] +/Subtype/Link/A<> +>> endobj +258 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 0] +/Rect [119.3912 545.5945 155.5853 554.7053] +/Subtype /Link +/A << /S /GoTo /D (cite.MAC97) >> +>> endobj +249 0 obj << +/D [247 0 R /XYZ 74.4095 738.3126 null] +>> endobj +251 0 obj << +/D [247 0 R /XYZ 74.4095 720.3798 null] +>> endobj +30 0 obj << +/D [247 0 R /XYZ 74.4095 720.3798 null] +>> endobj +252 0 obj << +/D [247 0 R /XYZ 74.4095 695.5956 null] +>> endobj +34 0 obj << +/D [247 0 R /XYZ 74.4095 695.5956 null] +>> endobj +259 0 obj << +/D [247 0 R /XYZ 74.4095 378.6157 null] +>> endobj +260 0 obj << +/D [247 0 R /XYZ 74.4095 358.6904 null] +>> endobj +261 0 obj << +/D [247 0 R /XYZ 74.4095 326.81 null] +>> endobj +262 0 obj << +/D [247 0 R /XYZ 74.4095 294.9296 null] +>> endobj +263 0 obj << +/D [247 0 R /XYZ 74.4095 276.1799 null] +>> endobj +246 0 obj << +/Font << /F26 160 0 R /F31 172 0 R >> +/XObject << /Im1 151 0 R >> +/ProcSet [ /PDF /Text /ImageC /ImageI ] +>> endobj +269 0 obj << +/Length 3737 +/Filter /FlateDecode +>> +stream +x?????6?>_?*_4??????????8?wsHr?(??2?Hi??????\REb??q?@??FI?,\}???~????~#B???%??~#9[??U??L^?4?[]\?jOS??hV???S??~??:????????K?J?$?0[m? &??$c????_??$????? V??????????????????'X????9l?E?Q?u?@t? ?????mO???lN??E?fc?T(?0I4??? +)?>?X????B??0??????s?????????_?V?\7$5O?l-b?$???/????????$q?z???D??;??@???#??owW??Y?t?C??8?? +??;??E?????????A ???L??Y???2?N[I?F_?:?M???N?Zv~}?&?X?G?ph?????C????dJ???$?$3 +?d???(???y????y?M???EF??O?? ?$?:?a?pj?????u??u???4???>? ?????sj?t 0????b?J?]???~?B???????]z?d D(;?@'R??)|2?Gj?}Q???Fa?P/?i??5 +????????D???&?!? ???o??3?}t?ES????y????lER?(FB?d?? +(}?]???w?'YGh\#Wc?Iy??????)??)s??U?????JI0]@?(? ?`???DX?#P?Xy????R?~??D?d]?O?????yIC??g??? ??|??fh??????????a?iM????W2?????O M???D??6`?r?? ???? #f????&PS\?j- ??E?98????n?? ?@j??????O-??i?n????P?i??m`??9?????+????y??e????d&0???a? T???c? ???NMK??>???j?}????PQ?G?>?S{??ZJ!????B$H??]d?!$)`+???v???j???????6?a?E??R?B???lX??/???)^?=?????|2??r?'`f?!!iLi?b??[??m???????h??????K?C01SJ????+P??w?Z ??/???B?;;@k????nv?????tZ?M????]?a????v??`ld???gU?????7=;??<?{??????gM??,?????R?????X?u???i)??9?`4??s????Za?p?q???K???T??_?????? z????d?#:2??T? u??x>';=????8??>??v~?h<?.?n?k?V??_=?? +x????g???????C?k?L???????@?pA ??0???s?W?B.H}??B??/? ?&x?y'???'??cSg??I??!1?a?.????|?????bc??,??0?%1?R?l??t?0?? +B????r????9?5??d?E ?Sp5?dR?pPK?c81.???3??? m?O???oz?????c|?t ?!?x)/I?z??r??????)?n???`'-0?L?3|q??L;?^a?Nm???????+Y?#??b??|.?2K?????3???jb?1?14??0???k??Gk???L?^?#AY?k?hx?Y%????H?;j??MA???[_IL?K????????/?????3?}C1X(????8{?%6&??Up????Z?,?\=!??P?xx}?????UI??B c???]L}????T:?p???CT?DI7e???Mr????blp????? ????:?O?'HXME?????P? +/???yX????L?????????y?1^[*???l?@+cp? Y?j???3w?}?cl???4?9???:-?c?5???!Yh??a?l,?????|x-?????s??????~b?x?Zz ?v>y???JJ???a&???????Q????4P`???EA? ?,^??? a?P??p??U?D???O?e??q?t7=???????mP??VR+?wk???r&;???J ????H???A???0S?????!v?9`?Y???1tx?&?g?????Bq?>??5L2????rQ????g%???(l0$???K^?????j??? ??m!???OgG?~??_??????c?I"A?G?`?b?????p o????6?A ???:??=???rM???C????P???=????-??g??;??d??X?y;}d??C???=a)????{??N?*I>#???qN??????B???? P?FI? +?z?C??????S?f??v???j4???/???Ex?(??i:?P/??j?t?$??? ?Y?1 jMG????G?8&]?!?$M?[YH??0Te??? ?qph?b~?F??F?a AH??{???`k???V??9???Q??????J1????7??? +??e??w^5?9"? F?|l ??_t<\?@?8Y??? ??P??s??Uz?D???O?J??R[???|6??P???????~??z????????kH????Y*?T-?????1??sh??"C?F?]nFx,??M??U??"??)?8 }?] ?(:?G????????4??Kv?? '(eJFQ[?6???"?h??d?T????????/?????m??0?fR? +?c?G??3?????F?K??w??????G?N?!?????o?c?v~A?XL?~?("?E?8???? ????????"?1??v??????>[?%?"i??b;?Xw?~"Ui?L?M??_?a ^25*? g?U?#?g?k^?endstream +endobj +268 0 obj << +/Type /Page +/Contents 269 0 R +/Resources 267 0 R +/MediaBox [0 0 595.2757 841.8898] +/Parent 264 0 R +/Annots [ 271 0 R 272 0 R 273 0 R 274 0 R 275 0 R 276 0 R 281 0 R 282 0 R 283 0 R 284 0 R 285 0 R 287 0 R 288 0 R 289 0 R 291 0 R 292 0 R 296 0 R ] +>> endobj +271 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [98.1105 751.264 110.0657 767.2042] +/Subtype /Link +/A << /S /GoTo /D (page.27) >> +>> endobj +272 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 0] +/Rect [109.0854 709.2067 147.4014 718.3175] +/Subtype /Link +/A << /S /GoTo /D (cite.PRLG92) >> +>> endobj +273 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 0] +/Rect [356.2891 709.2067 392.4832 718.3175] +/Subtype /Link +/A << /S /GoTo /D (cite.MAC97) >> +>> endobj +274 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 0] +/Rect [102.7448 685.2964 140.9315 694.4071] +/Subtype /Link +/A << /S /GoTo /D (cite.CCLP93) >> +>> endobj +275 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 1] +/Rect [128.0328 670.746 142.8372 682.7558] +/Subtype/Link/A<> +>> endobj +276 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 0] +/Rect [251.8027 673.3412 287.0304 682.452] +/Subtype /Link +/A << /S /GoTo /D (cite.OPM95) >> +>> endobj +281 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 0] +/Rect [405.2771 576.4562 440.7838 585.5669] +/Subtype /Link +/A << /S /GoTo /D (cite.MCC59) >> +>> endobj +282 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 1] +/Rect [149.659 561.9058 185.8528 573.9156] +/Subtype/Link/A<> +>> endobj +283 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 1] +/Rect [222.8071 509.5518 316.5321 521.5616] +/Subtype/Link/A<> +>> endobj +284 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 1] +/Rect [393.6495 509.5518 452.4582 521.5616] +/Subtype/Link/A<> +>> endobj +285 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 1] +/Rect [472.3489 509.5518 521.8625 521.5616] +/Subtype/Link/A<> +>> endobj +287 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 1] +/Rect [326.7923 429.1553 353.6614 441.1651] +/Subtype/Link/A<> +>> endobj +288 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 1] +/Rect [226.109 400.7116 284.9177 412.7214] +/Subtype/Link/A<> +>> endobj +289 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 0] +/Rect [420.3084 401.678 446.6894 412.4176] +/Subtype /Link +/A << /S /GoTo /D (cite.AIJ94) >> +>> endobj +291 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 1] +/Rect [414.9538 332.2702 471.9496 344.2801] +/Subtype/Link/A<> +>> endobj +292 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 0] +/Rect [350.3229 306.4218 382.1434 315.5325] +/Subtype /Link +/A << /S /GoTo /D (cite.PVR02) >> +>> endobj +296 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 1] +/Rect [283.6848 96.8979 341.778 108.9077] +/Subtype/Link/A<> +>> endobj +270 0 obj << +/D [268 0 R /XYZ 74.4095 738.3126 null] +>> endobj +277 0 obj << +/D [268 0 R /XYZ 74.4095 631.3434 null] +>> endobj +38 0 obj << +/D [268 0 R /XYZ 74.4095 616.8354 null] +>> endobj +286 0 obj << +/D [268 0 R /XYZ 74.4095 501.1881 null] +>> endobj +42 0 obj << +/D [268 0 R /XYZ 74.4095 486.6801 null] +>> endobj +290 0 obj << +/D [268 0 R /XYZ 74.4095 401.7079 null] +>> endobj +46 0 obj << +/D [268 0 R /XYZ 74.4095 387.1998 null] +>> endobj +297 0 obj << +/D [268 0 R /XYZ 74.4095 85.939 null] +>> endobj +267 0 obj << +/Font << /F26 160 0 R /F31 172 0 R /F50 280 0 R /F14 295 0 R >> +/XObject << /Im1 151 0 R >> +/ProcSet [ /PDF /Text /ImageC /ImageI ] +>> endobj +306 0 obj << +/Length 3801 +/Filter /FlateDecode +>> +stream +x??ZK??6????m5U??c??8g??8??rHr?Hh??dr4???~??H:?r?4 ?????9????& ????M?N???&?????????e?M???|??{hz?????|???? ?3'M?h???m????r??#w???9???w??n?6??;U?=?}j???~??? ?????2????I?????>????????,? ???f?p? ?%3?o?z????$l???MENB?N?#???|???????t???Rq~2_????q?V??z?za??4\???{??????:Q?????????Q?DY????I?4?7n\' ?$$?iF??????{?%????m?m?~???r=P??z2????N?????wS???}F?????7???9??a??Q?XJu???*s2JS??????`??F?9Y???/??3z?Oz???U????9???Q?#?l?8??w?CYk??????o?X7Q?%$????hk?M???d!O$j??3JM??????-m???V???L-EX?:UU?*???l??o $??b?Tw3/?~??? +?:u:?Aeoe??3?C#?yt?^?? ????qK??5???a???7?v?Ym??-A^?DL4e?????^?M??`\?4q??L??1'[S>???????]d +!E??:+? ??|e?T??b???pe?n%v? ?,D?? @?}???u1a???? +*??i????????fYhe?]?&??????????? ??W??R??j ??~?1?~r8?L???`?$2e7>??F#???????x{*????xZ?w???R?~}??u?G?Y?n???\?q??7?PH??gPmV???C??1 +???g2 >g:1*J?i^???:m?????U?????5r?a(6Of?G??Dt y????fL??p?b@:j?ZL;??? ????&?R?p??.xy'? ????1r?@?,p]g??L;69D9??K?????tk?????????PJH?x[4?=?U7D?????? \?2? +l? +W0t8eIj?A?#I??MD?v?????1??????? '???>??>?AW??r??.???m??`i???n 0???????C???H??%??7???QNZ"<?????w{,??4?q???B>r??cdZ\??.???z??e?Zs?~5???I?c]?~?#?*?e?x??X??E??H|H??P?:?A?????~??@!??%*?S??I?.&&9?:???? ??A:???_?'?fp?r5p?XkI?n???{??KD???F??z?1??VD?)u!"?#??J??M?r??C[??;HQ??? ??m+n\???W?j??JinLg_??aLx?5?????P??;???WI2? ??V?R?u?"S??8o??|=?????Gwp?????:H??Tp????? ?Un??#7v????H?s?Wp?`?j?q?V?(?-?2@W?c?\~yv}'K?`{q7x??????NX+"???>?}????????????zi??4????? +u?? %?" ?C?&?#?L??RJq?@?8?L? 6??A5x)_???~zk???r??bTz(???1 ????j8Vl???c+Z?> endobj +308 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [98.1105 751.264 110.0657 767.2042] +/Subtype /Link +/A << /S /GoTo /D (page.27) >> +>> endobj +309 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 0] +/Rect [410.7982 633.484 442.26 642.5947] +/Subtype /Link +/A << /S /GoTo /D (cite.PAR86) >> +>> endobj +310 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 0] +/Rect [93.8761 621.5288 125.5671 630.6395] +/Subtype /Link +/A << /S /GoTo /D (cite.CPR87) >> +>> endobj +311 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 0] +/Rect [240.3654 621.5288 275.2743 630.6395] +/Subtype /Link +/A << /S /GoTo /D (cite.GHC87) >> +>> endobj +315 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 0] +/Rect [431.0342 605.1045 463.1337 614.2152] +/Subtype /Link +/A << /S /GoTo /D (cite.CCP90) >> +>> endobj +316 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 0] +/Rect [76.7307 581.1942 109.7566 590.3049] +/Subtype /Link +/A << /S /GoTo /D (cite.AKL91) >> +>> endobj +318 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 1] +/Rect [185.619 458.0262 200.4235 470.0361] +/Subtype/Link/A<> +>> endobj +320 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 0] +/Rect [201.9861 99.4932 235.9485 108.6039] +/Subtype /Link +/A << /S /GoTo /D (cite.CHR98) >> +>> endobj +307 0 obj << +/D [305 0 R /XYZ 74.4095 738.3126 null] +>> endobj +50 0 obj << +/D [305 0 R /XYZ 74.4095 720.3798 null] +>> endobj +317 0 obj << +/D [305 0 R /XYZ 74.4095 517.9454 null] +>> endobj +54 0 obj << +/D [305 0 R /XYZ 74.4095 503.4675 null] +>> endobj +319 0 obj << +/D [305 0 R /XYZ 74.4095 154.2219 null] +>> endobj +58 0 obj << +/D [305 0 R /XYZ 74.4095 139.744 null] +>> endobj +304 0 obj << +/Font << /F26 160 0 R /F31 172 0 R /F50 280 0 R /F52 314 0 R >> +/XObject << /Im1 151 0 R >> +/ProcSet [ /PDF /Text /ImageC /ImageI ] +>> endobj +329 0 obj << +/Length 963 +/Filter /FlateDecode +>> +stream +x??UK??6??+?W? H9?c??C2???f? ? ?????)R??0??S??y"H??,,???/ ?=`?A?9??&???#?$?Ynv??$9?$????|?.??:Ni??J?~[?F??m??2?????:????????V?` +???*?????7_??J"3 ?i?4Ir??QThw|?L?0 +0!?b??3??ZQ??1?g?O??\??~E`i?????K3?????|O??y]X?^?????[???:??XxIL??O?JiMe$?[??kH Ox?j~?k??DuF???/5 ???? ??P?C?%?!4AD??z?a ? ?q?H??? e???i??7U????I??{yLcJD??l??????@Nd?Z??*?????V??i]??p?x??tR?B????i???*?&???c?{??vU??@????+g"R'e*?5????m5l;t6???QQ??????Vc?? P??[a ?UyR0??[???? ?????V????K???jo??\?-W,???0???1!qWX????0??~=WXn??]??}|?tA!??#y|C?f]M??9^X???ab?Gj?F??l?iB???u?f??=n???????????^??:?n?????wf????\???????J?j????.?5;?> G???0????;???8??]?j=???h|?Y?4M?+???3??3?Htendstream +endobj +328 0 obj << +/Type /Page +/Contents 329 0 R +/Resources 327 0 R +/MediaBox [0 0 595.2757 841.8898] +/Parent 264 0 R +/Annots [ 331 0 R 332 0 R ] +>> endobj +331 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [103.0918 751.264 115.047 767.2042] +/Subtype /Link +/A << /S /GoTo /D (page.27) >> +>> endobj +332 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 0] +/Rect [449.1241 655.4085 479.3905 664.5192] +/Subtype /Link +/A << /S /GoTo /D (cite.PCS00) >> +>> endobj +330 0 obj << +/D [328 0 R /XYZ 74.4095 738.3126 null] +>> endobj +327 0 obj << +/Font << /F26 160 0 R /F31 172 0 R >> +/XObject << /Im1 151 0 R >> +/ProcSet [ /PDF /Text /ImageC /ImageI ] +>> endobj +336 0 obj << +/Length 2548 +/Filter /FlateDecode +>> +stream +x???????}?B@VX4???A???X??Y`????3)????OUW7II?????*Vu?U-???? d?E?D??`<^???p????1??@?)?????a?d d?O?4 D??8 ?4?????????????0 ???+???????e???~????6?PU?v?NU??i???D.???????~l?Y ??b??H,I???? a?>< ?????EA*?????f?`?=?|?_M????]?/??'W???Q?\??????+lH? 1?Q???t????????????d$?(?U$i*????" ????P?9?~?c2??Y?7?~?????????/#C"?g!?? M????#\??Ow`8Y-?? ???bw'e?(N?Ny????srj???c?? ??6_3?? `Il?(?A?a????x ????F?v????????%O?8?????????0?M??B??L]???il;????tY???S??P??Q,;?1??\?F?{;???0=???u?p??C?? "6?#YD1(Z1?(?F3?v5?XD?+>0,? ?????'??V\Y?0?`?3??'??? ?0ku?b5,??? +???Yk6n??'O?`Y??Z ???"g???S{??xL??A???L?;"?b????H?]?=&?(?????6??4??????aH???? ?????k??V?7?Q?????DXm??w[??? LR??D???rp?D&??tEQ6?C z??DY??9??G????9???0?-8??uA?}? ?Y???????;Msop????3?I?@D?????-?????_?T?[T?f??M??????6.> endobj +338 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [103.0918 751.264 115.047 767.2042] +/Subtype /Link +/A << /S /GoTo /D (page.27) >> +>> endobj +341 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 1] +/Rect [73.4132 175.4593 122.9268 187.4691] +/Subtype/Link/A<> +>> endobj +337 0 obj << +/D [335 0 R /XYZ 74.4095 738.3126 null] +>> endobj +339 0 obj << +/D [335 0 R /XYZ 74.4095 720.3798 null] +>> endobj +62 0 obj << +/D [335 0 R /XYZ 74.4095 720.3798 null] +>> endobj +340 0 obj << +/D [335 0 R /XYZ 74.4095 559.2971 null] +>> endobj +66 0 obj << +/D [335 0 R /XYZ 74.4095 544.1118 null] +>> endobj +334 0 obj << +/Font << /F26 160 0 R /F31 172 0 R /F14 295 0 R /F52 314 0 R /F34 239 0 R /F50 280 0 R >> +/XObject << /Im1 151 0 R >> +/ProcSet [ /PDF /Text /ImageC /ImageI ] +>> endobj +344 0 obj << +/Length 2178 +/Filter /FlateDecode +>> +stream +x??Y???6?_a?????))@p@/????6[$hS,h?^???}??;???C??,???}??b!???????4??:?Q*?1O?LM??I4}??'?????K?????- ? \(6?[O???$?*%I?????????????h?6J }}=?4???????Y^???b????????5;????>\?bf???????iJR +???tjD??nK???X[??w?QhdI*JI??Lo?G|q?9$?????K??_???Y??z????|?"???^?mq?/?&Y??Pw;S???????p|??))???7?D??P>e?$?? ?]%`?"_J??$???)???(SJT:_??-???_ +?g +??????? ???'X>?d????z?A.???????9????? =?T???B?f?&???Y}(?@a????2??B??? +S?r^????l????qI???i????D??? K?$~[V-u?????? ??????i0??1??&????%??2??? ? |.??"?????J??h??M?, &`?j?????S????%6e??^?w?E??[O????Nz?Tu???????p????,?iL$??oh??".7K-?=?r ?v?Ea??b?O??? +???)??????Y#??}?g??????v??=???????k??J???F?&????6??k??????_j??l?W?g??uh-?#??????Vx??3?~V0????o?????:w?/??#Y?Z??c????????Z?W??????/??>?q?p??P??y??????? +7???Y}u3< o.?f?B??j???EO?T at F??o???????R?C||?KW???/>`???l[??t??vm0?a???{3??#>0A??u?n??!?????z$?V?6???\?gw? 1?'. ?j? RK?nS??????|??r??1_n?"???????lTTx???b?M@x=z??? ?p???(?KSU=?52|??e?!?????F?:7?????w?n_0?6?apW/??O^W??z_??5?? ???Y??6!N?????4???S????5?\???p, +d?T??zWBkco??zg?C???Z?????C????????8?d?cM??C??Q?W@??!????)??t?|????)??/i]*?d??W??2mK?NF?~? y??M?d~?i?!??6=??~Em????w???T???6B?????.x\V??A??????[?$?S'? ?????{???4?e[?Q0??YH??ba?<@?|s?/RPzH>f???Q???u4?!endstream +endobj +343 0 obj << +/Type /Page +/Contents 344 0 R +/Resources 342 0 R +/MediaBox [0 0 595.2757 841.8898] +/Parent 264 0 R +/Annots [ 346 0 R 347 0 R ] +>> endobj +346 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [103.0918 751.264 115.047 767.2042] +/Subtype /Link +/A << /S /GoTo /D (page.27) >> +>> endobj +347 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 1] +/Rect [468.0637 230.7412 521.8625 242.751] +/Subtype/Link/A<> +>> endobj +345 0 obj << +/D [343 0 R /XYZ 74.4095 738.3126 null] +>> endobj +348 0 obj << +/D [343 0 R /XYZ 74.4095 219.7822 null] +>> endobj +70 0 obj << +/D [343 0 R /XYZ 74.4095 204.5969 null] +>> endobj +342 0 obj << +/Font << /F26 160 0 R /F31 172 0 R /F34 239 0 R /F14 295 0 R >> +/XObject << /Im1 151 0 R >> +/ProcSet [ /PDF /Text /ImageC /ImageI ] +>> endobj +351 0 obj << +/Length 1519 +/Filter /FlateDecode +>> +stream +x??X[??6~??pyr??W??S?@)?a??N??Qb?F?c_6l}?tdGN?????s?H?Q?z??????,?????????w??g??,z??+?d9?|[????[^{) X???8 ??D?2???{s7_????,??? F??kU6m-T?"??*nUy???-UnE??5~?5O?/W???????? ?!pL??AK?K?P???????C*??X?B?Q?j??K?)??????s#M#?%??lZ> endobj +353 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [103.0918 751.264 115.047 767.2042] +/Subtype /Link +/A << /S /GoTo /D (page.27) >> +>> endobj +352 0 obj << +/D [350 0 R /XYZ 74.4095 738.3126 null] +>> endobj +349 0 obj << +/Font << /F26 160 0 R /F31 172 0 R /F14 295 0 R /F34 239 0 R >> +/XObject << /Im1 151 0 R >> +/ProcSet [ /PDF /Text /ImageC /ImageI ] +>> endobj +357 0 obj << +/Length 2324 +/Filter /FlateDecode +>> +stream +x??Y???6?????? ?\?D?z@?d)z??q?8?E ?Z[]Yr?Xc??w?Y????`??? g??? ??lI??-CI$??2??er\??h?X0???L?>??????L!_n??%" +A??$?h???~]}|??t??]?????7k???????*????>??cV????????M??_???r?no~?|w{'?R??PL?k0? +?L??=?.?o??0 +lQ&????~?T??O??w??????S?h'?????#?#?;???N???Wv?w????Vm\9?y?(???a2$?E)F?D??/KJ???4\?1P?,??v9?~????-????/!?????(?????w?????[???(X??,?S??q!?"2P?????=?Y:?c?)????q????5[*????}??U?????"??&??+???"C??1???.m??? WngOV????8FQ^_&D3*??s?5F?sJ??N??????7??? fBf?%?T)?3j#gsH-o@?~? 1*;dnX?Jg? +F????? ?vL1? W????2????????N??yHY??;?S???c"@?c\e?6?B???,98 N??l?????v>??5v??!? ??X????+;??????:?? '#i?8?s?E???mJ?t?W??l?????u?M3Q?E??yMs?Q^$o$a`E?;Kp??0?j;?/+????0??-?e????????!??#?"\B?V??[?Bb?????9???????'???????Qf??^R?8QL???}???)71bN!u;h?S?dq??7n???n??c??;??]???GJM??IH-?e6???]??8R?V?Z?*?1mi????g???#t?:;?.E???9kN^i??m?im(?%V?w??N`??xt??`p??????8ZT?y??2??S?=??:9??6?j??t???H 7wp?V@ @?????'??ie? 7-????-??????}1????]V?y~A???T4[?????;5??\??Y??K??QOqV????{? ????3???f?^g?,??:?[=0?OEb??,??-?@??l?2y0P ?#KRsBi?????Nm???xt?V???`d?S??pL???y? ?/????????n??????r? %??????_?LC*?x_?1?;??YH?l%???%???X4?????k?d >?(\??`??)HP!I?c???z#????O ?HE???8y?(???BJ?1??=? ???Py??i?a?rII???R??!?????????h?T?==??_&?????@???????rU{:?U3J8?e???.??^???????WN?e??%Z???P??d?t????P?@???'??"!#t??(?t?V?]?g??NAB???y??k?z???F#?es??]?????FR?{?????h?e \??? j?0??z?? ?????U???i?Ar???j?????? u?|?<.??o?2???;!??Rz>?/???@????0??E??uw\S?C  ??P ??@??PJ??A?? +??X?gq?????S ??]??qM????E?`?=6??A???|=W?o?Xp?^W?qM5? r?QtU?_??"??Ab??bPapr9r?wq? +Q?])??????????????|?j?? (?F??Fl?D]9;???Z3????]7n?qM???X?h??4U????r??&??"???e??~?#??{???@???O2??zendstream +endobj +356 0 obj << +/Type /Page +/Contents 357 0 R +/Resources 355 0 R +/MediaBox [0 0 595.2757 841.8898] +/Parent 354 0 R +/Annots [ 359 0 R 360 0 R 361 0 R 362 0 R ] +>> endobj +359 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [103.0918 751.264 115.047 767.2042] +/Subtype /Link +/A << /S /GoTo /D (page.27) >> +>> endobj +360 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 1] +/Rect [325.2474 597.7146 360.7936 609.7244] +/Subtype/Link/A<> +>> endobj +361 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 1] +/Rect [458.1062 526.4451 489.3388 538.4549] +/Subtype/Link/A<> +>> endobj +362 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 1] +/Rect [98.4689 514.4899 140.0026 526.4997] +/Subtype/Link/A<> +>> endobj +358 0 obj << +/D [356 0 R /XYZ 74.4095 738.3126 null] +>> endobj +363 0 obj << +/D [356 0 R /XYZ 74.4095 515.4861 null] +>> endobj +74 0 obj << +/D [356 0 R /XYZ 74.4095 500.409 null] +>> endobj +364 0 obj << +/D [356 0 R /XYZ 74.4095 191.4803 null] +>> endobj +78 0 obj << +/D [356 0 R /XYZ 74.4095 183.9118 null] +>> endobj +355 0 obj << +/Font << /F26 160 0 R /F31 172 0 R /F34 239 0 R /F50 280 0 R >> +/XObject << /Im1 151 0 R >> +/ProcSet [ /PDF /Text /ImageC /ImageI ] +>> endobj +367 0 obj << +/Length 1221 +/Filter /FlateDecode +>> +stream +x??VK??6??W?(?B??E??6?6?t?,?C?L?D$?+Q???w?C??6Z? r???????D ??X??L?R???o,YC?f?8?*??HVy???\f?X???}??m^p???<9??z??q??x!?2i?gzl=Q?t3?????M?_!?]O??x"B??o;?y?x?h??u??9$^?"}??zGj~g?1???\???????H?????;3D???G??nw?h:@???axV??3Xs??????ipg??9?j????? ??????H z?-?m?E?[???Z?a??D?4??dS??_???u?f?`E??x?F??B6??v?e???Q?Q?t???(?????YQ??u?3 ? =?~w??C?La?]?mm?bl?G????????V7DF,/?46F???M??P?:?>w?sD;?GF??a8#x 9??:???5?!???Ez????S"??????J?R0????g(??? ?m?y^e% ?9??q?q?? +g??*??r?-???7???X^????N???{^???p?X??4&??6k?Q??S?!??8?F?=?&??"}?M??'?????????(?C?E??????OpT ??i??7r?NPd???=??{?\?E8?}p??(??(??????m???n?y!?j????? +????2]?0??j> endobj +369 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [103.0918 751.264 115.047 767.2042] +/Subtype /Link +/A << /S /GoTo /D (page.27) >> +>> endobj +368 0 obj << +/D [366 0 R /XYZ 74.4095 738.3126 null] +>> endobj +365 0 obj << +/Font << /F26 160 0 R /F31 172 0 R /F50 280 0 R >> +/XObject << /Im1 151 0 R >> +/ProcSet [ /PDF /Text /ImageC /ImageI ] +>> endobj +372 0 obj << +/Length 2058 +/Filter /FlateDecode +>> +stream +x??]??????Bok?g-)R_???5?+.(?M??=??@???K?I??m~}f8?,Y?n??"???|? ~???????? +g??e?b??L2?????????v|??>a`N??????f??????=`??????????v?&[?E??e?$bl???E?9?J?4?$?| X(?L??????????s???k???W???D +??Y?ea?JA???%??? +'??? m?y?+)?P?I?!??O? ???????8ba??o???Cp2.??? ????]?????????2G??E???S"U?q9?,LxD?B?????{eT $?np???tOv???G??'??@??????(?5?V?*????%??{???s?????OgUC???????$??o??U??v?????=??n^x?.~#??a??G v?????o?V?w|Vmat?)!D1m???V?????????@?1>(??hY??[????>?+"??me?'?????J???_s???jhi???2???'?`SqM"1t???M?T?????y???d?;U?9?9V??????uk?????\????u?Q?6.?$G?bA?b?9D????e=9??l??+?O?]s~??G?btl`+?tH??? ???N?????? +*[?`g???2k???b(??????????)?c9???.?MrY?"???????8?u~VA???b?????a]?????'n(???????????????????HO?GpG/,?c?j????=L??2?9? +?|s5w?????%f>??*??;W?9??m-??5??P????O?kc/?k*j4?a?oC?O 7s??]??a??|?[?????? ?4M???ly?? X????l?Fg?????0??hJe??K,?.?4H??x{?? ?K?? ???X????????H??endstream +endobj +371 0 obj << +/Type /Page +/Contents 372 0 R +/Resources 370 0 R +/MediaBox [0 0 595.2757 841.8898] +/Parent 354 0 R +/Annots [ 374 0 R 379 0 R ] +>> endobj +374 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [103.0918 751.264 115.047 767.2042] +/Subtype /Link +/A << /S /GoTo /D (page.27) >> +>> endobj +379 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 1] +/Rect [373.3047 265.9638 427.3016 277.9736] +/Subtype/Link/A<> +>> endobj +373 0 obj << +/D [371 0 R /XYZ 74.4095 738.3126 null] +>> endobj +375 0 obj << +/D [371 0 R /XYZ 74.4095 720.3798 null] +>> endobj +82 0 obj << +/D [371 0 R /XYZ 74.4095 720.3798 null] +>> endobj +376 0 obj << +/D [371 0 R /XYZ 74.4095 695.5956 null] +>> endobj +86 0 obj << +/D [371 0 R /XYZ 74.4095 695.5956 null] +>> endobj +377 0 obj << +/D [371 0 R /XYZ 74.4095 669.3336 null] +>> endobj +378 0 obj << +/D [371 0 R /XYZ 74.4095 669.3336 null] +>> endobj +370 0 obj << +/Font << /F26 160 0 R /F31 172 0 R /F34 239 0 R /F50 280 0 R >> +/XObject << /Im1 151 0 R >> +/ProcSet [ /PDF /Text /ImageC /ImageI ] +>> endobj +382 0 obj << +/Length 2573 +/Filter /FlateDecode +>> +stream +x?????????? \H'??,?j??&F???? +?\??N?F?+? ?py\?&??R-?,??]::'?( ?4??7\m?r???Ep?D?U??AZ&???6(.? ?E? l???c? (?~?0??????r?0T8m????M???^???????OL? ??* ? ??WUs?aw([v?m.??} 6??Z[?$?N??J?f???k?-q!(??`???@????vv??RJ??? ???m??K?h?S????5?%? +dkO??I??m???/+&??T???%o?-?t??$?USn?!f????85?-xR??mOp? +??n{??aAr=?t?;|??- +[?e??X ??) x??l8?(?q??????2?}0mu??&o?f?????,?"???R???E? ??n???',S?1?c??$d?F??????8!???V??gt????\?"5???,??, +$C%???z.???"?6?C???RT??p?Z????u?3 +??c??????(F(?0 +?"(,p??m?4??0_???L?$?'?????.????]:???jzJ?l????q?????[?Y +??????Pu<*?????????s?0x????#.Q?t?o??????s^??~&z???:g5{?I?c??AX??l????@?o??;`??5S?2X?/?>??H6k?s^oV?l??),?EYS????u?]y?,?? ???????r! 6?????7??%] &??(bW?d`|???*?H. ??%G?F??l1?s1C???x?4?>u????u?{??i?M??N#?????KC?u?o?????s ^;???g3???S:???qC??????>???O???C~:SU ^?NR??6t??????(???\??|?J&??F??{?? J?H?$qg??0U???#??|???05 ?6?k???W??1Na????????????R ?"cmL2??S??m???]?M?#e+?=^??W!!??6?????????r?Rg???????5U?$?8k3hm?? "?x??8?X???? ?Y????.L?????=?m?9p-???]??N???G?|?c)??=~pCQ????z +?z?G???I??????M?}?pGtb]?I?-????7?`?%????I3uj??~(?~j??m??? ????p?$? ????p&DI8I??`?C?(%X> endobj +384 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [103.0918 751.264 115.047 767.2042] +/Subtype /Link +/A << /S /GoTo /D (page.27) >> +>> endobj +383 0 obj << +/D [381 0 R /XYZ 74.4095 738.3126 null] +>> endobj +385 0 obj << +/D [381 0 R /XYZ 74.4095 363.112 null] +>> endobj +386 0 obj << +/D [381 0 R /XYZ 74.4095 348.108 null] +>> endobj +387 0 obj << +/D [381 0 R /XYZ 74.4095 85.939 null] +>> endobj +380 0 obj << +/Font << /F26 160 0 R /F31 172 0 R /F34 239 0 R /F50 280 0 R /F14 295 0 R >> +/XObject << /Im1 151 0 R >> +/ProcSet [ /PDF /Text /ImageC /ImageI ] +>> endobj +390 0 obj << +/Length 2413 +/Filter /FlateDecode +>> +stream +x??k??6????E>?Qo???? ZEz?"???-???$????o?C??-?X,D?A? ?A??l??n?e?2 R7`~??? o???w fp?i=??????[?? ??_>>-S? ??????^?|??;??????y?/s?O?u???%_???\??mF^r&?L??=??P????????yk???f??????Q?FY??b7I?%.?Yzn?I???cX?g?????g?/????\??X?y:P???3????n?????-s8?o p?,???`f??^?a??Q?XH???8??j?9=F???1????27?"???-`pF??Z??????Kg}??]??n????Bj???B??;t? ?????*w{???Zt=?? '@-???-???0 ?#??h?rS??????? E?+???"?????D?????i?p}??R`???c[??(?+q?~??? +7?\?U???y~?)Z?--mH???RB?f??z"??????F?Q???? Q?R??PJX=?=?????zz>??W?g?xz2??[???X ?xxB?bNg1???F at .?m[n??Bh?$}??HR??W??????Ox?3Na???)??S?;??(?3v*?w\???{zcp???92????_)tBD???PK?9M#t?????????Y?S??]? ?w??Ec???kA???????????!a??t??GI'?,pS?E???K +?H?fn??????.Bs 6??B-???Ix?@(??T??w6?????7aT?H????w=????? /?A?U5?????? +L@~?w8???@?uW????x.t^?c???W-8 f???*??Ve#lp?z??!?[ ??x?}?????? +?? }?U????Q?? ? H?`$3bs?? xw? u?PPdq??1????,?]C?z2???yC???>?K?Rt?} ?@? ???%???&9BV???SA???????zM_?dH????@??!??'H?UemPt?D?Z??4B?G?t6???J"??7????,??? KX????%?d?s??? ??J???s?>??}j???o??V??????,k??_?j??????????j??VS?????m?1?u+ X??pS?`? ??V??-d??lL??Hs?_???Y??????%??T???%?I?7Fv????? +?F?i?q?E1.??? ????u]*?u?6?u???1t?? ml???4???sp?????H??j[\]f?~?R????Z????V?????W??g???O? wR? +????????&??\??[%o??4UmI??O??@?o??2L?C!??V>??d??S?k h?C????N5??????z??|bj*h?8?y?? +;nh'x?I??M>f0?)?`??k?!}}O??8v?r??&eU?+l6Q7??)?#????6? ?9????>?uN?f?oi6??-??0m?6FfG? Lv?H;?i\?Qfe` ?i?e??:h????????????e!?.|???p,?yB???????_?????s??w??.?`????[=???D??|??A??c??lzC?5_z??YP??c-??????7??????????V at H?\???_??`r?B[??C??+?? 4S+w?????(???wB?????X?M"%?1??dU??????$???? "???z???B ?),????u??W????&?` ???w???wb^8?\?D?o??eF??/???!v?a\???f?? U????A}?S?q???6K????Cm dk"?S_@????H??????$?L? ?q?????NW3o?2?JX??',??9N?????Qz?0sc?R?Y??0j?2?KF?}[???9NO?q8?X?L?????h?v;%vf8??XZ??~AFLW ???????V7?b???C? +?I%@U?R6?x???wB??x<=???????iw????? ?q????\1?S|?2e??D,???a)??]?`.??~{??p?endstream +endobj +389 0 obj << +/Type /Page +/Contents 390 0 R +/Resources 388 0 R +/MediaBox [0 0 595.2757 841.8898] +/Parent 354 0 R +/Annots [ 392 0 R ] +>> endobj +392 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [103.0918 751.264 115.047 767.2042] +/Subtype /Link +/A << /S /GoTo /D (page.27) >> +>> endobj +391 0 obj << +/D [389 0 R /XYZ 74.4095 738.3126 null] +>> endobj +90 0 obj << +/D [389 0 R /XYZ 74.4095 720.3798 null] +>> endobj +393 0 obj << +/D [389 0 R /XYZ 74.4095 460.2255 null] +>> endobj +94 0 obj << +/D [389 0 R /XYZ 74.4095 453.0102 null] +>> endobj +394 0 obj << +/D [389 0 R /XYZ 74.4095 425.103 null] +>> endobj +395 0 obj << +/D [389 0 R /XYZ 74.4095 425.103 null] +>> endobj +396 0 obj << +/D [389 0 R /XYZ 74.4095 164.0241 null] +>> endobj +397 0 obj << +/D [389 0 R /XYZ 74.4095 148.8388 null] +>> endobj +388 0 obj << +/Font << /F26 160 0 R /F31 172 0 R /F14 295 0 R /F34 239 0 R >> +/XObject << /Im1 151 0 R >> +/ProcSet [ /PDF /Text /ImageC /ImageI ] +>> endobj +400 0 obj << +/Length 2258 +/Filter /FlateDecode +>> +stream +x??YY???~????%?????????$ d????XPR?D?"5$5? ?????)?z`??XU????%6??c?HI5?DL??|s?????>c?&?DA??o???G2I? ?|?8?)qL???1U?????????e?]|? a???`t??,??J???ke??;??[7?i?d???e$z???????`??$!(??<5????A?????U?F?,?AE?H,????????????>?~`??S`????@>??ht%? +???5?n(????G??????V~?N?@1?QI??B??D???9%R?H??V?fL&?sF????l????:??z????? ?????????_?| ??y???j~F[e?????!?*??L>{?]xvV??c8?4?H?(9F?O??U?"?2K0?>????c?$????? + ?X??eR????Njpt]???p,???? +}6?_??5??????\??3????$? +?IY?R???#??Z~?1?)??Lz+???0 VfaJ(f?~??k??S?7???}?????4Y???%???BWi?$??X-Y?(??M?:/?????R?i????. at R??}o?O']7zK?&1?yL????????\B?PVK??"??i?fE???-?????Y?????t??m?[*T??{?@K???? Z???>?2"4 ????F?Ku?????????t??&??J??)B??k?4??(P`Ex????C5???2??C6vJJ???????j(??????~0? ???z#???)??P Q????C5??2???v?.?JL???[???+t(???{?G\d????*| 3???t}9??P??9tWd????4??o?:?6{W???Zb?????P?????$[?H-?i???imYQ3{m????>??+,???~?????l??? ????X???*?V?f?v4??I??EfZ?6;??|?j?t??????l???A????7????$?$?(\?M(???.,]j?*s iX?????aZi8W?*;s.?o??)?2U?I??????1?J?8?u??? s?????p? ???]?C?u#????uY???y??o??:???@?>}v??????#m S??l{\]?Q???/??????M#N?????????2P>?q?43??{7s?}>??????5?????? ?|ce?S?????}y.??????n??%?:??F?> endobj +402 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [103.0918 751.264 115.047 767.2042] +/Subtype /Link +/A << /S /GoTo /D (page.27) >> +>> endobj +405 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 0] +/Rect [76.7307 192.5896 106.9971 201.7003] +/Subtype /Link +/A << /S /GoTo /D (cite.PCS00) >> +>> endobj +401 0 obj << +/D [399 0 R /XYZ 74.4095 738.3126 null] +>> endobj +403 0 obj << +/D [399 0 R /XYZ 74.4095 633.8842 null] +>> endobj +98 0 obj << +/D [399 0 R /XYZ 74.4095 618.6988 null] +>> endobj +404 0 obj << +/D [399 0 R /XYZ 74.4095 255.0277 null] +>> endobj +102 0 obj << +/D [399 0 R /XYZ 74.4095 247.8124 null] +>> endobj +406 0 obj << +/D [399 0 R /XYZ 74.4095 101.3269 null] +>> endobj +398 0 obj << +/Font << /F26 160 0 R /F31 172 0 R /F34 239 0 R /F50 280 0 R >> +/XObject << /Im1 151 0 R >> +/ProcSet [ /PDF /Text /ImageC /ImageI ] +>> endobj +410 0 obj << +/Length 2956 +/Filter /FlateDecode +>> +stream +x??ZK?#7????-?@\)I??`?3?? ?d??f?,?kS????/)Rr???}(??H???Or?Ub??a?*Sy??LWes?a??w?y??i=???????)?P??\=?Vy?<?i?y???????????L??]T????Z?(x??????i?SW?U?#ut?e?it;V%?~????l??>???{%VEX?`(?Vk0#R*?*eD???????""`?s01I??.???[????F???D???+{????HC??????M?????2?E7??? +??@Qi??y?W??0Vq[?yF??qA?E???|h??]w???????T;_D???y+???k???????)?du???B???8N?8I3G??>??e?F??%?&2 +?bs1p?~??@?E&??0 ?=D@???W?9B?3@??~9 e?$+??????$8?w?wGl?7?`????nA]???????A=???^ 0Q ?!?G???YY???? ??3y?&Q?Rm?m?&Ucl?A?F???y???i?*C?~?yXS?l3t???&,?O? +X?:????;??k???7vo???;[d?o?r?a)????Z??'?CeJ&mN7$?*??Pv3??? ??%?rp?j???+?? +h(, ?? @g?S=??S???d ?? +?0?A+?i???BM?Z0??Ks?EKn?n????m???35mG_????????'?4?4o7????Kg??\/.???P@??;]??,?~?l$i???? A0?z!??A???s\+]??R?l???o?1&W?$~K??<"? #???X?$??;?,?:@'?h?t?r?f???v?g0?U?CC=.>????*?0.?k?:?zaS????????^+]???????Q$???-`< +??p?% \2?!:,(? ??[b?H +0D{ME? P? =1m?E???^?f ,?!8??????a???d_?h2P/R +??7??^??F??viax???*(ExL???? `?=?Z??Y H??\[?i ?C\t"Fk?MX*???w???H<O?l?G??????.^=?"?d??s ?t?2??)k???O?y7???Y?0???"R?0??t%?s?j????x??|?mF??;{???!?? ????*?y??4?"*???rz???'4i{m??0? +?W???_1?V.UaiC????_?~??2?w??W&\???zM??4T??U?v"-????CK???????4???Rm&M?????????Wc?y??_<0?=_????m>???g?N???????2??+0@??? [* ??ehQu? pSlm?&:$??.??? D?=Os??? y??c? b`9@?6??>)?J/N?????j?????X?\~Z???0@?h\U{ ?R?s?9P ?d??h?K???K?? e ????Tg??!?? )???g]?U?S??? ?l?X???+???g????"?????~~m?????K3?G??D> endobj +412 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [103.0918 751.264 115.047 767.2042] +/Subtype /Link +/A << /S /GoTo /D (page.27) >> +>> endobj +414 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 1] +/Rect [230.8793 150.0127 259.7705 162.0225] +/Subtype/Link/A<> +>> endobj +415 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 1] +/Rect [346.0129 150.0127 423.4135 162.0225] +/Subtype/Link/A<> +>> endobj +416 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 0] +/Rect [343.2085 140.6528 373.4748 149.7635] +/Subtype /Link +/A << /S /GoTo /D (cite.PCS00) >> +>> endobj +411 0 obj << +/D [409 0 R /XYZ 74.4095 738.3126 null] +>> endobj +413 0 obj << +/D [409 0 R /XYZ 74.4095 720.3798 null] +>> endobj +417 0 obj << +/D [409 0 R /XYZ 74.4095 85.939 null] +>> endobj +408 0 obj << +/Font << /F26 160 0 R /F31 172 0 R /F50 280 0 R /F34 239 0 R /F14 295 0 R >> +/XObject << /Im1 151 0 R >> +/ProcSet [ /PDF /Text /ImageC /ImageI ] +>> endobj +420 0 obj << +/Length 3017 +/Filter /FlateDecode +>> +stream +x?????6?>_?[8UM|&??c?w??8?z?{?}?HH??Y$GV?~???D?l? ???n??Xy??8p/ W?L\)?h??w?jk?gm??6?/w/??P? "??]%?+??F??$^?z(>9???k???7^????Rx?????cV6=?}l?????$k + Uu??e???????6?_~}?V?U???????????/xC?E???=?G?% ??nD ???;??/??#???@G? pM????????_?????9?W??? >?[?9?'??????^?=?J? ?n??H*r?$ ?????s?a?cX?v'??? ?_????M{??????@2??O=???IH?????*???????I?:?[f???? ?? ?b??>?M4?U??t????I?????=?F ??"??C7t?{??s??F?,J??r3???[?D?p?@D?l?????0?Y_? |?;d??????{??m??I0?m4B?????QY?Xu???A?YUu?eqB????5???P?|???Z[z????x??H?!I?X-f?E?(#ju??Q?n??????\t +??n?|??3??9???3?v???o?Or?p:H?b :????CX ?7?Z?]?K 98?z?$`?/n???!???????;????=?t??K??zg3?z?????H? ????C '??b?q??????'?1??v=?y??????`?N?G??B?n??Y????:!?|??C!?????????c?n?o`a``n?j}=?EH????@2????q?]:???!??? ?]W??G?????,?9.?u??*?Y7?????a???'?hA?NS?0??{??b}*??@n???jHP?D$PKB??cg??T[???? ????vkWT??~{?:??a#?bx???t?z??5d?E?~?k??;km?2 ?H????S?F?2? +???$?a@???z??$??1+:{????Q_`????R:????~Rf#?@B???????l????c?????????]o?M??@7s????P>???X?c???\?}??k??.???????`b?'#??R??O??h??'?3?w??????)?4???LI???????Qu2X?????ta??$ +?aio??? K_?.??Lo?? ?D<7???"\~3X?1??FY;a1J>8?}?n??n??????????`??|K???I????r???????????Sl??e@?Y!I??(r?H\|9?z ?E???"p?U6??????????.??????7?33?L'$??O?????Nd????}I? ,??Q4?N???a?>~????(??+ ????P?]?%+???4?!??,? .??g_S???^.@?d?_v1??l&2_cd????????,??? ?#`???;????#???w????- ??)?(M????o2??\M/d{?????7U???*?~??3g?JQ?u??%5?B???A? +?g??D???Y????8?5d?;????? +???i????Z?$????q??????^X?vQ6y?{0P?? ~V??n??E??\w? 0?? +~S?x?5??h?bC^??j8???@??$?*?Z???Xf?7+???p?????????E?eendstream +endobj +419 0 obj << +/Type /Page +/Contents 420 0 R +/Resources 418 0 R +/MediaBox [0 0 595.2757 841.8898] +/Parent 407 0 R +/Annots [ 422 0 R 424 0 R 426 0 R 427 0 R ] +>> endobj +422 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [103.0918 751.264 115.047 767.2042] +/Subtype /Link +/A << /S /GoTo /D (page.27) >> +>> endobj +424 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 0] +/Rect [424.8217 457.1172 461.0158 466.2279] +/Subtype /Link +/A << /S /GoTo /D (cite.MAC97) >> +>> endobj +426 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 0] +/Rect [114.8286 171.9095 141.9668 181.0202] +/Subtype /Link +/A << /S /GoTo /D (cite.D07.4) >> +>> endobj +427 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 0] +/Rect [486.2263 159.9543 518.545 169.065] +/Subtype /Link +/A << /S /GoTo /D (cite.TVC99) >> +>> endobj +421 0 obj << +/D [419 0 R /XYZ 74.4095 738.3126 null] +>> endobj +423 0 obj << +/D [419 0 R /XYZ 74.4095 720.3798 null] +>> endobj +425 0 obj << +/D [419 0 R /XYZ 74.4095 245.0972 null] +>> endobj +106 0 obj << +/D [419 0 R /XYZ 74.4095 229.9119 null] +>> endobj +428 0 obj << +/D [419 0 R /XYZ 74.4095 110.5346 null] +>> endobj +418 0 obj << +/Font << /F26 160 0 R /F31 172 0 R /F50 280 0 R /F14 295 0 R >> +/XObject << /Im1 151 0 R >> +/ProcSet [ /PDF /Text /ImageC /ImageI ] +>> endobj +433 0 obj << +/Length 1267 +/Filter /FlateDecode +>> +stream +x??VKs?6??W?Vj&b|???u???:?gzHr?HXB ZV}???iu:??IhPFe?cl ?$?s???~???_?T(????4*XV?|????????g??????^?uq????0S?/?/?=k???W???7>????E8??(? yK?(-Kk*???`?c?# KX???9 ?+?J?????CC?k??? +>?Jr?|IbH????%???o$?!??+NY????4?8hV?eK?|?????d?L??^?c??????K?2Mp?)??#?cW?4??B???`?TF?{??????S???F?k|??Z??2Vc??2??a/????Hqd??E'[?~C?????D?d;>????????;??6?q?)??2?=N??????" o?&???o???MR??h=??7??p?v????x?s?????nt:bsw4{?D3*W-??J +o?V^????o?ln% ?l6s?q?%!??T+?t???c?x??{???i?b? ?Do??????V??????M/AKV???V???? ??q????2?[?X???? +8??????????????k?-*??????}?x?[??9?)??? )C??d go????*?????}P??;?R,0!?-??Xt????x??X??????E(?:??i???? +7?p??] ?}+8?7W?5??F???\??u?Rw??????????J??E5;4?o??h?%?????/?????)?NV??F?MM?????~?? +s??????I?G???F6C ????Iw?N?????????R??EL??%cM3??3???????> `???]??7??q?Z?J???K?B??>?????W?m??i^?[?:O?_?%??Be*+_ + S[?, ???|^K??a/p?????nQ8?nW??.????> s??E??;?X?^T?}Z@????pC{????$???5}??Y?y????h??6???OI???????\?/:t8endstream +endobj +432 0 obj << +/Type /Page +/Contents 433 0 R +/Resources 431 0 R +/MediaBox [0 0 595.2757 841.8898] +/Parent 407 0 R +/Annots [ 435 0 R ] +>> endobj +435 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [103.0918 751.264 115.047 767.2042] +/Subtype /Link +/A << /S /GoTo /D (page.27) >> +>> endobj +434 0 obj << +/D [432 0 R /XYZ 74.4095 738.3126 null] +>> endobj +110 0 obj << +/D [432 0 R /XYZ 74.4095 720.3798 null] +>> endobj +431 0 obj << +/Font << /F26 160 0 R /F31 172 0 R >> +/XObject << /Im1 151 0 R >> +/ProcSet [ /PDF /Text /ImageC /ImageI ] +>> endobj +438 0 obj << +/Length 3392 +/Filter /FlateDecode +>> +stream +x??Z[???~?_?? ?q-??}?i?L????t?????]???2??_H?r??$-?BQ??"???b??^?g?&??'Eo????y???? ??Y??K????o>@Q?? ?`?x???'??????~?y,~???????.????~????;)??wM???*???~k???~??? n?'U?eN???I???????????b&?7;??21S?4???????Y???Q??a??z??}b?_????;w?Y?D?%_#G?????d6?L?#??Y?p?w??z????A??? ?????????,CV???i?3n?l|/?a*? ?_?D??p???oNb?}s???????d;??,-??$?4????M?????????(?`s? ?? ?8?-??ow?N????(??4l??x +???"$????? d??U??#p????}?q?A??Q?H? ?p? ???j?|????4u?T?n`(????iPO???}}>??K??'f???t????t???lj????^??Hs????0?????C??T? 2MxY ????u????@'Y?}?#?d$| ??O? j?? +?|????d?mTHZ?C?Gsj????????# lm??<3???_????8y?????????43KY?%?(q?xX?????\???\p??/{#?qo?;Bqe:hn?-? 9D,?( ?? ??(??O??(??zY?} ?}?TG?#????<? 4??????? )??I??p2' ?p?????]?x"9AZ?????? Q???M?????V#?P??[:?=?????b?K3T?X????9??^?Lgz????3????3 ?kn?p?kh? ??1?2??? ??3? ?/? +?N?t?????$d`??*&?????V0??k??\?8?????shZ?[?.???????tRm???C??f:f??&c! Q?T?????????*?????E??W????? .y???q?????-C??:1_???va???ul??(?$ox???R ???p?y2???????? ??????^? +I.?5?s??Ymj?l"?????\ ?0 ????n?*P?L????u????] ?@?T???{??+??????8?y?????(??h???b????=??(O?????m?0?????eo#???D??p???r??]:?+?M +???"yo?N?0?Ho????:KutW&??????:W4E?98 j?:???b?F?????b?????D?????i]??Q?y???kw???????#??? ? ???Ku???&|?L???;m??h????7M`.???nF?? ???T?L??>?M??CeCX'? +p???D^;?????R[6??B^?????3??????e?q?a?'???=9>Ka!?rd0??O"nU?Q?{,?F?K??Y?? &???4_1?y5o?W^??7?_?? +x-?M?^??-']??;??t@?V?U?????k??oX???s??"P`???[uj??362?f ??W36????? ??1?????j?????V??3?T??h?????????1?fU?i?Z??K?? ?? /?n?SX??;`?zX?E1?D|?}Y.^??yQW?T??!?n?????S?e'$R1x??? %Cc?u???I???)?v??e a????K??,9i??w?vsH?'? ?H? ?[?1???Km,??????B|?If?v?in? +?\??tV??|?$?2 ???.???`???P??[??????^????G??/??W?Tb. ???D?P????0??8????o???k?=L???+????t?????i??Z??8??\KX2?P1??Y???Z????!???t]??"??j?????Y?????0??A???r???%????%??+????_???i???4*?G??^?@KO?L???4?x!?j^?????t?*? +|??gm$??@??]h?aR??PUTx????//?Y ??u??? +U?_lD/??jP +L????=?????}??UO?bp?=vJ?/?`? ????J? ?+??K~x?r?x{" Z?fwle?X?YY??C?^s?+8?.?\????!&g?2?\*X?(?rl\8LCn??x?`[?n??M?rPe?)kW????Dz?$;?Q???M? +l$h??d#23?5rL?? ???? $???$Q?I?1??[???D?U??)??j??N??,?%?/???4?+ ?? ?%X^???V?Ip?????H??_endstream +endobj +437 0 obj << +/Type /Page +/Contents 438 0 R +/Resources 436 0 R +/MediaBox [0 0 595.2757 841.8898] +/Parent 407 0 R +/Annots [ 440 0 R 442 0 R 443 0 R 444 0 R 445 0 R 446 0 R 447 0 R 449 0 R 450 0 R 451 0 R 452 0 R 453 0 R ] +>> endobj +440 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [103.0918 751.264 115.047 767.2042] +/Subtype /Link +/A << /S /GoTo /D (page.27) >> +>> endobj +442 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 1] +/Rect [93.7608 623.7789 158.9001 635.7888] +/Subtype/Link/A<> +>> endobj +443 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 0] +/Rect [140.3525 584.5549 166.2255 593.6656] +/Subtype /Link +/A << /S /GoTo /D (cite.OWL) >> +>> endobj +444 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 1] +/Rect [98.3198 544.1728 122.4691 556.1826] +/Subtype/Link/A<> +>> endobj +445 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 1] +/Rect [98.3198 512.3161 158.962 524.3259] +/Subtype/Link/A<> +>> endobj +446 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 1] +/Rect [98.3198 492.4146 120.2176 504.4244] +/Subtype/Link/A<> +>> endobj +447 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 1] +/Rect [98.3198 460.5579 157.2571 472.5677] +/Subtype/Link/A<> +>> endobj +449 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 1] +/Rect [184.2664 323.9511 210.5675 335.961] +/Subtype/Link/A<> +>> endobj +450 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 1] +/Rect [327.9666 306.0421 354.5663 318.0519] +/Subtype/Link/A<> +>> endobj +451 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 1] +/Rect [374.9399 306.0421 414.7204 318.0519] +/Subtype/Link/A<> +>> endobj +452 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 1] +/Rect [482.3313 306.0421 521.8625 318.0519] +/Subtype/Link/A<> +>> endobj +453 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 1] +/Rect [73.4132 294.0869 118.9419 306.0968] +/Subtype/Link/A<> +>> endobj +439 0 obj << +/D [437 0 R /XYZ 74.4095 738.3126 null] +>> endobj +441 0 obj << +/D [437 0 R /XYZ 74.4095 720.3798 null] +>> endobj +114 0 obj << +/D [437 0 R /XYZ 74.4095 720.3798 null] +>> endobj +448 0 obj << +/D [437 0 R /XYZ 74.4095 397.8644 null] +>> endobj +118 0 obj << +/D [437 0 R /XYZ 74.4095 389.4447 null] +>> endobj +454 0 obj << +/D [437 0 R /XYZ 74.4095 85.939 null] +>> endobj +436 0 obj << +/Font << /F26 160 0 R /F31 172 0 R /F14 295 0 R >> +/XObject << /Im1 151 0 R >> +/ProcSet [ /PDF /Text /ImageC /ImageI ] +>> endobj +458 0 obj << +/Length 1477 +/Filter /FlateDecode +>> +stream +x??XKs?6??W?H?D4?H????8?4N?iI [h?PH???,?JL?t::?.???b)??Q??^H??aA?????Z?h?.??Y????f????% ? ?}g??$? B??K9????x|<.W~D?;?z?v? +(q?6u????{?}l?Q??KVz?WY???>-Y????????}@??Kc0gf? `J????I?.~Y?PlI&F???q??JR??y??<?W?????K??v?_?v??,??5????W??=?????g???h?O??aaxQ?JQ???$??o?? d????@???a??)1?7u????????P? ?)????KX???_?S????4????p??S-?0??(ff?\|\?dZTut*??O?$lN?zi)?U@?G?|G??%???????u????l????({?7???eJ???wV?6?ziHC?f???P??-?????-?5????J]??v??????????-?E?? o?!??D?n.zP?!uz$ +??????????:??geix??wM?H??tO?I8t??|?aP?" ?n????V?^ods?{?M'!,+?iq??e?R??4?b????K??|X ??E?5???*sL????h?y?%:?7?Yt?9@???^W?lrcQM?????????}G?Z?z?DE?????????O??T????E????z???fD+E? x?jwT)??H~??_?,?r??[??M??B??4??????? ???"?? ???6???S??e??kL????7???C????W????????{??K????L???(??u?!.?."e????7~\RJ? I??`???I??d?3???9??D3????F?????}f?0?????????vt?d?[?h??????g??8?3??PCMt|:\S?;,(??????kr??r?2???yM^?s?d<$K?1?[?j???[M1????????????Cxp?){??????B?C^??????? >t???[U??bFl}8???X?????W?_?D??Fb??? u?8M??%?:????\j?-Y?h*8od,{n?7??^7G???c*??G???Dyc>?u?*????H???)lh?/???r???3 ?e! N?????n? P?TL>??????.?N??b,uwPw??Q???S??,n^?[??1????S?1?V??\????_+2ey1????X???> endobj +460 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [103.0918 751.264 115.047 767.2042] +/Subtype /Link +/A << /S /GoTo /D (page.27) >> +>> endobj +459 0 obj << +/D [457 0 R /XYZ 74.4095 738.3126 null] +>> endobj +122 0 obj << +/D [457 0 R /XYZ 74.4095 720.3798 null] +>> endobj +461 0 obj << +/D [457 0 R /XYZ 74.4095 700.3481 null] +>> endobj +462 0 obj << +/D [457 0 R /XYZ 74.4095 700.3481 null] +>> endobj +463 0 obj << +/D [457 0 R /XYZ 74.4095 648.3651 null] +>> endobj +464 0 obj << +/D [457 0 R /XYZ 74.4095 633.1797 null] +>> endobj +465 0 obj << +/D [457 0 R /XYZ 74.4095 575.7551 null] +>> endobj +466 0 obj << +/D [457 0 R /XYZ 74.4095 560.5698 null] +>> endobj +467 0 obj << +/D [457 0 R /XYZ 74.4095 517.6956 null] +>> endobj +468 0 obj << +/D [457 0 R /XYZ 74.4095 502.5103 null] +>> endobj +469 0 obj << +/D [457 0 R /XYZ 74.4095 405.8379 null] +>> endobj +470 0 obj << +/D [457 0 R /XYZ 74.4095 390.6525 null] +>> endobj +471 0 obj << +/D [457 0 R /XYZ 74.4095 347.7784 null] +>> endobj +472 0 obj << +/D [457 0 R /XYZ 74.4095 332.593 null] +>> endobj +473 0 obj << +/D [457 0 R /XYZ 74.4095 307.9107 null] +>> endobj +474 0 obj << +/D [457 0 R /XYZ 74.4095 307.9107 null] +>> endobj +475 0 obj << +/D [457 0 R /XYZ 74.4095 282.9693 null] +>> endobj +476 0 obj << +/D [457 0 R /XYZ 74.4095 282.9693 null] +>> endobj +477 0 obj << +/D [457 0 R /XYZ 74.4095 258.0279 null] +>> endobj +478 0 obj << +/D [457 0 R /XYZ 74.4095 258.0279 null] +>> endobj +479 0 obj << +/D [457 0 R /XYZ 74.4095 233.0865 null] +>> endobj +126 0 obj << +/D [457 0 R /XYZ 74.4095 233.0865 null] +>> endobj +480 0 obj << +/D [457 0 R /XYZ 74.4095 205.6426 null] +>> endobj +481 0 obj << +/D [457 0 R /XYZ 74.4095 205.6426 null] +>> endobj +482 0 obj << +/D [457 0 R /XYZ 74.4095 103.2436 null] +>> endobj +456 0 obj << +/Font << /F26 160 0 R /F31 172 0 R >> +/XObject << /Im1 151 0 R >> +/ProcSet [ /PDF /Text /ImageC /ImageI ] +>> endobj +485 0 obj << +/Length 1791 +/Filter /FlateDecode +>> +stream +x?????F?=_a????F??.j????M????? ??a??g???-^??Z?f!?/??^&?????^?!???)????b9q?J???r?????{?~[? %r?????{f???w ?]o?C?S??'????}q?????I??:?Xf?Y?EDNF?9)?=?I??z??D???????+&??C7???xK???/??R?E????U?\?????z????A???8i???????W??M?xE?????A)?SIQ????e?????v'hS/Yb ??J?t???a+i?hT?)??Y?LS@???g? +"?#YdM???cN??4?C!?F?X ???hZ(?c????I?Jc?$m2??????H?F???-???ZN%5???X? ???????|?1?5???W?zP?vlC??L??+?^????????W??)?QO;^??zw*??0??i?3q?Y?dm ??k??)?????&S?3?????|?8????ks:o??DV??>6"?GcO?1s)?Jf??D????,???c ?J?@??S?L|;???????!?J ?a??jf?:?hNK?"?? ???))PT????)?5????=???&??\?????':@?Pe??.?&??$?3!?xM?O?1l?q?k???d???w??xC}?(y?\mg/aSB8?(?6?v8?? o?-8????6???KN3%C ?$5-NuKd +?^?j?8@?*/n?|5?#/?Ri`X??OC388?Z??_?,??Q??????orNU???@O[ +H"?`??s??u?J?8??>A??G?|?1???????@`\??+??j ??????GFn?c????*?o KM:$L?????}???"E? ??@?L?????iG??n?I?e?????????????|??w?1????4??x`????#?:-S?6???\?}WTp??=?0???(???(LXa8???`?#6????X????#]????N1?$??? I??M???9=???v????s%{??M???r/Fjsm.?????b45??ueF?qF???????] ?????{6}??????N?26?``???D9{&??????9`A??`??4?'D?zA?W?U???+??gx?????_hyQ ?JQ?9-?8??X7?'WN)y?u[?B?}dpxy<:?]??B??#??.5B]@??y?????????YaU?>~M*??1VH~?cF???4?b?H????G????27??I???,? ?????c??????1dq????I)?c???????k?E? J???N??U????\ H?"S?yNi?LV??sFO~??T????zN???;K9W?3?a>(??hL??????u?~?h>??/Q??????????????4????m????/ee??endstream +endobj +484 0 obj << +/Type /Page +/Contents 485 0 R +/Resources 483 0 R +/MediaBox [0 0 595.2757 841.8898] +/Parent 497 0 R +/Annots [ 487 0 R ] +>> endobj +487 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [103.0918 751.264 115.047 767.2042] +/Subtype /Link +/A << /S /GoTo /D (page.27) >> +>> endobj +486 0 obj << +/D [484 0 R /XYZ 74.4095 738.3126 null] +>> endobj +488 0 obj << +/D [484 0 R /XYZ 74.4095 720.3798 null] +>> endobj +489 0 obj << +/D [484 0 R /XYZ 74.4095 646.8009 null] +>> endobj +490 0 obj << +/D [484 0 R /XYZ 74.4095 631.6155 null] +>> endobj +491 0 obj << +/D [484 0 R /XYZ 74.4095 576.7862 null] +>> endobj +492 0 obj << +/D [484 0 R /XYZ 74.4095 561.6008 null] +>> endobj +493 0 obj << +/D [484 0 R /XYZ 74.4095 482.8612 null] +>> endobj +494 0 obj << +/D [484 0 R /XYZ 74.4095 467.6758 null] +>> endobj +495 0 obj << +/D [484 0 R /XYZ 74.4095 415.4418 null] +>> endobj +130 0 obj << +/D [484 0 R /XYZ 74.4095 400.2564 null] +>> endobj +496 0 obj << +/D [484 0 R /XYZ 74.4095 130.9066 null] +>> endobj +483 0 obj << +/Font << /F26 160 0 R /F31 172 0 R /F34 239 0 R >> +/XObject << /Im1 151 0 R >> +/ProcSet [ /PDF /Text /ImageC /ImageI ] +>> endobj +500 0 obj << +/Length 2805 +/Filter /FlateDecode +>> +stream +x??YYs?8~????JUC???l9?$?????N?!?D?7???=?_???IQ?T.q4?@??$V6??U?Y?????,W8?*)???#?}?L?5D?)???????)?o? ??p??>Gx???????L??%?G?!?Wt??j?l?u/???c?G?|???? +?0???ZdE??????U +??? +?G??u???*?????8??Hs?`?.?h7?\????h?????K-?G??;v?uV? W?@??eZ?]?q4F.\?=^??2S?+?3@?c??uu???2???A?XgF8F?)???:0????.*??z????Xh????h?}???e?hG??0Z?Q????uw/? ????i n?)? ?)????A+.?IK????FF?7??c?w????u?Mu.;TEVR???w?l?L?sj???J????V??g????.???m???O%z???P???h]???P?`??Ok?q?T??&Z,w?.??n*??'y?\R?????p??l3V???\?0?:?????H?/??Y????E???:?g???=t?8?/ ?S at 4?LJ?3?d#p?p?hP4zX"??'J?????Q?g??&?}?2P???? ?? f??=h?{?!????? ???`??P?? P ?c?#J?P?H???(??D??f?Jq???F ??gxb????k??? +m??*4/?J??LP?\Bc?@$????V%I?????L>[/|S?&M?????%m7z""?????????c???D ?O?? ??uK?Rv}?u????)?O?B????Z????R? &?n?X??_?Q????ID?c:b?tS???|??E2O?p?3?|I??,;r?C?~??]Q??%?8?OV??????P?????t?*?endstream +endobj +499 0 obj << +/Type /Page +/Contents 500 0 R +/Resources 498 0 R +/MediaBox [0 0 595.2757 841.8898] +/Parent 497 0 R +/Annots [ 502 0 R 504 0 R 505 0 R ] +>> endobj +502 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [103.0918 751.264 115.047 767.2042] +/Subtype /Link +/A << /S /GoTo /D (page.27) >> +>> endobj +504 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 1] +/Rect [135.2044 638.6406 178.3191 650.6505] +/Subtype/Link/A<> +>> endobj +505 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 0] +/Rect [371.0337 537.9881 398.1917 548.7277] +/Subtype /Link +/A << /S /GoTo /D (cite.SPQL) >> +>> endobj +501 0 obj << +/D [499 0 R /XYZ 74.4095 738.3126 null] +>> endobj +134 0 obj << +/D [499 0 R /XYZ 74.4095 720.3798 null] +>> endobj +503 0 obj << +/D [499 0 R /XYZ 74.4095 695.5956 null] +>> endobj +138 0 obj << +/D [499 0 R /XYZ 74.4095 695.5956 null] +>> endobj +506 0 obj << +/D [499 0 R /XYZ 74.4095 440.3841 null] +>> endobj +142 0 obj << +/D [499 0 R /XYZ 74.4095 433.1688 null] +>> endobj +507 0 obj << +/D [499 0 R /XYZ 74.4095 360.4068 null] +>> endobj +146 0 obj << +/D [499 0 R /XYZ 74.4095 354.016 null] +>> endobj +508 0 obj << +/D [499 0 R /XYZ 74.4095 145.464 null] +>> endobj +429 0 obj << +/D [499 0 R /XYZ 74.4095 139.6512 null] +>> endobj +300 0 obj << +/D [499 0 R /XYZ 74.4095 107.7708 null] +>> endobj +498 0 obj << +/Font << /F26 160 0 R /F31 172 0 R /F14 295 0 R /F50 280 0 R >> +/XObject << /Im1 151 0 R >> +/ProcSet [ /PDF /Text /ImageC /ImageI ] +>> endobj +511 0 obj << +/Length 2756 +/Filter /FlateDecode +>> +stream +x??Z?r?:??+T5???"?>?N?qbO?7Y$Y?,qL? +I????i >@e? ?@?????N?s'?g{ND&m?"???9?-????Rf?????????kxt={>?<? +????Z??{ ??w???;?X???~_??S?????B?D?yi`???|??ES9r????U???a??[?????Y?5l??{????????d ??^^??? f?uU?h???&??X?2S\KU/?w72r< +\s??????cb??q^???V??$&?v??C?????`?PN2?g??????N?]??$>$?2;K?#??Ih??N(_?Q??????G?Y?c??????????%h?r?!BK??v???JN????Y???????? ? D?L@???I#?H??1?????1Go%???R???????0>??n??~p6(????wC?Y??????(r <9?ob????1??!???z!?JP]?L?;? &??CD???K?????????x?:W,~}hob?|nK?,?]5G??z???c??Vm?2?vr????f?????"???u}?D??K?????>[???b????blW_??an^n?_h??t +C??7h? ?B?C???j??I>?b?,??l2c???tq &??$+?-??R??s?????|???V4,? ???6v?~!@:??w??:???W~o*;???*??y??S ?S at 05u???????c??mQU??]?A??-?v? _?K??F,EIU???u?oLFqK??,E?g{???????@[I?;?<;???OY>????-????M?&)1^?`n"?{???.5B??u?|??O?Q???.??x???????/?z?1]/?Aa??P0??E????u)??k)???;?u?VpwX?-`????:B?????oHhLjn???W??cL??u?# ???C??x!(2???MhD?R????owf-?@6J?@t?a$??????=???i? ?7???[v?p?f??7?? ?c????=f9????,???c??P%?w??????Te????WS???????[???Ma?^?G?o}?s?'?l~??d.???e?0? ???u???:??S}@????|????^????Q?SJ??AG|??\??_?k??? #?E?? p??b????T?!Eo6???B?^%> endobj +512 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [103.0918 751.264 115.047 767.2042] +/Subtype /Link +/A << /S /GoTo /D (page.27) >> +>> endobj +514 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 1] +/Rect [297.725 256.3002 521.8625 268.31] +/Subtype/Link/A<> +>> endobj +515 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 1] +/Rect [121.353 245.5206 190.8922 256.3548] +/Subtype/Link/A<> +>> endobj +516 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 1] +/Rect [257.7505 212.4645 453.5344 224.4744] +/Subtype/Link/A<> +>> endobj +177 0 obj << +/D [510 0 R /XYZ 74.4095 738.3126 null] +>> endobj +265 0 obj << +/D [510 0 R /XYZ 74.4095 722.3723 null] +>> endobj +298 0 obj << +/D [510 0 R /XYZ 74.4095 690.4919 null] +>> endobj +266 0 obj << +/D [510 0 R /XYZ 74.4095 670.5666 null] +>> endobj +299 0 obj << +/D [510 0 R /XYZ 74.4095 638.6861 null] +>> endobj +301 0 obj << +/D [510 0 R /XYZ 74.4095 606.8057 null] +>> endobj +302 0 obj << +/D [510 0 R /XYZ 74.4095 586.8804 null] +>> endobj +303 0 obj << +/D [510 0 R /XYZ 74.4095 566.9551 null] +>> endobj +321 0 obj << +/D [510 0 R /XYZ 74.4095 523.1195 null] +>> endobj +323 0 obj << +/D [510 0 R /XYZ 74.4095 491.2391 null] +>> endobj +322 0 obj << +/D [510 0 R /XYZ 74.4095 459.3586 null] +>> endobj +324 0 obj << +/D [510 0 R /XYZ 74.4095 439.4333 null] +>> endobj +325 0 obj << +/D [510 0 R /XYZ 74.4095 407.5529 null] +>> endobj +326 0 obj << +/D [510 0 R /XYZ 74.4095 375.6725 null] +>> endobj +430 0 obj << +/D [510 0 R /XYZ 74.4095 343.792 null] +>> endobj +333 0 obj << +/D [510 0 R /XYZ 74.4095 323.8667 null] +>> endobj +513 0 obj << +/D [510 0 R /XYZ 74.4095 303.9414 null] +>> endobj +455 0 obj << +/D [510 0 R /XYZ 74.4095 284.0162 null] +>> endobj +240 0 obj << +/D [510 0 R /XYZ 74.4095 240.1805 null] +>> endobj +509 0 obj << +/Font << /F26 160 0 R /F31 172 0 R /F50 280 0 R >> +/XObject << /Im1 151 0 R >> +/ProcSet [ /PDF /Text /ImageC /ImageI ] +>> endobj +517 0 obj << +/Type /Encoding +/Differences [ 0 /.notdef 1/dotaccent/fi/fl/fraction/hungarumlaut/Lslash/lslash/ogonek/ring 10/.notdef 11/breve/minus 13/.notdef 14/Zcaron/zcaron/caron/dotlessi/dotlessj/ff/ffi/ffl/notequal/infinity/lessequal/greaterequal/partialdiff/summation/product/pi/grave/quotesingle/space/exclam/quotedbl/numbersign/dollar/percent/ampersand/quoteright/parenleft/parenright/asterisk/plus/comma/hyphen/period/slash/zero/one/two/three/four/five/six/seven/eight/nine/colon/semicolon/less/equal/greater/question/at/A/B/C/D/E/F/G/H/I/J/K/L/M/N/O/P/Q/R/S/T/U/V/W/X/Y/Z/bracketleft/backslash/bracketright/asciicircum/underscore/quoteleft/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/braceleft/bar/braceright/asciitilde 127/.notdef 128/Euro/integral/quotesinglbase/florin/quotedblbase/ellipsis/dagger/daggerdbl/circumflex/perthousand/Scaron/guilsinglleft/OE/Omega/radical/approxequal 144/.notdef 147/quotedblleft/quotedblright/bullet/endash/emdash/tilde/trademark/scaron/guilsinglright/oe/Delta/lozenge/Ydieresis 160/.notdef 161/exclamdown/cent/sterling/currency/yen/brokenbar/section/dieresis/copyright/ordfeminine/guillemotleft/logicalnot/hyphen/registered/macron/degree/plusminus/twosuperior/threesuperior/acute/mu/paragraph/periodcentered/cedilla/onesuperior/ordmasculine/guillemotright/onequarter/onehalf/threequarters/questiondown/Agrave/Aacute/Acircumflex/Atilde/Adieresis/Aring/AE/Ccedilla/Egrave/Eacute/Ecircumflex/Edieresis/Igrave/Iacute/Icircumflex/Idieresis/Eth/Ntilde/Ograve/Oacute/Ocircumflex/Otilde/Odieresis/multiply/Oslash/Ugrave/Uacute/Ucircumflex/Udieresis/Yacute/Thorn/germandbls/agrave/aacute/acircumflex/atilde/adieresis/aring/ae/ccedilla/egrave/eacute/ecircumflex/edieresis/igrave/iacute/icircumflex/idieresis/eth/ntilde/ograve/oacute/ocircumflex/otilde/odieresis/divide/oslash/ugrave/uacute/ucircumflex/udieresis/yacute/thorn/ydieresis] +>> endobj +313 0 obj << +/Length1 1620 +/Length2 7655 +/Length3 532 +/Length 8509 +/Filter /FlateDecode +>> +stream +x??veT???.???k(ww?b!@q $@ HCpw(-???@?wwZ(Z??k?X?\????????u??u???x?|?|????P7?`?0?????3lwE@??N/f??rF?????T????????"?D?O??k?_??{??N???@? ???A??1 ??Kn???!?p????wO?_U??l????????l????? +wU?{??`8??`A????]? +C"?N?;M???????7???????????`N???'???y?*?`??~??????z????$???.~???;{|??Dx\?Bw????? ??????k? A!??^n^^>??????Z???F????{??? N??M?O?o?? ???????k??????Y???8[K???e????s?GM?;???????}VT???# -??X??uew????&?O{.7j????d???a>?#[W?s??f0??k???/}??5V? ??o??j???\c??? ????? I??\?[???????W?}eN?9?c???????k??#'(?~??9:?y???^?RE???????????k????????E???-?????????li????K??x??E???I%/%??l,?]?~!?fcW???B ????aR+<;?+?,X????C?NM?cn?????o?? +?H?y???*????y??0??????? ??YCWD=???l,??,???Z??V)?p?d&%? jT???9?1??}??/????y???ngd??+k?????m?G?-(?q?Y???Q?+?C??@7?!???U?a? l??? +2?$???siE????y~??A??Z??4?????B ????1?k0???????? \?v?3? :E,???????Y??H y?}#6?A??Fa3??/n?????Y=??j5????!???Yr??_?#Yg?h????~??i?Ma??????/( V??? W?Vd????O??&b?~]W???M?m)?????(???????,???????G???D????\j?S?f?B???I?CZ?f]??wh?Fi????r?V"?Z???y?GQO?X????6?-??%Ohb????L?? ?I??R\???a?x_?y?6 U?????x???JN???o?Yo?:?@??AX??G???? ?]??b7???P???[?K ?A??@}?+?j5????ez?XY%r?R?I?V???6??????h?y 6?K?I?F??R??? ??>???YK??k???7??-?Ar. ?_???C????,H?BF8q5?? ???xX????l??wp4rv??bLs????5???ZV???wn??i9?Z????Q{?(?`??0??? + +X??sKL? ?d?H?K?Hg(??&?x????_????%??C??6?#!????T?MN??[??,??i?5????D?F?(=ZH??O1??????tt??D????Eq\?k?'?d???&?????pp?+?8?{?_ +FP????Wq~??_?u:5?n???[??R?????n#??????$??????m????k??"#??.????b???? ^2????Dd??t ?#???m?l+???5?f??f??BoI?f???8???????)?????$???r? ???G,?|?.x?z??$?9???5???3???vi?p?? ?8?n??????rV1??? ?f??g??@~??5~r???? +?a??/C?b!T?i?{K????YG?-???f)U??a???@??U?x?u1?h0R?\|aV??r?8 ?+p_?a??9??Z???????l???"iA????gEj?+.J?#A?~d'??+m?????+>??v]???+??T?V?v~????=jr??O???????K???|%?rf?c????bk???????{?????% ??????rZ??W??@??z5?tw??vD????A?b?^Ff??????H?c?/?_;??(R??8+?4??e?o??B?ej?x??????-?*O?9E}??????Izp??JN?????k?f&F??o?]#?gNG`???zp????RbU%???L??4???O?)8??p8#Hf??????????????u?Wu?F%?F???f?#?=4????@L????O?B????*?.e6?)}??h???1??vL????M?Q????h?y}K?? +??]QTz?sQ?????g?`U???????U ?$Dk\????? *???4|??i`????>J??????#?K31??P??{k?L?6?r?G}?l????-??????Y?n????7???6 ?kMG?f??7?????g???????o??^p0?????/????????=??L??????k4?@S??4?^? pT?{?F`?R? K.?)UN?uh??2ihj=???????Nxn< +Hk??V?Q??+J?(???1}I???4(??Q??????U?A?z +CI????v????M?????6??e????roBu1???'?g?W????/m?????I??I,J:???`??Y?}hN??V1?2??X1?pH4S?c?i??T?n?c??*??J??J??"?T??? i?R?^???o{o???=??x??? .?{??B}s??'?ui?v?|5??0p$??A?)???)qH;5 ???!N???6??????? ??1??a?W?3??I?? ?'y?Ne ???????i?:b??~?J +??lS*!??q???t?$??h??T?!?v(?m;?v??# ????????v?????}!???45?C????{V?????? ??<9[?n$????8M?t?y ??????~L?[+??????Z??XF??8j?%??%??>??)i???R$_??@?|n?????3?:??v????U?f??;?? *7???7I '???Y(Or?,??8????(???|*vbI??&jg?????2???; ~?|?.?????????^??3>?g7???d0{????XtF????He???????? +?C??G????!2'(???W?^v?e1??&d@???y?\K?7X?5>[y?>8????t? '?^B??d????(W&????WZ??m5~4|??I??????&?0?????C?_%????+,??|???>f??h?.??}??P?w? ?N_?u???)?????^???*|m&H????%??g?\.?$?32P-V?lK!????]ks?nl????$????)?b?????H?? +n????G?2/QN?' +sL&fPb?{?I?ER.?Kr/?:?????U??Y?Hy?f?b8??{y- +,gL?Hu??Rw?0{??'??B?:???0??????>?Io?`??l8N5? ?Nn)???????????D?W????D +::???}?1zK?-T????????O?#??Ik?fs?$l?UN??y$ ??Zj??7bR??%5E????????m-o<4v ??P??H?Z????K[+?nw|?????!?)#?G?l*???7?????.?|^?/?????(?v?D?b?3OLxV???S?C_96g\????,??????QTi?T??'?Ig$5ZGeJ?8??^????iB:B_????M??`??`???D???D???????:?.&???6!a???YA?{S??\u???Vv?Xl~?8??|????&?? +???\)?????/4j???y(qN"??)$!'?cDY?L?C????r??R??c?i?u*yu^???D]?KD|?d?@?2b?`????:j?F?e????.?P?]????D??jY?$%I?s????r?D?Rn9?t*???b:??pV?H???^ ???c?kQ +?`F/????jXR C??'~H?f????|j?T?????{h@?d?La??d7JaY??W M? +Hf\]z??????3????'?r~?>???U?4*?/?:???]"??}G????4??Z?-A????s?F??|?,*?6???b???Un?TOH?_?-\??D???'????B?[jN3g??yB?_??wf?|???????????????J.A (?'????].8?T???JO????]J?R??l?n'?? Jz1m?q?b/;???????i ?S?S??????Z? ???a??|1M???????-f?????????!???G?R2v?y??Vo?"?????O????1???d?^?t???Y??kB ?N??-D?e?????6M??W????D?4D?>??T?'F?????*??"? :=^?e?B???T???z??k?.a[K????N(?j?|??!amd~????c(????)?)?@?????????!????b??)q,t???K????? +?:#????E??q?G?*?-? <(???< ???;K=??[ ?Roz??,??M?'?YEM?Z.??C"Y?v?,?{?I9???D9??????u???????o?lB,?????????Q?h?n4???V??Wz?pQ??????(?????????I?d+R???#?????F,^????? ?? ?F? H??#?????Y?endstream +endobj +314 0 obj << +/Type /Font +/Subtype /Type1 +/Encoding 517 0 R +/FirstChar 97 +/LastChar 121 +/Widths 518 0 R +/BaseFont /PWGXPC+URWPalladioL-Ital +/FontDescriptor 312 0 R +>> endobj +312 0 obj << +/Ascent 722 +/CapHeight 693 +/Descent -261 +/FontName /PWGXPC+URWPalladioL-Ital +/ItalicAngle -9.5 +/StemV 78 +/XHeight 482 +/FontBBox [-170 -305 1010 941] +/Flags 4 +/CharSet (/a/e/k/l/n/o/s/t/w/y) +/FontFile 313 0 R +>> endobj +518 0 obj +[444 0 0 0 389 0 0 0 0 0 444 278 0 556 444 0 0 0 389 333 0 0 722 0 500 ] +endobj +294 0 obj << +/Length1 750 +/Length2 576 +/Length3 532 +/Length 1110 +/Filter /FlateDecode +>> +stream +x?SU ?uL?OJu??+?5?3?Rp? ?44P0?3?RUu.JM,???sI,I?R0??4Tp,MW04U00?22?25?RUp?/?,?L?(Q?p?)2Wp?M-?LN?S?M,?H??????????ZR???????Q??Z?ZT????eh????\????????r?g^Z??9D8??&U?ZT t????? +@'????T*???q????J???B7??4'?/1d<8?0?s3s*?*?s JKR?|?SR??????B????Y??.?Y???????????kh?g`l +??,v??HM ?,I?PHK?)N?????;|`???GzzziC?,???WRY??`?P ?"??P*??P?6?300*B+?2???????t#S3?????J.` +?L? 2?RR+R+?.????/jQM?BZ~(Z??I? ??% q.L?89?WT?Y*?Z? 644S077?EQ?\ZT??WN+?????2?A??Z???u?Z~?uK??mm+?\_X????????7?D?????Rl:/P1?d????????(??l=U?h?d?_O??E?k?v-X1??t???`????i????_y. ?1?????????:?un~Q???3/??S??}??]?? +???$e~s?]F1????/??Q???m????|<?????/??q'}I???+6???E??g???xT.??G??gt???v??G??U|?????~??]?R????_k?9???:?{?p??G?? ??d}dN<6??-uB?o?H??=c?M?vH??z?q?a???RK?~,K???}????????m??????yo??~?????v? +?_????s>???.#????????{?/?????k????\m?|??r???X???????ad?j|?????R/?,2?p?0, H?IM,*??M,???r?endstream +endobj +295 0 obj << +/Type /Font +/Subtype /Type1 +/Encoding 519 0 R +/FirstChar 15 +/LastChar 15 +/Widths 520 0 R +/BaseFont /LSYIIJ+CMSY10 +/FontDescriptor 293 0 R +>> endobj +293 0 obj << +/Ascent 750 +/CapHeight 683 +/Descent -194 +/FontName /LSYIIJ+CMSY10 +/ItalicAngle -14.035 +/StemV 85 +/XHeight 431 +/FontBBox [-29 -960 1116 775] +/Flags 4 +/CharSet (/bullet) +/FontFile 294 0 R +>> endobj +520 0 obj +[500 ] +endobj +519 0 obj << +/Type /Encoding +/Differences [ 0 /.notdef 15/bullet 16/.notdef] +>> endobj +279 0 obj << +/Length1 1630 +/Length2 17317 +/Length3 532 +/Length 18242 +/Filter /FlateDecode +>> +stream +x???cxf]?-?v???m[??m?V%?b;???T?T????=?}?>??????k?9???{]??DY?A???(?`?????? ?P?R6??56?r?gPu?3?5s?QP?9?]????]??-?@h +`e?????Q????,,]?9h??????? ???????.V???/?@[G;???_???@5 ?j ?[?bJ?:2?Rj)E ???ll Pv3??2?[??]?4sg???S{3?Zsa??%?0?8M???=M???@?G???????w?? ??????? \V???nf???n??????z?????);????:[9??fU??w???????v?? ??z?9????????4QWc+{?+????\&@??????????????U??????U@pZ;??]\?????g:??'????????_??????\]????p,?s????mae???????;X??m7ss?????Q??34?06s???????\??P??????'?????#?????O???????????;????????_A???c??.?????????????=???.??J#?j?w"??`?ad?f??7`?"i? 4S?r5?????????f at g[+{?_M?5N 3???-?Lm??>??!??????L???IBSU\U????W?l???! '??#??n????#???i)8????>QQO? ''?????????ag????????]??<z????,I?y2???? ??F#ao?`????????]??4???9;?U?_7????????=??pk??|????2\????'???{Y???K?? +kz~D??T???16M?~?y-?9~????b?R??? +??h? +Q?(;????? J3??b}??w t9?5??&UT J???;??a??h?? 1???M?0;Q?@??~??S??<=R ?? ??B????&?R??C R?:?? ?jTHT?j?????2??\??Ur? ?j~Z ?H????? +?d9`????????????>?q?b??9?? ?f??U??K'?s?s???H??FT?n7W?%P?T??Z??g??e??g at KRS???N?4=????"?????E:????????M?]? ????????:?????/?qV??.?3??8?{??????l?vW??? +???5?!?y?]Z?7??f????G1???5Zz????'%??i??Z?|? +???#?xj?<XV^h???RMY? z2(?"?uk{?K,?????R=?w?8??  +|??G??T?????2?qf?`p(5!~B????t??????5u?`hi????U&t????Q?u[??m?l????F?a??g???w9????j?'????f??$???G?;???~q???87b?????Y??"??.?oq2?7V???????Z??\ ?E??>4A:h??!}?E5T?k~)???R???U???"?J~JSj?f??U???&M@&????????P?ln?|??????I?????eGX?bj??"u"Qjc??>t???Iw%????_j?](D`D??a?]??fN^+A??u???x&n?#?N?????' @?? ?R??????D??1??? ??7!???????D??j???x +"??,??!w??<$9??Z?#??h???-|D??g|???[??^??K??pX3? ??]?i?|#??c5?B'u;?U??o:??%??Eme??ynbv????B?z ????P??O at v????>???tEB?_???!??-fzg??^G?@??A??^???? ???pg??,b?5y(?w??(x?.D<y??q?Za/ya??4l ??S????cM?x???3??M???Z!F2j`?jD?}%M[+???B?5I????l?Na?P?K@???{?=?k?y?d? ??s???GY7???V??0LEu??? ?V????[???Fru???d??H? dQ*q?w???????A??9???I???]??? ft??vj?5???????4??;?>?(?`04?Y??G%e]F? ??(+H???z$???R??????_? ???u???1??P?h-?o???????~j??Y???????!^a9?????J?}F??%?c^?r?lC?????u??F?AQ???@?|9z?k,P?)?`?????N?%l?Cz1e.?Z{??C?>?&?w?(???$FI?&??;d_1R?$?Ad???w? f?] +??M????L??;|/?G?x?h????27?!?&#?)????K?Y@??(??????%)?????/6?????$i??????_?#]?lZXe?Lu1sa???+?R+?????????/=?fvN(Vs???? ?g6d?|$???E3_??????n_2???&??c?Q??R??<??K?@#!41??,s???????*???_K???f6??7_ ?RHg??????1???F?h?:M????m??????????,s???????P?Rq?????3?!N#M?EHU?????O?R???!???6????;?{???4?j{Tmu??Q????? +???H ??C$?\M????Q?3????%??H???s{??aQ?a?*??h??[?{??R??%{x?Aa>???c??O??OA?!????]?#k????4~?_?e????D?[??j9??d??d?z9[S??Yu??t1~=???U?aXex d????d?i=??3???Ry?x?z{??m??.d~U?pJJ,Y'*?Q?j?h? ??'0%????jc???.???|C?0???????=a?????U?+??q|0?j??zt 3?v????z??^#?E?(???????QA???? +~R n??] W?%?? 2??i??]?a?N?~???6\*IB0OPB\???9z?o??Y????A?c5??&&????B???Z6?l?@?S8k"?n?? h???Edd?H???W???.??&?????K?????'???-????{??????3?1CS ??????$??m?#T?7??]??\???Tt???????q?X?< ?(W???[w???I?>#?n?/?K???????:fgUzcrqa ??Y?~?O???Fpt??? ???9??8??? jZp=ya9)???q?,?????TCM?'~&? ???^,2{??{P??7??Q???M?,?n???L?:N?`?/!??EkH??t?e.O+0 ?.?v????8?8?????Q???? ?;}}????v??>g???? ?Br??????h"Jw"???G?|?????J????y??x?U???[r?4?/_,?0xD?7S?C3ZJ6?6??%-??-??3????WoK?Fq?n?<8k????4????B??G?Ea????p???kH?+??B??????Y???m????9???0\?Q?7F?????????M??3???X?W?????n?=?:???C?3i;?d +O??=?>???J?D??"???h#%:3?????????_y???Z??Ub?nXHt?~u%??1???<~fNkO?J;.L?3??W??~??MAe;uc?U??.&Y{\S??xL?????)@??j??b?T?"D?7????Hc??_?? w???).? ???j"g?{)p?&???_VX?~H%?9=??K??M??T?*??A??y?< -?????l????+?V*2[???Z?C??w*?? <*??03??????(?!=?Z?)?]??k??g?2??RP?? ????IO???hY?N_O????)?O?Q?n?(~???*??C???;??1?4?U?`????????? +0?n?????YT??? +????z???? =?? +=??+?MK?p?7?5???&?=? 5??0d?#???$????T5b???b# +???|vU??pn?/?????? F???????X??L?@g??y???n?????P'???Y'^ ?????r? ?W?cR?@?A???????????3!???S??? Q???B?Bc??j??Q????@?? [??T!Rl?2??>%n?ZSm ?W?g&A?V??\???Y??mt???b[??D??~0????3???D:??]??????"g?)?sa?????????R?????+?b?????9? ?.z??????3?\??(??kCW? ;?? ?????wQ]?g?C\`?zJj*?p???e?"?j?6???B??3???? B95 +???c#U??+ a??f??t??45??????????C??py?t???????)?T?l"???i??f_? JK\SO'"???x?l????i?)??w6?M5?A????;h??K?g2mTO"Z8?o?Mrl ?L?????:??ZIC??????C?wb?D?6?`j???>4x??P??(UF?? +?{['G&i?%'?S???(??pb???r'?)??DBk????QaP?2Y' #?$W?!?+?8??Z;?'fk?up????^?=?W????*p;iN?r:?9`o?????b??s?&??a?M???A6?aR?h????jq?}?*e??o&??S?JC?(j???:??Q??Q? ? ??GM??b?????g?Y??kq?L????B?????k?[u??]????????6???jT ??s?G?+;???"Fp&I?????F??????T?g'??????>k???e?x?.??L?.?????a?u?D7?x'???????jA??\x??5?v???94)lj|???HxKq['&??~??(x?/M!E|l,`??J0P??KF? ??#????Z?f  ???)??2?u? ,???Fd???Q????+???owU ?~??????5,??C?#?-w,?Z4r?0?)9}??{Iz?c`ef?????=P?a?xO%?U?~?[?p?????p?????C?=H?g?VZ????v???Y????~? ??&?QC??]7p>?II?:???.apkV??#?T??+????[]eM?9?? ?E?"???? %???q??=hc???d????????)*?e??? I!M?$Y?g???f?T?}??[.??P????????E??;|T????4H=?lL??{?J{ ^?{?\B@y?o +???,???R??????R{??k3???>?'?e^?????????Fl?#???????%??????U/??.>?Y???M??`[?A +$??&E??????4z??_???c????2%'???+b??Tke?]??:?*5k???-LN?l)?"}?l{EP?4????0w<"M?(o???_]??$c?L??Bfv?????|?O?=???? Nf????\f?H]1?c???{7k*?X?D?????9.]5?dm +???Ps???lTr??v????5??4?[es?? ??$VOmm??6/Ad?G?kZ???Q?c0???R???tv[ +????_W?E0?????;???NHZU?>??o?3???jxP?=?????5???9J-%?|???????B[{? ?F?8??6Ls? qz[?r???p?I?20c?\t?f??71???k????IW?~x0????H?#?^???%?c??4???????#??%???/?R??0?|?~?????)W9??????#?)?0?v. ??G?v9?ZO?!`?z?rl_?[["+?O? ?pT???????zTI?mB???DS?]??????????D???g?a$???????% ???ZE?????????t???:??~????????kY???e?????????E?/?z??H s+???_?!%$/sE! ?@h?}??h? +\8?????c51???=[??B????g?w?c=r?_??p? ?? MSX???=#,?K??????*6??v?o?c0???????^???%?8OgY_???(< Z???9M?K???o?23???? Uh?EG?}???,??Q"???????F?,foP????m?oK???`|????:?:?R?g*?????*?'??V????H????L??/??G??F??$OwX?#? ]u??s?.?QM3?)???*??????!??????- ???k ?}????? ??}???6d?2??52}?\??r????e+S?r1A??+?;??$5e?)@?HO?i???a???p???+3)(W?7?????]?V#SR??ht?r?7D!??M_P????c????D????Eue?u?F* i??)?????u??7???H??????>?)????PM???u ?3????,????=?????^?~?T@2?????C\?(?g ?f@???c??"e??0-/?36?$?|?????Vb8???^?W?|??:?t??4?w.?6?j??$???[_W2??b???O??q87?Ak??+2????o~*????%f?0????dy?3l>?{!?,??,g?P???F7L?(??e?>?GP??B??O????:{?1?????(?~???_?!Friu?*?D?6?i>?Y\%???4??????????]l??Z?x?U\[?:KG???j??[/?,K????l???RTc?P??>?.?????\t?$??????-4?? ??)????;??B??3@?7T}??^f??,?+K??pYe??????R??5?_??Y#U~?I????4~LYF????????/??????V???41?tw?9?????z?}v??A???3??)> + ???=?????NM??????kP?????????F!? d.?A?Jg+?@?x????e???pI??4???X?aW?0??@UV?????N??????1T!Vb?YI1 +??m??"p?6u%?e?*???OP?QTk??wk???f???i?s?j]??!????????)?L?3c5???xZddM[?????NMJT?LU4????? +?`???9???xI:?W?l +)?Y?NdT?GZ??'???J?{??H??(??q???oD?-??yA??B)7????YF2 +9???????]S???% ?????`?G01G????L??':???\wv?????T????:???P>???4??T`??^???[?? |Y2??3?-O??>????????*??+Cb?Xi?tY????Y?n?M?y??Y1R9??D???B??$GPA??4t7d?{K?Uj?Q?j?w??o?(N?KcZt?N?qT*?F????~p#??W2??P?S?;???J+z???F$b??????u!?=?#C??-???Wf?S?-P??????H? |??????????????.GaM?c??=yk?6Z???3M?8E??xh?:a?Z??@??{?A????s??Q@)M???R1t2=!aG?3j)n?"wV??`????Q?B?? ??_??d?2?:Y????????N???%??1??,?sf????`?v ?????M0T?%?hLY????6vd????b??u? {?G?gt?o?,Z????sQO!????1??????? <f=???kP???-????;U?-I?v?m}kX??????9??*H?p|???4N#q4ir??xi1jI?o/?1?? ???Ajba;???? +3?x+??>r???p??s??????=???[?>?????G??????9???>?i]YF-e?&s??]CU>Y????m???~&hk^?=????1?=od??????2????5?m?O??V????-??Im??????!??v? ??h???vD2????F????8(??z?F?????m/?h?????V????K??4?u???4?*??? w??YT??I??O?{X????NO?h?#]?oWL?2e?TZ?;&???^??8??.MI?xG?y?q?;?3??n?!? +????Q?{?w?sH??~????????-??]???|?s????ut??1o&0???\?|??q??x?B Z??|???????4t? ?t#l???VE ?p?V??r????D?uv????!!???L?6U???,?y????????hi?Jv}?cE???P ??'7???? +T?1??\???9y? ?D?5?F?q3i?Yv?????e??Z+???g?9?`pU?QU:9B???4?Ga\Z?jM&R?(??"???(???s?Ncud?_y????%F?jv7X????+?m?G?;???N2?h??ti ?'o? ?N???b0??k?g??q?J U??gr???b|??[`??{F{???n_%???u?6?h??Z?`????-P4A?vJ:dWP??* +?zRn?7???????????RER#? +??????????qpKY@%?lL??w*O^?????????XpG@?????eB???@MdN?H5g?????N??`'??a?-0?Q?????$????j.i??*]^B^fI??*????S +?$? ?L??v???I?????6?L???????????,c??xNN???? I?,??N,?5:"j??\? ???W???7???yiN??`gw1"h??????iU?t??e(t???W?ai??6]??b?d??f??C-?7?J??'H?8kf:?????-???P at .?/Jas?EkO??(p?E/B? ?u?????????Z??+???Lj?o?9z??????T??m ??q?????X???K?\L???Mz?} Y????K??1 ??????J?[?*?E?;?GY+?)??X8%???r?%???????^s|???]4*9B4??(J ?d0?????P?`h%????D????m???tp???F???)(???e?l????e????????~O????????|??3N:????B$P.?"S.?????N??R ??_?????]?? ?D???X?I???"???g?>dP?????atPi{u????F???h`.?Cc??9~J?V???F??;N??????)n/???-!K??.??`?0?w/??;???v Y?E??,^??I]??0??BI????;??+?X???AKEi?U?r?d+?L1?C??H??Q??k?nv`??K?\??5??%09^~???VT??|?2J?J?G ?8&???e_?oe?fh9?????[t?D??_?N?????C ?K?9Gn??????>???%??N?Y4y/Mt??P?a?"?c?#?#???????j2D?6??7?OO?O?Z?`.??@i?R ???z?2`?i???4Q??Q?s??d?48h???????????????^CQ??Wf??R??r?????????????p?? ??r4??88???A?CW??B??^~??Ub?? F$A?,(@h}6c??\???}5o????? D?t????X???k5????,??e?7???????n?Q???????/?s?p??#?/?1??~ ?C?|????7??????%:0%??\??A???,?{"??8?r??^???Yt?????????`?vsi`????hr?y???xb?+}Fs>????z???/??:?  ???$?I?? ?7e.?????$????P?y???M???I??? q3??kmJ????w.:G??|JL?e ?????&^?6g ????e?y?MD??m?[]_??i6?o|l+i??q4?Ai?9?fU???(?????Y???? ?????6O?6?T?"3?o????????@?\ ???Gf???\?????q???+?7?+???3?X????TSRD?r?;B2???&????:(F?????-9???b?hrk?o?]????G*?hi~Y??????? ?o1?T?s? ^?l? R>??B????H\?????;^???Z;???WMH?R????X?8???&N6"?? +;?@?j???????fm?j at f +????$??41?GV?C?X?K?x?~\)?US7???????L?M?`?(1&>?\I? ?N?????}??????????F?y?sz?X?n?4??4??D???v?JL?t?n?I??Hw????q??Q?????_?M??b?\?Ax,???? 8??D?4?-?3a??(H?a???C.??>??????W?A?>n? +g?????pK{N\?]?4xsr?9i ?gn[h.?B???q?6???\??^??&Q??2?}???5 ?#?8.??y?q"????X.u w????{?K???rF????q? ?/t?H?3?*m??N??????>n??Q??z????\?w??v??:? ? ??zHy+g4?d?Ve?? r??~5?,???0H?????7?Z?t??O??(???rw?$V???9???? ???U?5^?+???0VGu?#Rg?3?I?U?v,]???O????;.?u???+`z5??X?&GV?P?0)3?z_????? ?????????[?. ??r?g/ $_?????J.?/?A???pi]|QZ?\?E?&???f????n?R??o?0a?f?G ?SZ'????j???z???Z?qs?Z(? 4oOq?_???>??72P????????*"????m?;,?!U?{?(}?????T????????V(???V0????C,????(YM`}??7?A????-[??k?>jJM?4??~?5I?+?im??????, (2?T)?X?Z????&????"??_?xH?n?$v??+?????|C5?R?}?9H  R?I??7G??5?6?=??????????????s?? +?k??(??s P???? ??J??u???????Nr?M A????c_uK??u?%[???5M??:??t?.?WS-?w?'?k]I#n?T??y?at ?i?'?q??-?P=Y?( ?w]?s?}??`?'????????[)r^?D~?Ad???????a?7?fq????f???E"Y0????????????/?O?????b??_$?B%endstream +endobj +280 0 obj << +/Type /Font +/Subtype /Type1 +/Encoding 517 0 R +/FirstChar 39 +/LastChar 122 +/Widths 521 0 R +/BaseFont /EVRDRA+URWPalladioL-Roma-Slant_167 +/FontDescriptor 278 0 R +>> endobj +278 0 obj << +/Ascent 715 +/CapHeight 680 +/Descent -282 +/FontName /EVRDRA+URWPalladioL-Roma-Slant_167 +/ItalicAngle -9 +/StemV 84 +/XHeight 469 +/FontBBox [-166 -283 1021 943] +/Flags 4 +/CharSet (/quoteright/comma/hyphen/period/colon/A/C/D/E/F/G/H/I/K/L/M/O/P/Q/R/S/T/U/W/underscore/a/b/c/d/e/f/g/h/i/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z) +/FontFile 279 0 R +>> endobj +521 0 obj +[278 0 0 0 0 250 333 250 0 0 0 0 0 0 0 0 0 0 0 250 0 0 0 0 0 0 778 0 709 774 611 556 763 832 337 0 726 611 946 0 786 604 786 668 525 613 778 0 1000 0 0 0 0 0 0 0 500 0 500 553 444 611 479 333 556 582 291 0 556 291 883 582 546 601 560 395 424 326 603 565 834 516 556 500 ] +endobj +238 0 obj << +/Length1 1612 +/Length2 16654 +/Length3 532 +/Length 17561 +/Filter /FlateDecode +>> +stream +x???ct???&?Tl[Ol;?$?[Ol??mTl''??q????_?}??????????s]??k?EN???^???(fk?D?????3?6tv?????W?:???????@'s[' @ h XX??????a[;wsS3'???5--?I?1??O??NGsS??? ????h?????'p2L???ay I9q??? +@ht0?(8Z?d???6?@j?????? ????????92|a : ?v@#??m at 7#???*:????????`?0u0?q????-??????????&?? +???????K??`???h?`n???? "??8?? ????h????|Y?9????t_0_Z'sG????_?@??????????/0;????hnc?_????V at G?/?/???_y??? ????????_V?+s'G?? ,3??O#?/???6???4????-????rcg???s:??@T?? ?W??6V?c? ,?????K??? ?}$?7P??B? ?????O???!??;?? -?le%g`???>`_'?-@??ce???27?6?r??l?OC5???????t2?*????!L L??;????????&V_???\???`en?b?_??331??N??????????[?1????H?W???R????y???J??{'ew????G*????k????????k?YX9_?????????_kY's7??W?L??J?|????Q#[?z??????W{?/??j#g?/V?5?_ ????t?./??Y?e?;?b?M?h??2? ??4(?U?????mqW???34N?|??/????I????bZQ??/???I?? +P?):8i?uK?O??R??????=?!????bt"7?????R$=>P? ?\C???????????#PD???? h?Tx?SC?7??]?_~?u{??????EX??(???????%A?? |O?u?h??T??????.?8?=????L.???? ?O`???%Y?T&T=????+?~?0?Z?j??>????)???z??=r&??p?JD?V;Gr??B?f????0?????y5C?????S?\??Ll????c??&?B??k??d???4??%H?O?;|."]????????#??????KT:[d???F?????????E?|?????H1 ???B?>O~f?m???U?{?8`??N??.i????????;(?o??Ykbx?R??k??_???'??????bF??t? ?j7??????=???: BX?j?Y>!?y ???F????u?n??'R??r6'?????1,?%???B]c9p: j8-?9$LOl???zR?H?I??_z?1A?P6`WmE~!z at i3N??W??? +??Y? +?P3?#?B?Fw?(?$????y?b#??Yu?(?sX??????$?j????H B8????O?w?)??3?{?> ????.????lL$Q][_Q??????? ??s?_.%?)?+Nt?@B???]??? ????A?%??h??+??v??M?E?Z??????^;??gc?}???_?:)????rKa?o????)lW%??>??$Q]$????/=??????9????U#F??Dd??@4????>e??2ll?YP?{D??p???y?V??[z|?,??6?:?}??3le1??]? ?8?V?????f????=?9?????&(i;??op-???VfR??`?>9??56N?mVS?{` "??????m'IdM????*?&?2??W???????tZ?l?Z3+?u????Q r????F?x??'Y??[???ZU?+z?????ropq9?a2,?y???NJ?V?+8???}3????T??9?-G? ??????9?TE\????M???:?(??? *j?T_??6??????SM???+=?;$?va?p?=u?A????N&?m;??WX??W??F????zK?????&???r???????????~??V ???O ?Y??X??O??Fdj?pR?????h?xUH?????e?0HhN?:?>( +??n^{?6w??n?x?t.`?-K?????????:???????g??wm`;?9????LN?>?:?~?????$?????&Lo??K??a? ?? -????2?I?/?V?5?k?????_?~??5?7?+?,\??G????H?5???7_b??V?Ls?Q?,????N?e ?S?e??{??&?fGa??`?y?????KyI +'E??w"4??X?W??E??(?C`??^?iR???h????$??????#? ????^???X?c???~r?Ap?P?x?{??o?%?H*X5???5@??5n??`tV?????c?????\X??zB|??x??~?? '.\x+?5?nx+e?@^=?Z?}'???$?em?a>?'?????c.?4t?????Y???8????L3iOS????[??BI??5??H???/?Lr?blt?z??#??#??yT???(??P?e? ? ?$??8?:V????$P??i??&?[z?37???@m|?6???K????w??g ?o????f??i?}G?????\?z?/??}g???]???a(?!???????l?????R???tO????}??T?O1g???x????????D??G&?? ??ja????? +??k??z???+3r??????????d?8]s?t?t??h%???ob?}???/??:?9P?????????QmL?????h??sSV?_????????\?7?????f?m3??(?w??h +r?K? +??X??????'F?s?8???nS??0??ekp?!???C?oS???;??W???F?2????]GZ7????j?.?????fk?Q? qZe?y???p4mv 5U?????.??5?p??*j?u?(?? ?Z??????~x'3?????E5???H4??3?0?#???YG4[>??????T?o??]???W=SQR?|OE.?????VQ.b?[|???@???|\-7!I?4gq???k?L?|?y?oN?'R?dc?!/\?? +?W????#????????.?????6Y?@?D??F>?P??gv,??j??????a??K?f???4??_???zJ??????'?:b?t.?????????|????;??|Ng???u??f?Tz??=?h?y???O???6??????X6uq?'??o????z?N?Y????V?>W?Z???i[?(?~C?.?S?m?????e?KK????t??J +?m??~?uguU??7????;???????:??E?Wk?l??Qx<-)?Q?{?Cu??qk?D?#????M?(q??c??????/s??-<??/???y????U?i?????YmWP??HS?8 F ?]????C????W?x? ???[s?N)?`.???+?Y?%??V?T??l?ko???P?!?h ?6????r?d?y???1k??M??f?Q?9?l6????0FY???6???>d???3?z?oU|?????{j????p?-?ueD?80???x???N?a^?P\???hg?k=.k????$D??1q??9??c^uft`?d??? G?F?S4?$ ?R?:\?R?????Q??(W???N?c???????x3@????%??K4YJ?z9?W???Mlq? +???5U???s?oV????g[? ??D?uL?C?k??????`{????????qy? +??P?vf78x??L?&?Lf;A/??Tc?o? ??Z?????F?w//?1B????@0?T??o?? +??? ??????{?6??] ?R????6?_?L? H???n?????*6?J??~e@?????)?m}???,?v?R?]?j=xh\>??CZ?Nldz???????u?IW??- ??J?tp`??h+?k80?.?=? ??y???x?c?D???i??????Vc?h?,???O?????????`jc0 }?????????C?-?*?3???^4?*???*??????L9e??-?)??U?CcA~ryg.Yd?????-?Q#???? ???Q???6w?A8???0??<9??4?%??e????jF#??#??????R7??IlV??c??1???????<}??? l=A????{?]?%A???u?<-JDA??)?F?;Iy??????rw???+????????e??Dl? MuN??b?i?????$?K?cA?;~?M?cq??%????zbk?6??#?????F7?_???`g????V????lA?u???bY??,#?????>^?b?BhA*??7????E?#?G?\?P?)v?/F???? ?a4???{Jm(vUm;Mp,L03???zf?/??K?~?-aC???tj???E?c0??N?l/?D ??>y??U7?t6??B???Ec?7?6?+?e?????/92?????A?? '?Z +??s?z?Z??bbSr??HI|8q(c??!N?[4~?m"5Up;tVT at bx?'?? :cu??]?7??C-?,??R?????p.ff?Q?-8???-??Gw?"?>???"H???: R??;?j?]???c9??-?ZS?? +N???,TRdT?=??s?4 +M??f???v*?4Z>????5??r???sf?{S?7????[ ??"??w{??R`??`\R???!PJ????j???l?6??y?I???;&J??R????3"(?\?UU9?]?c%???Y???z?}? `9o?9???=$???D??k??f?Xz?????kZIu?? ????????{??????Fj\????y?t%o? =??t| ?t~d?*5z#Z?\P??t??6??)????????Is55??%/??{??s??rH????o??????;ix, Oit??;C?(???K????????m??m$????s????/?r?_h(?Y? ?z?w?Au?2???7?+[w?|t? 1????*?R?%(l????L?"C]Ix?ZBR3??y???,(?*???o?J2?????%Hm??/S????L?A+??r?X??W?(j?K???*A?KT~????S??L??????F,q?ID_?=? ????L?????A?P??3?N????1e????O?}`??#?Bn?n?J:??-??r-??Q? +??5?T$?KA>?Dl??w???oBdc?d???? ?g??A???+OB%???|~????r?\$????OY?2Y??_oR?'?4??M??7;e????V?????{??Abk?F??p?&?N?0????IB?N:p??9?;P.???")+??6 ??y????Qz? P?e??UZ??D??!2k?U?=-?@?S=7?;?w????=??z?#'?uP[n?UJ ??_`?a??|??????b4????\9?-^? +??xLE/??6O?e1]?5??Kd??'?`???? ?????????7?.S??~Evq"???n?B??Z@????u?^?I??R??*5????i?x1jQN?C?C8?.??u??*}\?7El?uf???V?S???)??ag?R?\?^??+?D?)? w?????J~OW? ?:m??!?:G,hw??,?????4???Y P(????Z?w?? % ???bw???????} +??A?????&?S$"??;????4?????X*?%?}??m??? jqr????? +?'????f?&???4???@j?????f??k>????=? ??w`???_? ?M?^ +?0?Z???3G????? &?/?8?????2J?5?{,??)??A??? +X???:???l1??,?t???w??K-5=%5{????U? o@Q? +H?n ??r???'4????q?$2??/LWk?z5??(???@?+?9????6?.L4jO?cD?;?K????D?-??m +D?3x???7?U???nd-?+?A=S?.`? [?n?8??f@:Q??oBB????g????1?2?u?vx?i??v?,????'W?'????b?[/?j????????1y??1 ?%-!????`9? ?*=98b???!????:??/#??G????????????v?#?f??2V?bq??-o?R????8m0-:!>?y??R?@? 3??3R@?w??X_/?N +V????q?=0?d`?[K?{[&e,????)?????3R?[xG??i???????????+?P??3???/????U?7?????5?????n??X???>b)?k??U?YGBG????X?{??;1 .~ V???n?G? 2SZ1?E?+? +?$s?0 Y ?Qtwg?) ???????W??f?s,???qy?>?5?????>y?G???uQv? Z??|?X#J?nD4?W?@?T???????;~??;?w)??+?T??e}??{?????"??a???+??~?1?P??? +?s???(?2b?_Lz????k?z#VBWw???????!mq?6$?/??c??b?d?v(XJ..?XN?#???T???O ??????T-?6???]?s??????|?? ???6??^??q???&??L??-0?Y?????u??X'?qP?U:T??t?4?>a?{????ZD?Y??g??????J?? ?)? +?L!'??8'????(?)S???Y,??y?sO?l??d?\?QL2&??D???(????????nV?U:|?c?CU??SX??:E?v??&?c????LFO5TG,|:7i?B?I"?0?~???????&??????y2???I??h??7??????5?tk???%?{???????qyn8???????t|f? ?Vm?????? iXQs??f??????~~?!????R=? ?A??`=??=?*??_G??[NKn&?V?/bjb?; Q??68?&I31? #I????kM~l??fr??I?a??e?U?!?R_???nu?? ?>???G????? n????????n9????I?c?? ?????U??.V"T>?r???Ot?X?0,*??^?S.K9}O?? +~#Q?q\C?>X??fj??<-???Qr$?\????x ?????_g? +????9?]mI#??M??????+???+?%:?????q?4????N??????????w???????9G?? ????ja?X>??????H??6x??,?????5?1????.wJl?DcFo?S???????????z?????? ?????x???]h0??3??[?F?*O2??E? ?F?75??e??mh?TS?b?M?o?L?K~Aj?~???9?P+??l??????? +??9??q???vEe?????C??g????C?aV K???u?U????S????(d?=???5?k##a??|??n??@?@I????s?*0?4????X?j????????i????Z?N?)?ckh?&e????j?F?+9???B????????o?/???K?@PS???????z????????'b?C?k?ji?|/???]????K??????# ?#????=Qn?????5? +?I?? +f? i?h(P??f?B"???s?B~????ME(??W??lkL?h?:??%?Qi;_U:[??Nn???:[-??? ??W?u?zU???E??w?pU?? ?V?}??!????;??(?)?"?j??M????=???W?????8?5^>W??a?6??x???? ? ?m>>O?~??K?I?p_7???=?n???n?tp ?*w????{?>?"$0?0D(??;??%?|??b?2MU?h??j?DN?????*?h8???BW???nn?]?7?????v??S?r????Z?'????B?[$/*?????~4e????x|??=*???5?? B?????Y?+e?q???B??4??j?q?a??j/?}??,???pj???z?G?+Y???m??8E??p_?U?n??p2?!)?????~M???? ?6???t0B????uX?{9X????H=?A???Q??????<.2??\eY-X???L???M4;(?u,??v?*??o???G??V Y??q?2p??????p?e?????%???:?QdW? ? i?i????l?????eK\X??U???????:??V_A??6???? ?M?\/Xq +?????>??C??0`??V&6?OI?4?H??? ? ?,????F9^????????U1???>??Zn?I??%??/Y +?;J7???4???:?f????????R????E69y4n'??.7????n?,D?HO9?Q?)dF???B????nQ +?[`??h?f???4btJ?=U?u?/ +L*?????K`*D??U?2?T???4??j?\ BAZ?>???<??? ?!??R`??????a?|29?????_???w?JC??????xs?C|?eas?kAZEE??),?~???7??????1????????>|]?1?Q????L?Zfx?>? ??r1?f??&~?+?g?-8$??>?????6?o?NX???w?Y???#i?k?????%)N??0u????t?;???? ?;{\P}?/??????ks?6'??.:)?/ ???F??@-??????OO.o !?|??d5??*/??@N?,>?E??????B?????/??x???@?y/???W???????A?????????G???5??????+'????}??$??M\?y8RZ?R?5HV?u? ?y?n??;tI?t???D???!???~?????0??? ??GF(?=?-?H.??w\]?c?????%???QK???m??+??'j?#_?^?-JkW +????R?????@??x3?;?1?kpj???DR??????-???? ????t??m?;_?@?A??f?gZ? ?T?????\5GF???????r*????gt\?;?'8????V"?%?d????????j2z?B?i{?sB??g?>_?o???X??C?&"?????"?e????ZnijS2????(?D?T???w?VkN?}???'0??x??;??Q??P-/#}2?,N?AT@?|o?i?a??U{???2Oy?Vt?-DR1#??C??C???|QQU??w????) ?&?|wN)U?G??>???4? Q?M??s?4?????6??r????;KD+Y*K.Ph?? &??('??~qf?8???{oR5rh??J0(~W|@K???U????o?f>q?A$ +????#@X7?*d#???}N??S\?5?-w??VT?Q??P??@?<WY?w+g??T&Dg???][??`z+4??_???g#?^????D???A?????p?+'G?????Q?x????^??A?Eof?a????*??h?N????s??.?A?Z4'???? ]?N??>j?0'>#?f x]?c???f??;?vG8G?Pa??j?{??n?'???????hEW4.E??-????Hq????m?&? ?r?m??e?6X??1?i????V?m?Xtx?????????? Z???? ??????/w??`????\???*?7??`j?????????A??_-??j2?oo???J????g??9P?Lo?Z?I?B?+-?+r?????p#&?2'?? ???U?O??Y? ?? ??*???? +??)0?k???R??5??z??Wh?n ?????? ??`????????S?6???V6??I?O???1?#???[?0? ???"Fs??j??&???-?????,??y???i;rW@??*%]d?g?#?} ?pio??Sg?-???h&F"T?%? ????u??PvB?W&??1M{??m?? ??????s^S??r?7?nf??lI?a|?}|D?"?,?E??C??~`???7?#_???|??o{????????&S??Rf?r?? ?g??p?L????~?o????!i?RrV??/__:{??????@??y???:?IH1S????V?F??q?+???r?????????DZK?`??wAI???^??.???{_??k???l?????J+I???????|MXVW.????|?3zy,?V??6P1??.F?a?o?[-m:9m????2?N???| +???I??^x??~?#l?{*???|?????{0?J.&?x?3}^?9??'3?\2??MJ?????z6???9uO?%??? ????t??=??(?s??(?KN=?l?? +V??Vl???(?N7?< o3?k???fd ??*?5??Av?? W?,????+????{???? ?f?X?C??~?+????k????u??M#Hu)?Y???^Y?SF?v5?)d?In?3[???_?1?/??0??>+Z????-]??If??p?S]?? +???????,x{?1K??{????????w/j}?p ^???b?s????<&???C'^??w?S$?l\??????V???q??;yY?v~?C?DV???1?? Gv??p????E:?bqzx?E???W?X~n???&?7???+k???????y?T??L?B?????i??E??? ?0e?? j$T? +????|}?p????J???? ;`:#????0a?????O!J;?????4?:??????'w?an~h??)??=???xYzM4???!??#????G4????u +?T??I?O?},R=L?'??Na ??c?.?K%???????(&?"?R +P?K*?8?Qy??D-?2W??'?'\?2?6d??Z?s_?j]ZQ??B??????????Y"???? +????~????????o?? K??XR5??J?b$+5?D@??Z??????????o?B?Q??=????}??5(???=r?F? ?|6 S#K +.???????F?[:???}?-?=o???D? ?????\?(6?0u??????]D#???>W"?e|???k?v* ?C??^???????{O?IN{]0o?????5???0W\?+/I???1?L? [???I ?gy????w ?|????k jG?B?W?????0??? +z )H??`?~](i%?? ??b??? ???+8??????O?~rme\???6?^????A????f?X?I|?+=??}? v???Mf?????~???K?`?"?3j?W:?aa?? H????km&??Q?Ce?A??%??M!Qd?2\^??d9{[O???J??????""?????@o`V*???e%?wV??I??o?z+|MG??B%??\"???????z\?? ?v.?????-??jFW?86?}N?Yc6??jw%????]?k??D|P?{'Zg4?Ggf????f*?;c???c?\v???? ?P????3?e??*?wt-??=7????_SoBu?=????}F???v?\??? +?o?O\t'P???d??5|?Y ?{?????Q???l?O????u???o???VK_???vO?v???oW????])??? +n??{?????y??^D?O??]x????Xo_6????????d???zt???+?{[?t????|??3F??)/??>???tG??4S?????j?5V??>??K??????? ?x???#?????O????;??_????S???w*?|o???2??M???????k?j???h?^?????????e????~??=?????O?????????x????o???j???r,??W1??R??hrO???[?tp?4?E{?????k9?D?F`????1?O????"?????????=!??z???C???M?[???q??Z?k??i'???^~P)x\?Ir? S?YK?W\?y??z??^a?'W?7yH?,?x???U2?Zq? ???????]?m82?y?f}?? ?i =??jR%?]"?x??Z?}.???E:mE?T?Y?'m??Yiw????E????)????{???z?S????Yhb????M?L????9G??e??d??A +???????????????l.Nendstream +endobj +239 0 obj << +/Type /Font +/Subtype /Type1 +/Encoding 517 0 R +/FirstChar 33 +/LastChar 125 +/Widths 522 0 R +/BaseFont /MJIYQY+NimbusMonL-Regu +/FontDescriptor 237 0 R +>> endobj +237 0 obj << +/Ascent 625 +/CapHeight 557 +/Descent -147 +/FontName /MJIYQY+NimbusMonL-Regu +/ItalicAngle 0 +/StemV 41 +/XHeight 426 +/FontBBox [-12 -237 650 811] +/Flags 4 +/CharSet (/exclam/quotedbl/numbersign/quoteright/parenleft/parenright/plus/comma/hyphen/period/slash/zero/one/two/three/four/five/six/seven/eight/nine/colon/less/equal/greater/A/C/E/F/G/H/I/L/N/O/P/R/S/T/U/V/W/X/Y/Z/bracketleft/backslash/bracketright/underscore/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/braceleft/braceright) +/FontFile 238 0 R +>> endobj +522 0 obj +[600 600 600 0 0 0 600 600 600 0 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 0 600 600 600 0 0 600 0 600 0 600 600 600 600 600 0 0 600 0 600 600 600 0 600 600 600 600 600 600 600 600 600 600 600 600 0 600 0 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 0 600 ] +endobj +171 0 obj << +/Length1 1616 +/Length2 24119 +/Length3 532 +/Length 25001 +/Filter /FlateDecode +>> +stream +x???cx?]?&?vvl?v?I?????m;?????m?cv????=s??uf~?7??u=???]w?]k=?? QRa1?I?]X?yj?JF??F?V at ye???????B????? +h/n?b? ?03???XY,<<7D?(?|!m? +??V???.c_??YE??????????+?1~?????O?? Z???=|?????????a"[,??Vc??j??^??`|i???????H????U???????2H?w)?1????3?? 9????:\?g'+ ??? w???i at vi?????Ff`????l?h?E?/?_?O??????V???/r?R??????B?F??? +Ga??A9??[??^b??=??????????\?P????V'??_O?e?Y?3??C??J-\?????w???BKs?~Tf+?0?#? ???:?X?%?????HJ? 64?i?>Kc?????L?U??>M3H6Uv? ?.???:??h?4nYqnDo?dF??? ???O ]j??0d o6??H41??Z5????M}??t??2?> ?d?j???|(????P/?C??~G???yU7tD??g|??N?Zc /S?9?B8?????.?4y??????u?????*????2k aQS??k????y2g??!s| +g I????)e?(g?$A1?5??i??5???G?t*8?uO7?vlL??e?6D.??{o]?p?Z????a?dZ??B??/*_$[?????%??????Rb??ArT,?T??(???^?)???*?*????P at 1??? ?? ? ????S?w?x?? ?R}? ;)???"??e|?????aQ3?V?8???9??7(F??Ri?X?D "7?m????O[l+?,??e?n?6S?b?Wp?.??wl?L??K^??!f-? ?S?S???-`???7S?????????pc????$? ?;???J???&!???v@??$oOn??U?? +????Y?J??k?~,2?v?????4??T???)?R?C ?=?99????2j]Y/dS?????>?88I|?9????Ho?]??CJx?`=????u???)?B^?cV;K??*7????h??r}`?vD???|8????sa??E??~0k?~??????Ic???0/?#????8?A?????3???Y??u?^G7M???K???]??P'4pn?u??? ??;0?seL?:??Bk=d?|?????7???3s?m36???w?R?????? ???K??n???B?nR????Q???$k^??W?Cm??;?s??????3????Fuz??? +}???6X???^;?3????}????A?"???*?(kM??1?.vN????ty?43=b????z?Q??[??=$????|????'??? ?]??h|?UT??N???h??T????k?xt_????]j m?O;H5??x#??VK?J?w?";?2N??=??????B???^Q?>w?-???j????}K???oX??B?zGCdn ????O? [T'??^???????k??u? ?????5V?Pm?m??Zo#?)??z2j??M????rCH??DE?Ua67? -???????o?4??? ?%??^???????!?,&l???|?1?Nu at Z?#~???????/P?? +Ek?As????v??H????"?iL???A !??i P???m? ?hZ???L(t????D??E|\9????9z!?y?G?????hIYpV?Z\??`?&a?\??bp!????S? x<_l??m?:???u?i?J?Iv?]?cA??C????I?ENx??%??{?Q?W?S0?X?\?`0Y??k|?|{a ?????v??T??c????q#?ID?@?@??(R??????1?c??D?^5????n????????y??}i???~???i?z?.?TV??&?b??u??w7??=?y,?R??m=???????????[?S??g??V:,?v?`?e?R3?UdA??~yW?tmp6???z)u=m?B??WY3S|??7?2H*j?j?l*?c9??A3?gp???$3?Z+W???=?(? ??4? _? +:? ??q??p at B*??W??T??18 ?p?t??[qQPQ)???&u?G))?.gb??K +???|??,?5?5?h???vR???9/??H???;?m???Yt??c~?oJC??;????????a ???????x???? ?7?K??x<o<'M?Q?_^???, ?????EpxM???&c?rO?@S?3???x??W?????B??????t???a???=????j?LP!??yt??F ???8?O?I?c???????A?/k^?N?????R???v?g??????T?cu??e??????T3???\????#r?W%?|jalx"QR\l?k1?~??!%c???|?????v?????j??x>t?|?E??T?O1??{k?n??#N?%????#?????V?m:?Q??p?????_?@e?6??M:????X ?x}1??a?wZ?s?]??t?79??fR? @^???O??z%??Xrz??7%?{???D?{??X?~???pR%??J?????c|?Y?l????k??T?.?????[?c-^????????PN?ROI??r+I?%????^??T???[?????4?w??D?H!`???<}0?;?_???jJ;?Z+Ms???#??i??jypE????v[?$9?????:_s?????=??:z't?h??x?qR?%w8?q?N??|?Wh????B.??+.m??; -?zc?b?????iH???/?(????Z???6???????????E?TJ\??)??L?s?~>?????Z???8??????G????/&???e:?K`?M?r#H?!?.'??j?`s??)L??:?$'?)?"9g3???2??j???????B???S????2/>%q???O?l%=s)c?U?u?:????????b +?ll7??C#A??Z?g?d3??1???{????2??o?????ZS??~ly????C??sD)o??j?y?+l????_?? R.???Bd?A8???(z????0???^?XT9.s?UL?????C?? o)?>tud!iG0 ??( BW???~k?J????f?8 +r????j\?SX72?(??wy?1^,X(Y?u_????????????]>?0?&Prs.C?W??i???*)UfP)C `bMP9???=A????? +?qB?.? ???^?E~?:?????????y???0B?l?w?H&"?Xh????'w???!D n?'?k?W??t? +?7>_i???I(<?3Z? +oC???"?l]???G!?=?? +??2??:??????D????? ??7xz???NE??OQ?????????%??V?"??py?hw?P|5??(?3????]T???7?]??????????)?????@???N:BIzB??????z?pfF?????r?k?k~?9???4"?F???iaO??qQN?8?=9~???k??!b?r?????e????J????d?????? ?D[?M?6w%SB7??fz?d7?VZx????hx?,V?L?R?rv ??1]??\=???????!-??1??M ??Pp?a?G???????? ???l|^si_????????Zt????(?$?n????e?c??!??^Z^???? fD5l????Z?1+??F?wXc????#?{?#7?j??X? uZ??ds85<@X???R^???BF8%???yu??X4?:?%?????e?? ?,?J? v???5???Z?? ??r???n???L???Z??h!?o'?????Z@]???U?q?-????.JS????J3??p??+?p?? +?????j?[Y,??D??????M?t?9????????b???L??K??D+\?Ij?*t-?m???Esmr ???A|g?s? ??\U1$?o9e?0??? V???d+4????X???M????qe?c at +????`??\?e&^??? ?$??m??l]7??Y?.???n??%y???????r9?2?n]??B??Uv??2kBq*?H??Y??p? ?9?G?J,??p>???@Cr?L??B??PV?$7???, w?????t???r?????~?;?0??sK????dYG?1?/g?0Y???|?PP[]???1???P[??????-+?????????x???f??0B9????[?n?L7wbdKxR??Pj<??B?????I?P?0?06x?N???~T??? ??=0$E?(?7Bo2?a?Y????????? ???????>9gz??%+??*??U?????cO??:????B,!??sT???5??~?4F]?t???ZPgW<# ???y????N)?a??? ?t?X7j??DQ?? (ok????????`-?N?1??uV?A&?!N??&x~??W??S ???I??,g??&% ???G*????????G?H???u?q????c???Z ?p?/? C??JXo???!n?f??p????O?$?+???ts,?%`?+? +Z:(???M??8?? 4k??X&??&??????WhI???!?1?V?????@?1?????T???)??6??T0j]?Ns?yH?;JWC l?C?C)6bKa%E?- ????g$ ?F?x?i?`.?2!n?`D?&??*??2~?qx?W???}};SW??a?bp????!Nn?y??)????W??E????6q?p?;? ?????Zp?\????f ????*???Y#?"???????`?d??AWq;???Q?)?>???8?>$*A?s????}i?8Xx?&94Z??~?V???? ??R??????s?? ?C????g???xB~]@6???^AoC???g=??'u[l?z;L?TfI??(??f???????d?&L/?'l(??e???+d?}?To??? ?Mx?g?N? i~Ka%???vY-s??????\??|?|??E?~Uf?? 2??b QGY/?Y?~?A???????GU????+|??D|??o???j???K?zL??t??2 XS ?MD[?BA/bOz??2????????d?O?9????I???????a????F????G?C?f?l???+G?????e???d?????????????q??? G?"?N?????f?N?w?6R???N???E?se ?C2v???z? 5??D???3:????*??[ +xU??Ay???>ZH???C??]p1g???\ +?5?rdr????a?6q??]??'?M???p??W?"G?????`???'E?,? ???67Q?????\?? ?]?|??? ????? +t#?e?j??b+d?P???s?!???z?@?mhm?y????x???hzp?w54u?]?EK???v???(??Jh*we?AG!#$? 0?x? ??[G|?eOS? ??D???0??_?"?d? ?0?? ???Nh 7??O??3 _)????=?[?/??????? ?h-h??~d6??q?N/???=]?]vl?`??cS????????????5?????Jl??bW6j?.+p????'?????eG?zs????????S"Q?J??]?I??5???/?El(?????u(@?H?=e~6?,??Q? l???????x??????q??j???#+???>? ???}???0U????? j?????N)C|uY-??M|????~??7????s'????,??????? Y=<???&3?X?Lx?O?v~?O???A?C?Y ?????????"????J6?I?T??$????S??W?OV$ZD??{??v?kAB??@????,? T&O}??)???a?P$???s???????>y?????(-??v?`??"?.h?u???"?3?E +????|??&?$??6 +???&?wA @?[G2?v??x???~5?p?h??;??H?G?{????e??V?/?? +WN??zQ??B +m????u??^n?n?!?L?? ???.??h?a??f +&n#???t??Gfp|^??1?M????/???3??????cVV???Y?c?K+???"9?????w??^?Y\?*?R??f? ??:VD^??*?&I?????????:#7??3X?fak??b???$?6L???j$???XF?4???4?????O#???!/?3?i,om ?1 +?vm?E??\?{?0???W??do?$?myCx)??)????X??6oL +2???? ?E*??????~?ehL=?????F3??4?QZ?T!dEZ2R??7?7=ae|??j?w????s???? t?]V9M????c?-?%H??\8???????X???qY??1???d?? +TJ?&?YC?r???"?o??????mWgq(????<??%??.0???? UIQ??^??J?????6??8t??h?^9?8?A?~ ??,?n?H,xCia???{C?????????Tq?>x???=?? +7Ps???@???????U???Q?????d=K?JF??6+I??#?6???????2 3Z??+?C???m?1 +?????????BYW??C4_r???h??S??t??tT??NE??C????m??$R?^d???~??E1TL?\?? ?F?K? $hH ??f?????GX?j? y??Ytk?? +rV*'?-???????????e?'?^???up??8s??????B8?8??UD?D?d?C?};%???~B#B?M?????%???Ty????*???/??s?(K??? ?????c\}???q? ??1Bt.5?p???????2????(?_AP???????????=???Z](p?x?75v?p??K???.????,??1?1M??k??1?????]??t??I??Ia??#t? ??S1?;??1?E?????a?+i?K????V1?/???????????<g????????j@?x5?Nt???De??V/{?"?8?bG?????.????N}Fu??O???Uq??\????<??p??czi???fD ?0o??U??/:????n???U????PGq7??E$?2?vhxV???eY ??????o???.T?n??c???? ?"?r??M?=a?? .???~:(??????????y??0?~ ?S??e???t???j(???V??9??[??? ??? R/??????????f????N?????U??/s???$?{ ??K??????/D,???*????s?l~d?? }??:?xF6??g????qE?b?N????J@?[? ???m?1 +~p?h{??{?b??F8A ?5?nv?oX?9??UkI??%?l?2???~x?4*????s?g????a?l???Cp????f??K?o?s?`?????Klwy(?U??@Sq???WE?????#Q?m?oO?&?????Y?(v??g?t?y???o??aR??????)? +8?@Y` ??G ?o??ED??3F?? ????? +,%?0??s*?R?y?yy=?>????!j???MO?q??? '?-???fw?e?9? ? ??c[?????x???\?JK?2?????^??P??^I??m?w34}??<7(v?Z\??[/ B??? ?`w?_????e? ?r#{???VF??$ 5?a??w????>?tb i?;0???/_??K??(B$I?_??8??)C]??????C?UJ ?????z-=y???sOtM$?????j%I?1?7?4:????Cq?c?????y???u?? 1?Io?9??Q???Q?i?M??? ???? ???h????x??d??????j?9p?sY?&k????u??5????3???S??$?=8?2u?B1???}???X?? +Z=:???l=?s??????|???????vHF??????>???)??m0n???????V????C?????gyK#?A?q??????:??????e2???~n???????????*??? +[?R|JbY??Fn???\?a(??????????\_?DR +?+2???/?.????{w$?^?^{zV?s:?;????p)??????????? ?d?????&?N???ge>Qf{oO??=??B??$??????????b?L"????d+?m?????I1???:'d????&??????_?R????y0j???_? ?1K???0L???A????f?????JS7??H???????~&?f???r$???L???*?????uQo4?6:a?45.?y6(Q??;?(????Bc??7J???l?[?nB???H???k?l?.??(K?}i???????S???Fcybm??-)t[i??k?B?7Jo?0???{?"??=????"?1q?Fw M???>Q9?F?XeYX?:??(?BP????o?3?&v??z-Op?f?p?&R=?Z?q?(?qq?????ZX"?????:?q????"?TNI???az??1?????tfD?f???D???Q3???B??t?U????p/?$-Y??)P???-?9*?:3??CD?(?N?0[?4)??]|???s%????! ?0?? +??uN]?*2?Y3?????rM???W??5/?m?$??D?$!*Q??\???:???@?jQ?nl??^???3]2?/\ ?XO???l?B,*-??{??& +?4]??~??>??z?????mQr%????[^>??iP=??????k???+,?vrb??m?c??mvl?I?c?c??Ir???????????Z{m??"a??????T\?\_?? ??Eu??N~/?.?\??M?_| ??Q????_???qV??????` G???S? ????`??.?!mp??y4=?? +0M????b?eY??}?1[?U??-d?8????? ??????X2R^ ??I?+??` DsM&?/??\M?Z?rn ??{ ?ZE?G???(?' 2k?g*=???[?B?;?) +???"C?7q?W? +??g???W?????? 3?c[????I???????Cn?9?j????#U????/??g??)??i jm_??S:??? g?H*N?5+=-??}lE]?;??k 9 Y???h7 +K?ds??S?????&??] ?%1?L??Q(?$??e!?????f????C?${?y??R?B)2X?Q?A?????/yFm]?@?F5?E??2??T???>2?X???zx?=2?!5???????6????c?I???K?2??* + `????)!>Z??xE_??5t?=u?{^?? ??|?U?Hk?????Qxy??NP???6WhDd???? /9???? + +S ?sqG?6?)o?I????Tcb??/)? \??d?C?N??+??Y?P??wQ???%?1?o????k +?T?O?}?>C?x??6?qD? @?5?Y$?????Y|?f??????????C????WOp?u???v7??s??????d??\??????i!I?Y???*6???_?? +?/o?????FrL +????y?|R????R???<?lm?!???????5?Krt???>h???2??0_??P??Kk~???DOS??}?e?g??-=?|??u4??%?I???'X???!???????? ?S?I?C?r~?y??^[ '?9???????$??????MMM??\~???t|??4sJ-*A??? `'??|$%`?>ZQ??'#??? ??? ?Wx?S??z???6N??????X??!U??^DT??~?? ?q???????????=w? ??e ????#?Z3???C????&C???0&??i#v?QU???UB ?fZe?T????@??6?sM?Z?! e?Z????m?yx??l?'?#???y?qd2Eu&????# ?A????++???????wF??W?K???????4???T? +?????v?V??K?p?????iJ?km??????????l]?5??2??r??TK?N?????T??T??C??M???A??81,?? I??? +r????B??????(O?mo?9??~???g????C?{??o???~???????S?T*???I8+H??;k??0???w)l?/?)`??a?T?SF(p?{??z?????????????f)?)???L????????1q^?X??A?3????h???????+5?K-j????"?|?p? I??2???????s;}?c=2,@?LR????????)?S8??2?|??E??O??PUF???:?z???r??@ ??"???? ?????m?+??9??o?S?u????z???of?snw??????, .??{0F?5?e??v"???y g96R???5D?????r?I??F?}?O!j??0?fX?}\?0sq??????????j??????6???I????u???2?p,?6?)??????G?Yp???6??!v???G?;[?+??L?o?@%????rS??????'????Y;?e??gO???=yl+?a???I?a?aR?b???a@??)?J=A/???ey????.??6?/?j?H?9q??!S?*n ;?:?A? ?<???!?&??kjDB[1?????n? L_|K?59#?H??}??/???*??699??_?w??jl?????/G,i?Sa&?Iui??BB??sDJ'?#?_ (??? 2U?4?????]??u?6?? .?9,???????????fi~????? m5???B???P4????P??'d*z=m??? ?????6?????!V ^5l?/??j???B???d?*??p?8?P*??{????P??R??fI??Z??? ?QJ???R?T?\5)I}?Y????$=pv??J??Z???c???R?3""hL?e[???+?9H??&?;`??{R??k??y6f???A??+-? ?O?4??[VI?? +L?8?w??J^??+?;?i7jK???QUT?$K????V????h????9??f?jm%!=WF??0????????!>????m????? ??????>?8?D??r(^I?^??Q??t??S????g??????&???#R?as??? P? D}?????EapA%??S?H?b??????k?ms"?? ?jd???EcD??VN??]????????Z???l?#????q1i??|??q ??x?=??z"? +H?/????}?[Ok;??1m?q5?E,??*????#3?]I???????>??d-?%T?(??@???K?????+??E??%?q"1?!??\?q???????? ?}!?)??`??u?;.?:X?Mt&?l????????+?3?Wa?*?v???????????/??????kE????N?:O?????3????)??GL6?????/U??;?O?????=??? G2?S???#?s YN??.Q|?P?,U??Ehc?c0n\????`r???4????p??Y?8#]????&x?b\??Jeuzy?[]?H?p!??vF??? ="?A?K]ksu?? 4d}??? F??kF??C??VL????(?mR]?`??{?????Y???`?Y ??>Lgr??@ ?J\???IR!?y6"W?????6 E????du ???"?Q?_??? ??3?z[5?e??w?$x?6! +yS???}?l?]?????|?;???{??[s?If~???P????t8?sk?,????KTg!??lG?.&}8W??b,}???,???= ?????????????TE?o2?3?e2E?)IJ?:vQ???o1P??}???? ?V??$????>???Q???8?????E?|&????P?R0??D????"??2dU?????d s?r????u.?D?z???? ?^D???ED?cu???"W5I?3??5?gO????????cY?{?%??R???M????#? ?? G??????eJ?????_v???? g?i??????p????pI9{?? !???`??y+??8??8-X?_I??M?j??/??????.dy ??12?v???1x\A???Wy????????T?dtmQ>eH????;G[???4??`?i?+?\? ^? ??M????>FgX?3zO? +.t?>??9CF??j?r?6???5?q"F????Gt??? g5???7H???r??X=??#) ?l-?c ??]??F? ??\hd??????n(?E??z?t\h?*?? ?O?!}:@ 52?s1m?5? >????????T?('?Y???wx?6?? ?U?6???T??k???O!r?2niZE??w0}_?8?T(???G??-?L??????M?R???#3?/???;???f??H7mjL?x'?(?Nq!?uZ +>L$?????_?GCC_I5'?\/I??D^?/?=??x????Zo,?]???l`?????y?7???I=???????????????Y????p?c4C?????????????naX/-/{????q/?U?R?E?J??U???_J?M??Xx?5?????%?????g$???$z????~?rf^c?N%?n?RD?? ?y"???????}????h???????b?Q?????9???N?+e?T]????b*???'/????0??\?=??!?("?-t??V???hn&e??1?{???3?5??S??~?j8q???O???????$q5?,???!??j +???-??|zB??iyx9???Z?????D?O??)';?9,+??kV$?I?_?DQ??"??Y???B????+???F9?P?3????n?\?????.???1MH?????+??|?%/Z?o!2??&V?????Qd ?CJ?a??"(? ?|3?A???C???? ?X?p??v????{?? ?$Ft>x?-??g??????????xT,jv???:? +g??.?@?a??? ???Db??h??+??FD?????>B?b 7im?[jh????+??v??????Z~KA28??>$?tQ??????:r???9:}:?????????c??h??!f)SH?????d?7???6sXf???A???R?.???V????D&????: V???m?i?????|r}?I?RD`_.???? ??2??u ?????Q?@?]2??C_?X??Z????????h??????N????]-f?A^n???P/?? lVB??? ?,?;u?? ?????X??=?a?R+???#8?1B?D$??&??ez?&????N ????jv??lG??l??a?q??? 4?3??f#?Bq?/?}?J?2??*????%|????1??5?Y?7d?;K?' ?$????t?>?????[6???????3??f;Il:???(5-/?&?N P?]????Z?? ?????J??? ?:? +q??VD?*??-?MG???~u?$?~op +?????P??*?????W???Z5?$?l?5??/l???!k????n??Q???'?+6??Bkx??R?DA??X? +_?c??3??=????????v?????V???E4 ? {??sd?? EN?T???|9?I?,&???O\?????;>n?yi??*?c???'/??c/SL??????S%a!?9????u????s??js??????4?%?????????o2?&?N???\?#???}#9???X??O? ???,?????y!???k??,}^??g???????=???E?~[+?????44????v???f?eX?16?y??8?/YX??9?I?N???v ROz%?;?????T???Vk??-|?;[%?!Mv?!? {??f??>???gN%?#-M?_a?*z!PE!CtGrK???4?l5?O?&???\?? ??S?`?????as? ?99?@?@ t?.j?q^m??f??oX?E???v????"?m? ?g??~?q2??$DD+M?"5?I?N??g[v|?2?????~??M?Y?oB??; ???q3U8???J~i??t?wB???} ??*???5??[i???@O?`a??`?B??!6x?B?#2?L??3??C???]????"?H??%p?/??!0??e???ho?b ?????endstream +endobj +172 0 obj << +/Type /Font +/Subtype /Type1 +/Encoding 517 0 R +/FirstChar 2 +/LastChar 252 +/Widths 523 0 R +/BaseFont /WMEMVN+URWPalladioL-Roma +/FontDescriptor 170 0 R +>> endobj +170 0 obj << +/Ascent 715 +/CapHeight 680 +/Descent -282 +/FontName /WMEMVN+URWPalladioL-Roma +/ItalicAngle 0 +/StemV 84 +/XHeight 469 +/FontBBox [-166 -283 1021 943] +/Flags 4 +/CharSet (/fi/fl/numbersign/quoteright/parenleft/parenright/asterisk/plus/comma/hyphen/period/slash/zero/one/two/three/four/five/six/seven/eight/nine/colon/semicolon/equal/greater/question/A/B/C/D/E/F/G/H/I/J/K/L/M/N/O/P/Q/R/S/T/U/V/W/X/bracketleft/bracketright/underscore/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/bar/quotedblleft/quotedblright/egrave/eacute/odieresis/udieresis) +/FontFile 171 0 R +>> endobj +523 0 obj +[605 608 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 500 0 0 0 278 333 333 389 606 250 333 250 606 500 500 500 500 500 500 500 500 500 500 250 250 0 606 606 444 0 778 611 709 774 611 556 763 832 337 333 726 611 946 831 786 604 786 668 525 613 778 722 1000 667 0 0 333 0 333 0 500 0 500 553 444 611 479 333 556 582 291 234 556 291 883 582 546 601 560 395 424 326 603 565 834 516 556 500 0 606 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 500 500 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 479 479 0 0 0 0 0 0 0 0 0 0 0 0 546 0 0 0 0 0 603 ] +endobj +159 0 obj << +/Length1 1614 +/Length2 21387 +/Length3 532 +/Length 22278 +/Filter /FlateDecode +>> +stream +x??xct$\?fl???v??mvlWl;wl?f????:?1?~???????????????g?g??j??*??)??Lh?????? PW?T2??52??1?mM?p?NfF.V@{1#3^???)@???? +`??????L???V?????K?`pv03???f?ab?????`?dg????;??`?dd??w.@?????????????"???a???L ???l?d???[UIL??<],?\???l?? ???4??????|a?z]????.f.??26?Z9;?y???????_4\???-??=???????????/?_????}????l=?? ?W???`??lfk??????????V?pL?????9???o?????????5 ?v??/ #S???'????I???$???Me??>??$?o??E???q??F??%?????Z???V????_I??xcr???#????????_#5??????"?b?w???`fd????Y????T????`nd?wJ??????9?Z???U?_?0?03?????????c????????R?+???3??H??????/?????*?????????Dh??????=? ,?6f???/6??K????Y???????o?3?i?~????_`??M?????????????_??&?NNU??????????fff&pk?@????t?:???I????,?????jE5?????J???P??i??v??S?????^,[????|_2??????\t?AL????g???W?r?:??????*?%?P???lN0WO4dn??H~&? q?](M hu??g??'O?T?c#?C=7?}?t9q?|n??Q?9??:??UMt????Q????[?r?J??&??7?L??$m??]?/??????5?jT???9?u?/>?/F?,?qB?C?I);c?I?Cp???;4L? +??N%??ePOek)d?Z? +/j??[b:?c??Sc???B?+???;vX????^?7A??fL~?2!?ZF+F.S?l?T???6??F t? ?s????Wig???OKV?q'i?????Xj?u5?,?????v????9?/`?Y?|=a%?$EJ"z?????? ? 5 ?Z M??b??o/?7kiqC????&|????% @??I?x?p?I?$,??,J?n?i??;??H?\r?WO???i??c8??t??xe F??E?v?>T??]Bz??=W??????+X??|?$P#???im????x +??k???????6?4?????????5????we[bs??i?? ?8,???Z{wA??????<?^????N8z?c-??Gk?1^???oJ1?? +? Q1??DGo??dz??????k)?hJ?-?G=?????[?)r yR*??e??Y?U??? D?=???/ns???7fh?r?:????$?u?Vu???????? +???(?:JE0u-???>z?Zv_???N)??(?B?0c/???6?? ?A?=[??\_?'Z?)q?f(+]??y\?????~??YJ???u?l_???Dd??(????E??&9????? 3Y?M]p?/Wbn0?? ????W???C??? 7I??@ ???s??????????"???6??}Z?n???v\????B??E?x?????*?????????3????e??NQ@`93???9????:??? C? ??P?F?p??r???8???7"??????VE???^n4?Q??#?^?\ e?0??V?e??5I????d?f?h?U?K????y???H??~?0??X??!?#'1?"$????!?????_M?e??x9:?Vt? ?1R??U????f_?l??=?p?n???? +??h??Jiu?&q LpYO9B??QE??Rh? c?5)???b??z??]?k????w*??s??ab?????~????-??< mS???????? +??gl. ????,?t????},H????D?????6 ???e???w?rOW?/?Z)/?d????K??k??N?b???Oh????+??%??????Q?&??2?V=??J8?%:YS??y???MxG?y??J???S???J?ti??8??????n?.?O?????Wb????PC ?j? ??}Y???????#?v(y??5,A ?$y????d??C`?9[?????TgM?a +{?d/G?M?!? +? Wj\?gtLv~q??Lia??$i? ?M?X?????4??w?F??}_&??9?????p\\4E ?'??X????J??&???9????};[t?3^8?Sybi??=t?????t??B???_?*g??.???????\?D??Z?K_?$??u? +$i???a"??}?S"L*Y,??_h??_f?Dk?????s^[??d 2?H??F7?;? ?????!s ????I0+??/?^wz7?,'?Q?#??K???????=dVh^?aN?b"??? =y???*.M???????gA???k??| ??g?`Tu????[?[D???_O?`?3s???????,Sr:E&??(?*Zn??/&???Gi???????Fw????d?p[?F?H??mI????x??$ ??v?????????@????G?:???U"??hv9MW??sV?"???5s??Yz??y???WT_? S[??????;1\??M?s?Y!w?"v????*??Qt_????I???%?)?m?D???R??oC? cY???M)B?$?o??=?|15?(0??,`?"???_??j?????????D?(t?0H?/?alhu?DD-]?+o?R?? &K?KUh????(?Z?O????i?.Z7c!???(??X???????z?.8`:???d???0???%o?????????? s?e????0??+??">4??)???X???.M?_|??U??;???2/?D?*??????????\?e????????&?%???-?? ???????%k<C?????S2???l6iV?2??o???"??(????>?????FH=T?J/P=^?8?[Sh&??.??9?D??_?????tk??}??sd???RKA?W?a i??JN?]c?????? +qf?y[?l]bbg??  v????5?9k>?B????? ???o?t31?m??????_(??????"XI +HDPfl?\??????q ?`?)~I?NDf?D?@?F4n????=n?F??eR??n????`?????`???m?*?b:???eb??-m???FXwj??? ????\Pp?p??K??6C????Wo???|????F~=/$???? ??yM??\?m???#M~????????0??~o??QW?v?w ?HH?as?v???H{+??%???E??g???A/???#??[?????2??^+??Y????Z?Wf:4%???? ?P?7???AH????F?S??????O? ??/???'???V +KR/??P5??^&5]YL?n??????EW?G4Fc???-?????T?w?D??o???;??@???????p???#7?????@}???|??+??????e? +g? +&YY???> u? U??d??l? +?H?2v?CT???x????kq????<??M1aR????Y??ii?4s#????K????3\fx?[?')?`"????W?F0???t?n????J?N?=??:????"????N?L/??SU%W???4&/s?1G?)????P?@5??2????f?Zl?R??|(?:7j??g?#?G???v???ig?C?j?C????Q'I+?-~??t????r??T???l|??pn?H??i?? ?@X3??"z?z?YDc?nx?/????%????9?g???%?."????b2Ot???O?SNAQj?Y:?m:\?z[???wH????J?H?Fi?9 ?M 7W???T5?^ ^g??;??.?;?E1??????m"? +????h(p?I?Bv????}a?*?????j???g+?K[x`?? ??H??E?QV????}? B'??'??7???????? r??U8p{?kT??$@? ?\??!????z)???e(???w? u ?}?!???Q??s+?$ld?????--??Y!?E??? ????z?] T? ????|t ?????=?????]?=???&l??6?8SOaXq??a?;H?"??>??????j?<7??4?!~5??????^?????;?O??z{?????ez?H?>?/?"?rz?P????), ???xE`?u?q?s?2??j "w<~??H?F???&a???>???#????YCZ????IZ?P-?g?a??)???Y??e????+???^????h?wW?F????L?H??p)r?5?? +??=??M?6??Qs?????KZD-3??????g?e???n?(?&z9-l??I?\bx?w?? +]?Nz?W???`?????|x|/4?O?A????UP?x^???????g???J?GI?????1?*?"??V?????hT?????M? ~kt?.$??9??{?:]???|?rzVt +!?????]??,[N sM?7?~?P?iG?Xh?`?X??_o??????*1?M?!??}?l?c????d?&7??T??"??tv??R V????t?T??~??? T??8u 4?}???/??W?l'_ +?>???$ ?5??q?u???,??X???D"E??g??W`??T?43q@??J???9?f??>\?J?#??x???g??l??rv???V??A.?v??8p?D{???S|?qL??? +???v????6P}????(2Ign??????g?nz?? +?-????d?+?F???????C +:?????G,?@???????]*????I}??jW?^?u???M????`o? ?6v??? +?.Je Me?\??~d?kE????m???a??Py?????=c#???0|??c?"^?????J???S????x??gQ#?E??\zA???kTh"???8????k??F??a???s???? +=(?1?r??|???K?j-???????`*???VCI?????\!?Z??Y at Zr???GU???r???*?j?? ???j???2?*???=???;?9???yA????p? S?,?4,?????N????n?E??'?;?7?P?Hj?K?????\:BC??`L????vC??{a?a?????^Ym?/?1b?=??!&?L?'?_Ox??4?7F?4? NA????!??????y?CXk?EN???|b?%B%???-?FV*??????e;? +mW??<=R??B?N0/qUL?XsL????????T????*?k?H|K ?????[??}???R3???r?%?+?} +?K??70 ??Y?tXpm??i???y???????5?h?&?f?/]?z=q??-???R???/&?3?p??/kp??_7?CJ|O??\????t??\@ 6rYB?k?O5????gC???????V1?9h3V?19H7?s'??;|?X???]Z???????????B? ???????U3??Z??4b?83?? i?Xu?Z?V"????T?<b??[pr???vV??cZ??6~??S%_??6A?\????Is??V9????u??????Qj?(g??'{?Y???9?&R?HY[?t?%? +L??Xh?7?|??h1?wZ?U@?&??? `i???L?? ??B?|w?%??????v???qy>????Pm&?????aZ?W"??X:U?!??t?;M?j_*?????9??L???O?????$?? p1?u???@??ks????? ??}u? >??#g|?~??? ?l}????t?? =?X?SSR??? `??3??k?$,????N??+e???I8?Gs<r +d? ?8Okd????+l?=P??????l??????????!?EVR?W&2??C?K(?????v??l?j%v?\}R???Z?[?A? ?c_s?????????`??}??i?}?R???? ???4??7??0?.?=?3???m ????a?c)f?L??Y???????U?K?????????pI???qm%?0?l?^????????u0?mS5?N?Q?i? }he??m??#?? +jiKf)T?b?????$?NB???(*B0g?c(?} +K?xd???MNkG?vd?t?m?_kC]@??:??8@????2?Y?5$??ZXV f???!CRCK??P~a?o?][??V?o??P??` 9k(R??????w????&????E??'??? ? Lu???*?)Y?.???? ??L???7?.?~?#??E ?????{?$?{a??;?????RW?? ??{?N???,???????N?'a?)????%{u +?dBb^v\??]???z?Xv??l??e?st????P?????9C?q??h??I?N+??(k???f2^?@?Pv??i?Y?sh?c3?I+g???^W?'?6e?????`?i?5]?A??!???X???????tt~d|??????v=??~???Z?tl8>X~?"????RY'??g??e"\J?????R??8kCD?A??8???J?l-??4??P?? ?N? ????{?&??8p??mI???(Al#???e#-?W??9?=? ????_?/6???yS??Z?p!?7VM??As}+8N?$?a?|LB??????"?0???`????U?_? ??)z??? j???s?u?w?~???0A?^VBZ?=6J?4 ????m??S?0??d?x????_?;? ?\????s?3y???"G*?k????????g`?{?????k??W?c?V??{??????E.a?L-'@???s?#}L,?? ?z??TH?KF ???????+L?XxE_Z9?5Mb?^, c?G?ed #;~^ ????S9?H> s m??y7>q????\??a???C?g?19???!?#??2d??? k?/?Qm??f???/[7/5?SR???%?{+"wiM??`??_B?A??????b????`uZ7??????*?kE?????xA=?S???n?y.y?u??????g?z5i#????|??t????d???)?EO+X??Xw:?z?A?H??{J?Gb? ??{??KG?+#???????L`T??!k??cg??????}W???U??? R????!.n??FtI???WP?N*??V|ja]???????X???$?XC? S???:???????,!???adM?d?CT?H??.~???.????hX????t??. +}??+Ja???Ef6? ??? ?O???B??N????k?C"? ?a????Z??;?@c??7?7T??W??~+????&;???\?0kX ??L?~?:?!g?????8m?????&:;??u1? S6M,?g4?'??J&????H?:?Ig=_?jc[?Y?@t?i?t????p?P?????r?l??i?k?H?? ??*??u\??=d?q?.??v?I??Xfpt????p?nwVp_?X.#???(k?(??n????& w`?c$???4%*??? +w?#???J#???~?d?`???j???qk?r??8?\?????H???[?5 >-@?l??|?P?~h?x?$?;??A&|?E??{D8??~??Y9Z??/ 9????6???85F??n?&????#p?H???????F??-Z?????????F?kD'?yH???? y????V?.I?g1i?^-?????5??aj?????O????????Sz?b???A??? ?^@y$l?:?x???ZEa ????????>i???)??N?U???@?J??OTx?HpZk#??;q??? ? +^????D +:?o?2??_4??@w??????1?G at D?&??u?E??!.?wEP????A*???*???? ??Y?V????zI? ?? P??????????t??????u}?T?Kz??`n,a??V??4$???& ???t?5???u?,/?P1?Av?\?|???3???????g????TR? +8?L???6M???~?U?7gt???O??????????G?B?s??e?????????X???=??;?po???O0??5??D3j??? #??'3?-??/?;?T?a^??_??0??E??)r????dz?jt??l???H+??L?-?Oiw!6?q?R ?????b}?$?-?? ??Z????SCi??8a'?7?? ??Y)??]?2'##??!??^???O+??G?0?b??5q?5?ud?? l!?{ZF?i??1?????R???x?????Q??X??U???_??G?~??e????(q????I?5?Q~?G?\,???7>?,? L?"yKb??"}N&T???a?\n?V??>?V-??v??ie??LiK???;w??5O&]??!_?a aZ??q??BS?{???5=?^G???4<]??}???Y???g??b????Q?Q?a??#wk|?[??Dx??tG?f??$P????8?C>?!H???F?@???E?Q??i?S?C?????????aW[pv????m??X????e??a}?_???Wd??V?w?IC?????p#?e???K~q?? OS?m???Q????0z??@`Q??Q????emy?[?>3?5????y$?lu?? +O=??(????t??? +??LNn? ???:LG?k?Q??:18??? ??RK?=Od???? ?X???????*4& ?qTq0????v-????sl?? +??????b?p????/Z?????=?\?N2?xrU?LlG??:??l????z???????d?pBg?B6!f?}?????S??ZYZ???R?!??M??4JX????jP!??????/???/i? +G?Eaz? +S+iy???.???*???t@??c??o??o;+l*wF?#}??~ ep???7?<bh?sz???????E?*?o3k$???????47????U????)????}%??cB?x???oE??#>??Zpf?pD??????L?v?x?e ??~mg????p???k???W???.>? +??T?L8,????FT????S ?d4O?qWT7??_Jl?oL??Mt%?`?I?t?g??Y?dtB&??6?N#K???k:???Lu*U????4??\g!lBy?????>?g?c?g??$;#gU???U????T?????F?@?S??9?u????o?ou?????5plD?ZERa?\R???7???v?_"~DQ??k?ILVe9?qFT|??!Q??U???f|;??????(???) b?T?G??PBD??n????;??/Fiawu?%F??o :???),o? ?N? ?h??jX?:]?>????AR?`?^?~o|?????? 2??<4(Y???dKd?D????+?????X1G????%????\Ss,?N\?K?7T?? e????:b?[,V?lP?3?r?>??|fRY??t[h-???98I??_? +E]?o?%?P? }w????Q????D?> +?U?Qi?C???e?/?N?(?? ?8?CAq??Gxe"iI?-?#?x??I???v???F?>???? ?|???u??Bk.????? ?f??".?B8, ??A???h?E,?!M2?Mh?????!?? m??$????wL>?TN???s?Fa????AH???#$?b?????b?B??g??UC????k?? ?f??????&;?|????5#mR9&??>F???dKJ???f????`o?H?q{???1??4???-?4h??.{????2]&?????6?o???dF??g?X?5xg?H? j???Q?N@(J?e????xV?;???hg???p???=m??9s???n_9?????f?mj&????i??NL?????x{????WREX?????z??T?????i??d??%??M?ILK?n\K&??%L?\?=?M???bwR????????vj4?{??P???????? r?u??? ??Gf?#?$sm?h?p+N???QU??hU????nA,g???mK?|?4<|u????=}u??8?d;?!%?????/???Zh>???"l?A??o???1??U? N?EEkQ?cv???o??????#6??]w??gb?? 4??sP??39???????$S6??J??we?k?'??:????4?|? +?mPE?????>-?????y??G??C^??M??????$=Z@ e<?W}r?0?.I??^c??It? `W.;?}??~??N?V????L?W??9??]????=M???0????? 'W???\?eT4I?POV????@=??? ??Ix??o??f=??????n?1k- +?%i???h2a???B?~[????gF?{B?d???6?%?l}???q2M?????}w???????3??R??k.k??? ????????/?Dw??v?|^l ??I?? ? +??*h??????l?^?U???|$??????g??????np??T???x???r?3Q"???}???????e??G.U?bY?'f??<2?m*??????4?]????k?C?8???(?4?????l? \?_3???^_Xuf?XP*?????'????:r?l?}???? ??:nv???4???o??^l/??? 9?W-VF?????S?r'm?:&z??????u??'=?G~?c??^?"??? ??1@?\???^??(????H$?+?[X?5?????Uw8??y?????Ag:??M=?[????byia?]?K?? ??i???HS?TX???Mo??2,?i?U?cS?? h???? ?;?????>)? ??S??9? ??bWm?????`?'?!?;?t;?$*<|?-??G3???M?\???I??j?KDgm??T??S?u??t????<*XJR??-!??#h XV?MZx??GG??$sBS??D?J&E? ????!?3???????m?v?W;??k???=??;??$???n9K??.?'?8?K2?PV6N?J?U??e?V!??9??!???9???_?D??e??1?z'x?yE??r??#q?#?M??!?4??/2??y=F????%~?<???A???$i?dS?????KK?T? ??L?< +? ?is??????~?q+ +;?6?;?F????T?S0?9?T,??????l???????D??????G??9?_?t??????;J????{?vq??C??@??C???3??[ ????,n&?Q?a?\]"?.?????A???%??8K??-????N:???C?????N????L?I?'??????0???@??Z$=[W????U???2?u?%X ?'??;???h?????$z at MJ? ???,?????L?x|?B????????"$?h???Ej?I?f ?s[?r?=iEK????l?pA??????t?? f?{????????\-??3?T[f? ?????????KQ ? +?????:???P?i??b???iS??w????????????sb???V?"l?? ??N[?2?R3??%????y?b??t# ???$I??!?`?e?)?????????y??v??)W???B??Y?j"?V???t???[?? ??b?qB?>%?Otw?}t? ?X????j??L????s??2?$l? +?*?7??%.?+??????b??h(???????4?Y??7b?w???????/??uf?? +???????C???S??i???8[c?z?'??????$?]?uZZz??kyB???Xkoo???']?w????????A?"?????qu??p?????dQ??\????9?? T?}???H?`?3????s???`d??M?L/???R?? ?0?{???H~Mo????1??h??N?? +??v??{K?T?? ??W????????2?v???F?;??'????? ?!??i???((??.???_j?M?,??u?m?zk?L??????x?????c????h??}+v?b??'??0?????B#??a8??c%iU?????y3??f?dPf??G?P|?????eL??Z???o?U??u?z?k???3g >?F8/\??* ?t:?%?t???;"'zMO?8?????8???68????A?"jH?U~???????gm??lQ4???3????????Y? ???$fEl??????_c??d?]_?)k??u?y??y??l-?:~?oh.]+?n?OP?? ??? Wg@??)Z?7???W;?-???M?) ????(????T???!?osBI??PI??=?1??*??0??. at S??????2????GC|???R????? ?m?????m8??)Jm??j?:?/???M??? ? LiF?????/??w?j;?r0":Y?0???g?o??Q??C??r?????0J???\? ?????Ie????U???<=??.????"?N????UA??\0?????F?IN?SV{??$???u)????|???P?t?|$i????P?%??zj(?2?5*b?dcdN???p??I?t??T?^|????;9Md?????q?Z?^?7$?#???i?x'"?U??E??Ww?]+? Q>??lO??4???_#?????oH?k?E?????e?S0????&`[E??J#]|aT??????}??7??z+??Lf>?ib1 ?|-?}??????fBj?|l/?????lzx'??E%?? ?N?f?DD??lF??U6!?$, ??"c ?!??~??\&?v????;$Xb!j?0???}L??I?? ? ???4 +???Tr????c??h??bj?:E?*K?^??p?@{?}Y?g????2bv?EY I??? ?????&?+?l?p?U??OGZ???eF??I?4?????o???~??+??p??3??rG?cw??? ??`_'??4?Ba???(????j?????C?H???j?? @?????n_???/?~UIm??1j +hx???/?????Z? ?????.???105??V??f??O?b?~R????m?f??(?k?-?Hd??n(P??Jj?k+?Mo?bI?????~??0???????2!? ?u?y0r???F?pe?+# ??/?"{??n???Z??7J?D?n ?K???'??ct???c?&+? ???UP?}?+z>.G?E??????e?8F??C???1?9?p???G? ?`2?? +?? 7@??,??"p??T????e?iD???'??j J1l???%$4x?s??Z6?(2?/??"?q?????p??v!???endstream +endobj +160 0 obj << +/Type /Font +/Subtype /Type1 +/Encoding 517 0 R +/FirstChar 2 +/LastChar 233 +/Widths 524 0 R +/BaseFont /DJILZK+URWPalladioL-Bold +/FontDescriptor 158 0 R +>> endobj +158 0 obj << +/Ascent 708 +/CapHeight 672 +/Descent -266 +/FontName /DJILZK+URWPalladioL-Bold +/ItalicAngle 0 +/StemV 123 +/XHeight 471 +/FontBBox [-152 -301 1000 935] +/Flags 4 +/CharSet (/fi/fl/parenleft/parenright/comma/hyphen/period/slash/zero/one/two/three/four/five/six/seven/eight/nine/colon/A/B/C/D/E/F/G/H/I/K/L/M/N/O/P/R/S/T/U/W/Y/underscore/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/eacute) +/FontFile 159 0 R +>> endobj +524 0 obj +[611 611 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 333 333 0 0 250 333 250 296 500 500 500 500 500 500 500 500 500 500 250 0 0 0 0 0 0 778 667 722 833 611 556 833 833 389 0 778 611 1000 833 833 611 0 722 611 667 778 0 1000 0 667 0 0 0 0 0 500 0 500 611 444 611 500 389 556 611 333 333 611 333 889 611 556 611 611 389 444 333 611 556 833 500 556 500 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 500 ] +endobj +161 0 obj << +/Type /Pages +/Count 6 +/Parent 525 0 R +/Kids [150 0 R 167 0 R 179 0 R 217 0 R 226 0 R 242 0 R] +>> endobj +264 0 obj << +/Type /Pages +/Count 6 +/Parent 525 0 R +/Kids [247 0 R 268 0 R 305 0 R 328 0 R 335 0 R 343 0 R] +>> endobj +354 0 obj << +/Type /Pages +/Count 6 +/Parent 525 0 R +/Kids [350 0 R 356 0 R 366 0 R 371 0 R 381 0 R 389 0 R] +>> endobj +407 0 obj << +/Type /Pages +/Count 6 +/Parent 525 0 R +/Kids [399 0 R 409 0 R 419 0 R 432 0 R 437 0 R 457 0 R] +>> endobj +497 0 obj << +/Type /Pages +/Count 3 +/Parent 525 0 R +/Kids [484 0 R 499 0 R 510 0 R] +>> endobj +525 0 obj << +/Type /Pages +/Count 27 +/Kids [161 0 R 264 0 R 354 0 R 407 0 R 497 0 R] +>> endobj +526 0 obj << +/Type /Outlines +/First 7 0 R +/Last 147 0 R +/Count 9 +>> endobj +147 0 obj << +/Title 148 0 R +/A 145 0 R +/Parent 526 0 R +/Prev 135 0 R +>> endobj +143 0 obj << +/Title 144 0 R +/A 141 0 R +/Parent 135 0 R +/Prev 139 0 R +>> endobj +139 0 obj << +/Title 140 0 R +/A 137 0 R +/Parent 135 0 R +/Next 143 0 R +>> endobj +135 0 obj << +/Title 136 0 R +/A 133 0 R +/Parent 526 0 R +/Prev 119 0 R +/Next 147 0 R +/First 139 0 R +/Last 143 0 R +/Count -2 +>> endobj +131 0 obj << +/Title 132 0 R +/A 129 0 R +/Parent 119 0 R +/Prev 127 0 R +>> endobj +127 0 obj << +/Title 128 0 R +/A 125 0 R +/Parent 119 0 R +/Prev 123 0 R +/Next 131 0 R +>> endobj +123 0 obj << +/Title 124 0 R +/A 121 0 R +/Parent 119 0 R +/Next 127 0 R +>> endobj +119 0 obj << +/Title 120 0 R +/A 117 0 R +/Parent 526 0 R +/Prev 115 0 R +/Next 135 0 R +/First 123 0 R +/Last 131 0 R +/Count -3 +>> endobj +115 0 obj << +/Title 116 0 R +/A 113 0 R +/Parent 526 0 R +/Prev 83 0 R +/Next 119 0 R +>> endobj +111 0 obj << +/Title 112 0 R +/A 109 0 R +/Parent 83 0 R +/Prev 107 0 R +>> endobj +107 0 obj << +/Title 108 0 R +/A 105 0 R +/Parent 83 0 R +/Prev 103 0 R +/Next 111 0 R +>> endobj +103 0 obj << +/Title 104 0 R +/A 101 0 R +/Parent 83 0 R +/Prev 99 0 R +/Next 107 0 R +>> endobj +99 0 obj << +/Title 100 0 R +/A 97 0 R +/Parent 83 0 R +/Prev 95 0 R +/Next 103 0 R +>> endobj +95 0 obj << +/Title 96 0 R +/A 93 0 R +/Parent 83 0 R +/Prev 91 0 R +/Next 99 0 R +>> endobj +91 0 obj << +/Title 92 0 R +/A 89 0 R +/Parent 83 0 R +/Prev 87 0 R +/Next 95 0 R +>> endobj +87 0 obj << +/Title 88 0 R +/A 85 0 R +/Parent 83 0 R +/Next 91 0 R +>> endobj +83 0 obj << +/Title 84 0 R +/A 81 0 R +/Parent 526 0 R +/Prev 63 0 R +/Next 115 0 R +/First 87 0 R +/Last 111 0 R +/Count -7 +>> endobj +79 0 obj << +/Title 80 0 R +/A 77 0 R +/Parent 63 0 R +/Prev 75 0 R +>> endobj +75 0 obj << +/Title 76 0 R +/A 73 0 R +/Parent 63 0 R +/Prev 71 0 R +/Next 79 0 R +>> endobj +71 0 obj << +/Title 72 0 R +/A 69 0 R +/Parent 63 0 R +/Prev 67 0 R +/Next 75 0 R +>> endobj +67 0 obj << +/Title 68 0 R +/A 65 0 R +/Parent 63 0 R +/Next 71 0 R +>> endobj +63 0 obj << +/Title 64 0 R +/A 61 0 R +/Parent 526 0 R +/Prev 31 0 R +/Next 83 0 R +/First 67 0 R +/Last 79 0 R +/Count -4 +>> endobj +59 0 obj << +/Title 60 0 R +/A 57 0 R +/Parent 31 0 R +/Prev 55 0 R +>> endobj +55 0 obj << +/Title 56 0 R +/A 53 0 R +/Parent 31 0 R +/Prev 51 0 R +/Next 59 0 R +>> endobj +51 0 obj << +/Title 52 0 R +/A 49 0 R +/Parent 31 0 R +/Prev 47 0 R +/Next 55 0 R +>> endobj +47 0 obj << +/Title 48 0 R +/A 45 0 R +/Parent 31 0 R +/Prev 43 0 R +/Next 51 0 R +>> endobj +43 0 obj << +/Title 44 0 R +/A 41 0 R +/Parent 31 0 R +/Prev 39 0 R +/Next 47 0 R +>> endobj +39 0 obj << +/Title 40 0 R +/A 37 0 R +/Parent 31 0 R +/Prev 35 0 R +/Next 43 0 R +>> endobj +35 0 obj << +/Title 36 0 R +/A 33 0 R +/Parent 31 0 R +/Next 39 0 R +>> endobj +31 0 obj << +/Title 32 0 R +/A 29 0 R +/Parent 526 0 R +/Prev 11 0 R +/Next 63 0 R +/First 35 0 R +/Last 59 0 R +/Count -7 +>> endobj +27 0 obj << +/Title 28 0 R +/A 25 0 R +/Parent 11 0 R +/Prev 23 0 R +>> endobj +23 0 obj << +/Title 24 0 R +/A 21 0 R +/Parent 11 0 R +/Prev 19 0 R +/Next 27 0 R +>> endobj +19 0 obj << +/Title 20 0 R +/A 17 0 R +/Parent 11 0 R +/Prev 15 0 R +/Next 23 0 R +>> endobj +15 0 obj << +/Title 16 0 R +/A 13 0 R +/Parent 11 0 R +/Next 19 0 R +>> endobj +11 0 obj << +/Title 12 0 R +/A 9 0 R +/Parent 526 0 R +/Prev 7 0 R +/Next 31 0 R +/First 15 0 R +/Last 27 0 R +/Count -4 +>> endobj +7 0 obj << +/Title 8 0 R +/A 5 0 R +/Parent 526 0 R +/Next 11 0 R +>> endobj +527 0 obj << +/Names [(Doc-Start) 156 0 R (Item.1) 259 0 R (Item.2) 260 0 R (Item.3) 261 0 R (Item.4) 262 0 R (Item.5) 263 0 R (assessing-benefits) 506 0 R (basic-elements-serving-deterministic-logic-programming) 340 0 R (choice-points) 377 0 R (cite.AIJ94) 302 0 R (cite.AKL91) 325 0 R (cite.CCLP93) 299 0 R (cite.CCP90) 324 0 R (cite.CHR98) 326 0 R (cite.CPM01) 513 0 R (cite.CPR87) 322 0 R (cite.D07.4) 429 0 R (cite.ECP94) 265 0 R (cite.GHC87) 323 0 R (cite.MAC97) 266 0 R (cite.MCC59) 301 0 R (cite.OPM95) 300 0 R (cite.OWL) 455 0 R (cite.PAR86) 321 0 R (cite.PCS00) 333 0 R (cite.PRLG92) 298 0 R (cite.PVR02) 303 0 R (cite.SPQL) 240 0 R (cite.TVC99) 430 0 R (conclusion) 507 0 R (concurrent-constraint-and-logic-programming) 251 0 R (constraint-handling-rules) 319 0 R (constraint-programming-and-mac) 286 0 R (constraint-programs) 387 0 R (driving-logic-programs-with-computation-spaces) 385 0 R (example-of-using-the-owl-reasoner) 495 0 R (executive-summary) 230 0 R (extending-the-search-engine) 404 0 R (from-backtracking-engines-to-cclp) 297 0 R (from-cclp-to-oz-to-python-anecdotal-bits) 317 0 R (getting-solutions) 396 0 R (getting-started) 236 0 R (history-of-the-implementation-credits) 428 0 R (id24) 403 0 R (id28) 425 0 R (implementation-aspects) 364 0 R (implementation-of-builtin-owl-predicates) 479 0 R (implementation-of-builtin-owl-types) 454 0 R (implementation-of-owl-class) 461 0 R (implementation-of-owl-datatypeproperty) 475 0 R (implementation-of-owl-equivalentclass) 493 0 R (implementation-of-owl-equivalentproperty) 489 0 R (implementation-of-owl-functionalproperty) 469 0 R (implementation-of-owl-inversefunctionalproperty) 471 0 R (implementation-of-owl-inverseproperty) 477 0 R (implementation-of-owl-nothing) 465 0 R (implementation-of-owl-oneof) 480 0 R (implementation-of-owl-subclassof) 491 0 R (implementation-of-owl-thing) 463 0 R (implementation-of-owl-transistiveproperty) 473 0 R (implementation-of-rdf-property) 467 0 R (implementation-of-rdf-type) 482 0 R (implementation-of-the-owl-reasoner) 448 0 R (introduction) 231 0 R (limits-of-prolog-and-mac) 290 0 R (logic-programming-in-prolog) 277 0 R (logic-programming-in-pypy) 339 0 R (motivation) 252 0 R (non-deterministic-logic-programs) 376 0 R (page.1) 155 0 R (page.10) 330 0 R (page.11) 337 0 R (page.12) 345 0 R (page.13) 352 0 R (page.14) 358 0 R (page.15) 368 0 R (page.16) 373 0 R (page.17) 383 0 R (page.18) 391 0 R (page.19) 401 0 R (page.2) 169 0 R (page.20) 411 0 R (page.21) 421 0 R (page.22) 434 0 R (page.23) 439 0 R (page.24) 459 0 R (page.25) 486 0 R (page.26) 501 0 R (page.27) 177 0 R (page.3) 181 0 R (page.4) 219 0 R (page.5) 228 0 R (page.6) 244 0 R (page.7) 249 0 R (page.8) 270 0 R (page.9) 307 0 R (programming-with-search) 375 0 R (purpose-of-this-document) 232 0 R (related-documents) 235 0 R (scope-of-this-document) 233 0 R (searching-the-language-technology-world) 503 0 R (section*.1) 174 0 R (section*.2) 176 0 R (section*.3) 183 0 R (section*.4) 508 0 R (section.1) 6 0 R (section.2) 10 0 R (section.3) 30 0 R (section.4) 62 0 R (section.5) 82 0 R (section.6) 114 0 R (section.7) 118 0 R (section.8) 134 0 R (section.9) 146 0 R (semantic-web-reasoning-in-owl) 441 0 R (specification-of-a-problem) 394 0 R (subsection.2.1) 14 0 R (subsection.2.2) 18 0 R (subsection.2.3) 22 0 R (subsection.2.4) 26 0 R (subsection.3.1) 34 0 R (subsection.3.2) 38 0 R (subsection.3.3) 42 0 R (subsection.3.4) 46 0 R (subsection.3.5) 50 0 R (subsection.3.6) 54 0 R (subsection.3.7) 58 0 R (subsection.4.1) 66 0 R (subsection.4.2) 70 0 R (subsection.4.3) 74 0 R (subsection.4.4) 78 0 R (subsection.5.1) 86 0 R (subsection.5.2) 90 0 R (subsection.5.3) 94 0 R (subsection.5.4) 98 0 R (subsection.5.5) 102 0 R (subsection.5.6) 106 0 R (subsection.5.7) 110 0 R (subsection.7.1) 122 0 R (subsection.7.2) 126 0 R (subsection.7.3) 130 0 R (subsection.8.1) 138 0 R (subsection.8.2) 142 0 R (subsubsection.5.1.1) 378 0 R (subsubsection.5.1.2) 386 0 R (subsubsection.5.3.1) 395 0 R (subsubsection.5.3.2) 397 0 R (subsubsection.5.5.1) 413 0 R (subsubsection.5.5.2) 423 0 R (subsubsection.7.1.1) 462 0 R (subsubsection.7.1.2) 464 0 R (subsubsection.7.1.3) 466 0 R (subsubsection.7.1.4) 468 0 R (subsubsection.7.1.5) 470 0 R (subsubsection.7.1.6) 472 0 R (subsubsection.7.1.7) 474 0 R (subsubsection.7.1.8) 476 0 R (subsubsection.7.1.9) 478 0 R (subsubsection.7.2.1) 481 0 R (subsubsection.7.2.2) 488 0 R (subsubsection.7.2.3) 490 0 R (subsubsection.7.2.4) 492 0 R (subsubsection.7.2.5) 494 0 R (table-of-operators) 363 0 R (table.1) 157 0 R (table.2) 175 0 R (threads-and-dataflow-synchronization) 348 0 R (using-distributors) 417 0 R (using-the-constraint-engine) 393 0 R (using-the-results-for-semantic-web-applications) 496 0 R (writing-a-solver) 406 0 R] +/Limits [(Doc-Start) (writing-a-solver)] +>> endobj +528 0 obj << +/Kids [527 0 R] +>> endobj +529 0 obj << +/Dests 528 0 R +>> endobj +530 0 obj << +/Type /Catalog +/Pages 525 0 R +/Outlines 526 0 R +/Names 529 0 R +/PageMode /UseOutlines +/OpenAction 149 0 R +>> endobj +531 0 obj << +/Author()/Title()/Subject()/Creator(LaTeX with hyperref package)/Producer(pdfeTeX-1.21a)/Keywords() +/CreationDate (D:20070228165234+01'00') +/PTEX.Fullbanner (This is pdfeTeX, Version 3.141592-1.21a-2.2 (Web2C 7.5.4) kpathsea version 3.5.4) +>> endobj +xref +0 532 +0000000001 65535 f +0000000002 00000 f +0000000003 00000 f +0000000004 00000 f +0000000000 00000 f +0000000009 00000 n +0000034656 00000 n +0000223316 00000 n +0000000054 00000 n +0000000089 00000 n +0000034780 00000 n +0000223193 00000 n +0000000134 00000 n +0000000165 00000 n +0000034905 00000 n +0000223119 00000 n +0000000216 00000 n +0000000259 00000 n +0000035030 00000 n +0000223032 00000 n +0000000310 00000 n +0000000351 00000 n +0000035154 00000 n +0000222945 00000 n +0000000402 00000 n +0000000438 00000 n +0000035278 00000 n +0000222871 00000 n +0000000489 00000 n +0000000523 00000 n +0000041908 00000 n +0000222746 00000 n +0000000569 00000 n +0000000631 00000 n +0000042033 00000 n +0000222672 00000 n +0000000682 00000 n +0000000711 00000 n +0000049721 00000 n +0000222585 00000 n +0000000762 00000 n +0000000808 00000 n +0000049846 00000 n +0000222498 00000 n +0000000859 00000 n +0000000908 00000 n +0000049971 00000 n +0000222411 00000 n +0000000959 00000 n +0000001002 00000 n +0000055654 00000 n +0000222324 00000 n +0000001053 00000 n +0000001105 00000 n +0000055779 00000 n +0000222237 00000 n +0000001156 00000 n +0000001219 00000 n +0000055904 00000 n +0000222163 00000 n +0000001270 00000 n +0000001314 00000 n +0000061061 00000 n +0000222038 00000 n +0000001360 00000 n +0000001404 00000 n +0000061186 00000 n +0000221964 00000 n +0000001455 00000 n +0000001528 00000 n +0000064314 00000 n +0000221877 00000 n +0000001579 00000 n +0000001634 00000 n +0000070045 00000 n +0000221790 00000 n +0000001685 00000 n +0000001722 00000 n +0000070169 00000 n +0000221716 00000 n +0000001773 00000 n +0000001814 00000 n +0000074962 00000 n +0000221589 00000 n +0000001860 00000 n +0000001902 00000 n +0000075087 00000 n +0000221515 00000 n +0000001953 00000 n +0000002004 00000 n +0000081643 00000 n +0000221428 00000 n +0000002055 00000 n +0000002093 00000 n +0000081768 00000 n +0000221341 00000 n +0000002144 00000 n +0000002190 00000 n +0000085157 00000 n +0000221252 00000 n +0000002241 00000 n +0000002279 00000 n +0000085282 00000 n +0000221161 00000 n +0000002331 00000 n +0000002378 00000 n +0000093964 00000 n +0000221069 00000 n +0000002430 00000 n +0000002472 00000 n +0000095949 00000 n +0000220991 00000 n +0000002524 00000 n +0000002582 00000 n +0000102145 00000 n +0000220899 00000 n +0000002629 00000 n +0000002679 00000 n +0000102271 00000 n +0000220767 00000 n +0000002726 00000 n +0000002780 00000 n +0000104451 00000 n +0000220688 00000 n +0000002832 00000 n +0000002887 00000 n +0000105710 00000 n +0000220595 00000 n +0000002939 00000 n +0000002999 00000 n +0000108823 00000 n +0000220516 00000 n +0000003051 00000 n +0000003104 00000 n +0000112680 00000 n +0000220384 00000 n +0000003151 00000 n +0000003218 00000 n +0000112806 00000 n +0000220305 00000 n +0000003270 00000 n +0000003329 00000 n +0000112932 00000 n +0000220226 00000 n +0000003381 00000 n +0000003419 00000 n +0000113058 00000 n +0000220147 00000 n +0000003466 00000 n +0000003496 00000 n +0000004742 00000 n +0000004864 00000 n +0000006995 00000 n +0000018570 00000 n +0000003548 00000 n +0000018381 00000 n +0000018444 00000 n +0000018507 00000 n +0000218365 00000 n +0000195793 00000 n +0000218193 00000 n +0000219417 00000 n +0000006712 00000 n +0000018222 00000 n +0000018278 00000 n +0000018358 00000 n +0000021035 00000 n +0000020490 00000 n +0000018699 00000 n +0000020784 00000 n +0000194509 00000 n +0000169214 00000 n +0000194337 00000 n +0000020632 00000 n +0000020847 00000 n +0000020910 00000 n +0000020973 00000 n +0000117221 00000 n +0000029632 00000 n +0000023885 00000 n +0000021164 00000 n +0000029506 00000 n +0000024283 00000 n +0000029569 00000 n +0000024435 00000 n +0000024590 00000 n +0000024745 00000 n +0000024903 00000 n +0000025063 00000 n +0000025223 00000 n +0000025383 00000 n +0000025538 00000 n +0000025698 00000 n +0000025858 00000 n +0000026018 00000 n +0000026178 00000 n +0000026336 00000 n +0000026495 00000 n +0000026655 00000 n +0000026810 00000 n +0000026969 00000 n +0000027128 00000 n +0000027288 00000 n +0000027448 00000 n +0000027602 00000 n +0000027762 00000 n +0000027922 00000 n +0000028082 00000 n +0000028242 00000 n +0000028401 00000 n +0000028560 00000 n +0000028719 00000 n +0000028874 00000 n +0000029029 00000 n +0000029189 00000 n +0000029348 00000 n +0000031575 00000 n +0000030557 00000 n +0000029761 00000 n +0000031512 00000 n +0000030731 00000 n +0000030883 00000 n +0000031038 00000 n +0000031198 00000 n +0000031357 00000 n +0000035340 00000 n +0000034074 00000 n +0000031704 00000 n +0000034530 00000 n +0000034224 00000 n +0000034593 00000 n +0000034717 00000 n +0000034842 00000 n +0000034967 00000 n +0000034376 00000 n +0000035091 00000 n +0000035216 00000 n +0000168326 00000 n +0000150472 00000 n +0000168155 00000 n +0000118354 00000 n +0000036457 00000 n +0000036100 00000 n +0000035482 00000 n +0000036394 00000 n +0000036242 00000 n +0000042408 00000 n +0000040359 00000 n +0000036599 00000 n +0000041782 00000 n +0000040549 00000 n +0000041845 00000 n +0000041970 00000 n +0000040701 00000 n +0000040875 00000 n +0000041055 00000 n +0000041282 00000 n +0000041439 00000 n +0000041625 00000 n +0000042095 00000 n +0000042158 00000 n +0000042221 00000 n +0000042282 00000 n +0000042345 00000 n +0000219534 00000 n +0000117284 00000 n +0000117410 00000 n +0000050094 00000 n +0000046354 00000 n +0000042537 00000 n +0000049595 00000 n +0000046624 00000 n +0000046776 00000 n +0000046934 00000 n +0000047091 00000 n +0000047249 00000 n +0000047424 00000 n +0000049658 00000 n +0000149828 00000 n +0000131281 00000 n +0000149645 00000 n +0000047580 00000 n +0000047737 00000 n +0000047945 00000 n +0000048148 00000 n +0000048341 00000 n +0000049783 00000 n +0000048533 00000 n +0000048721 00000 n +0000048913 00000 n +0000049908 00000 n +0000049069 00000 n +0000049248 00000 n +0000130961 00000 n +0000129571 00000 n +0000130800 00000 n +0000049405 00000 n +0000050033 00000 n +0000117347 00000 n +0000117473 00000 n +0000113245 00000 n +0000117536 00000 n +0000117599 00000 n +0000117662 00000 n +0000055965 00000 n +0000054130 00000 n +0000050249 00000 n +0000055591 00000 n +0000054328 00000 n +0000054480 00000 n +0000054634 00000 n +0000054790 00000 n +0000129250 00000 n +0000120447 00000 n +0000129077 00000 n +0000054947 00000 n +0000055104 00000 n +0000055716 00000 n +0000055260 00000 n +0000055841 00000 n +0000055435 00000 n +0000117725 00000 n +0000117851 00000 n +0000117788 00000 n +0000117914 00000 n +0000117977 00000 n +0000118040 00000 n +0000057685 00000 n +0000057163 00000 n +0000056120 00000 n +0000057622 00000 n +0000057313 00000 n +0000057465 00000 n +0000118165 00000 n +0000061248 00000 n +0000060442 00000 n +0000057814 00000 n +0000060935 00000 n +0000060592 00000 n +0000060998 00000 n +0000061123 00000 n +0000060744 00000 n +0000064376 00000 n +0000063687 00000 n +0000061429 00000 n +0000064188 00000 n +0000063837 00000 n +0000063989 00000 n +0000064251 00000 n +0000066487 00000 n +0000066130 00000 n +0000064531 00000 n +0000066424 00000 n +0000066272 00000 n +0000219651 00000 n +0000070231 00000 n +0000069046 00000 n +0000066642 00000 n +0000069919 00000 n +0000069212 00000 n +0000069364 00000 n +0000069569 00000 n +0000069743 00000 n +0000069982 00000 n +0000070106 00000 n +0000072044 00000 n +0000071687 00000 n +0000070386 00000 n +0000071981 00000 n +0000071829 00000 n +0000075275 00000 n +0000074324 00000 n +0000072186 00000 n +0000074836 00000 n +0000074474 00000 n +0000074899 00000 n +0000075024 00000 n +0000075149 00000 n +0000075212 00000 n +0000074626 00000 n +0000078625 00000 n +0000078083 00000 n +0000075430 00000 n +0000078377 00000 n +0000078225 00000 n +0000078440 00000 n +0000078502 00000 n +0000078564 00000 n +0000082080 00000 n +0000081286 00000 n +0000078793 00000 n +0000081580 00000 n +0000081428 00000 n +0000081705 00000 n +0000081830 00000 n +0000081892 00000 n +0000081954 00000 n +0000082017 00000 n +0000085408 00000 n +0000084573 00000 n +0000082235 00000 n +0000085031 00000 n +0000084723 00000 n +0000085094 00000 n +0000085219 00000 n +0000084875 00000 n +0000085345 00000 n +0000219768 00000 n +0000089723 00000 n +0000088599 00000 n +0000085563 00000 n +0000089536 00000 n +0000088765 00000 n +0000089599 00000 n +0000088917 00000 n +0000089147 00000 n +0000089379 00000 n +0000089662 00000 n +0000094090 00000 n +0000092988 00000 n +0000089891 00000 n +0000093775 00000 n +0000093154 00000 n +0000093838 00000 n +0000093306 00000 n +0000093901 00000 n +0000093463 00000 n +0000093620 00000 n +0000094027 00000 n +0000113182 00000 n +0000118103 00000 n +0000096012 00000 n +0000095592 00000 n +0000094245 00000 n +0000095886 00000 n +0000095734 00000 n +0000102395 00000 n +0000099613 00000 n +0000096141 00000 n +0000102019 00000 n +0000099843 00000 n +0000102082 00000 n +0000099995 00000 n +0000100211 00000 n +0000100366 00000 n +0000100539 00000 n +0000100722 00000 n +0000100895 00000 n +0000102208 00000 n +0000101078 00000 n +0000101246 00000 n +0000101422 00000 n +0000101612 00000 n +0000101816 00000 n +0000102334 00000 n +0000118291 00000 n +0000105962 00000 n +0000104094 00000 n +0000102537 00000 n +0000104388 00000 n +0000104236 00000 n +0000104514 00000 n +0000104577 00000 n +0000104640 00000 n +0000104703 00000 n +0000104766 00000 n +0000104829 00000 n +0000104892 00000 n +0000104955 00000 n +0000105018 00000 n +0000105081 00000 n +0000105144 00000 n +0000105207 00000 n +0000105269 00000 n +0000105332 00000 n +0000105395 00000 n +0000105458 00000 n +0000105521 00000 n +0000105584 00000 n +0000105647 00000 n +0000105773 00000 n +0000105836 00000 n +0000105899 00000 n +0000108949 00000 n +0000107962 00000 n +0000106091 00000 n +0000108256 00000 n +0000108104 00000 n +0000108319 00000 n +0000108382 00000 n +0000108445 00000 n +0000108508 00000 n +0000108571 00000 n +0000108634 00000 n +0000108697 00000 n +0000108760 00000 n +0000108886 00000 n +0000219885 00000 n +0000113308 00000 n +0000111976 00000 n +0000109091 00000 n +0000112617 00000 n +0000112134 00000 n +0000112743 00000 n +0000112286 00000 n +0000112461 00000 n +0000112869 00000 n +0000112995 00000 n +0000113120 00000 n +0000118417 00000 n +0000116299 00000 n +0000113463 00000 n +0000116465 00000 n +0000118228 00000 n +0000116617 00000 n +0000116823 00000 n +0000117031 00000 n +0000118559 00000 n +0000129481 00000 n +0000131194 00000 n +0000131170 00000 n +0000150183 00000 n +0000168854 00000 n +0000195096 00000 n +0000218795 00000 n +0000219978 00000 n +0000220072 00000 n +0000223388 00000 n +0000228194 00000 n +0000228233 00000 n +0000228271 00000 n +0000228401 00000 n +trailer +<< +/Size 532 +/Root 530 0 R +/Info 531 0 R +/ID [ ] +>> +startxref +228664 +%%EOF From cfbolz at codespeak.net Wed Feb 28 16:54:08 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 28 Feb 2007 16:54:08 +0100 (CET) Subject: [pypy-svn] r39592 - pypy/dist/pypy/doc Message-ID: <20070228155408.108F610053@code0.codespeak.net> Author: cfbolz Date: Wed Feb 28 16:54:03 2007 New Revision: 39592 Modified: pypy/dist/pypy/doc/index-report.txt Log: update 9.1 entry Modified: pypy/dist/pypy/doc/index-report.txt ============================================================================== --- pypy/dist/pypy/doc/index-report.txt (original) +++ pypy/dist/pypy/doc/index-report.txt Wed Feb 28 16:54:03 2007 @@ -12,6 +12,11 @@ Reports of 2007 =============== +`D09.1 Constraint Solving and Semantic Web`_ is an interim version of a +report about PyPy's logic programming and constraint solving features, as well +as the work going on to tie semantic web technologies and PyPy together. All +feedback for it is welcome. *(2007-02-28)* + `D14.2 Tutorials and Guide Through the PyPy Source Code`_ is an interim version of a report about the steps we have taken to make the project approachable for newcomers. @@ -45,11 +50,6 @@ (stackless) features. This report refers to the paper `PyPy's approach to virtual machine construction`_. *(2006-12-15)* -`Draft D09.1 Constraint Solving and Semantic Web`_ is an interim version of a -report about PyPy's logic programming and constraint solving features, as well -as the work going on to tie semantic web technologies and PyPy together. The -report is still a draft, all feedback for it is welcome. *(2006-07-28)* - `D14.3 Report about Milestone/Phase 2`_ is the final report about the second phase of the EU project, summarizing and detailing technical, research, dissemination and community aspects. Feedback is very welcome! @@ -96,7 +96,7 @@ .. _`D05.4 Encapsulating Low Level Aspects`: http://codespeak.net/svn/pypy/extradoc/eu-report/D05.4_Publish_on_encapsulating_low_level_language_aspects.pdf .. _`D14.1 Report about Milestone/Phase 1`: http://codespeak.net/svn/pypy/extradoc/eu-report/D14.1_Report_about_Milestone_Phase_1.pdf .. _`D07.1 Massive Parallelism and Translation Aspects`: http://codespeak.net/pypy/extradoc/eu-report/D07.1_Massive_Parallelism_and_Translation_Aspects-2006-12-15.pdf -.. _`Draft D09.1 Constraint Solving and Semantic Web`: http://codespeak.net/pypy/extradoc/eu-report/D09.1_Constraint_Solving_and_Semantic_Web-interim-2006-07-28.pdf +.. _`D09.1 Constraint Solving and Semantic Web`: http://codespeak.net/pypy/extradoc/eu-report/D09.1_Constraint_Solving_and_Semantic_Web-interim-2007-02-28.pdf .. _`D14.3 Report about Milestone/Phase 2`: http://codespeak.net/pypy/extradoc/eu-report/D14.3_Report_about_Milestone_Phase_2-final-2006-08-03.pdf .. _`PyPy's approach to virtual machine construction`: http://codespeak.net/svn/pypy/extradoc/talk/dls2006/pypy-vm-construction.pdf .. _`D03.1 Extension Compiler`: http://codespeak.net/pypy/extradoc/eu-report/D03.1_Extension_Compiler-interim-2007-02-28.pdf From ludal at codespeak.net Wed Feb 28 17:19:47 2007 From: ludal at codespeak.net (ludal at codespeak.net) Date: Wed, 28 Feb 2007 17:19:47 +0100 (CET) Subject: [pypy-svn] r39596 - in pypy/dist/pypy/module/_stackless: . test Message-ID: <20070228161947.E6A0F10063@code0.codespeak.net> Author: ludal Date: Wed Feb 28 17:19:46 2007 New Revision: 39596 Modified: pypy/dist/pypy/module/_stackless/interp_clonable.py pypy/dist/pypy/module/_stackless/interp_coroutine.py pypy/dist/pypy/module/_stackless/test/test_clonable.py Log: fixes a segfault when cloning a clonable before starting it _stackless/test pass with the compiled executable Modified: pypy/dist/pypy/module/_stackless/interp_clonable.py ============================================================================== --- pypy/dist/pypy/module/_stackless/interp_clonable.py (original) +++ pypy/dist/pypy/module/_stackless/interp_clonable.py Wed Feb 28 17:19:46 2007 @@ -1,11 +1,8 @@ -from pypy.module._stackless.interp_coroutine import AbstractThunk, BaseCoState, Coroutine +from pypy.module._stackless.interp_coroutine import AbstractThunk, Coroutine from pypy.rlib.rgc import gc_swap_pool, gc_clone from pypy.rlib.objectmodel import we_are_translated - from pypy.interpreter.error import OperationError -from pypy.tool import stdlib_opcode as pythonopcode - class InterpClonableMixin: local_pool = None @@ -36,6 +33,7 @@ # clone! data, copy.local_pool = gc_clone(data, self.local_pool) copy.frame, extradata = data + copy.thunk = self.thunk # in case we haven't switched to self yet return extradata Modified: pypy/dist/pypy/module/_stackless/interp_coroutine.py ============================================================================== --- pypy/dist/pypy/module/_stackless/interp_coroutine.py (original) +++ pypy/dist/pypy/module/_stackless/interp_coroutine.py Wed Feb 28 17:19:46 2007 @@ -207,7 +207,9 @@ return chain def _bind(self): + state = self.costate incoming_frame = yield_current_frame_to_caller() + self = state.current return self._execute(incoming_frame) def _execute(self, incoming_frame): Modified: pypy/dist/pypy/module/_stackless/test/test_clonable.py ============================================================================== --- pypy/dist/pypy/module/_stackless/test/test_clonable.py (original) +++ pypy/dist/pypy/module/_stackless/test/test_clonable.py Wed Feb 28 17:19:46 2007 @@ -165,3 +165,21 @@ res = first_solution(example) assert res == [1, 1, 0, 1, 0] + def test_clone_before_start(self): + """Tests that a clonable coroutine can be + cloned before it is started + (this used to fail with a segmentation fault) + """ + import _stackless + + counter = [0] + def simple_coro(): + print "hello" + counter[0] += 1 + + s = _stackless.clonable() + s.bind(simple_coro) + t = s.clone() + s.switch() + t.switch() + assert counter[0] == 2 From cfbolz at codespeak.net Wed Feb 28 17:20:40 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 28 Feb 2007 17:20:40 +0100 (CET) Subject: [pypy-svn] r39597 - pypy/extradoc/eu-report Message-ID: <20070228162040.E3CF110108@code0.codespeak.net> Author: cfbolz Date: Wed Feb 28 17:20:37 2007 New Revision: 39597 Added: pypy/extradoc/eu-report/D07.1_Massive_Parallelism_and_Translation_Aspects-2007-02-28.pdf Log: add final version of 7.1 Added: pypy/extradoc/eu-report/D07.1_Massive_Parallelism_and_Translation_Aspects-2007-02-28.pdf ============================================================================== --- (empty file) +++ pypy/extradoc/eu-report/D07.1_Massive_Parallelism_and_Translation_Aspects-2007-02-28.pdf Wed Feb 28 17:20:37 2007 @@ -0,0 +1,5573 @@ +%PDF-1.4 +5 0 obj +<< /S /GoTo /D (section.1) >> +endobj +8 0 obj +(Executive Summary) +endobj +9 0 obj +<< /S /GoTo /D (section.2) >> +endobj +12 0 obj +(Introduction) +endobj +13 0 obj +<< /S /GoTo /D (subsection.2.1) >> +endobj +16 0 obj +(Purpose of this Document) +endobj +17 0 obj +<< /S /GoTo /D (subsection.2.2) >> +endobj +20 0 obj +(Scope of this Document) +endobj +21 0 obj +<< /S /GoTo /D (subsection.2.3) >> +endobj +24 0 obj +(Related Documents) +endobj +25 0 obj +<< /S /GoTo /D (section.3) >> +endobj +28 0 obj +(Stackless Features) +endobj +29 0 obj +<< /S /GoTo /D (subsection.3.1) >> +endobj +32 0 obj +(Introduction: Stackless Features for RPython Programs) +endobj +33 0 obj +<< /S /GoTo /D (subsection.3.2) >> +endobj +36 0 obj +(The Stackless Transformation) +endobj +37 0 obj +<< /S /GoTo /D (subsubsection.3.2.1) >> +endobj +40 0 obj +(Saving and Resuming Frames) +endobj +41 0 obj +<< /S /GoTo /D (subsubsection.3.2.2) >> +endobj +44 0 obj +(``Unbounded'' Stack) +endobj +45 0 obj +<< /S /GoTo /D (subsubsection.3.2.3) >> +endobj +48 0 obj +(Interface to Explicit Stack Manipulations) +endobj +49 0 obj +<< /S /GoTo /D (subsubsection.3.2.4) >> +endobj +52 0 obj +(Resume Points) +endobj +53 0 obj +<< /S /GoTo /D (subsubsection.3.2.5) >> +endobj +56 0 obj +(Performance Impact) +endobj +57 0 obj +<< /S /GoTo /D (subsection.3.3) >> +endobj +60 0 obj +(Application Level Interface) +endobj +61 0 obj +<< /S /GoTo /D (subsubsection.3.3.1) >> +endobj +64 0 obj +(Coroutines) +endobj +65 0 obj +<< /S /GoTo /D (subsubsection.3.3.2) >> +endobj +68 0 obj +(Tasklets and Channels) +endobj +69 0 obj +<< /S /GoTo /D (subsubsection.3.3.3) >> +endobj +72 0 obj +(Greenlets) +endobj +73 0 obj +<< /S /GoTo /D (subsubsection.3.3.4) >> +endobj +76 0 obj +(Coroutine Pickling) +endobj +77 0 obj +<< /S /GoTo /D (subsubsection.3.3.5) >> +endobj +80 0 obj +(Coroutine Cloning) +endobj +81 0 obj +<< /S /GoTo /D (subsubsection.3.3.6) >> +endobj +84 0 obj +(Composability) +endobj +85 0 obj +<< /S /GoTo /D (subsubsection.3.3.7) >> +endobj +88 0 obj +(Microbenchmarks of Stackless Features) +endobj +89 0 obj +<< /S /GoTo /D (subsection.3.4) >> +endobj +92 0 obj +(Practical Uses of Massive Parallelism) +endobj +93 0 obj +<< /S /GoTo /D (subsection.3.5) >> +endobj +96 0 obj +(Related Work) +endobj +97 0 obj +<< /S /GoTo /D (section.4) >> +endobj +100 0 obj +(Optimizations and Memory Management) +endobj +101 0 obj +<< /S /GoTo /D (subsection.4.1) >> +endobj +104 0 obj +(Optimizations) +endobj +105 0 obj +<< /S /GoTo /D (subsubsection.4.1.1) >> +endobj +108 0 obj +(Function Inlining) +endobj +109 0 obj +<< /S /GoTo /D (subsubsection.4.1.2) >> +endobj +112 0 obj +(Malloc Removal) +endobj +113 0 obj +<< /S /GoTo /D (subsubsection.4.1.3) >> +endobj +116 0 obj +(Escape Analysis and Stack Allocation) +endobj +117 0 obj +<< /S /GoTo /D (subsubsection.4.1.4) >> +endobj +120 0 obj +(Pointer Tagging) +endobj +121 0 obj +<< /S /GoTo /D (subsection.4.2) >> +endobj +124 0 obj +(Memory Management) +endobj +125 0 obj +<< /S /GoTo /D (subsubsection.4.2.1) >> +endobj +128 0 obj +(The GC Transformer) +endobj +129 0 obj +<< /S /GoTo /D (subsubsection.4.2.2) >> +endobj +132 0 obj +(Using The Conservative Boehm Collector) +endobj +133 0 obj +<< /S /GoTo /D (subsubsection.4.2.3) >> +endobj +136 0 obj +(Reference Counting) +endobj +137 0 obj +<< /S /GoTo /D (subsubsection.4.2.4) >> +endobj +140 0 obj +(The GC Construction and Testing Framework) +endobj +141 0 obj +<< /S /GoTo /D (subsubsection.4.2.5) >> +endobj +144 0 obj +(The Mark-and-Sweep Collector) +endobj +145 0 obj +<< /S /GoTo /D (subsubsection.4.2.6) >> +endobj +148 0 obj +(Performance \046 Future work) +endobj +149 0 obj +<< /S /GoTo /D (subsection.4.3) >> +endobj +152 0 obj +(Related Work) +endobj +153 0 obj +<< /S /GoTo /D (section.5) >> +endobj +156 0 obj +(Conclusion) +endobj +157 0 obj +<< /S /GoTo /D (section.6) >> +endobj +160 0 obj +(Glossary of Abbreviations) +endobj +161 0 obj +<< /S /GoTo /D (subsection.6.1) >> +endobj +164 0 obj +(Technical Abbreviations:) +endobj +165 0 obj +<< /S /GoTo /D (subsection.6.2) >> +endobj +168 0 obj +(Partner Acronyms:) +endobj +169 0 obj +<< /S /GoTo /D [170 0 R /Fit ] >> +endobj +174 0 obj << +/Length 1238 +/Filter /FlateDecode +>> +stream +x??W?r?H}?+?U?d?????KW?? ??T?!d??.I??_?=7?1??a?*4Hg?Ow??$??O"??ZDJ0D4?QV?p??g?F?c8?? ?????1?q?aE?B?Qa`??( ???kD?v?7??Ht??nG??`? ?????%??}?o?yl??????I?&5??Nq?????????=??G?5??O(bD?p??F?{cx??K?sD?H ?1*?~?_U??F](eH?_ ??21?????+*#??!?j? ?7_~??'1M??j*c??Rz?s~3??????XG??_? ?!??I;??d at 1? ?:??Hc?? ??? +I?gHO?M??? ,"A@?????=6??? -5? ??I$?5???6O?5??E?r?K???X??g??2?P<~*?p?z?4??????^???c?%?????mB???m??!??0???????y???????uaLyR_,???#??(???n?I|???[???F?=w??>?;?# +z +?QK???*???????h???? ?"?g????@??Q2???Ap??v>2z?f)4%?b+JO?1??}?9&?tB?3jI?????S>T?V;m?????`??6-??,??@?~w?.Ka?!?@!??[wV ???B???*Z'?"Tg;????????????YWdi????P??? ??O ?]`???f;%6i???#1?' |?u[?8k7y????!0R??H?P?O??x@????a9b\??UQM??? ????_:r?[???BBG?????I??????R???$??R??j?8 ??1t???F"???p?u}(??_@??!?!??uA??{I?p???!? 4!M????K_??x??NAy?c?? y?W?|;8??X+%??A~u?g[?? ???????W?ySwF?A|?Q?.?6??~????2<8xh?????3;?`?y????'??~??M???l?|l????z3???r??U?kxjq??z??wW??????{??<)V??????a???cGx??rxU?A?L??0????0?Y@??z???o??????9*?k?FP)???????#'k?6????;E9?Y???2_?>?????w?6yZyT/???a??f?S??M+??G??1?? Ex#N?R/3Os??|?u?9?M?K"???N????oG??????#??8;? ??u0?????+gz? ?> endobj +171 0 obj << +/Type /XObject +/Subtype /Image +/Width 149 +/Height 110 +/BitsPerComponent 8 +/ColorSpace [/Indexed /DeviceRGB 63 182 0 R] +/Length 1649 +/Filter /FlateDecode +>> +stream +x???m[?:???BjmjZ????e???v?]Q????Ih??$!Dv?s]<~??-7O??????S???????Oi?}?tjru???uTE?L??~?s ?@?_?"T??????? ?r?????]??V? 0?7$??,????B??^??>a???s/???T??!D1?J???+5@ ? +??B?????Zu&k?*T?????A?????@Q?X?'f????Q??5("B??RV?{|???|?P?y*s~????a?X7&In?3TO??kJ#Ty??l??s?G? (Ju?k???GTP?f[?????4?tD?UZ?a#?LFi?Z??s!R-???&F??;5V?? ????`U??0?m+P%?*Q2lQuP??%??)f6n? +s????1D ??|z|J?????U??aYN?5?T?R?[APSh?Q????#J *??1?P?r?*F)A???:??J?(%??A (?C?b??5???B?????Rs*?? ?TPa????lT)%?6c?(?? (?n-?A??{????#??w????'42jI?d??oL??q?!75J8i?6?x??Y?F?????s4?"wt????????MZHt??{????(?L?????d??a??? ???ne8?:3HL ?D?G|*?M??????I??wW;??0?#???!8"?????R????+?Q%6*u?r??h? ???T?*0By? +? ?t)1??=7?????;???t'w*T????\VuRe?sV??L??&????KJ]??,??2#q$?8?????Uo??P}????b{???d6??w4T=?o??%_(??,???$?zX???R\???2?J????&?H?>??N?#?1}?$??2?e? ???FoH?Q{=??#V??f??????7 ?????+?Pd ????L????]?????????l??F?t?{ xD;`?J?T???m???M?????} ? u???|??bqw????.Z???|?;?gyY?d??????77?????e&8?Q,?:?e???^?\?A%ow?2??c?1??? j??N.&~>??=?t?a~6?"?????4???j??????w@?U?????:??@?YJ?? +5s=??0??5&PVE?f?|&???????|*?m??Q???????????????????????;E?ZEz?)?~?n&"F????r?W????g?:2(A ??^ad=?tx??????????W?endstream +endobj +182 0 obj << +/Length 203 +/Filter /FlateDecode +>> +stream +x?????/?&T??:??^???????k????????????pK???????S&?Z????D?????-???????????????|?? +???_7??O??-???ph??wWO????b:?h ???????????}?|???????????u*????????{??????{Y?????x??,??s?4??????(u[endstream +endobj +172 0 obj << +/Type /XObject +/Subtype /Form +/FormType 1 +/PTEX.FileName (../img/ist-norm.pdf) +/PTEX.PageNumber 1 +/PTEX.InfoDict 183 0 R +/Matrix [1.00000000 0.00000000 0.00000000 1.00000000 0.00000000 0.00000000] +/BBox [0.00000000 0.00000000 385.00000000 199.00000000] +/Resources << +/ProcSet [ /PDF ] +/ExtGState << +/R4 184 0 R +>>>> +/Length 185 0 R +/Filter /FlateDecode +>> +stream +x?u}[?%?????&?????aO??{l???????2W?66????zS_???_??? +?????????????????????????}??u????????(?u|???????/+?o?(???????R??R?)??????????j?w???(???????s??fF5???&)g?+??????1??3v&^?'G??YX/?????/??_????>???n>G????^z|?u?B?a???h p|?????|?%??!?? +?g???,`?>?O??c?????~??[]?c| ?????7?t????)/?????k?? ????y3???q???????T?4??]????zO????fl?l?*???o ^??n?]??#???Qvh.???KOM [??N??>?i?z???????M??d<]j?s????k??????"m??j??^k?<.|????~? v?p??kn??E?s???-? +?n??g?~??^x???w?]p??X?~Xvj????????????4q?p~???8 +??|G?}j????c?pw>%?%?iR????l?g_????,!?????????O??V?7????Q?[??"_,?????????!?/??,BS?zL=?5_??t?P?1???5?.???g???>cN??b??)Z???x???kK?????l?Gw??!? ?3?]??#??s??????&?4??+{??x???Eo??w?S?dw?y?@????(;L??F?U?{D????|?)??H ?t86^???????*Y?h?NN??????VN{#W??OM+2???a?????:???????z?{?Ys?_???l?X#??\?0?$???B?h????D???~nIx4??/?h?E??? %????}?????? ?gR??` nI?3?$??l?? zK{(O???? ?Q???????g0?????(lI9?%???s?~OH???y??????NHn?a?????????Hc<~?????8??s?xU?VJ?jS?l?X]s%/????K}??????bs??????Au}?lnh????????m'{??u???~:kS??n<[??*?g?]???fj?????????w????????????????-??I??[???? ??.C? >?{??X?????sk*??J???A???E??1??P???????9n???jT$???:?? g??<]/??"???IQ???8?}??!?|????-v'?,a +rC? ?8?????+??T?? ?????3P>??y(?paKIB]???tThWV??7?n???B?\?R?$??,??sv??|?n????Y,?* +????V???-???????_??s%?a?}???? U?'??zA9H#??C8y? ??$P$??????bI????t??d??.??? +?/?_ ?(2?B?w?'??????^C?N????S?????c?:`????z_?????\(8!?Q??X_?sP?^wm??????\?e????bS'aK???C???h?p?$?.8?^?aj?J\-_???????4j????}}????????&?&!?L??\?=_???By??? ???o4?,?z???5????i???jnM ?dsA???!??\.?~!C????&????&|??4?;.?`???G?^???X=???X????R????}y:[???j?/?Z??H???/L{1 ????X??k?Z?V???t??'3???Ax???B?,? G??N? ???????;?????F? ??re$a?8????O8?}K-?l??Y?????8/??9?9x?#???D?6[?.Xc8??????????Jp???@8?5;??M??N????????{??R(??M?G?????Lf???"/Be???0??-??A????|?GK?8?CI???+???X?q?r?+ ??T(LX?? ??!?&V?????v?????s?P?j?Q??L?L??st?????u???3?s????%????F???? ???tA??#3??W8??0??G???? ?=-????t???2?mI8NJ??l)?? +M?y?*Q?BB??L,?? ?=??/?????)_?????6?:O? ??yDn???!4???????{???vyl?????????/`?Uzf? +? j_M?-:??f?}?????????????{??4??K4V??????s??dK????v_Wg?"????-&??|???!?`f???????v????`???2??? +??]???m.A??U?VM???????i????? ????%????q.d?????????l???????ms R?????m/??B?6 ?'??????? ?H???v?f?J?>????C???C6 ????6 ?z??V???d? ?"?>??'?????:5??88S?? 7?????A?? ?jO#`K?z???w??G??????b????W?u>2??g?X??*???d?3?'S?P??[??????6t??(j?|???lp)=O?K2Gru??w???(?hR ????????W???K?g?Q???/?j?????E??I????rf?sN??a1??x??H?7?'=V??* ?????+!?I ?B??f`?Tnl??z?|????$<N$E?????G\?B??K?z?????G?M???R?RS???%??\?S?}?? ???N???EdA?.?? +?`?Eh?4????&A?tx?"`????r_WNVo?[?S ?p???!?z?0-?K???O??~??S??;??? ?&N? 9?XC????S? ???j~A$??????? ??V?Lg? ?Y?1?5?n?Oj????et(? Z?7W?@ _?>? +?????????????HVD????b???????????^mz -f?!mE@?b| ?8?@?t!?%?????????SU????(\?K???>?to?E?*+? Y +M??D??0?????:?WD?C%??@7;? + g??I?????m??*H!????X'C???{????ib??????RKE????X?B W? G;k?O ?{?B%?R??}??:?v???B8?q???q'???PYtY9?Dn$l&?x??*????????x??dBD at .??j??S? +??5??6Fg?&???????8????????/, ?????6?T?4i?L?v?????U>/h??????G +pW?4?{2???9????B?t????U?????? ??`?qc???JP??~~A+??k ???????l,??2??O?? ??_8/????v&??? 8=?O?\:???.6??Q??n?H$?v?%{ %???i?8??&???3??7????????q??T????8???D#??t[iai?X??b?.:]????????1??.?E?*$ ??\*{?L??W?#????] ????+J4h(???Fs??N??}B]??? ????n [?H?????(?I!??)??S?e?????????w????|C?>R?7d#;?????./?q?b?R;O???!?|.?? ???c???? +?v F??5A???O?P????? ? ????\`}?%*?$????9Z'bQ:???o?Q???CQ?a?A9?{o@????l ??=,???K@????j?,?F']?Lx+???&6?S???[Th?`?????????d.?3>??f???b@??%C?????%F?h?/pV5?@% +?X%[? ?X?x??d?2_Hp?"> ]aX.0S?Z???6???????? L?F?'?o@?U?>??`????H?9?l????U?q???:??f?????/?????@??#=?e?lG7i"? ,?>5?`?|\?%?5sm??5??1P??O?j!F?W?W???????`7?????s??OHY?:?c|Kb2??@ ??m?*Pq??z?!4^??? 9?????/?zrt?T????A6??C?Le%???UJ:h?? ???`2?? +??x?s&?Y?d)Y ??A6:??EKy?8???V@F]?Pg??7??????F????@???$?2?? l???c!e????uF\?????aM?R????<T?%?p?`??F??jh?`I??m?kD?c?+?#? ?1??K??????MtW???it?n?v??=? ^?Q?J???z}????8??M?j??:?;6?2????CHS?8?7li~?1??P?5?o?u?m?I'?!?fIE??????????????k-???#???M?????????? J;B?d?r:5$Lf?$3???n?B+gL6??z?0[??(?a??? ?O??????????/=? +ppk??S?O?(0?0?U?"???]??6F???????2?????XQ? ?^%?]2Rxz??]?S????pe?p?x!k???M??w/?B?!??2?vD??(?}+ ?v?R?)$p?S%?D[?LDf???Q8?x?E)????d??7???F?@??????????F??????2 ?UB??????l +?R?>????/?Pxb"?l??=J??5%???O=(??2?.R?I||A?*RN?o???? e???v???S??????9Z?xg??23?$8???X??M?`??????I?F?? ?4???Pn??????-x8?Z$7b5q???Lp?Hx~?r(???]?d?w?+#??ad??:Fx?XIZ?(f?????OW???9d|}??????????|N???~????O N?? ?j=?=??km]??PI8????k???~H8S$al1? I???????C~?K???fH????^???/h>?7@??br?S?I +?c??B??!)????]X??????????T??+&???? Sk-B???CPn"??9#??_?gpX ?\~??f????0????????E?`?g???a ??????o???Q??7???dr|?{2 ?V?!i?????u!}T?/????S ?N/?J?I?Syl?K???C{ ?Q????]?? +???J|?jFg??~??~?3t???HY4?k;??]z???H?D8&V?`93?J.e?#&;??????????<,??qF?rR??P????? m/??[?"?OH?%?KA??;?6.;? ??U?????c?sw?.????`}?hQ?D??}????????????8??a????4x4??y??N??U?A ?.?fFeF??=x> ???%`9N??G7??S?N??`*$????N???Om??W????r$??T{?o-?D??c??a????)F +BFt?1~d?? ?3a????f5/?p????2y7?>1??< ??#????_????????_?Y???2????X??[i??8? ? F??????.??,@^??b:?Mz)????e?'6?HGz@??t????9c???a&??v?~?v?:??H???bFc^;??+"??}???UO????g???7?I?.sP?vZ????M*:??????0???x:C???:J??vB???]??T)hjE?9n?v?:P8?em?? $G??'???bxD S?????!?{@Y??j???I ???*c??2Y??&d]%?C?4??D???.???}0?UqB?;?y?/??+???Vx?? ?d^O??]?w?Hyin?O????b?/????8?#Q?k?j9??U?`X????qwd?????>?`pB?W?>??F??W?>S??? X?d? r?7?+?L??????B-rm??E??????|?H+Y#E^Eq?L?=?? ?\A*D<)?,????5????(???L)?a+???*X?j?????? ?????????a[????,b????? ?u#X???G??? =??N???f/??%?&~ *?????.????qR???H /?N??Lb{p??????u?G^??????Q?$?i???1.??iD0a?????(E?2?b,1b?QBh>???V??????]0?H??-?|?@o???_|f?A\j?yb???????$?u ??^?pv;/??V ??rb?O??{3gB=?5????,???????Dh???#?qK?H?Gm?Rc?K????:?????&2?????h?E? ??f?????+7???????????d??$?",?9???[x??X?70?G?"??????>FZ??i?I???|c?Wt|}?-3??9?????K??$0xU:????u!?? S?????-P?3?.B?E?,]?Dj?.???j=?G?d???w?x`???y??Q??????]?? ?q??b?????e????b??H^p?T?%(9???r!?C????n6?d??3$p?K?`H??5??Z??~4????`~L??\???z?i|??(???-{??f5?q ???_??K #???????????Y???=O???4 +]5U???????}Mj??+?s39~???? +^y ???/e?? ???sF??%????b?1?*?&??0?? +???d????~M?\|H???_D?s^y??p?a?o??H?)???}????TtR_????Vf?#'?a??R?fC?p????b?-??6Am???*?????0??q???N??d???o? ?Y?_??>??C????N??`?%?> +endobj +184 0 obj +<< +/Type /ExtGState +/Name /R4 +/TR /Identity +/OPM 1 +/SM 0.02 +>> +endobj +185 0 obj +10833 +endobj +175 0 obj << +/D [170 0 R /XYZ 74.4095 753.1919 null] +>> endobj +176 0 obj << +/D [170 0 R /XYZ 74.4095 735.2591 null] +>> endobj +177 0 obj << +/D [170 0 R /XYZ 74.4095 735.2591 null] +>> endobj +173 0 obj << +/Font << /F26 180 0 R >> +/XObject << /Im1 171 0 R /Im2 172 0 R >> +/ProcSet [ /PDF /Text /ImageC /ImageI ] +>> endobj +188 0 obj << +/Length 2375 +/Filter /FlateDecode +>> +stream +x??[K??F??W?Te??E??????S?s+Y$Y ??#P.??????? (??bJuo??s??N?E $?9?8??8b??$ ?? +{??nEL?M?h????a?? ??qA??? ??%1*Ra?_?w???????5??j?a<?fm[~\S:??|????*??=???k????n?l????lj??=y?????F???lC)?cU=??q6?2???????8???4s??7I?;6??o?????/J?x|Q9????Oj??}Hu????d?/4?7???'???9?'??????ID1?????? ?*P?$\V?`???J??C?+?S???>????$x??~\?Zn,NPJ ?)"??????8??%~X?/?I|??N?????\ ???V??l?C,?V??f??b???[? ?8,?)G)S}_H[~,?? ?/???M:?_?????9?H??????????b????,???e{?H?`????8?D ???B?u?2?)?B$?S??8?????P??????D*?%0? %.C?1F"N?1??E?*??}?z~s?????D?????`?#???Z@???,{tLQ3????F???~??????Z?v?~????2c??*??y?:????2?od ,??p???1???N?r?????lW??a?-?????+???LN"?y?x#y?r?8?7?%?????B????M.?H?\\?~????#?E2V..??8????]??d?????_????l_?????y?&????A???ZM3?k?o??o???%!?$b,?h^>?Po?Y?i???3????hj????K?t?Ve{??j???? ?????????/Nw??H??E?????(??Y??!bVn???????????F?? +?A[???????\?R>TE???N??n/'f*??X?q?o?$?8?????x*???!????)??Z?jA} ?EV???????t+o??,b?2???E???????????v}0??????Z????????(??D#,L??2??`?U?zu???t3??yQx???b?????H"S?:m*}x?&OF?e???{?/????;??^?l?:? K)??xc???8?$???X????'t???-??z?Z??P??~??p??H???%!????r?}????? ?} ??(? ?!???{,Fda?pJ?&?E?V.T/?qd!,??Bp??V?u?????AzP1?"v??????8??zh?"????)"?N?? ???/?To?YDj??B??od?,???q????in 1???}????R???v????????^?7?~^L?L??"??????k???a? ?????|a? ?*?E??)?U>';62?Qu?Y??????????? s??X??Xo8e??1.?j:m$G???F?^&?????L?$?'?\6?HU=D?Z?!??L??R?s??MS??????2???????*L??!??>{4G?PZC????5d???7? ????????!???? ?"*1B???\d????L-?????7???G??k?T???mi?ePV??ZfW'?+`??Ie?6(??*?3? ??+oj?T:@??]Y??tea??????1?????>>?=?????????N????!???}???U????t???u?0???? ??VGe}? +????'1?t????&??:?4T)F+?!?????2+??/5?????4????????G+w??jF?k?V*????Ug?K???m?(??????~?h????????WHL{?????_~???B??m?>?????$?'?????Iy??? ??+????{???*E;???????W?~@`???k?Q??rpc? Zp?endstream +endobj +187 0 obj << +/Type /Page +/Contents 188 0 R +/Resources 186 0 R +/MediaBox [0 0 595.2757 841.8898] +/Parent 181 0 R +/Annots [ 193 0 R ] +>> endobj +193 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [100.0827 750.9806 113.1137 766.9208] +/Subtype /Link +/A << /S /GoTo /D (page.47) >> +>> endobj +189 0 obj << +/D [187 0 R /XYZ 74.4095 753.1919 null] +>> endobj +194 0 obj << +/D [187 0 R /XYZ 74.4095 709.6344 null] +>> endobj +195 0 obj << +/D [187 0 R /XYZ 74.4095 697.6792 null] +>> endobj +196 0 obj << +/D [187 0 R /XYZ 74.4095 479.3021 null] +>> endobj +186 0 obj << +/Font << /F26 180 0 R /F31 192 0 R >> +/XObject << /Im1 171 0 R >> +/ProcSet [ /PDF /Text /ImageC /ImageI ] +>> endobj +200 0 obj << +/Length 2855 +/Filter /FlateDecode +>> +stream +x???Yo7???+?q?h???9??`?Ul????x???C???Q~??yt???Ey,lK`?Q?*V,?dH???RqlD??F?Z-7'?????9!A?4 +??R???<{MeE8b\???s?1bZ?F?A????o??????)?x?+D?1?e\??-????s?g????y??Y???z?????=?3?>?{+UR???h?????s????n?/??;??A?b???C?am[?Hi???F?>A???????N7????????????????oLid(a??a????o????z???????o?P1?? ?q!U?d}???k3???t???b?????r;0??T{?^???z??K]????$??R;??hA?P?m6????????/?L?????p????w??]3??M??`??jE{??I?????NI??D?F7?ny?=?????.n?.R }?m??? L:!J,??????"m?W?Q;??.?!???????Zun@ ?g?~?_??u?????j?_??-o7?????I?9??Nj? +vRf???o(?????7??? |? c?%??(T?l??(}m?UrF?|M??_!???!?S R`4yD?G??rw??lRm?,?Do?f????????u?????w;:!?[*? ??????0??f+??d???zq?/?0f?>?v???U???(U???(??[???F????? +?;k FT????????Mu?]'aJ ???Ra9??:?e??|Y?????|???Iv???:#?(??<>????A?`]?????S??v]d0???M?????kb???@????%'?|???????????????????-:??3??????d?eR????I???R?N2e??v????HO?B???(???5?P7 +!?G'1??f? ?E)?ZHc??B3??]8T??*=????V(?Y{H????|J?R??????m????)R!gv?????*? +??6%F?????w?T?K)??e '??V]`?|?a??j{??\lC~????n??_???OT?,Mi]?F?lF????0$9????f;S?A?????????Ls?r???7 +QCL??V,rG=w???}?~??n/? ??bf? ???T?H R?\?4r`???Y?i?4??V????5W?$?d?Z???\5??!%2?X$?y2m?X???y? 3?a?????z?Z?CV??w????v?&?< d??S??40J??8FX?A?-6'Q???: o????AP???%??XD?{??<;?K? ??? +?F?Rmy??R???B?????(???VA???9V?4????E?7??(?b?U?Yu??!0?-?%?n???@?9?*??2q?????????'n?? ??S??J?BZ?.?r??Tc/?[)?g(?>?nf?E8 `a?g????B??????aj?v??Z1?i?*?a?Z??1???` +:5o?a*?1??> ?b?$???2?P?????? o??H=?d8?R%y=6L?#%h???=??W?? ??????rWH??9*??S??V,???sc????>?e?W???^? +7H(??T?H, R ??e??GDAovT???[sTNos?Z???N?jl*P?"?a??????[GeB1?f'???? +?? ???)??W?? ???????UvP???`?S?v?bW>2????*l5u????e?PZ?jG\??u????u???UK???O??yk???j?F%GD????V?3)F?F?{??? ??)w?TpY?????6R???*,?f=???6??#?|yk????:??????-$????O?R?*???????j????T?P?j?}??????????????????????TAO??9T??s????s?76???E?V??n??W??Z??*?R$??/?72m??Y?????4m? 't??[stN??> ??'? ? ???_{??????Tj??_???]j[?? R??pL?g??=& :5?tj?Z SH????4???2JEH??????~???b???>????????????D???^v7?~? ?????? w?Yx5??K???'?P?;??ngm9???+ ?]??? Z??????[?????* endstream +endobj +199 0 obj << +/Type /Page +/Contents 200 0 R +/Resources 198 0 R +/MediaBox [0 0 595.2757 841.8898] +/Parent 181 0 R +/Annots [ 202 0 R 204 0 R 205 0 R 206 0 R 207 0 R 208 0 R 209 0 R 210 0 R 211 0 R 212 0 R 213 0 R 214 0 R 215 0 R 216 0 R 217 0 R 218 0 R 219 0 R 220 0 R 221 0 R 222 0 R 223 0 R 224 0 R 225 0 R 226 0 R 227 0 R 228 0 R 229 0 R 230 0 R 231 0 R 232 0 R 233 0 R 234 0 R 235 0 R ] +>> endobj +202 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [100.0827 750.9806 113.1137 766.9208] +/Subtype /Link +/A << /S /GoTo /D (page.47) >> +>> endobj +204 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [73.4132 675.6979 185.3922 687.2594] +/Subtype /Link +/A << /S /GoTo /D (section.1) >> +>> endobj +205 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [73.4132 649.5908 148.1823 659.3641] +/Subtype /Link +/A << /S /GoTo /D (section.2) >> +>> endobj +206 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [88.3572 629.9396 237.0378 641.2171] +/Subtype /Link +/A << /S /GoTo /D (subsection.2.1) >> +>> endobj +207 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [88.3572 612.0068 229.4267 623.2844] +/Subtype /Link +/A << /S /GoTo /D (subsection.2.2) >> +>> endobj +208 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [88.3572 595.8175 209.6015 605.3516] +/Subtype /Link +/A << /S /GoTo /D (subsection.2.3) >> +>> endobj +209 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [73.4132 567.8972 177.8803 577.6704] +/Subtype /Link +/A << /S /GoTo /D (section.3) >> +>> endobj +210 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [88.3572 548.0267 368.4335 559.5235] +/Subtype /Link +/A << /S /GoTo /D (subsection.3.1) >> +>> endobj +211 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [88.3572 532.0566 248.1661 541.5907] +/Subtype /Link +/A << /S /GoTo /D (subsection.3.2) >> +>> endobj +212 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [111.2713 512.1612 285.8751 523.658] +/Subtype /Link +/A << /S /GoTo /D (subsubsection.3.2.1) >> +>> endobj +213 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [111.2713 496.1911 242.3489 505.7252] +/Subtype /Link +/A << /S /GoTo /D (subsubsection.3.2.2) >> +>> endobj +214 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [111.2713 476.5149 336.3948 487.7925] +/Subtype /Link +/A << /S /GoTo /D (subsubsection.3.2.3) >> +>> endobj +215 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [111.2713 460.3256 213.3077 469.8597] +/Subtype /Link +/A << /S /GoTo /D (subsubsection.3.2.4) >> +>> endobj +216 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [111.2713 440.6494 245.5764 451.927] +/Subtype /Link +/A << /S /GoTo /D (subsubsection.3.2.5) >> +>> endobj +217 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [88.3572 422.7166 243.2551 433.9942] +/Subtype /Link +/A << /S /GoTo /D (subsection.3.3) >> +>> endobj +218 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [111.2713 406.5273 196.9393 416.0615] +/Subtype /Link +/A << /S /GoTo /D (subsubsection.3.3.1) >> +>> endobj +219 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [111.2713 388.5946 250.5676 398.1287] +/Subtype /Link +/A << /S /GoTo /D (subsubsection.3.3.2) >> +>> endobj +220 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [111.2713 370.6618 191.5299 380.196] +/Subtype /Link +/A << /S /GoTo /D (subsubsection.3.3.3) >> +>> endobj +221 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [111.2713 350.7664 231.7885 362.2632] +/Subtype /Link +/A << /S /GoTo /D (subsubsection.3.3.4) >> +>> endobj +222 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [111.2713 332.8337 233.3027 344.3305] +/Subtype /Link +/A << /S /GoTo /D (subsubsection.3.3.5) >> +>> endobj +223 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [111.2713 315.1201 214.7921 326.3977] +/Subtype /Link +/A << /S /GoTo /D (subsubsection.3.3.6) >> +>> endobj +224 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [111.2713 298.9308 333.1668 308.465] +/Subtype /Link +/A << /S /GoTo /D (subsubsection.3.3.7) >> +>> endobj +225 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [88.3572 280.9981 284.4894 290.5322] +/Subtype /Link +/A << /S /GoTo /D (subsection.3.4) >> +>> endobj +226 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [88.3572 263.0653 177.8509 272.5995] +/Subtype /Link +/A << /S /GoTo /D (subsection.3.5) >> +>> endobj +227 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [73.4132 233.023 289.4509 244.9182] +/Subtype /Link +/A << /S /GoTo /D (section.4) >> +>> endobj +228 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [88.3572 215.4937 178.2991 226.7713] +/Subtype /Link +/A << /S /GoTo /D (subsection.4.1) >> +>> endobj +229 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [111.2713 197.3418 222.4536 208.8386] +/Subtype /Link +/A << /S /GoTo /D (subsubsection.4.1.1) >> +>> endobj +230 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [111.2713 181.3717 222.9319 190.9058] +/Subtype /Link +/A << /S /GoTo /D (subsubsection.4.1.2) >> +>> endobj +231 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [111.2713 161.6955 324.669 172.9731] +/Subtype /Link +/A << /S /GoTo /D (subsubsection.4.1.3) >> +>> endobj +232 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [111.2713 143.5435 218.9866 155.0403] +/Subtype /Link +/A << /S /GoTo /D (subsubsection.4.1.4) >> +>> endobj +233 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [88.3572 125.6108 223.5591 137.1076] +/Subtype /Link +/A << /S /GoTo /D (subsection.4.2) >> +>> endobj +234 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [111.2713 109.6407 239.0905 119.1748] +/Subtype /Link +/A << /S /GoTo /D (subsubsection.4.2.1) >> +>> endobj +235 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [111.2713 89.7453 340.3498 101.242] +/Subtype /Link +/A << /S /GoTo /D (subsubsection.4.2.2) >> +>> endobj +201 0 obj << +/D [199 0 R /XYZ 74.4095 738.0292 null] +>> endobj +203 0 obj << +/D [199 0 R /XYZ 74.4095 696.3583 null] +>> endobj +198 0 obj << +/Font << /F26 180 0 R /F31 192 0 R >> +/XObject << /Im1 171 0 R >> +/ProcSet [ /PDF /Text /ImageC /ImageI ] +>> endobj +238 0 obj << +/Length 1198 +/Filter /FlateDecode +>> +stream +x??X?n?8??+?H@??????N?)P m tQt?8Jj???4???)??dQ?0h????x?{?????("?G?X+??fZ?3??a?*?-f@???x?$#?(0?d??.???3s?.??+B'dPA???r????? ?M?o?b??-?.7??b^?W??????3?u??<6v?????'?Kx??(?x?CJ??x?????L?c:Kz?Y???\NdfTd??}???5;? ?Y????????6f ???G???? =???=??o?V`???14?????C?????l?;3?\??HtI????%??KE??;????]??)??k?q? +??????????Kkb?????IcZbb$GqrC5?D @2?~l???5?J4E\$?$q???$??*8? (?Lk4s?ac??D$?#X??m??T??pU????~(??? +)?? ? 5?53M?qZ??v?_???bD:N.?p6?:??T??t???;?+??J?E|??$`???i?`??c\???C?l???#??8?P?5?GC?&?'"x?j?W???KB? ????Sp???ut?6?????S???????e??t?e?g}?r??P:???8U!?!?9I%????ky1~??:?? Soy?????Y.??7?C???z8??K??O at M?????D??$?78?gIn~??v8?i?u~?????2?A???" (/R?E?~?t?x??v?N?? ??? ?? ? ??? ??l?????r???S?M??7??p6?_9??T?C???1e?$???2?D??Wendstream +endobj +237 0 obj << +/Type /Page +/Contents 238 0 R +/Resources 236 0 R +/MediaBox [0 0 595.2757 841.8898] +/Parent 181 0 R +/Annots [ 240 0 R 241 0 R 242 0 R 243 0 R 244 0 R 245 0 R 246 0 R 247 0 R 248 0 R 249 0 R ] +>> endobj +240 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [100.0827 750.9806 113.1137 766.9208] +/Subtype /Link +/A << /S /GoTo /D (page.47) >> +>> endobj +241 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [111.2713 707.0703 243.1758 718.5671] +/Subtype /Link +/A << /S /GoTo /D (subsubsection.4.2.3) >> +>> endobj +242 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [111.2713 689.1376 358.8599 700.6344] +/Subtype /Link +/A << /S /GoTo /D (subsubsection.4.2.4) >> +>> endobj +243 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [111.2713 671.424 295.16 682.7016] +/Subtype /Link +/A << /S /GoTo /D (subsubsection.4.2.5) >> +>> endobj +244 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [111.2713 655.2347 276.0815 664.7689] +/Subtype /Link +/A << /S /GoTo /D (subsubsection.4.2.6) >> +>> endobj +245 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [88.3572 637.302 177.8509 646.8361] +/Subtype /Link +/A << /S /GoTo /D (subsection.4.3) >> +>> endobj +246 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [73.4132 609.3817 144.1971 619.1549] +/Subtype /Link +/A << /S /GoTo /D (section.5) >> +>> endobj +247 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [73.4132 579.6979 213.496 591.2595] +/Subtype /Link +/A << /S /GoTo /D (section.6) >> +>> endobj +248 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [88.3572 563.5784 231.2003 573.1126] +/Subtype /Link +/A << /S /GoTo /D (subsection.6.1) >> +>> endobj +249 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [88.3572 543.9022 201.0335 555.1798] +/Subtype /Link +/A << /S /GoTo /D (subsection.6.2) >> +>> endobj +239 0 obj << +/D [237 0 R /XYZ 74.4095 738.0292 null] +>> endobj +236 0 obj << +/Font << /F26 180 0 R /F31 192 0 R >> +/XObject << /Im1 171 0 R >> +/ProcSet [ /PDF /Text /ImageC /ImageI ] +>> endobj +252 0 obj << +/Length 3565 +/Filter /FlateDecode +>> +stream +x?????6??_?[??,??N???$???nw~?9?z??^nwA?8o????l}?)y?-?????????<{? ???j ?? 2?7??r?)?{?> ?????? u???X??~?????X?C?I????J,???`??????????????\5????w?????j???.p???? ?`8z?}??? ??????:?????^? ??????S?Sw?(_I&??????`?RR??{5?{??????k?oA?:T??izz}?_9??*?@8??3rN]]??$?????S???!???????M?Y?????(C-O?????????%^)???HNa?! +??$?rMj?$??9bTa?`X???l&??!?????a|??Ni????F??9gk8T?XC???X??C? ?*A0?P9??T???n|???X????????\?M?9?1:??,tN???q???:??2??XS??3JI??%?c??}?l???????????????[7?R?(????#??3B>???u????X???yQL0?3?7???VL?? ??y?PyU???E\`?8?H+.z?K0=?3?3?Tz??d? ?b N??P?B?????'?_E)?Kh%??E +??6??\??`?I]???????????o nt??|??[???jx?{?v[?n??e?'????p5/?~[{??q{?????%????|1???a? c[?????#??(y??rS??V?????- w?x??t??P5?Q?9'?o9?+?=??.??Cy|?????^:|G|??aO? ?$?$@o?????i?q??x?6=?+8??$~m??ix$??@?H?O-???6?s8?B??h??1????v??E?_cE-?;??????G?d?9???[?+d?ed??d??@>NU,???+_?&?x??d???????4E?b??NC/????GYq?w??L?????A?6?}!'????b????k+??b?????????..?D????5?*? C)$,L=????u@? ???#%>?^ R?? *?????:?????:iow?@ ?{c?M????z?Ax?L?$n???+[R?????/?)Nq.%F;P D????1>???R@?K?zA???Dr1?6?????z ?wC(V??I???P?^?_?m?u8ld?.???`?t?5?????????hx?;?&????E??{??{&AX?b{?/??t???J$O??<???%??6??8uU!K?r{?[i[1Te?,%Zq?????{A0j?L(???tZ??.K??2B:??.??? tO???q???????vz?????Y?R?s ?f?H"?lK???!+?G?w?.T?B??y ??????4?????Q2=?w`?e Qa L??&(dc{hyK"*?-???Y wp??????J?mg? %b)S?4O?l??f???B????/?%#]? ?&X??Z????d?B?d?fn*q??d~???l??.????CC7KU???+5? ?T?Z!mR??`??"i?y9???22?I???~x?]???????\ZKc? c??Fnz,???A???L? +??m3??3?7$??~x?%/$%??0"?aa??( ??~0? L?9???g??C??{??B???{h???????G??$???b???B.?$???;-??V??K?,?q??Bp???chNpF?????kf???r??%1????e?? +???????Q?LF;{?A??7?{A???p???cQ???jg??S?< el??A?K.??d??`??V?#??????.%r?)G?I?UjS????@Cr??og?0K~??????t,?2?,,??????N??Ij?c.?*??????? ??????q?V???$?A?????M?Pf??R?? O?W?????A??E???????J?????'??N??t???? +???? g +L???`???e'\??a'-??g`?Sat j[?#?????????1?kq|??????%8????n??x#?J?u?I?????*K?L?J??T?????????g???5M??T ?????C7?R??0.????7? ?*?>?s*??g ??8k???????8??}B??s?lw??(+k??5??A??????7&???T??/)N?L?R??????K?X??? 9??|???5f/?jE????-[&????&??a?H??????p??O?N??y?< %?????o???Fp97???I?,??,??VT?k??????kv??}:Y????8??4?c????????x_V"?s?t? +?%I???????8X????z???.?]w??s???d?@'?~6)????#sn_?? F????Ru0K?a??bk)??-??;???|\?>0(`q,pS8'??Y?W$ ??V????,f?]??????????5?????B?;??i9?o8???9c7?W?v??????E?/endstream +endobj +251 0 obj << +/Type /Page +/Contents 252 0 R +/Resources 250 0 R +/MediaBox [0 0 595.2757 841.8898] +/Parent 181 0 R +/Annots [ 254 0 R 256 0 R 260 0 R 261 0 R ] +>> endobj +254 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [100.0827 750.9806 113.1137 766.9208] +/Subtype /Link +/A << /S /GoTo /D (page.47) >> +>> endobj +256 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 0] +/Rect [472.7408 677.5112 501.4627 687.0453] +/Subtype /Link +/A << /S /GoTo /D (cite.D05.1) >> +>> endobj +260 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [98.3198 370.6618 186.3587 380.196] +/Subtype /Link +/A << /S /GoTo /D (stackless-features) >> +>> endobj +261 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [98.3198 145.536 300.8681 157.0328] +/Subtype /Link +/A << /S /GoTo /D (optimizations-and-memory-management) >> +>> endobj +253 0 obj << +/D [251 0 R /XYZ 74.4095 738.0292 null] +>> endobj +255 0 obj << +/D [251 0 R /XYZ 74.4095 720.0964 null] +>> endobj +6 0 obj << +/D [251 0 R /XYZ 74.4095 720.0964 null] +>> endobj +250 0 obj << +/Font << /F26 180 0 R /F31 192 0 R /F14 259 0 R >> +/XObject << /Im1 171 0 R >> +/ProcSet [ /PDF /Text /ImageC /ImageI ] +>> endobj +267 0 obj << +/Length 2042 +/Filter /FlateDecode +>> +stream +x??XK??6??W?HUE4??=%??TR?*'??=8>PGB?Y$-+?>?EI\;???n??_???)/??(?c/5Y?\{e? +?=??WJl6?h3???e???N<&J????ea`?M? V +d??????z????)L??zc??W??????_??=??SQ?Um??;???M???????&???????V?????????Q^? A??F? ????'`??~?????L?R? +?4??8????s???b??,?|3???xXc???JJ??????OV?r??z??w????=?[??yaA#???A?i?????? ???(??n??????7?fA???]????Z4?????A&~Y??,??X?@??fEI?I?$????u????.?4?a?%?G,??T?@?T????RZ????m ?R?;???_?ua~n?~????Tb?TM???t??\??]C_Tlr(\o?~?c??N?"??d}W??? ?}?q???@??V????}]? _????)?$?????e??o?1??V?_?2x?G???g{?G?6U;??}U???i?}5??Q???s6K???m?l?*-1????:4L ??=n?8m9??)J??????U?b?y6???>@3?????m??T B?+?I????Sq??1???j[~?@????w???+????????C'3???H?~??? ????m?????4}?;?b?!?E(?8?48?????z? +$O?3'?C??????s z?Y?a?64 g???Jt??????l? K#??=$&?]X?? ?,??$ ????q???E<7?=)?y`T????????H?m?V????6pL +8?a?h?<I?c??U?????en????Gc??}?#H?????b_S??? +???????v/?Q?A???? +d?M??Vb?O??3i'?6?,i??ny)??%?? ?@?J?O ?X??????E ???m?gU1?}??8?????>f?????Y???b???i??%????f??)?{??6?? *@???vW42?8G?F???}k?q'?E?&O??t00???ALdy%t! ??f??VHO??r?%P??_????V?+r???J>J???g)1#<v?@!???fy ???? ]?Y})X`????P4??N????{d???.N?E???CE??g???? +??-??o2??RXO?pp???:?]?? H 2?m#???Y?d?L??Q???????yp2??S?Aw$r????#c?O?k?P)u??ci??G +??N??c7?h3>??N ??Lz{Nl?ns+?f??@v{I???????h?????ng%???<[??_4??XWH?L=?s??6?%.[?v???w?D?dT?"?????i??{[R?(?T?v Y??'??H??????????^?u??e???8"1.??\y???j@?Nw9DgZ??(!??(?/?U??+9?w??9B4??K8?`????,??!??VC???\????0???7???eD??p?T????E??S%?.???5??d???????; B????E|sf??????\2??k?*?@???.?m:~J?v#]?Aj?/??$???]?&??/?/??B_Y0??(8??"GL??????N???(??? ??-??B at J' 0?s_??C?W???5?gs?C?U??,???^?????`????&??N???M??4?????B=+?8??????????`Q??In????S?Bz?- ??N?????qk.?; | s?H?%*u???????????g???.v???u??8?UN??x???w7????????????|???+G> endobj +269 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [100.0827 750.9806 113.1137 766.9208] +/Subtype /Link +/A << /S /GoTo /D (page.47) >> +>> endobj +270 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 0] +/Rect [250.5367 440.0417 276.778 449.5758] +/Subtype /Link +/A << /S /GoTo /D (cite.VMC) >> +>> endobj +268 0 obj << +/D [266 0 R /XYZ 74.4095 738.0292 null] +>> endobj +265 0 obj << +/Font << /F26 180 0 R /F31 192 0 R >> +/XObject << /Im1 171 0 R >> +/ProcSet [ /PDF /Text /ImageC /ImageI ] +>> endobj +274 0 obj << +/Length 1738 +/Filter /FlateDecode +>> +stream +x??X???6 ?_??9@???_}?z??b???/]|?/1??i?????#E???%?????$R$E?HQ?????i??^??e*?|???h???? S0???n??????????@&???1/?????.k???Zr? ?-??cVUEU??g?z?V??fu[e? ???????=y?????}?Z /ei??? ?b??c?>?8??d]?r??Jp?x?zq?0R!?)??e?0??c???#?3?h??g??dB?z?}???????4???N??8??3??2?j??M&?Ir>?Q??)???8I4*??y?i??6\?1P???Ni??n?????n??????|6',?B?)S&B????? ?6???+?R??? +)?n??:b:?b?R?>??2T?u????,?????'O!? ?I???o?????lN????! +, Ciq?$??*????|{?X??b?i???lm?4?i_??2?e?'??h ?p????hsRS???il??"?Y??_A\R* +???Y??'hA?2%" ? =??`2)=??.?%b2?]?? z???q?H??T:??[????S????F?????@?H?S??+?b????uX?-???????P?bC;????rP?4KG?K????iY`j?4U?????6R???d???u?C?.o6-??????o[??p85:\?'"???F 2?",o??)??(?,??CAp?h>?e?????B?@eSd8???fq????8??????*/?=?q?w?#?w?g??+?om????????O?C?g???}?"??e?U. ]VVO?8JX"????\?\??????????z?p?Po??2???|XG?????j)??X???}?-h!o?????Y??????1?3? y????8?q???aJ????5?R%???/T???,&uT(m?e? +?Z?y???E?(?Z?????????3?q??}?T?b??.???Dj?=??????]?s(??????Z|?8?ltq?Z_6?n\???%??ek??e0P?YJ+fWUdm?l?? ????w??i????A4?x-???.?????5??^ou^?wk???9??sQ?1 ????????fft"??.I?PK?^??u???????)??EG?37,??`??)?qjN-?? + ?D??4Qq?@?????????NF??????? fx0?H????????O??m??^nR???(??P???U?n????????o/S?)???+MU%?????%?????}??9???&?T?fk??q?}s?B??a$???N\??Q?b <K??be?+"??:?? ?? ??84?*H [w?E??s??i??n???T?6?xvE5l??????D?L9t??P??=)?????u???%?n??xW,??1(?????=P6t=???cs[??;???4u??[D)?b?????@????q]?J.;hJ?J?{???!??a/?y????i 7??;????? ?+]g????:|? +nr=9R?/!8???_>?L*???W3?I +M??]?3]?9??:?|J???w2d)??!?v??? ???{[?)??Sm!??D?????I c8????,???=??> endobj +276 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [100.0827 750.9806 113.1137 766.9208] +/Subtype /Link +/A << /S /GoTo /D (page.47) >> +>> endobj +281 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 0] +/Rect [364.5084 330.6422 390.7497 340.1764] +/Subtype /Link +/A << /S /GoTo /D (cite.VMC) >> +>> endobj +282 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 0] +/Rect [387.7614 278.8365 416.4832 288.3706] +/Subtype /Link +/A << /S /GoTo /D (cite.D05.1) >> +>> endobj +275 0 obj << +/D [273 0 R /XYZ 74.4095 738.0292 null] +>> endobj +277 0 obj << +/D [273 0 R /XYZ 74.4095 720.0964 null] +>> endobj +10 0 obj << +/D [273 0 R /XYZ 74.4095 720.0964 null] +>> endobj +278 0 obj << +/D [273 0 R /XYZ 74.4095 696.3583 null] +>> endobj +14 0 obj << +/D [273 0 R /XYZ 74.4095 696.3583 null] +>> endobj +279 0 obj << +/D [273 0 R /XYZ 74.4095 535.0903 null] +>> endobj +18 0 obj << +/D [273 0 R /XYZ 74.4095 525.3494 null] +>> endobj +280 0 obj << +/D [273 0 R /XYZ 74.4095 443.4516 null] +>> endobj +22 0 obj << +/D [273 0 R /XYZ 74.4095 425.7406 null] +>> endobj +272 0 obj << +/Font << /F26 180 0 R /F31 192 0 R /F14 259 0 R >> +/XObject << /Im1 171 0 R >> +/ProcSet [ /PDF /Text /ImageC /ImageI ] +>> endobj +286 0 obj << +/Length 3548 +/Filter /FlateDecode +>> +stream +x???r?6????[8U? >?????r*?rlo?!???P?r"r,???_ ??,[U&?h4?~s?.???KMh???R??Q????|??a??7Jp??c?????o?d?L?M?>???(?Y +D????'???x(??j??????: +??o???C????R? +?4????6??O?3??????C???$???+???IW??8T*5??r?^?tE w}?'CB?}??(??4Q??sq&Hq?x4V?ZGPM?4? n??{?n??????o??y?????g??????f??t6?fa+ ??Ce??h??F?#H??????x,???%? ?T?%O?;???chb??H?I?????p???J?;????D??D??J?y?/?;?b*at?$&?v??"|???/?g??q%P??o(???_???B +"6?Oa +?p?e??QJ"???6d???????????T?P_?w??????!]?q65E???h?7?K ?uU?tk?>?aY??C??c? +B?{i????ry?w??4?K???>`??(03?T??>5)/???j?~d???E?a???m???V?V-;+L??6??f!?9?.N?P%Y?B?2?? ????GB ?0S?"1????NdBm??m?J???H?>??w?4T?f5/?a?uH?0??tb?JP?????:%3?2U?F?U??~??)B???nj?s?#=BH'qP}???'??2???9?????????X????[?v?sA???y??4B??0?"|????$?S.?`?-DA???n?????,}?&\???\,4,?}@?????|*L]=O?]????S"@/??;? ?r??6M??????r? ??\{?A?m\?^"? ?????nx?X ???f?? ??Q?3??P???8????]x?l'xwg??????F?\ ?? ? ?U^??g?? ?????\H???????_?????N???2?Y?S9??"?_r??~?????U??????_V??l??e?? e??,??5;.?F??BH?????0?L>?Z:?e???P?H?;Z:?t???+????5??`?Xl? ?????Z? cu??I??QN?N?g?jL??endstream +endobj +285 0 obj << +/Type /Page +/Contents 286 0 R +/Resources 284 0 R +/MediaBox [0 0 595.2757 841.8898] +/Parent 283 0 R +/Annots [ 288 0 R 292 0 R 294 0 R 295 0 R 296 0 R 297 0 R 298 0 R ] +>> endobj +288 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [100.0827 750.9806 113.1137 766.9208] +/Subtype /Link +/A << /S /GoTo /D (page.47) >> +>> endobj +292 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 0] +/Rect [121.6144 653.6008 144.588 663.1349] +/Subtype /Link +/A << /S /GoTo /D (cite.SLP0) >> +>> endobj +294 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [365.0223 378.6794 432.6396 390.1762] +/Subtype /Link +/A << /S /GoTo /D (related-work) >> +>> endobj +295 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [477.2303 267.068 521.8625 276.6021] +/Subtype /Link +/A << /S /GoTo /D (stackless-transformation) >> +>> endobj +296 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [73.4132 255.1128 145.3525 264.6469] +/Subtype /Link +/A << /S /GoTo /D (stackless-transformation) >> +>> endobj +297 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [434.9917 187.6159 521.8625 198.8935] +/Subtype /Link +/A << /S /GoTo /D (application-level-interface) >> +>> endobj +298 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [73.4132 177.4042 119.0416 186.9383] +/Subtype /Link +/A << /S /GoTo /D (application-level-interface) >> +>> endobj +287 0 obj << +/D [285 0 R /XYZ 74.4095 738.0292 null] +>> endobj +263 0 obj << +/D [285 0 R /XYZ 74.4095 720.0964 null] +>> endobj +26 0 obj << +/D [285 0 R /XYZ 74.4095 720.0964 null] +>> endobj +293 0 obj << +/D [285 0 R /XYZ 74.4095 491.2397 null] +>> endobj +30 0 obj << +/D [285 0 R /XYZ 74.4095 473.5287 null] +>> endobj +299 0 obj << +/D [285 0 R /XYZ 74.4095 178.4005 null] +>> endobj +300 0 obj << +/D [285 0 R /XYZ 74.4095 178.4005 null] +>> endobj +34 0 obj << +/D [285 0 R /XYZ 74.4095 160.6895 null] +>> endobj +284 0 obj << +/Font << /F26 180 0 R /F31 192 0 R /F34 291 0 R >> +/XObject << /Im1 171 0 R >> +/ProcSet [ /PDF /Text /ImageC /ImageI ] +>> endobj +306 0 obj << +/Length 3545 +/Filter /FlateDecode +>> +stream +x?????6??_????X!E?????L??df??L?????????????D??{?@Kb??b?i?R??W? ???Uj?PEy?*?Oj??/OZp6i?c????w??d?mhl?>=?2?,?I?Z??????????&?T??JC??zcl??????u??????8MS5u|????F????b?????Z????r??~??w??^?a??b`j??&?m????4?????O?????J?U?a???w???^P~?d??7>>?`???*???7?uj??+?Wr??bzC ?????'!o????KO??W?E? EJ????&4Fe at 5 ?,??|?e?B 'h ???'ms???????^??=????m??I?0???]?????h???$??'????(?B?C??J???8?%???.?GR??>]????D????0?F??lYW) .????n/?EMCN=? ??'6????Ox??D??d???P???????( ??F?1??x|??M?????????*?K/?kY?^?B?,?h2?t?To??X?D%?i?t? ????P50z?M?\g???.+??6????X{????? ???aN-?n???Q????q^?D_Gx/7???ewiv ?c&_[4bzCK???n???%?????)[d ???8?$??}[V**?V????v(??C/??L'?Bak>??x??S?]JvEIpj?Rh????SM?]%????t??)r.K[g???b?? ??n P????=?P ??z8???????)t@?,P???;ZN?Q??? +F^?? :uu+K`?^??:G? ???3?+?? ?v?0X8A?{??M??4?gw?oye??:?Xp?Z????9?(??:~?8K???51Z^_-i??? U at M????D???????????t??3?]??Gu??f??K~?,??*!?|;38??-VHH??[??y%??????Y:MI)"P???R????m%*?? +??K??0O1???67ab!;???-???????mFDH??4?x?&??x 9;???r???$??;?a~7{????0?#Cd?=?????????r?x?;3?????????l?aSl???;??:;&*1????E? +?????+?(6??TJ????I ?1"??????p?X??a?f?)???,?J??xX?a????N +p?tY|??A[? 3?}5?(%????&???z?!u{Ws90??ut?T?K???9??U?O`??@O7I[???#nv-8??I?TVE???k&?U?i e???:p???MCgZ??{X?????H?I?E?9?`??????x?4?0kb +??t?&????fR ??W?E4.?G?H-J"?]M?+??Ud??FW???a?ps?&p??h??j???u8|?E?I????P-?!????*???Pa????????VX????$W?q? 0\??????????????65?M0???/???{?"??X???b?}TJ?uu????D????#JL6??g???Cel~???A??B?w??e?c}?p???GG?;a??w??5P??p?????{????d???wn????bL??;?v46?V?0???[?]^"iY?,?????Gy(.????\????c??c?Y????/??K_?|???[??????F? "hgj??>???y[??M?5 X???n????? ???F?i!K??!N????8?U?fq??:???WG#?[??C?cut?t?:?1?? j??zq??D??x2?????M?yK?w??+S?C??? ?zXd?????#??L??.??gZHSE?g??QQ1??_.wg???@?"?4?E7G?~ ?ZY.???+?????? E?"??? ?&$?*u?[s)???9?w)?O%?A?g? X;?D?;??*P~?@?????Z??/???5??j? F,sB_?C???j??Jh???v ?+?]??_?^P?)p??q2'??????h?w??_6??)G??$zL????t&_.???}??u???6???8??s?jA??$??#>?}??????LG??a?h?3?c?d2?????A????Y}\? ???d?#A ?=<?r???/?v5?????n?'???n3????8x?h?kR???x1??S?W4o;?7Mh?y??g?FE?y#?3o???Fa*w?\^O???j?c ???`6?a/X???8p??^??> endobj +308 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [100.0827 750.9806 113.1137 766.9208] +/Subtype /Link +/A << /S /GoTo /D (page.47) >> +>> endobj +307 0 obj << +/D [305 0 R /XYZ 74.4095 738.0292 null] +>> endobj +309 0 obj << +/D [305 0 R /XYZ 74.4095 566.6339 null] +>> endobj +38 0 obj << +/D [305 0 R /XYZ 74.4095 549.095 null] +>> endobj +304 0 obj << +/Font << /F26 180 0 R /F31 192 0 R /F14 259 0 R /F48 312 0 R >> +/XObject << /Im1 171 0 R >> +/ProcSet [ /PDF /Text /ImageC /ImageI ] +>> endobj +315 0 obj << +/Length 4001 +/Filter /FlateDecode +>> +stream +x???????>_?[8U+??W|rboj]y???|?}?(??1E?"?????_A??-5 4?o@???]ab?T??H?8???5??d? }{P??wH??/?x???2qjr????+?8- ?Wq????E??~????e}?????>5E??z?O?:?,w~???Zw????????$???????,????????m??????~?>U?*?rX ,"??UW?(hz??????'?}???gK%y?U??Ygy?1??u}????????????:Lq7?*??j?????z??c???PNI>??Yw?4 ?r $ ????A???.??????`g3???A?!8f??q`??g??^0???(????r.?$?7??o??t??IF??Y??D???Y&e??2?*X,?o?q4X??x?6??Y????+??l~=??M?y}e?_-h +n??S??????O??E???N?????i?:?Lii???3Z??5??*??|?@?C;??0b???R?????6iq< xJ <??u?25El???Y?rSq;??????+??????Iu???????^T?N???? +?????w?p?_$?- +-????xr?\?KL\TI?d'?)??J?F??? S9?Xj??????ItXD??l?s?#?, ??%??| ??D?3$B???4??????>gS?????B?r\?U?? ??O49~?????U?D???nv?????????? HJK8 m4.???8???g4c???KZ??#??&z??8 Zs??a? ???B????:6?=?)?Q? u??'r?<'?yJ?9Q?I??$]I?? ?????q?f u?????$? *??@RZ JB??Z,0?Z??f??O??? ??qY?D?)h 7i??Y?R^?F?af5?w?????!?f"???C???1B'v? ?4?b???.{??-?????G?5?o???b????G?nN???qa?e:???LJ? ??:C???@:_$siZq?K????Z??????^?:?:??f.?????V?5p?????L?\?t???.wi?????T?Z??s????;???8?K?\??(????z?}8`??????a??G?1??W???T?Z?)V?Z?Y????U?&??K9X?V?_??5?V?'|e C&??@?j}{WV?V??XT?t%v???v???*?~???e??y??p?>4?I?gK? ?.???\"??rq'_K??????H??,e?T??S*?A???J???(?;+k?x?????I?/??2?+???EmC??p?-?=-?c???\?? U2{???{??]????????D ?R?,?4??R??kn??i?s??-?@?????Q/??I%??[?|??J?=??~rs???????F? ??m???????X? ? ?o? ?U????s????????{)???:??h?F???|??A?u Y??F?(Tg??2DB,@?wK?J?E>???4t??????{?4?????^?Op???EpY?2-?????2wo?rp?_?-& ?`????i???K??C?q?A??E"w?I??? Q??y???G?$?~Y@_????|?(x??? ?FvE?>??MKr???h}??R?;????3?VOu??- ????v???? uK?,?ag??w=?m ?t?\6?"??/j???D~?????M??$?S???bq???D????$5?x?Sa???T?????L@?S?B?8????WyWSj?@6?-Zs??????|c)?EL"?l)????p?r?q??o??#?`W??~??a3M\??x?>?/?(?X^?`???8?F??\ft??0?l9t7??#?????, ?CK??JKq;???????????@@???{????e????? ]??:D?9?? ??K?? 8????rC???.l?68F??[yDU??????Ev?2S?R??f"?'?uY???vJC&?Fq?????_48? ??P?:_? ?[??????v??_"???+ at l=?As?sb/?]???r????u??p?(1? $???? S?-eSBk???A???m?#???2?]???{=L-?W?????U?????> endobj +317 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [105.602 750.9806 118.6329 766.9208] +/Subtype /Link +/A << /S /GoTo /D (page.47) >> +>> endobj +318 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 0] +/Rect [346.4438 434.0641 380.1967 443.5983] +/Subtype /Link +/A << /S /GoTo /D (cite.PICOIL) >> +>> endobj +319 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [326.3722 348.4153 416.211 359.9121] +/Subtype /Link +/A << /S /GoTo /D (unbounded-stack) >> +>> endobj +316 0 obj << +/D [314 0 R /XYZ 74.4095 738.0292 null] +>> endobj +320 0 obj << +/D [314 0 R /XYZ 74.4095 116.505 null] +>> endobj +321 0 obj << +/D [314 0 R /XYZ 74.4095 116.505 null] +>> endobj +313 0 obj << +/Font << /F26 180 0 R /F31 192 0 R /F34 291 0 R >> +/XObject << /Im1 171 0 R >> +/ProcSet [ /PDF /Text /ImageC /ImageI ] +>> endobj +325 0 obj << +/Length 3218 +/Filter /FlateDecode +>> +stream +x??]????}?????DR_y)??]q?^? ???,km?d?Y??????/J?,??X`E??p8?t???/?d&4Q?l2???*??:?E????.??C??X?x????J7? ?I???q?G??3X4-?$???-?????~??(?.??????6Y?Cim??^EA???]>?m[??=?a????????my?M???;xk?u5????????7EX?@ m?? ?e?}??, ?G??{?0+??0)r???$LR???q?? 8?y\???b????u??]?ga??l????#??v?Z w}??O??=A/ +.%|M????IE??&???Q??a??7????B?h?o??_w?)xz9?7N???????????t????5???n????G??'??y*?d????????44 T ???w???(M]ci??0OS?.?KG??a+?s??U??A?(?])?K??/???C??l?S??a???R?Z?v?jy?ld??y?m? ????NV???aZ?E`G????????$?f`?x?F?#M???P??? e??{????`??3ha??+??t?f?k??? KS7?!????bk?mhR?J??p???7??d?-{???s?^?ZH?&I?#Q???\?p$1KT74??HOu????.?* p????H??V??Q??d?(?L*2*7? ???n?u?l?? ?G??q?????=}?2???Q\q?thViB??Q????{?w?=???9????O?q{4p??0?j4j2?|?t^?%? K ?}??QjHZ??s??!??F!?{??E +??????????D??A~??!??c?????????`?J?X?c?_? ?a??????%K???vS?L???0?J*cm??? ?e? ?c???60???e?????????????????x?|??K??$i9?8?d?s?????A+g?dL ?'q??79????~C!?? n?6???z???~??8"pAJ#??"?YTx?? vMRkg??q4 ?8&z????M9,A?q?9??N?????%???/<@???G ? ??$???,8,?}?h?g??^?}??y??c??PFk???IdPA??`?{REb%???mu???X??4JiU??r???#?;4vu?1???dr:43?/2?|?,m??VHk\??d5s@u#?W???? vu??x?????g??? ????#?z?\IV^n????v?puH?2N +?shZq8z??idz'??<^??x<??\?"iV?AF +6?????5???.3? ?E?j?? +??-B$?:?aE6I",K?o?????Q??r+?Q,v????? [???i?m"??????J??????fIP?????7Y p???b?1f???d?0??" \f??+?S?1s???7??h6 L?)/!d?a?(???4??????TE1? ?mk?? ?A"6,Dp??F?x?x?S?-?r?X?:?S?E4?H%???(H?p?` ?+}?z????B3?????r?s??C ;? O?d????s??+???)????8?g7k?}?g?P??$?M +?g??"/U;????$0(\???TBX7t=g;?RJ??^2?g??I????.?7{?C??{???; )??m?\?0???????$-?-?~???HH~?*??r8??H?Z????4????????;????A?W??u?? ???6???05^Y[KY?Z?G?g+y??k???/X]&~? +???????ez?????'??UtU?????I?????r??=????>?? ???2N?CS?j???? 15?c?b? s?RVX???A?R5?l?????????1)??u????aZ??'???????c??=]??]?h?d???Bk?g??4?u??WXJ??}9Hae??Hc?q%dc'??y]?c???Y??2l?f??????? ?l??:pe???=?U?????|\h??$y???m???^????T?2J +?:J H?B?&~"?? &o4???Z??Q??=CV??$?{9???{d???T"G?"9E??j??|1????$????? +?H?L?Q?h?o????.???????Q?X?????E?m?????W/?? ?6???:??M8mZ??q?7E???B?I5L??7S {*/??sf)????(1?k?3p?[??????H???????}?T????fA?B?G????@??(??2tgR??!????????j??0V?W?~BzE???:?????/v\?xoGV??'?????j_Q?X?0??t????jm????q9K$x???c?8????U???&?.??w?? ???7?b?i?;?v?wf??'?On?s2?J]8WYLa????Z??b&??~?B ?O?|,? +Tb?#t??;?????^?e?? 0?? 8??=5? {?w/J??????{CL?j??Y??]??????endstream +endobj +324 0 obj << +/Type /Page +/Contents 325 0 R +/Resources 323 0 R +/MediaBox [0 0 595.2757 841.8898] +/Parent 283 0 R +/Annots [ 327 0 R 329 0 R ] +>> endobj +327 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [105.602 750.9806 118.6329 766.9208] +/Subtype /Link +/A << /S /GoTo /D (page.47) >> +>> endobj +329 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [183.7685 146.9535 273.1427 156.4876] +/Subtype /Link +/A << /S /GoTo /D (unbounded-stack) >> +>> endobj +326 0 obj << +/D [324 0 R /XYZ 74.4095 738.0292 null] +>> endobj +42 0 obj << +/D [324 0 R /XYZ 74.4095 720.0964 null] +>> endobj +328 0 obj << +/D [324 0 R /XYZ 74.4095 341.2373 null] +>> endobj +46 0 obj << +/D [324 0 R /XYZ 74.4095 323.5263 null] +>> endobj +323 0 obj << +/Font << /F26 180 0 R /F31 192 0 R /F14 259 0 R /F48 312 0 R >> +/XObject << /Im1 171 0 R >> +/ProcSet [ /PDF /Text /ImageC /ImageI ] +>> endobj +332 0 obj << +/Length 2462 +/Filter /FlateDecode +>> +stream +x??Y???F?_????z2??z??z9????t??b????Yr,9????????w?+???H?? 9Kbk?yj??J??\n ?|??/??Y?????w?7o?] +???ry?[&??$?6eF????~??Z??G?????Wk????Y?_V?G9-??~v??2/???????NY???jm???+Z??9???Y?q????J,S?ZP????P,?q?? ?qT??v???n[?[f?D.cc?????q???i> ?????83????z??B???U6??????zI?7??m??3?? F<:g?j=??Lk???f?B??g*x?h>??s+??hy??60?I w?#?rF%?+?y??????X????qahv??'A-??q ?m?t.?2i"???@ +lb$?????\?s3{?j??????C??@??+@??s0????)F?H???6L?\??+??%??5??O?WB??)!}?$F??1= + ??f}a????"?S???????h???M4???:???B_??s6P?J???? ???<@?]Ey- ?\??(??????K(Sh??BgQ~$t?S`2,?4?J??*????>??O=??p?v/M?s? ?P???bk????????8Q?Jb??3???U?t9 at S??'_>}?X???v? 6??????h??UG??r:?Nn:?????tT/9?M???\?u??P?;-??'d-??H8?V?A2?8o??>?[?????N?hr??a?w??????? "???gs<\w????e? ?r??7/|??C?0?S?C?1{????F?T3??????g?-Yb?5\X???? ?? ?s??k?/??dw?Vm3?Y?9?6C????x ?8K?K???v????$????x??? ?????`G????p?YH???8?xK?F?S????r???????]}?? ????W{??CX/V??O??#?J???y???D;'???Q5???? H5?????-^?m=???+??^??????i???????? ????T?mR??T?i?S;???U??|???????f=?Y9??~?S?p?a??endstream +endobj +331 0 obj << +/Type /Page +/Contents 332 0 R +/Resources 330 0 R +/MediaBox [0 0 595.2757 841.8898] +/Parent 283 0 R +/Annots [ 334 0 R ] +>> endobj +334 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [105.602 750.9806 118.6329 766.9208] +/Subtype /Link +/A << /S /GoTo /D (page.47) >> +>> endobj +333 0 obj << +/D [331 0 R /XYZ 74.4095 738.0292 null] +>> endobj +330 0 obj << +/Font << /F26 180 0 R /F31 192 0 R /F48 312 0 R /F14 259 0 R /F34 291 0 R >> +/XObject << /Im1 171 0 R >> +/ProcSet [ /PDF /Text /ImageC /ImageI ] +>> endobj +337 0 obj << +/Length 3831 +/Filter /FlateDecode +>> +stream +x??]????}???j??"?%5??5????r@?`!???z?????????%J??y* ?cH?{?V???&K?$*?M??0??xS?????p?f???>??>?}?&6??:1????&?B?g??)?T)???{~?|???(?>?B????N??_e?????(?? ?v??????P?v???U??Ag A??Y??{6????q +aET$s?s8@?????h????V?????`w?g?d8a?ly?i]:-@??[??E"?? ~???[{?WB????????r ?CH???+g?A! .???$???~?/??S??^Y?? +?< ?ms\?r?z ???+?:f?u?w??? 04????,? ??4? ?&?T??$aTx ?{{??^??E???&[?\br??a?a?{????]#???????R???;=?????rF ??rg?h???? ?O???6??B sY?d|?u`????9???"m??????g9??b ?!?l????i"??v?? ,Y?^????h?b???????0D?4{^??V3rG?l??(??????????N???????4??6?????? ????di???/????G???S??/?M???w??A??Q??? ?H?xW|?P? |??o\?Y?!?Sm+ +?8??/?\h4?n?R Oy2??R?H??G????-??E? +?@?q??`G^?????gw????-????????)@?]?????9?@???? +n +???????/???FF?,C?N???Fh5;R"W *??????R7??#???????V?Z??????????????? ??y?W?Hy"??l?x?J?q?3???f??N???$??? ????3?z0??o?F??[????b?6ha?0??,?5k5BQ???"?F,?b?qvu???/'?????(??q??3??_mu!?^?aUJ???RA???C2?v?1????#???I?@z +?m?}??r???DF?c????0???.b??T???pV???0zK? `g{9?6E??? +?2??/Zn???/??/?q??:?P?A???"???KF?]??PV ?9???$ ???%%???2?\FDY????t???????o?+???????9E??".zWKd?Q?U) +?I?M??as??$P[l???? ??PJ +?- ?"O8g?????? ??2P?+}p{v??DVF????=???p??P?g?T??????[??????D'?:]Z?X?_???9?H??}??@n???i?Rf??P??O?0????K??2|?????*XSa??T?????K[M?? ??d#?g[??9??V??/%\yu?9???????i??MW????/a??\ ???>5??l$(??????m?z?l=8??i?LjJ?,??b? ???? yf\???????^??e~?]2?uy b??\'????????? ?{A??=v???8???!??=???????3?) +???5?T?#??1?y?@?[wv????????Z?w?Q?xh'SG.~??H?^e"5??.??:???,&#?XYH?=?`hnt???*p???8?r????T???H???1n$?~????I/?xE-?????e ?"T?q?: )+yz?????%s?^??=?? j??F]?????iF?~???oH<6?P???z???baB???R\????? < ?'??7?? I?!?R?Eg?[? ??????1+A????????+?iH ?"?t?)U??hQE$?~+%?91{W?%??z{^??KWFRt??6??'r#{????"???????????e??N]oe?(?+>;?A0Ej1???2??>f???,????x??????????;yd"8????| +{{??%?o??a.x?b???E?SM~?0; ?jjt???3??????J??]?)I????%??s?cM??8]u{??\?m???g??jW??w??I.m?W?"U-???^?\????_ B?d????N?O?g? U?)Hendstream +endobj +336 0 obj << +/Type /Page +/Contents 337 0 R +/Resources 335 0 R +/MediaBox [0 0 595.2757 841.8898] +/Parent 345 0 R +/Annots [ 339 0 R 340 0 R 342 0 R 343 0 R ] +>> endobj +339 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [105.602 750.9806 118.6329 766.9208] +/Subtype /Link +/A << /S /GoTo /D (page.47) >> +>> endobj +340 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [432.8548 635.3393 486.6425 646.8361] +/Subtype /Link +/A << /S /GoTo /D (coroutines) >> +>> endobj +342 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [471.9402 467.3175 521.8625 478.5951] +/Subtype /Link +/A << /S /GoTo /D (coroutine-pickling) >> +>> endobj +343 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [73.4132 455.1431 111.3607 466.6399] +/Subtype /Link +/A << /S /GoTo /D (coroutine-pickling) >> +>> endobj +338 0 obj << +/D [336 0 R /XYZ 74.4095 738.0292 null] +>> endobj +341 0 obj << +/D [336 0 R /XYZ 74.4095 576.779 null] +>> endobj +50 0 obj << +/D [336 0 R /XYZ 74.4095 559.3055 null] +>> endobj +344 0 obj << +/D [336 0 R /XYZ 74.4095 159.2168 null] +>> endobj +54 0 obj << +/D [336 0 R /XYZ 74.4095 141.7433 null] +>> endobj +335 0 obj << +/Font << /F26 180 0 R /F31 192 0 R /F48 312 0 R /F34 291 0 R >> +/XObject << /Im1 171 0 R >> +/ProcSet [ /PDF /Text /ImageC /ImageI ] +>> endobj +350 0 obj << +/Length 3800 +/Filter /FlateDecode +>> +stream +x??]s?6???b?Wy ??i???\????UWW????!a?1Lv?_?%!?NmyGt??V??_R???_???0??l?+FI?l??E?????Xh??h?S?????]?7q?T'?????BerTa??} +><}x??&& +?Fy??r???m[??p?b?????????r?c?w?x5zRp?[??a?????G?????V:_?????zi???p?+^?;??#|E????4 +??!J????4S?R??Qu??????6Q??.?D????E??=?,????m?????im*7a?? +VY?q;F??}?6;???/@? +?m????q?w?HS?,T ?????????4K??h????L??l?0?R?$:? -???# ??q_sC$?m?? ?a,??8 ~??,(?]??O[???h?9??????;?q?w????!?????=6?n??{?A???S?g9V{??8&E???]i?$???8,??rIk{x???j?'?_???G?U?E?/??F?m]w G?!d??????e0?? `????U?21#X? ss???52O??mY???-?_{?????9???`?b?9ZU???iP???0?e???f? ???R@h???;?6??Xl?$C?d???????S??/0]?Mw????LH???(?K@#?W????W7# +???n??????R?#?0x???A??=7?"~?#R??~???q???8?????o??f??F??? ???1G?9RNu? I*?8???????M[???Q?0????b??PA???8?5-_=???p;??5 }EIH?????] ??n1??????!I??f?o 4?.S?5?+k??A at x??.???? ?7??c?' h??@?Q??? jf??tj????=?:Z6?????cg?N???1??????????@????X ???@vn??L??|?-?e?7=?{?z??fgW?????%?J5+W?2YF(?? ?< ?$5? Q????N????(????O?pv]v??C ?j???2????E?g??"X?I!????S????I?lW?g?p?;???#Y at R??#@?b?????Y???4??8;????O?!V?b???I ?{???V???Cc?y????ymK?VSah?u?????VR?e? ???? ???Zq ?kt?e?\??vn?????.???6?Y??? ?#?:?PL??s?|????DGa???G???4?y??w??a????UV???[ +Q???T?vR???/??l??:P a?L?S?`Q?W??kW\?u)??????t7??????O?????d??V4?k????b????s'"??? e??"???B+??]???X???i?f?h??* ?(??&?@c????"rNLl#,?!????_1^r????%l????m? ????O????P?K?$??????b?? ?X????r+9?6N\?f?f???=?- @?j?? ?L??#p+??\?.?/?D??Q?TfN.?n (??Q?~`??m?j?F??D,???????>?hR???2??I???}>????T????N,?P]????U???|??~;U????JP??t??? )?6?+T?c?;??~??{??2t ??O?????_???u????`?+I?X???m3?0??/K????> endobj +352 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [105.602 750.9806 118.6329 766.9208] +/Subtype /Link +/A << /S /GoTo /D (page.47) >> +>> endobj +353 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [409.8793 607.1852 521.8625 618.682] +/Subtype /Link +/A << /S /GoTo /D (memory-management) >> +>> endobj +354 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [485.3695 595.2301 521.8625 606.7268] +/Subtype /Link +/A << /S /GoTo /D (finding-roots) >> +>> endobj +355 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [73.4132 583.2749 98.4987 594.7717] +/Subtype /Link +/A << /S /GoTo /D (finding-roots) >> +>> endobj +351 0 obj << +/D [349 0 R /XYZ 74.4095 738.0292 null] +>> endobj +348 0 obj << +/Font << /F26 180 0 R /F31 192 0 R /F14 259 0 R /F34 291 0 R >> +/XObject << /Im1 171 0 R >> +/ProcSet [ /PDF /Text /ImageC /ImageI ] +>> endobj +360 0 obj << +/Length 3581 +/Filter /FlateDecode +>> +stream +x??[K??F?????????M27o/l'6??$J?F?)RR?'?~????EQFV??1????uU}??MJ,"??D?:??E??0??\l????? ???5Z???????W?,??6r?n?H?P? j?0???o???? ?W??l?\??r?W???? ?|??,??1???+?s?|???CQw?$??????<{SF5Z/??|??8??q?????fO?}?^?????.V]???a?7??'????????[,???7???2H??*k?/???????t?^???[?u8e?=?D?? y?&I?????c?f?Es3,???g????????4f,?9??U?=???w ??s??S?$?z?H H.?io?c?3@?0 ??cd?????H^??P??=???Y^;t??B???G~??u?Ph????Y? E??C????\"????<??;?9v?$A?_V????m?d???8???o???h???c??f?YV????BeV????q?[)?X????%LEuU?%???L0?w??????-e-2????o?6?8p??8S?dM???Q??? ???6??u??a?Z?'n??? ???v?cP*???k???nh?e??n?????E???<6emc ???A?I0?2]?2??"?Nc5?X?5]??%?? ??6,5????7??2???>????;4??????-????_??,?q?^????,]????X??&y???Z? +??oyy } ?X:?A?????v ?}lk???~( +???t??j?*]?? F*???? el???o??-????@????@IkP?LU? a`?????o '?W?@Mr??Jw%?8 ?<4?P? ????$?o???k?;???y{????4???T??1??*(7Z+?\?V? ;????0????\X? +?Y???!???;79??qHw???????U?A2? ??^???TL?-V??$*??!-?`!Q??9=&n[$KL? +?C??lC?O dk +???>*??j3???M?????n6UP?7???-???R??????%?????C^???U$?4??1?Sk??#??<2u<+?H9?B?????K ??????????????o??G?x??;R???8???;_????????|??u??~???S???)??'?t?c??}?rr????????\?\????R?5A??K(?Ti??7? +v??????H??)?g:????LR??)?5`??NE????ym?LG?g?:??(a??ef?0???C8????u?????> endobj +362 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [105.602 750.9806 118.6329 766.9208] +/Subtype /Link +/A << /S /GoTo /D (page.47) >> +>> endobj +367 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [376.3505 371.1302 521.8625 382.6269] +/Subtype /Link +/A << /S /GoTo /D (microbenchmarks-of-stackless-features) >> +>> endobj +368 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [73.4132 361.1376 116.0529 370.6718] +/Subtype /Link +/A << /S /GoTo /D (microbenchmarks-of-stackless-features) >> +>> endobj +369 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [378.6507 128.0593 450.2912 139.5561] +/Subtype /Link +/A << /S /GoTo /D (composability) >> +>> endobj +361 0 obj << +/D [359 0 R /XYZ 74.4095 738.0292 null] +>> endobj +363 0 obj << +/D [359 0 R /XYZ 74.4095 720.0964 null] +>> endobj +364 0 obj << +/D [359 0 R /XYZ 74.4095 607.3194 null] +>> endobj +365 0 obj << +/D [359 0 R /XYZ 74.4095 585.3269 null] +>> endobj +366 0 obj << +/D [359 0 R /XYZ 74.4095 529.5361 null] +>> endobj +303 0 obj << +/D [359 0 R /XYZ 74.4095 362.1339 null] +>> endobj +58 0 obj << +/D [359 0 R /XYZ 74.4095 344.4229 null] +>> endobj +346 0 obj << +/D [359 0 R /XYZ 74.4095 129.0556 null] +>> endobj +358 0 obj << +/Font << /F26 180 0 R /F31 192 0 R /F48 312 0 R >> +/XObject << /Im1 171 0 R >> +/ProcSet [ /PDF /Text /ImageC /ImageI ] +>> endobj +374 0 obj << +/Length 2970 +/Filter /FlateDecode +>> +stream +x???r?6?????JEhb??s??3??Tu&??C:??(X?4E:"???~?P$E?????????\??????v??L?*W??x?????;?a6h3??????????$ju???b???&??R??????????Feq?c? +?~??&??St]?u?????G????]]u?oy?~???T4]]?76???????GW?????_?}?r??<a@?x??Z?&M??L!M??a?~??%?D???????w?_/g?i&r%5?2???????h??;???@??U??:???{?yp?????y+?/a??y?k]b?_? ~?>?@????KQ5OK?5?6??1?}{??k??????X?f??);n? ?DF@??KQ??????>????]J=!}C? T???9~ ?z?????7?i???b??0}%?-?\m/S'??H????*u~V????,???p?U +?xZ??9A{?????}??/???^?????7??_????\g8Q?m2J&KiU?\?z??? ??&??z?GP7 0@?i???^ p?t??L??@Y??????D????a? +?????y?fA?&{?FS??<?wYm?8???Q[?oU??????{/??8g?? _d????M?p09?D???fX???P +?0?Rmf???fV?}?|?1?????7???Fe&A???????????o +??,??q???s??????3C???f?_C? ?;?"1???'=?U2?????s?N??????o9??.?^-?}?_????I???_?<??????KA??D#???z?O?????`a???c?O????8 +?o?7??"p????B???v?vH(????????(? ???7g???s8~??????|?=?S???? ??~N-?O[???]??{???????:^8?z??G?S?? ??b0l?/q +?m??1/2[?????^?5S!`??+?@??;X?Px?3?@?lLH-?}?A?U?O??p?C\D?+?1??q????z?Eu???u??'? ?{??jC?ca???E???????`?ixd_J????????WV?????<&?zJ???;h37I?7??C????J?\??????I??tvcH=?!? ????????+]?@.]#?s??}?qO2x?? ?Y?g??7???)/?Z?v/???w?????endstream +endobj +373 0 obj << +/Type /Page +/Contents 374 0 R +/Resources 372 0 R +/MediaBox [0 0 595.2757 841.8898] +/Parent 345 0 R +/Annots [ 376 0 R 377 0 R ] +>> endobj +376 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [105.602 750.9806 118.6329 766.9208] +/Subtype /Link +/A << /S /GoTo /D (page.47) >> +>> endobj +377 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [361.6489 621.1874 433.2894 632.6842] +/Subtype /Link +/A << /S /GoTo /D (composability) >> +>> endobj +375 0 obj << +/D [373 0 R /XYZ 74.4095 738.0292 null] +>> endobj +62 0 obj << +/D [373 0 R /XYZ 74.4095 720.0964 null] +>> endobj +378 0 obj << +/D [373 0 R /XYZ 74.4095 227.8301 null] +>> endobj +372 0 obj << +/Font << /F26 180 0 R /F31 192 0 R /F48 312 0 R /F14 259 0 R >> +/XObject << /Im1 171 0 R >> +/ProcSet [ /PDF /Text /ImageC /ImageI ] +>> endobj +381 0 obj << +/Length 2319 +/Filter /FlateDecode +>> +stream +x??Xmo????_a?N??(Ro[?????????uSE?(Y???%?)%????p??l)IQirf83???????2?B?e??U!??L??n/a?? ?4?@?S?x???N???B?,Y?>,?X?"?Y)R)ams??????IG????Wk???/?9??J???????i???n??VoW*??u?Y????]K??}]?n?????k%??(3P???k?D???/s`???{@???n?f?8iY$????+??j?x????\?Q}?#???4d?b???????"???=v?????4??lq???X;tCo?`>?w{??5?[R?????#Dj??i[???}????N?????????*???[????? |?#??r?INH??S??~T#,??F???}????w?????|??Q??U???o???N?(?,?Z??L+?yP?E?????f?? +???-}?4??&?????o?I&d???o?5??G(?*IS F?? +Nqs??(??)wp???*??i\G???T? ??n0?U????k??>? ?81O?+ +?Y??Y????x?pw?Rb????3?`+?H??}????4?f??????(??g2? i?UI??|????{Y0??????uT?,&????T\F???3.??????,?2?j???qo?y?? +?'?@{?8?1????? ???0N??B'??V[bm}O??a??????-@??a?H??? ?H1???????>k=??+?T[?????'A5?????$??-???[_ J? ~??6??#?0??"?x `???z????xM4,}"YA???wx????hu?9?8 ?[@?????6???????QX,??? ??>????d/@[?8 E?(u???-??h?j???????? ??/?g8????z???~???j???cQQ?? -???~?.?:6?4.? ???p?qCczf2$?ah+j-??1?:s?,C?????eH??U???gnp?????+ +??P?J??;?B?z??0I?4?{;?W%?r)????Wx????#???V??pJJ?zC?b?????9?i?}MH??O???????l?$?W[????TOL??{??F?#?e?'?????_??;v?i?????v?b??q-H??{?cxN/?9? ?Lf????x?? S?\endstream +endobj +380 0 obj << +/Type /Page +/Contents 381 0 R +/Resources 379 0 R +/MediaBox [0 0 595.2757 841.8898] +/Parent 345 0 R +/Annots [ 383 0 R 385 0 R 386 0 R ] +>> endobj +383 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [105.602 750.9806 118.6329 766.9208] +/Subtype /Link +/A << /S /GoTo /D (page.47) >> +>> endobj +385 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 0] +/Rect [451.74 342.4254 469.1944 351.9595] +/Subtype /Link +/A << /S /GoTo /D (cite.SLP) >> +>> endobj +386 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [120.6453 310.794 172.7792 322.0716] +/Subtype /Link +/A << /S /GoTo /D (coroutines) >> +>> endobj +382 0 obj << +/D [380 0 R /XYZ 74.4095 738.0292 null] +>> endobj +384 0 obj << +/D [380 0 R /XYZ 74.4095 473.7055 null] +>> endobj +66 0 obj << +/D [380 0 R /XYZ 74.4095 463.9646 null] +>> endobj +387 0 obj << +/D [380 0 R /XYZ 74.4095 238.0145 null] +>> endobj +388 0 obj << +/D [380 0 R /XYZ 74.4095 132.2611 null] +>> endobj +389 0 obj << +/D [380 0 R /XYZ 74.4095 113.3072 null] +>> endobj +379 0 obj << +/Font << /F26 180 0 R /F31 192 0 R /F48 312 0 R /F34 291 0 R >> +/XObject << /Im1 171 0 R >> +/ProcSet [ /PDF /Text /ImageC /ImageI ] +>> endobj +393 0 obj << +/Length 2313 +/Filter /FlateDecode +>> +stream +x??]??6???B???@???>S?C{Mz)?b??K???????cI???? g?e+?=X????pf?U?????P?2??D?BY???????e?g7 ??X??o^? bO?B?q???z?:M?i??H)X+>?w???v???Y&B???t???L??_???-?pl???lU???z????????v?]????=??k???}?F+/Y ????)-?0I?x?A???#?n^??f)?(K/?"?:"?t?3??3/???9?s?B?[??G???W??u?\????????n(???9?? 3?????/ RF +???1???Z??5I??(???I?.?k>??? +3"WrX|??????????6??" ?+3?"?1G???? +?????,??'??2??& cF`(?T????? ?H?\:???"?????W I?t??i,d{#z]?k?fpHt?zs^7?g$f??*VK??m???NG +6?m??;?????g?5G???S??B}???d? ?A?9???G????X?jg???????i`??`?4~`e8?????{??m?n??k?4m~?E_?? ??g??[????-xU???v???Dd:????x;?: ???o??G?/kZ1?i;2????BK???.v4z ?]2??m?}???Q??D????i??\????D~g?i#??z?O?,?(??3??_z??[M] {???dY7??i???????m?!?Z????!?r1?????,???8???????T??????X( u??m??`k?? ?????Q?ew"?}??0?)o??????Bcp?F?gR???M?B?Yzn[???mql??????*??$& K(~B??7??3???-??PQ??~?,???????W?3~&^?$U?????T. ??????T??>d?N??^?S???:d?(? I??? 5$ "M???u???VX???ZTX??XJ?yS!???S? ??P2\n???DG#????sL??2?Q?,???????????2???!??@b?b? ?>????*?1???,>?z??@??]E;h^4D2+F8}?A?o??j?v,?AX?-{??x????????E!?-????m?5?!???????Y?v&?? ]7?\??????5}???;???L?L?X]$?|1?5W.T??2~V?w?D??f???_??a?{?g?????2V\&????1N2]?0??.u?E??|%????cfdW??L1?G???!???p f??+q?C??;?G????G?`?@?? ??V8x`?????J?????t?.L{2??????<|G8Zp4\h????? \ =K?"???????CG?? X???Ja:??y0?%B? 1?vnS?e??D????l??# ?w?8uQ?K??0r?N|?zd+ at d?? ?Z???R?P?''?>?a:p0?????%c;L????????]?x??A??^??? ?K?;?rE7Y?4?={? GZ??z +W?? +F??D'?l?q?U?~?{????ba???w-I??{(4??[zZ?g?Q?%? ???5{???2?|S??F?N,??3?hrH u?wj???? ??f?*h????????????I?~?h?g?{?SB(@?27V+??mS? {???? ++0?_T?Y?3!3??`?z????????9?f-%!?Afe??n;?MH ??_????I4?O=????FY?$EI!?Q)> endobj +395 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [105.602 750.9806 118.6329 766.9208] +/Subtype /Link +/A << /S /GoTo /D (page.47) >> +>> endobj +394 0 obj << +/D [392 0 R /XYZ 74.4095 738.0292 null] +>> endobj +396 0 obj << +/D [392 0 R /XYZ 74.4095 720.0964 null] +>> endobj +397 0 obj << +/D [392 0 R /XYZ 74.4095 608.6072 null] +>> endobj +398 0 obj << +/D [392 0 R /XYZ 74.4095 228.1041 null] +>> endobj +70 0 obj << +/D [392 0 R /XYZ 74.4095 210.3931 null] +>> endobj +391 0 obj << +/Font << /F26 180 0 R /F31 192 0 R /F48 312 0 R >> +/XObject << /Im1 171 0 R >> +/ProcSet [ /PDF /Text /ImageC /ImageI ] +>> endobj +401 0 obj << +/Length 3117 +/Filter /FlateDecode +>> +stream +x??Z[??F~????>D?????[}h?;P M?MQ??:????k?I?_???,??&?E?????p???????Z?6?Q?R??????;?N;?y3?? ?O 3L?]?????* ????g??>???j??s>??d??L}??????????h{?WLA??~???3z&7????? h??:???/? ??E?w??:?A$?`_??n?@?m???(?J??,?u?=?c???V?/????]?4?w?? ?? ???$??* v=x}l??l6r<???? ?C?p%??AM?&?b?v{f?$?P??O~?????????%d?E??:g/??Y?*????u??Ki +Z?$?d??t??z~?$? ?:S???ZI@?,?yYy?v?uDh???? +?)?6??!d?0 +???KT=6?D??????&V??D?m?! iC???????W???*????D!??U?]R????#?????{.x?XL.U???e?WL? 9IIG +??)1D%??Z6???G?U-?e?L????e?F???jY???/&??5?-?>?f$:?'X \=a??:B???????$`???f?%*1g??A?? ?F? >{}??????????g???/???/??yw?T??D?f???Q?2??_??4?E??Z? ,T???hh?_? ??_?P??y??6?t??????pE.<.Ii(?Y?*G?v???L9!???N???GR????u??I:???2?L?dJ??r???P???K Hy|z??A????A?:?h??)e?????=opp?$&????~W??s?/??}?jT?E?Lb?CC]?X ???????*k??\_? ?B@"&?? ?mxk_6q?s?~??%????(??@?.?? ?k?x?E??^S????.?X???q??9??'1???)=K???Dl?y? +??Q??n?_??6???????kZ=???2???%~ ??m??$??4*?H?=S?Q? +???u??M0??K???? ?s??m? ????M?????????z?????????}??v??????m?[??o?>??/???Jx???????m???W?> +?*?B?#???x???? ?&???O?S%8?????t??l*?w?W??t?y6?#??!?<[?<\[`s???8Z?$?D/Z??_?????'Oendstream +endobj +400 0 obj << +/Type /Page +/Contents 401 0 R +/Resources 399 0 R +/MediaBox [0 0 595.2757 841.8898] +/Parent 406 0 R +/Annots [ 403 0 R 404 0 R ] +>> endobj +403 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [105.602 750.9806 118.6329 766.9208] +/Subtype /Link +/A << /S /GoTo /D (page.47) >> +>> endobj +404 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [226.4163 365.6548 297.1908 377.1516] +/Subtype /Link +/A << /S /GoTo /D (resume-points) >> +>> endobj +402 0 obj << +/D [400 0 R /XYZ 74.4095 738.0292 null] +>> endobj +347 0 obj << +/D [400 0 R /XYZ 74.4095 684.1563 null] +>> endobj +74 0 obj << +/D [400 0 R /XYZ 74.4095 666.5717 null] +>> endobj +405 0 obj << +/D [400 0 R /XYZ 74.4095 287.4744 null] +>> endobj +399 0 obj << +/Font << /F26 180 0 R /F31 192 0 R /F48 312 0 R /F34 291 0 R >> +/XObject << /Im1 171 0 R >> +/ProcSet [ /PDF /Text /ImageC /ImageI ] +>> endobj +409 0 obj << +/Length 2245 +/Filter /FlateDecode +>> +stream +x??YY??? ~??p6???9$E]???d6????I?igk?-?m????????H?d?I??)?@??Vk j?ad??0Rgz?Vr}{])???L?1??oW???x??M????u*E?&?4?D????????_ot*??e"???Mh????i??k-G??qmO?,]Y4???^?28??)??& +???h?Msty?\?r???w?Zg"??pB?7*?Io^KH???!??/??k)?(K?:?"?aD??[?{???( +?f,??0q?R/?a? ?*q'3???\_?z? ????????;?? : ?F???Sf?R^?h?P??LAk,?45h|?i-??S4?k???O+e2W?'?????????V????&??? +?-3?"81/??/r??H???|??h???"T?wX ??2?\?{u?9???K!??i??|6?(?Y&BC:+0???h^?jqWT?2?6??N[U?X? ??6??QC6*z??????GZ4?=????X??%?4 L?}$1I?aXDj ?_??oL??????P???ZU????W??SW?_?????cY???)J???C???1?_ ???I"?ZD?????C?~&A??S?D^????x?a9? O????+?k??q????n?KX?Ea?_???D$2?Y#gC???G6???n[???N???1?F????T??5M?w??G`??L?????U??G?1lUu;????W[?3-?x**?nWTE?w???????V4?????GHff?T6?3?=??nf&????n?w?i?8[?&ce r?fW[w?$$??????x??1?mw8?4d????yY7?s????J?,?|:?2?0TDj?????6???6? R???K?????r???G$???B??{>B?|?d???P;?`/??nY{??)u?x~L?? ?????y???9, ?a?b??0I???/????Km????:]??!?E=?eVT?-?5O?o?Q?{?oTZ?/?-)???????h/bp??/+:&?????,c}?b??????4??o.o?????e?}??? ???i???4jX?mY?&A7????H???M?.???"?l?p?????????????DQ?O?z??w6???L??Z??I?D e??u???????y}?`#??T??Mp???3?Y1??p?????/?????????:z?j?E??K0,??0 !??!??? ?;???? +??JGg?????????? ?P??P81Az?37?? ??P-?m?f?11?%?M? z?\8f? ?D??!????????nh?#?r:???cQ2??'???k? 2??C?%???????y?ulp"??{ +????fq?!??(>?q????!?N?A?'?;>_?????? +??>??? ?????n:b?#?0??G\??????? ?,?&W????????h??#?????6???.????????_C4?Hb?????8 ?? l??nx> endobj +411 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [105.602 750.9806 118.6329 766.9208] +/Subtype /Link +/A << /S /GoTo /D (page.47) >> +>> endobj +410 0 obj << +/D [408 0 R /XYZ 74.4095 738.0292 null] +>> endobj +412 0 obj << +/D [408 0 R /XYZ 74.4095 223.9665 null] +>> endobj +407 0 obj << +/Font << /F26 180 0 R /F31 192 0 R /F48 312 0 R /F34 291 0 R >> +/XObject << /Im1 171 0 R >> +/ProcSet [ /PDF /Text /ImageC /ImageI ] +>> endobj +415 0 obj << +/Length 3437 +/Filter /FlateDecode +>> +stream +x??]????}????Z????!??????]??? ?Z?=YrVR??_???D???=??????!o"?o2??H6???HjS??????????uH[?????w*??&?&U???M?:??hZ?Il?k????r?Uy?ea???V?,?G????{5~?v?Z6M???????{?e?7??6 ??;???&????????-]???n???0?iv???'???? 5\?????{?^?%|M\xL?????f?&???QT?0?s??o~?D?)???0??]l +?G???o~??~???2?MgyX?X?)?0N at b4?????8???S?'?7K?x?;c??$pP?4w???iz?4u?????/X:?F Ki??:??>N?/?m?c{????8x??????k_?;knT?+J?? +? +n??V??z/??????P;b?0????L???I?}? ?N(?????&?!??"I?B???p??????G2??l???x\I?P'Z?k??%?jh.+?h?0Q&? +?{?o?4??`?????E???pC?????iR?'???D?a??????t?????$?5?Z?????????*???xfA??: ~???Li??N?)i?/ yC????q??]?,?KF?x + ??4?W?X%?l??t?0???????r?????Aw?????]j?p?3l??0??c?-????L??I?Y?I&????????????????NM????5?".mV?C?+y?????6??:P???K?pL%?DrjS8U??d?so?)sy+I??????4V?$?q??sM= a")???gu-????????]?=?N ??VB???x>??Ry?]?U!K???Ct?Lq??8&?h?( +?? ????g???????(0?4?D?r????:???B_G?\?(?????nE??m7??@?_j?8o?],?/Qwk?BC?T1?8h?_sK????7 nO?Z?9x???M??I\\?????!S?????Q!??;??E???"?|q0?,G^?L=??E)?@c'??o?k????Vo?{\g???????H64{:?{ Q??8?? ????c?!?0?r ?u?K?cd86!???q:????Z??(????????????%?t ???????[?????`?,???3I??;??rR?? +k,?1??/#8?-???*?U?R>r???VY??O??CVI???"?0\B.^????? +?3?T???B&u??g?W??|[LCE ??]S?z????)??V5?`???????Z2&1??#2}?1\???V??W?????,???a`v5?d??d???U?QVc/? ?]#*????*?????V#?_ ?? #??????Ar(%*????Q b?V?d????k?&?ZdM(p`????y?h?????y?B?^???%R?6????c?B??????f?? ???5a??0??(P??????kBz???R?;??K?f?e??d)M?*R?lI??????#S?%????{;83??o?/W???]!E????:?O(0?4???Y?? ?8??? ?????? `?j???+?x?7??????IP???"i?m?-?cI\???s??? +??e???7K;?P ???? +b?ka)??_???.?????W^?*L!h??Yog?Jj?y??G?b?]?? ??t??=? F?[?sZ?{?u?)AgN?-??, ~xjY??NB????????M???j?d??????D?rf??:???&???????pf???^.???q????8?W???qi?[??|? +?ZmVT? Z?NG???F????b?-?h?`?9k7?????|,*?1I?????0?q??E??lS/??????Z??s?[?3? +?n??aG??????????X0[??\fl?????j? ?9`:?? +?L?????f5?p7kg??`(??g????s??O??? +?tm?J??Dr??c`??c-a\1?K?V8??c-??p?v?d /?5-d????J??z?IY>??Rl7X7bk&GA [??k?B?W??????????m_;?9b?,6b???Tz?vf?(??f ??)/J?|?!??)?Gt?`8???x???{F??{(v??W?|?|???????i??Si[9B???????~?K?????? G?\s?3??!vP^????? `m9??"???x?~lj!-????]?8???f?"hCBf?k:Z???T])&?;?I]*?????jV?w????s??vc#D?C?\??w???B"Q?H6?T.??F??????C`?yU???[?E?????fs??;"{e??&?K?I????C??g ^????;?/??y? +J)hM??c?uHJ?ep?p???`?sveO???_??????P??]y??*???,???kk??dHG.??? ?8??p7???\?????;"?;?Wh?K?{!????F???r?3=w9i?J??^vp???+,+?7?e'?w}??7R??2+v"?? 0 +m3?`-?[?w??;?W???????????)?6R????KS?8a?=TO.5J??8?J?????qo?& ??\??)F?????#5? ?6??Q????NJ?{E*??sI??Cc????6??E3e???Q??e'????J?M??????{6?????3oF??X?y??,4|?"??F???HglLL?t??W??Ew2?? ??|1??B!+?>On???`??u????&v?m??.?????D?>I???("?6???c?Z?? v7L?r???Gy'Q??????(z??x^???G O?)?o~????.:???EWC?bQ8s+????dZ??&]?@???N?o???6??8SX?M??C?u??q~a??{??n$&??!H??P?;&???h"????!r???Z????????Uendstream +endobj +414 0 obj << +/Type /Page +/Contents 415 0 R +/Resources 413 0 R +/MediaBox [0 0 595.2757 841.8898] +/Parent 406 0 R +/Annots [ 417 0 R ] +>> endobj +417 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [105.602 750.9806 118.6329 766.9208] +/Subtype /Link +/A << /S /GoTo /D (page.47) >> +>> endobj +416 0 obj << +/D [414 0 R /XYZ 74.4095 738.0292 null] +>> endobj +418 0 obj << +/D [414 0 R /XYZ 74.4095 636.5548 null] +>> endobj +78 0 obj << +/D [414 0 R /XYZ 74.4095 618.975 null] +>> endobj +413 0 obj << +/Font << /F26 180 0 R /F31 192 0 R /F34 291 0 R /F48 312 0 R /F14 259 0 R >> +/XObject << /Im1 171 0 R >> +/ProcSet [ /PDF /Text /ImageC /ImageI ] +>> endobj +421 0 obj << +/Length 2789 +/Filter /FlateDecode +>> +stream +x???????}?B@J+?\x5??????i?H?80(iV"L????Z???)??:- +???3g?m?mFz???^?Q?<^?6 ???bs?S????N ??GZ???{?{x4?BG???xz^d*?Y +D???6??{?~???0?Ur!???-6?*???Ab??T$??f?U??C?7US;?? /v??2 +\?Vg?H??uY???????????6 ??e?(???(?R??'03?A?p? N,8???K?Ix?:??f/T??'CV???g?q??((de_V[?@ +s?A??????#A?T???U?rJK?? !?Cv.[9?c!v?i?.?M'???c?x.B????y?p,?D ?E?????k=???dx. at u?A?A???l7{? +?j?? s??-??m:?_X*H??????? /_???????O???a. md????????>6?.?`+.j+??Q?? +??OA??YO?g???Ym?????????????r??14?VP??????.N?fs??<?b????85???&?M??????M???$H>b?"?k?L???0??????[rs??????&??^Y???sY?th?G6x,?k?+?C??> endobj +423 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [105.602 750.9806 118.6329 766.9208] +/Subtype /Link +/A << /S /GoTo /D (page.47) >> +>> endobj +422 0 obj << +/D [420 0 R /XYZ 74.4095 738.0292 null] +>> endobj +424 0 obj << +/D [420 0 R /XYZ 74.4095 584.6968 null] +>> endobj +371 0 obj << +/D [420 0 R /XYZ 74.4095 269.728 null] +>> endobj +82 0 obj << +/D [420 0 R /XYZ 74.4095 252.017 null] +>> endobj +419 0 obj << +/Font << /F26 180 0 R /F31 192 0 R /F14 259 0 R /F48 312 0 R /F34 291 0 R >> +/XObject << /Im1 171 0 R >> +/ProcSet [ /PDF /Text /ImageC /ImageI ] +>> endobj +427 0 obj << +/Length 1426 +/Filter /FlateDecode +>> +stream +x??Wmo?6??_!t"1K??(?? m???n??+ E?!??Jr?????z?l?0 R???s?s(???4????^?9q??N +g??XK???6c?_?W??{????????P?B??H??]???{?{Yo???o?"??z??r??:?????????*???>??[??~??[EE????6YY???????z???????9! }0????q +??z??Rn?C?????-F}"??s??D?\Z???J[??GQ??7c???r??N?3E|????Y?{?kZO???[??{?? +??{?`?}?g^?y???($'????D?@???Y?j???/+&B??h???o9s????+???W =????0 3??>S'?H|X??@:???B^??'B???????? stjX?B*=J???,?QH??p????<0M???S??d?O?1h;`?(?dzg??~{?????_*)???????PJ[.????Y?v?"H5?? b*??%???e???8????CS??c{ +e??? }c????????a ????????)??HghN??Gp%Z??hN:????EoBI|??wk?4??? +6?h??!k?R?gM?h?Q?4 mu????e?d???8?"?p?R??{?UI??k9??J?:??f???????'?C???{;?Nt??i|??r??5??I1?3a??]U?KE???J7???G?M?m????H??L?$??????????=7???;f@?o???j?L?\c???rTk??a@??????=C???}??C+ +?bn?s????B?&?eM+??A??????L?A???D???;q;Y?z`*???L?O?%|??qM????\#???Q?)??+n,^qx?? Y??Zt??+X??????D?[?eQgI?QkF???}+?h2??.?h?#???4?eq????S]h???\4?1?7?J??0!6?M?f>St??????8a=???p??C?89t??H????Mo)t ??l??4?W?^?]E?? ???c?\(???.??5?n?v}???W]wU??'?z{([???????????vhZ?n????nvQ?????K????r?m?O?I=?i????^8k?????Nm?f?????? gg??!QJ S??+y?+y?+9??u +>?????.^???n??1X?#??W??X???r eStl ?v????_C??d$???zx?_o?B??CW??Iu? +n?K?0r?-?? ???gP}~^???'?{??nh?4?@??Yk???[7???R!}o?????k?"?M????? [?>&5V-????????? ??????$w.PW???+%?g?~8X????i????????3???,???????m?'???%?o????w??fendstream +endobj +426 0 obj << +/Type /Page +/Contents 427 0 R +/Resources 425 0 R +/MediaBox [0 0 595.2757 841.8898] +/Parent 406 0 R +/Annots [ 429 0 R ] +>> endobj +429 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [105.602 750.9806 118.6329 766.9208] +/Subtype /Link +/A << /S /GoTo /D (page.47) >> +>> endobj +428 0 obj << +/D [426 0 R /XYZ 74.4095 738.0292 null] +>> endobj +425 0 obj << +/Font << /F26 180 0 R /F31 192 0 R /F48 312 0 R >> +/XObject << /Im1 171 0 R >> +/ProcSet [ /PDF /Text /ImageC /ImageI ] +>> endobj +432 0 obj << +/Length 2680 +/Filter /FlateDecode +>> +stream +x??Ym??6?????}?1?WIlqZ??K?????)Y?zu?%?????????%[?MP?)r83>??U ??Ej???-R? ??^??????oT?YG????????ot?PV?????"??d)0M?pJ???????wO?????'? +??jml??w?u????????8??u]?U????+#?????|?v??j^??;?E????????^??%?b???6MI???!M?????|;K?D8??E??p?q|v\:??FV??? d???|Q?^?W?HL?^????@???+n(?? zs?/??I3??2pJ/?????)[??/7?'???^?P????6??A?L}???3??*m?3??RdI?g?l??I?F%j??L?4K??w-X/?r???U???'?k???N:?p?\h@??x@%?s??c?? v_??????????|??*?????|2?k??L%~??Nx?3?c???m{??]?0???.;^tXrJ?????????OaO]?V?-?????]??E?vi?????? +?E?8?????i???m????????o?x?!? ?#x??rj??e$?0????oL??lm??U??O????s????K??/?ZX?? ??^;?`???iZ?1?/?-R????????o>|????????b?i5?)?]9????We?EB???=K?)??????ME?e?+?>R??#m?vXgRs0???$??/????e?j???0x????q?????2A ?6?}?~???|??B???}X'o??6??y?? 5e????Cm?????j?x???Q?X?? ?n? x???? ??3?`v?k??2??l?/???J$*?a#% ???(q_?|?=Y??????? ??$Vj ??Vkm?R?)??v{*??0c;wb%???3?m 7?T7E?j( ?F???c??Z??{?c83p??S?K????PX1&Yn?C????%??,?:?Z?%?y??????A H??\??X("T?y???p(?w??????+;c?Q?9??????m|??S???,B??t?D5{?*?X????y??1?? dT?T*??MQ???Ur???QFa??)???5l4???O?0?`?A9?#??????d?????????5 bV ? P` ?8???\>??I? Q.?g[Z???c?????^???u?+?U\??I????????_?t???? O??.?T??D(?^hxc??:M?? ??k??r V??r?4p??#?d????{??{ {????? ?? |?Q?r?? ??? ? ??*?Y=F??bE???>fd?)hB???|v&???dp??y?!1Y| 0???3sph?= +?\?\??????}??p???L???*?>?????k??BV? ??/K?b4?w??? ?s?]?-J?||?vg?C??h??????r?s_?? +??:a?R?????sh??H?,???????endstream +endobj +431 0 obj << +/Type /Page +/Contents 432 0 R +/Resources 430 0 R +/MediaBox [0 0 595.2757 841.8898] +/Parent 406 0 R +/Annots [ 434 0 R ] +>> endobj +434 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [105.602 750.9806 118.6329 766.9208] +/Subtype /Link +/A << /S /GoTo /D (page.47) >> +>> endobj +433 0 obj << +/D [431 0 R /XYZ 74.4095 738.0292 null] +>> endobj +430 0 obj << +/Font << /F26 180 0 R /F31 192 0 R /F48 312 0 R /F34 291 0 R >> +/XObject << /Im1 171 0 R >> +/ProcSet [ /PDF /Text /ImageC /ImageI ] +>> endobj +437 0 obj << +/Length 3303 +/Filter /FlateDecode +>> +stream +x??[Ys??~???[???x??oN??UI|lUl?DBl? p??????p?F%)?e?????????V?e+#??N????r?W?? ]=@??nX?I?6?Q~w??7\??$Bj?zw???k@?vD1m????=?|????????/o7B?????.>?r??C?w?????>???Mh}w+?????>???uSTe???>????????_|#??? ??? ?Ic??\?c??=?????v[?j???+?QZ??w?:=?1???????'x5 ???8?y?>3D mF??t????? i?????o???N?]?3xJ?~}??A???DjA?&?Z???~_Q"??????o?ta:???????????f?}?7a,q? ??#L??????BW;???7?'g?? ??0?;?H??T????????????S/?TqJ????*mm??RBX??w?9PP +?n??????.<9=? #?A\????????9??????-'TI?9??) :??uW?????X??)Ly??r?? c?u??,A'Y????Mj??(???D???/??? ?? ????LD???}?? ?????N?)????%?)?^?Us:? +???81?{?d??HH???4\h?DJoN:?qk?E?n????q ??&'???ZY?lC bX/???S???5Xy??\??@M??rm??6??????0?_?????@?? ?6FdHO?y??`?u??6???CRE7[l'B9?B???+??? ???^????!??W ?0i@????hl>?/c?\?`L?>???v???D?????? + ?t c?!N?P??????%??@C????? 6A??/?El????|?o??pV?O?P?Q.W|? ?=Cq?Qd???-??? ???b"J?`?1?@?a?? ?c*g2?N(????_??K~????* ?Va*?=?z?y???>?.r??????T???_lN?????a0v??vB?tt?!????????`??)"????1?}?????1$?*?2e??y?5?bm]??e???B?o_=[,????!???"l]f?0??r?????Q?????`~X????qd??V?&?????)x?%&QtL]?X??7?P???M?????\???\?????@? +??b???|???3X%???/Q??Mb! +?r ?G?g?8??vx????puZ71??{?!0?}?V??t?*H)?????7}l????U;D?C?t??????>???gQ#? ??????*C^??E#<|?D}???E????kq?r?b??DU? +_t???n??????Kmp[&@?????? ?????4~??p????\i?u0?d?r?f?E???A???B??Uj??+????b?s??? ??????:E?UI???]??M???=Yx??z?Q?Hh??G?_?????a??aq????"???^????????Xe???? ?????u|>>o?D K$x?T2?????#?v/u??ZO2X??!??????3?6?L?IA??K??^1??????6&???????9?J????'|?wJ???O?7+G?? >? ?? +??CQ?vS`?x?d????8?+? ??oN??,q?6U?V??? ?1?????y?>Q??????????????}?z????f?T?+??????#M???}Oi??? +??h?s6*9Q?M????????? rak?}??>m>?a??gck>}???i?.?u??M???^n 8???f??I[??s[???y?4yC?qwaK?!D???????\?9?????? ?;??nO?b????????K???????[?AZ7M??@?j?2??3R_?/??8?6???o_?R?????;@? w??]c??+G ????? _7-#??k?)???X?????-F?Y?-}{5x?i?.?c?B???i?.??c?> endobj +439 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [105.602 750.9806 118.6329 766.9208] +/Subtype /Link +/A << /S /GoTo /D (page.47) >> +>> endobj +440 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [132.3743 390.4952 235.5173 401.7727] +/Subtype /Link +/A << /S /GoTo /D (performance-impact) >> +>> endobj +438 0 obj << +/D [436 0 R /XYZ 74.4095 738.0292 null] +>> endobj +370 0 obj << +/D [436 0 R /XYZ 74.4095 464.9782 null] +>> endobj +86 0 obj << +/D [436 0 R /XYZ 74.4095 447.2672 null] +>> endobj +441 0 obj << +/D [436 0 R /XYZ 74.4095 303.5711 null] +>> endobj +435 0 obj << +/Font << /F26 180 0 R /F31 192 0 R /F48 312 0 R /F34 291 0 R >> +/XObject << /Im1 171 0 R >> +/ProcSet [ /PDF /Text /ImageC /ImageI ] +>> endobj +445 0 obj << +/Length 3154 +/Filter /FlateDecode +>> +stream +x??\]o?8}???? ?,???m??.:?]dv?X,:}P%1j????L??\??H????n`jE"/???9??K? ?d?8????baj?d?>??x??3R??7??q?wgo?P9!1.???z?1bZ?Qi? ?]}???????T??X!????q5?g??.??(??????.????\-??7??????}QmW?l.????????+??????o?021?H ?dN2\)?????FZ?7j?f??\4K#li??H?zx??e?YeK?.J??7?r"?@?4??f?(??YN??L3??!zd?????>?J'X???$???!%??a?e?, 2?, ?W E?d??$???$??0?2????D????????P?I??oj???$ ????a ???0?(E??z??}&?v?o,????0????^??3 ??????g at 0? ??????IX?@lCih???-????gn?1X?????m??TWo?R1???5??L???U???L/???q%V??3??P?8???]k??????6u???#3??@?i??????;?SD?]w2???'d"??m?D>?[?#ns?2???Vn??*?=?kX???C??8"c'3C???n???(%????F?29?]???C0##Kjw?a~???7?5????????a?????_^?{???)????????%?HY?,???th???Nh??)?A)H??????7D^?\?K?j????[Z??? ??sY?3C??n?x?/y??? +??d?:J??????#i5? +i? H?]??N?.??1?? ?b??&h? ?w?=?v?!??7x,?"?|??T/$\??+!\?qX? j`EU ?ef???*i'?J?j?/?3?*u?????endstream +endobj +444 0 obj << +/Type /Page +/Contents 445 0 R +/Resources 443 0 R +/MediaBox [0 0 595.2757 841.8898] +/Parent 442 0 R +/Annots [ 447 0 R ] +>> endobj +447 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [105.602 750.9806 118.6329 766.9208] +/Subtype /Link +/A << /S /GoTo /D (page.47) >> +>> endobj +446 0 obj << +/D [444 0 R /XYZ 74.4095 738.0292 null] +>> endobj +448 0 obj << +/D [444 0 R /XYZ 74.4095 660.2459 null] +>> endobj +449 0 obj << +/D [444 0 R /XYZ 74.4095 409.9845 null] +>> endobj +443 0 obj << +/Font << /F26 180 0 R /F31 192 0 R /F34 291 0 R >> +/XObject << /Im1 171 0 R >> +/ProcSet [ /PDF /Text /ImageC /ImageI ] +>> endobj +452 0 obj << +/Length 3305 +/Filter /FlateDecode +>> +stream +x?????6??_??P??4A?[n?c{( +@?Uj? ?OmR?0?7???0??M???????Q??[$????????(?(h?D???M:K?h??R????>?>m?( ???4P_l}mR??b???(?*^??q?X4M??C???w[z?E74??????;^x5??r??????[?6y?'p?D???r??t|???4??{??ys7?K?I?Y?I?8???q?? 8?9\??}w?aq?k?x?^??? ?Izq??g??;????????{?Y?M|M?=?Z? R?Ww4??3??i?<|??& H??;??_o??y? +-???Vm??o???|{~?N? ???W???Ab???_??8????7C8??l[?j??????LGf??-??{$????^?;T]E?_4??t?{?????c%e??~????#?4??~???=?Uk????n???zU?t:9??k??])???B?(?[??? +??ww?j?4s?)?s?????UG?8???#?i?w>\?D6??CW ???~/D?B???N?`???????|??B????b??? +???.%X,???O?????(T????]?j^^ype U?pP&???jj"H???????l|&?? }?l???MF$? ?Q???E2,0I@?????I?p???=5`T?X?????IG???NM]x#X??+DQl5?F??M??SS?h?x?(? C???O?R???(???????R`@?P7 '?;H}?;?:[/???v`X???????'?:??) c??X@????#?x?r???????Z?]??^?E.?zG.*??7??w??m???tJ??p?-8 ?i?x?yY`??RB?=?>?"??h?4?poK#?](B?^????x?{X?"?????]=????i ?F?Gs^QNQk?x:?p/D??(????f???{?T????? h?~????????=?????? L8???3??f??lP G?TN??pQ???N@????z??oq?ji?XwA???(???M{5?7h*?9?????0?n!?Bl???&??????zs#J ???3??9???????fB?DoI9?`w,S?=#????hO???n??&m'??[?B>??Zp?}9?,r??XM???&?a??^I???B???6???(?j*??????!??#?? ;:???v??p??D`TY~?CT??8???@???s?[????VEk????C?]j???Xt\??? ??GG??@??D?MT??v?Y????f=@oc?z4 `]d??@??b~?.??P??l?[????a??????Y??x!LX?&@??@5???g[]5????"????|???,?8r???-3???rz??!AB?Wc??`7??+?)?k??xk??Y?????]t???3?4H ???]O?u VT5 ?? +????? ?Mk?v?>???k??2?'?`~?q???????o?R(?????@?M????? ?;???^H?Ug!?L??~? +???Zi???7P???K?B????????T?O]?P? +?ld?Q?dL!?.'T,&{-Y?Q ??Rh?%?yE??^6%/???6?P2Hh?2?8?{??q}`??????|z?w?????? ~_???Y?d??va1??hQo? .sD???[d?'? |?????????9???'?/f?Q??6@?5?R???????u4?9LF?????=e?;?U?/?[???e?%?l???? |?zM???????{?{???????UI??N?0JQ2pI? ??|?tU,wX????????_\?l+-JT?Y??P??D?t?z??Z?d???I\? +?> endobj +454 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [105.602 750.9806 118.6329 766.9208] +/Subtype /Link +/A << /S /GoTo /D (page.47) >> +>> endobj +455 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [489.7334 629.0379 521.8625 640.5347] +/Subtype /Link +/A << /S /GoTo /D (performance-impact) >> +>> endobj +456 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [73.4132 617.3019 148.1323 628.5795] +/Subtype /Link +/A << /S /GoTo /D (performance-impact) >> +>> endobj +453 0 obj << +/D [451 0 R /XYZ 74.4095 738.0292 null] +>> endobj +457 0 obj << +/D [451 0 R /XYZ 74.4095 498.5273 null] +>> endobj +90 0 obj << +/D [451 0 R /XYZ 74.4095 480.8163 null] +>> endobj +450 0 obj << +/Font << /F26 180 0 R /F31 192 0 R /F34 291 0 R /F14 259 0 R >> +/XObject << /Im1 171 0 R >> +/ProcSet [ /PDF /Text /ImageC /ImageI ] +>> endobj +460 0 obj << +/Length 3859 +/Filter /FlateDecode +>> +stream +x?????6?>_??R?#?x??=?I????8?l???@I ?)?????/?=??????7?6??&?? ?p??t?7??M?9??7Jpvi7?zsw??[m???????~??Ib ?~????><}x??tx???^mw????Y?ou?? ????1+??,??-??mM?=fUSf?]??E]1?us?m????????I?4???"??N??qL????W?#???w??T?a??M?~????????|q????& X??u?x1????D?l??{?k?.??????????#|^??? ?'??D?t,?hC?$@5??$?8???&?-??%?q?_n?My? +\?w??j?C}?????ao&N?T+?L}?????? +6G??O7 Oin????*?;?X?6??JOy??f?9???5?Z??0 ??c?IC?????QJ????Iz?+;???u {????j??#_?0jLp??k9???a??t:o??|?M}???????O?s? ???K?H??? ???oWf?Q??W?n5k?g9??? ???c?+?B?NU2?b?????????P??? VS?B???8kJ2??4{?????>?????/?8(J???????e?JgP?8?k@???f?C???9Ur?????????t/????>?Z?+ }????8?k?YPjDR?V?8??? ??^F???^???4?5?2?=??? y.??4|??Bt?@6? H!k;1?FrO?a?? +y????C?.?n%'Q?$??6f????y??e??k???SX??6h?3?,_]???v?ER)3q9?V????J????,?FH/???E??-?8?E???? ?1 +?4??I)?e%2?pIy?67????T: +???:f? ??Y?3????"GRp5My???W??QxT?j{??+9? +v?6+??A\??qQ??2j?K?-g???3??4?????7?J??N???/]??*????????W ??"???Z?+?.? q??T?ua??Z36?: #?????!b) *.???iR????>?id/A?8 4.5.D4????v??F~j5? +???hQ????H??'????k??r? ??B ? +? +???/e ?i?^3??(??I??2??:???????@?V?]?L_k???;???]A???*?*?????ji4-???? ???1???f??+?k?S???1e\-?????(?09?D?f???O??Dx!?#r???\F??*?R??? ???`??X?? 8u#q$?????CJ????r.\??????l???2Ojo?fVdqi??;P2?xM??Z?8y????jiJ? ?|#XZ?M?3???uL~???D?&z4d????j}i????+??????\H +??4??*JI???Dcj?"??1E????????goe????? ?]nX?????IA?n=S?e?9?=v&??p:?)?>?z?z?z&/eZ'O???????:? ?+;?zIc?-|Ac_?t??/??k?x???;?+?B????D)??JV?H???a???#???s? E? ?5_?Ds?:?[?????Z?_????R?u8????k(??2???a|X?(???j??5?'?(??j?u???{1"?b?)?????????}?a????????=?bdm,??P$????`??V??;???g ?=Z ??u ??&??N9"6~?&?d?c.?l?????X?B?????S[m?( ??????? 0l?C???)N$~W;H??#x{CmjpC;)??(???(???n?&??cW?^? ,A?~?l??Oh i?????\P@??????D???.??t ??}E??\MIE +;>Aq??sY??_'6?$????Z?a??????&??c?????N?I?&??7w????3Jrk??_??CV?[;??? ?*????????j???endstream +endobj +459 0 obj << +/Type /Page +/Contents 460 0 R +/Resources 458 0 R +/MediaBox [0 0 595.2757 841.8898] +/Parent 442 0 R +/Annots [ 462 0 R 463 0 R 464 0 R 465 0 R 466 0 R 467 0 R 468 0 R 469 0 R 473 0 R ] +>> endobj +462 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [105.602 750.9806 118.6329 766.9208] +/Subtype /Link +/A << /S /GoTo /D (page.47) >> +>> endobj +463 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 0] +/Rect [314.7955 694.519 341.3756 704.0531] +/Subtype /Link +/A << /S /GoTo /D (cite.SEDA) >> +>> endobj +464 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 0] +/Rect [361.4198 694.519 397.9225 704.0531] +/Subtype /Link +/A << /S /GoTo /D (cite.Twisted) >> +>> endobj +465 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 0] +/Rect [364.6959 534.2776 397.0742 543.8117] +/Subtype /Link +/A << /S /GoTo /D (cite.LIMBO) >> +>> endobj +466 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 0] +/Rect [139.7638 481.9055 221.9351 491.4397] +/Subtype /Link +/A << /S /GoTo /D (cite.von-Behren-et-al) >> +>> endobj +467 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 0] +/Rect [379.8296 469.9504 419.2216 479.4845] +/Subtype /Link +/A << /S /GoTo /D (cite.Seaside) >> +>> endobj +468 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 0] +/Rect [429.7417 469.9504 496.919 479.4845] +/Subtype /Link +/A << /S /GoTo /D (cite.PLTWebserver) >> +>> endobj +469 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 0] +/Rect [76.91 353.2511 112.0578 362.7852] +/Subtype /Link +/A << /S /GoTo /D (cite.AB-OC) >> +>> endobj +473 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 0] +/Rect [369.2884 87.3642 393.856 96.8984] +/Subtype /Link +/A << /S /GoTo /D (cite.R5RS) >> +>> endobj +461 0 obj << +/D [459 0 R /XYZ 74.4095 738.0292 null] +>> endobj +470 0 obj << +/D [459 0 R /XYZ 74.4095 279.787 null] +>> endobj +471 0 obj << +/D [459 0 R /XYZ 74.4095 217.2331 null] +>> endobj +472 0 obj << +/D [459 0 R /XYZ 74.4095 158.6831 null] +>> endobj +302 0 obj << +/D [459 0 R /XYZ 74.4095 158.6831 null] +>> endobj +94 0 obj << +/D [459 0 R /XYZ 74.4095 141.7522 null] +>> endobj +458 0 obj << +/Font << /F26 180 0 R /F31 192 0 R /F14 259 0 R /F34 291 0 R >> +/XObject << /Im1 171 0 R >> +/ProcSet [ /PDF /Text /ImageC /ImageI ] +>> endobj +484 0 obj << +/Length 3991 +/Filter /FlateDecode +>> +stream +x??ZYo?F~????????O????'?v`PJ??CND??????n??-M @?????:??? ?Om?8??"?dQ?????xn???+%4;C?s?~?????N7*?8????MQ???i$JA??????????????a??wQ?m????|???????X.????f8~????Q?},??-?w?vl??;~Nu5????????A??b`?f????????d???G?????m?0 ?"??,I?$??;v=>???)X??;???l?yqq???? ??l?q?????l??;??k:??G?????on??O?B??p??8??( +s?5 ?i!2K??c???I???k3?4j?n?a?M??u????*[n;?|?fRrE?T?????A??GYD?%????H??????????"T??|??K??W9 ?????rV?????7k?TH?`?? !??t52??,??C?G?TSKeh? ??? ????????q???z7|h??????4?$?X?x???????POm}??????^???tSi?\v???y???n?1??4????L?? t?_?@C????x??^?I?????Ct??j.???#*??9??&R????7???? ?P[??5?:4]?L???? b?$?????a?/??z^??w????=?b?/_????x5]????Jc?^0 ?fy?W? +|^???BrP?u???c??????f*:m$???4 ??2k???>?r?????j?7 &?8??!Z3]? ??s? ????????????}???4? +]?^????r W?t 0?R????C ??me??+??A?j`?R3???Ic??0D??QUz5#?(??G???#R???%??z???#??l+?sd?????G?&+??1?????'????ZY^=T????>?z??????V?Z =?? `?B?B?w=:?h????"??(,??z?R=????^???????W/???^???{?u??P???lK??F??B!?~3?a?I?{nx??r?'?T??????G???16?n???j?LF????????AR???*?\??b +??w?Hqh??'v@??#7u5?5f??-bcmM?#?>??c?????A??? ?XVx??1?????Y(??3???$B?n??M$?1^?x #???i!??AJ??f????????j?[D??#?R?f?e0?$u@?<???????U???1???M?eC???e"?h3 ?????vK??Y W??em?.qd????????uQR?A^??,)?8???A v?Q u?????<7a [?gc?????QF?G??$ +??kq?? ??? +?) j????|<2?< :?i?????J?1pO?X1??"F?4?#???????/><Lc?0 W +??K?f??????p???C?FQH5 b?YZ?[12??Z?7D?\[???xl(?2??S?5????6w??9?FcH???V?U?m??X???iB??`^+XJ???$K??'? ?G?N?}??a +0,? ???z??Y?K~?E?????z??SC??\?vN?@?=??@?Z??????o2?x(??? ?:(?5? ???F???`??2hK? ?$?????V????=@[Q?I>*? +J s??? ??R3?????L?y?M?B??(?*?(|[???i?C?2U?d?Y?1 ??_\3???A??????}i? ???z?????>????D???s?^?CuQ^b:????_\???$??qX0z?B???(0?Il???????s ,?I??:(?(??"???n??-??'?tl????, +??(d8?????v!????-P?4?}???Pi??h?:????u?2 N???Mr?r???~????,?r??,4.??Bc?. ??L????z????,4???,???^j]??Z?(??c??Q?????%F??P4?L!&{%????N?0?wzj/?CA??TFQ?G????x???}(>dXXd\?I???S??U??B??_??O??????"?HA?????x?CSq??y????Pc?0???\?h.(???F?X?????&??t{????$@ +y?2 O??r?;7??#??=4?q??=?]???F?9????N? 2?:G?Zn?ox?`0?n?-J?\?? (t?3|?s#4T??G?%???????\?i^Tr??R?bC??s??`Q??O??s??#a7? ???????l4?p?F??YQ???N???9$???1%???j? d?..=???;?????u???jq$?????i.?\?d?P`??????hCb?B?%`j????????,#m??cB?\?5?*??????`=t?* +?_I?l@??????c?u? ??#2?>EW??I??>U??????%$?g??????>Z??Lg?????i/?(JM? +J???BE,5?P?????? ?Y>'?%WaU????f??SH?Fm'?C?????4?????;? ?????*???R??C-???? ?G.???1%:?pW?PL?2;?5?o+(e?????hw???D?w??DaF!Oh?ClAJ_?8???C???@b?????$?A??MlRI@?VU?E W>!?????3 at L0?Q?"?|??j???y??OJ?%???}????? le[?9?#?+|?K??zn?hbF +?~?8???????B????l?]Y4;"???8;Of???Hk????^??z?YX??9?? + ??L4U???1;CD?V?9?V?]??N=?????Df$ ???????????[????yk?H?? +Kd????&?????f?f +?o?i?M?2!`?6v?,G??~2??"l???E??? K&???so\Ag~*pZ&???_??N????{0?+h???j??b+??????|?-???i?P??Xw?.???{J?Tv?Z~?nn?[dW|\?$,?#F"???$???#?;K???F??v61??????Y?.u?O???1???????V??W????.?y-f????|?8`???? ?K??9???0????-??N??l?g?W??#?A?????s> endobj +486 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [105.602 750.9806 118.6329 766.9208] +/Subtype /Link +/A << /S /GoTo /D (page.47) >> +>> endobj +487 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 0] +/Rect [76.91 697.0778 102.9022 706.612] +/Subtype /Link +/A << /S /GoTo /D (cite.CGSI) >> +>> endobj +488 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 0] +/Rect [76.91 685.1227 100.3917 694.6568] +/Subtype /Link +/A << /S /GoTo /D (cite.MAS) >> +>> endobj +489 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 0] +/Rect [104.496 673.1675 138.2489 682.7016] +/Subtype /Link +/A << /S /GoTo /D (cite.PICOIL) >> +>> endobj +490 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 0] +/Rect [417.0789 673.272 453.4221 682.7016] +/Subtype /Link +/A << /S /GoTo /D (cite.PMTPM) >> +>> endobj +491 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 0] +/Rect [132.0819 290.6021 149.5363 300.1362] +/Subtype /Link +/A << /S /GoTo /D (cite.SLP) >> +>> endobj +492 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 0] +/Rect [365.166 117.2522 397.5443 126.7863] +/Subtype /Link +/A << /S /GoTo /D (cite.LIMBO) >> +>> endobj +485 0 obj << +/D [483 0 R /XYZ 74.4095 738.0292 null] +>> endobj +482 0 obj << +/Font << /F26 180 0 R /F31 192 0 R /F14 259 0 R /F48 312 0 R >> +/XObject << /Im1 171 0 R >> +/ProcSet [ /PDF /Text /ImageC /ImageI ] +>> endobj +498 0 obj << +/Length 1571 +/Filter /FlateDecode +>> +stream +x??XK??8 ??W??P?zX~???????m?=?=8?&1???X?l?????$???,?I?)fD??ODy?R^?(W???Q??x?????2IJ.????^??Y$R??LF????L9(?J????K|w?;?Y?? ???}??4??T???XKb???z??????? ?f?x?T?c[??f???j|4???6?|?DT?2g? %B?2?sg^q8???p????6????. ?Z3?)MwG????|???$?\pa?r?V/???7?E?2??3???OR??z? ?????u??>???? +?)?O????????j???h?X^)??G?????I]???}%??? ?/?w"z3?>???????`? +nY2?!c???oUV???=?t?M?????*????'L?+?J??zG[???5?H at A{?? ???N???T??T?*???????,???Z?ax?+?X?W???F?? ??]v?Dl?m??T?E??u?????d???R??Z?? ?H"?a?+?!??u????W ?84{?)?9?G?%\~?];?P??w[c?`?? ?????.?g??,?4?c??G?6?? ??6?m?@Kn0?o1???J'\?G[??XdR ??#.????H?8??LI?? ???U??Du??t$^6w?J +?n????:m?{????T3?Y?;?32?w?V?????ksu??W?dUyQ at 4?u?????d??d*O|??C?PIO???|?"?qP??? ?#??w%????????a V?????I??iMR???~?k?X?T???>xr?T?Ilr`?????yM? ????MB???i??C??p ??E ?x?????y?? ?????jv??????|??0F????h?B??3 +???'?x??K?h??? +4L?P?,W%???pq]^> endobj +500 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [105.602 750.9806 118.6329 766.9208] +/Subtype /Link +/A << /S /GoTo /D (page.47) >> +>> endobj +501 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [450.222 587.5187 521.8625 599.0154] +/Subtype /Link +/A << /S /GoTo /D (composability) >> +>> endobj +502 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 0] +/Rect [454.4339 547.7427 490.7772 557.1724] +/Subtype /Link +/A << /S /GoTo /D (cite.PMTPM) >> +>> endobj +499 0 obj << +/D [497 0 R /XYZ 74.4095 738.0292 null] +>> endobj +496 0 obj << +/Font << /F26 180 0 R /F31 192 0 R >> +/XObject << /Im1 171 0 R >> +/ProcSet [ /PDF /Text /ImageC /ImageI ] +>> endobj +505 0 obj << +/Length 3467 +/Filter /FlateDecode +>> +stream +x??]??6?}??NbU)Q??^r?k?"i????????????XR6?_?E}?n?XH????|??&??pc???}?1*??hm??]?9?_w????nL?????~??M?}??hs??I_?&M?~?;~?><}x???4??????)m??m?_?Q???????f?2/??????[x7[5???b?-???7? +?r??1????{?9?$~?}????????x?;?_??Q??w???9GX?&?8 +?4I?W??7?`?&e??[?? ??_??R???e??i?#???_?A???=???j??V? ??y_?Y? D??gDV??m{ ?/u?2??\k>??V-cO?-A??????Lli??????????? :??"%?n?_b?????Mo??${ ?}?;??????????1(??O???t.Ng?^?$%#???w? ????'??QD???KU?j"??2?h??g?h???mc??O?'?B?B?X???????e?Nc?&??`6 ??4?kHFkex??V2?X?:??v?????-zWK??]????g?J?a'}z\S???>?O???4???H?1???*e????G???>u?&??A?P>?2????}????E*5????c?????4%???x???}?(? ?]2)nF D%??UJ +????????}5?`?'?P????qWC???`???I???=LJ^?L???F?n??????cG???kr[?J4???>0?r???l#@i??Z?? ?g?M2,o3&??0?eD#?$3?&?\??u: @NP????L?C\???Lh??f&?"c?e|?C??\:???^?????//&?B?1??{B1?????,????6M??????L?k???.#v??????L?u??*?OM??W???p??&??????r??s^^_T??s?ep???Cd??-vM????-??`]?????|FQ?VZ5?2?apv?JM????C0f?%X?-????e.?y? ??$y+?????C??o?a5x?3*????E??f4???h?+]???d??!|^k????6?[/x??@????? ?Y????????????eLX[?v? ?{=t???JW7L? +n"?d7A?Z?????V???y?????v?@j?8?????zm??l}??)9H??J?8??=r??b?@ Qp??? 2F????Q??2???yt? ?|=Z??B?\?v?&??C?N?&a]?R???kG??7x??&=2??9?Wq?????I?K.???I??#?->???G?=v?s??3??G??????E??u]B?[?'T?-xx??f\???????]B?Q?xC{??r6????G??_>h??y???7?Y~???5z?? =vi8H?')c????(??P??Nl?tw?(w?xE???j???r????tZ? ????N?Zj?]*V?B?|(?5&??7??.r[?b???%???Z??h ?O????#?????\!?J?~???.?DK????e???p2?????7?????5o=?p??p?^^?W?G????{q ??R?J??J?Fw?8?#?H??{ag?$?9A?C???z??k???Eg4 #?wa:??h??b??????endstream +endobj +504 0 obj << +/Type /Page +/Contents 505 0 R +/Resources 503 0 R +/MediaBox [0 0 595.2757 841.8898] +/Parent 515 0 R +/Annots [ 507 0 R 508 0 R 509 0 R 510 0 R 512 0 R 513 0 R ] +>> endobj +507 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [105.602 750.9806 118.6329 766.9208] +/Subtype /Link +/A << /S /GoTo /D (page.47) >> +>> endobj +508 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 0] +/Rect [318.743 569.9146 347.4649 579.4488] +/Subtype /Link +/A << /S /GoTo /D (cite.D05.3) >> +>> endobj +509 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 0] +/Rect [378.4463 569.9146 407.1681 579.4488] +/Subtype /Link +/A << /S /GoTo /D (cite.D05.4) >> +>> endobj +510 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 0] +/Rect [143.5685 516.2209 171.623 525.6505] +/Subtype /Link +/A << /S /GoTo /D (cite.DHRY) >> +>> endobj +512 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 0] +/Rect [403.9487 440.4179 432.6706 449.952] +/Subtype /Link +/A << /S /GoTo /D (cite.D05.1) >> +>> endobj +513 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 0] +/Rect [162.3058 213.2697 188.5471 222.8038] +/Subtype /Link +/A << /S /GoTo /D (cite.VMC) >> +>> endobj +506 0 obj << +/D [504 0 R /XYZ 74.4095 738.0292 null] +>> endobj +264 0 obj << +/D [504 0 R /XYZ 74.4095 720.0964 null] +>> endobj +98 0 obj << +/D [504 0 R /XYZ 74.4095 720.0964 null] +>> endobj +511 0 obj << +/D [504 0 R /XYZ 74.4095 503.414 null] +>> endobj +102 0 obj << +/D [504 0 R /XYZ 74.4095 485.703 null] +>> endobj +514 0 obj << +/D [504 0 R /XYZ 74.4095 130.5798 null] +>> endobj +503 0 obj << +/Font << /F26 180 0 R /F31 192 0 R >> +/XObject << /Im1 171 0 R >> +/ProcSet [ /PDF /Text /ImageC /ImageI ] +>> endobj +521 0 obj << +/Length 3878 +/Filter /FlateDecode +>> +stream +x??M??6?>?"?0qm???????[?E??C??ck?s???????_~I?=~]?`??(?")?J?K?????m?I????J?c](?{??????H??? $?o?"y?f??? U???W??X?o?7?p?G??;??zIt???'?+?eGA??? ??V?R??qy?y?6*??????f0JS?D??$>E????H?m???RG>?8??=(C?D??C3??????n8o?dV?i??4??e?hY???#????4?.??#j>????-????????f?????=S8??AY7???v??_x?lEG38nHC???!?cu?d^?Ep?dpi\i???????\?m\%Y?]o?????`?k?tY?1?gZDO??? #6????6u???z?(??? ???()?K???D1??~??_H?$??A????b + I?`?????kX????R}??*|I??pD[ ????NS??_??6??"??MNGn?l??#??8u,I?????Q??$u?}????l:?%]?/$???=?EG/d? ?,~Kt2??;?W???~l?O?r??????u????Od??|2=?h?_^??/2???u?5??^?Vd:C4@???`a8?@? _?? ?R,?$???y?!?u?f???^????Hx????@??s?? ???^???w>???????_?7?2??r'????N? #^???'Z???? +??R??->??9?????????06?&?\?* +?????G?$???I???w??,?=??N.k?????n?p??????v?C?D??R?{G???,9P?s7?=??@??n1???C7uZ???^??]?5???*?tx![|y?h7??*??XZ,??6\H?4>f?J??1b+??EUD???????M??\& +??TU?????.??|a????p?t`??c?Mb8??Z???? ?pd4'???i?F??;GU ???t y?-???}qb?u?W??2???7?Q????????2 ?'??Nccq?ByqZ8?R?iH?fD ?? N-???t??T?? ??_oVpYB??}???<#'???;??u??Gp?c? }qEl4? ?6??9?x?Z??N??Xe? ?ep-?hG?"???Nk??|v??&?????:??R?+??$y?s?????-??E?? ????-? +&;?GKL??.???W???????????Xu??[?(]'Kf??>?"C?L???!????2?L?' ?????`t?????$ ?yWO?%???{':????u 1b?g????sX]q?]u???z"fp ?"??? ??t9???4E? ??????????~dk-?.]?j?3e??D?.?G???D?????a???????Yb?)h#?>8??byA?O???: l??05? 8H???e?(e6U-?"D???????e??l+Hx??1?$?"O?9??????.D??Z???O?SU????0??s?sb??8?VB??8? +??$????tQH?q??8'ts?+?1u??N0??k??)?JA? \?!? +\??W????t????-h?N?=?????KV???|??y??s`???L4+?Ar?i??vd??>J??.4'_Z?????1?y??? ??W?3;,?????E?:??J???X???Kl.>Y?lg?? +?????? -??s9Y??????yb??????????m]_ N????8??\*N+?????{N???a?M???`?????9 %??)???P ? ? :?2??;???B?VO?9S??m?@?,>??}?s>??N??????>E?0??\???l?0.?NXW??%?:9?S??"=J}??#?????ts????B?r??h?+??$?%.K +Z?[HK0?A? ??2???n??@????*???2?i????#?ja??N???????Bz??6??\???$|'??{q?a???ch???h???? ?L????S8k-??x? z ??9?? ??[?F??)(?? +Cb??e??W.??9v??{?c&???=8??I$???H$?9?]??+????????8?????T?E???i?{??|???????_??{+???????u?L9??L? +??+S??xg?,`(?K8M????c?s??:>????,f at d???e??Fq=D2?, ??U?so???{lN???/y?;K????zX???? -%??? E????L>?%_??~???t????~@^9,?7C?n?\?u???y???o)8y??,???H ?_P??U_???w??IPf#????????J????w???M?[i????????H???/ ???kd??c+=&p?p???U?\i?tH??H??M.?????? +g?cB?@Q??=?fh0?Yqt?0????? *9Q?? ??\?Zl)gB??-?M"?r?D??a??a???C!*]?+?S???JA?}p=/O?9HJ(V at c???(W?9856?Iy|???%%?[?ZT?2w???Y??I????X? +??O7?~???F??`9?96??D?G?%+??z?C/C?Iy??> endobj +523 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [105.602 750.9806 118.6329 766.9208] +/Subtype /Link +/A << /S /GoTo /D (page.47) >> +>> endobj +522 0 obj << +/D [520 0 R /XYZ 74.4095 738.0292 null] +>> endobj +106 0 obj << +/D [520 0 R /XYZ 74.4095 720.0964 null] +>> endobj +519 0 obj << +/Font << /F26 180 0 R /F31 192 0 R /F48 312 0 R >> +/XObject << /Im1 171 0 R >> +/ProcSet [ /PDF /Text /ImageC /ImageI ] +>> endobj +526 0 obj << +/Length 2576 +/Filter /FlateDecode +>> +stream +x??]??6?}?e????>{?C??)p@??[?Y?m]e???n?????e???Kj8?!?{h???gVi?"????fJ?y?*?z??????<:?G??Oo????D?FI?z??2?l??$W?1??|x???~ 3??Se?_??( ?[?}??:?A??p^???????~???????h??X???Pw-/??OU9????~y???U?????GcU?)??6?i?????O???NT?g?*?c'6????y/8=)???????t?Qz???*?Iz??J?#????PC???????7g?????1?? ??? ?Z??1???Vg at 5Qi?E?|?y?UZ?????????h|??hV?u?>?~??f?L???p?\?4F??C?? ?_???,^=?Z?????Q??(?? +?y??a?????%???VY?? ?<??XY??D???X?u??p?xR????`???Hf?4 ?Tmy`????>?arE?????T7?Y?}?????????OZ?????Iw??Su??A????c??Q??*F?q??z??????????wS?mS??_????f?gc?D?=/RF?kp?????+?u?V???/?W4?.&?h%H?????@????y,x??M ????e??-6E????E+?K_ ?c??v??8p?5?)$?hG??????l??rj???@?%?7y:????h+???1?: ,l*TMI|? +>??e??gu*?C????W?2?e??W4r?IJD #??m7?%syG?6Q})???? M????K#6L?Q?p?g?? ??:9_??D%&J??H??#??????l???{$??8?^?+k31????\ ?q-C?#d?=?]?[?g???????\VJ?;?2??a?rr?=??D?DA_?p_x^?o ?'6OB=3??????0?3d? +t???C??  ?x?p?L%:????? Ulu*("?G?E ?&v? ??o???1D? +JF?????????8u??A??y??c?"-??n??;T?? Yk??,?c??},??|?=90E:?La?[-?O#?;:?[?h~xu?e6??(q?C???4 2?[?F>??S?OUnC6???????(??y???z? ?~]? ?/???t?^p?F`?VH}?qB? !?????!h??.A +;???K[?XM??a8???????~?D*8u???`???6p??"????He&?h(?????*[????b??=:?b??|??????I????n`l/\?z_ n??!? +???? I??CG`?"?W@?"TX?yJ(??????<x?????s?Gh???u???%9?r at 3%?\??\b"t????,??g?#??&?q??wq?? ?????_?8?[9?{g??apO?Q??? /??}?7??? ?j????=??+?????x6?????P/???q?$??H?%?I?-c? ????uK ??,????P) ?Mn???bp?)I?j!?N@?B9~??????qw?+???k??>I2??N???{?#??aP3Q?v??fu?YEs?? ?????6>f?_K8????6????Wr},?^L?wz???????????????^e:?L7Lg%?k?fL?V????Q???+l?T?rb??J??W)?? ????=l??+?uO?& ??&z]?>?}??X_???LG??0]???)?>s?!{M????????a?????????x?y?G??????j!?Xo[A=??,?? ???????????\???t?s?[/?o2I^?$?Z?N??0??5I????????????????o?? m?ruTm???;{?????_-?#??D:q?6?X<q?? ???`:??&??c???@q/?D?J??_i?_????(>?'endstream +endobj +525 0 obj << +/Type /Page +/Contents 526 0 R +/Resources 524 0 R +/MediaBox [0 0 595.2757 841.8898] +/Parent 515 0 R +/Annots [ 528 0 R ] +>> endobj +528 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [105.602 750.9806 118.6329 766.9208] +/Subtype /Link +/A << /S /GoTo /D (page.47) >> +>> endobj +527 0 obj << +/D [525 0 R /XYZ 74.4095 738.0292 null] +>> endobj +529 0 obj << +/D [525 0 R /XYZ 74.4095 696.1114 null] +>> endobj +110 0 obj << +/D [525 0 R /XYZ 74.4095 678.4004 null] +>> endobj +524 0 obj << +/Font << /F26 180 0 R /F31 192 0 R /F48 312 0 R /F14 259 0 R >> +/XObject << /Im1 171 0 R >> +/ProcSet [ /PDF /Text /ImageC /ImageI ] +>> endobj +532 0 obj << +/Length 3625 +/Filter /FlateDecode +>> +stream +x???n?F??_??Ah`??^?'??? 6????MQ???T????-Z???0??F????? ~???V_w7???~?h3i?Z?2U 7F??=Zm????^3t ????D?e???C??/?L ???????v ??????">??7T??L?a?$ p9 at z?-_v???'???? ??C??t$?:?????E6(???A?2??a??}1??? ?~#??>?}:??????? ?[:? ???t?i&/?;KE5t??ME?W???gN5?%?#F?+?!?=??vA??@??|?p?D?|4>?8?lWTp??W?%W&?????-pDGo?????????[??6??t +?K?@8UmNG?H??jy???3?C?_?X??Q?????[ ?s&ft&&?z`??l\6??????a???P????' ???????[??%??0??????????`K??#?x?b?2 +?2~??Hq:N +??o???.?????L.??? 4????C?(u?^???tb????d??J`?e~?????I#?'k??$b????X-E????pld???4?L???LY*y#NS)~)`?_? .3??}??/?}??W???>?/?m?C????,}u@???? Q??? +,???????#?k???????~x?@}??i? +? ?????t?? VI???_oA I5T??V??h?j????! ??D?g?8???0?i?]??MUl?E?D?A???hm???C?.? q?:(O???-9>5??f.(j?C????I$2??6?????DN +???-??o@?>?(?sl +??#5??y?????t?|XtZE ????F^" m????Q?A?p?????K?r ??k9+?p?mv?? +??v8_?yo?????3????H?1??B.??}???XJ??W?5%???j?? ?p??????/?['QhbmW&?Bk???????KE?? y??????????T??I|v?3 ?^A}?i93`?.?w.t$??&x?gnq$?5?????|???C??N??=??]G???$t?k?c>t?IU??/UbcW????^ WLp??*BW?7??(? !WE?????^??PdM?BY????L?d{z???r?n{???3/f:?z8??,+?? ?fg?*? r?M?%?Q !:6\v>??a?xyn???Q J??;????:? +!77??W"?P?OB?????.?????B?C:????????c@???:G,$??d??xP/????????zL9?{?+>?W???U?c??E??TVG??.?K?P?W&~yP/????????z?:?{?_>????tn9 ??>cq?Wx`&X?g?q?? ?aI?ik???Q ?r?????????Q? ?k?16??|?P +a??H-???m.???{Q????J?@IpR??z +??????MK?` ??r?@{A?7??? ?.4??n\L?/7^?Fo?5?z)b????([???????C?9H#H?U#'???u??K???(tGM?6???N?????U??b????Ei??? +?(??t)???/?A?B6?}wj6??????N?AKe?1?8?2;YS?????QN~????t>K??JT? ?C?{?<_?p?????-????8,?,???Ga???L:CK3?z?> endobj +534 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [105.602 750.9806 118.6329 766.9208] +/Subtype /Link +/A << /S /GoTo /D (page.47) >> +>> endobj +536 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 0] +/Rect [377.8176 449.8667 440.4023 459.4008] +/Subtype /Link +/A << /S /GoTo /D (cite.BLANCHET99) >> +>> endobj +537 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 0] +/Rect [450.9224 449.8667 489.7662 459.4008] +/Subtype /Link +/A << /S /GoTo /D (cite.CHOI99) >> +>> endobj +538 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 0] +/Rect [259.3562 397.3489 302.7928 406.883] +/Subtype /Link +/A << /S /GoTo /D (cite.FRANZ02) >> +>> endobj +533 0 obj << +/D [531 0 R /XYZ 74.4095 738.0292 null] +>> endobj +535 0 obj << +/D [531 0 R /XYZ 74.4095 567.3848 null] +>> endobj +114 0 obj << +/D [531 0 R /XYZ 74.4095 550.3742 null] +>> endobj +539 0 obj << +/D [531 0 R /XYZ 74.4095 88.3605 null] +>> endobj +530 0 obj << +/Font << /F26 180 0 R /F31 192 0 R /F14 259 0 R >> +/XObject << /Im1 171 0 R >> +/ProcSet [ /PDF /Text /ImageC /ImageI ] +>> endobj +545 0 obj << +/Length 3923 +/Filter /FlateDecode +>> +stream +x???????>_?K?T??& ???8?ZW?Y?S???%b$f)R;$w=??? Hql????h4? ??~?.????t??"??2????? s?~??`?>???|?d?X?Jg???iWD?*r@??a?0V??y???$E|?a???A??????]=Wmk?f???????????jH???;??z???8?{????*??a?1 at D?;?*,u???*?y?O???Gw?8???,?]??a?????S?g???????? ? ??":?????Le?j?????z? w}??K?>>C/ +? +?u??\RPEw4?T?JE`???(4n????B ?? ?o????X??5, ?T?????ti:3??]W????!??????!&?????8????n??.???e?)??}??I?&??3W???U???yqh=?&0Mw???u?xr?`??/??68??????I ???4y?N???u?? O*?2?????L ?bq?l?????? ?S?{???"&w$(f%??KV???????????Y?U#??u}w? +??#???Kq??$QN???y?^ ?Q????h?4?f5?(???RE???(??8??G??b?????? ?I??"??????+T.????\Q\2??????r?~?2???5r?`h?c??}}?.??#c!]???&?'??iX??R}~?-0?k???/?]0????{ uzC% + ?B???l??????Gk????????-??Y?Z<:r`|KlJ? ??h??????P??Py?5OU??????fv??X?????xj/x??-&????????/?"??j???f????X ?????d ???8u?????0?AD???9????????}??A??NV$?L????????????*?w??j(??c?!??\??6???????:??uf??F.GhiV?X?y???.J???x?F?r>??????5??I?n??K??????C??J ???H?U?1??Q?1?'i???z???[b?-?.p?f.)*???\???3g?7?95?r?`r?I?c/???9$??.p??+???c BI|L??K&N?CK?%b?qj7- ??rF?%?4+?B#??}{?@???s?s? '?dd??????\@??e]??????/p?c?'?[?)wh?,`X? ???????@V?n??? ?A,v?8j?a?"?F\J?f`???^?A??OB???R0?@]j?????1??q????T> {??&o??&L?T ?zn-+>Zae ??????z?{??????5X???_??('?,>?????R@?S? ?#0N+?@??s???$e`y[z?V'QE?)Z*?}?Dg!X1[U??zK?x????????B2?6?D?S??z?????x??? ?C:y{?-?8C ??Z.?L??N]Ek??<6????8h_%?!??$i?y???@???*P.?A(J"`P??aNK??,b=o?.}?f?5?B{?n??>???{;??? ?@?NU?\???:???p????/Ul??H8J???*?t?]E?i?C?)?^.?k???l???p???Os? ?Gy|"??p??M??]/mFg???.???ep?z$??R??v]0?'???????Q&,#??3???y +xJel???????F??`&??Gq?i??0V?$x??S&???E??[g,???????;?X??uD0?????AG?X?-;T??$0?l??]? H ?????|O??Z???[??R??,???w?.????t#{endstream +endobj +544 0 obj << +/Type /Page +/Contents 545 0 R +/Resources 543 0 R +/MediaBox [0 0 595.2757 841.8898] +/Parent 515 0 R +/Annots [ 547 0 R 548 0 R 549 0 R ] +>> endobj +547 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [105.602 750.9806 118.6329 766.9208] +/Subtype /Link +/A << /S /GoTo /D (page.47) >> +>> endobj +548 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 0] +/Rect [306.9728 516.495 335.6947 526.0292] +/Subtype /Link +/A << /S /GoTo /D (cite.D04.2) >> +>> endobj +549 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 0] +/Rect [261.4686 468.6744 290.1904 478.2085] +/Subtype /Link +/A << /S /GoTo /D (cite.D04.2) >> +>> endobj +546 0 obj << +/D [544 0 R /XYZ 74.4095 738.0292 null] +>> endobj +118 0 obj << +/D [544 0 R /XYZ 74.4095 720.0964 null] +>> endobj +543 0 obj << +/Font << /F26 180 0 R /F31 192 0 R /F34 291 0 R >> +/XObject << /Im1 171 0 R >> +/ProcSet [ /PDF /Text /ImageC /ImageI ] +>> endobj +553 0 obj << +/Length 3787 +/Filter /FlateDecode +>> +stream +x????????_1W8U??WrRd?%??ey?,8$v?6?-9??_?~?????j?n4@?_`? ?/?%?7A???????8??{?}w +???T???y?Z??????jw{?K_? 0?3? +C???y??=?* ?o?????h?xo?????W?g???C^?????? ????{??????????a???b????~????:?e~?0 D?;???L???:?I??wH{?????0??(K?.?"??u?kG????????@??m? ???r?d5????????????u? g????6???????k??q*"+M?}????~??'?}???S4D5m??Mh2???9?}???t??i\?NR?S??Uf~?????~v%???7?OY?>???a?w?1&?M H}????s???[[??O?Xm??lK???TZ???w{???.??49????9? +??.I?gQ?w4??U?h???,????????5????mh?U-c>Q?????T?'???????wy at i?K~?#/?? ??$???%? +}??hi??t?5?;?o|????[{nG?C?6o?{{?0???P?`???K??LyH ???g?yZ?El???z??=?'??*??/?????Z?;~u??_??q?y?'K???EM???AF???????o??N#??o??N??????=??[Q?? ??q?3q?id????a:`?b???????o_?km??????+K?D????E?Z 1??T????l?  ?n{qV8??U4?9?4?}???1l??6???/W??1?{?%??????XXs?????f3H\!ul??W?2???T??h???????|_???(?k#????!JBil??U?ji?h?rB b'??<;?1@??18?L3Z,h?b???1???>,w???Y???e??7? D??'hwg????p?T?dB??Q???^I?B?hkJM??o???QUHoj?:qn'????d4??&AR??v??$#???.)\??n?t?z&?c?t????}?$???FEq4T????.L3?"??$?)u)?p??7k ??1z0???I?Y4"&uB?sr?'? ??d???7*?7H???*?'?l[?t?,n6?q?????`??ul?1???}{?????/????K0x???{?e??1B?c~??U]??@-????F7?x??3?3?\?????#?r?S?vt?T?????O/NH???#?bC?R??N?zT?(????????[???J@??3??h7???H?????'`???A??R?????????9 t?3X??????>???A??m?????}r????/T|K?u}G?n?2???(t?_-? ???h?B???????????a"9L?i ???6'J@ E +RA??(Z$^??3???. ???:$?K????M6???!]?8 L?????? r? +nc??? ? DVX??-?@??U,k?]??qg?A?]H 6?????B?y?0???\&?!s194h?,?ry???j=mAOc??)?F(?g? ?K?3?d?dVk?????=?&? +??????????U????Zr?N''?^z6?Yi(=?;??>w3h^L ???ucEk5???J?Jq?W +U?????9?V?=???*?x?!I????~l,kklq??0???@gx??z??'8?\mR??z????/?$??? ?ix`)?R,?????A??ya?ZE:??dD?!???E?|"4`'?"wOD??X?????:"??/_?1F???^?[?????6?.??/21x?$????5??CA????|/v??L?!Ic? V??q?hC??o??0?Q? ??????ET??:?M???? o? ???X?0>N?B?:?6??o??`,?IZIi???????f?L??d???????z*?)q|?}????!??#?;y?ii??a!?hY??s?????^?h?Z*???K?1????%?? ?/?U^?h??u?H?}9ib?V????iN??F?R/endstream +endobj +552 0 obj << +/Type /Page +/Contents 553 0 R +/Resources 551 0 R +/MediaBox [0 0 595.2757 841.8898] +/Parent 515 0 R +/Annots [ 555 0 R 556 0 R 557 0 R 558 0 R 559 0 R 560 0 R 561 0 R ] +>> endobj +555 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [105.602 750.9806 118.6329 766.9208] +/Subtype /Link +/A << /S /GoTo /D (page.47) >> +>> endobj +556 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 0] +/Rect [489.6438 621.3793 518.3657 630.9135] +/Subtype /Link +/A << /S /GoTo /D (cite.D05.1) >> +>> endobj +557 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 0] +/Rect [166.9926 549.6483 195.7145 559.1825] +/Subtype /Link +/A << /S /GoTo /D (cite.D05.3) >> +>> endobj +558 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 0] +/Rect [226.3069 549.6483 255.0287 559.1825] +/Subtype /Link +/A << /S /GoTo /D (cite.D05.4) >> +>> endobj +559 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [307.3462 535.7305 402.7954 547.2273] +/Subtype /Link +/A << /S /GoTo /D (the-gc-transformer) >> +>> endobj +560 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 0] +/Rect [363.1104 459.9846 403.8672 469.5187] +/Subtype /Link +/A << /S /GoTo /D (cite.SQUEAK) >> +>> endobj +561 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [214.2531 296.6271 429.9614 308.1239] +/Subtype /Link +/A << /S /GoTo /D (the-gc-construction-and-testing-framework) >> +>> endobj +554 0 obj << +/D [552 0 R /XYZ 74.4095 738.0292 null] +>> endobj +356 0 obj << +/D [552 0 R /XYZ 74.4095 696.1114 null] +>> endobj +122 0 obj << +/D [552 0 R /XYZ 74.4095 678.4004 null] +>> endobj +562 0 obj << +/D [552 0 R /XYZ 74.4095 232.0892 null] +>> endobj +126 0 obj << +/D [552 0 R /XYZ 74.4095 214.3782 null] +>> endobj +551 0 obj << +/Font << /F26 180 0 R /F31 192 0 R >> +/XObject << /Im1 171 0 R >> +/ProcSet [ /PDF /Text /ImageC /ImageI ] +>> endobj +567 0 obj << +/Length 3680 +/Filter /FlateDecode +>> +stream +x??]??6?}???j?Z??f?.?????0??t??????( ????:????04??QP???Oe??m3\?`?????????~?c?w???p??q?????/_j?+??3?D??+I???:? Y???{???t-?0-?x??i????q??$8o)L?{w?a???.??d??Um2?|O??s?????_??_??O0??[ ?I|??8?8?V<&???r?j?,?<|?a? ?bBX?V??????*??/_]???????????t??E?4??U +/F??=?A???>y??????r?$&LR??@????f??*m?iGanL??? ?N???(?s????PcM???&??"U?~M\&??k?????~?5]?3??s?F`T????O?s???????? ?h +YX??????Ew???uR8o?~~?d^+ jwu}???q?]???`?[????'????P????oq??'?\?m}??is?)?? ?=?; ?'?-??u{??[?F????`?????? ?jr??????i?"?v??a???W? ?nX???.????/V ?1\?????Fy1M???p??6??5.?oAJ?i I8?m??????~?!?xB????J?k ????mB?rb?Ol???u?8??B???aWN?D?.???E????8?-??y??|4f??{?>D????k&l?x?,A$7?Y '?X?5???MZ1?????p? ?B9hv??4???v????A???m?fl????|jM\???C?????U?4)???1???v[?r?0??^0????P?$|X n???(??Or?f???f vT?z?f???~?kI?.??B???,?n#c???K?l?;6????$??? ?/8""8??'rS????a*L?????<?8kF?=?t?!?????F?3? +????9Y\???k???Z??+??$??gY?8nf%?$w??" T?p.????n????JI???w??s????I? 8??????A??T??c_? ?r?WI??U+???IQ +?O9@:??%2!D???$p\??L???? +8z????"?? +?:?Z????m??D???`?I?w6 kY?Y3? + ????AE?,??d?0J'?o?jc0* x~??R??K??????tR/ ??R????u1??????o?^??????6Aj????\????? w???ex?? e's w"? ?PlUACI?0?????#?a??N?l??Dz??????9r??f?y6]`???????I?h?j?xs?ns?,r??T?a??Y?0???8G?R??h[?Z??z)/?3&=??r? +>H?J???3W??T?(?????FO%?G?-???^YJ???????7Ve???G??G!a??N????@G $A?V6?r??DV?D??\????%? /4??? u?%?H ????G!???F??05$J?/?+Z;??m???}?6?$Jm?3??W ?????U?;?"?$F???%Sv??].?N? 1??r3???s?O?u???[f??U??>b??>6?{????_Gua??n-????[? +?????Jo???gRZ3??,????'\%Sl???H:???.????}????&z,v???o?G??L ????[ 0G;<?lw???4?Z9@?R0????R6??A9?!??????o??????N ?WJ??g?tA:?? @?$????xL??Y???S|x%????%[?J=3??0jNu?&l??7[+cs??8??g??n???rTO??????????o??????,?5?8????~????%??,?0??C??S???%??2??(Z?d???n? ?W???_?)BSQX??????t???E?n??a????????h?'?A?"??????qeY?G???+[.M^?pa;????1?6?V???~???i???l???a??@????m??????p?w>_l;P?Cb???xQ??i?????8??2Ky???;?W^?/??r?x?M?}?9?+?d'???v?{&B?$??d?R???@?SZK?m?8[?t?o?m?|??????Rlb?????F0?nx???????Az??? ]\)????E{?g??PY?i?_?@?y?j?&? !???*?P)??G? ?nXwY?tQZ?????????????BL?????To??9}M???QG$I4~?W^??V?7?EfF?< +Uj?gd??.???U???R?"i?z???b??9tMM????N&??O?? 4\0 ??\?????,?%`??d c]?)??ce? ??????j4n?R?q??h??h??"?F??x2?q?Cy?J????????2??G?\@Btr?@1???,8???\?c?)??O?U[^??*?}????|???U?I???T@ ??r?yD?????/er'?D?)W at b??3??g???*"?Kr??w[?:???s??c??}LSs ?k 4? ??,?6??apnNg?o?u????(?"?????-yr????D????jiCn<3Sd??6?c3S2?T??X>I?J?? {???]<+??????U?y???r????OA?? +????TGQS??b?? ?????$?Muvz???j??????> endobj +569 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [105.602 750.9806 118.6329 766.9208] +/Subtype /Link +/A << /S /GoTo /D (page.47) >> +>> endobj +570 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 0] +/Rect [321.2003 697.1823 351.6358 706.612] +/Subtype /Link +/A << /S /GoTo /D (cite.MMTK) >> +>> endobj +571 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 0] +/Rect [257.6944 667.1899 283.9357 676.724] +/Subtype /Link +/A << /S /GoTo /D (cite.VMC) >> +>> endobj +573 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 0] +/Rect [241.1365 557.6184 278.8051 567.1526] +/Subtype /Link +/A << /S /GoTo /D (cite.BOEHM) >> +>> endobj +575 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 0] +/Rect [475.3313 191.0109 518.5389 200.545] +/Subtype /Link +/A << /S /GoTo /D (cite.GCSURV) >> +>> endobj +576 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 0] +/Rect [89.7673 179.0557 108.5467 188.5898] +/Subtype /Link +/A << /S /GoTo /D (cite.GC) >> +>> endobj +568 0 obj << +/D [566 0 R /XYZ 74.4095 738.0292 null] +>> endobj +572 0 obj << +/D [566 0 R /XYZ 74.4095 630.358 null] +>> endobj +130 0 obj << +/D [566 0 R /XYZ 74.4095 612.647 null] +>> endobj +574 0 obj << +/D [566 0 R /XYZ 74.4095 252.0145 null] +>> endobj +134 0 obj << +/D [566 0 R /XYZ 74.4095 234.3035 null] +>> endobj +565 0 obj << +/Font << /F26 180 0 R /F31 192 0 R /F48 312 0 R /F34 291 0 R >> +/XObject << /Im1 171 0 R >> +/ProcSet [ /PDF /Text /ImageC /ImageI ] +>> endobj +584 0 obj << +/Length 3854 +/Filter /FlateDecode +>> +stream +x?????6?>_?#Ue?$@?????N??kg*{Hr?$??k?T?????o?????T ?? 4? ????M??IT?M??0R???7???~??e??N????}w???J7q?$U???M?:?iZ?&?v?=????i?Sy???0??v??,?X?}?u?????O?.???????b??VG?c??M???`???~?/?a???}x?N??",R? l"??bI?y???, ?{?{???+?????d??&????C?2???7?/ 6L6????H??8 S?f3?3??Y/Q]`C????????G?E???oO2????? k???hqs?vGf#??*?? +z?< ??a ?]??cC? :D?j?????l?????'p?K?`?Y? w??-?kM?YiX?T?8C??)?F??????? i??]????m6?????\e??9h ????:?g:x?j??~??v+K??? ? d???ep?|Au+????Q#w\;r*{K?B?v???8??????0I^m ??!C??K?p?Z???5i????%?+o??PM?????????a?G?7tO??????#?(v1?eO!;?mo1W?h?&0~?HG?%6|BU?s??k?kK?:???P?\?G??????pt?????: ?O?????"?????J?R?????k?3$' +??JO???A?H?p????????@?f????l??,?16&???r??w,&J?(-??$:TJ?/??n??_?t1K??x??OT??~NE?c),????~e?S]?4?N ??He ?gF??J9?[?F;k?O[?? l?3]A???m?Q?????? ?z????>?\??+^??4?<??????????v???Q?3??%:$b{??/??????????=I???t?U"?p?$-?%+l??????@?F???B? ??o??J??<|??o%??]??R??????cj?M?4?j?v??Ql???w??b F?????x??W?/46??0???(+??;??v?5?????~?????D ?X?sz??hc?tc?69]????M???U=N?????9????|?B?!AY9S?.??%Jq?V???F?l[i?E?????d???p???BC?"gm?B?iJ????? g?ho+?&U?)6 ,l}Z2U??Br????9????????C"??? ????,?w4e?p??bEX?^??E???.?Pgp??O??????87????x????06fF}^d?I/?\????N ????j???????????Qx *?ac??t?#?L?&q??e?>??49??????,?]?!?L??????? ??????????? +`?????????????D?q?????=W????&?\?r?#' +R??[?a?E????n?>(a???hW?JCG?L?)?6??~qmZs6q????Q 2??(? ?>3????????(???H??????s??????j?????1???<2d???=?T?ky??J??PZ? ?|Um???u_zY?? +?L????????Y??V+?$8?ll???*`???u??8?}??#+?R2?F?M???f`Q??????wr'??X3?#~?'?6?lb???zd?????n`??? ???-2^h???'???2????e?J?S??"?????\?m?;1?:-L?????~?JF?W?UM\{??P.?B?E???mp::s|3?O?rU????B??@%8?mw@??A=?????P[_???ROf&??[P&j?viH2A?? ? XK???P??????q?7???Vb@\[{??????]$m?H?? +????? +L}??\??????'?p%???k?pj9:W  V'? ??(0???^????i?x?#???;???XJ?~?x?n???^ug?"??'??T}c???S?0?o??"??????0??T?_??)?#Y???)???C-I?????d?;?? ?????q????H*??b?q-,?q?J???p?=X?8????!?`6? qD???o?b?a????Y?G???\mU????F?l_b9?7?5_j?,Q?(??Sm???$M??Q????`?P??K%??w?-v??aV???";?%? l_ +?@??*???;? ?j ?x??4?2?J$ @?|I?s??]???????[???>rgqEq????F?Eh???w.7?/X?Dxq????????"L?8?ma??Y/^`?w???H??\$???.?wV?_?f?k6V??q?? ????T???'~?%?6?G}e9? ?m? +FZ????h??M_???o4=7K~.f?b???DM?? ??cE???%X9~?~#"S?>C?9????2??jF?Y??K??i????N??x$R?????? q?SO[c???????????X???p??M?7?9<]?p?L6?B??M?8H?X!??-?Kcz??$?e???s??z?J???o)?? ?F??q?`??????????}????j?4??)???u[?z??}c?????nq???]K???1nw?)?X?,z?N3??v?~9T?+???$v???V??4??|*?L!??"???h???b???R0v??oN%?UT?89??X????|T?"?#4x8>K?#??????)?\????GD??T???f5??HI?????&??_x?]??c?|?,u????G +??:+?2??N>? ???1?U???@9!??Gv` )1??.#6??8??u??J? g?e)?d??Y????/?M?0???hzLwo??S?B??dX??l?L?,z?A?[???;?????Nu???.W?\r%(???tp"??b??gq(??J????6$W+?2??&?j?? );???>P?;W?M?>Yc9)&?o2!?I?????_?????A?eendstream +endobj +583 0 obj << +/Type /Page +/Contents 584 0 R +/Resources 582 0 R +/MediaBox [0 0 595.2757 841.8898] +/Parent 577 0 R +/Annots [ 586 0 R 587 0 R 588 0 R 589 0 R 590 0 R 591 0 R 592 0 R ] +>> endobj +586 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [105.602 750.9806 118.6329 766.9208] +/Subtype /Link +/A << /S /GoTo /D (page.47) >> +>> endobj +587 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 0] +/Rect [224.8143 637.302 290.0191 646.8361] +/Subtype /Link +/A << /S /GoTo /D (cite.DETREVILLE90) >> +>> endobj +588 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [503.0731 540.1601 521.8625 551.6569] +/Subtype /Link +/A << /S /GoTo /D (the-mark-and-sweep-collector) >> +>> endobj +589 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [73.4132 528.2049 205.7376 539.7017] +/Subtype /Link +/A << /S /GoTo /D (the-mark-and-sweep-collector) >> +>> endobj +590 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 0] +/Rect [76.91 397.2743 103.1513 406.8085] +/Subtype /Link +/A << /S /GoTo /D (cite.VMC) >> +>> endobj +591 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 0] +/Rect [239.354 230.4687 269.7895 239.8983] +/Subtype /Link +/A << /S /GoTo /D (cite.MMTK) >> +>> endobj +592 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 0] +/Rect [145.203 218.409 170.4381 227.9431] +/Subtype /Link +/A << /S /GoTo /D (cite.JIKES) >> +>> endobj +585 0 obj << +/D [583 0 R /XYZ 74.4095 738.0292 null] +>> endobj +564 0 obj << +/D [583 0 R /XYZ 74.4095 469.6446 null] +>> endobj +138 0 obj << +/D [583 0 R /XYZ 74.4095 452.06 null] +>> endobj +582 0 obj << +/Font << /F26 180 0 R /F31 192 0 R >> +/XObject << /Im1 171 0 R >> +/ProcSet [ /PDF /Text /ImageC /ImageI ] +>> endobj +598 0 obj << +/Length 3274 +/Filter /FlateDecode +>> +stream +x?????4??_Qb]]??so??? ?*[]??]???i??|??]??????TJ?w?:???????"?e*????v??.????](4Ktp??|?{?6Jwa??8?v??Ip??v8?b?5B?H?L???U??O?`!??? +?? ??0?? t[? ? ?j?#?t,D??K????????5 J2????R!]??/???????Dh?}?x(F???a1#?7?\?R7?1O|X ???s]F????? I?'???-(E7??x7.?1J??U ?_?[w"???????"?????#o PR<|??08??t?'?$?r???@?6T?:qA?\?{?<3????iK!??iX ]??~???n??Y???'?K3e6@???????.?l???)~?]2?PG???D?T?Cx??e7@??'gv??< ??X??? ? +????}??1|+d?O???t?L? (??#???4t?????J??Vl]?hb?&?\?|^M?%?xd?#?H1?u?b? K0?.??3,7$? ???????? ????x?????-?/??B???^}+t?@%?O?7??I??0????+P`7??'????e8Ol??)???? +?0?l/??b??P??????>?H3 ?0shjvt&?OU???0c??1AI????G:??H??U ??X /aI ??$*jH?Go??CD?AYd??\g2? Lj?? O?3?h?`?tB??1u?ej3?E??????????X??x?R6u?sL?c +z}?Fy@?0@$??6??T?@????W?n)bd?we?Q????r9v &M????(J7L:?(f2^bd?'????X?????Od??????q???M?? M?5?s????p]???{??j`?c?!Y8?)??v??b?9??C0?A??80??p@??????? ??? +x????L*??????*???R7?X??+?$q? Y?8X2e??????X +?,??#J?????7??Z 'Dn.?a?VI)??*?E?h??5:d??/e??QH???{6s\???0}w?v?-?[??R??~?"+?(?#??Y??|?8???&z?P??8??B?z??1??y?? ??? L-??*??Xq????+N????n???xb5y?U,?(?? c >?????????Z??9O;5?????????F?%@[??? ?GYg???E]?R?J???}W??-??l{?(???/?R9?Y_?*???? Y???F??+?L?@???t?tr?-?(X??1?C??Q?Q??-`?M??S?C?\?!??U;?T?9?? c?00X?p?m?r?;?C.9y???.??5????z6?????V???20?R????S???)?B?)A~?P??R???r?1?$/S=O5 ?n??T??As?????? Fye????!??????i???`????}??E?????[1??=\????w?k);E?@m'b??ph??a.E9x?E??????4?p?????9g}?t?h +??Z6\ {???t?$????v?Y?\?l??XY?(O??M ??3\?u?%???3/??c ?l??,?n????J??Imp???2Sn?IT6$?GPOU????N1Gk?x??#?&M4??)|7?:???7?5z/5???i??? ?Ea?q???y???.??am?wn}???e}?L~????\>??_?>??????o?????"]Y?'??<2?C&?????M?y?????nAG`???`??/? ?}l#??\?k?? ???$??1?@|?F`?XY???4y??\m{?l]_?:4=er????OcC????M??q??J>????> endobj +600 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [105.602 750.9806 118.6329 766.9208] +/Subtype /Link +/A << /S /GoTo /D (page.47) >> +>> endobj +603 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [110.6344 206.9809 246.934 218.4777] +/Subtype /Link +/A << /S /GoTo /D (the-stackless-transformation) >> +>> endobj +599 0 obj << +/D [597 0 R /XYZ 74.4095 738.0292 null] +>> endobj +601 0 obj << +/D [597 0 R /XYZ 74.4095 478.7592 null] +>> endobj +602 0 obj << +/D [597 0 R /XYZ 74.4095 369.1877 null] +>> endobj +596 0 obj << +/Font << /F26 180 0 R /F31 192 0 R >> +/XObject << /Im1 171 0 R >> +/ProcSet [ /PDF /Text /ImageC /ImageI ] +>> endobj +606 0 obj << +/Length 3494 +/Filter /FlateDecode +>> +stream +x??k?????? +j??Y?DR????=r?Kz??rm?&A????z??Xr6?_?y??,?m??????%'+?????????c??js?Q????Ig???c?o?z?f????d????*W?????& ???F??????\E?????o????]?u?o???*?|???\???????V??\6???]?????'?w?j?w??????:Yq??a?j?Nt\?h{?`?sQ{??7?| l%*?m??+gml3m?w?:???H +=^@b?`N???f?'.?t?????}?zj?5??3??}w?7]Jx=?\? R??????Xk??,vynp???+??!??f?IL????_?=&?W???7??????"M4pY?????V?-H????"??TK?`x?c??X`T ??n??YZ?$R??8??t???:0?"/V.????I?o^?O???F-??o????E????t?0?)H?0??p6??>???u?E;?Y???l?i?*l???????A???>???jzF??? +????/{??M$?????z<;N???G?HN??%??L???o?j?/???g}8?}??(???(V???[?K???6m??uC?K?O3?D??^???IR?/3??M?????T6eI?u>D?Rr.??????? +?&?H??Wx????&???I4L!?j????A?/???)?H??1 ?(???E?B?q????b??s7?[ ?C??n?~^???nF?2B??m???? ?+f???Z?APz~O??6?????.?x?U? k??C?>?D#??f??YOD?:??????????'Sq.?vSr?&kK?{?B%?~????a?/y?m??x??X:}Rk????D???E??8wq??!??)?/?????p"????k?^?Q}?,?u?3???g0% ?y??4??Q?6.???m??p??'0?LE?%?8???!Y?%v5>,?5_???l???qbtx|????/?x?hO.a ?e?E???a??V?Hy???? ]V?O0??e?-(??#^?????????8?W|?4w????????????7Bf,p~???Us?ip ?Btv?C??R????{?"?P*???? ?D??l????q?'?|????????n??Kq\?(????BC????A??Z?1$??<6?????(Ls??a`?g-D?P??-?^v:??X?@???7?Pv!%8?$m(?????)?;?]H&??m?K??14P????jt;F?V??,???&3.u???oR4???R'???(|{zlcL??!i??? s?I?a?_@? ??:T}??W??A?]ID?R???v??`,??C?j?("??\??G???[?y???f?I???`???????> endobj +608 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [105.602 750.9806 118.6329 766.9208] +/Subtype /Link +/A << /S /GoTo /D (page.47) >> +>> endobj +613 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 0] +/Rect [137.5151 450.0375 156.2945 459.5717] +/Subtype /Link +/A << /S /GoTo /D (cite.GC) >> +>> endobj +614 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 0] +/Rect [176.5013 450.0375 219.7088 459.5717] +/Subtype /Link +/A << /S /GoTo /D (cite.GCSURV) >> +>> endobj +615 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 0] +/Rect [256.5345 236.3676 275.8818 245.7972] +/Subtype /Link +/A << /S /GoTo /D (cite.DEL) >> +>> endobj +607 0 obj << +/D [605 0 R /XYZ 74.4095 738.0292 null] +>> endobj +609 0 obj << +/D [605 0 R /XYZ 74.4095 700.0417 null] +>> endobj +594 0 obj << +/D [605 0 R /XYZ 74.4095 521.1898 null] +>> endobj +142 0 obj << +/D [605 0 R /XYZ 74.4095 503.8668 null] +>> endobj +616 0 obj << +/D [605 0 R /XYZ 74.4095 196.1255 null] +>> endobj +146 0 obj << +/D [605 0 R /XYZ 74.4095 178.8025 null] +>> endobj +604 0 obj << +/Font << /F26 180 0 R /F31 192 0 R /F52 612 0 R /F48 312 0 R /F34 291 0 R >> +/XObject << /Im1 171 0 R >> +/ProcSet [ /PDF /Text /ImageC /ImageI ] +>> endobj +621 0 obj << +/Length 3914 +/Filter /FlateDecode +>> +stream +x???[o?????)?(.????n?? +??yh? ??u5???d?~??P"5?8???????????????S???sI$-?}. +By????;z? i??1?g7e???~????w\?3I??????}A?(r?T?D1q??e?????????@s?~??2??\ C???Y????p?R?m?6????? h?RuC[=?T66}? ??z????????/I?A ???;&H)??6/???2y???i????????RDi???&?????)????fXx[????i??D ?_?e?9??V??fZ?;??5?? \??R????+???e????(? B?j?$/ +i???? ?(m?0 ???1YbqF??:????w??????? Rr&??%a +F???????,?????P?_??V??;?I??T?Q?????????k&U??Bk?2?&?????(?E}=?V"?? ?l?N5F==?]??v?"?????:; ??Xw?? '???fw?}??l_???~??:y?a??m??v?m????k???L??o??j????Cm #?R?V/C?=CKJeM?6\?????r??1??Af??7??W?????????*?}_C_m??XF0????0C??0K??;??>?V7*A??^???? ?}?;U??m_?M?y?????????8_vLeG1,??b{?d? v????K7???AF????U?ce??u?????L?^L?? 3`?!????Qf?L???um??S?????D??_p???Wk{??ZSB????W*?????????t??T??(???S?eU~?????p?? ?D??qY??*$??C???v?1ve/A???rs???????\??\???;?}?V???,`@? ?j?!4?D??R???-?}?/cG?t="?gD?&???p???p?).?6?I ????3??B:?c,???MJ?8T????X????????We?x?`?J??? ?,?z U?h??rB?B%'\n?!??q?3??dJ?M@??W9???t -??!!Q7?????^c??/????o?7??1??t????!?FO??? ?????z6?z4?s?"dH?0CL?????Bns!??3???nqA X?qaB???;??n???n??d??v?c#?Y?"? Ezl?E??EB7H???????JT??~?Nc???H???#?#?=?C*?K?C?????1V???aw??n?????????o???64???A#?!??G???????9C#II? ?d=4?=4B????O*?i ???qe?r? ???!?????S SV53??k?4? ?.yl}?U??GB??q?35?0??&4?I???*??*?R??H&1`FT?gF?q????????,'??[89%?(Wp?????????awh?s5????A??h???E??\??g??q9?" ??~??L??ET??E(Q?"?L#??Q?Wv??????????n|Y??&\?2?a????]?U???D?????A"??????F$???8"??6?gB?R??? +?E????Ja???DO?+F???????L?7?y????????????w??C=???? ?E' ?o$??? 7DNY??=?L?qfH\? ??D%????t=E?"g????????|?? Zjy??'?@?b|????^?????_uO6? ??x\?}? ?E:?q?3.B?k?f\$??q??qJTJl??Nc???H??P$L???t?|??P`XV?x?)? ??5Z??A?n?[?mZ?&?E?'?AW??,B?t"=-?"gZ?"I?y{?N??ET??E?????tVD5zV,????$??3*$4??q?i?Lc@??HO?[v??Hg??? ?\~?>DH?9??b7??????s[?]?????@L2????v??"??$?F????? ?Do??H??$&??#X??????I??X?PE?K?????x??~d$?0?J????H)?}?a????(e6??? ????? ?.E??j[,?_^0f??#X????????W1J???????? ??>?z????`N?&OO????mCx ?)??????}????????Xg(k??*39a?,??z,?????!g??X=?k=??m[???}?b|???P??Q? F?ri?????w??@??~ ???????uk???z??q3??"k?????ac??(??0g??jo?0]???????/k^p?????/??1?c?Rq????&m??d?L?????Q??cv?)cs:?????????a?u????e?X#?Y|NJ??,?m?????2V4???h?????h}?(???d???L)?????v?\,????????????+pm????-??,???qdB?????Q?S?????U@]8?]kEP9T??R9?B&?}?????XM?6W? +??tt??\??????H????Wu????J?u_C?aj??P??????\6Q??R ?K??? +??? +??bn?j?????Y=???????o3u???????5??????/_??d? /?9[z??bo?:?y|??9???l?s? ?dr?S??YZ??p7???}k> endobj +623 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [105.602 750.9806 118.6329 766.9208] +/Subtype /Link +/A << /S /GoTo /D (page.47) >> +>> endobj +622 0 obj << +/D [620 0 R /XYZ 74.4095 738.0292 null] +>> endobj +624 0 obj << +/D [620 0 R /XYZ 74.4095 660.4651 null] +>> endobj +625 0 obj << +/D [620 0 R /XYZ 74.4095 189.357 null] +>> endobj +150 0 obj << +/D [620 0 R /XYZ 74.4095 171.646 null] +>> endobj +619 0 obj << +/Font << /F26 180 0 R /F31 192 0 R /F48 312 0 R >> +/XObject << /Im1 171 0 R >> +/ProcSet [ /PDF /Text /ImageC /ImageI ] +>> endobj +628 0 obj << +/Length 614 +/Filter /FlateDecode +>> +stream +x??T?n?@}?W??Z???zw??4?j?J$?-?? $?jp?M*?????A???e???????N???&FZ`? ?Xg?<#?-??SH??u=?&SQ?@?R??? ?5?t?9G??????}^?? 3????T?????~???????VM?j?n}??\2??6]S???}?n"??{]-?.??N??????#)??? ??@ch???????,?J?? +b?]Jk???9q?]8???Ch???? ?0g???R?f???#?Y????W??ih??-?btW???GL?D???Qi R2?QK0?*??? +??kxG?-??Ew????5'7mv???Sm?Xp?K???8??????;q??>9????o?)U??Xh?4???s??K-=rp?~????7?/?P\?sn?s8?e????????????#??% 2??????M??Y?i??!?I?|??>~?b??eJ> endobj +618 0 obj << +/Type /XObject +/Subtype /Form +/FormType 1 +/PTEX.FileName (./graph.pdf) +/PTEX.PageNumber 1 +/PTEX.InfoDict 632 0 R +/Matrix [1.00000000 0.00000000 0.00000000 1.00000000 0.00000000 0.00000000] +/BBox [0.00000000 0.00000000 285.00000000 413.00000000] +/Resources << +/ProcSet [ /PDF ] +/ExtGState << +/R7 633 0 R +>>>> +/Length 634 0 R +/Filter /FlateDecode +>> +stream +x???M?&9?$??S? r"??'????f??,k????/?;"2?g$?E5??? : ?????????????????????????????????????\?????O?W?V????s??z????????????y?z?????_???3?????]??????=??i???>kG??????>?=?????Z???l^??T???)??C???77?n?? ???Q|????{??(???]??j?+??????-???S^_?z???2J??^m}???r +??q????Z?????~??j????????z?m???|5??<5u(????????W?????P??? +J????K?*(???????UP?W?????????Z?????J???????????3?g??J????yg?%}?K????C?:?zrt???hN??\?????tc???????w??'{Fn?\k}???XQ?.??k?Tq????????g???????t??}n?\{t?Z???pN~o???? +l?? ?}c8z??/H????~.????? ?a??????=?Q???u?~(es2?????g?????=????;??,F9????[?????????v??8r\ ?b?b??j4?)??q?????? P??7??????7??@????`s]zIe?V??\?????~?J ????5[?????la? +??V?v??Q?????E/??`+ Ew?? +? &Z? +:?Q?n?V?K??j1?IT???STP??????4???{??7m ????[?xtvkUP????|Q?s??"??O4;?V9??u??m%?2o?????'Jl?-4?????^?????5??[????v?j? ???Uh6W?u???^????RB?9(eo^1?????U???a????n??;?????? A?????r? +???-?%?3?2?_?b???A??c???_(???|m?????ov?:?Ut?.??1??????f?}Q]?k?1;[???`??p?[?? ???*?[?? ???V7????_)?W??)?:n???AQwy~q?? ??|S9?6??? ????Kwy#??$?????d eoJ?9;???o(?"???-???fO?o???z???_?????EQk?S?~|????}ml????D??G?Tl????YW?]??SjP?VXK?Q??t?-5?@?0?pq??l?F?S?'S1"?)?????)????B???)??rqL_+?|w?lL~??????V?O??(YZ{?????B?_?P? ??????|???rN? H?B?[?*l_?&?)?Ho?????TC??C?? z?jP?{cq?e??????u?????????????+?? ??fqu~??O%?q]?r??F?=?? ?{? ?~??9???i/?&????}?????????l8??.?? ???S??_mE)???i&????Fy????????ha??U?S??oj?U???v????=?? +???{?????p?E}k????+???p??YLKX??3????????L?????????ml??Y??x??O">??????U????&_?R?????QwdkF??????H???s!`#?P6??pi{???? +/???????O Pd????=?????????{ 4Q????u??????]n?)????\??????U?,w6,??s??B?????-??)]>N [?OMm ? 8???.????????#z=iI?[ +Rv??wT??n!g???H?????YM?K??Q?<???5???2?[!?g?K????/??j?V??s??6Q??? ?[V?g?Y???????L????B?1:??*4?Z?????U?????f??? +-??????WN??????r???D???1?????D????JL??????????-'m???????????Tl8?4?0????O??P???? Q]?A?M+??'??ic?MKCz????wE{?A?Y $8???P?@??:UR??Z`?????? D4?$ ? ?P ?e\L?????F?#?1??????">Gww?????????!+ +P???????????J????(N?ycit?tl??jm??u?r @4??????FW??6_???M???C{??-???z?] J?????w??m???o???(????o????????R+l?/.???P?W1??8;?W?(???J?v?P???????W??q????L?????????z?~???-.ec?? +???7??????|??xnM????s?@ l?d?)??g?.?Y???/nm'?>?Z[V8l??C_P???????e??d2????? e? ???I???c??mD?? @mp??t???l?%?Y??|???\??}???E??&0f?!??2:?`?t??w ???\?n???6?v???1???f???1? L^~??E?w~??????'??@?n???_T>?-??qV-??{??Y?h?2YM-Z??}??h5)??????@??9???]mG/???D ???k*5????D`???ow?X??c?K;???Rt????????1j???1?Uqa\????P?S???? 2??02?i ??~???HRZI?8>?????M.??q????V?B??????X?s???t +?V ?'?????????!?X??+?N??nU???Q???L?87P???? ?????uX?b??PW?eo?B?VW?mK?7?h&???d?Eh_g9?????;c?????L?N.16?s:????ql?u$j??e????V?6k0????M??+??E?'?????5????}?]???? +s +?0?W??tnr?&lx?c??6????s?*??-4??? ???' O????E?V???{?l??U????;?????N.?u?i?:?J%ug-??w?(?W?ev?.?2X??T?w(Y?????d9u?p????E???(C? ????K..D??G?V????:#?]7?S?H? ?Di?xFW.??^m????ZVwv?P????nr?/3??????|???d?j?C??-`??????b-?/???????0????z ???G6??? r?{Jw?tW??`? +??!?j(?R???pu?????['????@???n3E????9Z8?j? ?ZJhC??1kR\?? ??{fk~?Oz?& +?L?B?`?' `??ik +?-????pQ?????)?DZY[n???.??q^?{??a??????.????~~!???uR;?t ???N;???B?????5?Qx?1E?O????wY?B"??l?%?? 7???)]?)X??1l??????8??????z?}v????A"(w?? 3???R?T?n?????`W?T|???m"??5%~?/?E?B??F!?????????????l\I???, DPlTpsA?sB????v?????@gv?JX?U+???$OQ??????y??>????T|???????G"xw@?n=??Y,???I???K??E$??????????3C??S?U?)P?as???KB?E???! M{VZ)???g?h?'?????k???????2?n???^?1?w??!???&ll\????????f???{|? ?c??=t{?56??-????q_?Z (?Eg?????#c? R0.m?Q?cGP?^???`?????l??s?_ at 1?.? 3{?QSy???????&????y??F?V? ???^>????? ?It^?M????&.vr?L??QF/?_ r?]???F???XE+??VP??,"?)??<.%SP?$l???u?kp1x!'g???8??J?8????R?}???????7J?~eJ??7?????tu??7j*? ?S?l??rc??*[P9?"^??JW \? W???=?x??_?p9??F??V??|K??-]??U3?m?X?????N??6b^???????!? ?IR??c????Z?J????W +*?7?+f?:?Qr??!op?q?\?8??,?[??sk?y0?????[???????Vj???3?6?????na???nq?W"4?????+?d??L?m:D??????N??????&w??@??n?l??eK?s(?7??I???NR?na>?k????????^>??????Y -??6z?*.l?\F9?q(???[Br?$Q??%?i???{???E???-NqO?xf?Bvn???\]+?+???S^:?;?|??O????-??|&???)/?K|a?????!? s?1I??(G/E??L?DH*?0Y?&?o??[E??u)????????M???'??? ?Q~??/;%~???????N???X?^4ce9N[?p&?????P????t? ????QfWHH?0? e??w?a????ag*8?W?>???OM????J&?X??D???)??'?c??`"NZ?1R??)?j?.?F???~????????P??.???? L?EQ?????J??!??v?]?P7Ye ???????=_e_?eim??1???I???{fo)r?\???c?wV????PE?bF??1??t??nn??-?2???????v1?$b?G????s?,L(E???(.0g??@?b&=?S?#@?? T?3???r??(??8?=?r????7b?"????l]????G?e?N???2Q.??+?sW?????&??v?#?}??k?s?E????7????3#?????i+T?YED?` ?P}:u?????(O??v(? ? +???HD????J|?J??????U???I?Z?n??J?b"??b?E????5???X???/???x_B?-??????8&??*o?W????????i+B????h?u?C"b A??kM???S????,??wQ?rkg?p??%/?S?P7??:?A?2?7 ?UI????????f?H?`?y????%? ???????e?=o73fG???>??!C?!?.?>rU|]???n?=?h-w???H"?L4?~Qi??O.[??c???d?NWF?,??l?i{?(???:????K????ZHx???,???}?m??Lt?r#?]+?M?qs?? ?j???-?e??2S?t??%`??F???? q???-?7Q.??L??E????e???A??g???~Y??g ?/???=(c???x?C?c?01^2Q??l ??G????E??S?xR?G1H??&?5??c??/???+??m????J????L~bfN?~?R?2??? ?b?[9??? ?{ ?'>-???y0G???Ev??? ??'.?????z?C???B?~b??z?????'V #??j???'njwb>???m +????G???fA;~b6!?3?1??? f???????e~???????xq?D:??MLk.w_??R?;7*?^*5P?#wS???????D??M?_???kp7?i????D?X?6? 7??|???4?A?d?????)~????v? 7c?/??j?a??3?q??T????IH?t?B?Y??? +? ?7??????o?YK????eh???V????Q??2L???EyW|???e<]???????????@?G??i \P?b??17/?????k?O:?????Zq????]3?-?*????`??z??E ??w.y-?s??0?aST,~?D??? ??x0?:?B?\??????ps?Y?*C)}~??_???6 %???M?!??|>??@?DS?)??[(U?JRYW%??? +??J?7q5??A\???????L???7`?kpn?7?9Qd?7 O?\E?LQn????&n???????s??????!g3??|?M??NG???6T?L]?Gk??????K t????7@??9O?? ':??????#?Q=???py!wI?P??????~??ZNE?r????????\?/?9????F?Gn?n8???Y[????}q????9?w?v?T?Dypp?????m?2???? +??U??'Q?MvZ?z??a???????^????<5???D?,|~!I??7?Q?Wx???a??=??je=8?d??E??R?bY????L??N??U?C? + ?<#?0]?}???Y?7q+?'??vt+-8b??6sw*?_0?3}???:N ???6??j\?????(G??b=????.?Js at BRE???,?` +??Q???~= +B??~?K?,?>?X??~_???2~??B????y???{Z??)W?b?/????J??o(??H????????`?`?? E?-xJ(J???????Kak?fe???? ??8??e??0;e!?;%??? A???x?7o?%?\???L:%???'U???_Lf?`ri?v?\??:L2??@???$?`???`??=??z,??`r!N??P??`r= +?p???????`2j(?f?Q?U??@0??r?#(?S?I??d???d??`?E?m?L???I?8 at 1R7????"&1L=?$??L?_???zM0????`?*/??4G???wlLz??d|a5??6 ?? ??2????XO????qd?\?4?K?????0 ??3Le??I?[??e ??I??$??~??????I???Q?'??????H? &?JO0???cr?\U?????%?\L?a?l/x??{C??M??IJ??M/?????y??0?U4t????????j?? +???PD?b?s_??!????8=wDq:?1i?Z??k?F7Q?'?????te?w|U?????M>N? +|D???+??w????*????o?)?? >?q??N??Xx?O?? ?un?f??T???C????m??0P(?m??&?|???b5??@????k|???'?jC50?????? qQo=?\F9?q(xo??F?=?|?eI?VL??J ??)V??`?E????&?@? ??????RduV??#3?hQk?X?,~5]??b? ?3B??-6]??^[ ?/?&???6y??I??L????>{?J'(q;?G? ?2??RR0??uPF?7????jE?C?7?>mO?hE????CP???XS?'?]2?? ???Ic?j%??\?%?.{T???I ??*??!??p?'??o???&#??_)?V??s?D??? Q?2?????KA)???(P( ?'??l??9tPC6?-?wM?4ls???v(??8g2?{?K'V6>f????;$?\.???!??Y??2???t??k?O?? ????2 ???w?|??6g?????R???)?Xe?#X??L??P?B??I?vJ? R?q?7j???F??np?#>??h?????_???eK??k???Z)qk?@?z|?)?Y???8?????8????sT?b?a?G?q??:??uR??t????J?x;?O??B6????<8yP}./O???V/???h?0?|_??????5?3s?????????I? +O?p 4???E,?????? x??;??d??H??,5(?L=?Ylq??yn.???L3]x4???0?}*? L??g??????%???}?4M?2?r?? ???n?!?9f????_@????X0^??????Qc??N?#??_?`?????l?????r?0M???/9?4@ |$??V??"?2~q???????_?a???t?(2(f?2??Z????e??X?H??????y????4????G?<4?????S??9A???o??Z?,bB????w?????0?o ?? $?t???Xl?98??ls"?l8s???HG??????>??;e @:.1 +]?I^w=f????+?L????? A???zK?????[?????Qs?X=???Q?????#??K?I???#??%?\????*?t???>:?t? ??zd?e??&U? ????Y??jf??b? ?p+' 7J?z]??9????r O?p>3???/~??,?=???'u?|D3??;,??gPC???7A}?c,|???8??b????????p?xQ?f????r????V???S??b?U????TS?is???????????v.??x??V,?\?E/['??1D?t????!????/????#?????? ?? ?G]???h?+S??????????"?Qf? ???*???y???]???????-y???FD?w???%??F?rG???O?S??'[??F????SYk?1-??/???P???C ????La????h???&??.O??r ?q]?????3i?1???????PC?_?e??S??/????!??HN\???QNBmU? 2s?%b ?GtCE?k?c??;,qi?~??rqo??Ob?,????V>?8u?kp1xGP?????tQ `??T?h???;??+Qt??)?h?F?_?A???????????????Kv*w????U????Q???$?&?????P?B? +?????w'???)?k???????-ulA??1?91?V;???????f4????6? x~?js?_.?|??)???H??'Y??U?4??*?H?=???:J?#???f?)?I??q?? d`?W??(??????r5?j[y? +?@???xP???&?t??)& M?????2W??????K??/??W?j?fn??X??r????GP??^? ??8?2&?,????{445>:?7ZpX???????A-????-??3,???KZ!?`?CRM.????Y??,??_E'???\~?t]x<;,???f3?f?h?o?tr*>? ?S?i??1+?h??P????9?^????R??7)|???M[??A|???&?????{?N:?+Qt??????2?|Q????qg???u??}?7N???????>[YRH8??0?qr? ????:??I??Nb ?$????????d?`8y?p?t.?K/?~?z?8??p???w???b?????*?[?-?$???p{??B??(??????'??J8 6????| '??H8???NV8?_?Fk??????q"|ci?i?????p?/??A_y ??7?+?E???a'8?????g??%??????1o?????huF???c??e????7?K?a?g??ulm???????W/??@r\?#[:K?D?R V>?l??b?????????T?|???r????6{??Y?.a?????oC?Ff?9?J?? +???rC?L|?.?????;xa????cx??e?N?=%?84????? ??A!??Y????z???H;?=1???\????5 ?8?)dP|?.?D??????M???V?"f??0?<,?|??)??????y|~R????|??+ +?[???T?|? 7?}i?J?E?????? +??r=pj)?R??t^???r8-zH???>??l?6??????J??l?/?{?y?K???ii+?B?_}???(p??(?S?_(?ZO?O??&?S?L*??DH?N?????a{{"tf???D?0:?r??k???3??a??k???D??9K'B?-????y%??DpJ??#?p?_(?+M???t?ZN?^.W???g/???4?cQ??}E%Z??Mg"tX?)'dnj.?U??p?!?=??/???XW?{?????n]/???]#?}?v??????????}v??3-?r?r??????3??/???iy&H?q?/?}??8?????S??#?M???Hp??/??Kd=?=e??cT_p?W??????r??'e`PN? +S????R $???aS???????T??q:c ??]??om28M?SgWwW?0???5K?R?%e5x8?????q?t?#?DY??iN C??1?7#4N ?? ??????v???Q>?3???kpIxGV??K?? ?x?G6??j??s?)?%-??????*??? HS? ??u????,?e?(?1??*???)(??|1??i??7svy?lTGZ???n? ?O?r???sQ_>??????W.)|v??pz??5??kba??vE?5???fX?oae?h?:?9??S?"?????{|?L?D???C?16?.o?}????A,Zky =q?Tc/?F?????(?+C??????q3?x?f_?]?V?\4???e??/.=??'?5=???4??\|??&?n?[q?*C??H??????f +v??P?Y+|?????{1?!??&@{&?K?|?b JUxj(?G}E?$????Y?&?Q???? 3??D0??)n?y?c?? :;?1???Q?0kq??????A?+u??~? e???jJ?~?*??~'???c?z??NI}Zxt????2OD???vX??K*9q???[?W?~g G????}D+?c9??FVvd?x +X?+pn?IG??,?????~u?:?7?_?P}?? ???t:??<=?Sw:???"r???~?q";xB9g}?i?????|??Q~?="??*?9*??x:iE????$?d?]@???,0a??Q???6??8??Qu.?|???u???! ;?N???????C??1>G?$??@??N??ETa?g??G??r\??????/0?? ????U |W??6??,&?????'??G? a???+?H??D?^'?},NH;[?k??,N???#?,NH3[??MY?`*[?n?%*M???)???8K??(?s??Y?:???????????H~=F??w??/????"?& +5??]?Es2_?|???A?t ??H?e?(????;)??=WJ??3???1?Jp??a]BU???g??c?F???\$?h??7????9?7?*?r???Y?[???M ??i???Lf??^??K?????N?].??b????6????fb??L29N??(??K?q????6?b???????????1O?px??rF:?D?7??????H?B3?x??????H???]???63L??Q??NPF?;????.G??F??b???E??-OB??V?Sn??v??L3????/$n??fN??~T??,???K?C??)??o7?/?k???x:N]r?f.??_??8?C??3y]%????n?e????S???????$?D? ?Ra ?m?o??\U?q??f +\??n>2?????s?n??*?4/??s???24??'T???}?-U?o&??(?????fK?}?;?k?Q.?>????$9e??(?ml?? +uv?????_????4^?0?6?los?i^?w??????dn>?-= ?=[?O?????~xL??3W???^p?t??{(???>?]??Vv??i?'r}?= ?h??uZ?O/'86?W?4??1?_"???)????~~GmE????;z?W??fz{???n???|Rx?x>????s?|??????O??V T?}%??=?~???|?Nq?'?n)rL?R???w1??W??\v\=f??????V??mxgI????p?}??VN???^?; +N?(p.???k?V'Nx?]~?7Q??3??|\+g???Mc?????P?j>??x????1??{??C?C?gb??nR[???????t???ry?X?????v???b?OMl?l?u??O\? ?r?=~???s?q?? kX?%?Kw??Q? G^K?|s??????4*?F??`??? FYr????????#?v)h?~??q??1?=?He/30??eq???n A?????i?3K?P?????5?X?x?M?aX????`??WD???.?9???:??)H?w???b?Na????&?????o'Ha?<???g??!p?aN?J?no?q??~#?o????.H???VL^???w?]?3?@??|x??GnC5??Q ^??0g??T???t?4???o?!Roc(???b?3????F{2?????????#????i?R\???`??? #x7??U? +????e~??#J?q1???.?????7?D?v?????LTbfD>p????)?.?{?z8???????Q??W?0U??5?c?.6? :?)1??x?*???m*B?`???N?n*? ?? ?(??.???T$???Nq@??BQ ????B???????P}/T???M? +z?????tQ0???A?j?>F7?H???? ?? ??m???`???A??Z&o???YI?!??X?Pq ?X??????A??U??k???]?]I????o*N:?Nt???:???B?U???s?)???????{?6\?p?C?8&????_?K!??????h??7s? ?T??B?&?x??C?W?????|???1??????OP?????C???p?{??B??t?? 3A?_??vUI}?x??y?Y???W??u?????F?#?????o|?~R\?TD?~?*???? ?M??CEH?"??L???1Tt9N?G???PsV??E??l???/f?+h?{?YL?G,???g?2???3OiP?P?+?\??A3l?9?0????Q?;?D???R?]? +L8f???H?(_?$I +?Xwd???Sg?c??L??`[z,?o????CA???a?E^f?9H?)???e8?tZ?(????q@:oWfF?a??x? m???xW?????#$?$????J??9??P??cc??-?$?eB??{?????VZ?C????s??mQ?f????anQ???Tv??\?o??"??k????Z?EBN????{J?Zu?!+hpM??3W???V?? ??Kj[n?+??lO?8?'W5m??5w?^\\????9?b:??6??? ?h6&??h %????9???L???5?w????J??L ????/???Z???MA??P1?Eo!???"?@>?T?`?Cn?3`?0arq&?|Da???,fj3{??,u?? d??s?BT&???~?g?b??;?}CH?o???????L:??^p +??????(28??p????'??3t[???/???!?/Cb??@????k+0n?q?#??????X? FF?Sd6?????uXt??3?????;?%???????????e????^@??{??CE7?=??????J{??????????i????tBL U????Eq?U9??w9Y P?r??++????8?A?$?A????m????z??????jat5?? 1?Q^??(J??*9XIR?D??? Y?G#A?????a';?&2"???????!l!#rfi?2"K?3J ??2?/???!cnB?x??9?Q?a??h??8xR:?.???????=C??d9 +!?J???0???E?~r?C??(??Nq\Db??j?h5??F&??SZ>?????Q??f?:?im?A??3l???6B??*?????2 +??????S ?????;m???S?L??? ???T??)??U7??NZ???T?At?0????G??1??1???u ??*?}2?C?BG?5V t?J??v??????nN?c9Tag?U9????r ?YK???_????? +???b+A?{G,??????|??????????????B??????6?????#?`1??#D'??Gj!KI<9??#??HdG?|?4???o? +'/2?l????0???k;??? S?L?&???dA????G???0??? m]??% +?r??jAh?W?tan#?.'?L??)7?*?G ?F??x??^_h??? +? ????P????k8??I?,??????????\???M??ir??j??W???A???q ???Re<|????O3a?j&????]tk????????Lb?????3?N|a????:??????!c??U?R?????????~???u??????????,|??K????? +>??B,?Rh?4?f?W?EG??>X?(?W?}z?M?ta&?bC0?????e'?:H???M??,????$?+?f?????s'?? +??2?QA?l9?m???M$I?????? SR<AJ???J?lZX?b?Q?g5????Q???:??X?g??????Y????? ????~??????o?Z/?i?;FV????L ????????+9????,?QV?d??!?rVw*???j??Ew??????T??R??Y?~,??~?N ?C??[??? ??y#?/??????6?O?#qN>z?\w??9_??)??Pl????gW?(?p???)??}TT"???????tK#&s?????????"?? ???S\?V???>???r??q?d*?P?c?_J? ??*y?O3???I?????)????=?j?S??)?T?????_?[? QC?E?e???K??U???,?Y-Oo????s?}???^G?<( +???Y?Va?Na????%?x?2;%?f?????aj???"??M?????_,U[?'#-W?? ??x=??&?R?E&`???c??{???0O??a!???? h??pb????cbpx,??m'J?8B??9ZR??]C??=??Q#(?~????}(??2?s?(%???x??n??T?.????n??X?0/7K2R?%Kv??KK?O|???;?|??[zJj?[N??`"?tW?e??7????t~q?U??S>??r@????%a?J?.??nXJd??bw2v?????X?j at g ????)???J????F)E?V>???48???$????S[?o??*J?i?2?>Yo?I?? ?2?ne????#???????[??5??a?2? ?????7?@O?\??????????Z?Gd???*a??p??[i??L?O?????,?????? ?? ?7?8??_]?? ??[??v+#??ne??/Kb?s?=k??W???wS?g?si&???;??W ?b+??,??i?qki3?????| ???@????9~? s???|?????????g?r<"^99~?q?%?9??? ???| ??*?c&??m???w?b??????9A?&??*??\m?k?7G =?d?????ez??3?????/?e@????j?D?m???A?^V7?t?4!O sD?(W?r??Z???h^?g??Q???`XJ??????????~????4?GUI????:?+???QMyT??U&k????<+L/??cA???????O? ?r/??m????c?)gr?2???p????t?jJQ??!??b"?c??$?O????T?F7?fX6?t|?l?a??0l?aI?,?O??l???&(??/???$Q?????OU??L??C+p???????q????????w?s??{:??9k????o%{?????l???j? E?????J???=/{?9??=?T?r??h,?rX?9????????|U-\q|8?TO^ d????*_?2?\:? +?RzWo?????IP-??????>6?"????/V{j???? ? .,t7???????????2AXIR?E??? Y?G??n?hG?V 2Hm?t?W?(? ???O~??_?????K???*g??zD?f????wtu +??F?ofUP@????}?Vo?uc??z$?N?2R9B??? ?W0-Y?7????L?m?????o???????:?8????????P;,z???)?K? ???????8 9?GB?R?K?i??.kD?????1?6?8???VXuU/?`?L-?~?e? ????????F??I8(v?|mH`::?UO?? ?~EJ?]^"??W??2,Ut?n,? hSW?n?;???4 +?7?6@?F??7O?VO? 0_???0I?? #???( +DMu?B9?F?(????? #??/ #K???????= #??? #K???A???#?,???0?????H&/O??? #?|0?|!?<5L5y????3!<F]g>A??_{?A?Cw.?3?????'?????U1B-6?E???_ ?????B??cN/?9?1?????T?=*#B?!?b++?ewjh???6??I\?l?K/Y8e*???`Gbj?{???IZ? ?&y?M?6?;'???(??%-???yv?H??)Li?ZP]?OE?\?????Z4?9h??h0?9!??bB:?(W??aNQ?`=P?o?d??/? +S?4????0? +??s?A:??????????_j???P???RE???pt????#??/??>b??yL??yL???c?G?HX??r?x[?#?p??'??Go4???)`?"????'??????_?>?i>{+???!??t? +?TCk??l???????????:q??I???w?{?i?^?-8E?S??],??ew?Y??????2?????[?,Iu ???\A???'??Q??O????????T?~?BH????S??? ?\?S??"n???yAH>??I??o??Z?>??j?]F???8??????s? g;Z???o????^???|?3d??Ww?????N???9?=????a??=B?8???????_n??%??7?s???7?s_?i???|f?~???U?u'???? "`EFlC??ML???? ??T??n~??1??K3?9??s??5?????4Q*?Si???????-NF??????_M???y=??:^?r???#]>?????%??b??[????Ei??5??i???_p?g ?Uf[?z#?Z???K/?????J1H?AI?(? C??a.?vLG??)5?J??3 ?/`?;????cV[?yq??N?c?????7????u?j?uS????J???y?????>???O@?Sj???6P?dE?^8???B??JmQ??!??Xp?j"????"?j? R???n????UC/?z?/5???[????A??;? ??j??}?x?????V??_x+I{?4???`??v?f????y$?????Yb?????~8?s?)_`??k??oi?N????z7d??l?cQf????k??l)?'??&Z?obf?????4????;h??????bb9???y??{?h?G??? ???h?(C? ~g`???s???-@?D?Y?4?# [???c?,_???\??l??3?~?9??a?I\q???t4"E6D??Vh1????k?W??????????z??? q~???b????? /??f8?c3?~??cl?A at G|:??-O:q?3>???95??Vij?????(?w????zi$06?Z?8?????????;????O?N? ???N????qz??=?m1?L???-h??A???????"-:1???0(??&ui?8MX? z+!???x[??N????N/; |[??Y?-?h??X????&?s????x???Q$]?tmY?3 ??V=%??X?A1??S???c??]AWD?????(?G???u???Mz? {??X??l??lY?????A*W)w?0???????'?_??O\?_??!E???1"?M??K??O???O??c??????-???e5?~sm5Z O^??3???H??@N_??#?ETc'??p? ?y?(??e??@u????N??????Grmu[?GgY{??P???????ti?5??';5?W?d?;???Zr?????<0s";?Lu????E??l+p?;',??s? g???~????W?:???W1?'??u3???d????}??????~?p?l???b?I?????G?#???9&?????q?\ 6?go??;w=???????? ?????:X??q_d? ??3T'G??;?? ?l????jg=????b???mm~?{nCY???S??pCY to?N??X???H???h4&?????<?-?\?q;RA? ?q???>%???%?e?:???;>Zp??i??9MAk(?w??QCx?????[?{B?m?n???Yq?}???????E?+??????=?d????<"L??Z??q?7w?6??????uc?b??i????l6?S??#-4r???B.1Uy26? s????c????D??#?!???K???I?/????????f??w??a??N:o????8w?T_??m?x?)????[??6?,??;??nYw???k?e?R?;=???????/$??~u ObM?~:P?sg???=?W?Kj9?gMR?u???O<??|?z)??En??J?#!?&???R?? gW?????5??|?&?s?wk??@HnM`????$8?gv??.w??????_???%??Y??[3[A?e?2????????? ????<`??&?=95 V/???Ms?{A:???^????? +?W?M8e???uD| +m????p?V?pj+?(????????D+P|???>?A?O3?XZ?kX??;????7v'??q?????l???w?%F?'???Q,????)m??W:4???g?????p?dB?l?[?/? ????? ???g6?3??? ?????.??????? G???*??Tz? af? ?^tMA??y>????L,cf????n`??Z[p2?0???s??.O$?h?????#??Z?8?-N/!?&????8????? ?y?6Z?h>?ge?pln)??6?????_ >??U???)?#m'??4?G\gy?(?.?@??%????,???_:??GDZ????I?X?3?0[??`?i4+-8??L??????:????? q?????)%|pr?\???????M ?O????? h??Y\)E? ?!????,t??Ve;??I???O???????6????s?oq?9zj?????3b;?uF`g?????(??G?G? 4c*??c?/]b?p?;?sS|?????\?I??????}g?V?????3?:??????????Y????? ???.w??:o8??s??q?Q?aw?@?vc? +(}??_5?7?7bi????31?w?Ho???6??+?q??yz?a'w9?:#??l ?+?!Lf?p&?a??????E??s?u\g?#.??dntb?Y?Uq??yJ???????; q:??*???S?f???7??M?{z? +d??f??N ????5???iFgyS u?? ?q?G???y?????fDr??i????-??!P:???L{?????iV???._?i?????Z??????i?Pd<>1?#?? ??????z"?(???????????Y Y?j?l?6l=?m]z?S%?TE???T#C??????????7h????????s??3???LS??7N????? F ?/?Av?????> ???{???2r???v?~e???(??Xt?`????^?1M6???)???W_?.?Y??4j?????#W??^9?NQ?d}Y?d??;???}Ng??>??????9:!$K??R?????=?? ?j]zQ?:5?3???W>F6'P??mUb `m??5FP?Hs?????9#???JC$?W?????`No?Q?u K?%8????????i??W?6????y??????8?G?"PEH?.2T?\???:?x?n??????Gs?8??>?2z???????;??9>?????I ?????<+t?_9?c??c???????fj??:(???i?K??j???|???? tqtM!???????K?@?b???B???n????????=?????Z4?g???s? ??8s/?N??j???Z???j??}???????Z?a?J?f?S??a?>/?x????EMn?o?A?j?^4??5????t????j1 +??/*??Q ?????.=p???j1e@?X?D??R?ZL!?8?"8U-?!?d???hNU?vP????-???iW?x;????c???? ??B,.$)z?I?S=??1???????0`d?????|????5P>)i:???????b??I??U??E^?????G?????N?e*?7?+W$9??K??O?O?oQ???n???h?D????{<1?18??gZ??_?b,???7?q???D??Mc>???*f?X? aVa?8??N?????9s'??2??'?????x???u?)4??5???4$???4dD\?O???sD?????K]4"z3??-?Ak???|ao??R???a???@?h?????(?9?o0nY??)??*??????? ??g?[?=H ?9??_?x?%I?aO?w?jM?R??N?a??k ???3?N????s??=??H?Ao?Z+????C???6?i3??lC?b?????O.????g?i?uV?G?????.?.D???3? ???7bl?e?????o?Vi???O?p?alF?z2x)/??Mk??]X???(????P?0??&??;??S???u?N?u?????I??8????~?f{??g:??l?q?W?????0???????[?|A????cva ??C??~?!;'G?s???`?????570?h?`??{? ????2+?Z7l??u z??????pg>8??8v????e?!???x?h????r???w ???k +???Kq????f2O"????X@??jz$?????d?+???G?|?? ??;?q?Wx???xr?Z??M?d5?DyJO_?K??????:?^??v$8??? ??Y??<-?z??n??(?C?sRou??j?Q^?;'?? ?????#?P?:????????/%?S~? ?????c????F[Z?e???A?????? ??x??9?e?9???w?3?lx?K?f???};??x6iw???????F?m???EJ?N?J#?/'$]f??????z????/N<\???8*????R:5?/??(??X=[?;???f*??4?m l0TWU#e??b??Nl? w?0q??f???-??n???I[V???[^?z???WeV???M??]8??????????z???2d?X;?m@?g??/???o?PK??.???????c?k~?l0[-?i???u??f??????;???Q2J?[???=/???f????1p?+??z ??Y?????;??:8z?@?j?L??16?a???q???YG`a???e ?,?|????/?? ?????H?g?'?????r?`?X?x_?)o??wY#W ?3?X? ????qn?(????????I?ce?9?~G?4???;?\???????y-??lY? ?q?zN???*??:`??5 +h?|?;@????s????l?E??????Xy???~d??8??????n?G?P&??\W?u?0????p?X?[ ???A????????????)3Y???;F??? f?\???p7???X?c???-?1?j? ????8????? +??^??,???i0t??.3L?qQ???%7L {?1???I?n ???p{|??{??H??E??(>X?K????? +g???.w*?t?X??]O?r?F??????{???>mm?g???P?b?r\?????t9??S???a\?L???q??L????z?D????oa?d???Cc??????? ????K????x??z1 ??1\?~i B???E??????S??fF?/??????9p2??6??YB?,F?????vGMMhPsw??9w/?s???3??H??????Z=?,X{?o?????M?a(L??D ?M?a??M???So? (????"S?!????.??M]????Zo?????6?.??{t?! p??P???!??)4??p?C$???L??)M`9_???y?O????{b???B??j8???????t?|?????w?i?W????e^ ?/??P???0~k?? ?pDC?? ????f?{ax?y?^??Y?,Dt5eX?L.6dX????\#?Y?3???uN??j?Y???\?u?7????L?j???]??-o?+????i???_WH????C"7*"f??2??k28???@??t???}?g`?^????p ?A????wNU??I?????????C???]????????f?zz?~???u{?J?u?7?n??Q?~??????N??????x???k????`?D @?=E?e??T}?Pp?XgLhT?@?F?E?@4i???y ??P??K 6?NiA?_0[?t??9?K?R`UNlD??mL1?????????????h????? ???]??o^E??????/?f?1?fJE????????Q;P???c???? N??{p??`^???^???A??xzC.???t #~???h]???????8hiK?U?p??^r? ??'v??.f?(?-???o#B5??X2B??9?????j\S?RR???(?q?H??j\@O?????Lz??????XU?kk*R5?????Q??7?c?.?1??j??KT??*?l??? q??T?)??*'???$UcJ?5????????????j?^?q??_E5.??+?q??? ? ???????bY[??7.?q+?1???j?/???????-[@??-t:? N?R%?TE???rTC??q??q ?5U?????????? SR?????4????i????y+?_8?A??C??????w?qQ5ZS[Q??l?????j???o?f??o???6FU?&????xc???K5???;?v?4a?U?F?j?? Z?:@ L??r?? +??Od??????!gNj ?W*:???i?????e0?{?/??%?E???R?,l????????{G? ????@b??\L????lO>j????^+???]?k????.t?5I?E[??*,?TI&J?????d??? i"?}wx??CP??k?f???Og ??Y??3?????h????3n??q3hr@??h?]?yV?\T?x1t?KK?\*?kx????3?v??f??mC??2???????\???;v"k5??i'F?Ks??i;????}??s??W?????[???????6??6nO??r? ?wrZ?Fo?X??m????????n?g?"???????Vv ?5A?g????????l5??((1?at1?????@X??7??C???K+???E???v??^????A?p]?,???t ?h??O????:????? ?f?j???,???^?%}?????[??SM????=?%k?h<j??????t????-X?>?n^????9 2????????}? ?b??K?{???A??h???k?9i??7????bd???}??W????s?Z?w?I+^?5?q???9?M??N??}?&bad???9:?E@???4???4?k4?? Z??D???`d?L}a??1?n??>??O????????cCS?? M}?? S????W??mM?a^???gN?Q??t??>+a?????_g5M???0?sU???_????wo?;???2?????Xr?c?0m??U??k?q?f??Xg?r+???h????_L7V>3? ?z?p??}????8mK?ZF??b?h?5?Dt ??J?????O??????G??4D?89????Iq?w??-:NI????5!??q?(|?C ?)GD????1?,??E? +(O?4dk`????w???v??????L???IC?? }??b;??????h??t&????v?J????)c?M+?BhG?lc\??(????'UZ????*??q?B??j?~T?Um??Gs???"&???Tlp????.?P?3l??/mW?c????G?"n?Gy ??p?wa?J^??+'~??????V??:??????????#?B> F????dm?X?n? ??az?>bab?\}???d???!??c?c???_????????jWF????5??'?q???UOnG?L??P????*_dM??>?d??az?P????s????CI;{KCT;;z.1?s +m%??Y???-G,|},?6.In?P at g??w???????[? ??^?)?n?{??????V ??/C?sw??-!t???????/:???@v???OP?q?2?{?A??T???_??????o?????u? ??Q??? ???r????V????S???????W;^?b???q C?pd?[??????\W2?????%o-????K[?=?:9=?V????oC???}(O?2$i??,6??]&?? ?u?y:=#?Mx????m130????Nm??? ?*????????f??t<,XV?V????????PV???~?os? ?x???o???G??jS N???#L?9?3?V|????#(?z?Mu)?|??j??&e?????F??? +??Az.3???????:d5p? ?q?????? ?o??d\9xd] 4??:??i7~???iB5?CO?F???G??/?=?-?w$??'?Ro=?z???vi???e?????[?ye??s??????o?????}T7e?T????u??P9?????????1?/?}y9o??P?vsf(?s2y??vJ??y? ???x??@^?G%/ +?kk`$D??WFB at ppc$???P??f\?H????n){?? ????7?CJ?oY?2K?3`??????J_??4?|?S3%??h??k9?)??f?4.]? &???!?????x7??o???S?H?=X6cZ?y??j?xl?z?8"g?#,0??pb<????\????K?i?????Nct??_?3e%0t?(o6?k??@+?????I?xtC68?!??E?[?Jp|??!??o?\=r2?qg??>C?Z??u{k{^??P;?? ??O???[?<=?5????Ts??????s?v?i??t{f^??? ????km???_5C????K?x ??/????,??? # $??|?\???{???yh?E?J?E? ? :??1?gg= ??')?????{?R??w???????d?& }??C???k??@?t)?????#jbF+:?*?h????????"P?b????g???j?g??Fv?? ?E[~uT??V??? ??T?d???? +??n???^??h??????????}J??O?????F:???:?%? ?????"e?V????????n?b?????????%?? R???"?;??#?x?nB?r>*??I[??X?9N\??Q?/???? +c???y0??Vp?($??k'??PW. ?u?3???Ytl4E??o?H{??9?K?pF*-?%X???!&x-(????????4dg&??Bt?w????e???W??"_? ?>L?*??Y?/???^U?m(??*??-}?I.O??i|?]*?=zL*?=++?xL??*?@wM?>u?N?_PEf ]uz?"????AG7??~??t1??LA??tQ??tQ??T????"??????T6W`V+????`??+ at k??f?????coB??U?a}o??5???????9c???????? ????R[3V???????I%?kwww???Q??_??N?z1??VE??? ??s??m??ay?0~~a7+c??v???l7??eSM?``w7?)???? ? ?|? ??G??!=.?4??????]??B~??9??]????E ?{?Az#???0?G??V?vY/??q?Z?e??????n?????%,T??B??u?X6????X? f?]Wu?I??????n???tP???*B?L????dB?0??u?WVA??D?:b?n`?kO??B?????7[????n???r ??????|S?????Mgb????????????mj???X?qe;??}'?T??????>?7??g??8????=)z'???????\?V?F?90?|Z?J???.???????R?????k?aD|+??Ab????A?J???p?\8 am?????W@???C@?s? ?+?`?a?????B?'???-?a?_?z?4?????? ?????0 Y?k??????E??-V?]?????V?s????????v???V?A"?6? G?v!O$?0?g??o?%???|%[V????????M]?3?e???6??y???o????:c???o?R/TG?=??=????84???7???????v? +??&I??????b??)?6;????%???:??W#b??0?D??C????????or?n?A?#Vm???z??d?sF/?6 ??????a????????MC!?M)Z??c?%?v%??????9?e???w?????????+H??t??8?q_?G?????Gv???5?m???]2 :?oK?:?c???iY??,_t??c%?????e????????ZQ?q???~????m?4??4?????T??Q??_?/?????@?W?N?MI????4??(????~1? ???!]oN?c??3??z?x?c4"Pp:Zo??J? yX$T?s?????y???2,?????????????4?Ig?+#W?y/?_?^$K????MB????????8?9??M?Q??^$????????r???P_~????@???j-+b??????G????Q?????????~xa?M? |:V????0?j??? /???"??E?V?&y???.?HN?E?$??"??I??!??X?-n?Gn????n?av???Io%h#?Iou?[?6?3|??B~?y???_?3u2?M?vn?W??G??n???f?vG?uo?;?3?)*??????~]7???qN???y?Q???306?3?qq?.????N?>??U???Fi??TrO=?zx?t???9y ?W?????????U???M??=?????W? ???X??.???qO|rxFt???l?3??g???????Y???& Y?? ??&???I?C????B-?c?0?k??#v??Olm??B?^W36?.?eaQ4?;??0??&???L???????s??~x??#??K?9??????y??i??? ??????1???S?V????? CK?zN??C??????????{???-???}?m?v???^???2 g??'??8?+??i???$??\Q~#esr?r?a?c??Tsb>q?y0{?+?h??^?o?pu??u?q??5b?????F?K???V?Rxqm?_j???~??g??b?}?d?Ml?[???????????]*???>?/?=l???4?PS??A??????F?aSX????e?V?R????/???|?61?ss?????M?????8??A2F????U?0{?K[?0{O1???w%>[??D???????l???j?0gp? ;?X}?!?a?6??????$?????? ?`?w??;?Q?~? ?>?R?j:w???Bq??`{q??9?w0?9?/es#?\jyk?a???A!???A "?h????????W?"a??{??L? +?\\t?&????0B=?RV??M?xK??#v?!?s???Z????a??'?R&????????W??G=s????8??v?1??3?????]Al??wh??? ? Nb?y??=w????<,??????M????Sa??2?????? ????XmMxV??h%??]?????????_1?S/e?? ?[h???Y +???G?50bi?e`?s20b???+#?=r}????zj??+BU??????????.?{???e/??v??? F?????F???t?Q???????FXE?'?FF?~?|????K?2#V??00???R?F7??'#L?g??<j ?X??n???u?+/ ?p?kr?A??????{? ?Wq???H?????????\?T?0?(,|????5(??l???????%#??????<???hM?5? 7?M?V_6?e????ho?E??M* w??I?? e?????k?????sJ?;c?r ???????????Es8\?N??]??c?T??^????N? ??Q?d?????|???2w}n3??A????????P??z%R4??????_~g???????????)#=??n?G??AX?|??????TA}???~?f?F?)????5?????#N,?Xp??38?D?7?p? 3?n?????wqJ??g%?? '~?????A?;sI?$??%1Z^???n?:|???c?#}?d?/???=?~?f.t??'l;?????? u?(?NOk???W:???5??c8+?[|:?????Gj??l7>???x?????????!'N?????f???x?J1???U??t???;??F?w?=?????%???>? iS?\???????B???&?W?>@?D??6?x6 a?}??XLr???<7h???X?8????n|??C?v????J?~?Cl~a^??%??UFv?=????F???????T????Ze~??sQvs??"??[7?1pn?Q?????o?7??Q6?H?0p:oP? ?0[???v#[0h?e=??8???^?5?=E&?I??V?8?V?:s?H?g??_?Ct2/?6?:??c?f|l?.???.???}NjFC)?R3HQi?3Qa?z?p ?j?4#???f|?3???1_???y?h?Kwj??\??????????{?i??]/???)??????iS3??R,!???o????C{?'???;??N@,????3 ???nWc?!?????b???0d1?? M??l0 ?gm???"?7W ?i???????????U??J ?E?? ???eA????\\?@?????????0S78|??q??2???`????X????/?a*?4????'[?/??y+??~g?F??(????(?d????6#?r?l?????f?`??G????.c8A??X2? ??J{,*Z????v0?N!c?9???U?zN[k?y??6i??3??)?{???K?P=???8??9??y9?a????@!?+%?k>?!O}n3? |? ????3???9??B??pK?hB??4Z??Z3c9b???@Pi@?3??????&~?d????[???? ?^jO|N$??>\?.1R?}???5????????R???s????? ????t??n?%?b ! ??/?????????22???r?????C.hC??FF 7????4 +??? P?g ???n?????????L??j01?????Z?c???V?? ??o??2??????q?w??8M}??? #C??pd?N???ua?N??:nI???O????/e5???6g??8?Es3?pI0Qd?O[ik??????Sb????i??? ?&?7j?????(?SS??U!L??B??Q??8?,X??q??????f2-6?5??? IL??????q? ?*?=qbv?u?k???K`?j?a?`!?????yZ?/x??t?(u?D???%Zt9???=?\^G??Z?d+S??????? ??k??C?_???S?~&?|??? /?~pM?e)D=??)??#??s?8?@???k^?l\k?Y??K???@??=??????_p?F Z?? +-?h?TA42?;m!q.w?A?? ??????B?Ri)l)=?F?aD????,???9?????tS?)?9>??Y:Za6??????j]???D1??????D?D???h???r?y??/?????R?G?A???d?!8???Y?K?kH9y\?????{,? ~za?o`??p?l?_?????7PF??? ? ?~?ly?c-T???_8vR?TtN?\? ~?&?<0=4?y???????y?? +?]?Z????We?X7$o?Z??m??Z?????C????-6`L?_???O?-????vW???? ?!;m??h???_Rp????x????L?J???? ?C[?<9b<3%????????J??+??a^?;9@?<>@+?d ?b?-???4???u????a?[?c:W?s??1???W?*?G??=?0??)p??2?u?G?????"??.??7?!???H?I????????h?&!,l+??+?s?4??"?~???D???????64??[?qQ?18W??????&: +??i@??`??w?A?'?)????q?g +V? +?????? (nf`?L*9???$?9 ???????mO?eZG?t?x??;??N?!?c???{????D?y??!???m\?]?r????>?dm| [u??0?P-?w???St??(>Q1?%?????W??9M??qa??>???????+??? ??'z???O??q??)zl?4???? +?S?9?=?????2?^?W?*-????npxN?>'l-?N? ?V??^J??D+???V:???z?%?$??"+?"??V????????????&F??,?5.??? ??!/? ? :??rHkH??C????Nt???&?O????h?8?2?\%d?)~BkJ?ZCy\%???8??'?Z?JW??P?n???V?4Q??+??? ?=.?? ??)'Nh?l>???H\?v??y\?\??#Z~?#r???#???k?P??Y???R/?-?G4Hj?8?Q?w9?A?4?nBV`????y?A ?/x at s?????4???r at k +cw??9u*?D????????,&??q@???J'4?%??yBCN(=???b?>|????? ???? BY??}:??rvn??P?57???? ??????e&?o???:e?~????NS?????v?m?]??6???u???a ??w????Fj3?s??/?kf?k??W?&??f ??.$????B???R??b??b~?ln?[?[f`?h?B????C????2???"??m8?w?G,P??Y?d?]?1?P|??VT?????w?~??-3??f%h;+uh??VhC?V&??H??>?$??#e??piz+]?????????Q??1?a?^?????|?,?,?Rjp???>?w??#?? /?y6x? ?O?e~???O?C`??z??r8P,??_~?j??M???4s?If?2?<`??T??~???C?? ???x???/p???9_ ???R0??V?&%;A?C??Z???t l?}:???[9?6A?C9???CR tCz????????1?:?p???p/;\lF????d??y??????Z?vnj???? ?,i???????M???Z!??O?m?6?l3 M:??M?ldsX@?;?&?n?L???7k???{?]?I???k?J?h?8?%?npJ?@?C(?! l??? ????V?!?&h ?$ZF|?\;?/ ??y{???U#??p??gp-?3=\????yb?q??yw?L8??r?K??1?.I?????V+?????f??I???9]??(++?\???w??FGuA?,okI{?Y???ew??.g? ???< i6?V???j?;?X;f?s?Jc}???A?c??*???<?s????.o?????57D? 2a?Fb?v:?G'?k?I*?????????\4'`????8???u?6`}w???FF5;f????w??D\???T?0??r!9?E c???????5??B??7 ??? ????????&???j at T?.?N1Q2???~?? ^?h{\T`?o??.JZ??l???%??(??? YQ?????????????GVS??n? ?ZR;?q??x???d??m???0??g?E^?o?MQ ?;???n ???????V "?P?D@|}??0]?.\?K??? Tj t:+?kq\?Z???V]>?u??? +?os?3?>??E +???*?-??+U?{???>???+?9??dTJ??Iy{????@???B*ak??????kS9??:B??^ +??A ? +????b??6~{*?%??.Ei? N{?v??????Y?C 5'7?4ZS2u^lU??F?2??/??J?????????#?D?.[??g?? +pO\b??]??[????FFD? xz????"????7D5??D?? ?r???'????E???o~hV?????)?w"?B???" u?"?g?D??#???/o?V"X??a?H??@-????>I.?1l?c?hD???rd)??%?c?? ? M??]???m'G?ob??cD? ?@e$w)R??+%?d????Wr???V?8?A?"?i?zQ_h7?h??@?2)???@????U?f63??a??,[?/-(???8?E?e?g5%??q????q;qqyVx?? +??3? @?+????(?,?.?????&5-??w??*x??s??????`KB?*?0?!?????u????EI/?)%.??*??;?????i* ????]Y?????d ??'?E? +??H???U?????)???,d?>????im??B?+eI]??'?$El?M???!?fF????a??T U?:?v?8??k??2???W?%?1d?;??c????%?????9??\?????~? ????????1??|G???/Q?????? ?/?|????????(4?h???`X.Q??`m?[l?ZL?$?X????>u#???p???dR????v ??B:/?ZS??Y?i???3??dl!?????O?Icm?f????????????l????????,0Z???LZY?-e????]Q?o}?2?i ???H\?O?`6)1?&Da??+?[?{J?c?v????&???????.?z7?????????e?p?? CFctx???;?>?T??g;? ?????}B????q??????{chun?l ??????????:?} +A? .??Su?? ???>W?i??9??l??? N2xN%? ??&??*@0????????V?A?????';PC?;&~5???Y(????? ??????G?M??py?#Z?P?Q??Y?i^???!rvjY????)FO~sLc??m\k???atXELq?yz?] ???i ????cy???%?p?6?]@?.?i9U C?z???+iQBg?????[e??HW?o??lg?????_ETn?????1)*??????????????maOET?GkET??=?T?ro%?I??9G ???0qQy51?D?T.*/?8?????;??B9.*? ??hA???!Q?? ?Q:??p????2)AQYiEQ????Lj?W:E%0/Q???R{05???=Y??????6?VD?>?[`63??3 ???"Y??9?>?KE?b?fl*???B?2Z??,}HT?((s??<?3U NuQ(?A-5???{5??<?Q??P<????XH???M?Y_??%0?????Y?????8?ai?E??D??? ?0+?I?????????-]17??UN??O??????u{?????2??6]??S??W??TK?w6?cR????K?*??}\.? Po+??j?mi?W?U7b??{<]?WW)Qo/?)?j??~XP???ra?z?G?4J?{???DuLJT?f????&*xK?Z?nHQ??]?%0m??`?T??i,S&?z???7???;1HT???!P??I?+3?h?@?/(P??J?? +??6?z??%?g??????$???G?j? }?v?J?Y?? C?????S?:F????\?~?5?????)yy??6????[r^??7?-!Q?R???,7r??$??^y??8?L?{Z_E??|m?*????k??k?+???Y?P +???<????????Xy??B??W>?ooxjE????9?????3\?S?u?W??????0???j9\?? ???h??Pp?5???Qp??3?&%?(???[????L????-B9W?p????]?.????????}{aV??w<??3???D?0?gDG?g????+=R_???3?h???eHa|r-H??K???????8??;???0???/C$??=??????Lal!??c ??E??????-)?m??:(?????y?Q??!?H??B??p?Ng(??^F?0?_?-U??ox?J?5?????????t;?????8?.G?Oe???`?"9???????????~`??t????~???????t???]v!??]???>a? ????}a?M?6t?pW????(n0*??K???VPub,??? ???O?? ?????A????@?6??!?^??????s??K???.Vl????;? +w?e????????0nLN`?p?4?u@?UH/p]z?????{?K????^????+???????n??? ?Jp?g????????3???$`x?uL??? ?l?RS???????/nWZH9?0?"?/1~? f??{Q+tPR???? f(.> ??.}?Q +???n????88C?E!?Yp?? ?A????yN`L1?o?sR#`??~?/h#??V?$??qi+????*{U??H`n??????? ??H?????.??c?edf ??O7?d +?U1P??????P?31??H?5??"?ts?~?????ou?:F????;?D?y???? ?A????n&F??? ?ny\.??0u?????[??`?W?d/?, ???????r`??]??F!)B??*?C?tL?imF???????i!? ?b??y?Ou?X$?T?8???????;p*?a??c??L???a????"???!?????????K???????$?? ?ypf?????C?1? ? ??????e?u???W?z??f?3?x?[{? ??-&??d?{{??`?0???w?]?X???yl???????? (;?D??1??<6 Q`??c|?j H?. +?8????D~/w??{2{3Y^??*O?z`?C7N?e0???H?[???/?y?Ml$???fb|?hS ?G?Z???s"h?b.???l?????b?T??L???s?????x.?m4??h?????(??+?????j?Y!l?nx??-?o,????i3????_ED?V??%"?U0???0?+?????<;??%"????$"??<7W"?D?L????py??c?3{$i/??""?%??%"???????B???t8Ed~A?-l??}l?????Q +.?p???"2)AYiE????Lb?:E$0/?I(?????s[V??g?zib? ^d?g??F?? ?????v?v?-x???d??)?A???s?;????gP<=???J??'???+??=4iz=???^?G????Y?RJ-??????B,??Q??:?pcl??5e??po???/[?A^?`??q]h?C?zj?L ?r??????9??C??xU?1uE? ??[T??D=M??^??Mo??6?f!?,r??^?S3?%???1pMY6????|???'????ts???dY?#????i??\?1H??%???K?;??u +??/?q?8??M&?? ????qm????B??x?coP ?6???|??0'^8???yv??mZ9???xL????o?<G???????????E$??Y??o6?d}I ???v??D??????l?k~8??????e?~l???v????v??9?4??????p]?vm????a! h?uN!I??u,?S???Uj???v?;??:????4?5???;?@l???????!???t`?|"??Q?????MZo?o?G????????gP??vL(????+??Z?D?1RihC????z??Q~A????GK/??q???????>?~3???i???B$b??T????`?x?1u??????#?g???~??2?tc???[?`r????By}? ?lax????^5 +_Ue?>?@h??? 2H7.t?Ma????I????1???Ybt)??\????*??r?F??}V}s???|&X75?b?k?>?Goq?~.????????c???j?a?1??-??`?????\4???H?S???D~/Cu?2???r(?|LUf???|q}l??e8wkm?p4???P`????B?~?gN??,ayf??;??T?.??N@C;??Um?3?[?G?uLf `?\~a?c??o???d??F?|??N????VZ?(???yG^?,?u0?????'?F???@\?}q?lj)`/r??z??[??L?0???epfmHpI??jh?5?uP?r)?l]?U???ym)?N???S?????yP??~d??O???yXa?b??\4????ZE???:v????$???6_e:$ry? J??o$??K??F? ?L?8????????>???[???9????=8??{?n??' ?3???+$o`??|?????lB?%z?As^en-?o??!????M???bmBk??M??r7?9?V?9$Q? +7:f^?F??3U ??????"F*??|????`???????<8??3]??S.@?`? +?:3?Bu ?)^[pK??-he??k ??m?=H?????v???$&?????f????[?U????*??)g??A+N????mm?)g?o??41Mca??&V?q??z???U???ZG??D???2?? +?~?a=T\?m"$?]???? ??b??Ctp??f??S?4z, h???R???< ?p?IYT????$(3??].???????]j??|??$?i?Qd?+?????R???tY???@i?Q?o?????gplC???4.????4y?????B??%???X6Vv???U?{?#?8U?!?%?+y0? :8?y at J???|???IF????????:j?A??B@ ??l^D??Y8F?|?e~????T*MX?I??RpI?? +c??a.D??(???N;L$X???>y?K#?dIY?ic??X6??&??W???-l???,S??5?????I?m??;rm????w?b?_7?????????+?'?L?1>E5$PI#?!h?!??????X?? ??X??"X???[??ji?|???'eeq/??= g_<1???e? >???V??u3??mUku??1?g?0??nA?Y????8???????4e???@?Q??D????O?Aos??U1c?????? H? =K?|}co?????E??)?UD?9A?*?? ?{??&D?X1???SD??[?"??2?h4??.????/?4H?h5{Z?Vg?hD???h?b;G???TD??)??)??[??2?????@??c\f?M??1??2eI%???#Ec????)????.???????*mLG??M????W?????Poa?t`??/?ht?);?nb?K?I???)????[?}J????/?'?L?1>E5$PI#?!h?!???PE?9??K4v??/???"????(?SD???9?h????Dc?'^??'?e9???Q4ZY?VD???W?hE??"m?w??????u_" ?K??r?F???D5?w;??Ny??????^??.???pP???1|?n4w^R4?Y??L!w???? +?f5e0 S?????/?? o????5??Us??i?.?qH?/7?O ?y???2?*g9???X????x4???;??m??i?^??+?~??tb?U3a??}O +3~????g"x&D[?4????2aX?1?PGx????I|u????A??'J??????LT7?!L8?r??$??z???q? +v??EPv`-? 9??'???#K???P?|-????z??8j??:un?`?y?!??.L?q?y? +?N???'J?$?????????S? +???hB?j???? ?h??????d?g?VR?cG=????Gn?????.?Bl???{????JoV?bv=?f-???[b<;?=????FR??l1???.'??q?R??C??O?_gn3l~???:?f?)I???Z?d=? +b???T????&M)?? ^^??Ti?????{k??v???_n ???f;?b3?????-??3??\??? an?????s;CM??Osv?i4?)????^q??i7p/???$?0_???1`?????q??=(O?aj?W?D??iNGN??v/?:??Q??6???O`??? ?A?_SV??0(??k??????/?3?{?q???e???? +?s?-?@?pl?qbZ??h??? $?D?r?v?PuD-0_?qo???????R?I??N???????b?bW???t?q??mb7L4??ACz?Yd?? ???;???!?iC??g??????e???a?u?????X??Pi\{ ^|???Q?1?????x?k???L??y?,?5+??$0?S??r? +S6=j?U??'L???Z?d??\-i ?-?m{?*??2? +??p???j????v??/c\a0? p????%p?O??C?$,??d?U????4??ga}?? ??_?`????????gA?zt????Cr)????Yp|??|6q?K???a??gQ?\\????q~,??v?0?L-?V-??G??q??l?A?J??w?????}x?' ?C?#!?iG???5 f?mJ?y?????SaF +??\?2?v??-k?????c|???K2P]???=a???I?????.?(?{q???Xr???j]=? ?u?9by??T?x???>?+?3????G~????? ?fQ???n?kuf\??,??Y?wh?}???x?#t8????Z*??B& !???+Q??V???????|47????hR??-??}w????)????"?KtL?^gc?p?>??d??+???u +???.?`;g2??59LIqy=???9??W?o?Y????y????'7??"?p???R?S??`)w????#B????5??`??? +????g??;?W?!????????G??k,?>?-???X???M??z??r???????????#???v?K??s??b?7Vw???L???s????????v,??,??d]??t???&~??P??=,??c?co???q?8?:O`???R?1k??!??]??#?k??4?q(w??"?[??Gl}??????4V?R??J??8????????? +?????]?n?HH ???MC??? a???~? ??L??!??????? P???}\?u?]?|??Ek?r??q???e??ao????W??+????????-l????15??????P??O.????;!g96???: +b???e9Mw?q?j?&?"|z(?`?$ ????????????v?:""q???m?S~D?bhB_x?7#q?????6?$u?H\+1z?????!p|?\???%?mkE??A?F?u^#q?`?(???&?ZF?:,c?????T???d?>????9 ?h???$???T?d :?%?t~?p?*?%?n`[???J ,t???G????? +J/E?^ +40?Kq??8????Sz)? ?r???Qj?x)P?W/???T?m???3??3?z)?.(??^ ++?J??^ +????B?R??#?e4????R?k +?[?X??;"Oxx)?,t??Kq??w?R????^?{?!?z??k???pLz)l??o^??A??)?s ?J???JA??3)??j???M~T????????^ +??Hz)@??^ +??KQ?`???@?RX??D/???R??P?????;??m?????H?7??`?3??w?R?3?????G??x?? *?R?M???y??n??h??5:??K????cV\?-??C+W?R)? ?Nj?U_B?z)????1I5"?>??% *_???x?D???Y"?o*;T?J? nS??B?m ???7ben??j??"\3}??w5. ????;??? 3=yq???{?9J???C~z???]V?#*?>??~???|??!?? +???<&*0???X?v?j?k&T? ??X????????J??X?%?{??? h`f,?h?F70??v????n-~???Zj?|??! ????? ?`X}M? l??/?q?O?1_???? ?7?????B|U??? ?X??]? ?=?u??X[??g]?Qrv??);>X?5?'?t|`?Oq~r???1???V?gr5"A?D?9??Y.?88"?h???@??-c21??*?????"P?^????2??[??? ???? j%???m/?;??+?JE?????J??Dk???v?? ?TQ LF?py?s?&??6?G?C???q?`?/5??,??? ?????t??????D=D???7?? ,??~e`9?+???2ugV;L??? D???????9l???,U???:pys???H)???X?n?T,??j??>??W????? ?? c??cS????U?X?" `T??Lh;????$????SE??Z???s?w +?`Y????l?)X??`? \L??Yf??a?02??-K??)q1 ?????P?????+???(|???yt?z?)??d????q?p?D?Ur,??*O3?*?~?,??????S"\Q?o???f?k?(7???????*? +pE??:???W???9T?N??+???c8??o????(?lA???????+?8?qlm]*(,O?c? +f?A??|;?=??)???Fe??z? ?~9?6+)??????0?X?Zk???j???J???;???p???}w0? ,??o?$=?lR??d?;?Vy?Wu}??F????A?9?L?7?<????D??'???9wq1???}q??;???-t?!5-??????@????3???????jtZ +b}??j?Q????v.???t?"pu};?}??d??EP???=a?z:??R%{???-??~Hq??d??????????:??-????9}_ZC?Y|i?I_Zkx????8???@?8#/?/pa??x?`?j????TQ ?/2T??????`?V???Q??4T?^???????{? ???U,????????/|???9????????^???R?W s?????/G????98??}oV?? ??+?a?? +sx`?? s?? ?#?tmA ?%^????qI;???K???D^?[??G#i?Y?M?;??gz??P???TN`^;??d???_?b}????4??f?YMsa?inU?\?????T?????????*?U???(?l?%?E?????'7??sT?????YH?ms+??[fXl????9??;???b???"??^t???U??s??uW????d??9B????e?&3??2????T5 ???+???2??un-,??????a~\??T????~??????2????F???q?e?F??????????m?3?D?\?b??z5??k??sr??B5?mL?t%VkW9~_%6?l?c?????tMZ;bhh??F83????{??.????~?????k?_?j?W??S???}>?>????m?yW??H????:???_a?c+D????????n?q)fR?p1?? ????~ ?z?F???P????u?#Q???P??op?j$?]???<]!Nl? Q?C????m?????a??e#???D?~??1??F????G???^??"???n??Y??a?(,?%??????,??>?f???Xf,y????M?/l?h?Wp???5?1LD;?Q?+gA?????V???????????s.?=c?-? ?i$??H???)?? -s????j???c???????C?9??RH8?^/^?Y?? _?m?e?XV??p^?#r8f???\????I?},}?%??/?.G?ZX??y? r?&9Jn???o?6??_??6?R-]L&s? &S?c? ?4??F "D???A??1F??c5????6???Q0v?na??6u*?i??j?\Y??H???? ?-????9 +n?%7QYm?f#???uB???"x???h,??L8??1?i? JDA????Y????^?fvahi?e???u]?h8??sc????S5?:????p?-1d?hA?}??(?b??!1??C??:?|????e????Q?!q?Z 2a?F`4?hA??>?T>?2?(Z????>???]0v5}?????U????oq?? +?Y??C?????G?w?B; F????{h??C_?!?V ?3_{H9/1?ujgk? ?<??F ?D???Q??1J??{=?:6????p?\?????r?E??:??6?(???vU?J??V0?_x ???>??s?9J????????>??????t?E??+???]e???M4Z!?? ?B??1?????????o.\??s?u??!??>?9??L?9?pN,0??l???}8?(?{??)??=d+x?s??????G??9t??g??????J??P`???Q"?Z?(D?????z=???}!??V?T??V&??UB?I?-S??Y??8Q?*????Yu??U??v?2?Ye?T??7pZ??4??G0?U????a?iV??P?? +.f?0a???0y??0?4?0?4?k??D???HJ?(??>J'?{)???i??,iT9????J??#?e??[???Y?=NDa???L???? ?q??;-? .?????a???4.??>?Pl@?<'Md?F??,???2nui ??{?[]L?????h?Y? +??U?X?\??8??v??? g?J?j?????T?V??` ???????\?? ??@??t???N2? ???o?hi???????*Zyn?????i7?R??q%Q?????]??/?7a???????0?t????^?>?-#o?M????+?_>??}??D?B}RqAK??I?^??em??s??1n??v?)???V.????A?pN?1rP0?v????vS??{`????M'?e?/L????{5??D???????????jo???V????V????? 8?z??>g???F??(? *???k???t??t???9??h?????]$?4???)??????q?????^_sW{?+\?u??R|p?K?MoA??]$o? ??}??;ru|??>?_???-?F?}???AH??1:????? 8?????i?? Z?W????? ?W?P{????[??*?q???*a?Z`????X7???A??c??1????Q?T8??H? ??1??1H?s??D????HBi NI?S?c-????? ?W?P{????W??+?q???*???0??h??]o? ??1H???:??????????i??Y?????q8?O`????w???A8-}?N????J??BHwUzS??a +?jE?u?W?LH???WqL?;??(J???0????a?wWq?c??p?K????_?W_???(=?9??AZr???t?m????s??7B??9??????q x?p;????B?ct?f?jU?#??+Gi??3???T?? (???4???T??T?d?1??h???}?|?e?Q??X??u}?????c\?*???.???j???\Y?t?F???sb?i??{ v?W?8??] ?u?B???)?q?E??/??F RuKR?}??c??,?yF?Ct??A??d???U?????c\??UwU7???agW?????%???-?y?g?7@???#??;?u????LS?uKR?cR?c??4??F "D???A??1F??c5????rU?1???????|???s?k??Y ?????????sw?????G(???BU?/??F Rv??:?;H?r???cF;(???T B?? ???????D???O }?Q???B??D?G?B?t?W?0 ??V????cX2??"8??_ ???%]y ??Zm????)j{?a??0??;??b"G?s??qv+f?_L??3??tm?&,"??Xj?0??y??W?"d?gW?y?1L{??9?J??Jf?B?c? s?b????i?F??L??b???DQ2??u???AKN????1A?+?????k???'?7 +?????k?)????A?Q8??? #.???&?N@??? ???.???I??`??.}??m^R`7??+Gi??eT??yI?_?? ? B?BW 1]A? ?i$??D??#H??-c????j????X??/??3-??/?Yn)??H??$C???9f??m????O?x???| ?:s?*???8?)? ?D ?C(}??!F?[?e??g???yjA??>?V1 +Q3F??~?G??({??_W?j|???I?p??Y?-'g???M}??3Z?F??1 +m??vH?#???-??o?????-#?[N>??c??D?"?R? D??h?????r??W??_u7|?/?2r?q??9+???c?????7???Qh?(?Cr}|???_?]?-???}?m??p??Gp?#1?i? JDA????tj???e]? +?E??k??a?c?m$? ?I?U?pU?{f d??????:?=??????c%?{(Z%???U?B??Q???Q?+OU?9y?? ??,??c?*f?wnM??Aq?????PQ3??i?????&j??}???b^M?$????Vi~?y5????y?`?#q???O????????? _??W???????P????iE??,3??y??:gXW?u_??|?a]? ??h???}?|?e?Q??X??u}p??????xz?????D??b?<2?? \??9???^?[?L??>??\?? ????????;6n???e??e:e???b??b? ??IF "Btd?A??1D'?{!?q??????Y? ??Sr??V?3nz9O%?S+^?D ????9;GA??Qrk?<|????_?:1?? ???L??L?d?>??h???}?|?e?Q??X??u}?y??q??EZt???+??r?q???*??W`t??-?w?1w????c??(??G?d???e??e3???Q??v}@?'a???????,o???kP?ov??|????g???????????l{??h???S?????o???7?2}4???Z?????????hx?b?:?>??D??=f??1??"???7?:?vx????(?J????mx????3?XJw ????Dz??b??a???????:???R?xu??o?}V.?!q????????: +>??OK??h?????}"????=?kF???7??6 ?'?<`???????8O?7???V???????N?z8???/?Xg7????aO???????N????? ????D ????G?:???????e?????~??i?A???????o?}??C_?????l???uc]~kbA?V????'???7+???????? ??bsg?}????}"??g???~?T?{????:??????Zz?????zJ?5?f?.??Z?V?EiU?-??|??*[so????y?Q???K???=??????2??xj?;?O`?U?A?){B?Y??7 ?? `??3?0??E?sl?[???jR?b??n=?U0E]??9?3?j????j7|??G1???}????e???4?E??/?$??S?!???? ?=???p?e?????8? +Fu??: ????4?BQ 4y.??v?0'L??????0?,' ????J\??h???'4????????6??|?????????hLx?I?????"???N?ER?H?s?K???G?^????T??/,?@B ?1????????V l6L??@?p?eZ ~Ba?a?????_??9:u?W?,s??~?c???s?#l?s????0?'c?????8X ?~v?,???~????Tt[m?&??$????%?:?K?X???m?~??^nc;????????8???????L?T?V?v??I?M?nu8?X 7^??z?????y???? 28?u?Owrb?'??[M??l?'L?bT?v???:?%???????01|?-?AVE???>??t?5`??0m???? ??>????O=0???w??h?????????w???6????7?????7 .??e?????x?h????C??9??3u??:?=P????\ ???6/6 ?m_????2*]?[@??l`9????M _-???h %??6?ab???X?? Lq\H?'?????l?,?????/?)?&??? O???l??^????k???)=?"???i??M??d?x???9?Dy? ??????.m???s?????`?O?v;?-lF>'=?X?/??l??^m?$???$?B?????H|?wC?LL|??G????|??w7m"Bj?Z????????,lLr?????n=????W?rPD?Q?)d??s ??????NB?oF??k?.??l?9?oN??[??"k&}`????o?????yw??&g???a)7???=???+??q?9???|)???cJIs???+p'-c????-??q?\??[?1?? ??y????C?5????2R{???AO?????$???P?? F?b|??`_T#s??;W~>0.??G?cP?0?oc?x?fQ?r???ljT%?????;?c\???.<X???:?Q?~??rb?/.W??9)r?2?>??r?U?'???????l-? =}?4?|??[n.????????ji='?8=?J?????>???31??}_8B?N1?0=? D?;X$?)??????0??2????'??mb?? o?3?S???? +zo?G?b?^??b????rnJ??D'?YB?+??c??j~?|???X???8??? ~?Z??`=??mGZ?c?R??1??.?y????$ +???k????j??qKV????n?f]? ??}????????S1,~r?&D????!???!?g? ?-??&6?e ?\w?????4???Tf?????Lu?V??J??4(?????z?(?? v???????????l]T????.?6??nKp5??S??8_???3???/p{=@?M???u? *g|?"????]??9p??!6?2????e?b?D??"?[|s?[I??Z2L????;??;?Y?????l? +???Q?y??9p ?>6?Q7???g{???:4????????S??1.??W?1k +?I????&?????*?Q???j??c?8?r???????u???????qO??H?e_?^?7c?ur??Q????? ?\]Hz?'??9?rt[rF6????E?xE=?E?4M?_s??5?~?\y??}?v+????S|??? ?)? ?????p?P???[7S????~1?IC@???4???s?? 1??8??|0???%?K?:? ?;??&1?NC??Q?N?a?-%??o:?)??l?K?Eo? /? #e??&#???|q??????j??#??+????2U? +/91???Q?eV+pY?.v????b?NU???'oa?N?K??*?|U??r5?Yx5?#??P11t?b?%{??U0]???j-D?L???cn??.???iI???lb? +?JH?!'?(?1M?t?Qa??????? ?Q???]??i;???&q?? +?M????Ed=l(M??8??/?Eso????{??b???????Nc?a[n.??1??i??6%????|?N????4\????????n? 3??i???NZ?l??Q&.????nw ? ????v[?>??*w??;?m?e? c?A ?1???a?5I?@???r??r?????)7????}k{LD??T ??)?n???@??Q????t{7?xS*???E(SfX\S?:F?L???? bT?k'gA?+^???pA??wqmG?0??)!M?????????q%?c[????O7 ??????(?/??+?endstream +endobj +632 0 obj +<< +/Producer (ESP Ghostscript 815.02) +/CreationDate (D:20060723202022) +/ModDate (D:20060723202022) +/Title () +/Creator (inkscape 0.43) +/Author (cfbolzcfbolz cfbolz) +>> +endobj +633 0 obj +<< +/Type /ExtGState +/OPM 1 +>> +endobj +634 0 obj +83385 +endobj +630 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [105.602 750.9806 118.6329 766.9208] +/Subtype /Link +/A << /S /GoTo /D (page.47) >> +>> endobj +629 0 obj << +/D [627 0 R /XYZ 74.4095 738.0292 null] +>> endobj +631 0 obj << +/D [627 0 R /XYZ 117.7423 210.6604 null] +>> endobj +626 0 obj << +/Font << /F26 180 0 R /F31 192 0 R >> +/XObject << /Im1 171 0 R /Im3 618 0 R >> +/ProcSet [ /PDF /Text /ImageC /ImageI ] +>> endobj +637 0 obj << +/Length 3305 +/Filter /FlateDecode +>> +stream +x??ZI???????[?Uj?$?-9Yr??.?d{?,?lN7-.?)i???6? ?c??????'???R?? ?w??? ??]???3?^??"s?BW????w?F?.???I???e???Mr?C??~??????,?~R?????t??-???????????c?4US??S??*???4??{C?w???\?r0????}?? +w??'?XD?;???u???Z?B?z?????~?V$~?g?.?c?NT?{G??Yd~u?0?\2?b???:?????OT???_?~???YoF?Y_??$C?xc_xO??2???f?:V?RA?&~?e'?}???S?$?????.?9???%~?? w??w???~???????P?.s????H??????????g??+????N???1lT(??ow???T?LG??%I????I'?a*?2????(?a?}:?h??@jt5?7??????}{??G?}E??L?pe?d?'???\k??vd>????G? ??EO????RG%??WL(?? r?%?GLN?y??>??m?Zm?*?|pW?? ? ??tL?GZ{u{m???Z?0a????n??4?:(?=j U?????`P?L??????d?4+?I??i?WZ~?D?^r?8}!?weu?Aa????3??X??????Z=N??2?%Ktx,(??????0??-??+??f????????? ????Z??\?!C 6???3:?E????(??a?CD??f?3?n??V??????*a?Pl?V??'????n2??f?c????!??p???F???}`???mdcG@!r?????!??< +??b??Gv?r???O???f? +????^?m??C?0w??MSI??Hd??^?K?|2V????????],tW?a ?@??D?i 7?a?d+? ?c?????9?Q?????Q????M?\??)?????;?H ?o?9?L?$?????L???z???fh?_k0?h????B?S?|ga?t?0??4??.??c??q?CSD?4??????2pc?e?q??Mo??L^?>????l?e$?h9>?4?".??`???P?? ((???'ddc??A??as??P3?+????(???(`8????m????'?|6??^?RD??$Rl??????jd/i?*??? 29?????R??????42N?R?9? ?c#t*?{???X?L?????$qJ???>?=???a???\i1??F*??t??7#?T?\?b`1R????fw!????X?w?/%?m??\P? ??~*)^X|*?\??aO??!?t?.?6??R xn$???a?????"??8N??g3?[G??L?q????3????dX???e ?y??g????^??1W ?eTBaW?f??a?T0?@?B.?? ???????????? 8@???~? !??N?a& C???0??0M?/G?????x????6M?[ ??KR?- ?? +R??? +??)??d?????? ??????????B$d????M\ ?_???Y?? Rj??.?D??!&\0ymX:?4??w??W?Z?? +?T?SI?=?i??.(??&Y????a????`XfeT???W!???%j?|?c\A^{?VY?d?!???,h?d%l@?x?;)??@???z???u?a?b?N&??b?????_??i,Et +??????Y?? ?T? ?e"????g1?D?G?-:i`OU?ud?e231?F?c??XX?\?F?????? ??????i r?=b???? ???F?K?g?zN??kYH?E?5H?????%?H&/????W?????^J??!?R?)???????=??DC2????8.?bk??P?G????6???C"??@$t?<1?/Y&7 $:@E?????y ??B??O??????K? _2???|??????Z????\K}?E?k1 ??A????Iu?? yU???|?E?X??ex(??r???K?jT?n x????????1-?' (?e3*q?Q?????N?O????q????Kz(?F? ???B?3??rr??????0??,1v? +?????z?[?^???$????$I?,u??[?,H???H7EaD????%????r?????????N????z?> endobj +639 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [105.602 750.9806 118.6329 766.9208] +/Subtype /Link +/A << /S /GoTo /D (page.47) >> +>> endobj +638 0 obj << +/D [636 0 R /XYZ 74.4095 738.0292 null] +>> endobj +640 0 obj << +/D [636 0 R /XYZ 74.4095 630.521 null] +>> endobj +154 0 obj << +/D [636 0 R /XYZ 74.4095 611.5368 null] +>> endobj +635 0 obj << +/Font << /F26 180 0 R /F31 192 0 R >> +/XObject << /Im1 171 0 R >> +/ProcSet [ /PDF /Text /ImageC /ImageI ] +>> endobj +644 0 obj << +/Length 2985 +/Filter /FlateDecode +>> +stream +x??\[o?:~????B*V??R???6H??9MN_?>??bk+K>??4??w??n?%?nla?%r8?f?q8??????L "?P???B6???l u????????????????QA?????~x? +??!??B???s?t?4wY?9oQA ??g?<"?- +#?????.??9????W[:{S\?q1????????r?2$T?3???f+??? ?S???~-??@???> ?%???E??Sk?s?d |??s??M???(????C?mR??????0x???1?qYa???F????*P??$X?I"?f??????K%?6???e???e?X???qV???s?? mq?xa??V,???4[YSL????????I??RbG??2???0?(?U?'X??,? +?? ??l?(?*????m?+????4?"????v?z???6?>[aD?"?*?-7?z??b?o(4.?7???6??U??????L+Q?Vo??Q??z??4? +??y?Pc\?j???=(??v????? ?HIBt( ?6??]?[5?=?????G?&?y7?k??{???1??:C]???!??V++b??E?s D?I8[S???Qe?7?}f?????@??f7?tZx2%?????`?0?????6?!:J? +??@??E???? ??+?C????~=???A????+l' +pegz??f??? ???j??????y)?_??'x)9a?f?????0%;?&??(???=?E? ?r;?CQ=??u?u?Nc??A???J???vMf?y??K??? ?aL???mp;L?????5 +?%Wc?Wi?7S?h?????VOY2B???8o?0?AOP?)Z???*?+??l??F?Wa4??dV?5?x????L???"??K??U7??!6\?c???=?v??Lg?yGi???6? ?1?b??f?f?0{::'c?(??=]???o??]???AM[?Vi???t?R??u???I????5??:?s??/??g?]???id??J?k?u????[ ?L~????????*??0????;o^???1~"????? 1??\ ???m2R?"lI??=,?Q-.?,???a??X ? ?Y??s????SIL?E? ?2?? _?E?o?O???y?y?T????[u???NP?p(??y>?D?????):?????6?r?VI?L??Wk?)????7??J????f?j,Q?????? ??B?1O? 3e??6?2__?)?????G????"??-??????>p?8??s?YGj??1=????^?????du???H=??t?o?kW?`?T???3?.?@G>??? ????n???w:??;K`?/EO,?0??c??&[G?dsaK?D?k%p??*5??? +??Ws7?h??s `}^A?Ge?l????_%P0????~g????????????7{?ToW??'??yS* g??b????2??? []??E?Q?-??0_[?"??M????]??o??%?~?w?p??j?q?~??( B?1~*????5?vJ0D????"?8??t=??=o?y?\????\:?x????;????????v???j???|X?;????c????~O???_eY?????~???a????D?]?????1? :?pL??QK?XR?? ??w?ax??n?X<??}?@???????t??:?"???VT????\?v[??????d?<????Q?-y??a ?J8Y????[??v??9Z???v,?x{?M??Q.e????Q??M????????;@?{(g? ^$X???? V}?1?e?i?1?b?[?Ic+??^???,?????B????4x?v??=~?????m?????H????*???@?=????/?KV?endstream +endobj +643 0 obj << +/Type /Page +/Contents 644 0 R +/Resources 642 0 R +/MediaBox [0 0 595.2757 841.8898] +/Parent 641 0 R +/Annots [ 646 0 R 647 0 R ] +>> endobj +646 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [105.602 750.9806 118.6329 766.9208] +/Subtype /Link +/A << /S /GoTo /D (page.47) >> +>> endobj +647 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 0] +/Rect [113.7426 661.2123 139.9839 670.7465] +/Subtype /Link +/A << /S /GoTo /D (cite.VMC) >> +>> endobj +645 0 obj << +/D [643 0 R /XYZ 74.4095 738.0292 null] +>> endobj +648 0 obj << +/D [643 0 R /XYZ 74.4095 648.2908 null] +>> endobj +158 0 obj << +/D [643 0 R /XYZ 74.4095 629.2174 null] +>> endobj +649 0 obj << +/D [643 0 R /XYZ 74.4095 574.8404 null] +>> endobj +162 0 obj << +/D [643 0 R /XYZ 74.4095 557.1294 null] +>> endobj +650 0 obj << +/D [643 0 R /XYZ 74.4095 518.9864 null] +>> endobj +642 0 obj << +/Font << /F26 180 0 R /F31 192 0 R >> +/XObject << /Im1 171 0 R >> +/ProcSet [ /PDF /Text /ImageC /ImageI ] +>> endobj +653 0 obj << +/Length 3076 +/Filter /FlateDecode +>> +stream +x??[?s?6?_???f"?${s??q??no:Mh??XS?jRq????HQ?H?.|?x21I`?X`?X`!6????|I$ ?????"J e??U3G??5 ????L???|??V??'Zh?Y????????7???????????*????????#??n?(? B??j????G?(??Ei???P????m?h]??|?F????F???&???? eH??????AGS????0P?GT a!oq ?&R?@]Ivp}????5MwM???h???'A????????;??qEB??n^?^??n?? +?L? A?:?? ?Vx???*?0??E??d?N?????%?iq?6a?{??0?!???{3?W?:'>????| +???V??Ub??|K/?/_!?????? tU?ZT?eul???+?'9N?q??JY?e?ak4l???>n?|?^??I??"#?m??????Yi?'^?5????x>L?d????!?? +??C??? ???J??\?t???o0?????{[H??????Z????X???? ?L!Na??En?E)??k?~?-?i?????|*?da V%?Ko????b???*?J??t?u?????:??????????????S5/?n??X?^1????3)^??xXh?Y????8J(????o??K???=F??gqk? &??F +???????????6l??*-v?A?W?*?EDG?????E?????,?????"pS)??p?2"??f???`i? +,?"6`i?x?;n/- h0^w? @3???4??????rE?Ih;?/???????:vz%???%? 3????a? ??;.???]B??P??e`?s ??????U?? {???hry???4#*`A? ?????xg?mv}???4???A?y??9??l?t 2????8????!,?????%<3????[e@,?`~L??4y???????Ilw8???%??D;?? ?`Tu??>?????[-m?n?4TV-????????Z+??]Z????r{?=s??uk????{?[??/c?y?Kr??G?S??b???4?(~??????` +??8(?[L;??)?????so????b??CBaD?Fh??t#?v??dsw??(??x?TN????]^^]5????H?G?-???TV????.z???qK?[=??|?????6?M? ?Y?5j???<9??????X&v}??K?X??&G????9Z??r??@p?6H%AUE2_?w??w IZ?w???f?????1?f???`q???EY}??F?A??\???M|?(?E?????(?????G?}??t???Z???M?*??????qo!?CXF??q???BW???5???w??(?v??<@9?#sip?d??Q\????@?^???k?.??4:?a??PbkQV???X[X?Y?;`f??f9???b???????,????Y?q?L! (m????u??du`M?W)?jn??I_????O??????]Xb^n?7?Xm?t??1r?b???? X????2?w^?Y? ? ?3U?f?t???Yp??*?42_ e????- +?M??? >????d?`???>?>?????a?????O?? +y??^??+??qz.?v? ????? ?l??s?.?qy??????? ??X4??v???-?(??????};-R? R? ??-????g??V???K?{??x^???"??[?~NW?*j?Wu +.-l?k? M=ki??? ?s? +(TE?W?F?%??c?kc?t?o?]?d??>??.???z/?\??? ?U???!B?ZT=??,???z??m @????????5?E`c ?????U:-\?EMM??(KL???)l^??ny? G??R?f{tN????s???\5??E?3????g]?cl???}????S??M???> endobj +655 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [105.602 750.9806 118.6329 766.9208] +/Subtype /Link +/A << /S /GoTo /D (page.47) >> +>> endobj +660 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 1] +/Rect [277.226 152.52 494.4585 164.0168] +/Subtype/Link/A<> +>> endobj +662 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 1] +/Rect [165.5668 88.7591 278.0837 100.2559] +/Subtype/Link/A<> +>> endobj +654 0 obj << +/D [652 0 R /XYZ 74.4095 738.0292 null] +>> endobj +656 0 obj << +/D [652 0 R /XYZ 74.4095 540.3704 null] +>> endobj +166 0 obj << +/D [652 0 R /XYZ 74.4095 540.3704 null] +>> endobj +657 0 obj << +/D [652 0 R /XYZ 74.4095 498.1697 null] +>> endobj +658 0 obj << +/D [652 0 R /XYZ 74.4095 336.7171 null] +>> endobj +480 0 obj << +/D [652 0 R /XYZ 74.4095 330.9259 null] +>> endobj +659 0 obj << +/D [652 0 R /XYZ 74.4095 299.0455 null] +>> endobj +540 0 obj << +/D [652 0 R /XYZ 74.4095 279.1202 null] +>> endobj +579 0 obj << +/D [652 0 R /XYZ 74.4095 247.2398 null] +>> endobj +493 0 obj << +/D [652 0 R /XYZ 74.4095 215.3593 null] +>> endobj +541 0 obj << +/D [652 0 R /XYZ 74.4095 147.6134 null] +>> endobj +661 0 obj << +/D [652 0 R /XYZ 74.4095 115.7329 null] +>> endobj +651 0 obj << +/Font << /F26 180 0 R /F31 192 0 R /F34 291 0 R >> +/XObject << /Im1 171 0 R >> +/ProcSet [ /PDF /Text /ImageC /ImageI ] +>> endobj +665 0 obj << +/Length 3318 +/Filter /FlateDecode +>> +stream +x??ko?6?{~??2n??"???C?8?d?M?d????A?[[?F????? ??h[??C ?8C9???\???P2??~/s???MW'no???qi`c????^zA?K&d???{??D??A?|?an??s?~??x??\?!???B??8)??{?s????8N^??2]f???>????&y?L????"'?Y?N?U??????R?^???p{.X,?P??,C?xF???c}-???#??>?????:?8? 5??^???u??}?9?=?????I???>?V?n?F?f?,???/??d?M??6???d?????Uy?c???C8i$?xq????f??`xa??{??n??Q[????Z????$??????BO?}\????a|??V? V?u???.???(?s?&=???b??? [???????m?O +????c????q\`???#??:8n?????~w????I???M?"+?H?P}9????"??5r[9??L??+???+?H???? &????H'Z ????oP?6?????,????????%x?@F??(? ?h?!??"g???l^0?j8??7e??(Yr????9 ??NR? ?? ?+??H?f???.q4??????????????:?a=5??3??"8???)^o?F??? ???u???VH9H????/??Y G ?i:?*??eZ????U???X???v??q??aD V????`|?qQ5?6????????(v[??s?????Sm?`??Z?r??[?n+a??BO?U?Yb=???v]?l?8??\0p???4ja?|??m??? ?z?a$Z?????x?A??}????Z????I??t?j??E9??j?E?R?=??ji????#??,?#? +?7AQw??%?o}?l?v?????s`%??6KzS???N?,?\?y??9P:?$?4??w?R??|???qp?S2??\{Z?8F??E??i?P??;?tUX?0?Hr`z?4???!@>????M???s?#????,K+K??tQ??d?l???tku???7??h?l9??????X?e^c)??\={'?F???[??E??J????,M?? ???[j??A C$?t?Q???????7????3??l?6V?!C ?0?????"!+???C4N3?s?sU??i?s??[? +O?k!s>?h??r ?\????.?|?RS\?.2 =3+?)?DO>h????p??/louE>K +og??}??????}?Ln?f>BY?.U? :?Y?Tgs??$?hQQK_??!???B?T ???z?CI????????.?p:??e?\??????>eK??tko???&????/???RI?Y???j]F?c+dLY?#a ,??a?m?TG?????,dV??V?s?z?tQ??P??|??s7?V?*i?t3?U 2?6?`?&z?????(??J???x?~p{ mS6??e?H6. g?[????\??l?_ ??S?C??\?4?v????????B?J?Z????D???S????z??T??U?U,M??;?h? +?#?? ???e2?`???3?y?Y{.?;y????b??#?eau??"??~???.??e?nM/?(????????????A??o +???? ????i?E:??&/l????N? +?YN???5? ?{?0>??u?@?|)?:q?F??????eBM?'?I?iE?:4?????v%s?R=?X?6X$??E????Z????.h??x????8??} ??:???,@*_J?=?P???? }_l?u??A?Irt???O7???;?`???0$??4?5??Hk???Cw:S?{eZ?]?j????y?1??#?%???k,%?????u?7?N????I?B?????d? ?>??j@?<$/????6???s?q???H???j??? ??????fM??V???b?5h??????+??? ??G:?`???D?????b??[?p?&m??6x????D@??X?b???{?K9?'=[??endstream +endobj +664 0 obj << +/Type /Page +/Contents 665 0 R +/Resources 663 0 R +/MediaBox [0 0 595.2757 841.8898] +/Parent 641 0 R +/Annots [ 667 0 R 668 0 R 669 0 R 670 0 R ] +>> endobj +667 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [105.602 750.9806 118.6329 766.9208] +/Subtype /Link +/A << /S /GoTo /D (page.47) >> +>> endobj +668 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 1] +/Rect [165.5668 603.4589 521.8625 614.9557] +/Subtype/Link/A<> +>> endobj +669 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 1] +/Rect [165.5668 591.7229 291.384 603.0005] +/Subtype/Link/A<> +>> endobj +670 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 1] +/Rect [165.5668 308.7839 429.0856 320.0615] +/Subtype/Link/A<> +>> endobj +666 0 obj << +/D [664 0 R /XYZ 74.4095 738.0292 null] +>> endobj +550 0 obj << +/D [664 0 R /XYZ 74.4095 722.0889 null] +>> endobj +262 0 obj << +/D [664 0 R /XYZ 74.4095 702.1637 null] +>> endobj +516 0 obj << +/D [664 0 R /XYZ 74.4095 682.2384 null] +>> endobj +517 0 obj << +/D [664 0 R /XYZ 74.4095 662.3131 null] +>> endobj +617 0 obj << +/D [664 0 R /XYZ 74.4095 642.3878 null] +>> endobj +593 0 obj << +/D [664 0 R /XYZ 74.4095 586.597 null] +>> endobj +518 0 obj << +/D [664 0 R /XYZ 74.4095 542.7614 null] +>> endobj +542 0 obj << +/D [664 0 R /XYZ 74.4095 510.881 null] +>> endobj +580 0 obj << +/D [664 0 R /XYZ 74.4095 467.0454 null] +>> endobj +581 0 obj << +/D [664 0 R /XYZ 74.4095 435.1649 null] +>> endobj +595 0 obj << +/D [664 0 R /XYZ 74.4095 403.2845 null] +>> endobj +476 0 obj << +/D [664 0 R /XYZ 74.4095 335.5385 null] +>> endobj +494 0 obj << +/D [664 0 R /XYZ 74.4095 303.6581 null] +>> endobj +578 0 obj << +/D [664 0 R /XYZ 74.4095 247.8673 null] +>> endobj +671 0 obj << +/D [664 0 R /XYZ 74.4095 215.9868 null] +>> endobj +322 0 obj << +/D [664 0 R /XYZ 74.4095 184.1064 null] +>> endobj +663 0 obj << +/Font << /F26 180 0 R /F31 192 0 R /F34 291 0 R >> +/XObject << /Im1 171 0 R >> +/ProcSet [ /PDF /Text /ImageC /ImageI ] +>> endobj +674 0 obj << +/Length 3429 +/Filter /FlateDecode +>> +stream +x??Zms?6??_?o?fB? ?t?>?v;?b?r.?i:??%^(R5???_?X??(??d?bXQ?SY;D?9???V???@?t?} ?????};??+z??W??z!w?O?$?7?`?S???? ????o??-???????C[]b?????"??"\?0pD9??J?A:$qn???? 1} |9l?*2~??w????_?????????Y?hL??q?????0WW:?[??C3u??x\???n?!??h?:????\??1?????`*??=?3????W??t?U?I?=?AY?SW%??]A?? I?%,????i?=???zJ ?WvP??M??9??0?,?u\kW+G??8????p?Q?A???Zc?b???????*???4??.?`?JYg52?5??V?%B??? ??}F&?? >0{I?s`?V:&E????;?E?7?5?RtnFd????a?.@????J?P?3 ???9X??????v???u??? ????? $???*?,??????. (t?X??JY???tp??6??u? ol??t#??????Ou!mR?~p ?'`HE?n??p??>E'-?9q??R9??+?T'??#?&A??t???F????X?????{????]??!??F?j??P????O?!?*??1?J?????<)"@??j ?NQ?????u?-?l??=?????659(?A?? +q???a|?W[$????????fM8?]????A???G???u?2?I?}???^ST?c??P???w?3ih?j???p?????????&????R???MT?h???@w???G?0?^?*Z?????m?=??n +??N????N?????^???,???? 3???]?J??q6*??6?y???4??L?J?7?s??PX??hq??N2N????A??????^?O?7+??????YC??E??^ep7????^???????L}??"]??????im?y??c????@??V?/???hZ??y??8&_??@U??? l?Q????]?x "????dh?:K?\??(T??:???&???"?=?qpVWi??c$P???q????C?yR?{D&?)?y?P??6K;pL??&??_??1?W ??z???F??x??c??E???.?tJS$?z????????X???L?c????r????X??L???y\o???????1??u?;lUiJX?6?q???^I??3] ?)K=?mH? ??????w???? ???(j%??NpRhm2??>f?R ?????Sey19UW??^s;?wK?A???f?+?A?????_\b+?r??<.?mF"?.P? :?? ???f|?????w\?????Mu??4T??|W????R??]?im??? 4???^Ks??X????zQ??feo0+????P???+?P???S??V???*????c5???T}??"c~???gh-???B!??????:[?m at w?{????P???P????|?()??e??;b?Wo?U???"&??????7???8??m?Tz(34????k?K???$??0??????I????1?????k+??????4U??????e????{?.??r?e?&???]??????????????/???????.?P??[|??x`???`????h???c???endstream +endobj +673 0 obj << +/Type /Page +/Contents 674 0 R +/Resources 672 0 R +/MediaBox [0 0 595.2757 841.8898] +/Parent 641 0 R +/Annots [ 675 0 R 677 0 R 678 0 R 680 0 R 681 0 R 682 0 R 683 0 R 684 0 R ] +>> endobj +675 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [105.602 750.9806 118.6329 766.9208] +/Subtype /Link +/A << /S /GoTo /D (page.47) >> +>> endobj +677 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 1] +/Rect [308.0107 631.3543 435.6409 642.8511] +/Subtype/Link/A<> +>> endobj +678 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 1] +/Rect [282.2871 563.6083 488.4812 575.1051] +/Subtype/Link/A<> +>> endobj +680 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 1] +/Rect [290.8748 495.8624 486.0304 507.3592] +/Subtype/Link/A<> +>> endobj +681 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 1] +/Rect [327.8158 420.3655 458.6733 431.6431] +/Subtype/Link/A<> +>> endobj +682 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 1] +/Rect [165.5668 400.4402 364.4586 411.7178] +/Subtype/Link/A<> +>> endobj +683 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 1] +/Rect [321.9983 268.9334 467.431 280.211] +/Subtype/Link/A<> +>> endobj +684 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[0 1 1] +/Rect [165.5668 157.1326 551.8148 168.6294] +/Subtype/Link/A<> +>> endobj +197 0 obj << +/D [673 0 R /XYZ 74.4095 738.0292 null] +>> endobj +479 0 obj << +/D [673 0 R /XYZ 74.4095 722.0889 null] +>> endobj +495 0 obj << +/D [673 0 R /XYZ 74.4095 678.2533 null] +>> endobj +676 0 obj << +/D [673 0 R /XYZ 74.4095 646.3729 null] +>> endobj +481 0 obj << +/D [673 0 R /XYZ 74.4095 626.4476 null] +>> endobj +679 0 obj << +/D [673 0 R /XYZ 74.4095 558.7017 null] +>> endobj +474 0 obj << +/D [673 0 R /XYZ 74.4095 490.9557 null] +>> endobj +390 0 obj << +/D [673 0 R /XYZ 74.4095 435.1649 null] +>> endobj +301 0 obj << +/D [673 0 R /XYZ 74.4095 415.2396 null] +>> endobj +563 0 obj << +/D [673 0 R /XYZ 74.4095 395.3144 null] +>> endobj +478 0 obj << +/D [673 0 R /XYZ 74.4095 339.5236 null] +>> endobj +475 0 obj << +/D [673 0 R /XYZ 74.4095 295.688 null] +>> endobj +271 0 obj << +/D [673 0 R /XYZ 74.4095 263.8075 null] +>> endobj +477 0 obj << +/D [673 0 R /XYZ 74.4095 208.0167 null] +>> endobj +672 0 obj << +/Font << /F26 180 0 R /F31 192 0 R /F34 291 0 R >> +/XObject << /Im1 171 0 R >> +/ProcSet [ /PDF /Text /ImageC /ImageI ] +>> endobj +357 0 obj +[170 0 R /Fit] +endobj +685 0 obj << +/Type /Encoding +/Differences [ 0 /.notdef 1/dotaccent/fi/fl/fraction/hungarumlaut/Lslash/lslash/ogonek/ring 10/.notdef 11/breve/minus 13/.notdef 14/Zcaron/zcaron/caron/dotlessi/dotlessj/ff/ffi/ffl/notequal/infinity/lessequal/greaterequal/partialdiff/summation/product/pi/grave/quotesingle/space/exclam/quotedbl/numbersign/dollar/percent/ampersand/quoteright/parenleft/parenright/asterisk/plus/comma/hyphen/period/slash/zero/one/two/three/four/five/six/seven/eight/nine/colon/semicolon/less/equal/greater/question/at/A/B/C/D/E/F/G/H/I/J/K/L/M/N/O/P/Q/R/S/T/U/V/W/X/Y/Z/bracketleft/backslash/bracketright/asciicircum/underscore/quoteleft/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/braceleft/bar/braceright/asciitilde 127/.notdef 128/Euro/integral/quotesinglbase/florin/quotedblbase/ellipsis/dagger/daggerdbl/circumflex/perthousand/Scaron/guilsinglleft/OE/Omega/radical/approxequal 144/.notdef 147/quotedblleft/quotedblright/bullet/endash/emdash/tilde/trademark/scaron/guilsinglright/oe/Delta/lozenge/Ydieresis 160/.notdef 161/exclamdown/cent/sterling/currency/yen/brokenbar/section/dieresis/copyright/ordfeminine/guillemotleft/logicalnot/hyphen/registered/macron/degree/plusminus/twosuperior/threesuperior/acute/mu/paragraph/periodcentered/cedilla/onesuperior/ordmasculine/guillemotright/onequarter/onehalf/threequarters/questiondown/Agrave/Aacute/Acircumflex/Atilde/Adieresis/Aring/AE/Ccedilla/Egrave/Eacute/Ecircumflex/Edieresis/Igrave/Iacute/Icircumflex/Idieresis/Eth/Ntilde/Ograve/Oacute/Ocircumflex/Otilde/Odieresis/multiply/Oslash/Ugrave/Uacute/Ucircumflex/Udieresis/Yacute/Thorn/germandbls/agrave/aacute/acircumflex/atilde/adieresis/aring/ae/ccedilla/egrave/eacute/ecircumflex/edieresis/igrave/iacute/icircumflex/idieresis/eth/ntilde/ograve/oacute/ocircumflex/otilde/odieresis/divide/oslash/ugrave/uacute/ucircumflex/udieresis/yacute/thorn/ydieresis] +>> endobj +611 0 obj << +/Length1 1606 +/Length2 8282 +/Length3 532 +/Length 9134 +/Filter /FlateDecode +>> +stream +x??weP\??-??o?-?]?w??6?H????5? $@???=?K ???[??oK1?t????)? ?q?l???k?-?C?k??rt??O?Z?O at w???k?ZG????p??!i????????????=?d?9q?????? Q??9d??^,????`"?.???3"??p?p???7????vU)4????.???<{?&??I?%??4Z2tP??j?'?K:ry?oB?? +gW?=/??r?v F?5"&?'/???s#?Z???#%?? ?x?r???????&P??j??sR?J?????.X??? ?7???6?Km??????,?{??3H??l????????[?Ep?????si?]??aMS???+?o???"p_??? ?????~>S?#\?e?T +0??)AL?????mNu]N??+?0$'H???Jdq[????Z??Bw??W??B$f?????v?B?)?uu?0??? ??E?p??X??9?T??GG?N????Y?J?{-????i???t?????2?????Iw-?3 ?w"?{?wR??uC?x??????U?"??F??g?6??m??K??^? ??? +?????M??x?X??l???bd9 ??X???J?N?!????M??'7L??T~??X??F|o?a+??1??M?;(???3J?~??????~?&p@?'?????4???^C}??G/X~@?]???{???Q??E?[[????S????0?`????????QT?7?t?=????????C????%m"?????Q ???? E???`????7????;c6C?l??g?K_??o{??????????Xb:d_?b ?(?%??U???\9j>????????2M??????5e??{(??^???{?f6? ]d??l?6W?=kt8[-\R#?????1? A????Y??Q?MN?\A?cn??Z????q?u;????;???m??????????mlo??2$????h?ro?4??H?;'?? X?$??? ?}??i??????????Hn>|?T??e????w?????? S???9??R?????2{3?ZE?? ?1VY???ip?z!??$UM)??"?x}[???????0A??????*o!?g???????? ?SDy ??[??M +>??h ???????????G??r/?s??????x????7??b??%1?v0??8?\#?????????????g??????*q$??????T??????R?R?M ?*??S???|??? Ym???E.jh??[?????[ ?%)?? f9??D~?7??3}???h?.??` +?????Yb??;w4?o0*{'1?B?????P_?n$?o?x$1?{p?0???5>s'T??G?XO??.?1/?U??%EG?,ux??#z??u?0U????y??????A???x?g???????i,??/?du?g????}??j?????yuMw??>?*?AT?si G?Z$j)G??????@???YW2?M*Tn?OuL9???0????????S%$?fRp???7???Ec???9??%cs???????r.3x(????B{?T???e????cI?k9?YCO?>k?\_`*?????(????+T???&|?Cb1????? ?V;e??%> \??a9? ??M???S[o?m??3g??'?XS?9?QD ?????`?H?@]?z?n`?m]?^?????m?m??.}??????N?wR??#\8???c??f&??}??g]???Q?UH??????K+?'y???Gj??=+?B? ?a?c-w?U????? ?ow?>D????????VY??(? +??????o????n?J????+??? *???{7d?}?a??????_???"q??kS??S???`=?aV)??? ???????vs?@??L?c??Q?J????|???\??^??}?H?~(?qx?F?KB??m.???w?T?? ?? W?~?Pn??^???j????K?Bn???????S?`?Z?1?s???c??_459???m?n??^D%?>???)d???/x??r?????W?N???^=?j?????? 9v??@C=?u4??Le???#??? 8 |?!u);????t???F???e2????g??xDbp??|????? e?HL/6?.?{8(r?t9<%??qrJ?0?f???F?V?W??c6vh?????5k?>_UB??e??A~J??=(??oNW7?mfh?q??5KC??I??)???a??G>???o?u??[~U?-??????/?c???h??18P?? ??L??H}~??un?}???? ??Z???Q^?rC?h??G??V`?-n4???$?3?/?????=$}???}??o&j r?>E_4???F5?~? {?9??1?j#o0?|?2+^?/???????*?H^?e? ??+fy?Oc?y?Gb0h??m???21(?????N????>?? +?pJ?/??(?c?O}S^1?n??^????Y???.kM????L?U?7Sg?3??ZjXmq??????V?DT?]5?? ? n?>???????)W4? n?"=}????????0?F??7????nh????????X?-?>EB??8W?S??K +?G s||>?LSt"?p3|?r?V??h'c?r????t0U??????8>P?lh?}4?????H?s?????E?a ?b??yE????????Q?|?????? ???L???~ ??????????uC|??#??th???^?]??/???4??#?lc???zaBsl?i???Bh?x?I???E?ta_Fg??f???u?? ??/????+?%?2Q}??8?B}`?|f/??e???s{??B? +(????e{?#N ???K8??(l?b3??/??|?]/??????Dim?|????b?~?:Q?&,??w??\??.??w??I?h?N???ep?I~?_???? ??F?-t+?j??^c?~?w???ZC?[{?U????????*?uJ?z?=?<]?Y???R_&?L?t,?- ?+?T???-?K??p????W??`J??q +\?? +}x????i???v???_??[W???k?????t?Gk????zq??????WL?+&D4????EYI9D?????%6??z??P??N}'?m????je????!??"?{??n??????? ????S,K???]???????E???2 ??^wPk}?0?B??ID??i??gT?7?????)??.#?j?? R?-Ja?? ?{|>tq??<1???x?G?3?a1 ??J=F +??G??k??dhbH?l?l? 9???\?9'???3{? ? ??????*~?????a??Rm?eQ???n??NB&Lkw?RF?jD?U Z???/Y?Y??2-9%?:h????????`? +??*?C??????p<ZU??+?.?? _??SN? "GU=???????,z???????r???w???d;F???N?rLl?z??????????Q??`???D?6??/?=????????????R? ?Rfl??\??????3?:F?????^????T9?-???c???????? ?????Jv?QJB\?????{? ?}?/QU?i|????? ???jh???U?K?L-??>.K??n??4 ??????iZ??>x?d ^??s??Mt?v>?f??E ??4??n(??n???B?AGx?????g?T??y????* ??f??#???X???i????????*????P???3gE?f?v4Kkd?@/>???Go?~?=?B?a???e?<`??????n?????tL??????0[????e.?\Id?dN?h?o??}}??@??7?X?3#?????~???R?k6?rCT???1U&c?8?+fx? 5? +e??:??& ?Z?aN?;s?[?A?0?n??=?2???!???? ?".?lX??8x?$`X?-??yS??????R<|)??U??Q}?QG?? +?????Cf??[ h????? 7=?)???q?d"lg?&c?U?????cO?V*??K?l??P??+Y?K+^p?g??th????S.?o@??h[? w???@??"?t?E??d @????1z??>???G?H??y?V??sL??D????ww?Z?????}w?? ?U???>h?%?? ??@?"3L?V-?+?4?l)T???K??/?y?p?2?????B?R???????5?p?5u????5?>;?{?? /?'???(?r)[?u"Z/??y??m???.?'??????T+??X0sK??=??Y???????8n?q?_???\?H??$?P???`S_eI?^?? +??,?t,Ud?U!A?-?Q|?????tH,C??H??%,2n]M?^m???/?? ????????o$?!?j})???????lW?R? )Z??%?U/e??? ???V?:&4??`??????[3?t??X?4z?w???t??"????)??k?????>??d +??8???H ?2#????V:???+????7??????:tw?'qWX|.T??;??~,?M??????x\??????`?9???fNvh??l??endstream +endobj +612 0 obj << +/Type /Font +/Subtype /Type1 +/Encoding 685 0 R +/FirstChar 40 +/LastChar 121 +/Widths 686 0 R +/BaseFont /UQEYQY+NimbusMonL-Bold +/FontDescriptor 610 0 R +>> endobj +610 0 obj << +/Ascent 624 +/CapHeight 552 +/Descent -126 +/FontName /UQEYQY+NimbusMonL-Bold +/ItalicAngle 0 +/StemV 101 +/XHeight 439 +/FontBBox [-43 -278 681 871] +/Flags 4 +/CharSet (/parenleft/parenright/comma/hyphen/greater/underscore/a/b/c/d/e/g/h/i/l/m/n/o/p/r/s/t/w/y) +/FontFile 611 0 R +>> endobj +686 0 obj +[600 600 0 0 600 600 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 600 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 600 0 600 600 600 600 600 0 600 600 600 0 0 600 600 600 600 600 0 600 600 600 0 0 600 0 600 ] +endobj +311 0 obj << +/Length1 1612 +/Length2 15071 +/Length3 532 +/Length 15930 +/Filter /FlateDecode +>> +stream +x???ep\??%(ffV?,ff?????R?????bY????`1Y???0??????M????kb*?"????re???D*2e5FQs?)?+????????hmo???r?gTZ??9?????&??  W @ h????????Tq???????+?FCU??????-??L????w???????w?????????F5 ?jXX??J?:2?R)E ???lbPv3??6?[?\?? ?3??? ???????\??b??L.?@3?????f@?\ G???????g?? ??????o\Ak3;7???[??E???7????/?2?????????7?????t?2q?'???_7d?7?d??OI??????u5?vp?=]??e +?[?8??x???????_4?\?,???hi?lntq? ?????g????zGG;???+?r?vu?Y0!????i??7??????"?`????n???>w???D?????%abr???-?A?Sh??????'????-????&???9??????Bu??S4??;??`o@??cg?? 7??????l???Z?????q5?? Q????0???h????h?l?jf?0?????5???v???????FV???S??6?u?????v??+??"??:??????,??S???W{Wu/????G) + ????CL ? ?a?{???\?????o?? ???? +&??????%?????????????t0??3+j?&????q??9;?U?_'?o????????@3??E??MJz?k n????^_+?P?cq?zA^`?; ??o??[uS?$?G???????,??H?u?/?E.?mo???vn??`f?b??S?(??y?M(].???qU??7??vvg??G?@ +??@,?G?????0?????/ G????C?????{??Y1?T??P?_"???u5?}?iaR???.?H??| s?( (#??_?-sW????S????[?*?q?f'#D&yg??W??$]p?&B?n?m)C??a?H??!?h?\~???W????d? O?t?y4??Q?0??U???8?Py??????d?p?Ix??2l????>?7?6p?I?Sf:i?~?}???o?p-??!??x???[???T????"????2????5R[?2????X??Y~N?1q??????p!4S???7?e, +??\??w?????4? ???? ??on8??s??? f:??\J;Q{??A??/e?M?????|???~V:??-?Lf????2??????_????7??4G?<m??7f?6?????Z.???;??Zk?-??Od???y????4?;yT,?Z??sb?%mh>Uy?p?}{!???H8 jI 8E4As?9?)C??????????e? 2?_??0d?c?4?? +P ??P????p?(>?Q?H?y?#?{?3??_>??T_??%?y>f???~0??N?)???+k?S?? ?e??[??]???D?o?U;>a????ue??F??m?1+?????q#?\>5fm??? +?P???ZV@????4?? W5????gPs??s6??!?e???b? +??m????????7]-t?:?Ht8H???k S*D????c?D? ^?F??I??X?G.???V?-?Z???|2T??}*??????yQ??#??H]g ???/(?V???"? ?G)LI??????v?3?*???????L?|????Y??Oaq??5??????V7s?lM;t???-???Z???+D???2??Z??????????$F???~?L:cn??????KKG?<????"?3V???4?0??.?a]????+?T?}??%????w??????k??5) ?.?3 ??????????L2B????v?-?Uo??;}??l???pn.??x?????@T?`#/?$??C?w????Wzl?t???G???v??U??r\I?NkT??U{t@(M9????C?W?nk #f???:?m0?@?^I??u?m??E?A?????%???C???E??P???????P???+$?0 (??pM????60m????o??A;??S-????'*Ni?T???C?Sj?M?????P??XJ? ,??5c????H??-??,0?R? +X???N9??K?p??B%?pk????/?Y????????0??f???9?(??nUe??? S??"??? ????@?Q?#]F5=)? ?,AJ?K?S??????%??u?CS???%7?3?Jw???g.??/????g?l?Q??????G?m??$?????.?F?O?b??-?=??xIbDy?m#?f)???D???1???????o?f??%_??{???:$?????*?Y?QJ???l?{9w????e?????????? ?~???*?$????Xy?/8O?????????F??@??? |T\??Z?????,??$?'???M?TZQ??+0xVs?*??b???C5 +x?e????71o~D???? r???1??S?jHC!?Oe_}B???]?????8?????h?R TP?jp?????d????) +@)??F?1CV???V?*zpZ#B???~Z}:?O$???h????[y2???U;h?%???A?[J???#?&?I;??)?@?%?y4???\?j??5G}B?k??uA/-5z??T?I?Q? ?????$??4N??6???:????0??????X?%??s*??_@?HR???4???""???? ??R???????:??? #??t??2????t?J?9n???0?@????Z?" ??? ?????2X?Jer7?o????Z?Cw?Tg~]|?,?LF=??XT?????;+G????|?F ?L?N?'`+a=;?@2 + +??e? +?LO??C5|?I?????n?+?m???t??'?;w????O??GbN???]g???6x @??T??R?J?h?^-n??Q??I??+lZ;@ ???j??? Us'?F>? ?w>?[A?FO ??B???RICh?{?~??%?KB??? ?p?~??7W%??D>??j'????7??P?X???????h??????[,` L??Y?B8{?z???M???:t0i????\??S?????krv???N?eQ???b? ???40??K???xi??????[IN? )e\?w??????'t????????B?.??#HP?\?0?f????t?? +x???y??l???oy??????V?a????? ????6[e?t_G&??{????D? "?K????K>>???5?2??T?$?Z? ?????l????g'_n:]?.???~m8?o h!??W5?????????????e?R?&x7???????m?q^??S(~?"?!*w$wDUj???$?K??R?????W??8?W?;"???8????k?QD????mJ]S?`?Z??48???I??????I???????w?24}??/?u??? ???2Z????*?'?x?}p???8a'$???`yp??`?_???Rc?-J????6+f??F?a?Mn?g????4?????I?\?j???s??%"t???:??] ??,?????[q???Z]F ?l?"?o5?b??k?I?????p??F??K7????RK?x?Xp"G??9???????P?Y? evB?: +????U?l[???6????e????P/????!5?"L?"????>.KJK????+??O[?lu ??sT????RL????N??H?V-bp-. ?I?Q??????{??????K???????G;W??j?e???Nz??po???mCK%??t?T)??;??c}M??????;N??$T???_+F??0%?????~?,-2?{??F',o?o?W????q??Xv(???H? ?N?ms??{ +?M&?~"??\]?N#v?.?$?0??j##?(?3H?x??E? +??hG ??a?????"!???y ???????k?|7h4D?~?X??n??F>)????y^R???d?,???F??y??7CE??|????n?-??Y???]V??x????.???7,I?y1?M4??? ???8???W??N j gj???????????` ?u?Pr?,????Y?>????4N???fj????K& ?%=*[????N???????)???@Q??I??:????T??~?? ????'?6??H??3??=?,??n?q???6{t??F??3?m???/y?f?:?xvx5????,l9??\r?9????dE??W????0n:?dYj?*?gC?N??4?????????????5?v??5d?????`??.?????S?! ?????u]s]??x???g???M??Y'?5?n???u?{aL?????????????P??N??)i?+?I?4C?????ta??3?Ba?Q2y??T^??#K????i????f?]????~??i2?6bb??_?c????????)??}?M?4???hi|??.?1=!d?`2!'????2??G?%w?)???Y??????????4?&???????@yRCx??X?i?V??????|G?*??B?Z}Z?Eb??5z??uw ?????? ????l?@l4????Ac~t?`?y??6??Sa-?? eb????8?? ?7??pX?!??:??1???????- ???$??8r??%?*? ??\b#??q??????] +p??v? r???5?????P+??*?Q$??2??@?5?? +=g'O?? +?;???&?"l?{???/???1?u?&??g??N?? ??K]?/R??#??vj?-%????hB???L?D???FW{??#?N?gpI???o2????*VcGc????????t?f??q\~?????(? 3???n??I??P?b??)?Oo???W?h]?Z??W?u%?6???j?y]? ?bb?H. ?????v??????U????:)?jc?????o}????.?N?oq????%???S,?D)?#???y?? ??J???3!?P?%g?h??*u? icY?K9?????? "?lF??bCF?f?nq>G??T>?;L??e??R??*?e????`??s_1?3D??(??FW??x2?r???j?"?O?G??\???d?d59t?Q???????Jrl?:?ubvOc?????? +????,??W,vn?? +??:%??=S.???0q?1 ? ???)x??t???8A?&?? G??T????WCN?1??&%?wky???]H??????,K???q?#???m??-?????????m??????A?F???_??X)?w?)???0? d[_(T???T,P_,??^?Oc}?>??~??XR?o5?.?_??5??B~?D?H???4???N???@l?T????h?g??Ok=k,9????$?S?G|???;0*[????z?e???????w??_?? ??P??????n56??k??)?z?X?b?A???^???|?= +4.?PO?Xe3??!1??LN?]????]???r?|)???j4?h?HMq?~(/!&5?n??i?*?E??? ???S?@?q??X?*TH???.???j?[|??`rU?t4??L]w??zqlI?nd? ????????^???????=?U???4e??#G????l( ) ?b????Z?p^?;???b?+yoe??n>?????Y_?m>K?u?V?Ur???? +-a?? +??x?3)"?q???_$dnI`1??]??Z??t??hf??i????"???>8??3?E&????n??]/ubW??Z=}?~??T??z??????+n?? ????????&?H?&??{> +??? ??F?8}- +|?$:???fa???h?(??????Bg +jcn??S?????eVf???A?:C?A??1????\3?^K\?|?????(????????U[????Y?t\???B?Y??=? w?Ly?G?????/???T??V?:???C?\?/??_??B?]??J?:?(?????4z?:?!??o?2qV???????\p?3R{{?????V??{?b???????m?v?ww????/??w?l?U\??????-?|?&H??'w????H?d?O*S#a??????????S??7??z???8???? ????S,"y?'>??W Y4S??`Dz|??}d\???C????>???P?H????k??? n??'?"??,??d??s??c5???P0???z@7?????????CaJ)??Si?/??????fOlo????f???m?`?@w????p????????+??????n??b???~??55??-?~?[??d?Af?Ps???p?Fm,?]?L???m???.G&F??"Q>?0??[?7 ?W?M??Q?$#:q?5Q"?g??HA????? ???J_?bD? +?"`?=??;s???y??&N???,??,[,?8?}&???b\??'g??5??Z?KH??s???1:??2t???????|?T0I??M;8x??*:??@lB!f,?O??)??H?)?????????>9?Vxz???8?g??5?Z??G?DG??????????V?????i??n??+l????I????M0?-(?pg?d?\?#???Z?77?????"????,??B?]9 ?3????&?????B????????)y?-??4pdvS ??E??hc?D??W?@?[?gw{?3|?3???X?5l?^????$S???$&?!+4R???????p V5? X`bz??y????????^T??eS4??]?? ?>?YQ?.3?????{??H?U??i;?su\/?4???2?T?>??j?p??a???VI4??????n,?????bb???1If???_??&d?%?U?O?wD?d6{s w?x?k????\?Y???p?`???hsI?|>?r?l?m?<??2????????V?R?f?????awv"???8?3???q7?"??? ???*?X(???c?}vZ;?B T??/?5"?8???7?{?a&? +???????????m?m?Me???v??l?f??)S???M6?=???\Q???????r????;|?f?=?@$?????`??R?U?t?????P+?&???p???Y??G?????p??g???p???Q.H???!???}?F_ +?Y?&Z?H??????,??if\Jb+aD*????F?7??|?o.x%l?&"?&??s????_??U9???O???}i??Num?'?[?????l?/DKW?_??F??NR?0???]??d???E?W?????s4????l???i)?5N?G?????B????D???o1???js???y????@?? ??k????Gq?v7??w???PD?*??q?w?Q)?/??)?|p??x??^)&v??? p_??s^?[?,+??-??A G?t;?? ???j|???C?^?>??y?3 ??Ot?r???????m?????Q{??????p??c";^h???y?1$_'H|??????NP*????-????3?\C?<7? +M??????l??J??$???e6Q??????}????E8???A??Y??]????;35??8E%}]??]???V?^y????s??=EZL??_?}4?~?u"???k?;6Op???J?(3????H?????-[?Rt?*??!??@????????>???zm?oE?I?N?%S??Y????$?M?/?????B?x?>????X? Zr?????&9B=?%????~M??nS?dC??Wqi?a%??0??????I%??f??D&???z?N?LrEE?(a?=v?? ??}>Nw=??37=P??$` ??????x#`????%?%?x??6??q,??$?E?????|?W?S????oR@??t??[r/2??a6????T?Ac????"????2?P!?W??JXj!?i??U??Q?N}?;-???99??????~?H????]??? '???]????_??7?0q?gIVG?s?5??? ??KO%d??]^?????L?+7}??}L??????P?????7r??\d?00?m;???C0-??Zc1 +?E ?? ??b"g?L??]d????? ?????B?m???]??Yk?Tr??>???GVor?2j???D}??F +?/:??q???Go?F?G???G???LU?????%T?u????? ???v0p?!??@?????.?? wR\?z1X#?4i???-C??c-y8?????8b}U~Og???jXjtm?S??s??3 ?P????????r?1?Su??-4?:s????R'?l??x?`??:w=??.:=7??A?z? +???8?U???Yi?9???g?? ??[??/???s??SeH??????zr?_?Z?Gps?26_?CuOJe|???b?? ????Y?3?????R {&[^??f ????N????????????g3\5S?6?,?IJKl|3?~y?? +P??h?3??? ???d@*????Y??"[?? ?'????f?b??????????, h-???`NcM? +???T??O?h>??9??|2? c|q!?Q?????)???7?h???-!??"Jt???[?@I??I?CZEM?z???H[?)???wW?????D?=?(????8:?p +0??n?.??8O|???)/"+??v ??cu}?Y%_P?%????D????z?$???????'?2%???iY??}???"????y>_???t?hK?j???zH?w??????A?:??r?? ??????1??R????:????]??N???kO?=??R ?i???E??u?av}?T?"V#8??c??/?!@7P?!?H??,?4Y??Y?[???~????_???F?????????????^??4 ?? w??"?[??R??????? ?J? Z?9???zN)?ACP))?6?}P????Z?!g?k?}??g?????CE?8?[?X??J????Y?>???X????@0?q?h8k?9?@?,"????}Y???i&khI?"??????`?\?:?????g??Bn?x[?? +Kpl?????B???r>}?3??\;??~?s?.?|k???????????x9R<8m??????X??$`???V!f/??C?[??????? ??sJ?)???=??? ???s?d???I?$P?|?:????g??\?Dg???3??+c?QD;]FDX?zW-A?? ??]??)??1]L??????rdJ2?????X? ??vIC?$??K??56n???lk?e?????F?.?J?X2??.e\????..l??h??????D???B\b?p;??K?p??;?1????????????5??]K??{????????l??COK?zR*???? Q??_*T?b??=?yS??C?j?R?????r??????AC/??J?\?f??????P?H?t+?/?sQ?s??c?Tf?Q????;??*) +?+?)?^P]??m???{W?O?????L?,AV?+P?:?h?||?7?">9q?ly?D??@??v:????B????k35v?.??$????n??N?6???5??????~??????????? ???c:?|???f[???1?)?7??F????,6#??[?=?????w?9?????eq7I?E??-0????1?6??(/???@?!?h??vS??|??w????p?G_??K????Y???j??????Y???}??????l?HQ???2u.????z??^???HF?+%v?@.%Pl?o4???}K3VvJ??[?y??>?????N)|/?#?:????p[???d??yZ|???2E.M?!??2??3xO????0?Lo?nC%?iu??'???P?Gd???s???o1u$??QJuG??y???L?h`?x7????z??K??????????????? +???LNO6n???U2??&A??evu??mO?> endobj +310 0 obj << +/Ascent 625 +/CapHeight 557 +/Descent -147 +/FontName /ZRZVGJ+NimbusMonL-Regu +/ItalicAngle 0 +/StemV 41 +/XHeight 426 +/FontBBox [-12 -237 650 811] +/Flags 4 +/CharSet (/quotedbl/numbersign/quoteright/parenleft/parenright/asterisk/plus/comma/hyphen/period/slash/zero/one/two/three/four/five/six/seven/eight/nine/colon/semicolon/equal/D/E/F/I/M/N/P/R/S/T/U/W/Y/bracketleft/bracketright/underscore/a/b/c/d/e/f/g/h/i/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z) +/FontFile 311 0 R +>> endobj +687 0 obj +[600 600 0 0 0 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 0 600 0 0 0 0 0 0 600 600 600 0 0 600 0 0 0 600 600 0 600 0 600 600 600 600 0 600 0 600 0 600 0 600 0 600 0 600 600 600 600 600 600 600 600 600 0 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 ] +endobj +290 0 obj << +/Length1 1623 +/Length2 9318 +/Length3 532 +/Length 10178 +/Filter /FlateDecode +>> +stream +x??veT???-N???pw?@p ??PH????]?'w ????]?=r??}{??_????????s??d?????V?b????? `;7?@[SW?Y??KA vj?? ?3??NO/ ??@?? (?Zd????0:=@??Y??L?,???l???c0w?'??? ??\??G ?L??v?0 ? +dH???+????U??@0jfPwy.???????+`?????)????K?`pvZ????n@???u9;??@?k???[??X?I?y? +?WB?P????3?L?q?9[@A?0?sTu?? ?1???? z??gKK????????i?Q?? ??`b?? gG{3????d?P?_i?8?????? Z?A-?????4?????:??z3GG{???!Y?G ?3??????9??9?5???gX?V7???-]????5????0?'af ??,?V????sH??Le??????-?[?????w???!?????S??????9?r?????\3????? ????9????????t??????1E??s3$?????ssq??c?,rZ??`6+3??^??? ?B?A`?????.,?7??sv????? ?-????J?????/?????]?Y?????#???y ????))??????????|????y????q?k?? ? ?8????????ke?7Y?????h?????S?` (?Y???s??\?5?@??}~b!d??? +? ???1?h?F? v?Z?.??? ????"\????U???qj??*????w????{{?[O??7?X?G????"a1D?9}&?0?QW??t@???J5Y?;y???b??)g???J?Z?[?????Z }a?a?????9L'??K?'??F???????,~k??L ??M???t??*?6???Mxd\9&aE?r???{v?^????x|?B?h%??M?.?W?*p???z????6???Z?????gr?????vo????d??{?L??N?????A??m??R!???x??? ??t?7??;???????J?aR??D|?;???i?!?qh??2/)q?y?? ?????????l'??Y????? ?????c??!f???sf[?+?{T? GB?W??$ s ]??|#?7d>-'\???U?r ?1H?dM???A'?????,??vuB?+S???B??KjVU?$???-?.XG???????M?9l?~[Z??^ I??#c??Ie???$ ? +?????>?? p;7??AW?? +?"*?z????????y???!??~?tz???{, at lVu,??13w??i??2&?C?-?????????#RZ??joVZq?M?????d?8????m???Z?????N? ??e???Q?g?????z?G??]?k???? ?1?m?f?5nyE???RQ +?YZ??5!???y?????a)8x3???3??9????uv?m?C??uuu$?V?H8y??L????,K(??mE?^??&j?Aqc?????????p]???C2?y?c??dLD?M??_?)?GfJ????8z?NM??????!9t 4X??-_?TV???__)N???u???.??q?I??v????????W?2?b,?%?????9???p ?~???????1?v? E??O??*"~?wk??L?>}?8??,W? +??1I???4T?x??????&??V?????j(??X?????)??Q43???x???? ?y??cB} + ??u??;?M@\j?????$V-???,?(o}?E%?Sy?.?h?(????@x?n?d?????L?U????j?Z~??)_??I?????M?Nab?h????O?^???~??????M?I?z ?\??M??i??G+???d?rqN?:??Z??M???Q?-??1?%nk??cwn??@??9???}8?g?%?~???k?r??7??{]??&;/?? ?h?M? c? ?c????????5@?~?&??x??L?bE?hG;>?????(??????h?wU+WR??XD??K;?"HQ?????E E&????d???@n???%??zo$[??#?6s^?????a???????e??HKVt?hR??L??U?????V??7?9? ^??????P??g?P?C?1??i???dY?Ai P????'?d*\n??;{oR?r????e?Q?3?dFw? ? ?E?????o????EF?n~\<0?|D +?N?m????~?k?????1UzC???5????????kTr??C??&S8?H?h?U??Z" ????+?f5??Y+}??)???y???r6Ia?u?r2??5?i2?cwXx??lB?c??X?Xw???}(3W?4??????e+$'??????N6A?{ ?6?mj???N??????h??X??g-?;???o???,?y??}??y?MR???N????w???}?????S?T?????\6?BTi?????)?]??K??????{\[r ???? ???:W +?TL????w???!KW???????VuU??y????eTs ;?I???O??i?`["|?\?????????e]Vl??F?F?V5?d??ow?f?AhwE9?k??$MjK???????h-hT??Oih"p?> +w????l?}??+XoZ? O???????V?????l8 +~??^?H?~l???STH?{??e +RZ?k??wR?e?=we6c?A?;?hs?&??8?G>???$???U$??????U? +?wm??????Sh????})??`"?l}?,?)??O??>?A??S?%????A[j??C??????/?J??;UFa?3????????? ?-B ?"A7?h1A??w????<+??L???06E?#??Iv??V??8,?A????E!?????e4??w+p?? +^?I????"????C{|??A?2?7]?5n????H?????????TK???7v???8?8???R??m??'D? &?j?6??e???0"?(?`??`>Y?3k #jY?JW??J??5Vzybeh???Y?|??Z?_?V?$?^??(????M?v?*??&??<?/CMnt???f?l? ?Q?*H?7 +Lr?E?hrUy??Y??,????r# ?4???\qk??&??6s???VW8?????????;t@?H?t?3h??0ZP??? ???n???*? ?m ?W???w??l????T?O/?>???????l?':??E?^??b???7???A??g??r,L??=$4e??p/???|?{#??2oB?~= 3 J???P?P?JL??R?????)????$H5?????o????x???bw?J?Y???f/i?c?E? +???B????B8??7F?X??1n??????qvz??S??[t???UXPbI}??& Xh? +???Y???t?????gg|?pr??r#?????}???Y?????]?????A??QJy/;?FZ????????D??$})I6_??i +??)9G@^_?~9????&? ??;+Zz?????d?V???E^W<{?q;h:$k?z????6 N?T??????#?h??&:?}??f_p0????O?????3?\G??^v???a? 1O?{B?@??Q<)m+?4??`|??????!#??f????x?tV???o??^o?(?k>?#dP?G.??r???_??? z? ??:,^1??Ocs??6?????????s??? =8???+????m??|P???*E??????*RE?J#8????p????N?_???{??4??S??y?????0?[???^?W?>??(z?o?)~?L?????}?Q>?Bi%?~????!?4?p5??;-i}% ?6gY>Q?J??c?1????$=????"?????c?_)Exn?)?nN??????b?<?E#????.?"X ?8?c&A?3?+cr????K???-~Z????????BP?0??,?9F?/??uJq&??-???uI?]-I?L? Pz??@?i???F?O?'8?9??"?X?g?+1????S9?_??Hp?????? +^,z?v??V?xvp?b?wE?????G?I???!gq?Fh??'y????b1A/{.$??J ?%g?[??Qy??B{J?}????0?#*?B3'+?b???????h??M,????K?[w??y??y#??g??L4?K??????3!???K}? P??j%?????ty??>iM??S/??:`2e?[?H???Sh?~}Q???3???????eo? ??`??z???????K??o3??a?0???????%??y??F$??z??m????@????q??? ?O?I???[?8???????n?F???; Nm?e???O????^xu?EQ??c ???`[G???<_???~?9??x??_?L?W???????>??B???t?]?*I;???%n?????it?QX?k????6???!???:_?gbw?"???M???DM?Zn?????x~K?d???b????????N???_?4?0????3G? v8?'???????? '????Pr?????dl??%yu?????e.^?t??x?\????["??)?? ?`}?^.??Mm??}?^??KFJ?n?t??1?b?^? +????R?$????lrd<20s +?L??Rh????[*??DAY?5es?}?\???.s%,H?7???Qp3???v?n#? p?????!?????? ?W5??UQ?Md???.Z?\PTf??!?^?M\?????`??'?VB??z???'?FiI,???????A?f?{?x?g?c??/?+? ???????!????Yi?_???I?n$?i??1?S??????vZ=?T?0?-????????N%?:? ?????K????!??N?W?j????Z?|???a?G<`?"?? ?K?P??ZB??7??$I??9?????l???-o?_?:?|8?N??a I ??Y????????,?V????,?<vQ? +; d?????92?yR?kV*-\??T7??6C???LU?k???Z????{4b{?q ??k?z b|????J??Y??FP?B^ s?@?'?n???\A???F??|?K?????o? qw???? 0 r x???F4 wX WK??rg9N$C??H??D)???lP?D?O??>?????$R%?Y?D????ri!??? ?9??%??????CV_? l!?_s4K?r:)?f?qJ[T_ ????3m???Z???H????|fo??zUVst?p?9-?W ?Qz?uAM????~?*7???]lxo-???t_???(?p??$e?#?+???_"vvP.??]~?*n*Oi??E?_L??????8??*>????h?{\??_??q??s?????%??3DX??d??H?c??c.?????,?"9l??"??&Q??>? ,?|??F??o??????yT???#????7??eeDE?e_?ULE?z???0?F`???w?H???5?{?:K?K?+?U?CIm&A]??4?0?v6?????? ??MD}Hg??@???'^???4Rg???Ts@?????h +[W??J8??(?v" ?? Y????_??8?O/?L??".{}?-?m?P???N??O?8]A??H?g s +x???k???<v?ZfySKc??8+?}A?????j"xbz??ZK??????????????6x??; u?,?_?M???Y?i;?VM|???C[???? ?5?N??,9n????P?#??)??W?*??/???????o_?? 7???C?????????2?p ???^?irGr^?s?>?bY%????c?????????',??fP?? j??????endstream +endobj +291 0 obj << +/Type /Font +/Subtype /Type1 +/Encoding 685 0 R +/FirstChar 2 +/LastChar 121 +/Widths 688 0 R +/BaseFont /WJYAOH+URWGothicL-BookObli +/FontDescriptor 289 0 R +>> endobj +289 0 obj << +/Ascent 752 +/CapHeight 752 +/Descent -206 +/FontName /WJYAOH+URWGothicL-BookObli +/ItalicAngle -10.5 +/StemV 78 +/XHeight 547 +/FontBBox [-115 -232 1275 972] +/Flags 4 +/CharSet (/fi/quoteright/parenleft/parenright/plus/comma/hyphen/period/slash/two/colon/question/A/B/C/D/E/G/H/I/J/L/M/N/O/P/R/S/T/U/V/W/underscore/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y) +/FontFile 290 0 R +>> endobj +688 0 obj +[487 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 351 369 369 0 606 277 332 277 437 0 0 554 0 0 0 0 0 0 0 277 0 0 0 0 591 0 740 574 813 744 536 0 872 683 226 482 0 462 919 740 869 592 0 607 498 426 655 702 960 0 0 0 0 0 0 0 500 0 683 682 647 685 650 314 673 610 200 203 502 200 938 610 655 682 682 301 388 339 608 554 831 480 536 ] +endobj +258 0 obj << +/Length1 750 +/Length2 576 +/Length3 532 +/Length 1110 +/Filter /FlateDecode +>> +stream +x?SU ?uL?OJu??+?5?3?Rp? ?44P0?3?RUu.JM,???sI,I?R0??4Tp,MW04U00?22?25?RUp?/?,?L?(Q?p?)2Wp?M-?LN?S?M,?H??????????ZR???????Q??Z?ZT????eh????\????????r?g^Z??9D8??&U?ZT t????? +@'????T*???q????J???B7??4'?/1d<8?0?s3s*?*?s JKR?|?SR??????B????Y??.?Y???????????kh?g`l +??,v??HM ?,I?PHK?)N?????;|`???;??x?jC?,???WRY??`?P ?"??P*??P?6?300*B+?2???????t#S3?????J.` +?L? 2?RR+R+?.????/jQM?BZ~(Z??I? ??% q.L?89?WT?Y*?Z? 644S077?EQ?\ZT??WN+?????2?A??Z???u?Z~?uK??mm+?\_X????????7?D?????Rl:/P1?d????????(??l=U?h?d?_O??E?k?v-X1??t???`????i????_y. ?1?????????:?un~Q???3/??S??}??]?? +???$e~s?]F1????/??Q???m????|<?????/??q'}I???+6???E??g???xT.??G??gt???v??G??U|?????~??]?R????_k?9???:?{?p??G?? ??d}dN<6??-uB?o?H??=c?M?vH??z?q?a???RK?~,K???}????????m??????yo??~?????v? +?_????s>???.#????????{?/?????k????\m?|??r???X???????ad?j|?????R/?,2?p?0, H?IM,*??M,??`Brcendstream +endobj +259 0 obj << +/Type /Font +/Subtype /Type1 +/Encoding 689 0 R +/FirstChar 15 +/LastChar 15 +/Widths 690 0 R +/BaseFont /GBFLIM+CMSY10 +/FontDescriptor 257 0 R +>> endobj +257 0 obj << +/Ascent 750 +/CapHeight 683 +/Descent -194 +/FontName /GBFLIM+CMSY10 +/ItalicAngle -14.035 +/StemV 85 +/XHeight 431 +/FontBBox [-29 -960 1116 775] +/Flags 4 +/CharSet (/bullet) +/FontFile 258 0 R +>> endobj +690 0 obj +[500 ] +endobj +689 0 obj << +/Type /Encoding +/Differences [ 0 /.notdef 15/bullet 16/.notdef] +>> endobj +191 0 obj << +/Length1 1605 +/Length2 13195 +/Length3 532 +/Length 14041 +/Filter /FlateDecode +>> +stream +x??zeP???. ????????????????? 6??????r????g??????n???????'?????;?????2????P???????????.a?lna,K/lgg?4?????8 ?-?lE ???u? @h `a0sqq??D??=-???T????t???0??w??J' 3[???hmgo?u????^? ???S k @D??????JB^ ?:Z??Y[d-???N at j???#????????_?91|b 9 N?@c??e at wc??_.:?=??????s ?p?9?:???`akl?b??O???????>#l>}?`??????-???Y??????????_??,>?;??H;c??J??? ??u6??u8????e?X8?[z|???w????????????f??&?@'?O?O?????:??zC{{k??W???,????? ??,?9???s?Y??2??Q?lM??L??????????w????3??$ M?l?=&@SXFy;?????;???D?_??E??y?g???F???O???B??X[???^?? ??u???PC k????q?????0?? ?? dk?)???N??@?o???SC???mW?5:Z[??????z.?q?|R?????l????&???S??Y3j+? ++???U?w??O??U???r?8:~???Q?,????p ?h ??`g?l????\??30&???? 6????V? ?????/5l??????;C??{???????4??P?5eg2?<????;e????v/?Q?!?D=??bNv\??ImokLQI???`?????????5??????8?w Frj???????{???????+??]:?e????+H61?7BVB??T?0?t??C?Z?15?Y#??KR?J?G???{:?V?KK??Bk???w?9??????????g??]???;?????ah?.?U_/aH??I?h0?{p???0??nP\#}??v?1?? M-????P????_???U????>Ek??s?h,?%?47j}ii??1^)O?J]e%^?oR;r"??? 1q???lY_` ?>?Y??Nn???-??????;r?:??????s!???Y?Nj?d???V?5??ri(q1?(?y??w??2$??? r?????????/?"?ATu&d??@"???x?7n30?A??#???+?UI???9?,?WQd??*?s????Z????B +?Gy?v??}?????TG}?[?????]$N?v6???A??@h?"R?_1 ? +s????2j?????????zi?[??er???n?YU?R ??(?????????%??????:rw~?-??c6;?????m ?????BU???3???????' +%??s?????????<?1?1?F?J| +cw??!?V??GnZ?~ ?o??w\h?*??Tn?@?*(??b?RvW??bpAF:??`????????~?Xi???#O?;2??/P?X??9v??R???i?5???-?E+??nB-?KS*;?Ii31{?@? ?? ?? {G?? +|?\CH???p???????i?x(@?/???? ?}?_????????Ur??oQ?<90????????????`??????8+???5NI??V??8l???$??=? ?X ?B?}?????p???? %?d?)???{VxX?????)-Q?? K&J??A+L?r=?*r??u?????`]?8?? ?#?;o?????????F?? +E?P?k?4|??????IW???w#????Fc?????6h?  +q*??'`??*Lz?z?K???)??+.:?????o??vo?lP??s????8o??RUO("\XK???`B'0?k?V???,??c????5Od))? .?Q ?5??U??????Z,lY?F? ??9 +???u??????H ?????T??5?G????]s/?T=???????z??? >?u<^? ?u-&?e????_3Q?-??_oG?@,????*??jy?dCK??J????$m????`??~C(f?K?d?%w??3X???6???"???j?R|?????>?e??6h?x +e?=B???b#???6??K$??? @ifbO??#?1H???O>?!??K$D?0??+??2??5d?h? +blT:?J?????TE??j"???????/??a???Av???????0?????W +T{)8.M!?$????&??b(38?1??T???\O?? 5q??"??nV?@9??d%;??v?????j?????\b???????_?Dr??1??:c?`ESz5???k??%??3?C?\|?c??XJ? ?W??%1?.R??b.?9??m??W?G???_nhK%|D??=????#??A?????|?M?Ml?f?]j??^9??(?x?,?"@?z?????K_P?? ??G???8g? ???66?9?.y????R????7"t?? ?#T??????.?]??Ov?(Ls4?g??K??????C?X??T??????0??b?)?|(?1{we??????@3? ????5?????a????xB???^?M%?I`? ??6]??????R?&??!D?????????0??[I??zPY m???_)????G????,?Tp[\?^?#???(?"'K?_<?x??m6??????J??A? P????o?6%E???q??=?>wu`???A}?????q ?3#0?????gp]??????SB?s?????F#9'????Hi?DD4????OP??W]????f?????6X???q???6??l????>???????15{???D4??k???????r?9????S???aN??&K?+??s??? +=??au,?E[%pT??`? ?o[?o\?x?R?V>bo?????J?"i^?V +_?oi?;;f???|??o9?d?8$?@?^?K B?t? ??f-C#PJ{?????@???7#? ???????&??" K?Z?I]?0??XA?L???2ML(?c>??t%?;l?,?? ?????o?!???:?1?????????G]E???sTA?????`n? uj? ?ygH?A??dKQkJN? ?9?Eu??-`]??^ 7N?{GW?_?A??eR?A?U$??????:z'"? ?{Y?A???>j???'?>???#????????l?*???=?ji8?9??l[?>????{??B??????`????LX??'s8'??? W???6???????????8 ??`??{?[?? ??k?Lo??? ?Ic?V;????????????A????-???H??j????IV?C??y?2z????9~T??H?6?????9??X?[W?*???????O??n??r????V\?5?6??*.?????2X?A????N?_??:?E%????}C#+ ~?6K4??)`??w????Y?3??;Q??j?nUh????????????%?\miF????gt?P?7??????????k??{?;(]X??d?z??r/I?????&?U3???|???,?{???{q?7???+&?rJ????3?D ?D"o??dDjdI???N???????? ?#6 ???#??X?>??????????sx7?hKv?L???5-}??????!????????u?B???T?F ?}wq K??#???d?????????63?a?l???{?Uq}?n???sD?%-#???V?????????Cu?J??,???H?c^?X?a???m&|??P????w?'0??g9??? ?u??????????Y??Y?P c?^??l?v?-??Z7???.????"B7e???zN??,?[?N?I??????_)???i0??v??'?????????6??=?P????p? ?????E?w? ^#??ah$????dU???a??]?n??? ?)?!x?1~??/sQ.$?V??p????N?^V&??mv?_??N?#@?hV?Z?;??}?m??^?`\?E?lN?? +? ?@8???*S> 'L?????? Vf???????4s)?B.lN???^???????\4?!:x??L?7??(????Q +????/S?A)G??~?j?q??KE??N??RyO???%$|N??[zh??x???%=??????wFk?wb???.????? "+ACN?b?=???$????30Z??? ?s?H?+?` VG???Q?7???????;??\D?1?)E??X?v?{x??m???b?????@N? Pn???l?!????? ???Kd?q???????7R???????q]0$????????8t'n??????7?}+N??U?????qlr^./G(&D??OK{?s?,??*?7D5??E?# qgDwUy?bEk7y$Z|?(????x.V?????6??X"??a>~??? +?w???w???:??c;?:?????S??e?Qd????31?+?C;????\u?).X ?,wC?f?tWu2??h????FWp?Q?f5???cqu?/W36? Q?q?8?? ??9D??ym?oNc?1[??w?-?)???lh??UP?u???Km?W??O`??x???T7U)?]?F +??????B5????bAf????[zb?um3??Nz?i:??XH?M?????jc??XL?N?T??M(CuY?7]?J??????)b{????*/???@%tZg ??n*?T?B?3?m??????z?&??X??? +??M%?9y?B???w???????rHmk?tZ=??2 e??9F?!3B]?O0??? 7????4ZB?Z?????????????(??4)w????&??????? +g},*q?*????j???E?>N?4g)?:?????SC?????????/L?{?tL?? ? ??HA?????L?a???|??iCY&:??? +???????^????s&??s 5???a?~?3???BF??????^?m????QW????^???/?tW???;X?u???u?i??? ????? +?;!g??D?????e????$WO ;N*?????T3p?p???Q?)y???x??????,? +??*?m>?????ct]???!x?????K1~H?&???^??"?3?????P?O?9?+<??c?Ji?{??B??0???{ 0??U[?m???o?r?2?s????U})|? B)C??????d?????6=?&b???&?"?Lm"S;?)?5???'?p??]3?ousd????g??wX????Aw?????-,?S???b?f???A?{???^????? +?R?N?pE??x#?SPJ?]?Il???=?F??m?T???Q??;&????iQMZ)?`?8?1??#?R~"v?F???X?1B%" +??l?t?y3?????98??vS`tp?o8n ??????N??v????a?Mob1o???m?5y???e?~??:????H?PQn?q?W??M?T?}<'???2"v????????XK?T6Y?y?? ??>f??k4 +??????V#e`?0?J????W??Q^?DKHs??)?>N-5????????r???E???Qd??b???N???d?8gyOK??????4?81?2 U at M??e?.??HK?????!??evj???6?a?'?KDK1??A6Ix????hw0?7??????='??tZq?k?4????x[?g?~?,$?^? ?4???????yl,c?????????B????{?O?TZ?q????F??t????}?80??y?O???C?4C???.???u??, at zu?\aPLk??`F??2g+??????? R???]j:?J???CI?5.?7???qs???c_? +r%$??$???_?1?v? U o{?bb???}????,*??o?l>?Y?????N??j??BO?T ??]???l'?{??q{?1??H?#f?*?|?fB??t????(W?F?Q/\???]x??:??????????%?f^??,???8 ??K??@j?)k???=k0?????_R??T??u???q???"Iu?P? ?-????1T>1????;??>???zn?zj?\F? X?? ?@? ???t?r?nX?:z???`?Z??CUWx??'??8?*?SB?U? ?({?P???)?? ???<? +C?? E????I????cF??????????%???^I?C???"????GWYL?q1???7????,?@??s(FTjiN???XT????}? k?????~??SE=td?Y"?f?O??w?k?76+?]{.???4?y??/?5?;??????y??????^+ ???4P???Ae?LO??D1?ul?w*#????x]?N$qX?n??? ??h?>?9??H?????X??-???M??C??????NoB]?????L??G??y??H+7?&????_a????MHP???????? ???)???;???_?dD???E????"(?:??v8?????e??????5G??g? ?G???'?T4n????v?LT?Zi???Un/? +??????=?%Q?s?x???????D???k7?7?? )(@L?n???DE?:?`?E?9:?}13?cL??LH??'??I??(?`?3v?^9KC??@????C??k5???'???z*?E???zP?N?bhLa????wU?8???%_??9?q?]??"/c??V???6?g'u??X??Nu ????A????"?k?:?4[????????? ?2??@s???u?Vm?2??????=?????/d?-F?????A!j2O+??v???n> endobj +190 0 obj << +/Ascent 752 +/CapHeight 752 +/Descent -206 +/FontName /XBQUBO+URWGothicL-Book +/ItalicAngle 0 +/StemV 74 +/XHeight 547 +/FontBBox [-115 -240 1151 976] +/Flags 4 +/CharSet (/fi/fl/exclam/numbersign/percent/ampersand/quoteright/parenleft/parenright/plus/comma/hyphen/period/slash/zero/one/two/three/four/five/six/seven/eight/nine/colon/semicolon/equal/question/A/B/C/D/E/F/G/H/I/J/K/L/M/N/O/P/Q/R/S/T/U/V/W/X/Y/Z/bracketleft/bracketright/underscore/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/quotedblleft/quotedblright/endash/adieresis/eacute/iacute/udieresis) +/FontFile 191 0 R +>> endobj +691 0 obj +[487 485 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 295 0 554 0 775 757 351 369 369 0 606 277 332 277 437 554 554 554 554 554 554 554 554 554 554 277 277 0 606 0 591 0 740 574 813 744 536 485 872 683 226 482 591 462 919 740 869 592 871 607 498 426 655 702 960 609 592 480 351 0 351 0 500 0 683 682 647 685 650 314 673 610 200 203 502 200 938 610 655 682 682 301 388 339 608 554 831 480 536 425 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 502 484 0 500 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 683 0 0 0 0 650 0 0 0 200 0 0 0 0 0 0 0 0 0 0 0 0 0 0 608 ] +endobj +179 0 obj << +/Length1 1606 +/Length2 11753 +/Length3 532 +/Length 12602 +/Filter /FlateDecode +>> +stream +x??teP???.???q?????????!H??wwww n?????]/?wf?L??_w????U]??%?z?z?????Z?V?@Yg????C???'? ???Tf?:???<(??R`?9??$m +??Vi?%?? ?) ?B ?rv????B o???,??????w?[??? @???ttvq? o???Z@ b X?9Rj? +?r9U??;??-?,?v?@??`? 8???tY????????????{KzZ]?r?\?`';7??o???l???? ?Y:?[?E??n??7!??[???? L?? ?f ?s????K???'???Wm7?77???-????????????y!?v 7? ???`e???h??V? ?l?7 w7;?????@s??#??? ? ?????O?????????l??????? ?h?????V??V???????(??????[??????{@ ? ? s+g??? +h???? y+ `??S??O????W?_??&??j??.???>?+?????????$??^?2??'????;?9z??????????1???M6???d?7?G?oN??[????M?p_ ???d@??L????`:z??R???C????_?=??I???f?/!H????????C??1a??4Rry"???#d?1??&V???3????J?? ?E??:????????6 ?^?6~?H???0?????kWjz???0vw;Q?d'????%?)?v\???Xn??????S??) _24Y??????I??m?}???d=???h??|7???????????);???~G??? A?????'??Py5?_kr?????t???I??a?}?3??Z}???????C??'B(?2???i?q? :???F????%i#??L??#6????W?`,9H`x?L???{???????`?Qz???L;e???????/?aP??lI?pq?~???? ??? d?C??o?Pw?9???]2????dR&??(?h????Bi&;?^?\?????[?.?M?i?????d}]??$?\Eg??M??&?????j???K?A=?D?h??J??q?????7F???.j4? GW???????? +M$???oQ4?P?$z?U-" a?Sg? 5?;[!UA???O(?Y???=$!P?O??j?Y?{??6?6??/????(??@F??.T?N?)???T?????3???`]??ip?hEtp?b?g????:???[L?Fu???????t4?5gK?]???k>???=6B]? ,S ??E??{|?1??M]?F0H3???cUi??"Kly?}?Ym?s'??Z??? ?Q?HYu 7?X???+gb??t??$???????}!"??I?kM?;?L?3???L?\???wx??0????@? %??qpV??/}V?o?f??e???????1???3???^}???e?k??} ??sq???9?? NJy??\???9?%????:?+??O???1s?F???k9??j7u)h?~=?X?-qw??l? ???????????Rfk/ 9(N?L?sY|V?R???`?? ]B??$?? ????????Y'??}8G???W????Fu?)*?t[?'d??T????4???8 ??z?????6???,`,?r?':gX?d?;??1; .?lC%?????????V\??????WZ??L?$*GX?/????|?ka?1??M?k6???u??d? "?)????i?????;i???????M??z?#i??zkw???????j?l?????u{3?????bc7KQ????_??]Mg~?????2 ?J?y#?ZM???y1>X`.?+2??8?X@?~C)?m??P?]??p)?????}???^&{??s???x?1?e&?_??&?2?.?t ngf?m??W???r??4x??,z??Vb?K?G????????'??8 +?,L?\??4???O7??f]???e;q;??N???ku?c??D?Y3???H??[?F?4k?=?C?<S?T?????c??pTGM??y&?4?14????|oUE+dA?J??:??-%}oO???s???R?Q?c$?e??SUb????0x*?5vfS??0??g??_y??vr`-????{??????HS$?U^?:?r`??)??O8???%i??m?9??L???????}HP??s}?Q?q`?F?a????????????p??)????L['?z.???a?f???4 ?????9w????>Z??48??a?3? ??????????7????U?JA??1hK???X? ph???EZIF??$???T?!?}?"3?D?C?X????.^??&U???5?EzSr???O?\? 5TJ at wA0?1jo?%?????P?S??F??'?3?z7J]???:?(D??_??????"?\Q??Es???? ?N.D?;?x????*?o??=6A?/ +?X?GZ?'yn`??h?qMxK?&???IS???t% ??j???n?'????????e??J?!B ????x?)1o???(??"#A? 7???$Z????~????n ??gJV\????^o?v??z?Hba?=?!sw?2???4C?????*????? +N?3?1=I??sX92t??????g???Z??Zu~4/?b?????M4QyP~?d?W?\?C????????C?????DJo???~?x??>??`~????l??!?^??F? h`My??$????X??1???2KK??`?^??b??p???^?t??"?:{????"?.??> ??%??[L?d?-???7 ?qt?t??2 ???P???c?????x??L?dVn?????Y??d0x???r?H/a???1??:8\rA??A???J???L??>Q@?????=K??r??=?7j?Vy??s?9? }iWF] 05??W?#R?y,r??1???>??) +?n????a??d?e?H?? +???T-?m?W`??i????? ????}????c%????$?b?E?????????????t???4 =??2&??:?I ????U?ea_???6f+W?$?NHPV<:?*??p?yM??)/??p?^X ?{?W???[&?' ??r'???v?????{??X m????~??!????S????D???{??t>?E??c?d???n??B??W?;=???q?z?@{b?????OM:~I?????-E??\[???????F?=?c??D??z??/?h?R?B:??,?$y???'?B? +\#????D?oh??v??????O??-#+Y?6??4?&???;???l??M?????^F???1??,??(??qN??;??ih6?R????0???%=>j??*???]??WtlL=8?nE???s??X??50\?d???%???]Mtg????mC?i?j?j{?F,?l??FSAq??j ?/?[&D??mw????.????:?????M????????0??!?VS,W?? +?]??Z??.;6??~("?% ?,??5?z?|?6~?8????;YoV ? ????^4r"?????#v??h?????'V|1-?O????9?????F??? ????Z Qc????fdN,d??&-?n??bZ?H????k???d??$???s;Q? ???NKH=y??"~????$9;???58?? ??<+???&P?'u-<X?$?/u]?na.l`B?? ;?? ??)????????&?`?O???c??m_????????U?=;1???H?8????LJ?Ug?wI?j?l????FST?????;T?? ?YC??,? ??????Au????;?6OXGP?d??????i]J!~?E????W??? +??co?gr?_^??R?P&??? ??vo>??__?>q??AO?B?)?*-_?)??i??l??.????H??xV???_?y6TKM?M???C????`?@??aI??uN ?y?d9?B???YV^?u???c8dto??????L0^6+??A??V?#???d?0?3????= &g5K???4K6[?H????K??z?????rO ?+Z?$?h?Q??X??+?N?N=? ?[?8\?%F??????e>???h???P?ij\t ?F???TQc-s2#??&?P?A??Vs???s? +0?p?w?? @)|?H???P4i?%?.n!??Wvx ????e}? ?:????@ ?T +???????!!??~' n???9{???k?U????Q????l???E?T??z??u?E-^???6T?r^???D?&Kp????? +?W?}?9?^???????V!?\#PUXz?????> +????N&??????^?*:?=?XJ??)?:?Y?sN?u1#???C@??????n??????}&??z?????UK??[n?q?G??dF??7??M?????l??%j???!?s%??ix???e?L9??Y?B????$h%?X????>??????????^??L^??????H?5????2elj???5??d]?1??Y ???{?u????d?%???b???QR????iU????'?X?Uv??rS ,?jQ?b??6?? ?!???+?+??"y??U:U???p`?????k???fd?????4????"{%~?dj?x??4?;\o?;??^Jht?[?:Wg^?#???.R???B??n?/??????~??"[E?k`?t%?[???J?????!???k??^1??=??'4????????F??W??o????}Pc?? ?EW??}i?!W????{???? ?o?V??n?B?Q!?G7??E?J ?C?.Ge???-??X?]??a?%vdu??:V???G?W?8??j?C0????n???gi]?-?O?6??GT6?Ki]7?&zcA?????p??h?@+??,?"??*&??cYgL???Z?K?c?????????|?U??3'?V?$???5n?(4v???f??O?i????o?#???????P??wB????T???O +.t;?????2&+v?uM?C# +???j?sb????cd*????Ud?{?B)M?)uq6??? ?F6{ ?s?LX"?o?*???vA?l?~??Y??|.???P9?#n'',R?1^?v\?+[?=??EqjJ???????????pK?Q??>3??(?W?{ +?>G*9+??)J?|?????9????7z?H"b??????|??5.-)??????{T????%????Y]|?V????,4?{s}c??g?????? 2???e\??+?????][?/] ?a,??????uX?6?|?q??{a^?It9????????D#??J??b%:]?P3?b~?i?????3y=$N??(?{L?G?U????l??w ???3='?E???P ?>????G???s&,O=5? +a"??~???6??.?)(?????Ys?g???{?%??QU???\?Syi??KQ???( ?????^??d?d]?W??????68Z???6?hG%J?>G???q?R?[???????>LH??S??r??D??Ni??7?%?????M?????????KN?,?f ,A*?D?>???XDN?Tx?p?zS?'?????H????T???w?^F??\Q?/f?????yj?{?b??b ?;"d??????K?+?\`???`??l???s??}?`3?8?n?E?7??@?????6??x?|??55???'???G4??@?v;/Z???#??mb/??N?j?>????F??G#?,v??Q????d?a?35?u_???1?Y????.????c????f??3?? ??O0e9?8:u???s????l???Y??L??o??@?'?)o=?GD????v?3??&?/ +L????_??7?v-???_??I?6F?mn????_K??J?????k?Y???ff??X?%H?r&??;f?:?)J?X?J?ZH6?`?u??W~8P?h?d?mUn?b3?%J?"??dU`yY?e%???s?j??s?!??!??3y?A??`?f??????????>??M~???m2?/q,P??v??'"??X?c??e?????$?????&Y??B=?d%?x6?C?p?????X?'?q?L??(??_z???!1e*?????3kS?A??oi\??d??2i\?u??'g?r?G????e??1ty????-?!?&cB(E$???????? ??:fk??a9 ?????4??j:]?X? ^?????V?%b? ??6;??< c??c(??p]v??!????~&??X??l/p?????Z??s9??[?T?^?]v????_?b??N gY?I ?lBrN??Y??o^?/?dwk???? ???s???K?????O|???z eMW????W?i?a?s?????}??}?p0???N???7??6??UM?~s??????o;tl?????z?O?*8???????q?! #? +?H:??i?D???????hh?????c{an??l?3?>?O?n?????@\WMD????k??t?X[dN???3?-K?????{n^???3;r$?tt?D0??L??p??M=|??#>??m??,i8A?%??n??>????n8s??/????????Via? ?6 at 1G??P?*(?????$?{??#?? h+\?? Q??u?\X?[???7gN??;Y?*-B???O?V? ???W?X?\}?u#? +???u???k!"??n?).X0I38[??b??2?$??A?M+6?R??0????Y?????????]?5 +Gh?L?M ?8??N\|O??M???G.)?/\?#???NLMU?"?vqa;?-Ng?T?i?S??y??\ZSL???~?????z}?k???4?b??=#?u???oF????? ??G?!0??Z?H"l?K???Wd??CL??????(?? ??&?????#a?}J?4?OQ :??J?w??????????)??? WEf?t[?0?/????]?2"#?W?}?7@????? `???????Q,?Z????v?2 $???d??8?svE??)/????`?x???D?>@T???51X&D?{0??????D]?/? ??LJ?%?Q ?r+f$?q?%? ? E??????????!R^f??????{0???f??K??76|gun1?)d??I?y?????? ?X???h?0(M??-?????*???c_#hO4=??sr??p?????m?B??jQl-XMU?R??????>????????j??????+?? ???0????????eb??f?;? _?a??K???n???fS O:??P?Ti?'??x??5GV????$a$"?<hL????I?????vU???i??I?~??E???d?A6-?^???thl????H?A?'X? ???*x??/?#,??????1Yo??NJarh?[?n!???? ????x?U??&d??0v???O????H????]????s???IR@???u?a?????6[?.?? ?;???@??.?s??;???B????2???????%)i????C\5??=W!?*?(}??q+??/?*????##?????[?'z???????{??S?????????8??C?z??d?2 ?q?J?^n??%????^z? ? ?n?Gp=G9? ?p ?58??B?n???)K???????????+??> endobj +178 0 obj << +/Ascent 756 +/CapHeight 756 +/Descent -192 +/FontName /EYEBNW+URWGothicL-Demi +/ItalicAngle 0 +/StemV 134 +/XHeight 555 +/FontBBox [-121 -251 1248 1000] +/Flags 4 +/CharSet (/fi/ampersand/quoteright/parenleft/parenright/comma/hyphen/period/zero/one/two/three/four/five/six/seven/eight/nine/colon/A/B/C/D/E/F/G/H/I/J/L/M/O/P/R/S/T/U/W/Y/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/r/s/t/u/v/w/x/y/z/quotedblleft/quotedblright/endash) +/FontFile 179 0 R +>> endobj +692 0 obj +[520 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 680 280 380 380 0 0 280 420 280 0 560 560 560 560 560 560 560 560 560 560 280 0 0 0 0 0 0 740 580 780 700 520 480 840 680 280 480 0 440 900 0 840 560 0 580 520 420 640 0 900 0 620 0 0 0 0 0 0 0 660 660 640 660 640 280 660 600 240 260 580 240 940 600 640 660 0 320 440 300 600 560 800 560 580 460 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 480 480 0 500 ] +endobj +181 0 obj << +/Type /Pages +/Count 6 +/Parent 693 0 R +/Kids [170 0 R 187 0 R 199 0 R 237 0 R 251 0 R 266 0 R] +>> endobj +283 0 obj << +/Type /Pages +/Count 6 +/Parent 693 0 R +/Kids [273 0 R 285 0 R 305 0 R 314 0 R 324 0 R 331 0 R] +>> endobj +345 0 obj << +/Type /Pages +/Count 6 +/Parent 693 0 R +/Kids [336 0 R 349 0 R 359 0 R 373 0 R 380 0 R 392 0 R] +>> endobj +406 0 obj << +/Type /Pages +/Count 6 +/Parent 693 0 R +/Kids [400 0 R 408 0 R 414 0 R 420 0 R 426 0 R 431 0 R] +>> endobj +442 0 obj << +/Type /Pages +/Count 6 +/Parent 693 0 R +/Kids [436 0 R 444 0 R 451 0 R 459 0 R 483 0 R 497 0 R] +>> endobj +515 0 obj << +/Type /Pages +/Count 6 +/Parent 693 0 R +/Kids [504 0 R 520 0 R 525 0 R 531 0 R 544 0 R 552 0 R] +>> endobj +577 0 obj << +/Type /Pages +/Count 6 +/Parent 694 0 R +/Kids [566 0 R 583 0 R 597 0 R 605 0 R 620 0 R 627 0 R] +>> endobj +641 0 obj << +/Type /Pages +/Count 5 +/Parent 694 0 R +/Kids [636 0 R 643 0 R 652 0 R 664 0 R 673 0 R] +>> endobj +693 0 obj << +/Type /Pages +/Count 36 +/Parent 695 0 R +/Kids [181 0 R 283 0 R 345 0 R 406 0 R 442 0 R 515 0 R] +>> endobj +694 0 obj << +/Type /Pages +/Count 11 +/Parent 695 0 R +/Kids [577 0 R 641 0 R] +>> endobj +695 0 obj << +/Type /Pages +/Count 47 +/Kids [693 0 R 694 0 R] +>> endobj +696 0 obj << +/Type /Outlines +/First 7 0 R +/Last 159 0 R +/Count 6 +>> endobj +167 0 obj << +/Title 168 0 R +/A 165 0 R +/Parent 159 0 R +/Prev 163 0 R +>> endobj +163 0 obj << +/Title 164 0 R +/A 161 0 R +/Parent 159 0 R +/Next 167 0 R +>> endobj +159 0 obj << +/Title 160 0 R +/A 157 0 R +/Parent 696 0 R +/Prev 155 0 R +/First 163 0 R +/Last 167 0 R +/Count -2 +>> endobj +155 0 obj << +/Title 156 0 R +/A 153 0 R +/Parent 696 0 R +/Prev 99 0 R +/Next 159 0 R +>> endobj +151 0 obj << +/Title 152 0 R +/A 149 0 R +/Parent 99 0 R +/Prev 123 0 R +>> endobj +147 0 obj << +/Title 148 0 R +/A 145 0 R +/Parent 123 0 R +/Prev 143 0 R +>> endobj +143 0 obj << +/Title 144 0 R +/A 141 0 R +/Parent 123 0 R +/Prev 139 0 R +/Next 147 0 R +>> endobj +139 0 obj << +/Title 140 0 R +/A 137 0 R +/Parent 123 0 R +/Prev 135 0 R +/Next 143 0 R +>> endobj +135 0 obj << +/Title 136 0 R +/A 133 0 R +/Parent 123 0 R +/Prev 131 0 R +/Next 139 0 R +>> endobj +131 0 obj << +/Title 132 0 R +/A 129 0 R +/Parent 123 0 R +/Prev 127 0 R +/Next 135 0 R +>> endobj +127 0 obj << +/Title 128 0 R +/A 125 0 R +/Parent 123 0 R +/Next 131 0 R +>> endobj +123 0 obj << +/Title 124 0 R +/A 121 0 R +/Parent 99 0 R +/Prev 103 0 R +/Next 151 0 R +/First 127 0 R +/Last 147 0 R +/Count -6 +>> endobj +119 0 obj << +/Title 120 0 R +/A 117 0 R +/Parent 103 0 R +/Prev 115 0 R +>> endobj +115 0 obj << +/Title 116 0 R +/A 113 0 R +/Parent 103 0 R +/Prev 111 0 R +/Next 119 0 R +>> endobj +111 0 obj << +/Title 112 0 R +/A 109 0 R +/Parent 103 0 R +/Prev 107 0 R +/Next 115 0 R +>> endobj +107 0 obj << +/Title 108 0 R +/A 105 0 R +/Parent 103 0 R +/Next 111 0 R +>> endobj +103 0 obj << +/Title 104 0 R +/A 101 0 R +/Parent 99 0 R +/Next 123 0 R +/First 107 0 R +/Last 119 0 R +/Count -4 +>> endobj +99 0 obj << +/Title 100 0 R +/A 97 0 R +/Parent 696 0 R +/Prev 27 0 R +/Next 155 0 R +/First 103 0 R +/Last 151 0 R +/Count -3 +>> endobj +95 0 obj << +/Title 96 0 R +/A 93 0 R +/Parent 27 0 R +/Prev 91 0 R +>> endobj +91 0 obj << +/Title 92 0 R +/A 89 0 R +/Parent 27 0 R +/Prev 59 0 R +/Next 95 0 R +>> endobj +87 0 obj << +/Title 88 0 R +/A 85 0 R +/Parent 59 0 R +/Prev 83 0 R +>> endobj +83 0 obj << +/Title 84 0 R +/A 81 0 R +/Parent 59 0 R +/Prev 79 0 R +/Next 87 0 R +>> endobj +79 0 obj << +/Title 80 0 R +/A 77 0 R +/Parent 59 0 R +/Prev 75 0 R +/Next 83 0 R +>> endobj +75 0 obj << +/Title 76 0 R +/A 73 0 R +/Parent 59 0 R +/Prev 71 0 R +/Next 79 0 R +>> endobj +71 0 obj << +/Title 72 0 R +/A 69 0 R +/Parent 59 0 R +/Prev 67 0 R +/Next 75 0 R +>> endobj +67 0 obj << +/Title 68 0 R +/A 65 0 R +/Parent 59 0 R +/Prev 63 0 R +/Next 71 0 R +>> endobj +63 0 obj << +/Title 64 0 R +/A 61 0 R +/Parent 59 0 R +/Next 67 0 R +>> endobj +59 0 obj << +/Title 60 0 R +/A 57 0 R +/Parent 27 0 R +/Prev 35 0 R +/Next 91 0 R +/First 63 0 R +/Last 87 0 R +/Count -7 +>> endobj +55 0 obj << +/Title 56 0 R +/A 53 0 R +/Parent 35 0 R +/Prev 51 0 R +>> endobj +51 0 obj << +/Title 52 0 R +/A 49 0 R +/Parent 35 0 R +/Prev 47 0 R +/Next 55 0 R +>> endobj +47 0 obj << +/Title 48 0 R +/A 45 0 R +/Parent 35 0 R +/Prev 43 0 R +/Next 51 0 R +>> endobj +43 0 obj << +/Title 44 0 R +/A 41 0 R +/Parent 35 0 R +/Prev 39 0 R +/Next 47 0 R +>> endobj +39 0 obj << +/Title 40 0 R +/A 37 0 R +/Parent 35 0 R +/Next 43 0 R +>> endobj +35 0 obj << +/Title 36 0 R +/A 33 0 R +/Parent 27 0 R +/Prev 31 0 R +/Next 59 0 R +/First 39 0 R +/Last 55 0 R +/Count -5 +>> endobj +31 0 obj << +/Title 32 0 R +/A 29 0 R +/Parent 27 0 R +/Next 35 0 R +>> endobj +27 0 obj << +/Title 28 0 R +/A 25 0 R +/Parent 696 0 R +/Prev 11 0 R +/Next 99 0 R +/First 31 0 R +/Last 95 0 R +/Count -5 +>> endobj +23 0 obj << +/Title 24 0 R +/A 21 0 R +/Parent 11 0 R +/Prev 19 0 R +>> endobj +19 0 obj << +/Title 20 0 R +/A 17 0 R +/Parent 11 0 R +/Prev 15 0 R +/Next 23 0 R +>> endobj +15 0 obj << +/Title 16 0 R +/A 13 0 R +/Parent 11 0 R +/Next 19 0 R +>> endobj +11 0 obj << +/Title 12 0 R +/A 9 0 R +/Parent 696 0 R +/Prev 7 0 R +/Next 27 0 R +/First 15 0 R +/Last 23 0 R +/Count -3 +>> endobj +7 0 obj << +/Title 8 0 R +/A 5 0 R +/Parent 696 0 R +/Next 11 0 R +>> endobj +697 0 obj << +/Names [(Doc-Start) 176 0 R (Item.1) 364 0 R (Item.2) 365 0 R (Item.3) 366 0 R (Item.4) 388 0 R (Item.5) 389 0 R (Item.6) 396 0 R (Item.7) 470 0 R (Item.8) 471 0 R (application-level-interface) 303 0 R (cite.AB-OC) 480 0 R (cite.ARCH) 659 0 R (cite.BLANCHET99) 540 0 R (cite.BOEHM) 579 0 R (cite.CGSI) 493 0 R (cite.CHOI99) 541 0 R (cite.CPy) 661 0 R (cite.D04.2) 550 0 R (cite.D05.1) 262 0 R (cite.D05.3) 516 0 R (cite.D05.4) 517 0 R (cite.DEL) 617 0 R (cite.DETREVILLE90) 593 0 R (cite.DHRY) 518 0 R (cite.FRANZ02) 542 0 R (cite.GC) 581 0 R (cite.GCSURV) 580 0 R (cite.JIKES) 595 0 R (cite.LIMBO) 476 0 R (cite.MAS) 494 0 R (cite.MMTK) 578 0 R (cite.MRD) 671 0 R (cite.PICOIL) 322 0 R (cite.PLTWebserver) 479 0 R (cite.PMTPM) 495 0 R (cite.PYLIB) 676 0 R (cite.R5RS) 481 0 R (cite.RCPFCC) 679 0 R (cite.SEDA) 474 0 R (cite.SLP) 390 0 R (cite.SLP0) 301 0 R (cite.SQUEAK) 563 0 R (cite.Seaside) 478 0 R (cite.Twisted) 475 0 R (cite.VMC) 271 0 R (cite.von-Behren-et-al) 477 0 R (composability) 371 0 R (conclusion) 640 0 R (coroutine-cloning) 418 0 R (coroutine-pickling) 347 0 R (coroutines) 346 0 R (escape-analysis-and-stack-allocation) 535 0 R (executive-summary) 255 0 R (figure.1) 631 0 R (finding-roots) 357 0 R (function-inlining) 514 0 R (glossary-of-abbreviations) 648 0 R (greenlets) 398 0 R (id18) 472 0 R (id53) 625 0 R (id9) 320 0 R (interface-to-explicit-stack-manipulations) 328 0 R (introduction) 277 0 R (introduction-stackless-features-for-rpython-programs) 293 0 R (malloc-removal) 529 0 R (memory-management) 356 0 R (microbenchmarks-of-stackless-features) 370 0 R (optimizations) 511 0 R (optimizations-and-memory-management) 264 0 R (page.1) 175 0 R (page.10) 316 0 R (page.11) 326 0 R (page.12) 333 0 R (page.13) 338 0 R (page.14) 351 0 R (page.15) 361 0 R (page.16) 375 0 R (page.17) 382 0 R (page.18) 394 0 R (page.19) 402 0 R (page.2) 189 0 R (page.20) 410 0 R (page.21) 416 0 R (page.22) 422 0 R (page.23) 428 0 R (page.24) 433 0 R (page.25) 438 0 R (page.26) 446 0 R (page.27) 453 0 R (page.28) 461 0 R (page.29) 485 0 R (page.3) 201 0 R (page.30) 499 0 R (page.31) 506 0 R (page.32) 522 0 R (page.33) 527 0 R (page.34) 533 0 R (page.35) 546 0 R (page.36) 554 0 R (page.37) 568 0 R (page.38) 585 0 R (page.39) 599 0 R (page.4) 239 0 R (page.40) 607 0 R (page.41) 622 0 R (page.42) 629 0 R (page.43) 638 0 R (page.44) 645 0 R (page.45) 654 0 R (page.46) 666 0 R (page.47) 197 0 R (page.5) 253 0 R (page.6) 268 0 R (page.7) 275 0 R (page.8) 287 0 R (page.9) 307 0 R (partner-acronyms) 656 0 R (performance-future-work) 616 0 R (performance-impact) 344 0 R (pointer-tagging) 539 0 R (practical-uses-of-massive-parallelism) 457 0 R (purpose-of-this-document) 278 0 R (reference-counting) 574 0 R (related-documents) 280 0 R (related-work) 302 0 R (resume-points) 341 0 R (saving-and-resuming-frames) 309 0 R (scope-of-this-document) 279 0 R (section*.1) 194 0 R (section*.10) 601 0 R (section*.11) 602 0 R (section*.12) 609 0 R (section*.13) 658 0 R (section*.2) 196 0 R (section*.3) 203 0 R (section*.4) 378 0 R (section*.5) 387 0 R (section*.6) 397 0 R (section*.7) 405 0 R (section*.8) 412 0 R (section*.9) 424 0 R (section.1) 6 0 R (section.2) 10 0 R (section.3) 26 0 R (section.4) 98 0 R (section.5) 154 0 R (section.6) 158 0 R (stackless-features) 263 0 R (stackless-transformation) 300 0 R (subsection.2.1) 14 0 R (subsection.2.2) 18 0 R (subsection.2.3) 22 0 R (subsection.3.1) 30 0 R (subsection.3.2) 34 0 R (subsection.3.3) 58 0 R (subsection.3.4) 90 0 R (subsection.3.5) 94 0 R (subsection.4.1) 102 0 R (subsection.4.2) 122 0 R (subsection.4.3) 150 0 R (subsection.6.1) 162 0 R (subsection.6.2) 166 0 R (subsubsection.3.2.1) 38 0 R (subsubsection.3.2.2) 42 0 R (subsubsection.3.2.3) 46 0 R (subsubsection.3.2.4) 50 0 R (subsubsection.3.2.5) 54 0 R (subsubsection.3.3.1) 62 0 R (subsubsection.3.3.2) 66 0 R (subsubsection.3.3.3) 70 0 R (subsubsection.3.3.4) 74 0 R (subsubsection.3.3.5) 78 0 R (subsubsection.3.3.6) 82 0 R (subsubsection.3.3.7) 86 0 R (subsubsection.4.1.1) 106 0 R (subsubsection.4.1.2) 110 0 R (subsubsection.4.1.3) 114 0 R (subsubsection.4.1.4) 118 0 R (subsubsection.4.2.1) 126 0 R (subsubsection.4.2.2) 130 0 R (subsubsection.4.2.3) 134 0 R (subsubsection.4.2.4) 138 0 R (subsubsection.4.2.5) 142 0 R (subsubsection.4.2.6) 146 0 R (table.1) 177 0 R (table.2) 195 0 R (table.3) 363 0 R (table.4) 441 0 R (table.5) 448 0 R (table.6) 449 0 R (table.7) 624 0 R (table.8) 650 0 R (table.9) 657 0 R (tasklets-and-channels) 384 0 R (technical-abbreviations) 649 0 R (the-gc-construction-and-testing-framework) 564 0 R (the-gc-transformer) 562 0 R (the-mark-and-sweep-collector) 594 0 R (the-stackless-transformation) 299 0 R (unbounded-stack) 321 0 R (using-the-conservative-boehm-collector) 572 0 R] +/Limits [(Doc-Start) (using-the-conservative-boehm-collector)] +>> endobj +698 0 obj << +/Kids [697 0 R] +>> endobj +699 0 obj << +/Dests 698 0 R +>> endobj +700 0 obj << +/Type /Catalog +/Pages 695 0 R +/Outlines 696 0 R +/Names 699 0 R +/PageMode /UseOutlines +/OpenAction 169 0 R +>> endobj +701 0 obj << +/Author()/Title()/Subject()/Creator(LaTeX with hyperref package)/Producer(pdfeTeX-1.21a)/Keywords() +/CreationDate (D:20070228172454+01'00') +/PTEX.Fullbanner (This is pdfeTeX, Version 3.141592-1.21a-2.2 (Web2C 7.5.4) kpathsea version 3.5.4) +>> endobj +xref +0 702 +0000000001 65535 f +0000000002 00000 f +0000000003 00000 f +0000000004 00000 f +0000000000 00000 f +0000000009 00000 n +0000039185 00000 n +0000378983 00000 n +0000000054 00000 n +0000000089 00000 n +0000044728 00000 n +0000378860 00000 n +0000000134 00000 n +0000000165 00000 n +0000044853 00000 n +0000378786 00000 n +0000000216 00000 n +0000000259 00000 n +0000044978 00000 n +0000378699 00000 n +0000000310 00000 n +0000000351 00000 n +0000045103 00000 n +0000378625 00000 n +0000000402 00000 n +0000000438 00000 n +0000050406 00000 n +0000378500 00000 n +0000000484 00000 n +0000000521 00000 n +0000050531 00000 n +0000378426 00000 n +0000000572 00000 n +0000000644 00000 n +0000050719 00000 n +0000378302 00000 n +0000000695 00000 n +0000000742 00000 n +0000054970 00000 n +0000378228 00000 n +0000000798 00000 n +0000000843 00000 n +0000064052 00000 n +0000378141 00000 n +0000000899 00000 n +0000000937 00000 n +0000064177 00000 n +0000378054 00000 n +0000000993 00000 n +0000001053 00000 n +0000072303 00000 n +0000377967 00000 n +0000001109 00000 n +0000001141 00000 n +0000072428 00000 n +0000377893 00000 n +0000001197 00000 n +0000001234 00000 n +0000082428 00000 n +0000377769 00000 n +0000001285 00000 n +0000001331 00000 n +0000086271 00000 n +0000377695 00000 n +0000001387 00000 n +0000001416 00000 n +0000089696 00000 n +0000377608 00000 n +0000001472 00000 n +0000001512 00000 n +0000093042 00000 n +0000377521 00000 n +0000001568 00000 n +0000001596 00000 n +0000097032 00000 n +0000377434 00000 n +0000001652 00000 n +0000001689 00000 n +0000104151 00000 n +0000377347 00000 n +0000001745 00000 n +0000001781 00000 n +0000107732 00000 n +0000377260 00000 n +0000001837 00000 n +0000001869 00000 n +0000117217 00000 n +0000377186 00000 n +0000001925 00000 n +0000001981 00000 n +0000125508 00000 n +0000377099 00000 n +0000002032 00000 n +0000002088 00000 n +0000131604 00000 n +0000377025 00000 n +0000002139 00000 n +0000002170 00000 n +0000144638 00000 n +0000376896 00000 n +0000002216 00000 n +0000002271 00000 n +0000144762 00000 n +0000376779 00000 n +0000002323 00000 n +0000002356 00000 n +0000149332 00000 n +0000376700 00000 n +0000002413 00000 n +0000002450 00000 n +0000152614 00000 n +0000376607 00000 n +0000002507 00000 n +0000002541 00000 n +0000157460 00000 n +0000376514 00000 n +0000002598 00000 n +0000002654 00000 n +0000162417 00000 n +0000376435 00000 n +0000002711 00000 n +0000002746 00000 n +0000167940 00000 n +0000376304 00000 n +0000002798 00000 n +0000002835 00000 n +0000168066 00000 n +0000376225 00000 n +0000002892 00000 n +0000002930 00000 n +0000173254 00000 n +0000376132 00000 n +0000002987 00000 n +0000003045 00000 n +0000173379 00000 n +0000376039 00000 n +0000003102 00000 n +0000003140 00000 n +0000178974 00000 n +0000375946 00000 n +0000003197 00000 n +0000003258 00000 n +0000187862 00000 n +0000375853 00000 n +0000003315 00000 n +0000003363 00000 n +0000187988 00000 n +0000375774 00000 n +0000003420 00000 n +0000003468 00000 n +0000192696 00000 n +0000375696 00000 n +0000003520 00000 n +0000003552 00000 n +0000281988 00000 n +0000375604 00000 n +0000003599 00000 n +0000003629 00000 n +0000285829 00000 n +0000375486 00000 n +0000003676 00000 n +0000003721 00000 n +0000285955 00000 n +0000375407 00000 n +0000003773 00000 n +0000003817 00000 n +0000290166 00000 n +0000375328 00000 n +0000003869 00000 n +0000003906 00000 n +0000005276 00000 n +0000005398 00000 n +0000007529 00000 n +0000019104 00000 n +0000003958 00000 n +0000018915 00000 n +0000018978 00000 n +0000019041 00000 n +0000373146 00000 n +0000360252 00000 n +0000372976 00000 n +0000374051 00000 n +0000007246 00000 n +0000018756 00000 n +0000018812 00000 n +0000018892 00000 n +0000022236 00000 n +0000021688 00000 n +0000019233 00000 n +0000021984 00000 n +0000358950 00000 n +0000344617 00000 n +0000358780 00000 n +0000021830 00000 n +0000022047 00000 n +0000022110 00000 n +0000022173 00000 n +0000301732 00000 n +0000031178 00000 n +0000025300 00000 n +0000022365 00000 n +0000031052 00000 n +0000025698 00000 n +0000031115 00000 n +0000025852 00000 n +0000026007 00000 n +0000026162 00000 n +0000026322 00000 n +0000026482 00000 n +0000026642 00000 n +0000026797 00000 n +0000026957 00000 n +0000027117 00000 n +0000027282 00000 n +0000027448 00000 n +0000027614 00000 n +0000027780 00000 n +0000027945 00000 n +0000028105 00000 n +0000028271 00000 n +0000028437 00000 n +0000028602 00000 n +0000028768 00000 n +0000028934 00000 n +0000029100 00000 n +0000029265 00000 n +0000029425 00000 n +0000029585 00000 n +0000029739 00000 n +0000029899 00000 n +0000030065 00000 n +0000030231 00000 n +0000030396 00000 n +0000030562 00000 n +0000030722 00000 n +0000030888 00000 n +0000034465 00000 n +0000032585 00000 n +0000031307 00000 n +0000034402 00000 n +0000032799 00000 n +0000032953 00000 n +0000033119 00000 n +0000033285 00000 n +0000033448 00000 n +0000033614 00000 n +0000033773 00000 n +0000033928 00000 n +0000034082 00000 n +0000034242 00000 n +0000039246 00000 n +0000038239 00000 n +0000034594 00000 n +0000039059 00000 n +0000038405 00000 n +0000039122 00000 n +0000038559 00000 n +0000344297 00000 n +0000342907 00000 n +0000344136 00000 n +0000038716 00000 n +0000038879 00000 n +0000295456 00000 n +0000050343 00000 n +0000144575 00000 n +0000042031 00000 n +0000041510 00000 n +0000039388 00000 n +0000041968 00000 n +0000041660 00000 n +0000041814 00000 n +0000302487 00000 n +0000045165 00000 n +0000043978 00000 n +0000042160 00000 n +0000044602 00000 n +0000044136 00000 n +0000044665 00000 n +0000044790 00000 n +0000044915 00000 n +0000045040 00000 n +0000044290 00000 n +0000044445 00000 n +0000374168 00000 n +0000050781 00000 n +0000048935 00000 n +0000045307 00000 n +0000050280 00000 n +0000049125 00000 n +0000342131 00000 n +0000331658 00000 n +0000341957 00000 n +0000049279 00000 n +0000050468 00000 n +0000049434 00000 n +0000049593 00000 n +0000049763 00000 n +0000049933 00000 n +0000050107 00000 n +0000050593 00000 n +0000050656 00000 n +0000302236 00000 n +0000131541 00000 n +0000082365 00000 n +0000055031 00000 n +0000054548 00000 n +0000050923 00000 n +0000054844 00000 n +0000054690 00000 n +0000054907 00000 n +0000330850 00000 n +0000314627 00000 n +0000330679 00000 n +0000060084 00000 n +0000059267 00000 n +0000055186 00000 n +0000059897 00000 n +0000059425 00000 n +0000059578 00000 n +0000059736 00000 n +0000059960 00000 n +0000060022 00000 n +0000296336 00000 n +0000064239 00000 n +0000063524 00000 n +0000060226 00000 n +0000063989 00000 n +0000063674 00000 n +0000064114 00000 n +0000063827 00000 n +0000067294 00000 n +0000066936 00000 n +0000064394 00000 n +0000067231 00000 n +0000067078 00000 n +0000072490 00000 n +0000071373 00000 n +0000067462 00000 n +0000072178 00000 n +0000071539 00000 n +0000071692 00000 n +0000072241 00000 n +0000071849 00000 n +0000072014 00000 n +0000072365 00000 n +0000374285 00000 n +0000082490 00000 n +0000096969 00000 n +0000077388 00000 n +0000076525 00000 n +0000072645 00000 n +0000077325 00000 n +0000076691 00000 n +0000076844 00000 n +0000077007 00000 n +0000077167 00000 n +0000167877 00000 n +0000302755 00000 n +0000082553 00000 n +0000081204 00000 n +0000077543 00000 n +0000082050 00000 n +0000081370 00000 n +0000082113 00000 n +0000082176 00000 n +0000082239 00000 n +0000082302 00000 n +0000081523 00000 n +0000081707 00000 n +0000081890 00000 n +0000117154 00000 n +0000107670 00000 n +0000086396 00000 n +0000085745 00000 n +0000082695 00000 n +0000086208 00000 n +0000085895 00000 n +0000086048 00000 n +0000086333 00000 n +0000089947 00000 n +0000088950 00000 n +0000086551 00000 n +0000089570 00000 n +0000089108 00000 n +0000089633 00000 n +0000089261 00000 n +0000089414 00000 n +0000089758 00000 n +0000089821 00000 n +0000089884 00000 n +0000302173 00000 n +0000093104 00000 n +0000092495 00000 n +0000090102 00000 n +0000092790 00000 n +0000092637 00000 n +0000092853 00000 n +0000092916 00000 n +0000092979 00000 n +0000097157 00000 n +0000096443 00000 n +0000093246 00000 n +0000096906 00000 n +0000096593 00000 n +0000096746 00000 n +0000097094 00000 n +0000374402 00000 n +0000100058 00000 n +0000099637 00000 n +0000097312 00000 n +0000099932 00000 n +0000099779 00000 n +0000099995 00000 n +0000104212 00000 n +0000103730 00000 n +0000100213 00000 n +0000104025 00000 n +0000103872 00000 n +0000104088 00000 n +0000107793 00000 n +0000107249 00000 n +0000104380 00000 n +0000107544 00000 n +0000107391 00000 n +0000107607 00000 n +0000109825 00000 n +0000109467 00000 n +0000107961 00000 n +0000109762 00000 n +0000109609 00000 n +0000113085 00000 n +0000112727 00000 n +0000109967 00000 n +0000113022 00000 n +0000112869 00000 n +0000117342 00000 n +0000116623 00000 n +0000113240 00000 n +0000117091 00000 n +0000116773 00000 n +0000116926 00000 n +0000117279 00000 n +0000374519 00000 n +0000121215 00000 n +0000120731 00000 n +0000117497 00000 n +0000121026 00000 n +0000120873 00000 n +0000121089 00000 n +0000121152 00000 n +0000125570 00000 n +0000124742 00000 n +0000121357 00000 n +0000125382 00000 n +0000124900 00000 n +0000125053 00000 n +0000125218 00000 n +0000125445 00000 n +0000131666 00000 n +0000129664 00000 n +0000125725 00000 n +0000131290 00000 n +0000129870 00000 n +0000130023 00000 n +0000130178 00000 n +0000130336 00000 n +0000130493 00000 n +0000130661 00000 n +0000130820 00000 n +0000130983 00000 n +0000131353 00000 n +0000131415 00000 n +0000131478 00000 n +0000131137 00000 n +0000302110 00000 n +0000302425 00000 n +0000296084 00000 n +0000302550 00000 n +0000302362 00000 n +0000301795 00000 n +0000290355 00000 n +0000301984 00000 n +0000137226 00000 n +0000135892 00000 n +0000131821 00000 n +0000137163 00000 n +0000136082 00000 n +0000136235 00000 n +0000136387 00000 n +0000136539 00000 n +0000136696 00000 n +0000136852 00000 n +0000137007 00000 n +0000290607 00000 n +0000296147 00000 n +0000301858 00000 n +0000139722 00000 n +0000139032 00000 n +0000137381 00000 n +0000139659 00000 n +0000139190 00000 n +0000139343 00000 n +0000139502 00000 n +0000144887 00000 n +0000143398 00000 n +0000139851 00000 n +0000144512 00000 n +0000143580 00000 n +0000143733 00000 n +0000143889 00000 n +0000144046 00000 n +0000144700 00000 n +0000144201 00000 n +0000144357 00000 n +0000144824 00000 n +0000374636 00000 n +0000295519 00000 n +0000295582 00000 n +0000295770 00000 n +0000149395 00000 n +0000148974 00000 n +0000145016 00000 n +0000149269 00000 n +0000149116 00000 n +0000152677 00000 n +0000152193 00000 n +0000149537 00000 n +0000152488 00000 n +0000152335 00000 n +0000152551 00000 n +0000157585 00000 n +0000156537 00000 n +0000152832 00000 n +0000157334 00000 n +0000156703 00000 n +0000157397 00000 n +0000156856 00000 n +0000157018 00000 n +0000157176 00000 n +0000157523 00000 n +0000290481 00000 n +0000290670 00000 n +0000295833 00000 n +0000162480 00000 n +0000161730 00000 n +0000157727 00000 n +0000162354 00000 n +0000161888 00000 n +0000162041 00000 n +0000162197 00000 n +0000295393 00000 n +0000168129 00000 n +0000166489 00000 n +0000162622 00000 n +0000167814 00000 n +0000166679 00000 n +0000166832 00000 n +0000166989 00000 n +0000167146 00000 n +0000167303 00000 n +0000167468 00000 n +0000167626 00000 n +0000168003 00000 n +0000302299 00000 n +0000178911 00000 n +0000173442 00000 n +0000172018 00000 n +0000168258 00000 n +0000173129 00000 n +0000172200 00000 n +0000172353 00000 n +0000172508 00000 n +0000173192 00000 n +0000172662 00000 n +0000173316 00000 n +0000172819 00000 n +0000172976 00000 n +0000374753 00000 n +0000296210 00000 n +0000290544 00000 n +0000295895 00000 n +0000295958 00000 n +0000179035 00000 n +0000177531 00000 n +0000173597 00000 n +0000178848 00000 n +0000177721 00000 n +0000177874 00000 n +0000178037 00000 n +0000178212 00000 n +0000178386 00000 n +0000178538 00000 n +0000178693 00000 n +0000295708 00000 n +0000187799 00000 n +0000296021 00000 n +0000183184 00000 n +0000182518 00000 n +0000179164 00000 n +0000182995 00000 n +0000182668 00000 n +0000183058 00000 n +0000183121 00000 n +0000182821 00000 n +0000188051 00000 n +0000186887 00000 n +0000183313 00000 n +0000187673 00000 n +0000187053 00000 n +0000187736 00000 n +0000314101 00000 n +0000304675 00000 n +0000313930 00000 n +0000187206 00000 n +0000187360 00000 n +0000187518 00000 n +0000187925 00000 n +0000295645 00000 n +0000193736 00000 n +0000192758 00000 n +0000192213 00000 n +0000188219 00000 n +0000192508 00000 n +0000192355 00000 n +0000192571 00000 n +0000192634 00000 n +0000278041 00000 n +0000193594 00000 n +0000192900 00000 n +0000277914 00000 n +0000277761 00000 n +0000277977 00000 n +0000277507 00000 n +0000277691 00000 n +0000277738 00000 n +0000282051 00000 n +0000281568 00000 n +0000278183 00000 n +0000281863 00000 n +0000281710 00000 n +0000281926 00000 n +0000374870 00000 n +0000286081 00000 n +0000285245 00000 n +0000282180 00000 n +0000285703 00000 n +0000285395 00000 n +0000285548 00000 n +0000285766 00000 n +0000285892 00000 n +0000286018 00000 n +0000290796 00000 n +0000289366 00000 n +0000286210 00000 n +0000290040 00000 n +0000289524 00000 n +0000290103 00000 n +0000290229 00000 n +0000290292 00000 n +0000290418 00000 n +0000289677 00000 n +0000290733 00000 n +0000289868 00000 n +0000296399 00000 n +0000294336 00000 n +0000290938 00000 n +0000295330 00000 n +0000294502 00000 n +0000294655 00000 n +0000294892 00000 n +0000295128 00000 n +0000296273 00000 n +0000302613 00000 n +0000300050 00000 n +0000296541 00000 n +0000300248 00000 n +0000301921 00000 n +0000300401 00000 n +0000300577 00000 n +0000302047 00000 n +0000300769 00000 n +0000300959 00000 n +0000301136 00000 n +0000301326 00000 n +0000301505 00000 n +0000302787 00000 n +0000314395 00000 n +0000331330 00000 n +0000342531 00000 n +0000344530 00000 n +0000344506 00000 n +0000359550 00000 n +0000373599 00000 n +0000374979 00000 n +0000375097 00000 n +0000375183 00000 n +0000375253 00000 n +0000379055 00000 n +0000383890 00000 n +0000383929 00000 n +0000383967 00000 n +0000384097 00000 n +trailer +<< +/Size 702 +/Root 700 0 R +/Info 701 0 R +/ID [<4F621749BB312EA017437467E631C030> <4F621749BB312EA017437467E631C030>] +>> +startxref +384360 +%%EOF From cfbolz at codespeak.net Wed Feb 28 17:23:40 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 28 Feb 2007 17:23:40 +0100 (CET) Subject: [pypy-svn] r39598 - pypy/dist/pypy/doc Message-ID: <20070228162340.B1E821007F@code0.codespeak.net> Author: cfbolz Date: Wed Feb 28 17:23:38 2007 New Revision: 39598 Modified: pypy/dist/pypy/doc/index-report.txt Log: add link to 7.1 report Modified: pypy/dist/pypy/doc/index-report.txt ============================================================================== --- pypy/dist/pypy/doc/index-report.txt (original) +++ pypy/dist/pypy/doc/index-report.txt Wed Feb 28 17:23:38 2007 @@ -12,6 +12,12 @@ Reports of 2007 =============== +`D07.1 Massive Parallelism and Translation Aspects`_ is a report about +PyPy's optimization efforts, garbage collectors and massive parallelism +(stackless) features. This report refers to the paper `PyPy's approach +to virtual machine construction`_. *(2007-02-28)* + + `D09.1 Constraint Solving and Semantic Web`_ is an interim version of a report about PyPy's logic programming and constraint solving features, as well as the work going on to tie semantic web technologies and PyPy together. All @@ -45,11 +51,6 @@ Reports of 2006 =============== -`D07.1 Massive Parallelism and Translation Aspects`_ is a report about -PyPy's optimization efforts, garbage collectors and massive parallelism -(stackless) features. This report refers to the paper `PyPy's approach -to virtual machine construction`_. *(2006-12-15)* - `D14.3 Report about Milestone/Phase 2`_ is the final report about the second phase of the EU project, summarizing and detailing technical, research, dissemination and community aspects. Feedback is very welcome! @@ -95,7 +96,7 @@ .. _`D05.3 Implementation with Translation Aspects`: http://codespeak.net/svn/pypy/extradoc/eu-report/D05.3_Publish_on_implementation_with_translation_aspects.pdf .. _`D05.4 Encapsulating Low Level Aspects`: http://codespeak.net/svn/pypy/extradoc/eu-report/D05.4_Publish_on_encapsulating_low_level_language_aspects.pdf .. _`D14.1 Report about Milestone/Phase 1`: http://codespeak.net/svn/pypy/extradoc/eu-report/D14.1_Report_about_Milestone_Phase_1.pdf -.. _`D07.1 Massive Parallelism and Translation Aspects`: http://codespeak.net/pypy/extradoc/eu-report/D07.1_Massive_Parallelism_and_Translation_Aspects-2006-12-15.pdf +.. _`D07.1 Massive Parallelism and Translation Aspects`: http://codespeak.net/pypy/extradoc/eu-report/D07.1_Massive_Parallelism_and_Translation_Aspects-2007-02-28.pdf .. _`D09.1 Constraint Solving and Semantic Web`: http://codespeak.net/pypy/extradoc/eu-report/D09.1_Constraint_Solving_and_Semantic_Web-interim-2007-02-28.pdf .. _`D14.3 Report about Milestone/Phase 2`: http://codespeak.net/pypy/extradoc/eu-report/D14.3_Report_about_Milestone_Phase_2-final-2006-08-03.pdf .. _`PyPy's approach to virtual machine construction`: http://codespeak.net/svn/pypy/extradoc/talk/dls2006/pypy-vm-construction.pdf From cfbolz at codespeak.net Wed Feb 28 17:25:20 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 28 Feb 2007 17:25:20 +0100 (CET) Subject: [pypy-svn] r39599 - pypy/extradoc/eu-report Message-ID: <20070228162520.41E5710128@code0.codespeak.net> Author: cfbolz Date: Wed Feb 28 17:25:14 2007 New Revision: 39599 Removed: pypy/extradoc/eu-report/D03.1_Extension_Compiler-interim-2007-01-22.pdf pypy/extradoc/eu-report/D07.1_Massive_Parallelism_and_Translation_Aspects-2006-12-15.pdf pypy/extradoc/eu-report/D09.1_Constraint_Solving_and_Semantic_Web-interim-2006-07-28.pdf Log: remove old versions of report From cfbolz at codespeak.net Wed Feb 28 17:37:58 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 28 Feb 2007 17:37:58 +0100 (CET) Subject: [pypy-svn] r39603 - pypy/extradoc/eu-report Message-ID: <20070228163758.74A8210128@code0.codespeak.net> Author: cfbolz Date: Wed Feb 28 17:37:55 2007 New Revision: 39603 Modified: pypy/extradoc/eu-report/D07.1_Massive_Parallelism_and_Translation_Aspects-2007-02-28.pdf Log: regenerate Modified: pypy/extradoc/eu-report/D07.1_Massive_Parallelism_and_Translation_Aspects-2007-02-28.pdf ============================================================================== --- pypy/extradoc/eu-report/D07.1_Massive_Parallelism_and_Translation_Aspects-2007-02-28.pdf (original) +++ pypy/extradoc/eu-report/D07.1_Massive_Parallelism_and_Translation_Aspects-2007-02-28.pdf Wed Feb 28 17:37:55 2007 @@ -249,14 +249,18 @@ << /S /GoTo /D [170 0 R /Fit ] >> endobj 174 0 obj << -/Length 1238 +/Length 1251 /Filter /FlateDecode >> stream -x??W?r?H}?+?U?d?????KW?? ??T?!d??.I??_?=7?1??a?*4Hg?Ow??$??O"??ZDJ0D4?QV?p??g?F?c8?? ?????1?q?aE?B?Qa`??( ???kD?v?7??Ht??nG??`? ?????%??}?o?yl??????I?&5??Nq?????????=??G?5??O(bD?p??F?{cx??K?sD?H ?1*?~?_U??F](eH?_ ??21?????+*#??!?j? ?7_~??'1M??j*c??Rz?s~3??????XG??_? ?!??I;??d at 1? ?:??Hc?? ??? -I?gHO?M??? ,"A@?????=6??? -5? ??I$?5???6O?5??E?r?K???X??g??2?P<~*?p?z?4??????^???c?%?????mB???m??!??0???????y???????uaLyR_,???#??(???n?I|???[???F?=w??>?;?# -z -?QK???*???????h???? ?"?g????@??Q2???Ap??v>2z?f)4%?b+JO?1??}?9&?tB?3jI?????S>T?V;m?????`??6-??,??@?~w?.Ka?!?@!??[wV ???B???*Z'?"Tg;????????????YWdi????P??? ??O ?]`???f;%6i???#1?' |?u[?8k7y????!0R??H?P?O??x@????a9b\??UQM??? ????_:r?[???BBG?????I??????R???$??R??j?8 ??1t???F"???p?u}(??_@??!?!??uA??{I?p???!? 4!M????K_??x??NAy?c?? y?W?|;8??X+%??A~u?g[?? ???????W?ySwF?A|?Q?.?6??~????2<8xh?????3;?`?y????'??~??M???l?|l????z3???r??U?kxjq??z??wW??????{??<)V??????a???cGx??rxU?A?L??0????0?Y@??z???o??????9*?k?FP)???????#'k?6????;E9?Y???2_?>?????w?6yZyT/???a??f?S??M+??G??1?? Ex#N?R/3Os??|?u?9?M?K"???N????oG??????#??8;? ??u0?????+gz? ??<_L#????,?0?R????Mp??$ ?? +????A0C?q?vp)???"'>?$?"?!?7H?O*b8Mz?m????RH` +*f??t???>?;')!?vN0?M???v~??y???I?)??M^j/??zS>?|?????S????+???Y?%?0_????O?3+???tzo"&??b?TDx???[?j[?U^w?????6?H}1?~??|?j?? ??#?u??v5oz?g??m??oO?H?9(?'G ???????.?gD?????^???8_?]? Z?@???X p2?9+G?:????}??? +?9?a9?W&??d?? ??&?????!?:K ?I?c?4??/~8?B??.+m??3|f? ;??;wd\!?? ?Wn?m???M??]??ozWQ?O???jy ?????????]?n?????kxR,?Q?9??T?#????sxU?^/?L??0????0?Y?A????\??o???????k??lE????lu?h}??M@??5c???~T???5?C_?????m8?.{?k????G??e F}?m^?H???> stream x??weP\??-??o?-?]?w??6?H????5? $@???=?K ???[??oK1?t????)? ?q?l???k?-?C?k??rt??O?Z?O at w???k?ZG????p??!i????????????=?d?9q?????? Q??9d??^,????`"?.???3"??p?p???7????vU)4????.???<{?&??I?%??4Z2tP??j?'?K:ry?oB?? gW?=/??r?v F?5"&?'/???s#?Z???#%?? ?x?r???????&P??j??sR?J?????.X??? ?7???6?Km??????,?{??3H??l????????[?Ep?????si?]??aMS???+?o???"p_??? ?????~>S?#\?e?T @@ -4055,7 +4059,7 @@ ?????Cf??[ h????? 7=?)???q?d"lg?&c?U?????cO?V*??K?l??P??+Y?K+^p?g??th????S.?o@??h[? w???@??"?t?E??d @????1z??>???G?H??y?V??sL??D????ww?Z?????}w?? ?U???>h?%?? ??@?"3L?V-?+?4?l)T???K??/?y?p?2?????B?R???????5?p?5u????5?>;?{?? /?'???(?r)[?u"Z/??y??m???.?'??????T+??X0sK??=??Y???????8n?q?_???\?H??$?P???`S_eI?^?? ??,?t,Ud?U!A?-?Q|?????tH,C??H??%,2n]M?^m???/?? ????????o$?!?j})???????lW?R? )Z??%?U/e??? ???V?:&4??`??????[3?t??X?4z?w???t??"????)??k?????>??d -??8???H ?2#????V:???+????7??????:tw?'qWX|.T??;??~,?M??????x\??????`?9???fNvh??l??endstream +??8???H ?2#????V:???+????7??????:tw?'qWX|.T??;??~,?M??????x\??????`?9???fNvh? ???endstream endobj 612 0 obj << /Type /Font @@ -4064,14 +4068,14 @@ /FirstChar 40 /LastChar 121 /Widths 686 0 R -/BaseFont /UQEYQY+NimbusMonL-Bold +/BaseFont /UIMQKK+NimbusMonL-Bold /FontDescriptor 610 0 R >> endobj 610 0 obj << /Ascent 624 /CapHeight 552 /Descent -126 -/FontName /UQEYQY+NimbusMonL-Bold +/FontName /UIMQKK+NimbusMonL-Bold /ItalicAngle 0 /StemV 101 /XHeight 439 @@ -4092,7 +4096,7 @@ >> stream x???ep\??%(ffV?,ff?????R?????bY????`1Y???0??????M????kb*?"????re???D*2e5FQs?)?+????????hmo???r?gTZ??9?????&??  W @ h????????Tq???????+?FCU??????-??L????w???????w?????????F5 ?jXX??J?:2?R)E ???lbPv3??6?[?\?? ?3??? ???????\??b??L.?@3?????f@?\ G???????g?? ??????o\Ak3;7???[??E???7????/?2?????????7?????t?2q?'???_7d?7?d??OI??????u5?vp?=]??e -?[?8??x???????_4?\?,???hi?lntq? ?????g????zGG;???+?r?vu?Y0!????i??7??????"?`????n???>w???D?????%abr???-?A?Sh??????'????-????&???9??????Bu??S4??;??`o@??cg?? 7??????l???Z?????q5?? Q????0???h????h?l?jf?0?????5???v???????FV???S??6?u?????v??+??"??:??????,??S???W{Wu/????G) +?[?8??x???????_4?\?,???hi?lntq? ?????g????zGG;???+?r?vu?Y0!????i??7??????"?`????n???>w???D?????%abr???-?A?Sh??????'????-????&???9??????Bu??S4??;??`o@??cg?? 7??????l???Z?????q5?? Q????0???h????h?l?jf?0?????5???v???????FV???S??6?u?????v??+??"??:????????S???W{Wu/????G) ????CL ? ?a?{???\?????o?? ???? &??????%?????????????t0??3+j?&????q??9;?U?_'?o????????@3??E??MJz?k n????^_+?P?cq?zA^`?; ??o??[uS?$?G???????,??H?u?/?E.?mo???vn??`f?b??S?(??y?M(].???qU??7??vvg??G?@ ??@,?G?????0?????/ G????C?????{??Y1?T??P?_"???u5?}?iaR???.?H??| s?( (#??_?-sW????S????[?*?q?f'#D&yg??W??$]p?&B?n?m)C??a?H??!?h?\~???W????d? O?t?y4??Q?0??U???8?Py??????d?p?Ix??2l????>?7?6p?I?Sf:i?~?}???o?p-??!??x???[???T????"????2????5R[?2????X??Y~N?1q??????p!4S???7?e, @@ -4152,7 +4156,7 @@ ?Q??-????? ??;?????4S???7?*??w at S??k???s?;}C ?+?3s?m)?Ss?!)?k?^???{h7???L?/Pt??37%i?n????APYL`qx??FAoH????P?????mK~Uf$?i???i?a*rl!G?/{?/(O?????6?v??X????????s?d??=??W^???ty?I0??? ????????d???HSiv ?0??\H??|? ?8?????/C?,?C -?_??E?Y?????'???&?? {g[?? L???endstream +?_??E?Y?????'???&?? {g[?? ?k??endstream endobj 312 0 obj << /Type /Font @@ -4161,14 +4165,14 @@ /FirstChar 34 /LastChar 122 /Widths 687 0 R -/BaseFont /ZRZVGJ+NimbusMonL-Regu +/BaseFont /GBKUUO+NimbusMonL-Regu /FontDescriptor 310 0 R >> endobj 310 0 obj << /Ascent 625 /CapHeight 557 /Descent -147 -/FontName /ZRZVGJ+NimbusMonL-Regu +/FontName /GBKUUO+NimbusMonL-Regu /ItalicAngle 0 /StemV 41 /XHeight 426 @@ -4190,7 +4194,7 @@ stream x??veT???-N???pw?@p ??PH????]?'w ????]?=r??}{??_????????s??d?????V?b????? `;7?@[SW?Y??KA vj?? ?3??NO/ ??@?? (?Zd????0:=@??Y??L?,???l???c0w?'??? ??\??G ?L??v?0 ? dH???+????U??@0jfPwy.???????+`?????)????K?`pvZ????n@???u9;??@?k???[??X?I?y? -?WB?P????3?L?q?9[@A?0?sTu?? ?1???? z??gKK????????i?Q?? ??`b?? gG{3????d?P?_i?8?????? Z?A-?????4?????:??z3GG{???!Y?G ?3??????9??9?5???gX?V7???-]????5????0?'af ??,?V????sH??Le??????-?[?????w???!?????S??????9?r?????\3????? ????9????????t??????1E??s3$?????ssq??c?,rZ??`6+3??^??? ?B?A`?????.,?7??sv????? ?-????J?????/?????]?Y?????#???y ????))??????????|????y????q?k?? ? ?8????????ke?7Y?????h?????S?` (?Y???s??\?5?@??}~b!d??? +?WB?P????3?L?q?9[@A?0?sTu?? ?1???? z??gKK????????i?Q?? ??`b?? gG{3????d?P?_i?8?????? Z?A-?????4?????:??z3GG{???!Y?G ?3??????9??9?5???gX?V7???-]????5????0?'af ??,?V????sH??Le??????-?[?????w???!?????S??????9?r?????\3????? ????9????????t??????1E??s3$?????ssq??c?,rZ??`6+3??^??? ?B?A`?????.,?7??sv????? ?-????J??)#?&+????]?Y?????#???y ????))??????????|????y????q?k?? ? ?8????????ke?7Y?????h?????S?` (?Y???s??\?5?@??}~b!d??? ? ???1?h?F? v?Z?.??? ????"\????U???qj??*????w????{{?[O??7?X?G????"a1D?9}&?0?QW??t@???J5Y?;y???b??)g???J?Z?[?????Z }a?a?????9L'??K?'??F???????,~k??L ??M???t??*?6???Mxd\9&aE?r?? ?9??%??????CV_? l!?_s4K?r:)?f?qJ[T_ ????3m???Z???H????|fo??zUVst?p?9-?W ?Qz?uAM????~?*7???]lxo-???t_???(?p??$e?#?+???_"vvP.??]~?*n*Oi??E?_L??????8??*>????h?{\??_??q??s?????%??3DX??d??H?c??c.?????,?"9l??"??&Q??>? ,?|??F??o??????yT???#????7??eeDE?e_?ULE?z???0?F`???w?H???5?{?:K?K?+?U?CIm&A]??4?0?v6?????? ??MD}Hg??@???'^???4Rg???Ts@?????h [W??J8??(?v" ?? Y????_??8?O/?L??".{}?-?m?P???N??O?8]A??H?g s x???k???<v?ZfySKc??8+?}A?????j"xbz??ZK??????????????6x??; u?,?_?M???Y?i;?VM|???C[???? ?5?N??,9n????P?#??)??W?*??/???????o_?? 7???C?????????2?p ???^?irGr^?s?>?bY%????c?????????',??fP?? j??????endstream +F?/?q??W?kr???| 4?Z????w??6?????rNx?????????"?????O?b?i??7g???J?? O????In??"??????or??????2?!t??r?%/?????J??`???I?@)?p??xl? 1,>>?bY%????c?????????',??fP?? j??m3?fendstream endobj 291 0 obj << /Type /Font @@ -4237,14 +4241,14 @@ /FirstChar 2 /LastChar 121 /Widths 688 0 R -/BaseFont /WJYAOH+URWGothicL-BookObli +/BaseFont /DCOEAY+URWGothicL-BookObli /FontDescriptor 289 0 R >> endobj 289 0 obj << /Ascent 752 /CapHeight 752 /Descent -206 -/FontName /WJYAOH+URWGothicL-BookObli +/FontName /DCOEAY+URWGothicL-BookObli /ItalicAngle -10.5 /StemV 78 /XHeight 547 @@ -4266,11 +4270,11 @@ stream x?SU ?uL?OJu??+?5?3?Rp? ?44P0?3?RUu.JM,???sI,I?R0??4Tp,MW04U00?22?25?RUp?/?,?L?(Q?p?)2Wp?M-?LN?S?M,?H??????????ZR???????Q??Z?ZT????eh????\????????r?g^Z??9D8??&U?ZT t????? @'????T*???q????J???B7??4'?/1d<8?0?s3s*?*?s JKR?|?SR??????B????Y??.?Y???????????kh?g`l -??,v??HM ?,I?PHK?)N?????;|`???;??x?jC?,???WRY??`?P ?"??P*??P?6?300*B+?2???????t#S3?????J.` +??,v??HM ?,I?PHK?)N?????;|`??{z??DjC?,???WRY??`?P ?"??P*??P?6?300*B+?2???????t#S3?????J.` ?L? 2?RR+R+?.????/jQM?BZ~(Z??I? ??% q.L?89?WT?Y*?Z? 644S077?EQ?\ZT??WN+?????2?A??Z???u?Z~?uK??mm+?\_X????????7?D?????Rl:/P1?d????????(??l=U?h?d?_O??E?k?v-X1??t???`????i????_y. ?1?????????:?un~Q???3/??S??}??]?? ???$e~s?]F1????/??Q???m????|<?????/??q'}I???+6???E??g???xT.??G??gt???v??G??U|?????~??]?R????_k?9???:?{?p??G?? ??d}dN<6??-uB?o?H??=c?M?vH??z?q?a???RK?~,K???}????????m??????yo??~?????v? ?_????s>???.#????????{?/?????k????\m?|??r???X???????ad?j|?????R/?,2?p?0, H?IM,*??M,??`Brcendstream +??-??????W???d?????_?~?+ ????i?s?s?`??C???u?I^>??\m?|??r???X???????ad?j|?????R/?,2?p?0, H?IM,*??M,??K?r?endstream endobj 259 0 obj << /Type /Font @@ -4279,14 +4283,14 @@ /FirstChar 15 /LastChar 15 /Widths 690 0 R -/BaseFont /GBFLIM+CMSY10 +/BaseFont /IKTLPY+CMSY10 /FontDescriptor 257 0 R >> endobj 257 0 obj << /Ascent 750 /CapHeight 683 /Descent -194 -/FontName /GBFLIM+CMSY10 +/FontName /IKTLPY+CMSY10 /ItalicAngle -14.035 /StemV 85 /XHeight 431 @@ -4310,8 +4314,9 @@ /Filter /FlateDecode >> stream -x??zeP???. ????????????????? 6??????r????g??????n???????'?????;?????2????P???????????.a?lna,K/lgg?4?????8 ?-?lE ???u? @h `a0sqq??D??=-???T????t???0??w??J' 3[???hmgo?u????^? ???S k @D??????JB^ ?:Z??Y[d-???N at j???#????????_?91|b 9 N?@c??e at wc??_.:?=??????s ?p?9?:???`akl?b??O???????>#l>}?`??????-???Y??????????_??,>?;??H;c??J??? ??u6??u8????e?X8?[z|???w????????????f??&?@'?O?O?????:??zC{{k??W???,????? ??,?9???s?Y??2??Q?lM??L??????????w????3??$ M?l?=&@SXFy;?????;???D?_??E??y?g???F???O???B??X[???^?? ??u???PC k????q?????0?? ?? dk?)???N??@?o???SC???mW?5:Z[??????z.?q?|R?????l????&???S??Y3j+? -+???U?w??O??U???r?8:~???Q?,????p ?h ??`g?l????\??30&???? 6????V? ?????/5l??????;C??{???????4??P?5eg2?<????;e????v/?Q?!?D=??bNv\??ImokLQI???`?????????5??????8?w Frj???????{???????+??]:?e????+H61?7BVB??T?0?t??C?Z?15?Y#??KR?J?G???{:?V?KK??Bk???w?9??????????g??]???;?????ah?.?U_/aH??I?h0?{p???0??nP\#}??v?1?? M-????P????_???U????>Ek??s?h,?%?47j}ii??1^)O?J]e%^?oR;r"??? 1q???lY_` ?>?Y??Nn???-??????;r?:??????s!???Y?Nj?d???V?5??ri(q1?(?y??w??2$??? r?????????#l>}?`??????-???Y??????????_??,>?;??H;c??J??? ??u6??u8????e?X8?[z|???w????????????f??&?@'?O?O?????:??zC{{k??W???,????? ??,?9???s?Y??2??Q?lM??L??????????w????3??$ M?l?=&@SXFy;?????;???D?_??E??y?g???F???O???B??X[???^?? ??u???PC k????q?????0?? ?? dk?)???N??@?o???SC???mW?5:Z[??????z.?q?|R?????l????&???S??Y3 +?k ++????U?w??O??U???r?8:~???Q?,????p ?h ??`g?l????\??30&???? 6????V? ?????/5l??????;C??{???????4??P?5eg2?<????;e????v/?Q?!?D=??bNv\??ImokLQI???`?????????5??????8?w Frj???????{???????+??]:?e????+H61?7BVB??T?0?t??C?Z?15?Y#??KR?J?G???{:?V?KK??Bk???w?9??????????g??]???;?????ah?.?U_/aH??I?h0?{p???0??nP\#}??v?1?? M-????P????_???U????>Ek??s?h,?%?47j}ii??1^)O?J]e%^?oR;r"??? 1q???lY_` ?>?Y??Nn???-??????;r?:??????s!???Y?Nj?d???V?5??ri(q1?(?y??w??2$??? r?????????/?"?ATu&d??@"???x?7n30?A??#???+?UI???9?,?WQd??*?s????Z????B ?Gy?v??}?????TG}?[?????]$N?v6???A??@h?"R?_1 ? s????2j?????????zi?[??er???n?YU?R ??(?????????%??????:rw~?-??c6;?????m ?????BU???3???????' @@ -4363,7 +4368,7 @@ /??B??;???? fm??f??lI{??ze"id???v???Ve?`?;??0e;?????;k6??kUj?7!7???^B???k??.1? Q#???v??T????:???X???;????2;j?3??a?M?????????? ?=???=???BM???????_?&z?p?Xg?!CE?5Hh[AO+f?^_?u???BU?????????&qg?????|K??f - ??%b?Z???]??=2W?????`P??Z????^?N?8?WP&??&?Qi??/??1[?1\???.?????????r???)#?!????????? g??????> endobj 190 0 obj << /Ascent 752 /CapHeight 752 /Descent -206 -/FontName /XBQUBO+URWGothicL-Book +/FontName /BNYBRU+URWGothicL-Book /ItalicAngle 0 /StemV 74 /XHeight 547 @@ -4403,7 +4408,7 @@ ??Vi?%?? ?) ?B ?rv????B o???,??????w?[??? @???ttvq? o???Z@ b X?9Rj? ?r9U??;??-?,?v?@??`? 8???tY????????????{KzZ]?r?\?`';7??o???l???? ?Y:?[?E??n??7!??[???? L?? ?f ?s????K???'???Wm7?77???-????????????y!?v 7? ???`e???h??V? ?l?7 w7;?????@s??#??? ? ?????O?????????l??????? ?h?????V??V???????(??????[??????{@ ? ? s+g??? h???? y+ `??S??O????W?_??&??j??.???>?+?????????$??^?2??'????;?9z??????????1???M6???d?7?G?oN??[????M?p_ ???d@??L????`:z??R???C????_?=??I???f?/!H????????C??1a??4Rry"???#d?1??&V???3????J?? ?E??:????????6 ?^?6~?H???0?????kWjz???0vw;Q?d'????%?)?v\???Xn??????S??) _24Y??????I??m?}???d=???h??|7???????????);???~G??? A?????'??Py5?_kr?????t???I??a?}?3??Z}???????C??'B(?2???i?q? :???F????%i#??L??#6????W?`,9H`x?L???{???????`?Qz???L;e???????/?aP??lI?pq?~???? ??? d?C??o?Pw?9???]2????dR&??(?h????Bi&;?^?\?????[?.?M?i?????d}]??$?\Eg??M??&?????j???K?A=?D?h??J??q?????7F???.j4? GW???????? +M$???oQ4?P?$z?U-" a?Sg? 5?;[!UA????O?n?????@\WMD????k??t?X[dN???3?-K?????{n^???3;r$?tt?D0??L??p??M=|??#>??m??,i8A?%??n??>????n8s??/????????Via? ?6 at 1G??P?*(?????$?{??#?? h+\?? Q??u?\X?[???7gN??;Y?*-B???O?V? ???W?X?\}?u#? ???u???k!"??n?).X0I38[??b??2?$??A?M+6?R??0????Y?????????]?5 Gh?L?M ?8??N\|O??M???G.)?/\?#???NLMU?"?vqa;?-Ng?T?i?S??y??\ZSL???~?????z}?k???4?b??=#?u???oF????? ??G?!0??Z?H"l?K???Wd??CL??????(?? ??&?????#a?}J?4?OQ :??J?w??????????)??? WEf?t[?0?/????]?2"#?W?}?7@????? `???????Q,?Z????v?2 $???d??8?svE??)/????`?x???D?>@T???51X&D?{0??????D]?/? ??LJ?%?Q ?r+f$?q?%? ? E??????????!R^f??????{0???f??K??76|gun1?)d??I?y?????? ?X???h?0(M??-?????*???c_#hO4=??sr??p?????m?B??jQl-XMU?R??????>????????j??????+?? ???0????????eb??f?;? _?a??K???n???fS O:??P?Ti?'??x??5GV????$a$"?<hL????I?????vU???i??I?~??E???d?A6-?^???thl????H?A?'X? ???*x??/?#,??????1Yo??NJarh?[?n!???? ????x?U??&d??0v???O????H????]????s???IR@???u?a?????6[?.?? ?;???@??.?s??;???B????2???????%)i????C\5??=W!?*?(}??q+??/?*????##?????[?'z???????{??S?????????8??C?z??d?2 ?q?J?^n??%????^z? ? ?n?Gp=G9? ?p ?58??B?n???)K???????????+??> endobj 178 0 obj << /Ascent 756 /CapHeight 756 /Descent -192 -/FontName /EYEBNW+URWGothicL-Demi +/FontName /NQESNX+URWGothicL-Demi /ItalicAngle 0 /StemV 134 /XHeight 555 @@ -4854,7 +4859,7 @@ >> endobj 701 0 obj << /Author()/Title()/Subject()/Creator(LaTeX with hyperref package)/Producer(pdfeTeX-1.21a)/Keywords() -/CreationDate (D:20070228172454+01'00') +/CreationDate (D:20070228174150+01'00') /PTEX.Fullbanner (This is pdfeTeX, Version 3.141592-1.21a-2.2 (Web2C 7.5.4) kpathsea version 3.5.4) >> endobj xref @@ -4865,709 +4870,709 @@ 0000000004 00000 f 0000000000 00000 f 0000000009 00000 n -0000039185 00000 n -0000378983 00000 n +0000039198 00000 n +0000378996 00000 n 0000000054 00000 n 0000000089 00000 n -0000044728 00000 n -0000378860 00000 n +0000044741 00000 n +0000378873 00000 n 0000000134 00000 n 0000000165 00000 n -0000044853 00000 n -0000378786 00000 n +0000044866 00000 n +0000378799 00000 n 0000000216 00000 n 0000000259 00000 n -0000044978 00000 n -0000378699 00000 n +0000044991 00000 n +0000378712 00000 n 0000000310 00000 n 0000000351 00000 n -0000045103 00000 n -0000378625 00000 n +0000045116 00000 n +0000378638 00000 n 0000000402 00000 n 0000000438 00000 n -0000050406 00000 n -0000378500 00000 n +0000050419 00000 n +0000378513 00000 n 0000000484 00000 n 0000000521 00000 n -0000050531 00000 n -0000378426 00000 n +0000050544 00000 n +0000378439 00000 n 0000000572 00000 n 0000000644 00000 n -0000050719 00000 n -0000378302 00000 n +0000050732 00000 n +0000378315 00000 n 0000000695 00000 n 0000000742 00000 n -0000054970 00000 n -0000378228 00000 n +0000054983 00000 n +0000378241 00000 n 0000000798 00000 n 0000000843 00000 n -0000064052 00000 n -0000378141 00000 n +0000064065 00000 n +0000378154 00000 n 0000000899 00000 n 0000000937 00000 n -0000064177 00000 n -0000378054 00000 n +0000064190 00000 n +0000378067 00000 n 0000000993 00000 n 0000001053 00000 n -0000072303 00000 n -0000377967 00000 n +0000072316 00000 n +0000377980 00000 n 0000001109 00000 n 0000001141 00000 n -0000072428 00000 n -0000377893 00000 n +0000072441 00000 n +0000377906 00000 n 0000001197 00000 n 0000001234 00000 n -0000082428 00000 n -0000377769 00000 n +0000082441 00000 n +0000377782 00000 n 0000001285 00000 n 0000001331 00000 n -0000086271 00000 n -0000377695 00000 n +0000086284 00000 n +0000377708 00000 n 0000001387 00000 n 0000001416 00000 n -0000089696 00000 n -0000377608 00000 n +0000089709 00000 n +0000377621 00000 n 0000001472 00000 n 0000001512 00000 n -0000093042 00000 n -0000377521 00000 n +0000093055 00000 n +0000377534 00000 n 0000001568 00000 n 0000001596 00000 n -0000097032 00000 n -0000377434 00000 n +0000097045 00000 n +0000377447 00000 n 0000001652 00000 n 0000001689 00000 n -0000104151 00000 n -0000377347 00000 n +0000104164 00000 n +0000377360 00000 n 0000001745 00000 n 0000001781 00000 n -0000107732 00000 n -0000377260 00000 n +0000107745 00000 n +0000377273 00000 n 0000001837 00000 n 0000001869 00000 n -0000117217 00000 n -0000377186 00000 n +0000117230 00000 n +0000377199 00000 n 0000001925 00000 n 0000001981 00000 n -0000125508 00000 n -0000377099 00000 n +0000125521 00000 n +0000377112 00000 n 0000002032 00000 n 0000002088 00000 n -0000131604 00000 n -0000377025 00000 n +0000131617 00000 n +0000377038 00000 n 0000002139 00000 n 0000002170 00000 n -0000144638 00000 n -0000376896 00000 n +0000144651 00000 n +0000376909 00000 n 0000002216 00000 n 0000002271 00000 n -0000144762 00000 n -0000376779 00000 n +0000144775 00000 n +0000376792 00000 n 0000002323 00000 n 0000002356 00000 n -0000149332 00000 n -0000376700 00000 n +0000149345 00000 n +0000376713 00000 n 0000002413 00000 n 0000002450 00000 n -0000152614 00000 n -0000376607 00000 n +0000152627 00000 n +0000376620 00000 n 0000002507 00000 n 0000002541 00000 n -0000157460 00000 n -0000376514 00000 n +0000157473 00000 n +0000376527 00000 n 0000002598 00000 n 0000002654 00000 n -0000162417 00000 n -0000376435 00000 n +0000162430 00000 n +0000376448 00000 n 0000002711 00000 n 0000002746 00000 n -0000167940 00000 n -0000376304 00000 n +0000167953 00000 n +0000376317 00000 n 0000002798 00000 n 0000002835 00000 n -0000168066 00000 n -0000376225 00000 n +0000168079 00000 n +0000376238 00000 n 0000002892 00000 n 0000002930 00000 n -0000173254 00000 n -0000376132 00000 n +0000173267 00000 n +0000376145 00000 n 0000002987 00000 n 0000003045 00000 n -0000173379 00000 n -0000376039 00000 n +0000173392 00000 n +0000376052 00000 n 0000003102 00000 n 0000003140 00000 n -0000178974 00000 n -0000375946 00000 n +0000178987 00000 n +0000375959 00000 n 0000003197 00000 n 0000003258 00000 n -0000187862 00000 n -0000375853 00000 n +0000187875 00000 n +0000375866 00000 n 0000003315 00000 n 0000003363 00000 n -0000187988 00000 n -0000375774 00000 n +0000188001 00000 n +0000375787 00000 n 0000003420 00000 n 0000003468 00000 n -0000192696 00000 n -0000375696 00000 n +0000192709 00000 n +0000375709 00000 n 0000003520 00000 n 0000003552 00000 n -0000281988 00000 n -0000375604 00000 n +0000282001 00000 n +0000375617 00000 n 0000003599 00000 n 0000003629 00000 n -0000285829 00000 n -0000375486 00000 n +0000285842 00000 n +0000375499 00000 n 0000003676 00000 n 0000003721 00000 n -0000285955 00000 n -0000375407 00000 n +0000285968 00000 n +0000375420 00000 n 0000003773 00000 n 0000003817 00000 n -0000290166 00000 n -0000375328 00000 n +0000290179 00000 n +0000375341 00000 n 0000003869 00000 n 0000003906 00000 n -0000005276 00000 n -0000005398 00000 n -0000007529 00000 n -0000019104 00000 n +0000005289 00000 n +0000005411 00000 n +0000007542 00000 n +0000019117 00000 n 0000003958 00000 n -0000018915 00000 n -0000018978 00000 n -0000019041 00000 n -0000373146 00000 n -0000360252 00000 n -0000372976 00000 n -0000374051 00000 n -0000007246 00000 n -0000018756 00000 n -0000018812 00000 n -0000018892 00000 n -0000022236 00000 n -0000021688 00000 n -0000019233 00000 n -0000021984 00000 n -0000358950 00000 n -0000344617 00000 n -0000358780 00000 n -0000021830 00000 n -0000022047 00000 n -0000022110 00000 n -0000022173 00000 n -0000301732 00000 n -0000031178 00000 n -0000025300 00000 n -0000022365 00000 n -0000031052 00000 n -0000025698 00000 n -0000031115 00000 n -0000025852 00000 n -0000026007 00000 n -0000026162 00000 n -0000026322 00000 n -0000026482 00000 n -0000026642 00000 n -0000026797 00000 n -0000026957 00000 n -0000027117 00000 n -0000027282 00000 n -0000027448 00000 n -0000027614 00000 n -0000027780 00000 n -0000027945 00000 n -0000028105 00000 n -0000028271 00000 n -0000028437 00000 n -0000028602 00000 n -0000028768 00000 n -0000028934 00000 n -0000029100 00000 n -0000029265 00000 n -0000029425 00000 n -0000029585 00000 n -0000029739 00000 n -0000029899 00000 n -0000030065 00000 n -0000030231 00000 n -0000030396 00000 n -0000030562 00000 n -0000030722 00000 n -0000030888 00000 n -0000034465 00000 n -0000032585 00000 n -0000031307 00000 n -0000034402 00000 n -0000032799 00000 n -0000032953 00000 n -0000033119 00000 n -0000033285 00000 n -0000033448 00000 n -0000033614 00000 n -0000033773 00000 n -0000033928 00000 n -0000034082 00000 n -0000034242 00000 n -0000039246 00000 n -0000038239 00000 n -0000034594 00000 n -0000039059 00000 n -0000038405 00000 n -0000039122 00000 n -0000038559 00000 n -0000344297 00000 n -0000342907 00000 n -0000344136 00000 n -0000038716 00000 n -0000038879 00000 n -0000295456 00000 n -0000050343 00000 n -0000144575 00000 n -0000042031 00000 n -0000041510 00000 n -0000039388 00000 n -0000041968 00000 n -0000041660 00000 n -0000041814 00000 n -0000302487 00000 n -0000045165 00000 n -0000043978 00000 n -0000042160 00000 n -0000044602 00000 n -0000044136 00000 n -0000044665 00000 n -0000044790 00000 n -0000044915 00000 n -0000045040 00000 n -0000044290 00000 n -0000044445 00000 n -0000374168 00000 n -0000050781 00000 n -0000048935 00000 n -0000045307 00000 n -0000050280 00000 n -0000049125 00000 n -0000342131 00000 n -0000331658 00000 n -0000341957 00000 n -0000049279 00000 n -0000050468 00000 n -0000049434 00000 n -0000049593 00000 n -0000049763 00000 n -0000049933 00000 n -0000050107 00000 n -0000050593 00000 n -0000050656 00000 n -0000302236 00000 n -0000131541 00000 n -0000082365 00000 n -0000055031 00000 n -0000054548 00000 n -0000050923 00000 n -0000054844 00000 n -0000054690 00000 n -0000054907 00000 n -0000330850 00000 n -0000314627 00000 n -0000330679 00000 n -0000060084 00000 n -0000059267 00000 n -0000055186 00000 n -0000059897 00000 n -0000059425 00000 n -0000059578 00000 n -0000059736 00000 n -0000059960 00000 n -0000060022 00000 n -0000296336 00000 n -0000064239 00000 n -0000063524 00000 n -0000060226 00000 n -0000063989 00000 n -0000063674 00000 n -0000064114 00000 n -0000063827 00000 n -0000067294 00000 n -0000066936 00000 n -0000064394 00000 n -0000067231 00000 n -0000067078 00000 n -0000072490 00000 n -0000071373 00000 n -0000067462 00000 n -0000072178 00000 n -0000071539 00000 n -0000071692 00000 n -0000072241 00000 n -0000071849 00000 n -0000072014 00000 n -0000072365 00000 n -0000374285 00000 n -0000082490 00000 n -0000096969 00000 n -0000077388 00000 n -0000076525 00000 n -0000072645 00000 n -0000077325 00000 n -0000076691 00000 n -0000076844 00000 n -0000077007 00000 n -0000077167 00000 n -0000167877 00000 n -0000302755 00000 n -0000082553 00000 n -0000081204 00000 n -0000077543 00000 n -0000082050 00000 n -0000081370 00000 n -0000082113 00000 n -0000082176 00000 n -0000082239 00000 n -0000082302 00000 n -0000081523 00000 n -0000081707 00000 n -0000081890 00000 n -0000117154 00000 n -0000107670 00000 n -0000086396 00000 n -0000085745 00000 n -0000082695 00000 n -0000086208 00000 n -0000085895 00000 n -0000086048 00000 n -0000086333 00000 n -0000089947 00000 n -0000088950 00000 n -0000086551 00000 n -0000089570 00000 n -0000089108 00000 n -0000089633 00000 n -0000089261 00000 n -0000089414 00000 n -0000089758 00000 n -0000089821 00000 n -0000089884 00000 n -0000302173 00000 n -0000093104 00000 n -0000092495 00000 n -0000090102 00000 n -0000092790 00000 n -0000092637 00000 n -0000092853 00000 n -0000092916 00000 n -0000092979 00000 n -0000097157 00000 n -0000096443 00000 n -0000093246 00000 n -0000096906 00000 n -0000096593 00000 n -0000096746 00000 n -0000097094 00000 n -0000374402 00000 n -0000100058 00000 n -0000099637 00000 n -0000097312 00000 n -0000099932 00000 n -0000099779 00000 n -0000099995 00000 n -0000104212 00000 n -0000103730 00000 n -0000100213 00000 n -0000104025 00000 n -0000103872 00000 n -0000104088 00000 n -0000107793 00000 n -0000107249 00000 n -0000104380 00000 n -0000107544 00000 n -0000107391 00000 n -0000107607 00000 n -0000109825 00000 n -0000109467 00000 n -0000107961 00000 n -0000109762 00000 n -0000109609 00000 n -0000113085 00000 n -0000112727 00000 n -0000109967 00000 n -0000113022 00000 n -0000112869 00000 n -0000117342 00000 n -0000116623 00000 n -0000113240 00000 n -0000117091 00000 n -0000116773 00000 n -0000116926 00000 n -0000117279 00000 n -0000374519 00000 n -0000121215 00000 n -0000120731 00000 n -0000117497 00000 n -0000121026 00000 n -0000120873 00000 n -0000121089 00000 n -0000121152 00000 n -0000125570 00000 n -0000124742 00000 n -0000121357 00000 n -0000125382 00000 n -0000124900 00000 n -0000125053 00000 n -0000125218 00000 n -0000125445 00000 n -0000131666 00000 n -0000129664 00000 n -0000125725 00000 n -0000131290 00000 n -0000129870 00000 n -0000130023 00000 n -0000130178 00000 n -0000130336 00000 n -0000130493 00000 n -0000130661 00000 n -0000130820 00000 n -0000130983 00000 n -0000131353 00000 n -0000131415 00000 n -0000131478 00000 n -0000131137 00000 n -0000302110 00000 n -0000302425 00000 n -0000296084 00000 n -0000302550 00000 n -0000302362 00000 n -0000301795 00000 n -0000290355 00000 n -0000301984 00000 n -0000137226 00000 n -0000135892 00000 n -0000131821 00000 n -0000137163 00000 n -0000136082 00000 n -0000136235 00000 n -0000136387 00000 n -0000136539 00000 n -0000136696 00000 n -0000136852 00000 n -0000137007 00000 n -0000290607 00000 n -0000296147 00000 n -0000301858 00000 n -0000139722 00000 n -0000139032 00000 n -0000137381 00000 n -0000139659 00000 n -0000139190 00000 n -0000139343 00000 n -0000139502 00000 n -0000144887 00000 n -0000143398 00000 n -0000139851 00000 n -0000144512 00000 n -0000143580 00000 n -0000143733 00000 n -0000143889 00000 n -0000144046 00000 n -0000144700 00000 n -0000144201 00000 n -0000144357 00000 n -0000144824 00000 n -0000374636 00000 n -0000295519 00000 n -0000295582 00000 n -0000295770 00000 n -0000149395 00000 n -0000148974 00000 n -0000145016 00000 n -0000149269 00000 n -0000149116 00000 n -0000152677 00000 n -0000152193 00000 n -0000149537 00000 n -0000152488 00000 n -0000152335 00000 n -0000152551 00000 n -0000157585 00000 n -0000156537 00000 n -0000152832 00000 n -0000157334 00000 n -0000156703 00000 n -0000157397 00000 n -0000156856 00000 n -0000157018 00000 n -0000157176 00000 n -0000157523 00000 n -0000290481 00000 n -0000290670 00000 n -0000295833 00000 n -0000162480 00000 n -0000161730 00000 n -0000157727 00000 n -0000162354 00000 n -0000161888 00000 n -0000162041 00000 n -0000162197 00000 n -0000295393 00000 n -0000168129 00000 n -0000166489 00000 n -0000162622 00000 n -0000167814 00000 n -0000166679 00000 n -0000166832 00000 n -0000166989 00000 n -0000167146 00000 n -0000167303 00000 n -0000167468 00000 n -0000167626 00000 n -0000168003 00000 n -0000302299 00000 n -0000178911 00000 n -0000173442 00000 n -0000172018 00000 n -0000168258 00000 n -0000173129 00000 n -0000172200 00000 n -0000172353 00000 n -0000172508 00000 n -0000173192 00000 n -0000172662 00000 n -0000173316 00000 n -0000172819 00000 n -0000172976 00000 n -0000374753 00000 n -0000296210 00000 n -0000290544 00000 n -0000295895 00000 n -0000295958 00000 n -0000179035 00000 n -0000177531 00000 n -0000173597 00000 n -0000178848 00000 n -0000177721 00000 n -0000177874 00000 n -0000178037 00000 n -0000178212 00000 n -0000178386 00000 n -0000178538 00000 n -0000178693 00000 n -0000295708 00000 n -0000187799 00000 n -0000296021 00000 n -0000183184 00000 n -0000182518 00000 n -0000179164 00000 n -0000182995 00000 n -0000182668 00000 n -0000183058 00000 n -0000183121 00000 n -0000182821 00000 n -0000188051 00000 n -0000186887 00000 n -0000183313 00000 n -0000187673 00000 n -0000187053 00000 n -0000187736 00000 n -0000314101 00000 n -0000304675 00000 n -0000313930 00000 n -0000187206 00000 n -0000187360 00000 n -0000187518 00000 n -0000187925 00000 n -0000295645 00000 n -0000193736 00000 n -0000192758 00000 n -0000192213 00000 n -0000188219 00000 n -0000192508 00000 n -0000192355 00000 n -0000192571 00000 n -0000192634 00000 n -0000278041 00000 n -0000193594 00000 n -0000192900 00000 n -0000277914 00000 n -0000277761 00000 n -0000277977 00000 n -0000277507 00000 n -0000277691 00000 n -0000277738 00000 n -0000282051 00000 n -0000281568 00000 n -0000278183 00000 n -0000281863 00000 n -0000281710 00000 n -0000281926 00000 n -0000374870 00000 n -0000286081 00000 n -0000285245 00000 n -0000282180 00000 n -0000285703 00000 n -0000285395 00000 n -0000285548 00000 n -0000285766 00000 n -0000285892 00000 n -0000286018 00000 n -0000290796 00000 n -0000289366 00000 n -0000286210 00000 n -0000290040 00000 n -0000289524 00000 n -0000290103 00000 n -0000290229 00000 n -0000290292 00000 n -0000290418 00000 n -0000289677 00000 n -0000290733 00000 n -0000289868 00000 n -0000296399 00000 n -0000294336 00000 n -0000290938 00000 n -0000295330 00000 n -0000294502 00000 n -0000294655 00000 n -0000294892 00000 n -0000295128 00000 n -0000296273 00000 n -0000302613 00000 n -0000300050 00000 n -0000296541 00000 n -0000300248 00000 n -0000301921 00000 n -0000300401 00000 n -0000300577 00000 n -0000302047 00000 n -0000300769 00000 n -0000300959 00000 n -0000301136 00000 n -0000301326 00000 n -0000301505 00000 n -0000302787 00000 n -0000314395 00000 n -0000331330 00000 n -0000342531 00000 n -0000344530 00000 n -0000344506 00000 n -0000359550 00000 n -0000373599 00000 n -0000374979 00000 n -0000375097 00000 n -0000375183 00000 n -0000375253 00000 n -0000379055 00000 n -0000383890 00000 n -0000383929 00000 n -0000383967 00000 n -0000384097 00000 n +0000018928 00000 n +0000018991 00000 n +0000019054 00000 n +0000373159 00000 n +0000360265 00000 n +0000372989 00000 n +0000374064 00000 n +0000007259 00000 n +0000018769 00000 n +0000018825 00000 n +0000018905 00000 n +0000022249 00000 n +0000021701 00000 n +0000019246 00000 n +0000021997 00000 n +0000358963 00000 n +0000344630 00000 n +0000358793 00000 n +0000021843 00000 n +0000022060 00000 n +0000022123 00000 n +0000022186 00000 n +0000301745 00000 n +0000031191 00000 n +0000025313 00000 n +0000022378 00000 n +0000031065 00000 n +0000025711 00000 n +0000031128 00000 n +0000025865 00000 n +0000026020 00000 n +0000026175 00000 n +0000026335 00000 n +0000026495 00000 n +0000026655 00000 n +0000026810 00000 n +0000026970 00000 n +0000027130 00000 n +0000027295 00000 n +0000027461 00000 n +0000027627 00000 n +0000027793 00000 n +0000027958 00000 n +0000028118 00000 n +0000028284 00000 n +0000028450 00000 n +0000028615 00000 n +0000028781 00000 n +0000028947 00000 n +0000029113 00000 n +0000029278 00000 n +0000029438 00000 n +0000029598 00000 n +0000029752 00000 n +0000029912 00000 n +0000030078 00000 n +0000030244 00000 n +0000030409 00000 n +0000030575 00000 n +0000030735 00000 n +0000030901 00000 n +0000034478 00000 n +0000032598 00000 n +0000031320 00000 n +0000034415 00000 n +0000032812 00000 n +0000032966 00000 n +0000033132 00000 n +0000033298 00000 n +0000033461 00000 n +0000033627 00000 n +0000033786 00000 n +0000033941 00000 n +0000034095 00000 n +0000034255 00000 n +0000039259 00000 n +0000038252 00000 n +0000034607 00000 n +0000039072 00000 n +0000038418 00000 n +0000039135 00000 n +0000038572 00000 n +0000344310 00000 n +0000342920 00000 n +0000344149 00000 n +0000038729 00000 n +0000038892 00000 n +0000295469 00000 n +0000050356 00000 n +0000144588 00000 n +0000042044 00000 n +0000041523 00000 n +0000039401 00000 n +0000041981 00000 n +0000041673 00000 n +0000041827 00000 n +0000302500 00000 n +0000045178 00000 n +0000043991 00000 n +0000042173 00000 n +0000044615 00000 n +0000044149 00000 n +0000044678 00000 n +0000044803 00000 n +0000044928 00000 n +0000045053 00000 n +0000044303 00000 n +0000044458 00000 n +0000374181 00000 n +0000050794 00000 n +0000048948 00000 n +0000045320 00000 n +0000050293 00000 n +0000049138 00000 n +0000342144 00000 n +0000331671 00000 n +0000341970 00000 n +0000049292 00000 n +0000050481 00000 n +0000049447 00000 n +0000049606 00000 n +0000049776 00000 n +0000049946 00000 n +0000050120 00000 n +0000050606 00000 n +0000050669 00000 n +0000302249 00000 n +0000131554 00000 n +0000082378 00000 n +0000055044 00000 n +0000054561 00000 n +0000050936 00000 n +0000054857 00000 n +0000054703 00000 n +0000054920 00000 n +0000330863 00000 n +0000314640 00000 n +0000330692 00000 n +0000060097 00000 n +0000059280 00000 n +0000055199 00000 n +0000059910 00000 n +0000059438 00000 n +0000059591 00000 n +0000059749 00000 n +0000059973 00000 n +0000060035 00000 n +0000296349 00000 n +0000064252 00000 n +0000063537 00000 n +0000060239 00000 n +0000064002 00000 n +0000063687 00000 n +0000064127 00000 n +0000063840 00000 n +0000067307 00000 n +0000066949 00000 n +0000064407 00000 n +0000067244 00000 n +0000067091 00000 n +0000072503 00000 n +0000071386 00000 n +0000067475 00000 n +0000072191 00000 n +0000071552 00000 n +0000071705 00000 n +0000072254 00000 n +0000071862 00000 n +0000072027 00000 n +0000072378 00000 n +0000374298 00000 n +0000082503 00000 n +0000096982 00000 n +0000077401 00000 n +0000076538 00000 n +0000072658 00000 n +0000077338 00000 n +0000076704 00000 n +0000076857 00000 n +0000077020 00000 n +0000077180 00000 n +0000167890 00000 n +0000302768 00000 n +0000082566 00000 n +0000081217 00000 n +0000077556 00000 n +0000082063 00000 n +0000081383 00000 n +0000082126 00000 n +0000082189 00000 n +0000082252 00000 n +0000082315 00000 n +0000081536 00000 n +0000081720 00000 n +0000081903 00000 n +0000117167 00000 n +0000107683 00000 n +0000086409 00000 n +0000085758 00000 n +0000082708 00000 n +0000086221 00000 n +0000085908 00000 n +0000086061 00000 n +0000086346 00000 n +0000089960 00000 n +0000088963 00000 n +0000086564 00000 n +0000089583 00000 n +0000089121 00000 n +0000089646 00000 n +0000089274 00000 n +0000089427 00000 n +0000089771 00000 n +0000089834 00000 n +0000089897 00000 n +0000302186 00000 n +0000093117 00000 n +0000092508 00000 n +0000090115 00000 n +0000092803 00000 n +0000092650 00000 n +0000092866 00000 n +0000092929 00000 n +0000092992 00000 n +0000097170 00000 n +0000096456 00000 n +0000093259 00000 n +0000096919 00000 n +0000096606 00000 n +0000096759 00000 n +0000097107 00000 n +0000374415 00000 n +0000100071 00000 n +0000099650 00000 n +0000097325 00000 n +0000099945 00000 n +0000099792 00000 n +0000100008 00000 n +0000104225 00000 n +0000103743 00000 n +0000100226 00000 n +0000104038 00000 n +0000103885 00000 n +0000104101 00000 n +0000107806 00000 n +0000107262 00000 n +0000104393 00000 n +0000107557 00000 n +0000107404 00000 n +0000107620 00000 n +0000109838 00000 n +0000109480 00000 n +0000107974 00000 n +0000109775 00000 n +0000109622 00000 n +0000113098 00000 n +0000112740 00000 n +0000109980 00000 n +0000113035 00000 n +0000112882 00000 n +0000117355 00000 n +0000116636 00000 n +0000113253 00000 n +0000117104 00000 n +0000116786 00000 n +0000116939 00000 n +0000117292 00000 n +0000374532 00000 n +0000121228 00000 n +0000120744 00000 n +0000117510 00000 n +0000121039 00000 n +0000120886 00000 n +0000121102 00000 n +0000121165 00000 n +0000125583 00000 n +0000124755 00000 n +0000121370 00000 n +0000125395 00000 n +0000124913 00000 n +0000125066 00000 n +0000125231 00000 n +0000125458 00000 n +0000131679 00000 n +0000129677 00000 n +0000125738 00000 n +0000131303 00000 n +0000129883 00000 n +0000130036 00000 n +0000130191 00000 n +0000130349 00000 n +0000130506 00000 n +0000130674 00000 n +0000130833 00000 n +0000130996 00000 n +0000131366 00000 n +0000131428 00000 n +0000131491 00000 n +0000131150 00000 n +0000302123 00000 n +0000302438 00000 n +0000296097 00000 n +0000302563 00000 n +0000302375 00000 n +0000301808 00000 n +0000290368 00000 n +0000301997 00000 n +0000137239 00000 n +0000135905 00000 n +0000131834 00000 n +0000137176 00000 n +0000136095 00000 n +0000136248 00000 n +0000136400 00000 n +0000136552 00000 n +0000136709 00000 n +0000136865 00000 n +0000137020 00000 n +0000290620 00000 n +0000296160 00000 n +0000301871 00000 n +0000139735 00000 n +0000139045 00000 n +0000137394 00000 n +0000139672 00000 n +0000139203 00000 n +0000139356 00000 n +0000139515 00000 n +0000144900 00000 n +0000143411 00000 n +0000139864 00000 n +0000144525 00000 n +0000143593 00000 n +0000143746 00000 n +0000143902 00000 n +0000144059 00000 n +0000144713 00000 n +0000144214 00000 n +0000144370 00000 n +0000144837 00000 n +0000374649 00000 n +0000295532 00000 n +0000295595 00000 n +0000295783 00000 n +0000149408 00000 n +0000148987 00000 n +0000145029 00000 n +0000149282 00000 n +0000149129 00000 n +0000152690 00000 n +0000152206 00000 n +0000149550 00000 n +0000152501 00000 n +0000152348 00000 n +0000152564 00000 n +0000157598 00000 n +0000156550 00000 n +0000152845 00000 n +0000157347 00000 n +0000156716 00000 n +0000157410 00000 n +0000156869 00000 n +0000157031 00000 n +0000157189 00000 n +0000157536 00000 n +0000290494 00000 n +0000290683 00000 n +0000295846 00000 n +0000162493 00000 n +0000161743 00000 n +0000157740 00000 n +0000162367 00000 n +0000161901 00000 n +0000162054 00000 n +0000162210 00000 n +0000295406 00000 n +0000168142 00000 n +0000166502 00000 n +0000162635 00000 n +0000167827 00000 n +0000166692 00000 n +0000166845 00000 n +0000167002 00000 n +0000167159 00000 n +0000167316 00000 n +0000167481 00000 n +0000167639 00000 n +0000168016 00000 n +0000302312 00000 n +0000178924 00000 n +0000173455 00000 n +0000172031 00000 n +0000168271 00000 n +0000173142 00000 n +0000172213 00000 n +0000172366 00000 n +0000172521 00000 n +0000173205 00000 n +0000172675 00000 n +0000173329 00000 n +0000172832 00000 n +0000172989 00000 n +0000374766 00000 n +0000296223 00000 n +0000290557 00000 n +0000295908 00000 n +0000295971 00000 n +0000179048 00000 n +0000177544 00000 n +0000173610 00000 n +0000178861 00000 n +0000177734 00000 n +0000177887 00000 n +0000178050 00000 n +0000178225 00000 n +0000178399 00000 n +0000178551 00000 n +0000178706 00000 n +0000295721 00000 n +0000187812 00000 n +0000296034 00000 n +0000183197 00000 n +0000182531 00000 n +0000179177 00000 n +0000183008 00000 n +0000182681 00000 n +0000183071 00000 n +0000183134 00000 n +0000182834 00000 n +0000188064 00000 n +0000186900 00000 n +0000183326 00000 n +0000187686 00000 n +0000187066 00000 n +0000187749 00000 n +0000314114 00000 n +0000304688 00000 n +0000313943 00000 n +0000187219 00000 n +0000187373 00000 n +0000187531 00000 n +0000187938 00000 n +0000295658 00000 n +0000193749 00000 n +0000192771 00000 n +0000192226 00000 n +0000188232 00000 n +0000192521 00000 n +0000192368 00000 n +0000192584 00000 n +0000192647 00000 n +0000278054 00000 n +0000193607 00000 n +0000192913 00000 n +0000277927 00000 n +0000277774 00000 n +0000277990 00000 n +0000277520 00000 n +0000277704 00000 n +0000277751 00000 n +0000282064 00000 n +0000281581 00000 n +0000278196 00000 n +0000281876 00000 n +0000281723 00000 n +0000281939 00000 n +0000374883 00000 n +0000286094 00000 n +0000285258 00000 n +0000282193 00000 n +0000285716 00000 n +0000285408 00000 n +0000285561 00000 n +0000285779 00000 n +0000285905 00000 n +0000286031 00000 n +0000290809 00000 n +0000289379 00000 n +0000286223 00000 n +0000290053 00000 n +0000289537 00000 n +0000290116 00000 n +0000290242 00000 n +0000290305 00000 n +0000290431 00000 n +0000289690 00000 n +0000290746 00000 n +0000289881 00000 n +0000296412 00000 n +0000294349 00000 n +0000290951 00000 n +0000295343 00000 n +0000294515 00000 n +0000294668 00000 n +0000294905 00000 n +0000295141 00000 n +0000296286 00000 n +0000302626 00000 n +0000300063 00000 n +0000296554 00000 n +0000300261 00000 n +0000301934 00000 n +0000300414 00000 n +0000300590 00000 n +0000302060 00000 n +0000300782 00000 n +0000300972 00000 n +0000301149 00000 n +0000301339 00000 n +0000301518 00000 n +0000302800 00000 n +0000314408 00000 n +0000331343 00000 n +0000342544 00000 n +0000344543 00000 n +0000344519 00000 n +0000359563 00000 n +0000373612 00000 n +0000374992 00000 n +0000375110 00000 n +0000375196 00000 n +0000375266 00000 n +0000379068 00000 n +0000383903 00000 n +0000383942 00000 n +0000383980 00000 n +0000384110 00000 n trailer << /Size 702 /Root 700 0 R /Info 701 0 R -/ID [<4F621749BB312EA017437467E631C030> <4F621749BB312EA017437467E631C030>] +/ID [ ] >> startxref -384360 +384373 %%EOF From afayolle at codespeak.net Wed Feb 28 18:30:52 2007 From: afayolle at codespeak.net (afayolle at codespeak.net) Date: Wed, 28 Feb 2007 18:30:52 +0100 (CET) Subject: [pypy-svn] r39609 - in pypy/dist/pypy: config doc/config interpreter interpreter/astcompiler interpreter/pyparser interpreter/pyparser/test interpreter/stablecompiler module/dyngram module/recparser module/recparser/hooksamples module/recparser/test Message-ID: <20070228173052.717EB1012F@code0.codespeak.net> Author: afayolle Date: Wed Feb 28 18:30:48 2007 New Revision: 39609 Added: pypy/dist/pypy/doc/config/objspace.usemodules.dyngram.txt (contents, props changed) pypy/dist/pypy/interpreter/pyparser/asthelper.py (contents, props changed) pypy/dist/pypy/interpreter/pyparser/test/expressions.py (contents, props changed) pypy/dist/pypy/interpreter/pyparser/test/test_parser.py (contents, props changed) pypy/dist/pypy/module/dyngram/ (props changed) pypy/dist/pypy/module/dyngram/__init__.py (contents, props changed) pypy/dist/pypy/module/recparser/hooksamples/ (props changed) pypy/dist/pypy/module/recparser/hooksamples/constchanger.py (contents, props changed) pypy/dist/pypy/module/recparser/hooksamples/tracer.py (contents, props changed) pypy/dist/pypy/module/recparser/test/test_dyn_grammarrules.py (contents, props changed) Modified: pypy/dist/pypy/config/pypyoption.py pypy/dist/pypy/interpreter/astcompiler/ast.py pypy/dist/pypy/interpreter/astcompiler/ast.txt pypy/dist/pypy/interpreter/astcompiler/astgen.py pypy/dist/pypy/interpreter/pycompiler.py pypy/dist/pypy/interpreter/pyparser/astbuilder.py pypy/dist/pypy/interpreter/pyparser/ebnfgrammar.py pypy/dist/pypy/interpreter/pyparser/ebnflexer.py pypy/dist/pypy/interpreter/pyparser/ebnfparse.py pypy/dist/pypy/interpreter/pyparser/grammar.py pypy/dist/pypy/interpreter/pyparser/pysymbol.py pypy/dist/pypy/interpreter/pyparser/pythonlexer.py pypy/dist/pypy/interpreter/pyparser/pythonparse.py pypy/dist/pypy/interpreter/pyparser/pythonutil.py pypy/dist/pypy/interpreter/pyparser/pytoken.py pypy/dist/pypy/interpreter/pyparser/syntaxtree.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_lookahead.py pypy/dist/pypy/interpreter/pyparser/test/test_pytokenizer.py pypy/dist/pypy/interpreter/pyparser/test/test_samples.py pypy/dist/pypy/interpreter/pyparser/tuplebuilder.py pypy/dist/pypy/interpreter/stablecompiler/transformer.py pypy/dist/pypy/module/recparser/__init__.py pypy/dist/pypy/module/recparser/codegen.py pypy/dist/pypy/module/recparser/compat.py pypy/dist/pypy/module/recparser/pyparser.py pypy/dist/pypy/module/recparser/test/test_parser.py Log: merge ast-experiments branch in the trunk. The ast branch being in a weird state, I'm merging this by hand (as suggested on IRC by mwh and cfbolz). Here follows the commit messages for the ast-experiments branch. ------------------------------------------------------------------------ r39399 | afayolle | 2007-02-26 08:45:45 +0100 (lun, 26 f?v 2007) | 5 lines merge trunk with branch svn merge -r 38798:39398 svn+ssh://codespeak.net/svn/pypy/dist ------------------------------------------------------------------------ r39210 | mwh | 2007-02-19 15:49:22 +0100 (lun, 19 f?v 2007) | 2 lines fix shallow failures in test_dyn_grammarrules.py ------------------------------------------------------------------------ r38879 | adim | 2007-02-15 14:26:12 +0100 (jeu, 15 f?v 2007) | 1 line small doc for the --withmod-dyngram option ------------------------------------------------------------------------ r38877 | adim | 2007-02-15 14:13:49 +0100 (jeu, 15 f?v 2007) | 4 lines - made a special "dyngram" module that exports the runtime grammar modifications ability ------------------------------------------------------------------------ r38854 | adim | 2007-02-14 17:33:38 +0100 (mer, 14 f?v 2007) | 7 lines merged revision 38798 into the branch fixed pyparser's unit tests (svn merge -r 35032:38798 http://codespeak.net/svn/pypy/dist) ------------------------------------------------------------------------ r38796 | adim | 2007-02-14 11:53:28 +0100 (mer, 14 f?v 2007) | 1 line small rpython fixes ------------------------------------------------------------------------ r36913 | syt | 2007-01-18 10:07:03 +0100 (jeu, 18 jan 2007) | 1 line make abstract builder wrappable ------------------------------------------------------------------------ r36912 | syt | 2007-01-18 10:06:29 +0100 (jeu, 18 jan 2007) | 1 line fix target ------------------------------------------------------------------------ r36911 | syt | 2007-01-18 10:05:45 +0100 (jeu, 18 jan 2007) | 5 lines Leysin sprint work: more tests and bug fixes on the parser package ------------------------------------------------------------------------ r36910 | syt | 2007-01-18 10:01:45 +0100 (jeu, 18 jan 2007) | 5 lines Leysin sprint work (mwh around): refactoring and fixes to make it tranlatable (not yet there though) ------------------------------------------------------------------------ r36451 | adim | 2007-01-11 10:36:52 +0100 (jeu, 11 jan 2007) | 1 line try to avoid using global PYTHON_PARSER ------------------------------------------------------------------------ r36450 | adim | 2007-01-11 10:34:19 +0100 (jeu, 11 jan 2007) | 2 lines use parser's tokens dict and get rid of setattr() usage in pytoken ------------------------------------------------------------------------ r35939 | adim | 2006-12-21 17:40:55 +0100 (jeu, 21 d?c 2006) | 1 line renamed get_pyparser_for_version to make_pyparser ------------------------------------------------------------------------ r35934 | adim | 2006-12-21 16:19:02 +0100 (jeu, 21 d?c 2006) | 2 lines added a hook to modify the grammar rules at applevel ------------------------------------------------------------------------ r35933 | adim | 2006-12-21 16:13:54 +0100 (jeu, 21 d?c 2006) | 5 lines - added a reference to the parser in AstBuilder, and tried to avoid using PYTHON_PARSER as much as possible. - split astbuilder.py in 2 modules ------------------------------------------------------------------------ r35754 | adim | 2006-12-14 17:28:05 +0100 (jeu, 14 d?c 2006) | 6 lines small pyparser refactorings - removed some unused code - eased a bit python parser creation (build_parser / get_pyparser) ------------------------------------------------------------------------ r35729 | adim | 2006-12-14 11:17:18 +0100 (jeu, 14 d?c 2006) | 1 line removing old / unused code ------------------------------------------------------------------------ r35066 | adim | 2006-11-28 10:56:19 +0100 (mar, 28 nov 2006) | 4 lines for some reason, svn failed to completly commit the merge yesterday :-( This is the second part of the merge ------------------------------------------------------------------------ r35047 | adim | 2006-11-27 18:15:58 +0100 (lun, 27 nov 2006) | 6 lines merging revision 35032 into the branch Note: still need to backport keyword management from trunk (svn merge -r 22393:35032 http://codespeak.net/svn/pypy/dist) ------------------------------------------------------------------------ r22813 | ludal | 2006-01-29 02:21:18 +0100 (dim, 29 jan 2006) | 4 lines refactoring III most tests pass. a problem remains with TupleBuilder messing on import xxx ------------------------------------------------------------------------ r22790 | ludal | 2006-01-28 15:13:53 +0100 (sam, 28 jan 2006) | 4 lines refactor, part II forgot the parser class make pythonlexer.py use it ------------------------------------------------------------------------ r22761 | ludal | 2006-01-28 02:10:44 +0100 (sam, 28 jan 2006) | 4 lines big refactoring, of the parser -- part I isolates management of symbols and grammar rules into a Parser class ------------------------------------------------------------------------ r22604 | adim | 2006-01-24 17:28:50 +0100 (mar, 24 jan 2006) | 1 line oops, forgot to checkin tracer update ------------------------------------------------------------------------ r22583 | ludal | 2006-01-24 13:18:01 +0100 (mar, 24 jan 2006) | 2 lines bugfixes ------------------------------------------------------------------------ r22570 | adim | 2006-01-24 10:55:56 +0100 (mar, 24 jan 2006) | 1 line updated assign tracer example with insert_before / insert_after ------------------------------------------------------------------------ r22556 | adim | 2006-01-24 09:52:24 +0100 (mar, 24 jan 2006) | 3 lines added insert_after and insert_before methods on appropriate Node classes (exposed those methods at applevel) ------------------------------------------------------------------------ r22540 | ludal | 2006-01-23 18:14:22 +0100 (lun, 23 jan 2006) | 4 lines (ludal,adim) debugging and first attempt to replace old with new grammar parser ------------------------------------------------------------------------ r22533 | ludal | 2006-01-23 16:42:50 +0100 (lun, 23 jan 2006) | 5 lines (adim,ludal) a new (not yet annotatable) EBNFParser that will build grammar parsers at runtime ------------------------------------------------------------------------ r22399 | adim | 2006-01-18 17:27:36 +0100 (mer, 18 jan 2006) | 4 lines - added a parent attribute to AST nodes - added a few hook examples (they will probably be used as a basis for improvements) ------------------------------------------------------------------------ r22393 | adim | 2006-01-18 16:36:14 +0100 (mer, 18 jan 2006) | 3 lines create a branch to explore ast manipulation without having to make sure PyPy compiles before each checkin ------------------------------------------------------------------------ Modified: pypy/dist/pypy/config/pypyoption.py ============================================================================== --- pypy/dist/pypy/config/pypyoption.py (original) +++ pypy/dist/pypy/config/pypyoption.py Wed Feb 28 18:30:48 2007 @@ -24,7 +24,7 @@ working_modules = default_modules.copy() working_modules.update(dict.fromkeys( ["rsocket", "unicodedata", "mmap", "fcntl", "rctime", "select", - "crypt", "signal", + "crypt", "signal", "dyngram", ] )) Added: pypy/dist/pypy/doc/config/objspace.usemodules.dyngram.txt ============================================================================== --- (empty file) +++ pypy/dist/pypy/doc/config/objspace.usemodules.dyngram.txt Wed Feb 28 18:30:48 2007 @@ -0,0 +1,7 @@ +Use the 'dyngram' module. + +The 'dyngram' module exports the 'insert_grammar_rule' function to +application-level code. This function allows to modify dynamically +the python the grammar. + + Modified: pypy/dist/pypy/interpreter/astcompiler/ast.py ============================================================================== --- pypy/dist/pypy/interpreter/astcompiler/ast.py (original) +++ pypy/dist/pypy/interpreter/astcompiler/ast.py Wed Feb 28 18:30:48 2007 @@ -30,6 +30,7 @@ def __init__(self, lineno = -1): self.lineno = lineno self.filename = "" + self.parent = None #self.scope = None def getChildren(self): @@ -61,6 +62,12 @@ def descr_repr( self, space ): return space.wrap( self.__repr__() ) + def fget_parent(space, self): + return space.wrap(self.parent) + + def fset_parent(space, self, w_parent): + self.parent = space.interp_w(Node, w_parent, can_be_None=False) + def descr_getChildNodes( self, space ): lst = self.getChildNodes() return space.newlist( [ space.wrap( it ) for it in lst ] ) @@ -84,6 +91,7 @@ mutate = interp2app(descr_node_mutate, unwrap_spec=[ ObjSpace, W_Root, W_Root ] ), lineno = interp_attrproperty('lineno', cls=Node), filename = interp_attrproperty('filename', cls=Node), + parent=GetSetProperty(Node.fget_parent, Node.fset_parent), ) Node.typedef.acceptable_as_base_class = False @@ -363,6 +371,15 @@ del self.nodes[:] for w_itm in space.unpackiterable(w_arg): self.nodes.append( space.interp_w(Node, w_itm)) + def descr_insert_after(space, self, node, w_added_nodes): + added_nodes = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_added_nodes)] + index = self.nodes.index(node) + 1 + self.nodes[index:index] = added_nodes + + def descr_insert_before(space, self, node, w_added_nodes): + added_nodes = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_added_nodes)] + index = self.nodes.index(node) + self.nodes[index:index] = added_nodes def descr_And_new(space, w_subtype, w_nodes, lineno=-1): self = space.allocate_instance(And, w_subtype) @@ -391,6 +408,8 @@ accept=interp2app(descr_And_accept, unwrap_spec=[ObjSpace, W_Root, W_Root] ), mutate=interp2app(descr_And_mutate, unwrap_spec=[ObjSpace, W_Root, W_Root] ), nodes=GetSetProperty(And.fget_nodes, And.fset_nodes ), + insert_after=interp2app(And.descr_insert_after.im_func, unwrap_spec=[ObjSpace, And, Node, W_Root]), + insert_before=interp2app(And.descr_insert_before.im_func, unwrap_spec=[ObjSpace, And, Node, W_Root]), ) And.typedef.acceptable_as_base_class = False @@ -536,6 +555,15 @@ del self.nodes[:] for w_itm in space.unpackiterable(w_arg): self.nodes.append( space.interp_w(Node, w_itm)) + def descr_insert_after(space, self, node, w_added_nodes): + added_nodes = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_added_nodes)] + index = self.nodes.index(node) + 1 + self.nodes[index:index] = added_nodes + + def descr_insert_before(space, self, node, w_added_nodes): + added_nodes = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_added_nodes)] + index = self.nodes.index(node) + self.nodes[index:index] = added_nodes def descr_AssList_new(space, w_subtype, w_nodes, lineno=-1): self = space.allocate_instance(AssList, w_subtype) @@ -564,6 +592,8 @@ accept=interp2app(descr_AssList_accept, unwrap_spec=[ObjSpace, W_Root, W_Root] ), mutate=interp2app(descr_AssList_mutate, unwrap_spec=[ObjSpace, W_Root, W_Root] ), nodes=GetSetProperty(AssList.fget_nodes, AssList.fset_nodes ), + insert_after=interp2app(AssList.descr_insert_after.im_func, unwrap_spec=[ObjSpace, AssList, Node, W_Root]), + insert_before=interp2app(AssList.descr_insert_before.im_func, unwrap_spec=[ObjSpace, AssList, Node, W_Root]), ) AssList.typedef.acceptable_as_base_class = False @@ -671,6 +701,15 @@ del self.nodes[:] for w_itm in space.unpackiterable(w_arg): self.nodes.append( space.interp_w(Node, w_itm)) + def descr_insert_after(space, self, node, w_added_nodes): + added_nodes = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_added_nodes)] + index = self.nodes.index(node) + 1 + self.nodes[index:index] = added_nodes + + def descr_insert_before(space, self, node, w_added_nodes): + added_nodes = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_added_nodes)] + index = self.nodes.index(node) + self.nodes[index:index] = added_nodes def descr_AssTuple_new(space, w_subtype, w_nodes, lineno=-1): self = space.allocate_instance(AssTuple, w_subtype) @@ -699,6 +738,8 @@ accept=interp2app(descr_AssTuple_accept, unwrap_spec=[ObjSpace, W_Root, W_Root] ), mutate=interp2app(descr_AssTuple_mutate, unwrap_spec=[ObjSpace, W_Root, W_Root] ), nodes=GetSetProperty(AssTuple.fget_nodes, AssTuple.fset_nodes ), + insert_after=interp2app(AssTuple.descr_insert_after.im_func, unwrap_spec=[ObjSpace, AssTuple, Node, W_Root]), + insert_before=interp2app(AssTuple.descr_insert_before.im_func, unwrap_spec=[ObjSpace, AssTuple, Node, W_Root]), ) AssTuple.typedef.acceptable_as_base_class = False @@ -820,6 +861,15 @@ del self.nodes[:] for w_itm in space.unpackiterable(w_arg): self.nodes.append( space.interp_w(Node, w_itm)) + def descr_insert_after(space, self, node, w_added_nodes): + added_nodes = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_added_nodes)] + index = self.nodes.index(node) + 1 + self.nodes[index:index] = added_nodes + + def descr_insert_before(space, self, node, w_added_nodes): + added_nodes = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_added_nodes)] + index = self.nodes.index(node) + self.nodes[index:index] = added_nodes def fget_expr( space, self): return space.wrap(self.expr) def fset_expr( space, self, w_arg): @@ -858,6 +908,8 @@ accept=interp2app(descr_Assign_accept, unwrap_spec=[ObjSpace, W_Root, W_Root] ), mutate=interp2app(descr_Assign_mutate, unwrap_spec=[ObjSpace, W_Root, W_Root] ), nodes=GetSetProperty(Assign.fget_nodes, Assign.fset_nodes ), + insert_after=interp2app(Assign.descr_insert_after.im_func, unwrap_spec=[ObjSpace, Assign, Node, W_Root]), + insert_before=interp2app(Assign.descr_insert_before.im_func, unwrap_spec=[ObjSpace, Assign, Node, W_Root]), expr=GetSetProperty(Assign.fget_expr, Assign.fset_expr ), ) Assign.typedef.acceptable_as_base_class = False @@ -1100,6 +1152,15 @@ del self.nodes[:] for w_itm in space.unpackiterable(w_arg): self.nodes.append( space.interp_w(Node, w_itm)) + def descr_insert_after(space, self, node, w_added_nodes): + added_nodes = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_added_nodes)] + index = self.nodes.index(node) + 1 + self.nodes[index:index] = added_nodes + + def descr_insert_before(space, self, node, w_added_nodes): + added_nodes = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_added_nodes)] + index = self.nodes.index(node) + self.nodes[index:index] = added_nodes def descr_Bitand_new(space, w_subtype, w_nodes, lineno=-1): self = space.allocate_instance(Bitand, w_subtype) @@ -1128,6 +1189,8 @@ accept=interp2app(descr_Bitand_accept, unwrap_spec=[ObjSpace, W_Root, W_Root] ), mutate=interp2app(descr_Bitand_mutate, unwrap_spec=[ObjSpace, W_Root, W_Root] ), nodes=GetSetProperty(Bitand.fget_nodes, Bitand.fset_nodes ), + insert_after=interp2app(Bitand.descr_insert_after.im_func, unwrap_spec=[ObjSpace, Bitand, Node, W_Root]), + insert_before=interp2app(Bitand.descr_insert_before.im_func, unwrap_spec=[ObjSpace, Bitand, Node, W_Root]), ) Bitand.typedef.acceptable_as_base_class = False @@ -1166,6 +1229,15 @@ del self.nodes[:] for w_itm in space.unpackiterable(w_arg): self.nodes.append( space.interp_w(Node, w_itm)) + def descr_insert_after(space, self, node, w_added_nodes): + added_nodes = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_added_nodes)] + index = self.nodes.index(node) + 1 + self.nodes[index:index] = added_nodes + + def descr_insert_before(space, self, node, w_added_nodes): + added_nodes = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_added_nodes)] + index = self.nodes.index(node) + self.nodes[index:index] = added_nodes def descr_Bitor_new(space, w_subtype, w_nodes, lineno=-1): self = space.allocate_instance(Bitor, w_subtype) @@ -1194,6 +1266,8 @@ accept=interp2app(descr_Bitor_accept, unwrap_spec=[ObjSpace, W_Root, W_Root] ), mutate=interp2app(descr_Bitor_mutate, unwrap_spec=[ObjSpace, W_Root, W_Root] ), nodes=GetSetProperty(Bitor.fget_nodes, Bitor.fset_nodes ), + insert_after=interp2app(Bitor.descr_insert_after.im_func, unwrap_spec=[ObjSpace, Bitor, Node, W_Root]), + insert_before=interp2app(Bitor.descr_insert_before.im_func, unwrap_spec=[ObjSpace, Bitor, Node, W_Root]), ) Bitor.typedef.acceptable_as_base_class = False @@ -1232,6 +1306,15 @@ del self.nodes[:] for w_itm in space.unpackiterable(w_arg): self.nodes.append( space.interp_w(Node, w_itm)) + def descr_insert_after(space, self, node, w_added_nodes): + added_nodes = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_added_nodes)] + index = self.nodes.index(node) + 1 + self.nodes[index:index] = added_nodes + + def descr_insert_before(space, self, node, w_added_nodes): + added_nodes = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_added_nodes)] + index = self.nodes.index(node) + self.nodes[index:index] = added_nodes def descr_Bitxor_new(space, w_subtype, w_nodes, lineno=-1): self = space.allocate_instance(Bitxor, w_subtype) @@ -1260,6 +1343,8 @@ accept=interp2app(descr_Bitxor_accept, unwrap_spec=[ObjSpace, W_Root, W_Root] ), mutate=interp2app(descr_Bitxor_mutate, unwrap_spec=[ObjSpace, W_Root, W_Root] ), nodes=GetSetProperty(Bitxor.fget_nodes, Bitxor.fset_nodes ), + insert_after=interp2app(Bitxor.descr_insert_after.im_func, unwrap_spec=[ObjSpace, Bitxor, Node, W_Root]), + insert_before=interp2app(Bitxor.descr_insert_before.im_func, unwrap_spec=[ObjSpace, Bitxor, Node, W_Root]), ) Bitxor.typedef.acceptable_as_base_class = False @@ -1834,6 +1919,15 @@ del self.nodes[:] for w_itm in space.unpackiterable(w_arg): self.nodes.append( space.interp_w(Node, w_itm)) + def descr_insert_after(space, self, node, w_added_nodes): + added_nodes = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_added_nodes)] + index = self.nodes.index(node) + 1 + self.nodes[index:index] = added_nodes + + def descr_insert_before(space, self, node, w_added_nodes): + added_nodes = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_added_nodes)] + index = self.nodes.index(node) + self.nodes[index:index] = added_nodes def descr_Decorators_new(space, w_subtype, w_nodes, lineno=-1): self = space.allocate_instance(Decorators, w_subtype) @@ -1862,6 +1956,8 @@ accept=interp2app(descr_Decorators_accept, unwrap_spec=[ObjSpace, W_Root, W_Root] ), mutate=interp2app(descr_Decorators_mutate, unwrap_spec=[ObjSpace, W_Root, W_Root] ), nodes=GetSetProperty(Decorators.fget_nodes, Decorators.fset_nodes ), + insert_after=interp2app(Decorators.descr_insert_after.im_func, unwrap_spec=[ObjSpace, Decorators, Node, W_Root]), + insert_before=interp2app(Decorators.descr_insert_before.im_func, unwrap_spec=[ObjSpace, Decorators, Node, W_Root]), ) Decorators.typedef.acceptable_as_base_class = False @@ -3544,6 +3640,15 @@ del self.nodes[:] for w_itm in space.unpackiterable(w_arg): self.nodes.append( space.interp_w(Node, w_itm)) + def descr_insert_after(space, self, node, w_added_nodes): + added_nodes = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_added_nodes)] + index = self.nodes.index(node) + 1 + self.nodes[index:index] = added_nodes + + def descr_insert_before(space, self, node, w_added_nodes): + added_nodes = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_added_nodes)] + index = self.nodes.index(node) + self.nodes[index:index] = added_nodes def descr_List_new(space, w_subtype, w_nodes, lineno=-1): self = space.allocate_instance(List, w_subtype) @@ -3572,6 +3677,8 @@ accept=interp2app(descr_List_accept, unwrap_spec=[ObjSpace, W_Root, W_Root] ), mutate=interp2app(descr_List_mutate, unwrap_spec=[ObjSpace, W_Root, W_Root] ), nodes=GetSetProperty(List.fget_nodes, List.fset_nodes ), + insert_after=interp2app(List.descr_insert_after.im_func, unwrap_spec=[ObjSpace, List, Node, W_Root]), + insert_before=interp2app(List.descr_insert_before.im_func, unwrap_spec=[ObjSpace, List, Node, W_Root]), ) List.typedef.acceptable_as_base_class = False @@ -4172,6 +4279,15 @@ del self.nodes[:] for w_itm in space.unpackiterable(w_arg): self.nodes.append( space.interp_w(Node, w_itm)) + def descr_insert_after(space, self, node, w_added_nodes): + added_nodes = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_added_nodes)] + index = self.nodes.index(node) + 1 + self.nodes[index:index] = added_nodes + + def descr_insert_before(space, self, node, w_added_nodes): + added_nodes = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_added_nodes)] + index = self.nodes.index(node) + self.nodes[index:index] = added_nodes def descr_Or_new(space, w_subtype, w_nodes, lineno=-1): self = space.allocate_instance(Or, w_subtype) @@ -4200,6 +4316,8 @@ accept=interp2app(descr_Or_accept, unwrap_spec=[ObjSpace, W_Root, W_Root] ), mutate=interp2app(descr_Or_mutate, unwrap_spec=[ObjSpace, W_Root, W_Root] ), nodes=GetSetProperty(Or.fget_nodes, Or.fset_nodes ), + insert_after=interp2app(Or.descr_insert_after.im_func, unwrap_spec=[ObjSpace, Or, Node, W_Root]), + insert_before=interp2app(Or.descr_insert_before.im_func, unwrap_spec=[ObjSpace, Or, Node, W_Root]), ) Or.typedef.acceptable_as_base_class = False @@ -4350,6 +4468,15 @@ del self.nodes[:] for w_itm in space.unpackiterable(w_arg): self.nodes.append( space.interp_w(Node, w_itm)) + def descr_insert_after(space, self, node, w_added_nodes): + added_nodes = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_added_nodes)] + index = self.nodes.index(node) + 1 + self.nodes[index:index] = added_nodes + + def descr_insert_before(space, self, node, w_added_nodes): + added_nodes = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_added_nodes)] + index = self.nodes.index(node) + self.nodes[index:index] = added_nodes def fget_dest( space, self): if self.dest is None: return space.w_None @@ -4392,6 +4519,8 @@ accept=interp2app(descr_Print_accept, unwrap_spec=[ObjSpace, W_Root, W_Root] ), mutate=interp2app(descr_Print_mutate, unwrap_spec=[ObjSpace, W_Root, W_Root] ), nodes=GetSetProperty(Print.fget_nodes, Print.fset_nodes ), + insert_after=interp2app(Print.descr_insert_after.im_func, unwrap_spec=[ObjSpace, Print, Node, W_Root]), + insert_before=interp2app(Print.descr_insert_before.im_func, unwrap_spec=[ObjSpace, Print, Node, W_Root]), dest=GetSetProperty(Print.fget_dest, Print.fset_dest ), ) Print.typedef.acceptable_as_base_class = False @@ -4439,6 +4568,15 @@ del self.nodes[:] for w_itm in space.unpackiterable(w_arg): self.nodes.append( space.interp_w(Node, w_itm)) + def descr_insert_after(space, self, node, w_added_nodes): + added_nodes = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_added_nodes)] + index = self.nodes.index(node) + 1 + self.nodes[index:index] = added_nodes + + def descr_insert_before(space, self, node, w_added_nodes): + added_nodes = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_added_nodes)] + index = self.nodes.index(node) + self.nodes[index:index] = added_nodes def fget_dest( space, self): if self.dest is None: return space.w_None @@ -4481,6 +4619,8 @@ accept=interp2app(descr_Printnl_accept, unwrap_spec=[ObjSpace, W_Root, W_Root] ), mutate=interp2app(descr_Printnl_mutate, unwrap_spec=[ObjSpace, W_Root, W_Root] ), nodes=GetSetProperty(Printnl.fget_nodes, Printnl.fset_nodes ), + insert_after=interp2app(Printnl.descr_insert_after.im_func, unwrap_spec=[ObjSpace, Printnl, Node, W_Root]), + insert_before=interp2app(Printnl.descr_insert_before.im_func, unwrap_spec=[ObjSpace, Printnl, Node, W_Root]), dest=GetSetProperty(Printnl.fget_dest, Printnl.fset_dest ), ) Printnl.typedef.acceptable_as_base_class = False @@ -4856,6 +4996,15 @@ del self.nodes[:] for w_itm in space.unpackiterable(w_arg): self.nodes.append( space.interp_w(Node, w_itm)) + def descr_insert_after(space, self, node, w_added_nodes): + added_nodes = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_added_nodes)] + index = self.nodes.index(node) + 1 + self.nodes[index:index] = added_nodes + + def descr_insert_before(space, self, node, w_added_nodes): + added_nodes = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_added_nodes)] + index = self.nodes.index(node) + self.nodes[index:index] = added_nodes def descr_Sliceobj_new(space, w_subtype, w_nodes, lineno=-1): self = space.allocate_instance(Sliceobj, w_subtype) @@ -4884,6 +5033,8 @@ accept=interp2app(descr_Sliceobj_accept, unwrap_spec=[ObjSpace, W_Root, W_Root] ), mutate=interp2app(descr_Sliceobj_mutate, unwrap_spec=[ObjSpace, W_Root, W_Root] ), nodes=GetSetProperty(Sliceobj.fget_nodes, Sliceobj.fset_nodes ), + insert_after=interp2app(Sliceobj.descr_insert_after.im_func, unwrap_spec=[ObjSpace, Sliceobj, Node, W_Root]), + insert_before=interp2app(Sliceobj.descr_insert_before.im_func, unwrap_spec=[ObjSpace, Sliceobj, Node, W_Root]), ) Sliceobj.typedef.acceptable_as_base_class = False @@ -4922,6 +5073,15 @@ del self.nodes[:] for w_itm in space.unpackiterable(w_arg): self.nodes.append( space.interp_w(Node, w_itm)) + def descr_insert_after(space, self, node, w_added_nodes): + added_nodes = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_added_nodes)] + index = self.nodes.index(node) + 1 + self.nodes[index:index] = added_nodes + + def descr_insert_before(space, self, node, w_added_nodes): + added_nodes = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_added_nodes)] + index = self.nodes.index(node) + self.nodes[index:index] = added_nodes def descr_Stmt_new(space, w_subtype, w_nodes, lineno=-1): self = space.allocate_instance(Stmt, w_subtype) @@ -4950,6 +5110,8 @@ accept=interp2app(descr_Stmt_accept, unwrap_spec=[ObjSpace, W_Root, W_Root] ), mutate=interp2app(descr_Stmt_mutate, unwrap_spec=[ObjSpace, W_Root, W_Root] ), nodes=GetSetProperty(Stmt.fget_nodes, Stmt.fset_nodes ), + insert_after=interp2app(Stmt.descr_insert_after.im_func, unwrap_spec=[ObjSpace, Stmt, Node, W_Root]), + insert_before=interp2app(Stmt.descr_insert_before.im_func, unwrap_spec=[ObjSpace, Stmt, Node, W_Root]), ) Stmt.typedef.acceptable_as_base_class = False @@ -5352,6 +5514,15 @@ del self.nodes[:] for w_itm in space.unpackiterable(w_arg): self.nodes.append( space.interp_w(Node, w_itm)) + def descr_insert_after(space, self, node, w_added_nodes): + added_nodes = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_added_nodes)] + index = self.nodes.index(node) + 1 + self.nodes[index:index] = added_nodes + + def descr_insert_before(space, self, node, w_added_nodes): + added_nodes = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_added_nodes)] + index = self.nodes.index(node) + self.nodes[index:index] = added_nodes def descr_Tuple_new(space, w_subtype, w_nodes, lineno=-1): self = space.allocate_instance(Tuple, w_subtype) @@ -5380,6 +5551,8 @@ accept=interp2app(descr_Tuple_accept, unwrap_spec=[ObjSpace, W_Root, W_Root] ), mutate=interp2app(descr_Tuple_mutate, unwrap_spec=[ObjSpace, W_Root, W_Root] ), nodes=GetSetProperty(Tuple.fget_nodes, Tuple.fset_nodes ), + insert_after=interp2app(Tuple.descr_insert_after.im_func, unwrap_spec=[ObjSpace, Tuple, Node, W_Root]), + insert_before=interp2app(Tuple.descr_insert_before.im_func, unwrap_spec=[ObjSpace, Tuple, Node, W_Root]), ) Tuple.typedef.acceptable_as_base_class = False Modified: pypy/dist/pypy/interpreter/astcompiler/ast.txt ============================================================================== --- pypy/dist/pypy/interpreter/astcompiler/ast.txt (original) +++ pypy/dist/pypy/interpreter/astcompiler/ast.txt Wed Feb 28 18:30:48 2007 @@ -71,7 +71,7 @@ CallFunc: node, args!, star_args& = None, dstar_args& = None Keyword: name*str, expr Subscript: expr, flags*int, sub -Ellipsis: +Ellipsis: Sliceobj: nodes! Slice: expr, flags*int, lower&, upper& Assert: test, fail& @@ -337,6 +337,31 @@ return space.call_method(w_visitor, "visitCompare", w_self) +def descr_Compare_mutate(space, w_self, w_visitor): + w_expr = space.getattr(w_self, space.wrap("expr")) + w_mutate_expr = space.getattr(w_expr, space.wrap("mutate")) + w_mutate_expr_args = Arguments(space, [ w_visitor ]) + w_new_expr = space.call_args(w_mutate_expr, w_mutate_expr_args) + space.setattr(w_self, space.wrap("expr"), w_new_expr) + + w_list = space.getattr(w_self, space.wrap("ops")) + list_w = space.unpackiterable(w_list) + newlist_w = [] + for w_item in list_w: + w_opname, w_node = space.unpackiterable(w_item, 2) + + w_node_mutate = space.getattr(w_node, space.wrap("mutate")) + w_node_mutate_args = Arguments(space, [ w_visitor ]) + w_newnode = space.call_args(w_node_mutate, w_node_mutate_args) + + newlist_w.append(space.newtuple([w_opname, w_newnode])) + w_newlist = space.newlist(newlist_w) + space.setattr(w_self, space.wrap("ops"), w_newlist) + w_visitCompare = space.getattr(w_visitor, space.wrap("visitCompare")) + w_visitCompare_args = Arguments(space, [ w_self ]) + return space.call_args(w_visitCompare, w_visitCompare_args) + + def descr_Dict_new(space, w_subtype, w_items, lineno=-1): self = space.allocate_instance(Dict, w_subtype) items = [] Modified: pypy/dist/pypy/interpreter/astcompiler/astgen.py ============================================================================== --- pypy/dist/pypy/interpreter/astcompiler/astgen.py (original) +++ pypy/dist/pypy/interpreter/astcompiler/astgen.py Wed Feb 28 18:30:48 2007 @@ -319,6 +319,40 @@ print >> buf, " self.%s[:] = newlist"%(argname) print >> buf, " return visitor.visit%s(self)" % self.name + def _gen_insertnodes_func(self, buf): + print >> buf, " def descr_insert_after(space, self, node, w_added_nodes):" + print >> buf, " added_nodes = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_added_nodes)]" + print >> buf, " index = self.nodes.index(node) + 1" + print >> buf, " self.nodes[index:index] = added_nodes" + print >> buf + print >> buf, " def descr_insert_before(space, self, node, w_added_nodes):" + print >> buf, " added_nodes = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_added_nodes)]" + print >> buf, " index = self.nodes.index(node)" + print >> buf, " self.nodes[index:index] = added_nodes" + + + def _gen_mutate(self, buf): + print >> buf, " def mutate(self, visitor):" + if len(self.argnames) != 0: + for argname in self.argnames: + if argname in self.mutate_nodes: + for line in self.mutate_nodes[argname]: + if line.strip(): + print >> buf, ' ' + line + elif self.argprops[argname] == P_NODE: + print >> buf, " self.%s = self.%s.mutate(visitor)" % (argname,argname) + elif self.argprops[argname] == P_NONE: + print >> buf, " if self.%s is not None:" % (argname,) + print >> buf, " self.%s = self.%s.mutate(visitor)" % (argname,argname) + elif self.argprops[argname] == P_NESTED: + print >> buf, " newlist = []" + print >> buf, " for n in self.%s:"%(argname) + print >> buf, " item = n.mutate(visitor)" + print >> buf, " if item is not None:" + print >> buf, " newlist.append(item)" + print >> buf, " self.%s[:] = newlist"%(argname) + print >> buf, " return visitor.visit%s(self)" % self.name + def _gen_fget_func(self, buf, attr, prop ): # FGET print >> buf, " def fget_%s( space, self):" % attr @@ -370,6 +404,8 @@ if "fset_%s" % attr not in self.additional_methods: self._gen_fset_func( buf, attr, prop ) + if prop[attr] == P_NESTED and attr == 'nodes': + self._gen_insertnodes_func(buf) def _gen_descr_mutate(self, buf): if self.applevel_mutate: @@ -426,6 +462,9 @@ print >> buf, " mutate=interp2app(descr_%s_mutate, unwrap_spec=[ObjSpace, W_Root, W_Root] )," % self.name for attr in self.argnames: print >> buf, " %s=GetSetProperty(%s.fget_%s, %s.fset_%s )," % (attr,self.name,attr,self.name,attr) + if self.argprops[attr] == P_NESTED and attr == "nodes": + print >> buf, " insert_after=interp2app(%s.descr_insert_after.im_func, unwrap_spec=[ObjSpace, %s, Node, W_Root])," % (self.name, self.name) + print >> buf, " insert_before=interp2app(%s.descr_insert_before.im_func, unwrap_spec=[ObjSpace, %s, Node, W_Root])," % (self.name, self.name) print >> buf, " )" print >> buf, "%s.typedef.acceptable_as_base_class = False" % self.name @@ -660,6 +699,7 @@ def __init__(self, lineno = -1): self.lineno = lineno self.filename = "" + self.parent = None #self.scope = None def getChildren(self): @@ -691,6 +731,12 @@ def descr_repr( self, space ): return space.wrap( self.__repr__() ) + def fget_parent(space, self): + return space.wrap(self.parent) + + def fset_parent(space, self, w_parent): + self.parent = space.interp_w(Node, w_parent, can_be_None=False) + def descr_getChildNodes( self, space ): lst = self.getChildNodes() return space.newlist( [ space.wrap( it ) for it in lst ] ) @@ -714,6 +760,7 @@ mutate = interp2app(descr_node_mutate, unwrap_spec=[ ObjSpace, W_Root, W_Root ] ), lineno = interp_attrproperty('lineno', cls=Node), filename = interp_attrproperty('filename', cls=Node), + parent=GetSetProperty(Node.fget_parent, Node.fset_parent), ) Node.typedef.acceptable_as_base_class = False Modified: pypy/dist/pypy/interpreter/pycompiler.py ============================================================================== --- pypy/dist/pypy/interpreter/pycompiler.py (original) +++ pypy/dist/pypy/interpreter/pycompiler.py Wed Feb 28 18:30:48 2007 @@ -189,6 +189,7 @@ warnings.warn_explicit = old_warn_explicit + ######## class PythonAstCompiler(PyCodeCompiler): """Uses the stdlib's python implementation of compiler @@ -198,6 +199,13 @@ of incomplete inputs (e.g. we shouldn't re-compile from sracth the whole source after having only added a new '\n') """ + def __init__(self, space): + from pyparser.pythonparse import PYTHON_PARSER + PyCodeCompiler.__init__(self, space) + self.parser = PYTHON_PARSER + self.additional_rules = {} + + def compile(self, source, filename, mode, flags): from pyparser.error import SyntaxError from pypy.interpreter import astcompiler @@ -205,15 +213,18 @@ from pypy.interpreter.astcompiler.pycodegen import InteractiveCodeGenerator from pypy.interpreter.astcompiler.pycodegen import ExpressionCodeGenerator from pypy.interpreter.astcompiler.ast import Node - from pyparser.pythonutil import AstBuilder, PYTHON_PARSER, TARGET_DICT + from pyparser.astbuilder import AstBuilder from pypy.interpreter.pycode import PyCode + from pypy.interpreter.function import Function flags |= stdlib___future__.generators.compiler_flag # always on (2.2 compat) space = self.space try: - builder = AstBuilder(space=space) - target_rule = TARGET_DICT[mode] - PYTHON_PARSER.parse_source(source, target_rule, builder, flags) + builder = AstBuilder(self.parser, space=space) + for rulename, buildfunc in self.additional_rules.iteritems(): + assert isinstance(buildfunc, Function) + builder.user_build_rules[rulename] = buildfunc + self.parser.parse_source(source, mode, builder, flags) ast_tree = builder.rule_stack[-1] encoding = builder.source_encoding except SyntaxError, e: @@ -251,4 +262,29 @@ def install_compiler_hook(space, w_callable): # if not space.get( w_callable ): # raise OperationError( space.w_TypeError( space.wrap( "must have a callable" ) ) - space.default_compiler.w_compile_hook = w_callable + space.default_compiler.w_compile_hook = w_callable + +def insert_grammar_rule(space, w_rule, w_buildfuncs): + """inserts new grammar rules to the default compiler""" + from pypy.interpreter import function + rule = space.str_w(w_rule) + #buildfuncs_w = w_buildfuncs.content + buildfuncs = {} + #for w_name, w_func in buildfuncs_w.iteritems(): + # buildfuncs[space.str_w(w_name)] = space.unwrap(w_func) + w_iter = space.iter(w_buildfuncs) + while 1: + try: + w_key = space.next(w_iter) + w_func = space.getitem(w_buildfuncs, w_key) + buildfuncs[space.str_w(w_key)] = space.interp_w(function.Function, w_func) + except OperationError, e: + if not e.match(space, space.w_StopIteration): + raise + break + space.default_compiler.additional_rules = buildfuncs + space.default_compiler.parser.insert_rule(rule) + +# XXX cyclic import +#from pypy.interpreter.baseobjspace import ObjSpace +#insert_grammar_rule.unwrap_spec = [ObjSpace, str, dict] Modified: pypy/dist/pypy/interpreter/pyparser/astbuilder.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/astbuilder.py (original) +++ pypy/dist/pypy/interpreter/pyparser/astbuilder.py Wed Feb 28 18:30:48 2007 @@ -1,518 +1,18 @@ """This module provides the astbuilder class which is to be used -by GrammarElements to directly build the AST during parsing +by GrammarElements to directly build the AS during parsing without going through the nested tuples step """ from grammar import BaseGrammarBuilder, AbstractContext + +from pypy.interpreter.function import Function from pypy.interpreter.astcompiler import ast, consts -from pypy.interpreter.pyparser import pythonparse -import pypy.interpreter.pyparser.pytoken as tok +# from pypy.interpreter.pyparser import pythonparse +#import pypy.interpreter.pyparser.pytoken as tok from pypy.interpreter.pyparser.error import SyntaxError from pypy.interpreter.pyparser.parsestring import parsestr - -sym = pythonparse.PYTHON_PARSER.symbols - -DEBUG_MODE = 0 - -### Parsing utilites ################################################# -def parse_except_clause(tokens): - """parses 'except' [test [',' test]] ':' suite - and returns a 4-tuple : (tokens_read, expr1, expr2, except_body) - """ - lineno = tokens[0].lineno - clause_length = 1 - # Read until end of except clause (bound by following 'else', - # or 'except' or end of tokens) - while clause_length < len(tokens): - token = tokens[clause_length] - if isinstance(token, TokenObject) and \ - (token.get_value() == 'except' or token.get_value() == 'else'): - break - clause_length += 1 - if clause_length == 3: - # case 'except: body' - return (3, None, None, tokens[2]) - elif clause_length == 4: - # case 'except Exception: body': - return (4, tokens[1], None, tokens[3]) - else: - # case 'except Exception, exc: body' - return (6, tokens[1], to_lvalue(tokens[3], consts.OP_ASSIGN), tokens[5]) - - -def parse_dotted_names(tokens): - """parses NAME('.' NAME)* and returns full dotted name - - this function doesn't assume that the list ends after the - last 'NAME' element - """ - first = tokens[0] - assert isinstance(first, TokenObject) - name = first.get_value() - l = len(tokens) - index = 1 - for index in range(1, l, 2): - token = tokens[index] - assert isinstance(token, TokenObject) - if token.name != tok.DOT: - break - token = tokens[index+1] - assert isinstance(token, TokenObject) - name += '.' - value = token.get_value() - name += value - return (index, name) - -def parse_argument(tokens): - """parses function call arguments""" - l = len(tokens) - index = 0 - arguments = [] - last_token = None - building_kw = False - kw_built = False - stararg_token = None - dstararg_token = None - while index < l: - cur_token = tokens[index] - if not isinstance(cur_token, TokenObject): - index += 1 - if not building_kw: - arguments.append(cur_token) - else: - last_token = arguments.pop() - assert isinstance(last_token, ast.Name) # used by rtyper - arguments.append(ast.Keyword(last_token.varname, cur_token, last_token.lineno)) - building_kw = False - kw_built = True - continue - elif cur_token.name == tok.COMMA: - index += 1 - continue - elif cur_token.name == tok.EQUAL: - index += 1 - building_kw = True - continue - elif cur_token.name == tok.STAR or cur_token.name == tok.DOUBLESTAR: - index += 1 - if cur_token.name == tok.STAR: - stararg_token = tokens[index] - index += 1 - if index >= l: - break - index += 2 # Skip COMMA and DOUBLESTAR - dstararg_token = tokens[index] - break - elif cur_token.get_value() == 'for': - if len(arguments) != 1: - raise SyntaxError("invalid syntax", cur_token.lineno, - cur_token.col) - expr = arguments[0] - genexpr_for = parse_genexpr_for(tokens[index:]) - genexpr_for[0].is_outmost = True - gexp = ast.GenExpr(ast.GenExprInner(expr, genexpr_for, expr.lineno), expr.lineno) - arguments[0] = gexp - break - return arguments, stararg_token, dstararg_token - - -def parse_fpdef(tokens, index): - """fpdef: fpdef: NAME | '(' fplist ')' - fplist: fpdef (',' fpdef)* [','] - - This intend to be a RPYTHON compliant implementation of _parse_fpdef, - but it can't work with the default compiler. - We switched to use astcompiler module now - """ - nodes = [] - comma = False - while True: - token = tokens[index] - index += 1 - assert isinstance(token, TokenObject) - if token.name == tok.LPAR: # nested item - index, node = parse_fpdef(tokens, index) - elif token.name == tok.RPAR: # end of current nesting - break - else: # name - val = token.get_value() - node = ast.AssName(val, consts.OP_ASSIGN, token.lineno) - nodes.append(node) - - token = tokens[index] - index += 1 - assert isinstance(token, TokenObject) - if token.name == tok.COMMA: - comma = True - else: - assert token.name == tok.RPAR - break - if len(nodes) == 1 and not comma: - node = nodes[0] - else: - node = ast.AssTuple(nodes, token.lineno) - return index, node - -def parse_arglist(tokens): - """returns names, defaults, flags""" - l = len(tokens) - index = 0 - defaults = [] - names = [] - flags = 0 - first_with_default = -1 - while index < l: - cur_token = tokens[index] - index += 1 - if not isinstance(cur_token, TokenObject): - # XXX: think of another way to write this test - defaults.append(cur_token) - if first_with_default == -1: - first_with_default = len(names) - 1 - elif cur_token.name == tok.COMMA: - # We could skip test COMMA by incrementing index cleverly - # but we might do some experiment on the grammar at some point - continue - elif cur_token.name == tok.LPAR: - index, node = parse_fpdef(tokens, index) - names.append(node) - elif cur_token.name == tok.STAR or cur_token.name == tok.DOUBLESTAR: - if cur_token.name == tok.STAR: - cur_token = tokens[index] - assert isinstance(cur_token, TokenObject) - index += 1 - if cur_token.name == tok.NAME: - val = cur_token.get_value() - names.append( ast.AssName( val, consts.OP_ASSIGN ) ) - flags |= consts.CO_VARARGS - index += 1 - if index >= l: - break - else: - # still more tokens to read - cur_token = tokens[index] - index += 1 - else: - raise SyntaxError("incomplete varags", cur_token.lineno, - cur_token.col) - assert isinstance(cur_token, TokenObject) - if cur_token.name != tok.DOUBLESTAR: - raise SyntaxError("Unexpected token", cur_token.lineno, - cur_token.col) - cur_token = tokens[index] - index += 1 - assert isinstance(cur_token, TokenObject) - if cur_token.name == tok.NAME: - val = cur_token.get_value() - names.append( ast.AssName( val, consts.OP_ASSIGN ) ) - flags |= consts.CO_VARKEYWORDS - index += 1 - else: - raise SyntaxError("incomplete varags", cur_token.lineno, - cur_token.col) - if index < l: - token = tokens[index] - raise SyntaxError("unexpected token" , token.lineno, - token.col) - elif cur_token.name == tok.NAME: - val = cur_token.get_value() - names.append( ast.AssName( val, consts.OP_ASSIGN ) ) - - if first_with_default != -1: - num_expected_with_default = len(names) - first_with_default - if flags & consts.CO_VARKEYWORDS: - num_expected_with_default -= 1 - if flags & consts.CO_VARARGS: - num_expected_with_default -= 1 - if len(defaults) != num_expected_with_default: - raise SyntaxError('non-default argument follows default argument', - tokens[0].lineno, tokens[0].col) - return names, defaults, flags - - -def parse_listcomp(tokens): - """parses 'for j in k for i in j if i %2 == 0' and returns - a GenExprFor instance - XXX: refactor with listmaker ? - """ - list_fors = [] - ifs = [] - index = 0 - if tokens: - lineno = tokens[0].lineno - else: - lineno = -1 - while index < len(tokens): - token = tokens[index] - assert isinstance(token, TokenObject) # rtyper info + check - if token.get_value() == 'for': - index += 1 # skip 'for' - ass_node = to_lvalue(tokens[index], consts.OP_ASSIGN) - index += 2 # skip 'in' - iterables = [tokens[index]] - index += 1 - while index < len(tokens): - tok2 = tokens[index] - if not isinstance(tok2, TokenObject): - break - if tok2.name != tok.COMMA: - break - iterables.append(tokens[index+1]) - index += 2 - if len(iterables) == 1: - iterable = iterables[0] - else: - iterable = ast.Tuple(iterables, token.lineno) - while index < len(tokens): - token = tokens[index] - assert isinstance(token, TokenObject) # rtyper info - if token.get_value() == 'if': - ifs.append(ast.ListCompIf(tokens[index+1], token.lineno)) - index += 2 - else: - break - list_fors.append(ast.ListCompFor(ass_node, iterable, ifs, lineno)) - ifs = [] - else: - assert False, 'Unexpected token: expecting for in listcomp' - # - # Original implementation: - # - # if tokens[index].get_value() == 'for': - # index += 1 # skip 'for' - # ass_node = to_lvalue(tokens[index], consts.OP_ASSIGN) - # index += 2 # skip 'in' - # iterable = tokens[index] - # index += 1 - # while index < len(tokens) and tokens[index].get_value() == 'if': - # ifs.append(ast.ListCompIf(tokens[index+1])) - # index += 2 - # list_fors.append(ast.ListCompFor(ass_node, iterable, ifs)) - # ifs = [] - # else: - # raise ValueError('Unexpected token: %s' % tokens[index]) - return list_fors - - -def parse_genexpr_for(tokens): - """parses 'for j in k for i in j if i %2 == 0' and returns - a GenExprFor instance - XXX: if RPYTHON supports to pass a class object to a function, - we could refactor parse_listcomp and parse_genexpr_for, - and call : - - parse_listcomp(tokens, forclass=ast.GenExprFor, ifclass=...) - or: - - parse_listcomp(tokens, forclass=ast.ListCompFor, ifclass=...) - """ - genexpr_fors = [] - ifs = [] - index = 0 - if tokens: - lineno = tokens[0].lineno - else: - lineno = -1 - while index < len(tokens): - token = tokens[index] - assert isinstance(token, TokenObject) # rtyper info + check - if token.get_value() == 'for': - index += 1 # skip 'for' - ass_node = to_lvalue(tokens[index], consts.OP_ASSIGN) - index += 2 # skip 'in' - iterable = tokens[index] - index += 1 - while index < len(tokens): - token = tokens[index] - assert isinstance(token, TokenObject) # rtyper info - if token.get_value() == 'if': - ifs.append(ast.GenExprIf(tokens[index+1], token.lineno)) - index += 2 - else: - break - genexpr_fors.append(ast.GenExprFor(ass_node, iterable, ifs, lineno)) - ifs = [] - else: - raise SyntaxError('invalid syntax', - token.lineno, token.col) - return genexpr_fors - - -def get_docstring(builder,stmt): - """parses a Stmt node. - - If a docstring if found, the Discard node is **removed** - from and the docstring is returned. - - If no docstring is found, is left unchanged - and None is returned - """ - if not isinstance(stmt, ast.Stmt): - return None - doc = builder.wrap_none() - if len(stmt.nodes): - first_child = stmt.nodes[0] - if isinstance(first_child, ast.Discard): - expr = first_child.expr - if builder.is_basestring_const(expr): - # This *is* a docstring, remove it from stmt list - assert isinstance(expr, ast.Const) - del stmt.nodes[0] - doc = expr.value - return doc - - -def to_lvalue(ast_node, flags): - lineno = ast_node.lineno - if isinstance( ast_node, ast.Name ): - return ast.AssName(ast_node.varname, flags, lineno) - # return ast.AssName(ast_node.name, flags) - elif isinstance(ast_node, ast.Tuple): - nodes = [] - # FIXME: should ast_node.getChildren() but it's not annotable - # because of flatten() - for node in ast_node.nodes: - nodes.append(to_lvalue(node, flags)) - return ast.AssTuple(nodes, lineno) - elif isinstance(ast_node, ast.List): - nodes = [] - # FIXME: should ast_node.getChildren() but it's not annotable - # because of flatten() - for node in ast_node.nodes: - nodes.append(to_lvalue(node, flags)) - return ast.AssList(nodes, lineno) - elif isinstance(ast_node, ast.Getattr): - expr = ast_node.expr - assert isinstance(ast_node, ast.Getattr) - attrname = ast_node.attrname - return ast.AssAttr(expr, attrname, flags, lineno) - elif isinstance(ast_node, ast.Subscript): - ast_node.flags = flags - return ast_node - elif isinstance(ast_node, ast.Slice): - ast_node.flags = flags - return ast_node - else: - if isinstance(ast_node, ast.GenExpr): - raise SyntaxError("assign to generator expression not possible", - lineno, 0, '') - elif isinstance(ast_node, ast.ListComp): - raise SyntaxError("can't assign to list comprehension", - lineno, 0, '') - elif isinstance(ast_node, ast.CallFunc): - if flags == consts.OP_DELETE: - raise SyntaxError("can't delete function call", - lineno, 0, '') - else: - raise SyntaxError("can't assign to function call", - lineno, 0, '') - else: - raise SyntaxError("can't assign to non-lvalue", - lineno, 0, '') - -def is_augassign( ast_node ): - if ( isinstance( ast_node, ast.Name ) or - isinstance( ast_node, ast.Slice ) or - isinstance( ast_node, ast.Subscript ) or - isinstance( ast_node, ast.Getattr ) ): - return True - return False - -def get_atoms(builder, nb): - atoms = [] - i = nb - while i>0: - obj = builder.pop() - if isinstance(obj, BaseRuleObject): - i += obj.count - else: - atoms.append( obj ) - i -= 1 - atoms.reverse() - return atoms - -#def eval_string(value): -# """temporary implementation -# -# FIXME: need to be finished (check compile.c (parsestr) and -# stringobject.c (PyString_DecodeEscape()) for complete implementation) -# """ -# # return eval(value) -# if len(value) == 2: -# return '' -# result = '' -# length = len(value) -# quotetype = value[0] -# index = 1 -# while index < length and value[index] == quotetype: -# index += 1 -# if index == 6: -# # empty strings like """""" or '''''' -# return '' -# # XXX: is it RPYTHON to do this value[index:-index] -# chars = [char for char in value[index:len(value)-index]] -# result = ''.join(chars) -# result = result.replace('\\\\', '\\') -# d = {'\\b' : '\b', '\\f' : '\f', '\\t' : '\t', '\\n' : '\n', -# '\\r' : '\r', '\\v' : '\v', '\\a' : '\a', -# } -# for escaped, value in d.items(): -# result = result.replace(escaped, value) -# return result - - -## misc utilities, especially for power: rule -def reduce_callfunc(obj, arglist): - """generic factory for CallFunc nodes""" - assert isinstance(arglist, ArglistObject) - return ast.CallFunc(obj, arglist.arguments, - arglist.stararg, arglist.dstararg, arglist.lineno) - -def reduce_subscript(obj, subscript): - """generic factory for Subscript nodes""" - assert isinstance(subscript, SubscriptObject) - return ast.Subscript(obj, consts.OP_APPLY, subscript.value, subscript.lineno) - -def reduce_slice(obj, sliceobj): - """generic factory for Slice nodes""" - assert isinstance(sliceobj, SlicelistObject) - if sliceobj.fake_rulename == 'slice': - start = sliceobj.value[0] - end = sliceobj.value[1] - return ast.Slice(obj, consts.OP_APPLY, start, end, sliceobj.lineno) - else: - return ast.Subscript(obj, consts.OP_APPLY, ast.Sliceobj(sliceobj.value, - sliceobj.lineno), sliceobj.lineno) - -def parse_attraccess(tokens): - """parses token list like ['a', '.', 'b', '.', 'c', ...] - - and returns an ast node : ast.Getattr(Getattr(Name('a'), 'b'), 'c' ...) - """ - token = tokens[0] - # XXX HACK for when parse_attraccess is called from build_decorator - if isinstance(token, TokenObject): - val = token.get_value() - result = ast.Name(val, token.lineno) - else: - result = token - index = 1 - while index < len(tokens): - token = tokens[index] - if isinstance(token, TokenObject) and token.name == tok.DOT: - index += 1 - token = tokens[index] - assert isinstance(token, TokenObject) - result = ast.Getattr(result, token.get_value(), token.lineno) - elif isinstance(token, ArglistObject): - result = reduce_callfunc(result, token) - elif isinstance(token, SubscriptObject): - result = reduce_subscript(result, token) - elif isinstance(token, SlicelistObject): - result = reduce_slice(result, token) - else: - assert False, "Don't know how to handle index %s of %s" % (index, len(tokens)) - index += 1 - return result - +from pypy.interpreter.gateway import interp2app +from asthelper import * ## building functions helpers ## -------------------------- @@ -546,31 +46,31 @@ top = atoms[0] if isinstance(top, TokenObject): # assert isinstance(top, TokenObject) # rtyper - if top.name == tok.LPAR: + if top.name == builder.parser.tokens['LPAR']: if len(atoms) == 2: builder.push(ast.Tuple([], top.lineno)) else: builder.push( atoms[1] ) - elif top.name == tok.LSQB: + elif top.name == builder.parser.tokens['LSQB']: if len(atoms) == 2: 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: + elif top.name == builder.parser.tokens['LBRACE']: items = [] for index in range(1, len(atoms)-1, 4): # a : b , c : d # ^ +1 +2 +3 +4 items.append((atoms[index], atoms[index+2])) builder.push(ast.Dict(items, top.lineno)) - elif top.name == tok.NAME: + elif top.name == builder.parser.tokens['NAME']: val = top.get_value() builder.push( ast.Name(val, top.lineno) ) - elif top.name == tok.NUMBER: + elif top.name == builder.parser.tokens['NUMBER']: builder.push(ast.Const(builder.eval_number(top.get_value()), top.lineno)) - elif top.name == tok.STRING: + elif top.name == builder.parser.tokens['STRING']: # need to concatenate strings in atoms s = '' if len(atoms) == 1: @@ -586,7 +86,7 @@ accum.append(parsestr(builder.space, builder.source_encoding, token.get_value())) w_s = space.call_method(empty, 'join', space.newlist(accum)) builder.push(ast.Const(w_s, top.lineno)) - elif top.name == tok.BACKQUOTE: + elif top.name == builder.parser.tokens['BACKQUOTE']: builder.push(ast.Backquote(atoms[1], atoms[1].lineno)) else: raise SyntaxError("unexpected tokens", top.lineno, top.col) @@ -607,11 +107,11 @@ else: lineno = atoms[0].lineno token = atoms[-2] - if isinstance(token, TokenObject) and token.name == tok.DOUBLESTAR: - obj = parse_attraccess(slicecut(atoms, 0, -2)) + if isinstance(token, TokenObject) and token.name == builder.parser.tokens['DOUBLESTAR']: + obj = parse_attraccess(slicecut(atoms, 0, -2), builder) builder.push(ast.Power( obj, atoms[-1], lineno)) else: - obj = parse_attraccess(atoms) + obj = parse_attraccess(atoms, builder) builder.push(obj) def build_factor(builder, nb): @@ -622,11 +122,11 @@ token = atoms[0] lineno = token.lineno if isinstance(token, TokenObject): - if token.name == tok.PLUS: + if token.name == builder.parser.tokens['PLUS']: builder.push( ast.UnaryAdd( atoms[1], lineno) ) - if token.name == tok.MINUS: + if token.name == builder.parser.tokens['MINUS']: builder.push( ast.UnarySub( atoms[1], lineno) ) - if token.name == tok.TILDE: + if token.name == builder.parser.tokens['TILDE']: builder.push( ast.Invert( atoms[1], lineno) ) def build_term(builder, nb): @@ -637,13 +137,13 @@ right = atoms[i] op_node = atoms[i-1] assert isinstance(op_node, TokenObject) - if op_node.name == tok.STAR: + if op_node.name == builder.parser.tokens['STAR']: left = ast.Mul( left, right, left.lineno ) - elif op_node.name == tok.SLASH: + elif op_node.name == builder.parser.tokens['SLASH']: left = ast.Div( left, right, left.lineno ) - elif op_node.name == tok.PERCENT: + elif op_node.name == builder.parser.tokens['PERCENT']: left = ast.Mod( left, right, left.lineno ) - elif op_node.name == tok.DOUBLESLASH: + elif op_node.name == builder.parser.tokens['DOUBLESLASH']: left = ast.FloorDiv( left, right, left.lineno ) else: token = atoms[i-1] @@ -658,9 +158,9 @@ right = atoms[i] op_node = atoms[i-1] assert isinstance(op_node, TokenObject) - if op_node.name == tok.PLUS: + if op_node.name == builder.parser.tokens['PLUS']: left = ast.Add( left, right, left.lineno) - elif op_node.name == tok.MINUS: + elif op_node.name == builder.parser.tokens['MINUS']: left = ast.Sub( left, right, left.lineno) else: token = atoms[i-1] @@ -676,9 +176,9 @@ right = atoms[i] op_node = atoms[i-1] assert isinstance(op_node, TokenObject) - if op_node.name == tok.LEFTSHIFT: + if op_node.name == builder.parser.tokens['LEFTSHIFT']: left = ast.LeftShift( left, right, lineno ) - elif op_node.name == tok.RIGHTSHIFT: + elif op_node.name == builder.parser.tokens['RIGHTSHIFT']: left = ast.RightShift( left, right, lineno ) else: token = atoms[i-1] @@ -727,7 +227,7 @@ # 'is', 'is not', 'not' or 'not in' => tok.get_value() token = atoms[i] assert isinstance(token, TokenObject) - op_name = tok.tok_rpunct.get(token.name, token.get_value()) + op_name = builder.parser.tok_rvalues.get(token.name, token.get_value()) ops.append((op_name, atoms[i+1])) builder.push(ast.Compare(atoms[0], ops, atoms[0].lineno)) @@ -755,15 +255,18 @@ lineno = token.lineno assert isinstance(token, TokenObject) if token.get_value() == 'not': - builder.push(TokenObject(tok.NAME, 'not in', lineno)) + builder.push(TokenObject(builder.parser.tokens['NAME'], 'not in', lineno, builder.parser)) else: - builder.push(TokenObject(tok.NAME, 'is not', lineno)) + builder.push(TokenObject(builder.parser.tokens['NAME'], 'is not', lineno, builder.parser)) else: assert False, "TODO" # uh ? def build_or_test(builder, nb): return build_binary_expr(builder, nb, ast.Or) +def build_or_test(builder, nb): + return build_binary_expr(builder, nb, ast.Or) + def build_and_test(builder, nb): return build_binary_expr(builder, nb, ast.And) @@ -811,7 +314,7 @@ return op = atoms[1] assert isinstance(op, TokenObject) - if op.name == tok.EQUAL: + if op.name == builder.parser.tokens['EQUAL']: nodes = [] for i in range(0,l-2,2): lvalue = to_lvalue(atoms[i], consts.OP_ASSIGN) @@ -845,7 +348,7 @@ lineno = -1 for n in range(0,l,2): node = atoms[n] - if isinstance(node, TokenObject) and node.name == tok.NEWLINE: + if isinstance(node, TokenObject) and node.name == builder.parser.tokens['NEWLINE']: nodes.append(ast.Discard(ast.Const(builder.wrap_none()), node.lineno)) else: nodes.append(node) @@ -871,10 +374,10 @@ for node in atoms: if isinstance(node, ast.Stmt): stmts.extend(node.nodes) - elif isinstance(node, TokenObject) and node.name == tok.ENDMARKER: + elif isinstance(node, TokenObject) and node.name == builder.parser.tokens['ENDMARKER']: # XXX Can't we just remove the last element of the list ? break - elif isinstance(node, TokenObject) and node.name == tok.NEWLINE: + elif isinstance(node, TokenObject) and node.name == builder.parser.tokens['NEWLINE']: continue else: stmts.append(node) @@ -894,11 +397,12 @@ l = len(atoms) if l == 1 or l==2: atom0 = atoms[0] - if isinstance(atom0, TokenObject) and atom0.name == tok.NEWLINE: - atom0 = ast.Pass(atom0.lineno) + if isinstance(atom0, TokenObject) and atom0.name == builder.parser.tokens['NEWLINE']: + # atom0 = ast.Pass(atom0.lineno) # break test_astcompiler + atom0 = ast.Stmt([], atom0.lineno) # break test_astbuilder elif not isinstance(atom0, ast.Stmt): atom0 = ast.Stmt([atom0], atom0.lineno) - builder.push(ast.Module(builder.wrap_none(), atom0, atom0.lineno)) + builder.push(ast.Module(builder.space.w_None, atom0, atom0.lineno)) else: assert False, "Forbidden path" @@ -914,7 +418,7 @@ return items = [] token = atoms[1] - if isinstance(token, TokenObject) and token.name == tok.COMMA: + if isinstance(token, TokenObject) and token.name == builder.parser.tokens['COMMA']: for i in range(0, l, 2): # this is atoms not 1 items.append(atoms[i]) else: @@ -944,22 +448,23 @@ atoms = get_atoms(builder, nb) lineno = atoms[0].lineno code = atoms[-1] - names, defaults, flags = parse_arglist(slicecut(atoms, 1, -2)) + names, defaults, flags = parse_arglist(slicecut(atoms, 1, -2), builder) builder.push(ast.Lambda(names, defaults, flags, code, lineno)) + def build_trailer(builder, nb): """trailer: '(' ')' | '(' arglist ')' | '[' subscriptlist ']' | '.' NAME """ atoms = get_atoms(builder, nb) first_token = atoms[0] # Case 1 : '(' ... - if isinstance(first_token, TokenObject) and first_token.name == tok.LPAR: - if len(atoms) == 2: # and atoms[1].token == tok.RPAR: + if isinstance(first_token, TokenObject) and first_token.name == builder.parser.tokens['LPAR']: + if len(atoms) == 2: # and atoms[1].token == builder.parser.tokens['RPAR']: builder.push(ArglistObject([], None, None, first_token.lineno)) elif len(atoms) == 3: # '(' Arglist ')' # push arglist on the stack builder.push(atoms[1]) - elif isinstance(first_token, TokenObject) and first_token.name == tok.LSQB: + elif isinstance(first_token, TokenObject) and first_token.name == builder.parser.tokens['LSQB']: if len(atoms) == 3 and isinstance(atoms[1], SlicelistObject): builder.push(atoms[1]) else: @@ -994,6 +499,7 @@ else: assert False, "Trailer reducing implementation incomplete !" + def build_arglist(builder, nb): """ arglist: (argument ',')* ( '*' test [',' '**' test] | @@ -1002,7 +508,7 @@ [argument ','] ) """ atoms = get_atoms(builder, nb) - arguments, stararg, dstararg = parse_argument(atoms) + arguments, stararg, dstararg = parse_argument(atoms, builder) if atoms: lineno = atoms[0].lineno else: @@ -1010,16 +516,17 @@ builder.push(ArglistObject(arguments, stararg, dstararg, lineno)) + def build_subscript(builder, nb): """'.' '.' '.' | [test] ':' [test] [':' [test]] | test""" atoms = get_atoms(builder, nb) token = atoms[0] lineno = token.lineno - if isinstance(token, TokenObject) and token.name == tok.DOT: + if isinstance(token, TokenObject) and token.name == builder.parser.tokens['DOT']: # Ellipsis: builder.push(ast.Ellipsis(lineno)) elif len(atoms) == 1: - if isinstance(token, TokenObject) and token.name == tok.COLON: + if isinstance(token, TokenObject) and token.name == builder.parser.tokens['COLON']: sliceinfos = [None, None, None] builder.push(SlicelistObject('slice', sliceinfos, lineno)) else: @@ -1029,7 +536,7 @@ sliceinfos = [None, None, None] infosindex = 0 for token in atoms: - if isinstance(token, TokenObject) and token.name == tok.COLON: + if isinstance(token, TokenObject) and token.name == builder.parser.tokens['COLON']: infosindex += 1 else: sliceinfos[infosindex] = token @@ -1044,7 +551,6 @@ else: builder.push(SlicelistObject('slice', sliceinfos, lineno)) - def build_listmaker(builder, nb): """listmaker: test ( list_for | (',' test)* [','] )""" atoms = get_atoms(builder, nb) @@ -1055,7 +561,7 @@ if token.get_value() == 'for': # list comp expr = atoms[0] - list_for = parse_listcomp(atoms[1:]) + list_for = parse_listcomp(atoms[1:], builder) builder.push(ast.ListComp(expr, list_for, lineno)) return # regular list building (like in [1, 2, 3,]) @@ -1077,13 +583,15 @@ nodes = [] # remove '@', '(' and ')' from atoms and use parse_attraccess for token in atoms[1:]: - if isinstance(token, TokenObject) and \ - token.name in (tok.LPAR, tok.RPAR, tok.NEWLINE): + if isinstance(token, TokenObject) and ( + token.name == builder.parser.tokens['LPAR'] + or token.name == builder.parser.tokens['RPAR'] + or token.name == builder.parser.tokens['NEWLINE']): # skip those ones continue else: nodes.append(token) - obj = parse_attraccess(nodes) + obj = parse_attraccess(nodes, builder) builder.push(obj) def build_funcdef(builder, nb): @@ -1112,7 +620,7 @@ arglist = [] index = 3 arglist = slicecut(atoms, 3, -3) - names, default, flags = parse_arglist(arglist) + names, default, flags = parse_arglist(arglist, builder) funcname_token = atoms[1] assert isinstance(funcname_token, TokenObject) funcname = funcname_token.get_value() @@ -1293,7 +801,7 @@ while index < l: as_name = None # dotted name (a.b.c) - incr, name = parse_dotted_names(atoms[index:]) + incr, name = parse_dotted_names(atoms[index:], builder) index += incr # 'as' value if index < l: @@ -1310,11 +818,11 @@ while index 1: token = atoms[1] - if isinstance(token, TokenObject) and token.name == tok.RIGHTSHIFT: + if isinstance(token, TokenObject) and token.name == builder.parser.tokens['RIGHTSHIFT']: dest = atoms[2] # skip following comma start = 4 for index in range(start, l, 2): items.append(atoms[index]) last_token = atoms[-1] - if isinstance(last_token, TokenObject) and last_token.name == tok.COMMA: + if isinstance(last_token, TokenObject) and last_token.name == builder.parser.tokens['COMMA']: builder.push(ast.Print(items, dest, atoms[0].lineno)) else: builder.push(ast.Printnl(items, dest, atoms[0].lineno)) @@ -1464,8 +972,8 @@ """ atoms = get_atoms(builder, nb) - l = len(atoms) handlers = [] + l = len(atoms) else_ = None body = atoms[2] token = atoms[3] @@ -1544,133 +1052,7 @@ 'eval_input' : build_eval_input, 'with_stmt' : build_with_stmt, } - -# Build two almost identical ASTRULES dictionaries -ASTRULES = dict([(sym[key], value) for (key, value) in - ASTRULES_Template.iteritems() if key in sym]) -del ASTRULES_Template - -## Stack elements definitions ################################### - -class BaseRuleObject(ast.Node): - """Base class for unnamed rules""" - def __init__(self, count, lineno): - self.count = count - self.lineno = lineno # src.getline() - self.col = 0 # src.getcol() - - -class RuleObject(BaseRuleObject): - """A simple object used to wrap a rule or token""" - def __init__(self, name, count, lineno): - BaseRuleObject.__init__(self, count, lineno) - self.rulename = name - - def __str__(self): - return "" % (sym.sym_name[self.rulename], self.count) - - def __repr__(self): - return "" % (sym.sym_name[self.rulename], self.count) - - -class TempRuleObject(BaseRuleObject): - """used to keep track of how many items get_atom() should pop""" - - def __init__(self, name, count, lineno): - BaseRuleObject.__init__(self, count, lineno) - self.temp_rulename = name - - def __str__(self): - return "" % (self.temp_rulename, self.count) - - def __repr__(self): - return "" % (self.temp_rulename, self.count) - - -class TokenObject(ast.Node): - """A simple object used to wrap a rule or token""" - def __init__(self, name, value, lineno): - self.name = name - self.value = value - self.count = 0 - # self.line = 0 # src.getline() - self.col = 0 # src.getcol() - self.lineno = lineno - - def get_name(self): - return tok.tok_rpunct.get(self.name, - tok.tok_name.get(self.name, str(self.name))) - - def get_value(self): - value = self.value - if value is None: - value = '' - return value - - def __str__(self): - return "" % (self.get_name(), self.value) - - def __repr__(self): - return "" % (self.get_name(), self.value) - - -class ObjectAccessor(ast.Node): - """base class for ArglistObject, SubscriptObject and SlicelistObject - - FIXME: think about a more appropriate name - """ - -class ArglistObject(ObjectAccessor): - """helper class to build function's arg list - """ - def __init__(self, arguments, stararg, dstararg, lineno): - self.fake_rulename = 'arglist' - self.arguments = arguments - self.stararg = stararg - self.dstararg = dstararg - self.lineno = lineno - - def __str__(self): - return "" % self.value - - def __repr__(self): - return "" % self.value - -class SubscriptObject(ObjectAccessor): - """helper class to build subscript list - - self.value represents the __getitem__ argument - """ - def __init__(self, name, value, lineno): - self.fake_rulename = name - self.value = value - self.lineno = lineno - - def __str__(self): - return "" % self.value - - def __repr__(self): - return "" % self.value - -class SlicelistObject(ObjectAccessor): - """helper class to build slice objects - - self.value is a list [start, end, step] - self.fake_rulename can either be 'slice' or 'sliceobj' depending - on if a step is specfied or not (see Python's AST - for more information on that) - """ - def __init__(self, name, value, lineno): - self.fake_rulename = name - self.value = value - self.lineno = lineno - - def __str__(self): - return "" % self.value - - def __repr__(self): - return "" % self.value - + class AstBuilderContext(AbstractContext): """specific context management for AstBuidler""" @@ -1681,97 +1063,87 @@ class AstBuilder(BaseGrammarBuilder): """A builder that directly produce the AST""" - def __init__(self, rules=None, debug=0, space=None): - BaseGrammarBuilder.__init__(self, rules, debug) + def __init__(self, parser, debug=0, space=None): + BaseGrammarBuilder.__init__(self, parser, debug) self.rule_stack = [] self.space = space self.source_encoding = None self.with_enabled = False + self.build_rules = ASTRULES_Template + self.user_build_rules = {} def enable_with(self): if self.with_enabled: return self.with_enabled = True - self.keywords.update({'with':None, 'as': None}) - + # XXX + # self.keywords.update({'with':None, 'as': None}) + def context(self): return AstBuilderContext(self.rule_stack) def restore(self, ctx): -## if DEBUG_MODE: -## print "Restoring context (%s)" % (len(ctx.rule_stack)) assert isinstance(ctx, AstBuilderContext) 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) def push(self, obj): self.rule_stack.append(obj) - if not isinstance(obj, RuleObject) and not isinstance(obj, TokenObject): -## if DEBUG_MODE: -## print "Pushed:", str(obj), len(self.rule_stack) - pass - elif isinstance(obj, TempRuleObject): -## if DEBUG_MODE: -## print "Pushed:", str(obj), len(self.rule_stack) - pass - # print "\t", self.rule_stack def push_tok(self, name, value, src ): - self.push( TokenObject( name, value, src._token_lnum ) ) + self.push( TokenObject( name, value, src._token_lnum, self.parser ) ) def push_rule(self, name, count, src ): - self.push( RuleObject( name, count, src._token_lnum ) ) + self.push( RuleObject( name, count, src._token_lnum, self.parser ) ) def alternative( self, rule, source ): # Do nothing, keep rule on top of the stack -## rule_stack = self.rule_stack[:] if rule.is_root(): -## if DEBUG_MODE: -## print "ALT:", sym.sym_name[rule.codename], self.rule_stack - builder_func = ASTRULES.get(rule.codename, None) - if builder_func: - builder_func(self, 1) + rulename = self.parser.sym_name[rule.codename] + # builder_func = ASTRULES.get(rule.codename, None) + w_func = self.user_build_rules.get(rulename, None) + # user defined (applevel) function + if w_func: + w_items = self.space.newlist( [self.space.wrap( it ) for it in get_atoms(self, 1)] ) + w_astnode = self.space.call_function(w_func, w_items) + astnode = self.space.interp_w(ast.Node, w_astnode, can_be_None=False) + self.push(astnode) else: -## if DEBUG_MODE: -## print "No reducing implementation for %s, just push it on stack" % ( -## sym.sym_name[rule.codename]) - self.push_rule(rule.codename, 1, source) + builder_func = self.build_rules.get(rulename, None) + if builder_func: + builder_func(self, 1) + else: + self.push_rule(rule.codename, 1, source) else: self.push_rule(rule.codename, 1, source) -## if DEBUG_MODE > 1: -## show_stack(rule_stack, self.rule_stack) -## x = raw_input("Continue ?") return True def sequence(self, rule, source, elts_number): """ """ -## rule_stack = self.rule_stack[:] if rule.is_root(): -## if DEBUG_MODE: -## print "SEQ:", sym.sym_name[rule.codename] - builder_func = ASTRULES.get(rule.codename, None) - if builder_func: - # print "REDUCING SEQUENCE %s" % sym.sym_name[rule.codename] - builder_func(self, elts_number) + rulename = self.parser.sym_name[rule.codename] + # builder_func = ASTRULES.get(rule.codename, None) + w_func = self.user_build_rules.get(rulename, None) + # user defined (applevel) function + if w_func: + w_items = self.space.newlist( [self.space.wrap( it ) for it in get_atoms(self, elts_number)] ) + w_astnode = self.space.call_function(w_func, w_items) + astnode = self.space.interp_w(ast.Node, w_astnode, can_be_None=False) + self.push(astnode) else: -## if DEBUG_MODE: -## print "No reducing implementation for %s, just push it on stack" % ( -## sym.sym_name[rule.codename]) - self.push_rule(rule.codename, elts_number, source) + builder_func = self.build_rules.get(rulename, None) + if builder_func: + builder_func(self, elts_number) + else: + self.push_rule(rule.codename, elts_number, source) else: self.push_rule(rule.codename, elts_number, source) -## if DEBUG_MODE > 1: -## show_stack(rule_stack, self.rule_stack) -## raw_input("Continue ?") return True def token(self, name, value, source): -## if DEBUG_MODE: -## print "TOK:", tok.tok_name[name], name, value self.push_tok(name, value, source) return True @@ -1799,7 +1171,7 @@ return space.call_function(f, space.wrap(value)) def is_basestring_const(self, expr): - if not isinstance(expr,ast.Const): + if not isinstance(expr, ast.Const): return False space = self.space return space.is_true(space.isinstance(expr.value,space.w_basestring)) Added: pypy/dist/pypy/interpreter/pyparser/asthelper.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/interpreter/pyparser/asthelper.py Wed Feb 28 18:30:48 2007 @@ -0,0 +1,635 @@ +from pypy.interpreter.typedef import TypeDef, GetSetProperty, interp_attrproperty +from pypy.interpreter.astcompiler import ast, consts +from pypy.interpreter.pyparser.error import SyntaxError + + +### Parsing utilites ################################################# +def parse_except_clause(tokens): + """parses 'except' [test [',' test]] ':' suite + and returns a 4-tuple : (tokens_read, expr1, expr2, except_body) + """ + lineno = tokens[0].lineno + clause_length = 1 + # Read until end of except clause (bound by following 'else', + # or 'except' or end of tokens) + while clause_length < len(tokens): + token = tokens[clause_length] + if isinstance(token, TokenObject) and \ + (token.get_value() == 'except' or token.get_value() == 'else'): + break + clause_length += 1 + if clause_length == 3: + # case 'except: body' + return (3, None, None, tokens[2]) + elif clause_length == 4: + # case 'except Exception: body': + return (4, tokens[1], None, tokens[3]) + else: + # case 'except Exception, exc: body' + return (6, tokens[1], to_lvalue(tokens[3], consts.OP_ASSIGN), tokens[5]) + + +def parse_dotted_names(tokens, builder): + """parses NAME('.' NAME)* and returns full dotted name + + this function doesn't assume that the list ends after the + last 'NAME' element + """ + first = tokens[0] + assert isinstance(first, TokenObject) + name = first.get_value() + l = len(tokens) + index = 1 + for index in range(1, l, 2): + token = tokens[index] + assert isinstance(token, TokenObject) + if token.name != builder.parser.tokens['DOT']: + break + token = tokens[index+1] + assert isinstance(token, TokenObject) + name += '.' + value = token.get_value() + name += value + return (index, name) + +def parse_argument(tokens, builder): + """parses function call arguments""" + l = len(tokens) + index = 0 + arguments = [] + last_token = None + building_kw = False + kw_built = False + stararg_token = None + dstararg_token = None + while index < l: + cur_token = tokens[index] + if not isinstance(cur_token, TokenObject): + index += 1 + if not building_kw: + arguments.append(cur_token) + else: + last_token = arguments.pop() + assert isinstance(last_token, ast.Name) # used by rtyper + arguments.append(ast.Keyword(last_token.varname, cur_token, last_token.lineno)) + building_kw = False + kw_built = True + continue + elif cur_token.name == builder.parser.tokens['COMMA']: + index += 1 + continue + elif cur_token.name == builder.parser.tokens['EQUAL']: + index += 1 + building_kw = True + continue + elif cur_token.name == builder.parser.tokens['STAR'] or cur_token.name == builder.parser.tokens['DOUBLESTAR']: + index += 1 + if cur_token.name == builder.parser.tokens['STAR']: + stararg_token = tokens[index] + index += 1 + if index >= l: + break + index += 2 # Skip COMMA and DOUBLESTAR + dstararg_token = tokens[index] + break + elif cur_token.get_value() == 'for': + if len(arguments) != 1: + raise SyntaxError("invalid syntax", cur_token.lineno, + cur_token.col) + expr = arguments[0] + genexpr_for = parse_genexpr_for(tokens[index:]) + genexpr_for[0].is_outmost = True + gexp = ast.GenExpr(ast.GenExprInner(expr, genexpr_for, expr.lineno), expr.lineno) + arguments[0] = gexp + break + return arguments, stararg_token, dstararg_token + + +def parse_fpdef(tokens, index, builder): + """fpdef: fpdef: NAME | '(' fplist ')' + fplist: fpdef (',' fpdef)* [','] + + This intend to be a RPYTHON compliant implementation of _parse_fpdef, + but it can't work with the default compiler. + We switched to use astcompiler module now + """ + nodes = [] + comma = False + while True: + token = tokens[index] + index += 1 + assert isinstance(token, TokenObject) + if token.name == builder.parser.tokens['LPAR']: # nested item + index, node = parse_fpdef(tokens, index, builder) + elif token.name == builder.parser.tokens['RPAR']: # end of current nesting + break + else: # name + val = token.get_value() + node = ast.AssName(val, consts.OP_ASSIGN, token.lineno) + nodes.append(node) + + token = tokens[index] + index += 1 + assert isinstance(token, TokenObject) + if token.name == builder.parser.tokens['COMMA']: + comma = True + else: + assert token.name == builder.parser.tokens['RPAR'] + break + if len(nodes) == 1 and not comma: + node = nodes[0] + else: + node = ast.AssTuple(nodes, token.lineno) + return index, node + +def parse_arglist(tokens, builder): + """returns names, defaults, flags""" + l = len(tokens) + index = 0 + defaults = [] + names = [] + flags = 0 + first_with_default = -1 + while index < l: + cur_token = tokens[index] + index += 1 + if not isinstance(cur_token, TokenObject): + # XXX: think of another way to write this test + defaults.append(cur_token) + if first_with_default == -1: + first_with_default = len(names) - 1 + elif cur_token.name == builder.parser.tokens['COMMA']: + # We could skip test COMMA by incrementing index cleverly + # but we might do some experiment on the grammar at some point + continue + elif cur_token.name == builder.parser.tokens['LPAR']: + index, node = parse_fpdef(tokens, index, builder) + names.append(node) + elif cur_token.name == builder.parser.tokens['STAR'] or cur_token.name == builder.parser.tokens['DOUBLESTAR']: + if cur_token.name == builder.parser.tokens['STAR']: + cur_token = tokens[index] + assert isinstance(cur_token, TokenObject) + index += 1 + if cur_token.name == builder.parser.tokens['NAME']: + val = cur_token.get_value() + names.append( ast.AssName( val, consts.OP_ASSIGN ) ) + flags |= consts.CO_VARARGS + index += 1 + if index >= l: + break + else: + # still more tokens to read + cur_token = tokens[index] + index += 1 + else: + raise SyntaxError("incomplete varags", cur_token.lineno, + cur_token.col) + assert isinstance(cur_token, TokenObject) + if cur_token.name != builder.parser.tokens['DOUBLESTAR']: + raise SyntaxError("Unexpected token", cur_token.lineno, + cur_token.col) + cur_token = tokens[index] + index += 1 + assert isinstance(cur_token, TokenObject) + if cur_token.name == builder.parser.tokens['NAME']: + val = cur_token.get_value() + names.append( ast.AssName( val, consts.OP_ASSIGN ) ) + flags |= consts.CO_VARKEYWORDS + index += 1 + else: + raise SyntaxError("incomplete varags", cur_token.lineno, + cur_token.col) + if index < l: + token = tokens[index] + raise SyntaxError("unexpected token" , token.lineno, + token.col) + elif cur_token.name == builder.parser.tokens['NAME']: + val = cur_token.get_value() + names.append( ast.AssName( val, consts.OP_ASSIGN ) ) + + if first_with_default != -1: + num_expected_with_default = len(names) - first_with_default + if flags & consts.CO_VARKEYWORDS: + num_expected_with_default -= 1 + if flags & consts.CO_VARARGS: + num_expected_with_default -= 1 + if len(defaults) != num_expected_with_default: + raise SyntaxError('non-default argument follows default argument', + tokens[0].lineno, tokens[0].col) + return names, defaults, flags + + +def parse_listcomp(tokens, builder): + """parses 'for j in k for i in j if i %2 == 0' and returns + a GenExprFor instance + XXX: refactor with listmaker ? + """ + list_fors = [] + ifs = [] + index = 0 + if tokens: + lineno = tokens[0].lineno + else: + lineno = -1 + while index < len(tokens): + token = tokens[index] + assert isinstance(token, TokenObject) # rtyper info + check + if token.get_value() == 'for': + index += 1 # skip 'for' + ass_node = to_lvalue(tokens[index], consts.OP_ASSIGN) + index += 2 # skip 'in' + iterables = [tokens[index]] + index += 1 + while index < len(tokens): + tok2 = tokens[index] + if not isinstance(tok2, TokenObject): + break + if tok2.name != builder.parser.tokens['COMMA']: + break + iterables.append(tokens[index+1]) + index += 2 + if len(iterables) == 1: + iterable = iterables[0] + else: + iterable = ast.Tuple(iterables, token.lineno) + while index < len(tokens): + token = tokens[index] + assert isinstance(token, TokenObject) # rtyper info + if token.get_value() == 'if': + ifs.append(ast.ListCompIf(tokens[index+1], token.lineno)) + index += 2 + else: + break + list_fors.append(ast.ListCompFor(ass_node, iterable, ifs, lineno)) + ifs = [] + else: + assert False, 'Unexpected token: expecting for in listcomp' + # + # Original implementation: + # + # if tokens[index].get_value() == 'for': + # index += 1 # skip 'for' + # ass_node = to_lvalue(tokens[index], consts.OP_ASSIGN) + # index += 2 # skip 'in' + # iterable = tokens[index] + # index += 1 + # while index < len(tokens) and tokens[index].get_value() == 'if': + # ifs.append(ast.ListCompIf(tokens[index+1])) + # index += 2 + # list_fors.append(ast.ListCompFor(ass_node, iterable, ifs)) + # ifs = [] + # else: + # raise ValueError('Unexpected token: %s' % tokens[index]) + return list_fors + + +def parse_genexpr_for(tokens): + """parses 'for j in k for i in j if i %2 == 0' and returns + a GenExprFor instance + XXX: if RPYTHON supports to pass a class object to a function, + we could refactor parse_listcomp and parse_genexpr_for, + and call : + - parse_listcomp(tokens, forclass=ast.GenExprFor, ifclass=...) + or: + - parse_listcomp(tokens, forclass=ast.ListCompFor, ifclass=...) + """ + genexpr_fors = [] + ifs = [] + index = 0 + if tokens: + lineno = tokens[0].lineno + else: + lineno = -1 + while index < len(tokens): + token = tokens[index] + assert isinstance(token, TokenObject) # rtyper info + check + if token.get_value() == 'for': + index += 1 # skip 'for' + ass_node = to_lvalue(tokens[index], consts.OP_ASSIGN) + index += 2 # skip 'in' + iterable = tokens[index] + index += 1 + while index < len(tokens): + token = tokens[index] + assert isinstance(token, TokenObject) # rtyper info + if token.get_value() == 'if': + ifs.append(ast.GenExprIf(tokens[index+1], token.lineno)) + index += 2 + else: + break + genexpr_fors.append(ast.GenExprFor(ass_node, iterable, ifs, lineno)) + ifs = [] + else: + raise SyntaxError('invalid syntax', + token.lineno, token.col) + return genexpr_fors + +def get_docstring(builder,stmt): + """parses a Stmt node. + + If a docstring if found, the Discard node is **removed** + from and the docstring is returned. + + If no docstring is found, is left unchanged + and None is returned + """ + if not isinstance(stmt, ast.Stmt): + return None + doc = builder.wrap_none() + if len(stmt.nodes): + first_child = stmt.nodes[0] + if isinstance(first_child, ast.Discard): + expr = first_child.expr + if builder.is_basestring_const(expr): + # This *is* a docstring, remove it from stmt list + assert isinstance(expr, ast.Const) + del stmt.nodes[0] + doc = expr.value + return doc + + +def to_lvalue(ast_node, flags): + lineno = ast_node.lineno + if isinstance( ast_node, ast.Name ): + return ast.AssName(ast_node.varname, flags, lineno) + # return ast.AssName(ast_node.name, flags) + elif isinstance(ast_node, ast.Tuple): + nodes = [] + # FIXME: should ast_node.getChildren() but it's not annotable + # because of flatten() + for node in ast_node.nodes: + nodes.append(to_lvalue(node, flags)) + return ast.AssTuple(nodes, lineno) + elif isinstance(ast_node, ast.List): + nodes = [] + # FIXME: should ast_node.getChildren() but it's not annotable + # because of flatten() + for node in ast_node.nodes: + nodes.append(to_lvalue(node, flags)) + return ast.AssList(nodes, lineno) + elif isinstance(ast_node, ast.Getattr): + expr = ast_node.expr + assert isinstance(ast_node, ast.Getattr) + attrname = ast_node.attrname + return ast.AssAttr(expr, attrname, flags, lineno) + elif isinstance(ast_node, ast.Subscript): + ast_node.flags = flags + return ast_node + elif isinstance(ast_node, ast.Slice): + ast_node.flags = flags + return ast_node + else: + if isinstance(ast_node, ast.GenExpr): + raise SyntaxError("assign to generator expression not possible", + lineno, 0, '') + elif isinstance(ast_node, ast.ListComp): + raise SyntaxError("can't assign to list comprehension", + lineno, 0, '') + elif isinstance(ast_node, ast.CallFunc): + if flags == consts.OP_DELETE: + raise SyntaxError("can't delete function call", + lineno, 0, '') + else: + raise SyntaxError("can't assign to function call", + lineno, 0, '') + else: + raise SyntaxError("can't assign to non-lvalue", + lineno, 0, '') + +def is_augassign( ast_node ): + if ( isinstance( ast_node, ast.Name ) or + isinstance( ast_node, ast.Slice ) or + isinstance( ast_node, ast.Subscript ) or + isinstance( ast_node, ast.Getattr ) ): + return True + return False + +def get_atoms(builder, nb): + atoms = [] + i = nb + while i>0: + obj = builder.pop() + if isinstance(obj, BaseRuleObject): + i += obj.count + else: + atoms.append( obj ) + i -= 1 + atoms.reverse() + return atoms + +#def eval_string(value): +# """temporary implementation +# +# FIXME: need to be finished (check compile.c (parsestr) and +# stringobject.c (PyString_DecodeEscape()) for complete implementation) +# """ +# # return eval(value) +# if len(value) == 2: +# return '' +# result = '' +# length = len(value) +# quotetype = value[0] +# index = 1 +# while index < length and value[index] == quotetype: +# index += 1 +# if index == 6: +# # empty strings like """""" or '''''' +# return '' +# # XXX: is it RPYTHON to do this value[index:-index] +# chars = [char for char in value[index:len(value)-index]] +# result = ''.join(chars) +# result = result.replace('\\\\', '\\') +# d = {'\\b' : '\b', '\\f' : '\f', '\\t' : '\t', '\\n' : '\n', +# '\\r' : '\r', '\\v' : '\v', '\\a' : '\a', +# } +# for escaped, value in d.items(): +# result = result.replace(escaped, value) +# return result + + +## misc utilities, especially for power: rule +def reduce_callfunc(obj, arglist): + """generic factory for CallFunc nodes""" + assert isinstance(arglist, ArglistObject) + return ast.CallFunc(obj, arglist.arguments, + arglist.stararg, arglist.dstararg, arglist.lineno) + +def reduce_subscript(obj, subscript): + """generic factory for Subscript nodes""" + assert isinstance(subscript, SubscriptObject) + return ast.Subscript(obj, consts.OP_APPLY, subscript.value, subscript.lineno) + +def reduce_slice(obj, sliceobj): + """generic factory for Slice nodes""" + assert isinstance(sliceobj, SlicelistObject) + if sliceobj.fake_rulename == 'slice': + start = sliceobj.value[0] + end = sliceobj.value[1] + return ast.Slice(obj, consts.OP_APPLY, start, end, sliceobj.lineno) + else: + return ast.Subscript(obj, consts.OP_APPLY, ast.Sliceobj(sliceobj.value, + sliceobj.lineno), sliceobj.lineno) + +def parse_attraccess(tokens, builder): + """parses token list like ['a', '.', 'b', '.', 'c', ...] + + and returns an ast node : ast.Getattr(Getattr(Name('a'), 'b'), 'c' ...) + """ + token = tokens[0] + # XXX HACK for when parse_attraccess is called from build_decorator + if isinstance(token, TokenObject): + val = token.get_value() + result = ast.Name(val, token.lineno) + else: + result = token + index = 1 + while index < len(tokens): + token = tokens[index] + if isinstance(token, TokenObject) and token.name == builder.parser.tokens['DOT']: + index += 1 + token = tokens[index] + assert isinstance(token, TokenObject) + result = ast.Getattr(result, token.get_value(), token.lineno) + elif isinstance(token, ArglistObject): + result = reduce_callfunc(result, token) + elif isinstance(token, SubscriptObject): + result = reduce_subscript(result, token) + elif isinstance(token, SlicelistObject): + result = reduce_slice(result, token) + else: + assert False, "Don't know how to handle index %s of %s" % (index, len(tokens)) + index += 1 + return result + + + +## Stack elements definitions ################################### + +class BaseRuleObject(ast.Node): + """Base class for unnamed rules""" + def __init__(self, count, lineno): + self.count = count + self.lineno = lineno # src.getline() + self.col = 0 # src.getcol() + + +class RuleObject(BaseRuleObject): + """A simple object used to wrap a rule or token""" + def __init__(self, name, count, lineno, parser): + BaseRuleObject.__init__(self, count, lineno) + self.rulename = name + self.parser = parser + + def __str__(self): + return "" % ( self.parser.symbol_repr(self.rulename), self.count) + + def __repr__(self): + return "" % ( self.parser.symbol_repr(self.rulename), self.count) + + +class TempRuleObject(BaseRuleObject): + """used to keep track of how many items get_atom() should pop""" + def __init__(self, name, count, lineno): + BaseRuleObject.__init__(self, count, lineno) + self.temp_rulename = name + + def __str__(self): + return "" % (self.temp_rulename, self.count) + + def __repr__(self): + return "" % (self.temp_rulename, self.count) + + +class TokenObject(ast.Node): + """A simple object used to wrap a rule or token""" + def __init__(self, name, value, lineno, parser): + self.name = name + self.value = value + self.count = 0 + # self.line = 0 # src.getline() + self.col = 0 # src.getcol() + self.lineno = lineno + self.parser = parser + + def get_name(self): + tokname = self.parser.tok_name.get(self.name, str(self.name)) + return self.parser.tok_rvalues.get(self.name, tokname) + + def get_value(self): + value = self.value + if value is None: + value = '' + return value + + def descr_fget_value(space, self): + value = self.get_value() + return space.wrap(value) + + def __str__(self): + return "" % (self.get_name(), self.value) + + def __repr__(self): + return "" % (self.get_name(), self.value) + +TokenObject.typedef = TypeDef('BuildToken', + name=interp_attrproperty('name', cls=TokenObject), + lineno=interp_attrproperty('lineno', cls=TokenObject), + value=GetSetProperty(TokenObject.descr_fget_value)) + +class ObjectAccessor(ast.Node): + """base class for ArglistObject, SubscriptObject and SlicelistObject + + FIXME: think about a more appropriate name + """ + +class ArglistObject(ObjectAccessor): + """helper class to build function's arg list + """ + def __init__(self, arguments, stararg, dstararg, lineno): + self.fake_rulename = 'arglist' + self.arguments = arguments + self.stararg = stararg + self.dstararg = dstararg + self.lineno = lineno + + def __str__(self): + return "" % self.value + + def __repr__(self): + return "" % self.value + +class SubscriptObject(ObjectAccessor): + """helper class to build subscript list + + self.value represents the __getitem__ argument + """ + def __init__(self, name, value, lineno): + self.fake_rulename = name + self.value = value + self.lineno = lineno + + def __str__(self): + return "" % self.value + + def __repr__(self): + return "" % self.value + +class SlicelistObject(ObjectAccessor): + """helper class to build slice objects + + self.value is a list [start, end, step] + self.fake_rulename can either be 'slice' or 'sliceobj' depending + on if a step is specfied or not (see Python's AST + for more information on that) + """ + def __init__(self, name, value, lineno): + self.fake_rulename = name + self.value = value + self.lineno = lineno + + def __str__(self): + return "" % self.value + + def __repr__(self): + return "" % self.value + Modified: pypy/dist/pypy/interpreter/pyparser/ebnfgrammar.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/ebnfgrammar.py (original) +++ pypy/dist/pypy/interpreter/pyparser/ebnfgrammar.py Wed Feb 28 18:30:48 2007 @@ -1,47 +1,18 @@ # This module contains the grammar parser # and the symbol mappings -from grammar import BaseGrammarBuilder, Alternative, Sequence, Token, \ - KleeneStar, GrammarElement, build_first_sets, EmptyToken +from grammar import Alternative, Sequence, Token, KleeneStar, \ + GrammarElement, Parser +class GrammarParser(Parser): + pass -sym_map = {} -sym_rmap = {} -_count = 0 - -def g_add_symbol( name ): - global _count - if name in sym_rmap: - return sym_rmap[name] - val = _count - _count += 1 - sym_map[val] = name - sym_rmap[name] = val - return val - - -tok_map = {} -tok_rmap = {} - -def g_add_token( **kwargs ): - global _count - assert len(kwargs) == 1 - sym, name = kwargs.popitem() - if name in tok_rmap: - return tok_rmap[name] - val = _count - _count += 1 - tok_map[val] = name - tok_rmap[name] = val - sym_map[val] = sym - sym_rmap[sym] = val - return val - -g_add_token( EOF='EOF' ) +GRAMMAR_GRAMMAR = GrammarParser() def grammar_grammar(): - """NOT RPYTHON (mostly because of g_add_token I suppose) + """ + (mostly because of g_add_token I suppose) Builds the grammar for the grammar file Here's the description of the grammar's grammar :: @@ -51,59 +22,56 @@ alternative: sequence ( '|' sequence )+ star: '*' | '+' - sequence: (SYMBOL star? | STRING | option | group star? )+ + sequence: (SYMBOL star? | STRING | option | group )+ option: '[' alternative ']' group: '(' alternative ')' star? """ - global sym_map - S = g_add_symbol - T = g_add_token + p = GRAMMAR_GRAMMAR + p.add_token('EOF','EOF') + # star: '*' | '+' - star = Alternative( S("star"), [Token(T(TOK_STAR='*')), Token(T(TOK_ADD='+'))] ) - star_opt = KleeneStar ( S("star_opt"), 0, 1, rule=star ) + star = p.Alternative_n( "star", [p.Token_n('TOK_STAR', '*'), p.Token_n('TOK_ADD', '+')] ) + star_opt = p.KleeneStar_n( "star_opt", 0, 1, rule=star ) # rule: SYMBOL ':' alternative - symbol = Sequence( S("symbol"), [Token(T(TOK_SYMBOL='SYMBOL')), star_opt] ) - symboldef = Token( T(TOK_SYMDEF="SYMDEF") ) - alternative = Sequence( S("alternative"), []) - rule = Sequence( S("rule"), [symboldef, alternative] ) + symbol = p.Sequence_n( "symbol", [p.Token_n('TOK_SYMBOL'), star_opt] ) + symboldef = p.Token_n( 'TOK_SYMDEF' ) + alternative = p.Sequence_n( "alternative", []) + rule = p.Sequence_n( "rule", [symboldef, alternative] ) # grammar: rule+ - grammar = KleeneStar( S("grammar"), _min=1, rule=rule ) + grammar = p.KleeneStar_n( "grammar", _min=1, rule=rule ) # alternative: sequence ( '|' sequence )* - sequence = KleeneStar( S("sequence"), 1 ) - seq_cont_list = Sequence( S("seq_cont_list"), [Token(T(TOK_BAR='|')), sequence] ) - sequence_cont = KleeneStar( S("sequence_cont"),0, rule=seq_cont_list ) - + sequence = p.KleeneStar_n( "sequence", 1 ) + seq_cont_list = p.Sequence_n( "seq_cont_list", [p.Token_n('TOK_BAR', '|'), sequence] ) + sequence_cont = p.KleeneStar_n( "sequence_cont",0, rule=seq_cont_list ) + alternative.args = [ sequence, sequence_cont ] # option: '[' alternative ']' - option = Sequence( S("option"), [Token(T(TOK_LBRACKET='[')), alternative, Token(T(TOK_RBRACKET=']'))] ) + option = p.Sequence_n( "option", [p.Token_n('TOK_LBRACKET', '['), alternative, p.Token_n('TOK_RBRACKET', ']')] ) # group: '(' alternative ')' - group = Sequence( S("group"), [Token(T(TOK_LPAR='(')), alternative, Token(T(TOK_RPAR=')')), star_opt] ) + group = p.Sequence_n( "group", [p.Token_n('TOK_LPAR', '('), alternative, p.Token_n('TOK_RPAR', ')'), star_opt] ) # sequence: (SYMBOL | STRING | option | group )+ - string = Token(T(TOK_STRING='STRING')) - alt = Alternative( S("sequence_alt"), [symbol, string, option, group] ) + string = p.Token_n('TOK_STRING') + alt = p.Alternative_n( "sequence_alt", [symbol, string, option, group] ) sequence.args = [ alt ] + p.root_rules['grammar'] = grammar + p.build_first_sets() + return p - rules = [ star, star_opt, symbol, alternative, rule, grammar, sequence, - seq_cont_list, sequence_cont, option, group, alt ] - build_first_sets( rules ) - return grammar - - -GRAMMAR_GRAMMAR = grammar_grammar() -for _sym, _value in sym_rmap.items(): - globals()[_sym] = _value +grammar_grammar() +for _sym, _value in GRAMMAR_GRAMMAR.symbols.items(): + assert not hasattr( GRAMMAR_GRAMMAR, _sym ), _sym + setattr(GRAMMAR_GRAMMAR, _sym, _value ) + +for _sym, _value in GRAMMAR_GRAMMAR.tokens.items(): + assert not hasattr( GRAMMAR_GRAMMAR, _sym ) + setattr(GRAMMAR_GRAMMAR, _sym, _value ) -# cleanup -del _sym -del _value del grammar_grammar -del g_add_symbol -del g_add_token Modified: pypy/dist/pypy/interpreter/pyparser/ebnflexer.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/ebnflexer.py (original) +++ pypy/dist/pypy/interpreter/pyparser/ebnflexer.py Wed Feb 28 18:30:48 2007 @@ -3,8 +3,8 @@ analyser in grammar.py """ -from grammar import TokenSource, Token -from ebnfgrammar import * +from grammar import TokenSource, Token, AbstractContext +from ebnfgrammar import GRAMMAR_GRAMMAR as G def match_symbol( input, start, stop ): @@ -15,6 +15,12 @@ idx+=1 return idx + +class GrammarSourceContext(AbstractContext): + def __init__(self, pos, peek): + self.pos = pos + self.peek = peek + class GrammarSource(TokenSource): """Fully RPython - see targetebnflexer.py The grammar tokenizer @@ -25,8 +31,9 @@ SYMBOL: a rule symbol usually appearing right of a SYMDEF tokens: '[', ']', '(' ,')', '*', '+', '|' """ - def __init__(self, inpstring ): - TokenSource.__init__(self) + def __init__(self, parser, inpstring): + # TokenSource.__init__(self) + self.parser = parser self.input = inpstring self.pos = 0 self.begin = 0 @@ -36,7 +43,7 @@ def context(self): """returns an opaque context object, used to backtrack to a well known position in the parser""" - return self.pos, self._peeked + return GrammarSourceContext( self.pos, self._peeked ) def offset(self, ctx=None): """Returns the current parsing position from the start @@ -44,14 +51,16 @@ if ctx is None: return self.pos else: - assert type(ctx)==int - return ctx + assert isinstance(ctx, GrammarSourceContext) + return ctx.pos def restore(self, ctx): """restore the context provided by context()""" - self.pos, self._peeked = ctx + assert isinstance( ctx, GrammarSourceContext ) + self.pos = ctx.pos + self._peeked = ctx.peek - def current_line(self): + def current_linesource(self): pos = idx = self.begin inp = self.input end = len(inp) @@ -65,7 +74,6 @@ def current_lineno(self): return self.current_line - def skip_empty_lines(self, input, start, end ): idx = start # assume beginning of a line @@ -117,17 +125,18 @@ # means backtracking more than one token # will re-tokenize the stream (but this is the # grammar lexer so we don't care really!) + _p = self.parser if self._peeked is not None: peeked = self._peeked self._peeked = None return peeked - + pos = self.pos inp = self.input end = len(self.input) pos = self.skip_empty_lines(inp,pos,end) if pos==end: - return Token(EOF, None) + return _p.build_token( _p.EOF, None) # at this point nextchar is not a white space nor \n nextchr = inp[pos] @@ -139,22 +148,22 @@ self.pos = npos _endpos = npos - 1 assert _endpos>=0 - return Token(TOK_STRING,inp[pos+1:_endpos]) + return _p.build_token( _p.TOK_STRING, inp[pos+1:_endpos]) else: npos = match_symbol( inp, pos, end) if npos!=pos: self.pos = npos if npos!=end and inp[npos]==":": self.pos += 1 - return Token(TOK_SYMDEF,inp[pos:npos]) + return _p.build_token( _p.TOK_SYMDEF, inp[pos:npos]) else: - return Token(TOK_SYMBOL,inp[pos:npos]) - + return _p.build_token( _p.TOK_SYMBOL, inp[pos:npos]) + # we still have pos!=end here chr = inp[pos] if chr in "[]()*+|": self.pos = pos+1 - return Token(tok_rmap[chr], chr) + return _p.build_token( _p.tok_values[chr], chr) self.RaiseError( "Unknown token" ) def peek(self): Modified: pypy/dist/pypy/interpreter/pyparser/ebnfparse.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/ebnfparse.py (original) +++ pypy/dist/pypy/interpreter/pyparser/ebnfparse.py Wed Feb 28 18:30:48 2007 @@ -1,15 +1,31 @@ -#!/usr/bin/env python -from grammar import BaseGrammarBuilder, Alternative, Sequence, Token, \ - KleeneStar, GrammarElement, build_first_sets, EmptyToken -from ebnflexer import GrammarSource -import ebnfgrammar -from ebnfgrammar import GRAMMAR_GRAMMAR, sym_map -from syntaxtree import AbstractSyntaxVisitor -import pytoken -import pysymbol +from grammar import Token, GrammarProxy +from grammar import AbstractBuilder, AbstractContext + + +ORDA = ord("A") +ORDZ = ord("Z") +ORDa = ord("a") +ORDz = ord("z") +ORD0 = ord("0") +ORD9 = ord("9") +ORD_ = ord("_") + +def is_py_name( name ): + if len(name)<1: + return False + v = ord(name[0]) + if not (ORDA <= v <= ORDZ or + ORDa <= v <= ORDz or v == ORD_): + return False + for c in name: + v = ord(c) + if not (ORDA <= v <= ORDZ or + ORDa <= v <= ORDz or + ORD0 <= v <= ORD9 or + v == ORD_): + return False + return True -import re -py_name = re.compile(r"[a-zA-Z_][a-zA-Z0-9_]*", re.M) punct=['>=', '<>', '!=', '<', '>', '<=', '==', '\\*=', '//=', '%=', '^=', '<<=', '\\*\\*=', '\\', '=', @@ -18,19 +34,14 @@ '%', '<<', '//', '\\', '', '\n\\)', '\\(', ';', ':', '@', '\\[', '\\]', '`', '\\{', '\\}'] +TERMINALS = ['NAME', 'NUMBER', 'STRING', 'NEWLINE', 'ENDMARKER', + 'INDENT', 'DEDENT' ] -TERMINALS = [ - 'NAME', 'NUMBER', 'STRING', 'NEWLINE', 'ENDMARKER', - 'INDENT', 'DEDENT' ] - - -## Grammar Visitors ################################################## -# FIXME: parsertools.py ? parser/__init__.py ? class NameToken(Token): """A token that is not a keyword""" - def __init__(self, keywords=None ): - Token.__init__(self, pytoken.NAME) + def __init__(self, parser, keywords=None): + Token.__init__(self, parser, parser.tokens['NAME']) self.keywords = keywords def match(self, source, builder, level=0): @@ -44,227 +55,228 @@ else: # error unknown or negative integer """ - ctx = source.context() tk = source.next() - if tk.codename==self.codename: - if tk.value not in builder.keywords: + if tk.codename == self.codename: + # XXX (adim): this is trunk's keyword management + # if tk.value not in builder.keywords: + if tk.value not in self.keywords: ret = builder.token( tk.codename, tk.value, source ) - return self.debug_return( ret, tk.codename, tk.value ) + return ret source.restore( ctx ) return 0 - + + def match_token(self, builder, other): """special case of match token for tokens which are really keywords """ if not isinstance(other, Token): - raise RuntimeError("Unexpected token type %r" % other) - if other is EmptyToken: + raise RuntimeError("Unexpected token type") + if other is self.parser.EmptyToken: return False if other.codename != self.codename: return False - if other.value in builder.keywords: + # XXX (adim): this is trunk's keyword management + # if other.value in builder.keywords: + if other.value in self.keywords: return False return True - -def ebnf_handle_grammar(self, node): - for rule in node.nodes: - rule.visit(self) - # the rules are registered already - # we do a pass through the variables to detect - # terminal symbols from non terminals - for r in self.items: - for i,a in enumerate(r.args): - if a.codename in self.rules: - assert isinstance(a,Token) - r.args[i] = self.rules[a.codename] - if a.codename in self.terminals: - del self.terminals[a.codename] - # XXX .keywords also contains punctuations - self.terminals['NAME'].keywords = self.keywords - -def ebnf_handle_rule(self, node): - symdef = node.nodes[0].value - self.current_rule = symdef - self.current_subrule = 0 - alt = node.nodes[1] - rule = alt.visit(self) - if not isinstance(rule, Token): - rule.codename = self.symbols.add_symbol( symdef ) - self.rules[rule.codename] = rule - -def ebnf_handle_alternative(self, node): - items = [node.nodes[0].visit(self)] - items += node.nodes[1].visit(self) - if len(items) == 1 and not items[0].is_root(): - return items[0] - alt = Alternative(self.new_symbol(), items) - return self.new_item(alt) - -def ebnf_handle_sequence( self, node ): - """ """ - items = [] - for n in node.nodes: - items.append( n.visit(self) ) - if len(items)==1: - return items[0] - elif len(items)>1: - return self.new_item( Sequence( self.new_symbol(), items) ) - raise RuntimeError("Found empty sequence") - -def ebnf_handle_sequence_cont( self, node ): - """Returns a list of sequences (possibly empty)""" - return [n.visit(self) for n in node.nodes] - -def ebnf_handle_seq_cont_list(self, node): - return node.nodes[1].visit(self) - - -def ebnf_handle_symbol(self, node): - star_opt = node.nodes[1] - sym = node.nodes[0].value - terminal = self.terminals.get( sym, None ) - if not terminal: - tokencode = pytoken.tok_values.get( sym, None ) - if tokencode is None: - tokencode = self.symbols.add_symbol( sym ) - terminal = Token( tokencode ) - else: - terminal = Token( tokencode ) - self.terminals[sym] = terminal - - return self.repeat( star_opt, terminal ) - -def ebnf_handle_option( self, node ): - rule = node.nodes[1].visit(self) - return self.new_item( KleeneStar( self.new_symbol(), 0, 1, rule ) ) - -def ebnf_handle_group( self, node ): - rule = node.nodes[1].visit(self) - return self.repeat( node.nodes[3], rule ) - -def ebnf_handle_TOK_STRING( self, node ): - value = node.value - tokencode = pytoken.tok_punct.get( value, None ) - if tokencode is None: - if not py_name.match( value ): - raise RuntimeError("Unknown STRING value ('%s')" % value ) - # assume a keyword - tok = Token( pytoken.NAME, value ) - if value not in self.keywords: - self.keywords.append( value ) - else: - # punctuation - tok = Token( tokencode ) - return tok - -def ebnf_handle_sequence_alt( self, node ): - res = node.nodes[0].visit(self) - assert isinstance( res, GrammarElement ) - return res - -# This will setup a mapping between -# ebnf_handle_xxx functions and ebnfgrammar.xxx -ebnf_handles = {} -for name, value in globals().items(): - if name.startswith("ebnf_handle_"): - name = name[12:] - key = getattr(ebnfgrammar, name ) - ebnf_handles[key] = value - -def handle_unknown( self, node ): - raise RuntimeError("Unknown Visitor for %r" % node.name) - - -class EBNFVisitor(AbstractSyntaxVisitor): - - def __init__(self): - self.rules = {} - self.terminals = {} - self.current_rule = None +class EBNFBuilderContext(AbstractContext): + def __init__(self, stackpos, seqcounts, altcounts): + self.stackpos = stackpos + self.seqcounts = seqcounts + self.altcounts = altcounts + + +class EBNFBuilder(AbstractBuilder): + """Build a grammar tree""" + def __init__(self, gram_parser, dest_parser): + AbstractBuilder.__init__(self, dest_parser) + self.gram = gram_parser + self.rule_stack = [] + self.seqcounts = [] # number of items in the current sequence + self.altcounts = [] # number of sequence in the current alternative + self.curaltcount = 0 + self.curseqcount = 0 self.current_subrule = 0 + self.current_rule = -1 + self.current_rule_name = "" + self.tokens = {} self.keywords = [] - self.items = [] - self.terminals['NAME'] = NameToken() - self.symbols = pysymbol.SymbolMapper( pysymbol._cpython_symbols.sym_name ) + NAME = dest_parser.add_token('NAME') + # NAME = dest_parser.tokens['NAME'] + self.tokens[NAME] = NameToken(dest_parser, keywords=self.keywords) + + def context(self): + return EBNFBuilderContext(len(self.rule_stack), self.seqcounts, self.altcounts) + + def restore(self, ctx): + del self.rule_stack[ctx.stackpos:] + self.seqcounts = ctx.seqcounts + self.altcounts = ctx.altcounts def new_symbol(self): - rule_name = ":%s_%s" % (self.current_rule, self.current_subrule) + """Allocate and return a new (anonymous) grammar symbol whose + name is based on the current grammar rule being parsed""" + rule_name = ":" + self.current_rule_name + "_%d" % self.current_subrule self.current_subrule += 1 - symval = self.symbols.add_anon_symbol( rule_name ) - return symval + name_id = self.parser.add_anon_symbol( rule_name ) + return name_id - def new_item(self, itm): - self.items.append(itm) - return itm - - def visit_syntaxnode( self, node ): - visit_func = ebnf_handles.get( node.name, handle_unknown ) - return visit_func( self, node ) - - def visit_tokennode( self, node ): - return self.visit_syntaxnode( node ) - - def visit_tempsyntaxnode( self, node ): - return self.visit_syntaxnode( node ) - - - def repeat( self, star_opt, myrule ): - assert isinstance( myrule, GrammarElement ) - if star_opt.nodes: - rule_name = self.new_symbol() - tok = star_opt.nodes[0].nodes[0] - if tok.value == '+': - item = KleeneStar(rule_name, _min=1, rule=myrule) - return self.new_item(item) - elif tok.value == '*': - item = KleeneStar(rule_name, _min=0, rule=myrule) - return self.new_item(item) - else: - raise RuntimeError("Got symbol star_opt with value='%s'" - % tok.value) - return myrule + def new_rule(self, rule): + """A simple helper method that registers a new rule as 'known'""" + self.parser.all_rules.append(rule) + return rule + + def resolve_rules(self): + """Remove GrammarProxy objects""" + to_be_deleted = {} + for rule in self.parser.all_rules: + # for i, arg in enumerate(rule.args): + for i in range(len(rule.args)): + arg = rule.args[i] + if isinstance(arg, GrammarProxy): + real_rule = self.parser.root_rules[arg.codename] + if isinstance(real_rule, GrammarProxy): + # If we still have a GrammarProxy associated to this codename + # this means we have encountered a terminal symbol + to_be_deleted[ arg.codename ] = True + rule.args[i] = self.get_token( arg.codename ) + #print arg, "-> Token(",arg.rule_name,")" + else: + #print arg, "->", real_rule + rule.args[i] = real_rule + for codename in to_be_deleted.keys(): + del self.parser.root_rules[codename] + + def get_token(self, codename ): + """Returns a new or existing Token""" + if codename in self.tokens: + return self.tokens[codename] + token = self.tokens[codename] = self.parser.build_token(codename) + return token + + def get_symbolcode(self, name): + return self.parser.add_symbol( name ) + + def get_rule( self, name ): + if name in self.parser.tokens: + codename = self.parser.tokens[name] + return self.get_token( codename ) + codename = self.get_symbolcode( name ) + if codename in self.parser.root_rules: + return self.parser.root_rules[codename] + proxy = GrammarProxy( self.parser, name, codename ) + self.parser.root_rules[codename] = proxy + return proxy + def alternative(self, rule, source): + return True + def pop_rules( self, count ): + offset = len(self.rule_stack)-count + assert offset>=0 + rules = self.rule_stack[offset:] + del self.rule_stack[offset:] + return rules + + def sequence(self, rule, source, elts_number): + _rule = rule.codename + if _rule == self.gram.sequence: + if self.curseqcount==1: + self.curseqcount = 0 + self.curaltcount += 1 + return True + rules = self.pop_rules(self.curseqcount) + new_rule = self.parser.build_sequence( self.new_symbol(), rules ) + self.rule_stack.append( new_rule ) + self.curseqcount = 0 + self.curaltcount += 1 + elif _rule == self.gram.alternative: + if self.curaltcount == 1: + self.curaltcount = 0 + return True + rules = self.pop_rules(self.curaltcount) + new_rule = self.parser.build_alternative( self.new_symbol(), rules ) + self.rule_stack.append( new_rule ) + self.curaltcount = 0 + elif _rule == self.gram.group: + self.curseqcount += 1 + elif _rule == self.gram.option: + # pops the last alternative + rules = self.pop_rules( 1 ) + new_rule = self.parser.build_kleenestar( self.new_symbol(), _min=0, _max=1, rule=rules[0] ) + self.rule_stack.append( new_rule ) + self.curseqcount += 1 + elif _rule == self.gram.rule: + assert len(self.rule_stack)==1 + old_rule = self.rule_stack[0] + del self.rule_stack[0] + if isinstance(old_rule,Token): + # Wrap a token into an alternative + old_rule = self.parser.build_alternative( self.current_rule, [old_rule] ) + else: + # Make sure we use the codename from the named rule + old_rule.codename = self.current_rule + self.parser.root_rules[self.current_rule] = old_rule + self.current_subrule = 0 + return True + + def token(self, name, value, source): + if name == self.gram.TOK_STRING: + self.handle_TOK_STRING( name, value ) + self.curseqcount += 1 + elif name == self.gram.TOK_SYMDEF: + self.current_rule = self.get_symbolcode( value ) + self.current_rule_name = value + elif name == self.gram.TOK_SYMBOL: + rule = self.get_rule( value ) + self.rule_stack.append( rule ) + self.curseqcount += 1 + elif name == self.gram.TOK_STAR: + top = self.rule_stack[-1] + rule = self.parser.build_kleenestar( self.new_symbol(), _min=0, rule=top) + self.rule_stack[-1] = rule + elif name == self.gram.TOK_ADD: + top = self.rule_stack[-1] + rule = self.parser.build_kleenestar( self.new_symbol(), _min=1, rule=top) + self.rule_stack[-1] = rule + elif name == self.gram.TOK_BAR: + assert self.curseqcount == 0 + elif name == self.gram.TOK_LPAR: + self.altcounts.append( self.curaltcount ) + self.seqcounts.append( self.curseqcount ) + self.curseqcount = 0 + self.curaltcount = 0 + elif name == self.gram.TOK_RPAR: + assert self.curaltcount == 0 + self.curaltcount = self.altcounts.pop() + self.curseqcount = self.seqcounts.pop() + elif name == self.gram.TOK_LBRACKET: + self.altcounts.append( self.curaltcount ) + self.seqcounts.append( self.curseqcount ) + self.curseqcount = 0 + self.curaltcount = 0 + elif name == self.gram.TOK_RBRACKET: + assert self.curaltcount == 0 + assert self.curseqcount == 0 + self.curaltcount = self.altcounts.pop() + self.curseqcount = self.seqcounts.pop() + return True -def parse_grammar(stream): - """parses the grammar file - - stream : file-like object representing the grammar to parse - """ - source = GrammarSource(stream.read()) - builder = BaseGrammarBuilder() - result = GRAMMAR_GRAMMAR.match(source, builder) - node = builder.stack[-1] - vis = EBNFVisitor() - node.visit(vis) - return vis - -def parse_grammar_text(txt): - """parses a grammar input - - stream : file-like object representing the grammar to parse - """ - source = GrammarSource(txt) - builder = BaseGrammarBuilder() - result = GRAMMAR_GRAMMAR.match(source, builder) - node = builder.stack[-1] - vis = EBNFVisitor() - node.visit(vis) - return vis - -def target_parse_grammar_text(txt): - vis = parse_grammar_text(txt) - # do nothing - -from pprint import pprint -if __name__ == "__main__": - grambuild = parse_grammar(file('data/Grammar2.4')) - for i,r in enumerate(grambuild.items): - print "% 3d : %s" % (i, r) - pprint(grambuild.terminals.keys()) - pprint(grambuild.tokens) - print "|".join(grambuild.tokens.keys() ) + def handle_TOK_STRING( self, name, value ): + if value in self.parser.tok_values: + # punctuation + tokencode = self.parser.tok_values[value] + tok = self.parser.build_token( tokencode, None ) + else: + if not is_py_name(value): + raise RuntimeError("Unknown STRING value ('%s')" % value) + # assume a keyword + tok = self.parser.build_token( self.parser.tokens['NAME'], value) + if value not in self.keywords: + self.keywords.append(value) + self.rule_stack.append(tok) Modified: pypy/dist/pypy/interpreter/pyparser/grammar.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/grammar.py (original) +++ pypy/dist/pypy/interpreter/pyparser/grammar.py Wed Feb 28 18:30:48 2007 @@ -13,7 +13,8 @@ except ImportError: # allows standalone testing Wrappable = object - NULLTOKEN = None + NULLTOKEN = -1 # None + from syntaxtree import SyntaxNode, TempSyntaxNode, TokenNode @@ -28,6 +29,7 @@ else: return "["+str(codename)+"]" + #### Abstract interface for a lexer/tokenizer class TokenSource(object): """Abstract base class for a source tokenizer""" @@ -50,7 +52,7 @@ of the context""" return -1 - def current_line(self): + def current_linesource(self): """Returns the current line""" return "" @@ -71,7 +73,8 @@ def build_first_sets(rules): - """builds the real first tokens set for each rule in + """XXX : dead + builds the real first tokens set for each rule in Because a rule can be recursive (directly or indirectly), the *simplest* algorithm to build each first set is to recompute them @@ -100,17 +103,17 @@ restore states""" pass -class AbstractBuilder(object): +from pypy.interpreter.baseobjspace import Wrappable + + +class AbstractBuilder(Wrappable): """Abstract base class for builder objects""" - def __init__(self, rules=None, debug=0, symbols={} ): - # a dictionary of grammar rules for debug/reference - if rules is not None: - self.rules = rules - else: - self.rules = {} + def __init__(self, parser, debug=0 ): # This attribute is here for convenience self.debug = debug - self.symbols = symbols # mapping from codename to symbols + # the parser that represent the grammar used + assert isinstance( parser, Parser ) + self.parser = parser def context(self): """Return an opaque context object""" @@ -142,23 +145,22 @@ class BaseGrammarBuilder(AbstractBuilder): """Base/default class for a builder""" + # XXX (adim): this is trunk's keyword management keywords = None - def __init__(self, rules=None, debug=0, symbols={} ): - AbstractBuilder.__init__(self, rules, debug, symbols ) + def __init__(self, parser, debug=0 ): + AbstractBuilder.__init__(self, parser, debug ) # stacks contain different objects depending on the builder class # to be RPython they should not be defined in the base class self.stack = [] def context(self): """Returns the state of the builder to be restored later""" - #print "Save Stack:", self.stack return BaseGrammarBuilderContext(len(self.stack)) def restore(self, ctx): assert isinstance(ctx, BaseGrammarBuilderContext) del self.stack[ctx.stackpos:] - #print "Restore Stack:", self.stack - + def alternative(self, rule, source): # Do nothing, keep rule on top of the stack if rule.is_root(): @@ -208,10 +210,12 @@ """Base parser class""" symbols = {} # dirty trick to provide a symbols mapping while printing (and not putting it in every object) - - def __init__(self, codename): + + def __init__(self, parser, codename): # the rule name #assert type(codename)==int + assert isinstance(parser, Parser) + self.parser = parser self.codename = codename # integer mapping to either a token value or rule symbol value self.args = [] self.first_set = [] @@ -226,7 +230,6 @@ if self.codename >=0: return True return False - def match(self, source, builder, level=0): """Try to match a grammar rule @@ -249,17 +252,17 @@ pos1 = source.get_pos() in_first_set = self.match_first_set(builder, token) if not in_first_set: # and not EmptyToken in self.first_set: - if EmptyToken in self.first_set: + if self.parser.EmptyToken in self.first_set: ret = builder.sequence(self, source, 0 ) if self._trace: - self._debug_display(token, level, 'eee', builder.symbols) + self._debug_display(token, level, 'eee' ) return ret if self._trace: - self._debug_display(token, level, 'rrr', builder.symbols) + self._debug_display(token, level, 'rrr' ) return 0 elif self._trace: - self._debug_display(token, level, '>>>', builder.symbols) - + self._debug_display(token, level, '>>>') + res = self._match(source, builder, level) if self._trace: pos2 = source.get_pos() @@ -267,21 +270,20 @@ prefix = '+++' else: prefix = '---' - self._debug_display(token, level, prefix, builder.symbols) + self._debug_display(token, level, prefix) print ' '*level, prefix, " TEXT ='%s'" % ( source.get_source_text(pos1,pos2)) if res: print "*" * 50 return res - def _debug_display(self, token, level, prefix, symbols): + def _debug_display(self, token, level, prefix): """prints context debug informations""" prefix = '%s%s' % (' ' * level, prefix) print prefix, " RULE =", self print prefix, " TOKEN =", token print prefix, " FIRST SET =", self.first_set - - + def _match(self, source, builder, level=0): """Try to match a grammar rule @@ -295,7 +297,7 @@ returns None if no match or an object build by builder """ return 0 - + def parse(self, source): """Returns a simplified grammar if the rule matched at the source current context or None""" @@ -304,27 +306,35 @@ pass def __str__(self): - return self.display(0, GrammarElement.symbols ) + try: + return self.display(0) + except Exception, e: + import traceback + traceback.print_exc() def __repr__(self): - return self.display(0, GrammarElement.symbols ) + try: + return self.display(0) + except Exception, e: + import traceback + traceback.print_exc() - def display(self, level=0, symbols={}): + def display(self, level=0): """Helper function used to represent the grammar. mostly used for debugging the grammar itself""" return "GrammarElement" - def debug_return(self, ret, symbols, arg="" ): + def debug_return(self, ret, arg="" ): # FIXME: use a wrapper of match() methods instead of debug_return() # to prevent additional indirection even better a derived # Debugging builder class if ret and DEBUG > 0: print "matched %s (%s): %s" % (self.__class__.__name__, - arg, self.display(0, symbols=symbols) ) + arg, self.display(0) ) return ret - + def calc_first_set(self): """returns the list of possible next tokens *must* be implemented in subclasses @@ -337,7 +347,7 @@ token('NAME','x') matches token('NAME',None) """ for tk in self.first_set: - if tk.match_token( builder, other ): + if tk.match_token(builder, other): return True return False @@ -355,12 +365,28 @@ pass +class GrammarProxy(GrammarElement): + def __init__(self, parser, rule_name, codename=-1 ): + GrammarElement.__init__(self, parser, codename ) + self.rule_name = rule_name + self.object = None + + def display(self, level=0): + """Helper function used to represent the grammar. + mostly used for debugging the grammar itself""" + name = self.parser.symbol_repr(self.codename) + repr = "Proxy("+name + if self.object: + repr+=","+self.object.display(1) + repr += ")" + return repr + class Alternative(GrammarElement): """Represents an alternative in a grammar rule (as in S -> A | B | C)""" - def __init__(self, name, args): - GrammarElement.__init__(self, name ) + def __init__(self, parser, name, args): + GrammarElement.__init__(self, parser, name ) self.args = args self._reordered = False for i in self.args: @@ -371,14 +397,14 @@ returns the object built from the first rules that matches """ if DEBUG > 1: - print "try alt:", self.display(level, builder.symbols ) + print "try alt:", self.display(level) tok = source.peek() # Here we stop at the first match we should # try instead to get the longest alternative # to see if this solve our problems with infinite recursion for rule in self.args: if USE_LOOKAHEAD: - if not rule.match_first_set(builder, tok) and EmptyToken not in rule.first_set: + if not rule.match_first_set(builder, tok) and self.parser.EmptyToken not in rule.first_set: if self._trace: print "Skipping impossible rule: %s" % (rule,) continue @@ -388,15 +414,15 @@ return ret return 0 - def display(self, level=0, symbols={}): - name = get_symbol( self.codename, symbols ) + def display(self, level=0): + name = self.parser.symbol_repr( self.codename ) if level == 0: name = name + " -> " elif self.is_root(): return name else: name = "" - items = [ a.display(1,symbols) for a in self.args ] + items = [ a.display(1) for a in self.args ] return name+"(" + "|".join( items ) + ")" def calc_first_set(self): @@ -420,7 +446,7 @@ # is only needed for warning / debugging purposes tokens_set = [] for rule in self.args: - if EmptyToken in rule.first_set: + if self.parser.EmptyToken in rule.first_set: empty_set.append(rule) else: not_empty_set.append(rule) @@ -429,7 +455,7 @@ # It will check if a token is part of several first sets of # a same alternative for token in rule.first_set: - if token is not EmptyToken and token in tokens_set: + if token is not self.parser.EmptyToken and token in tokens_set: print "Warning, token %s in\n\t%s's first set is " \ " part of a previous rule's first set in " \ " alternative\n\t%s" % (token, rule, self) @@ -438,7 +464,11 @@ print "Warning: alternative %s has more than one rule " \ "matching Empty" % self self._reordered = True - self.args[:] = not_empty_set + # self.args[:] = not_empty_set + for elt in self.args[:]: + self.args.remove(elt) + for elt in not_empty_set: + self.args.append(elt) self.args.extend( empty_set ) def validate( self, syntax_node ): @@ -457,16 +487,17 @@ class Sequence(GrammarElement): """Reprensents a Sequence in a grammar rule (as in S -> A B C)""" - def __init__(self, name, args): - GrammarElement.__init__(self, name ) + def __init__(self, parser, name, args): + GrammarElement.__init__(self, parser, name ) self.args = args for i in self.args: assert isinstance( i, GrammarElement ) + def _match(self, source, builder, level=0): """matches all of the symbols in order""" if DEBUG > 1: - print "try seq:", self.display(0, builder.symbols ) + print "try seq:", self.display(0) ctx = source.context() bctx = builder.context() for rule in self.args: @@ -480,15 +511,15 @@ ret = builder.sequence(self, source, len(self.args)) return ret - def display(self, level=0, symbols={}): - name = get_symbol( self.codename, symbols ) + def display(self, level=0): + name = self.parser.symbol_repr( self.codename ) if level == 0: name = name + " -> " elif self.is_root(): return name else: name = "" - items = [a.display(1,symbols) for a in self.args] + items = [a.display(1) for a in self.args] return name + "(" + " ".join( items ) + ")" def calc_first_set(self): @@ -503,18 +534,18 @@ for rule in self.args: if not rule.first_set: break - if EmptyToken in self.first_set: - self.first_set.remove( EmptyToken ) + if self.parser.EmptyToken in self.first_set: + self.first_set.remove( self.parser.EmptyToken ) - # del self.first_set[EmptyToken] + # del self.first_set[self.parser.EmptyToken] # while we're in this loop, keep agregating possible tokens for t in rule.first_set: if t not in self.first_set: self.first_set.append(t) # self.first_set[t] = 1 - if EmptyToken not in rule.first_set: + if self.parser.EmptyToken not in rule.first_set: break - + def validate( self, syntax_node ): """validate a syntax tree/subtree from this grammar node""" if self.codename != syntax_node.name: @@ -530,13 +561,10 @@ - - - class KleeneStar(GrammarElement): """Represents a KleeneStar in a grammar rule as in (S -> A+) or (S -> A*)""" - def __init__(self, name, _min = 0, _max = -1, rule=None): - GrammarElement.__init__( self, name ) + def __init__(self, parser, name, _min = 0, _max = -1, rule=None): + GrammarElement.__init__( self, parser, name ) self.args = [rule] self.min = _min if _max == 0: @@ -544,8 +572,8 @@ self.max = _max self.star = "x" if self.min == 0: - self.first_set.append( EmptyToken ) - # self.first_set[EmptyToken] = 1 + self.first_set.append( self.parser.EmptyToken ) + # self.first_set[self.parser.EmptyToken] = 1 def _match(self, source, builder, level=0): """matches a number of times self.args[0]. the number must be @@ -553,8 +581,8 @@ represent infinity """ if DEBUG > 1: - print "try kle:", self.display(0,builder.symbols) - ctx = 0 + print "try kle:", self.display(0) + ctx = None bctx = None if self.min: ctx = source.context() @@ -576,14 +604,19 @@ ret = builder.sequence(self, source, rules) return ret - def display(self, level=0, symbols={}): - name = get_symbol( self.codename, symbols ) + def display(self, level=0): + name = self.parser.symbol_repr( self.codename ) if level==0: name = name + " -> " elif self.is_root(): return name else: name = "" + star = self.get_star() + s = self.args[0].display(1) + return name + "%s%s" % (s, star) + + def get_star(self): star = "{%d,%d}" % (self.min,self.max) if self.min==0 and self.max==1: star = "?" @@ -591,23 +624,21 @@ star = "*" elif self.min==1 and self.max==-1: star = "+" - s = self.args[0].display(1, symbols) - return name + "%s%s" % (s, star) - + return star def calc_first_set(self): """returns the list of possible next tokens if S -> A*: - LAH(S) = Union( LAH(A), EmptyToken ) + LAH(S) = Union( LAH(A), self.parser.EmptyToken ) if S -> A+: LAH(S) = LAH(A) """ rule = self.args[0] self.first_set = rule.first_set[:] # self.first_set = dict(rule.first_set) - if self.min == 0 and EmptyToken not in self.first_set: - self.first_set.append(EmptyToken) - # self.first_set[EmptyToken] = 1 + if self.min == 0 and self.parser.EmptyToken not in self.first_set: + self.first_set.append(self.parser.EmptyToken) + # self.first_set[self.parser.EmptyToken] = 1 def validate( self, syntax_node ): """validate a syntax tree/subtree from this grammar node""" @@ -626,8 +657,8 @@ class Token(GrammarElement): """Represents a Token in a grammar rule (a lexer token)""" - def __init__( self, codename, value = None): - GrammarElement.__init__( self, codename ) + def __init__(self, parser, codename, value=None): + GrammarElement.__init__(self, parser, codename) self.value = value self.first_set = [self] # self.first_set = {self: 1} @@ -643,9 +674,10 @@ else: # error unknown or negative integer """ - if (self.value is not None and builder.keywords is not None - and self.value not in builder.keywords): - return 0 + # XXX (adim): this is trunk's keyword management + # if (self.value is not None and builder.keywords is not None + # and self.value not in builder.keywords): + # return 0 ctx = source.context() tk = source.next() @@ -661,13 +693,12 @@ source.restore( ctx ) return 0 - def display(self, level=0, symbols={}): - name = get_symbol( self.codename, symbols ) + def display(self, level=0): + name = self.parser.symbol_repr( self.codename ) if self.value is None: return "<%s>" % name else: return "<%s>=='%s'" % (name, self.value) - def match_token(self, builder, other): """convenience '==' implementation, this is *not* a *real* equality test @@ -678,16 +709,17 @@ the comparison algorithm is similar to the one in match() """ if not isinstance(other, Token): - raise RuntimeError("Unexpected token type %r" % other) - if other is EmptyToken: - return False - if (self.value is not None and builder.keywords is not None - and self.value not in builder.keywords): + raise RuntimeError("Unexpected token type") + if other is self.parser.EmptyToken: return False - res = other.codename == self.codename and self.value in [None, other.value] + # XXX (adim): this is trunk's keyword management + # if (self.value is not None and builder.keywords is not None + # and self.value not in builder.keywords): + # return False + res = other.codename == self.codename and self.value in [None, other.value] #print "matching", self, other, res return res - + def __eq__(self, other): return self.codename == other.codename and self.value == other.value @@ -707,8 +739,154 @@ return False -EmptyToken = Token(NULLTOKEN, None) - - +class Parser(object): + def __init__(self): + pass + _anoncount = self._anoncount = -10 + _count = self._count = 0 + self.sym_name = {} # mapping symbol code -> symbol name + self.symbols = {} # mapping symbol name -> symbol code + self.tokens = { 'NULLTOKEN' : -1 } + self.EmptyToken = Token( self, -1, None ) + self.tok_name = {} + self.tok_values = {} + self.tok_rvalues = {} + self._ann_sym_count = -10 + self._sym_count = 0 + self.all_rules = [] + self.root_rules = {} + + def symbol_repr( self, codename ): + if codename in self.tok_name: + return self.tok_name[codename] + elif codename in self.sym_name: + return self.sym_name[codename] + return "%d" % codename + + def add_symbol( self, sym ): + # assert isinstance( sym, str ) + if not sym in self.symbols: + val = self._sym_count + self._sym_count += 1 + self.symbols[sym] = val + self.sym_name[val] = sym + return val + return self.symbols[ sym ] + + def add_anon_symbol( self, sym ): + # assert isinstance( sym, str ) + if not sym in self.symbols: + val = self._ann_sym_count + self._ann_sym_count -= 1 + self.symbols[sym] = val + self.sym_name[val] = sym + return val + return self.symbols[ sym ] + + def add_token( self, tok, value = None ): + # assert isinstance( tok, str ) + if not tok in self.tokens: + val = self._sym_count + self._sym_count += 1 + self.tokens[tok] = val + self.tok_name[val] = tok + if value is not None: + self.tok_values[value] = val + # XXX : this reverse mapping seemed only to be used + # because of pycodegen visitAugAssign + self.tok_rvalues[val] = value + return val + return self.tokens[ tok ] + + def load_symbols( self, symbols ): + for _value, _name in symbols.items(): + if _value < self._ann_sym_count: + self._ann_sym_count = _value - 1 + if _value > self._sym_count: + self._sym_count = _value + 1 + self.symbols[_name] = _value + self.sym_name[_value] = _name + + def build_first_sets(self): + """builds the real first tokens set for each rule in + + Because a rule can be recursive (directly or indirectly), the + *simplest* algorithm to build each first set is to recompute them + until Computation(N) = Computation(N-1), N being the number of rounds. + As an example, on Python2.3's grammar, we need 19 cycles to compute + full first sets. + """ + rules = self.all_rules + changed = True + while changed: + # loop while one first set is changed + changed = False + for rule in rules: + # For each rule, recompute first set + size = len(rule.first_set) + rule.calc_first_set() + new_size = len(rule.first_set) + if new_size != size: + changed = True + for r in rules: + assert len(r.first_set) > 0, "Error: ot Empty firstset for %s" % r + r.reorder_rule() + + + def build_alternative( self, name_id, args ): + # assert isinstance( name_id, int ) + assert isinstance(args, list) + alt = Alternative( self, name_id, args ) + self.all_rules.append( alt ) + return alt + + def Alternative_n(self, name, args ): + # assert isinstance(name, str) + name_id = self.add_symbol( name ) + return self.build_alternative( name_id, args ) + + def build_sequence( self, name_id, args ): + # assert isinstance( name_id, int ) + alt = Sequence( self, name_id, args ) + self.all_rules.append( alt ) + return alt + + def Sequence_n(self, name, args ): + # assert isinstance(name, str) + name_id = self.add_symbol( name ) + return self.build_sequence( name_id, args ) + + def build_kleenestar( self, name_id, _min = 0, _max = -1, rule = None ): + # assert isinstance( name_id, int ) + alt = KleeneStar( self, name_id, _min, _max, rule ) + self.all_rules.append( alt ) + return alt + def KleeneStar_n(self, name, _min = 0, _max = -1, rule = None ): + # assert isinstance(name, str) + name_id = self.add_symbol( name ) + return self.build_kleenestar( name_id, _min, _max, rule ) + + def Token_n(self, name, value = None ): + # assert isinstance( name, str) + # assert value is None or isinstance( value, str) + name_id = self.add_token( name, value ) + return self.build_token( name_id, value ) + + def build_token(self, name_id, value = None ): + # assert isinstance( name_id, int ) + # assert value is None or isinstance( value, str) + tok = Token( self, name_id, value ) + return tok + + + # Debugging functions + def show_rules(self, name): + import re + rex = re.compile(name) + rules =[] + for _name, _val in self.symbols.items(): + if rex.search(_name) and _val>=0: + rules.append(self.root_rules[_val]) + return rules Modified: pypy/dist/pypy/interpreter/pyparser/pysymbol.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/pysymbol.py (original) +++ pypy/dist/pypy/interpreter/pyparser/pysymbol.py Wed Feb 28 18:30:48 2007 @@ -5,6 +5,7 @@ # important here class SymbolMapper(object): + """XXX dead""" def __init__(self, sym_name=None ): _anoncount = self._anoncount = -10 _count = self._count = 0 @@ -22,7 +23,7 @@ self._count = _count def add_symbol( self, sym ): - assert type(sym)==str + # assert isinstance(sym, str) if not sym in self.sym_values: self._count += 1 val = self._count @@ -32,7 +33,7 @@ return self.sym_values[ sym ] def add_anon_symbol( self, sym ): - assert type(sym)==str + # assert isinstance(sym, str) if not sym in self.sym_values: self._anoncount -= 1 val = self._anoncount @@ -43,7 +44,7 @@ def __getitem__(self, sym ): """NOT RPYTHON""" - assert type(sym)==str + # assert isinstance(sym, str) return self.sym_values[ sym ] def __contains__(self, sym): @@ -57,6 +58,12 @@ # once loaded the grammar parser will fill the mappings with the # grammar symbols +# XXX: is this completly dead ? +## # prepopulate symbol table from symbols used by CPython +## for _value, _name in _cpython_symbols.sym_name.items(): +## globals()[_name] = _value + + def gen_symbol_file(fname): """ Generate a compatible symbol file for symbol.py, using the grammar that has Modified: pypy/dist/pypy/interpreter/pyparser/pythonlexer.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/pythonlexer.py (original) +++ pypy/dist/pypy/interpreter/pyparser/pythonlexer.py Wed Feb 28 18:30:48 2007 @@ -5,10 +5,10 @@ import sys from codeop import PyCF_DONT_IMPLY_DEDENT -from pypy.interpreter.pyparser.grammar import TokenSource, Token +from pypy.interpreter.pyparser.grammar import TokenSource, Token, AbstractContext, Parser from pypy.interpreter.pyparser.error import SyntaxError + import pytoken -from pytoken import NEWLINE # Don't import string for that ... NAMECHARS = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_' @@ -51,7 +51,7 @@ ################################################################################ from pypy.interpreter.pyparser import pytoken from pytokenize import tabsize, whiteSpaceDFA, triple_quoted, endDFAs, \ - single_quoted, pseudoDFA + single_quoted, pseudoDFA import automata @@ -62,7 +62,7 @@ SyntaxError.__init__(self, msg, lineno, offset, line) self.token_stack = token_stack -def generate_tokens(lines, flags): +def generate_tokens( parser, lines, flags): """ This is a rewrite of pypy.module.parser.pytokenize.generate_tokens since the original function is not RPYTHON (uses yield) @@ -91,6 +91,7 @@ #for line in lines: # print repr(line) #print '------------------- flags=%s ---->' % flags + assert isinstance( parser, Parser ) token_list = [] lnum = parenlev = continued = 0 namechars = NAMECHARS @@ -120,7 +121,7 @@ endmatch = endDFA.recognize(line) if endmatch >= 0: pos = end = endmatch - tok = Token(pytoken.STRING, contstr + line[:end]) + tok = parser.build_token(parser.tokens['STRING'], contstr + line[:end]) token_list.append((tok, line, lnum, pos)) last_comment = '' # token_list.append((STRING, contstr + line[:end], @@ -129,7 +130,7 @@ contline = None elif (needcont and not line.endswith('\\\n') and not line.endswith('\\\r\n')): - tok = Token(pytoken.ERRORTOKEN, contstr + line) + tok = parser.build_token(parser.tokens['ERRORTOKEN'], contstr + line) token_list.append((tok, line, lnum, pos)) last_comment = '' # token_list.append((ERRORTOKEN, contstr + line, @@ -155,10 +156,10 @@ if line[pos] in '#\r\n': # skip comments or blank lines if line[pos] == '#': - tok = Token(pytoken.COMMENT, line[pos:]) + tok = parser.build_token(parser.tokens['COMMENT'], line[pos:]) last_comment = line[pos:] else: - tok = Token(pytoken.NL, line[pos:]) + tok = parser.build_token(parser.tokens['NL'], line[pos:]) last_comment = '' # XXX Skip NL and COMMENT Tokens # token_list.append((tok, line, lnum, pos)) @@ -166,12 +167,12 @@ if column > indents[-1]: # count indents or dedents indents.append(column) - tok = Token(pytoken.INDENT, line[:pos]) + tok = parser.build_token(parser.tokens['INDENT'], line[:pos]) token_list.append((tok, line, lnum, pos)) last_comment = '' while column < indents[-1]: indents = indents[:-1] - tok = Token(pytoken.DEDENT, '') + tok = parser.build_token(parser.tokens['DEDENT'], '') token_list.append((tok, line, lnum, pos)) last_comment = '' else: # continued statement @@ -198,22 +199,22 @@ token, initial = line[start:end], line[start] if initial in numchars or \ (initial == '.' and token != '.'): # ordinary number - tok = Token(pytoken.NUMBER, token) + tok = parser.build_token(parser.tokens['NUMBER'], token) token_list.append((tok, line, lnum, pos)) last_comment = '' elif initial in '\r\n': if parenlev > 0: - tok = Token(pytoken.NL, token) + tok = parser.build_token(parser.tokens['NL'], token) last_comment = '' # XXX Skip NL else: - tok = Token(pytoken.NEWLINE, token) + tok = parser.build_token(parser.tokens['NEWLINE'], token) # XXX YUCK ! tok.value = last_comment token_list.append((tok, line, lnum, pos)) last_comment = '' elif initial == '#': - tok = Token(pytoken.COMMENT, token) + tok = parser.build_token(parser.tokens['COMMENT'], token) last_comment = token # XXX Skip # token_list.append((tok, line, lnum, pos)) # token_list.append((COMMENT, token, spos, epos, line)) @@ -223,7 +224,7 @@ if endmatch >= 0: # all on one line pos = endmatch token = line[start:pos] - tok = Token(pytoken.STRING, token) + tok = parser.build_token(parser.tokens['STRING'], token) token_list.append((tok, line, lnum, pos)) last_comment = '' else: @@ -240,11 +241,11 @@ contline = line break else: # ordinary string - tok = Token(pytoken.STRING, token) + tok = parser.build_token(parser.tokens['STRING'], token) token_list.append((tok, line, lnum, pos)) last_comment = '' elif initial in namechars: # ordinary name - tok = Token(pytoken.NAME, token) + tok = parser.build_token(parser.tokens['NAME'], token) token_list.append((tok, line, lnum, pos)) last_comment = '' elif initial == '\\': # continued stmt @@ -258,10 +259,11 @@ if parenlev < 0: raise TokenError("unmatched '%s'" % initial, line, (lnum-1, 0), token_list) - if token in pytoken.tok_punct: - tok = Token(pytoken.tok_punct[token]) + if token in parser.tok_values: + punct = parser.tok_values[token] + tok = parser.build_token(punct) else: - tok = Token(pytoken.OP, token) + tok = parser.build_token(parser.tokens['OP'], token) token_list.append((tok, line, lnum, pos)) last_comment = '' else: @@ -271,33 +273,39 @@ if start and inserts corresponding rules in the parser""" + # parse the ruledef(s) + source = GrammarSource(GRAMMAR_GRAMMAR, ruledef) + builder = ebnfparse.EBNFBuilder(GRAMMAR_GRAMMAR, dest_parser=self) + GRAMMAR_GRAMMAR.root_rules['grammar'].match(source, builder) + # remove proxy objects if any + builder.resolve_rules() + # update keywords + self.keywords.extend(builder.keywords) + # update old references in case an existing rule was modified + self.update_rules_references() + # recompute first sets + self.build_first_sets() + +def make_pyparser(version="2.4"): + parser = PythonParser() + return build_parser_for_version(version, parser=parser) + +PYTHON_PARSER = make_pyparser() + +def translation_target(grammardef): + parser = PythonParser() # predefined_symbols=symbol.sym_name) + source = GrammarSource(GRAMMAR_GRAMMAR, grammardef) + builder = ebnfparse.EBNFBuilder(GRAMMAR_GRAMMAR, dest_parser=parser) + GRAMMAR_GRAMMAR.root_rules['grammar'].match(source, builder) + builder.resolve_rules() + parser.build_first_sets() + parser.keywords = builder.keywords + return 0 + + +## XXX BROKEN +## def parse_grammar(space, w_src): +## """Loads the grammar using the 'dynamic' rpython parser""" +## src = space.str_w( w_src ) +## ebnfbuilder = ebnfparse.parse_grammar_text( src ) +## ebnfbuilder.resolve_rules() +## grammar.build_first_sets(ebnfbuilder.all_rules) +## return space.wrap( ebnfbuilder.root_rules ) def grammar_rules( space ): w_rules = space.newdict() - for key, value in PYTHON_PARSER.rules.iteritems(): + parser = make_pyparser() + for key, value in parser.rules.iteritems(): space.setitem(w_rules, space.wrap(key), space.wrap(value)) return w_rules - - -def make_rule( space, w_rule ): - rule = space.str_w( w_rule ) - Modified: pypy/dist/pypy/interpreter/pyparser/pythonutil.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/pythonutil.py (original) +++ pypy/dist/pypy/interpreter/pyparser/pythonutil.py Wed Feb 28 18:30:48 2007 @@ -1,17 +1,109 @@ -__all__ = ["python_parse", "pypy_parse"] +"""miscelanneous utility functions +XXX: svn mv pythonutil.py gramtools.py / parsertools.py +""" + +import sys +import os import parser -import pythonparse -from tuplebuilder import TupleBuilder -from astbuilder import AstBuilder - -PYTHON_PARSER = pythonparse.PYTHON_PARSER -TARGET_DICT = { - 'exec' : "file_input", - 'eval' : "eval_input", - 'single' : "single_input", - } +from pypy.interpreter.pyparser.grammar import Parser +from pypy.interpreter.pyparser.pytoken import setup_tokens +from pypy.interpreter.pyparser.ebnfgrammar import GRAMMAR_GRAMMAR +from pypy.interpreter.pyparser.ebnflexer import GrammarSource +from pypy.interpreter.pyparser.ebnfparse import EBNFBuilder + +from pypy.interpreter.pyparser.tuplebuilder import TupleBuilder + +PYTHON_VERSION = ".".join([str(i) for i in sys.version_info[:2]]) + +def dirname(filename): + """redefine dirname to avoid the need of os.path.split being rpython + """ + i = filename.rfind(os.sep) + 1 + assert i >= 0 + return filename[:i] + + +def get_grammar_file(version): + """returns the python grammar corresponding to our CPython version""" + if version == "native": + _ver = PYTHON_VERSION + elif version == "stable": + _ver = "_stablecompiler" + elif version in ("2.3","2.4","2.5a"): + _ver = version + else: + raise ValueError('no such grammar version: %s' % version) + # two osp.join to avoid TyperError: can only iterate over tuples of length 1 for now + # generated by call to osp.join(a, *args) + return os.path.join( dirname(__file__), + os.path.join("data", "Grammar" + _ver) ), _ver + + +def build_parser(gramfile, parser=None): + """reads a (EBNF) grammar definition and builds a parser for it""" + if parser is None: + parser = Parser() + setup_tokens(parser) + # XXX: clean up object dependencies + from pypy.rlib.streamio import open_file_as_stream + stream = open_file_as_stream(gramfile) + grammardef = stream.readall() + stream.close() + assert isinstance(grammardef, str) + source = GrammarSource(GRAMMAR_GRAMMAR, grammardef) + builder = EBNFBuilder(GRAMMAR_GRAMMAR, dest_parser=parser) + GRAMMAR_GRAMMAR.root_rules['grammar'].match(source, builder) + builder.resolve_rules() + parser.build_first_sets() + parser.keywords = builder.keywords + return parser + + +def build_parser_for_version(version, parser=None): + gramfile, _ = get_grammar_file(version) + return build_parser(gramfile, parser) + + +## XXX: the below code should probably go elsewhere + +## convenience functions for computing AST objects using recparser +def ast_from_input(input, mode, transformer, parser): + """converts a source input into an AST + + - input : the source to be converted + - mode : 'exec', 'eval' or 'single' + - transformer : the transfomer instance to use to convert + the nested tuples into the AST + XXX: transformer could be instantiated here but we don't want + here to explicitly import compiler or stablecompiler or + etc. This is to be fixed in a clean way + """ + builder = TupleBuilder(parser, lineno=True) + parser.parse_source(input, mode, builder) + tuples = builder.stack[-1].as_tuple(True) + return transformer.compile_node(tuples) + + +def pypy_parse(source, mode='exec', lineno=False): + from pypy.interpreter.pyparser.pythonparse import PythonParser, make_pyparser + from pypy.interpreter.pyparser.astbuilder import AstBuilder + # parser = build_parser_for_version("2.4", PythonParser()) + parser = make_pyparser('stable') + builder = TupleBuilder(parser) + parser.parse_source(source, mode, builder) + return builder.stack[-1].as_tuple(lineno) + + +def source2ast(source, mode='exec', version='2.4', space=None): + from pypy.interpreter.pyparser.pythonparse import PythonParser, make_pyparser + from pypy.interpreter.pyparser.astbuilder import AstBuilder + parser = make_pyparser(version) + builder = AstBuilder(parser, space=space) + parser.parse_source(source, mode, builder) + return builder.rule_stack[-1] + ## convenience functions around CPython's parser functions def python_parsefile(filename, lineno=False): @@ -32,7 +124,6 @@ tp = parser.suite(source) return parser.ast2tuple(tp, line_info=lineno) -## convenience functions around recparser functions def pypy_parsefile(filename, lineno=False): """parse using PyPy's parser module and return a tuple of three elements : @@ -48,105 +139,3 @@ source = pyf.read() pyf.close() return pypy_parse(source, 'exec', lineno) - -def internal_pypy_parse(source, mode='exec', lineno=False, flags=0, space=None, - parser = PYTHON_PARSER): - """This function has no other role than testing the parser's annotation - - annotateme() is basically the same code that pypy_parse(), but with the - following differences : - - - returns a tuplebuilder.StackElement instead of the *real* nested - tuples (StackElement is only a wrapper class around these tuples) - - """ - builder = TupleBuilder(parser.rules, lineno=False) - if space is not None: - builder.space = space - target_rule = TARGET_DICT[mode] - parser.parse_source(source, target_rule, builder, flags) - stack_element = builder.stack[-1] - return (builder.source_encoding, stack_element) - -def parse_result_to_nested_tuples(parse_result, lineno=False): - """NOT_RPYTHON""" - source_encoding, stack_element = parse_result - nested_tuples = stack_element.as_tuple(lineno) - return nested_tuples - -def pypy_parse(source, mode='exec', lineno=False, flags=0, parser = PYTHON_PARSER): - """ - NOT_RPYTHON ! - parse using PyPy's parser module and return - a tuple of three elements : - - The encoding declaration symbol or None if there were no encoding - statement - - The TupleBuilder's stack top element (instance of - tuplebuilder.StackElement which is a wrapper of some nested tuples - like those returned by the CPython's parser) - - The encoding string or None if there were no encoding statement - nested tuples - """ - source_encoding, stack_element = internal_pypy_parse(source, mode, lineno=lineno, - flags=lineno, parser = parser) - # convert the stack element into nested tuples (caution, the annotator - # can't follow this call) - return parse_result_to_nested_tuples((source_encoding, stack_element), lineno=lineno) - -## convenience functions for computing AST objects using recparser -def ast_from_input(input, mode, transformer, parser = PYTHON_PARSER): - """converts a source input into an AST - - - input : the source to be converted - - mode : 'exec', 'eval' or 'single' - - transformer : the transfomer instance to use to convert - the nested tuples into the AST - XXX: transformer could be instantiated here but we don't want - here to explicitly import compiler or stablecompiler or - etc. This is to be fixed in a clean way - """ - tuples = pypy_parse(input, mode, True, parser) - ast = transformer.compile_node(tuples) - return ast - -def target_ast_compile(space, input, mode): - from pypy.interpreter.astcompiler import ast, misc, pycodegen - builder = AstBuilder(rules=None, debug=0, space=space) - target = TARGET_DICT[mode] - PYTHON_PARSER.parse_source(input, target, builder) - ast_tree = builder.rule_stack[-1] - misc.set_filename("", ast_tree) - if mode=="single": - codegenerator = pycodegen.InteractiveCodeGenerator(space,ast_tree) - elif mode=="eval": - codegenerator = pycodegen.ExpressionCodeGenerator(space,ast_tree) - elif mode=="exec": - codegenerator = pycodegen.ModuleCodeGenerator(space,ast_tree) - else: - raise ValueError("incorrect mode") - code1 = codegenerator.getCode() - return code1 - - -def internal_pypy_parse_to_ast(source, mode='exec', lineno=False, flags=0): - builder = AstBuilder() - target_rule = TARGET_DICT[mode] - PYTHON_PARSER.parse_source(source, target_rule, builder, flags) - ast_tree = builder.rule_stack[-1] - return (builder.source_encoding, ast_tree) - - -if __name__ == "__main__": - import sys - if len(sys.argv) < 2: - print "python parse.py [-d N] test_file.py" - sys.exit(1) - if sys.argv[1] == "-d": - debug_level = int(sys.argv[2]) - test_file = sys.argv[3] - else: - test_file = sys.argv[1] - print "-"*20 - print - print "pyparse \n", pypy_parsefile(test_file) - print "parser \n", python_parsefile(test_file) Modified: pypy/dist/pypy/interpreter/pyparser/pytoken.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/pytoken.py (original) +++ pypy/dist/pypy/interpreter/pyparser/pytoken.py Wed Feb 28 18:30:48 2007 @@ -5,131 +5,77 @@ N_TOKENS = 0 -tok_name = {} -tok_values = {} +# This is used to replace None +NULLTOKEN = -1 -def add_token(name, value=None): - global N_TOKENS - if value is None: - value = N_TOKENS - N_TOKENS += 1 - _g = globals() - _g[name] = value - tok_name[value] = name - tok_values[name] = value +tok_name = {-1 : 'NULLTOKEN'} +tok_values = {'NULLTOKEN' : -1} -# This is used to replace None -add_token( 'NULLTOKEN', -1 ) +# tok_rpunct = {} +def setup_tokens( parser ): + # global tok_rpunct # For compatibility, this produces the same constant values as Python 2.4. -add_token( 'ENDMARKER' ) -add_token( 'NAME' ) -add_token( 'NUMBER' ) -add_token( 'STRING' ) -add_token( 'NEWLINE' ) -add_token( 'INDENT' ) -add_token( 'DEDENT' ) -add_token( 'LPAR' ) -add_token( 'RPAR' ) -add_token( 'LSQB' ) -add_token( 'RSQB' ) -add_token( 'COLON' ) -add_token( 'COMMA' ) -add_token( 'SEMI' ) -add_token( 'PLUS' ) -add_token( 'MINUS' ) -add_token( 'STAR' ) -add_token( 'SLASH' ) -add_token( 'VBAR' ) -add_token( 'AMPER' ) -add_token( 'LESS' ) -add_token( 'GREATER' ) -add_token( 'EQUAL' ) -add_token( 'DOT' ) -add_token( 'PERCENT' ) -add_token( 'BACKQUOTE' ) -add_token( 'LBRACE' ) -add_token( 'RBRACE' ) -add_token( 'EQEQUAL' ) -add_token( 'NOTEQUAL' ) -add_token( 'LESSEQUAL' ) -add_token( 'GREATEREQUAL' ) -add_token( 'TILDE' ) -add_token( 'CIRCUMFLEX' ) -add_token( 'LEFTSHIFT' ) -add_token( 'RIGHTSHIFT' ) -add_token( 'DOUBLESTAR' ) -add_token( 'PLUSEQUAL' ) -add_token( 'MINEQUAL' ) -add_token( 'STAREQUAL' ) -add_token( 'SLASHEQUAL' ) -add_token( 'PERCENTEQUAL' ) -add_token( 'AMPEREQUAL' ) -add_token( 'VBAREQUAL' ) -add_token( 'CIRCUMFLEXEQUAL' ) -add_token( 'LEFTSHIFTEQUAL' ) -add_token( 'RIGHTSHIFTEQUAL' ) -add_token( 'DOUBLESTAREQUAL' ) -add_token( 'DOUBLESLASH' ) -add_token( 'DOUBLESLASHEQUAL' ) -add_token( 'AT' ) -add_token( 'OP' ) -add_token( 'ERRORTOKEN' ) + parser.add_token( 'ENDMARKER' ) + parser.add_token( 'NAME' ) + parser.add_token( 'NUMBER' ) + parser.add_token( 'STRING' ) + parser.add_token( 'NEWLINE' ) + parser.add_token( 'INDENT' ) + parser.add_token( 'DEDENT' ) + parser.add_token( 'LPAR', "(" ) + parser.add_token( 'RPAR', ")" ) + parser.add_token( 'LSQB', "[" ) + parser.add_token( 'RSQB', "]" ) + parser.add_token( 'COLON', ":" ) + parser.add_token( 'COMMA', "," ) + parser.add_token( 'SEMI', ";" ) + parser.add_token( 'PLUS', "+" ) + parser.add_token( 'MINUS', "-" ) + parser.add_token( 'STAR', "*" ) + parser.add_token( 'SLASH', "/" ) + parser.add_token( 'VBAR', "|" ) + parser.add_token( 'AMPER', "&" ) + parser.add_token( 'LESS', "<" ) + parser.add_token( 'GREATER', ">" ) + parser.add_token( 'EQUAL', "=" ) + parser.add_token( 'DOT', "." ) + parser.add_token( 'PERCENT', "%" ) + parser.add_token( 'BACKQUOTE', "`" ) + parser.add_token( 'LBRACE', "{" ) + parser.add_token( 'RBRACE', "}" ) + parser.add_token( 'EQEQUAL', "==" ) + ne = parser.add_token( 'NOTEQUAL', "!=" ) + parser.tok_values["<>"] = ne + parser.add_token( 'LESSEQUAL', "<=" ) + parser.add_token( 'GREATEREQUAL', ">=" ) + parser.add_token( 'TILDE', "~" ) + parser.add_token( 'CIRCUMFLEX', "^" ) + parser.add_token( 'LEFTSHIFT', "<<" ) + parser.add_token( 'RIGHTSHIFT', ">>" ) + parser.add_token( 'DOUBLESTAR', "**" ) + parser.add_token( 'PLUSEQUAL', "+=" ) + parser.add_token( 'MINEQUAL', "-=" ) + parser.add_token( 'STAREQUAL', "*=" ) + parser.add_token( 'SLASHEQUAL', "/=" ) + parser.add_token( 'PERCENTEQUAL', "%=" ) + parser.add_token( 'AMPEREQUAL', "&=" ) + parser.add_token( 'VBAREQUAL', "|=" ) + parser.add_token( 'CIRCUMFLEXEQUAL', "^=" ) + parser.add_token( 'LEFTSHIFTEQUAL', "<<=" ) + parser.add_token( 'RIGHTSHIFTEQUAL', ">>=" ) + parser.add_token( 'DOUBLESTAREQUAL', "**=" ) + parser.add_token( 'DOUBLESLASH', "//" ) + parser.add_token( 'DOUBLESLASHEQUAL',"//=" ) + parser.add_token( 'AT', "@" ) + parser.add_token( 'OP' ) + parser.add_token( 'ERRORTOKEN' ) # extra PyPy-specific tokens -add_token( "COMMENT" ) -add_token( "NL" ) - -# a reverse mapping from internal tokens def to more pythonic tokens -tok_punct = { - "&" : AMPER, - "&=" : AMPEREQUAL, - "`" : BACKQUOTE, - "^" : CIRCUMFLEX, - "^=" : CIRCUMFLEXEQUAL, - ":" : COLON, - "," : COMMA, - "." : DOT, - "//" : DOUBLESLASH, - "//=" : DOUBLESLASHEQUAL, - "**" : DOUBLESTAR, - "**=" : DOUBLESTAREQUAL, - "==" : EQEQUAL, - "=" : EQUAL, - ">" : GREATER, - ">=" : GREATEREQUAL, - "{" : LBRACE, - "}" : RBRACE, - "<<" : LEFTSHIFT, - "<<=" : LEFTSHIFTEQUAL, - "<" : LESS, - "<=" : LESSEQUAL, - "(" : LPAR, - "[" : LSQB, - "-=" : MINEQUAL, - "-" : MINUS, - "!=" : NOTEQUAL, - "<>" : NOTEQUAL, - "%" : PERCENT, - "%=" : PERCENTEQUAL, - "+" : PLUS, - "+=" : PLUSEQUAL, - ")" : RBRACE, - ">>" : RIGHTSHIFT, - ">>=" : RIGHTSHIFTEQUAL, - ")" : RPAR, - "]" : RSQB, - ";" : SEMI, - "/" : SLASH, - "/=" : SLASHEQUAL, - "*" : STAR, - "*=" : STAREQUAL, - "~" : TILDE, - "|" : VBAR, - "|=" : VBAREQUAL, - "@": AT, - } -tok_rpunct = {} -for string, value in tok_punct.items(): - tok_rpunct[value] = string + parser.add_token( "COMMENT" ) + parser.add_token( "NL" ) + # tok_rpunct = parser.tok_values.copy() + # for _name, _value in parser.tokens.items(): + # globals()[_name] = _value + # setattr(parser, _name, _value) Modified: pypy/dist/pypy/interpreter/pyparser/syntaxtree.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/syntaxtree.py (original) +++ pypy/dist/pypy/interpreter/pyparser/syntaxtree.py Wed Feb 28 18:30:48 2007 @@ -8,6 +8,8 @@ from pypy.tool.uid import uid +from pypy.tool.uid import uid + class AbstractSyntaxVisitor(object): def visit_syntaxnode( self, node ): pass Added: pypy/dist/pypy/interpreter/pyparser/test/expressions.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/interpreter/pyparser/test/expressions.py Wed Feb 28 18:30:48 2007 @@ -0,0 +1,504 @@ +""" +list of tested expressions / suites (used by test_parser and test_astbuilder) +""" + +constants = [ + "0", + "7", + "-3", + "053", + "0x18", + "14L", + "1.0", + "3.9", + "-3.6", + "1.8e19", + "90000000000000", + "90000000000000.", + "3j" + ] + +expressions = [ + "x = a + 1", + "x = 1 - a", + "x = a * b", + "x = a ** 2", + "x = a / b", + "x = a & b", + "x = a | b", + "x = a ^ b", + "x = a // b", + "x = a * b + 1", + "x = a + 1 * b", + "x = a * b / c", + "x = a * (1 + c)", + "x, y, z = 1, 2, 3", + "x = 'a' 'b' 'c'", + "del foo", + "del foo[bar]", + "del foo.bar", + "l[0]", + "k[v,]", + "m[a,b]", + "a.b.c[d]", + "file('some.txt').read()", + "a[0].read()", + "a[1:1].read()", + "f('foo')('bar')('spam')", + "f('foo')('bar')('spam').read()[0]", + "a.b[0][0]", + "a.b[0][:]", + "a.b[0][::]", + "a.b[0][0].pop()[0].push('bar')('baz').spam", + "a.b[0].read()[1][2].foo().spam()[0].bar", + "a**2", + "a**2**2", + "a.b[0]**2", + "a.b[0].read()[1][2].foo().spam()[0].bar ** 2", + "l[start:end] = l2", + "l[::] = l2", + "a = `s`", + "a = `1 + 2 + f(3, 4)`", + "[a, b] = c", + "(a, b) = c", + "[a, (b,c), d] = e", + "a, (b, c), d = e", + ] + +# We do not export the following tests because we would have to implement 2.5 +# features in the stable compiler (other than just building the AST). +expressions_inbetweenversions = expressions + [ + "1 if True else 2", + "1 if False else 2", + ] + +funccalls = [ + "l = func()", + "l = func(10)", + "l = func(10, 12, a, b=c, *args)", + "l = func(10, 12, a, b=c, **kwargs)", + "l = func(10, 12, a, b=c, *args, **kwargs)", + "l = func(10, 12, a, b=c)", + "e = l.pop(3)", + "e = k.l.pop(3)", + "simplefilter('ignore', category=PendingDeprecationWarning, append=1)", + """methodmap = dict(subdirs=phase4, + same_files=phase3, diff_files=phase3, funny_files=phase3, + common_dirs = phase2, common_files=phase2, common_funny=phase2, + common=phase1, left_only=phase1, right_only=phase1, + left_list=phase0, right_list=phase0)""", + "odata = b2a_qp(data, quotetabs = quotetabs, header = header)", + ] + +listmakers = [ + "l = []", + "l = [1, 2, 3]", + "l = [i for i in range(10)]", + "l = [i for i in range(10) if i%2 == 0]", + "l = [i for i in range(10) if i%2 == 0 or i%2 == 1]", # <-- + "l = [i for i in range(10) if i%2 == 0 and i%2 == 1]", + "l = [i for j in range(10) for i in range(j)]", + "l = [i for j in range(10) for i in range(j) if j%2 == 0]", + "l = [i for j in range(10) for i in range(j) if j%2 == 0 and i%2 == 0]", + "l = [(a, b) for (a,b,c) in l2]", + "l = [{a:b} for (a,b,c) in l2]", + "l = [i for j in k if j%2 == 0 if j*2 < 20 for i in j if i%2==0]", + ] + +genexps = [ + "l = (i for i in j)", + "l = (i for i in j if i%2 == 0)", + "l = (i for j in k for i in j)", + "l = (i for j in k for i in j if j%2==0)", + "l = (i for j in k if j%2 == 0 if j*2 < 20 for i in j if i%2==0)", + "l = (i for i in [ j*2 for j in range(10) ] )", + "l = [i for i in ( j*2 for j in range(10) ) ]", + "l = (i for i in [ j*2 for j in ( k*3 for k in range(10) ) ] )", + "l = [i for j in ( j*2 for j in [ k*3 for k in range(10) ] ) ]", + "l = f(i for i in j)", + ] + + +dictmakers = [ + "l = {a : b, 'c' : 0}", + "l = {}", + ] + +backtrackings = [ + "f = lambda x: x+1", + "f = lambda x,y: x+y", + "f = lambda x,y=1,z=t: x+y", + "f = lambda x,y=1,z=t,*args,**kwargs: x+y", + "f = lambda x,y=1,z=t,*args: x+y", + "f = lambda x,y=1,z=t,**kwargs: x+y", + "f = lambda: 1", + "f = lambda *args: 1", + "f = lambda **kwargs: 1", + ] + +comparisons = [ + "a < b", + "a > b", + "a not in b", + "a is not b", + "a in b", + "a is b", + "3 < x < 5", + "(3 < x) < 5", + "a < b < c < d", + "(a < b) < (c < d)", + "a < (b < c) < d", + ] + +multiexpr = [ + 'a = b; c = d;', + 'a = b = c = d', + ] + +attraccess = [ + 'a.b = 2', + 'x = a.b', + ] + +slices = [ + "l[:]", + "l[::]", + "l[1:2]", + "l[1:]", + "l[:2]", + "l[1::]", + "l[:1:]", + "l[::1]", + "l[1:2:]", + "l[:1:2]", + "l[1::2]", + "l[0:1:2]", + "a.b.l[:]", + "a.b.l[1:2]", + "a.b.l[1:]", + "a.b.l[:2]", + "a.b.l[0:1:2]", + "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 = [ + 'import os', + 'import sys, os', + 'import os.path', + 'import os.path, sys', + 'import sys, os.path as osp', + 'import os.path as osp', + 'import os.path as osp, sys as _sys', + 'import a.b.c.d', + 'import a.b.c.d as abcd', + 'from os import path', + 'from os import path, system', + ] + +imports_newstyle = [ + 'from os import path, system', + 'from os import path as P, system as S', + 'from os import (path as P, system as S,)', + 'from os import *', + ] + +if_stmts = [ + "if a == 1: a+= 2", + """if a == 1: + a += 2 +elif a == 2: + a += 3 +else: + a += 4 +""", + "if a and not b == c: pass", + "if a and not not not b == c: pass", + "if 0: print 'foo'" + ] + +asserts = [ + 'assert False', + 'assert a == 1', + 'assert a == 1 and b == 2', + 'assert a == 1 and b == 2, "assertion failed"', + ] + +execs = [ + 'exec a', + 'exec "a=b+3"', + 'exec a in f()', + 'exec a in f(), g()', + ] + +prints = [ + 'print', + 'print a', + 'print a,', + 'print a, b', + 'print a, "b", c', + 'print >> err', + 'print >> err, "error"', + 'print >> err, "error",', + 'print >> err, "error", a', + ] + +globs = [ + 'global a', + 'global a,b,c', + ] + +raises_ = [ # NB. 'raises' creates a name conflict with py.test magic + 'raise', + 'raise ValueError', + 'raise ValueError("error")', + 'raise ValueError, "error"', + 'raise ValueError, "error", foo', + ] + +tryexcepts = [ + """try: + a + b +except: + pass +""", + """try: + a + b +except NameError: + pass +""", + """try: + a + b +except NameError, err: + pass +""", + """try: + a + b +except (NameError, ValueError): + pass +""", + """try: + a + b +except (NameError, ValueError), err: + pass +""", + """try: + a +except NameError, err: + pass +except ValueError, err: + pass +""", + """def f(): + try: + a + except NameError, err: + a = 1 + b = 2 + except ValueError, err: + a = 2 + return a +""" + """try: + a +except NameError, err: + a = 1 +except ValueError, err: + a = 2 +else: + a += 3 +""", + """try: + a +finally: + b +""", + """def f(): + try: + return a + finally: + a = 3 + return 1 +""", + + ] + +one_stmt_funcdefs = [ + "def f(): return 1", + "def f(x): return x+1", + "def f(x,y): return x+y", + "def f(x,y=1,z=t): return x+y", + "def f(x,y=1,z=t,*args,**kwargs): return x+y", + "def f(x,y=1,z=t,*args): return x+y", + "def f(x,y=1,z=t,**kwargs): return x+y", + "def f(*args): return 1", + "def f(**kwargs): return 1", + "def f(t=()): pass", + "def f(a, b, (c, d), e): pass", + "def f(a, b, (c, (d, e), f, (g, h))): pass", + "def f(a, b, (c, (d, e), f, (g, h)), i): pass", + "def f((a)): pass", + ] + +one_stmt_classdefs = [ + "class Pdb(bdb.Bdb, cmd.Cmd): pass", + ] + +docstrings = [ + '''def foo(): return 1''', + '''class Foo: pass''', + '''class Foo: "foo"''', + '''def foo(): + """foo docstring""" + return 1 +''', + '''def foo(): + """foo docstring""" + a = 1 + """bar""" + return a +''', + '''def foo(): + """doc"""; print 1 + a=1 +''', + '''"""Docstring""";print 1''', + ] + +returns = [ + 'def f(): return', + 'def f(): return 1', + 'def f(): return a.b', + 'def f(): return a', + 'def f(): return a,b,c,d', + #'return (a,b,c,d)', --- this one makes no sense, as far as I can tell + ] + +augassigns = [ + 'a=1;a+=2', + 'a=1;a-=2', + 'a=1;a*=2', + 'a=1;a/=2', + 'a=1;a//=2', + 'a=1;a%=2', + 'a=1;a**=2', + 'a=1;a>>=2', + 'a=1;a<<=2', + 'a=1;a&=2', + 'a=1;a^=2', + 'a=1;a|=2', + + 'a=A();a.x+=2', + 'a=A();a.x-=2', + 'a=A();a.x*=2', + 'a=A();a.x/=2', + 'a=A();a.x//=2', + 'a=A();a.x%=2', + 'a=A();a.x**=2', + 'a=A();a.x>>=2', + 'a=A();a.x<<=2', + 'a=A();a.x&=2', + 'a=A();a.x^=2', + 'a=A();a.x|=2', + + 'a=A();a[0]+=2', + 'a=A();a[0]-=2', + 'a=A();a[0]*=2', + 'a=A();a[0]/=2', + 'a=A();a[0]//=2', + 'a=A();a[0]%=2', + 'a=A();a[0]**=2', + 'a=A();a[0]>>=2', + 'a=A();a[0]<<=2', + 'a=A();a[0]&=2', + 'a=A();a[0]^=2', + 'a=A();a[0]|=2', + + 'a=A();a[0:2]+=2', + 'a=A();a[0:2]-=2', + 'a=A();a[0:2]*=2', + 'a=A();a[0:2]/=2', + 'a=A();a[0:2]//=2', + 'a=A();a[0:2]%=2', + 'a=A();a[0:2]**=2', + 'a=A();a[0:2]>>=2', + 'a=A();a[0:2]<<=2', + 'a=A();a[0:2]&=2', + 'a=A();a[0:2]^=2', + 'a=A();a[0:2]|=2', + ] + +PY23_TESTS = [ + constants, + expressions, + augassigns, + comparisons, + funccalls, + backtrackings, + listmakers, # ERRORS + dictmakers, + multiexpr, + attraccess, + slices, + imports, + execs, + prints, + globs, + raises_, + + ] + +OPTIONAL_TESTS = [ + # expressions_inbetweenversions, + genexps, + imports_newstyle, + asserts, + ] + +TESTS = PY23_TESTS + OPTIONAL_TESTS + + +## TESTS = [ +## ["l = [i for i in range(10) if i%2 == 0 or i%2 == 1]"], +## ] + +EXEC_INPUTS = [ + one_stmt_classdefs, + one_stmt_funcdefs, + if_stmts, + tryexcepts, + docstrings, + returns, + ] + +SINGLE_INPUTS = [ + one_stmt_funcdefs, + ['\t # hello\n', + 'print 6*7', + 'if 1: x\n', + 'x = 5', + 'x = 5 ', + '''"""Docstring""";print 1''', + '''"Docstring"''', + '''"Docstring" "\\x00"''', + ] +] 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 Feb 28 18:30:48 2007 @@ -2,7 +2,7 @@ from pypy.interpreter.pyparser import pythonparse from pypy.interpreter.pyparser.astbuilder import AstBuilder -from pypy.interpreter.pyparser.pythonutil import ast_from_input +from pypy.interpreter.pyparser.pythonutil import ast_from_input, build_parser_for_version from pypy.interpreter.stablecompiler.transformer import Transformer import pypy.interpreter.stablecompiler.ast as test_ast import pypy.interpreter.astcompiler.ast as ast_ast @@ -13,6 +13,9 @@ from pypy.interpreter.astcompiler import ast + +from expressions import TESTS, SINGLE_INPUTS, EXEC_INPUTS + def arglist_equal(left,right): """needs special case because we handle the argumentlist differently""" for l,r in zip(left,right): @@ -142,211 +145,13 @@ return False return True -EXPECTED = {} - -constants = [ - "0", - "7", - "-3", - "053", - "0x18", - "14L", - "1.0", - "3.9", - "-3.6", - "1.8e19", - "90000000000000", - "90000000000000.", - "3j" - ] - -expressions = [ - "x = a + 1", - "x = 1 - a", - "x = a * b", - "x = a ** 2", - "x = a / b", - "x = a & b", - "x = a | b", - "x = a ^ b", - "x = a // b", - "x = a * b + 1", - "x = a + 1 * b", - "x = a * b / c", - "x = a * (1 + c)", - "x, y, z = 1, 2, 3", - "x = 'a' 'b' 'c'", - "del foo", - "del foo[bar]", - "del foo.bar", - "l[0]", - "k[v,]", - "m[a,b]", - "a.b.c[d]", - "file('some.txt').read()", - "a[0].read()", - "a[1:1].read()", - "f('foo')('bar')('spam')", - "f('foo')('bar')('spam').read()[0]", - "a.b[0][0]", - "a.b[0][:]", - "a.b[0][::]", - "a.b[0][0].pop()[0].push('bar')('baz').spam", - "a.b[0].read()[1][2].foo().spam()[0].bar", - "a**2", - "a**2**2", - "a.b[0]**2", - "a.b[0].read()[1][2].foo().spam()[0].bar ** 2", - "l[start:end] = l2", - "l[::] = l2", - "a = `s`", - "a = `1 + 2 + f(3, 4)`", - "[a, b] = c", - "(a, b) = c", - "[a, (b,c), d] = e", - "a, (b, c), d = e", - ] - -# We do not export the following tests because we would have to implement 2.5 -# features in the stable compiler (other than just building the AST). -expressions_inbetweenversions = expressions + [ - #"1 if True else 2", # Disabled 2.5 syntax - #"1 if False else 2", - ] - -EXPECTED["k[v,]"] = ("Module(None, Stmt([Discard(Subscript(Name('k'), 2, " - "Tuple([Name('v')])))]))") -EXPECTED["m[a,b]"] = ("Module(None, Stmt([Discard(Subscript(Name('m'), 2, " - "Tuple([Name('a'), Name('b')])))]))") -EXPECTED["1 if True else 2"] = ("Module(None, Stmt([Discard(CondExpr(" - "Name('True'), Const(1), Const(2)))]))") -EXPECTED["1 if False else 2"] = ("Module(None, Stmt([Discard(CondExpr(" - "Name('False'), Const(1), Const(2)))]))") - -funccalls = [ - "l = func()", - "l = func(10)", - "l = func(10, 12, a, b=c, *args)", - "l = func(10, 12, a, b=c, **kwargs)", - "l = func(10, 12, a, b=c, *args, **kwargs)", - "l = func(10, 12, a, b=c)", - "e = l.pop(3)", - "e = k.l.pop(3)", - "simplefilter('ignore', category=PendingDeprecationWarning, append=1)", - """methodmap = dict(subdirs=phase4, - same_files=phase3, diff_files=phase3, funny_files=phase3, - common_dirs = phase2, common_files=phase2, common_funny=phase2, - common=phase1, left_only=phase1, right_only=phase1, - left_list=phase0, right_list=phase0)""", - "odata = b2a_qp(data, quotetabs = quotetabs, header = header)", - ] - -listmakers = [ - "l = []", - "l = [1, 2, 3]", - "l = [i for i in range(10)]", - "l = [i for i in range(10) if i%2 == 0]", - "l = [i for i in range(10) if i%2 == 0 or i%2 == 1]", - "l = [i for i in range(10) if i%2 == 0 and i%2 == 1]", - "l = [i for j in range(10) for i in range(j)]", - "l = [i for j in range(10) for i in range(j) if j%2 == 0]", - "l = [i for j in range(10) for i in range(j) if j%2 == 0 and i%2 == 0]", - "l = [(a, b) for (a,b,c) in l2]", - "l = [{a:b} for (a,b,c) in l2]", - "l = [i for j in k if j%2 == 0 if j*2 < 20 for i in j if i%2==0]", - ] - -genexps = [ - "l = (i for i in j)", - "l = (i for i in j if i%2 == 0)", - "l = (i for j in k for i in j)", - "l = (i for j in k for i in j if j%2==0)", - "l = (i for j in k if j%2 == 0 if j*2 < 20 for i in j if i%2==0)", - "l = (i for i in [ j*2 for j in range(10) ] )", - "l = [i for i in ( j*2 for j in range(10) ) ]", - "l = (i for i in [ j*2 for j in ( k*3 for k in range(10) ) ] )", - "l = [i for j in ( j*2 for j in [ k*3 for k in range(10) ] ) ]", - "l = f(i for i in j)", - ] - - -dictmakers = [ - "l = {a : b, 'c' : 0}", - "l = {}", - ] - -backtrackings = [ - "f = lambda x: x+1", - "f = lambda x,y: x+y", - "f = lambda x,y=1,z=t: x+y", - "f = lambda x,y=1,z=t,*args,**kwargs: x+y", - "f = lambda x,y=1,z=t,*args: x+y", - "f = lambda x,y=1,z=t,**kwargs: x+y", - "f = lambda: 1", - "f = lambda *args: 1", - "f = lambda **kwargs: 1", - ] +EXPECTED = { + "k[v,]" : "Module(None, Stmt([Discard(Subscript(Name('k'), 2, Tuple([Name('v')])))]))", + "m[a,b]" : "Module(None, Stmt([Discard(Subscript(Name('m'), 2, Tuple([Name('a'), Name('b')])))]))", -comparisons = [ - "a < b", - "a > b", - "a not in b", - "a is not b", - "a in b", - "a is b", - "3 < x < 5", - "(3 < x) < 5", - "a < b < c < d", - "(a < b) < (c < d)", - "a < (b < c) < d", - ] - -multiexpr = [ - 'a = b; c = d;', - 'a = b = c = d', - ] + "1 if True else 2" : "Module(None, Stmt([Discard(CondExpr(Name('True'), Const(1), Const(2)))]))", + "1 if False else 2" : "Module(None, Stmt([Discard(CondExpr(Name('False'), Const(1), Const(2)))]))", -attraccess = [ - 'a.b = 2', - 'x = a.b', - ] - -slices = [ - "l[:]", - "l[::]", - "l[1:2]", - "l[1:]", - "l[:2]", - "l[1::]", - "l[:1:]", - "l[::1]", - "l[1:2:]", - "l[:1:2]", - "l[1::2]", - "l[0:1:2]", - "a.b.l[:]", - "a.b.l[1:2]", - "a.b.l[1:]", - "a.b.l[:2]", - "a.b.l[0:1:2]", - "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, :]", - ] -EXPECTED.update({ "a[1:2:3, 100]": "Module(None, Stmt([Discard(Subscript(Name('a'), 2, Tuple([Sliceobj([Const(1), Const(2), Const(3)]), Const(100)])))]))", "a[:2:3, 100]": "Module(None, Stmt([Discard(Subscript(Name('a'), 2, Tuple([Sliceobj([Const(None), Const(2), Const(3)]), Const(100)])))]))", "a[1::3, 100,]": "Module(None, Stmt([Discard(Subscript(Name('a'), 2, Tuple([Sliceobj([Const(1), Const(None), Const(3)]), Const(100)])))]))", @@ -363,307 +168,10 @@ "a[100, 1:]": "Module(None, Stmt([Discard(Subscript(Name('a'), 2, Tuple([Const(100), Sliceobj([Const(1), Const(None)])])))]))", "a[100, :2,]": "Module(None, Stmt([Discard(Subscript(Name('a'), 2, Tuple([Const(100), Sliceobj([Const(None), Const(2)])])))]))", "a[100, :]": "Module(None, Stmt([Discard(Subscript(Name('a'), 2, Tuple([Const(100), Sliceobj([Const(None), Const(None)])])))]))", - }) - -imports = [ - 'import os', - 'import sys, os', - 'import os.path', - 'import os.path, sys', - 'import sys, os.path as osp', - 'import os.path as osp', - 'import os.path as osp, sys as _sys', - 'import a.b.c.d', - 'import a.b.c.d as abcd', - 'from os import path', - 'from os import path, system', - ] - -imports_newstyle = [ - 'from os import path, system', - 'from os import path as P, system as S', - 'from os import (path as P, system as S,)', - 'from os import *', - ] - -if_stmts = [ - "if a == 1: a+= 2", - """if a == 1: - a += 2 -elif a == 2: - a += 3 -else: - a += 4 -""", - "if a and not b == c: pass", - "if a and not not not b == c: pass", - "if 0: print 'foo'" - ] - -asserts = [ - 'assert False', - 'assert a == 1', - 'assert a == 1 and b == 2', - 'assert a == 1 and b == 2, "assertion failed"', - ] - -execs = [ - 'exec a', - 'exec "a=b+3"', - 'exec a in f()', - 'exec a in f(), g()', - ] - -prints = [ - 'print', - 'print a', - 'print a,', - 'print a, b', - 'print a, "b", c', - 'print >> err', - 'print >> err, "error"', - 'print >> err, "error",', - 'print >> err, "error", a', - ] - -globs = [ - 'global a', - 'global a,b,c', - ] - -raises_ = [ # NB. 'raises' creates a name conflict with py.test magic - 'raise', - 'raise ValueError', - 'raise ValueError("error")', - 'raise ValueError, "error"', - 'raise ValueError, "error", foo', - ] - -tryexcepts = [ - """try: - a - b -except: - pass -""", - """try: - a - b -except NameError: - pass -""", - """try: - a - b -except NameError, err: - pass -""", - """try: - a - b -except (NameError, ValueError): - pass -""", - """try: - a - b -except (NameError, ValueError), err: - pass -""", - """try: - a -except NameError, err: - pass -except ValueError, err: - pass -""", - """def f(): - try: - a - except NameError, err: - a = 1 - b = 2 - except ValueError, err: - a = 2 - return a -""" - """try: - a -except NameError, err: - a = 1 -except ValueError, err: - a = 2 -else: - a += 3 -""", - """try: - a -finally: - b -""", - """def f(): - try: - return a - finally: - a = 3 - return 1 -""", - - ] - -one_stmt_funcdefs = [ - "def f(): return 1", - "def f(x): return x+1", - "def f(x,y): return x+y", - "def f(x,y=1,z=t): return x+y", - "def f(x,y=1,z=t,*args,**kwargs): return x+y", - "def f(x,y=1,z=t,*args): return x+y", - "def f(x,y=1,z=t,**kwargs): return x+y", - "def f(*args): return 1", - "def f(**kwargs): return 1", - "def f(t=()): pass", - "def f(a, b, (c, d), e): pass", - "def f(a, b, (c, (d, e), f, (g, h))): pass", - "def f(a, b, (c, (d, e), f, (g, h)), i): pass", - "def f((a)): pass", - ] - -one_stmt_classdefs = [ - "class Pdb(bdb.Bdb, cmd.Cmd): pass", - ] - -docstrings = [ - '''def foo(): return 1''', - '''class Foo: pass''', - '''class Foo: "foo"''', - '''def foo(): - """foo docstring""" - return 1 -''', - '''def foo(): - """foo docstring""" - a = 1 - """bar""" - return a -''', - '''def foo(): - """doc"""; print 1 - a=1 -''', - '''"""Docstring""";print 1''', - ] - -returns = [ - 'def f(): return', - 'def f(): return 1', - 'def f(): return a.b', - 'def f(): return a', - 'def f(): return a,b,c,d', - #'return (a,b,c,d)', --- this one makes no sense, as far as I can tell - ] -augassigns = [ - 'a=1;a+=2', - 'a=1;a-=2', - 'a=1;a*=2', - 'a=1;a/=2', - 'a=1;a//=2', - 'a=1;a%=2', - 'a=1;a**=2', - 'a=1;a>>=2', - 'a=1;a<<=2', - 'a=1;a&=2', - 'a=1;a^=2', - 'a=1;a|=2', - - 'a=A();a.x+=2', - 'a=A();a.x-=2', - 'a=A();a.x*=2', - 'a=A();a.x/=2', - 'a=A();a.x//=2', - 'a=A();a.x%=2', - 'a=A();a.x**=2', - 'a=A();a.x>>=2', - 'a=A();a.x<<=2', - 'a=A();a.x&=2', - 'a=A();a.x^=2', - 'a=A();a.x|=2', - - 'a=A();a[0]+=2', - 'a=A();a[0]-=2', - 'a=A();a[0]*=2', - 'a=A();a[0]/=2', - 'a=A();a[0]//=2', - 'a=A();a[0]%=2', - 'a=A();a[0]**=2', - 'a=A();a[0]>>=2', - 'a=A();a[0]<<=2', - 'a=A();a[0]&=2', - 'a=A();a[0]^=2', - 'a=A();a[0]|=2', - - 'a=A();a[0:2]+=2', - 'a=A();a[0:2]-=2', - 'a=A();a[0:2]*=2', - 'a=A();a[0:2]/=2', - 'a=A();a[0:2]//=2', - 'a=A();a[0:2]%=2', - 'a=A();a[0:2]**=2', - 'a=A();a[0:2]>>=2', - 'a=A();a[0:2]<<=2', - 'a=A();a[0:2]&=2', - 'a=A();a[0:2]^=2', - 'a=A();a[0:2]|=2', - ] - -TESTS = [ - constants, - expressions_inbetweenversions, - augassigns, - comparisons, - funccalls, - backtrackings, - listmakers, - genexps, - dictmakers, - multiexpr, - attraccess, - slices, - imports, - imports_newstyle, - asserts, - execs, - prints, - globs, - raises_, - ] - -EXEC_INPUTS = [ - one_stmt_classdefs, - one_stmt_funcdefs, - if_stmts, - tryexcepts, - docstrings, - returns, - ] - -SINGLE_INPUTS = [ - one_stmt_funcdefs, - ['\t # hello\n', - 'print 6*7', - 'if 1: x\n', - 'x = 5', - 'x = 5 ', - '''"""Docstring""";print 1''', - '''"Docstring"''', - '''"Docstring" "\\x00"''', - ] -] - -TARGET_DICT = { - 'single' : 'single_input', - 'exec' : 'file_input', - 'eval' : 'eval_input', + # stablecompiler produces a Pass statement which does not seem very consistent + # (a module should only have a Stmt child) + "\t # hello\n": "Module(None, Stmt([]))", } @@ -705,39 +213,39 @@ builtin = dict(int=int, long=long, float=float, complex=complex) -def ast_parse_expr(expr, target='single'): - target = TARGET_DICT[target] - builder = AstBuilder(space=FakeSpace()) - pythonparse.PYTHON_PARSER.parse_source(expr, target, builder) - return builder - # Create parser from Grammar_stable, not current grammar. -stable_grammar, _ = pythonparse.get_grammar_file("stable") -stable_parser = pythonparse.python_grammar(stable_grammar) +stable_parser = pythonparse.make_pyparser('stable') +python_parser = pythonparse.make_pyparser() # 'native') # 2.5a') def tuple_parse_expr(expr, target='single'): t = Transformer("dummyfile") return ast_from_input(expr, target, t, stable_parser) -def check_expression(expr, target='single'): - r1 = ast_parse_expr(expr, target) +def source2ast(source, mode, space=FakeSpace()): + builder = AstBuilder(space=space, parser=python_parser) + python_parser.parse_source(source, mode, builder) + return builder.rule_stack[-1] + +def check_expression(expr, mode='single'): + pypy_ast = source2ast(expr, mode) try: - ast = EXPECTED[expr] + python_ast = EXPECTED[expr] except KeyError: # trust the stablecompiler's Transformer when no explicit result has # been provided (although trusting it is a foolish thing to do) - ast = tuple_parse_expr(expr, target) + python_ast = tuple_parse_expr(expr, mode) check_lineno = True else: - if isinstance(ast, str): - ast = eval(ast, ast_ast.__dict__) + if isinstance(python_ast, str): + python_ast = eval(python_ast, ast_ast.__dict__) check_lineno = False print "-" * 30 - print "ORIG :", ast + print "ORIG :", python_ast print - print "BUILT:", r1.rule_stack[-1] + print "BUILT:", pypy_ast print "-" * 30 - assert nodes_equal(ast, r1.rule_stack[-1], check_lineno), 'failed on %r' % (expr) + assert nodes_equal(python_ast, pypy_ast, check_lineno), 'failed on %r' % (expr) + def test_basic_astgen(): for family in TESTS: @@ -749,6 +257,7 @@ for expr in family: yield check_expression, expr, 'exec' + NEW_GRAMMAR_SNIPPETS = [ 'snippet_with_1.py', 'snippet_with_2.py', @@ -810,7 +319,7 @@ for snippet_name in LIBSTUFF: filepath = os.path.join(os.path.dirname(__file__), '../../../lib', snippet_name) source = file(filepath).read() - yield check_expression, source, 'exec' + yield check_expression, source, 'exec' # FIXME: find the sys' attribute that define this STDLIB_PATH = os.path.dirname(os.__file__) Modified: pypy/dist/pypy/interpreter/pyparser/test/test_astcompiler.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/test/test_astcompiler.py (original) +++ pypy/dist/pypy/interpreter/pyparser/test/test_astcompiler.py Wed Feb 28 18:30:48 2007 @@ -1,4 +1,6 @@ +import sys import os + from pypy.interpreter.pyparser import pythonparse from pypy.interpreter.pyparser.astbuilder import AstBuilder from pypy.interpreter.pyparser.tuplebuilder import TupleBuilder @@ -11,93 +13,47 @@ from pypy.interpreter.astcompiler import ast, misc, pycodegen -from test_astbuilder import expressions, comparisons, funccalls, backtrackings,\ - listmakers, genexps, dictmakers, multiexpr, attraccess, slices, imports,\ - asserts, execs, prints, globs, raises_, imports_newstyle, augassigns, \ - if_stmts, one_stmt_classdefs, one_stmt_funcdefs, tryexcepts, docstrings, \ - returns, SNIPPETS, SINGLE_INPUTS, LIBSTUFF, constants - -from test_astbuilder import FakeSpace - - -TESTS = [ - constants, - expressions, - augassigns, - comparisons, - funccalls, - backtrackings, - listmakers, - dictmakers, - multiexpr, - genexps, - attraccess, - slices, - imports, - execs, - prints, - globs, - raises_, -# EXEC_INPUTS - one_stmt_classdefs, - one_stmt_funcdefs, - if_stmts, - tryexcepts, - docstrings, - returns, - ] +from test_astbuilder import SNIPPETS, LIBSTUFF, FakeSpace, source2ast +from expressions import PY23_TESTS, EXEC_INPUTS, SINGLE_INPUTS, OPTIONAL_TESTS + +TESTS = PY23_TESTS + EXEC_INPUTS + -import sys if sys.version_info[0]==2 and sys.version_info[1]>=4: # genexps and new style import don't work on python2.3 # TESTS.append(genexps) XXX: 2.4 optimizes bytecode so our comparison doesn't work - TESTS.append(imports_newstyle) - # assertions give different bytecode with 2.4 (optimize if __debug__) - TESTS.append(asserts) -TARGET_DICT = { - 'single' : 'single_input', - 'exec' : 'file_input', - 'eval' : 'eval_input', - } - -def ast_parse_expr(expr, target='single', space=FakeSpace()): - target = TARGET_DICT[target] - builder = AstBuilder(space=space) - pythonparse.PYTHON_PARSER.parse_source(expr, target, builder) - return builder.rule_stack[-1] + TESTS += OPTIONAL_TESTS -def compile_with_astcompiler(expr, target='exec', space=FakeSpace()): - ast = ast_parse_expr(expr, target='exec', space=space) # xxx exec: single not really tested, mumble +def compile_with_astcompiler(expr, mode='exec', space=FakeSpace()): + ast = source2ast(expr, mode, space) # xxx exec: single not really tested, mumble misc.set_filename('', ast) - if target == 'exec': + if mode == 'exec': Generator = pycodegen.ModuleCodeGenerator - elif target == 'single': + elif mode == 'single': Generator = pycodegen.InteractiveCodeGenerator - elif target == 'eval': + elif mode == 'eval': Generator = pycodegen.ExpressionCodeGenerator codegen = Generator(space, ast) rcode = codegen.getCode() return rcode - # Create parser from Grammar_stable, not current grammar. -stable_grammar, _ = pythonparse.get_grammar_file("stable") -stable_parser = pythonparse.python_grammar(stable_grammar) +stable_parser = pythonparse.make_pyparser('stable') -def compile_with_testcompiler(expr, target='exec', space=FakeSpace()): - target2 = TARGET_DICT['exec'] # xxx exec: single not really tested - builder = TupleBuilder() - stable_parser.parse_source(expr, target2, builder) +def compile_with_testcompiler(expr, mode='exec', space=FakeSpace()): + mode2 = 'exec' # xxx exec: single not really tested + builder = TupleBuilder(stable_parser) + stable_parser.parse_source(expr, mode2, 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': + if mode == 'exec': Generator = pycodegen.ModuleCodeGenerator - elif target == 'single': + elif mode == 'single': Generator = pycodegen.InteractiveCodeGenerator - elif target == 'eval': + elif mode == 'eval': Generator = pycodegen.ExpressionCodeGenerator codegen = Generator(ast) rcode = codegen.getCode() @@ -151,40 +107,27 @@ tuple(rcode.co_cellvars) ) return code -def check_compile(expr, target='exec', quiet=False, space=None): +def check_compile(expr, mode='exec', quiet=False, space=None): if not quiet: print "Compiling:", expr if space is None: space = std_space - ac_code = compile_with_astcompiler(expr, target=target, space=space) + ac_code = compile_with_astcompiler(expr, mode=mode, space=space) if expr == "k[v,]" or expr.startswith('"'): # module-level docstring py.test.skip('comparison skipped, bug in "reference stable compiler"') - sc_code = compile_with_testcompiler(expr, target=target) + sc_code = compile_with_testcompiler(expr, mode=mode) compare_code(ac_code, sc_code, space=space) -## def check_compile( expr ): -## space = FakeSpace() -## ast_tree = ast_parse_expr( expr, target='exec', space=space ) -## misc.set_filename("", ast_tree) -## print "Compiling:", expr -## print ast_tree -## codegenerator = pycodegen.ModuleCodeGenerator(space,ast_tree) -## rcode = codegenerator.getCode() -## code1 = to_code( rcode ) -## code2 = ast_compile( expr ) -## compare_code(code1,code2) def test_compile_argtuple_1(): - #py.test.skip('will be tested when more basic stuff will work') code = """def f( x, (y,z) ): print x,y,z """ check_compile( code ) def test_compile_argtuple_2(): - #py.test.skip('will be tested when more basic stuff will work') code = """def f( x, (y,(z,t)) ): print x,y,z,t """ @@ -192,14 +135,12 @@ def test_compile_argtuple_3(): - #py.test.skip('will be tested when more basic stuff will work') code = """def f( x, (y,(z,(t,u))) ): print x,y,z,t,u """ check_compile( code ) - def test_basic_astgen(): for family in TESTS: for expr in family: @@ -228,7 +169,7 @@ for snippet_name in LIBSTUFF: filepath = os.path.join(os.path.dirname(__file__), '../../../lib', snippet_name) source = file(filepath).read() - yield check_compile, source, 'exec' + yield check_compile, source, 'exec' def test_single_inputs(): Modified: pypy/dist/pypy/interpreter/pyparser/test/test_lookahead.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/test/test_lookahead.py (original) +++ pypy/dist/pypy/interpreter/pyparser/test/test_lookahead.py Wed Feb 28 18:30:48 2007 @@ -1,43 +1,37 @@ from pypy.interpreter.pyparser.grammar import Alternative, Sequence, KleeneStar, \ - Token, EmptyToken, build_first_sets + Token, Parser class TestLookAheadBasics: def setup_method(self, method): - self.count = 0 - self.tok1 = Token(self.nextid(), 'foo') - self.tok2 = Token(self.nextid(), 'bar') - self.tok3 = Token(self.nextid(), 'foobar') + self.parser = Parser() + self.tok1 = self.parser.Token_n("t1", 'foo') + self.tok2 = self.parser.Token_n("t2", 'bar') + self.tok3 = self.parser.Token_n("t3", 'foobar') self.tokens = [self.tok1, self.tok2, self.tok3] - build_first_sets(self.tokens) - - def nextid(self): - self.count+=1 - return self.count + self.parser.build_first_sets() def test_basic_token(self): assert self.tok1.first_set == [self.tok1] - def test_basic_alternative(self): - alt = Alternative(self.nextid(), self.tokens) - build_first_sets([alt]) + alt = self.parser.Alternative_n("a1t", self.tokens) + self.parser.build_first_sets() assert alt.first_set == self.tokens def test_basic_sequence(self): - seq = Sequence(self.nextid(), self.tokens) - build_first_sets([seq]) + seq = self.parser.Sequence_n("seq", self.tokens) + self.parser.build_first_sets() assert seq.first_set == [self.tokens[0]] def test_basic_kleenstar(self): tok1, tok2, tok3 = self.tokens - kstar = KleeneStar(self.nextid(), 1, 3, tok1) - build_first_sets([kstar]) - assert kstar.first_set == [tok1] - kstar = KleeneStar(self.nextid(), 0, 3, tok1) - build_first_sets([kstar]) - assert kstar.first_set == [tok1, EmptyToken] + kstar1 = self.parser.KleeneStar_n("k", 1, 3, tok1) + kstar2 = self.parser.KleeneStar_n("k2", 0, 3, tok1) + self.parser.build_first_sets() + assert kstar1.first_set == [tok1] + assert kstar2.first_set == [tok1, self.parser.EmptyToken] def test_maybe_empty_sequence(self): @@ -45,11 +39,11 @@ ==> S.first_set = [tok1, tok2, EmptyToken] """ tok1, tok2, tok3 = self.tokens - k1 = KleeneStar(self.nextid(), 0, 2, tok1) - k2 = KleeneStar(self.nextid(), 0, 2, tok2) - seq = Sequence(self.nextid(), [k1, k2]) - build_first_sets([k1, k2, seq]) - assert seq.first_set == [tok1, tok2, EmptyToken] + k1 = self.parser.KleeneStar_n( "k1", 0, 2, tok1) + k2 = self.parser.KleeneStar_n("k2", 0, 2, tok2) + seq = self.parser.Sequence_n( "seq", [k1, k2]) + self.parser.build_first_sets() + assert seq.first_set == [tok1, tok2, self.parser.EmptyToken] def test_not_empty_sequence(self): @@ -57,41 +51,42 @@ ==> S.first_set = [tok1, tok2] """ tok1, tok2, tok3 = self.tokens - k1 = KleeneStar(self.nextid(), 0, 2, tok1) - k2 = KleeneStar(self.nextid(), 1, 2, tok2) - seq = Sequence(self.nextid(), [k1, k2]) - build_first_sets([k1, k2, seq]) + k1 = self.parser.KleeneStar_n("k1", 0, 2, tok1) + k2 = self.parser.KleeneStar_n("k2", 1, 2, tok2) + seq = self.parser.Sequence_n("seq", [k1, k2]) + self.parser.build_first_sets() assert seq.first_set == [tok1, tok2] -def test_token_comparison(): - assert Token(1, 'foo') == Token(1, 'foo') - assert Token(1, 'foo') != Token(2, 'foo') - assert Token(2, 'foo') != Token(2, None) + def test_token_comparison(self): + tok1 = self.parser.Token_n( "tok1", "foo" ) + tok1b = self.parser.Token_n( "tok1", "foo" ) + tok2 = self.parser.Token_n( "tok2", "foo" ) + tok3 = self.parser.Token_n( "tok2", None ) + assert tok1 == tok1b + assert tok1 != tok2 + assert tok2 != tok3 -LOW = 1 -CAP = 2 -R_A = 3 -R_B = 4 -R_C = 5 -R_k1 = 6 -R_k2 = 7 class TestLookAhead: def setup_method(self, method): - self.LOW = Token(LOW, 'low') - self.CAP = Token(CAP ,'cap') - self.A = Alternative(R_A, []) - k1 = KleeneStar(R_k1, 0, rule=self.LOW) - k2 = KleeneStar(R_k2, 0, rule=self.CAP) - self.B = Sequence(R_B, [k1, self.A]) - self.C = Sequence(R_C, [k2, self.A]) + p = self.parser = Parser() + self.LOW = p.Token_n( 'LOW', 'low') + self.CAP = p.Token_n( 'CAP' ,'cap') + self.A = p.Alternative_n( 'R_A', []) + k1 = p.KleeneStar_n( 'R_k1', 0, rule=self.LOW) + k2 = p.KleeneStar_n( 'R_k2', 0, rule=self.CAP) + self.B = p.Sequence_n( 'R_B', [k1, self.A]) + self.C = p.Sequence_n( 'R_C', [k2, self.A]) self.A.args = [self.B, self.C] - build_first_sets([self.A, self.B, self.C, self.LOW, self.CAP, k1, k2]) + p.build_first_sets() def test_S_first_set(self): - for s in [Token(LOW, 'low'), EmptyToken, Token(CAP, 'cap')]: + p = self.parser + LOW = p.tokens['LOW'] + CAP = p.tokens['CAP'] + for s in [Token(p, LOW, 'low'), p.EmptyToken, Token(p, CAP, 'cap')]: assert s in self.A.first_set assert s in self.B.first_set assert s in self.C.first_set Added: pypy/dist/pypy/interpreter/pyparser/test/test_parser.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/interpreter/pyparser/test/test_parser.py Wed Feb 28 18:30:48 2007 @@ -0,0 +1,45 @@ + +from pypy.interpreter.pyparser.grammar import Parser + + + +def test_symbols(): + p = Parser() + x1 = p.add_symbol('sym') + x2 = p.add_token('tok') + x3 = p.add_anon_symbol(':sym') + x4 = p.add_anon_symbol(':sym1') + # test basic numbering assumption + # symbols and tokens are attributed sequentially + # using the same counter + assert x2 == x1 + 1 + # anon symbols have negative value + assert x3 != x2 + 1 + assert x4 == x3 - 1 + assert x3 < 0 + y1 = p.add_symbol('sym') + assert y1 == x1 + y2 = p.add_token('tok') + assert y2 == x2 + y3 = p.add_symbol(':sym') + assert y3 == x3 + y4 = p.add_symbol(':sym1') + assert y4 == x4 + + +def test_load(): + d = { 5 : 'sym1', + 6 : 'sym2', + 9 : 'sym3', + } + p = Parser() + p.load_symbols( d ) + v = p.add_symbol('sym4') + # check that we avoid numbering conflicts + assert v>9 + v = p.add_symbol( 'sym1' ) + assert v == 5 + v = p.add_symbol( 'sym2' ) + assert v == 6 + v = p.add_symbol( 'sym3' ) + assert v == 9 Modified: pypy/dist/pypy/interpreter/pyparser/test/test_pytokenizer.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/test/test_pytokenizer.py (original) +++ pypy/dist/pypy/interpreter/pyparser/test/test_pytokenizer.py Wed Feb 28 18:30:48 2007 @@ -1,17 +1,26 @@ from pypy.interpreter.pyparser.pythonlexer import Source, TokenError, \ match_encoding_declaration from pypy.interpreter.pyparser.grammar import Token, GrammarElement -from pypy.interpreter.pyparser.pytoken import EQUAL, ENDMARKER, LSQB, MINUS, NAME, NEWLINE, NULLTOKEN, NUMBER, RSQB, STRING +from pypy.interpreter.pyparser.pythonparse import make_pyparser -from pypy.interpreter.pyparser.pytoken import tok_name, tok_punct -GrammarElement.symbols = tok_name +P = make_pyparser() +EQUAL = P.tokens['EQUAL'] +ENDMARKER = P.tokens['ENDMARKER'] +LSQB = P.tokens['LSQB'] +MINUS = P.tokens['MINUS'] +NAME = P.tokens['NAME'] +NEWLINE = P.tokens['NEWLINE'] +NULLTOKEN = P.tokens['NULLTOKEN'] +NUMBER = P.tokens['NUMBER'] +RSQB = P.tokens['RSQB'] +STRING = P.tokens['STRING'] def parse_source(source): """returns list of parsed tokens""" - lexer = Source(source.splitlines(True)) + lexer = Source( P, source.splitlines(True)) tokens = [] - last_token = Token(NULLTOKEN, None) + last_token = Token( P, NULLTOKEN, None) while last_token.codename != ENDMARKER: last_token = lexer.next() tokens.append(last_token) @@ -49,24 +58,24 @@ s = """['a' ]""" tokens = parse_source(s) - assert tokens[:4] == [Token(LSQB, None), Token(STRING, "'a'"), - Token(RSQB, None), Token(NEWLINE, '')] + assert tokens[:4] == [Token(P, LSQB, None), Token(P, STRING, "'a'"), + Token(P, RSQB, None), Token(P, NEWLINE, '')] def test_numbers(): """make sure all kind of numbers are correctly parsed""" for number in NUMBERS: - assert parse_source(number)[0] == Token(NUMBER, number) + assert parse_source(number)[0] == Token(P, NUMBER, number) neg = '-%s' % number - assert parse_source(neg)[:2] == [Token(MINUS, None), - Token(NUMBER, number)] + assert parse_source(neg)[:2] == [Token(P, MINUS, None), + Token(P, NUMBER, number)] for number in BAD_NUMBERS: - assert parse_source(number)[0] != Token(NUMBER, number) + assert parse_source(number)[0] != Token(P, NUMBER, number) def test_hex_number(): """basic pasrse""" tokens = parse_source("a = 0x12L") - assert tokens[:4] == [Token(NAME, 'a'), Token(EQUAL, None), - Token(NUMBER, '0x12L'), Token(NEWLINE, '')] + assert tokens[:4] == [Token(P, NAME, 'a'), Token(P, EQUAL, None), + Token(P, NUMBER, '0x12L'), Token(P, NEWLINE, '')] def test_punct(): """make sure each punctuation is correctly parsed""" @@ -81,7 +90,7 @@ tokens = [tok for tok, _, _, _ in error.token_stack] if prefix: tokens.pop(0) - assert tokens[0].codename == tok_punct[pstr] + assert tokens[0].codename == P.tok_values[pstr] def test_encoding_declarations_match(): Modified: pypy/dist/pypy/interpreter/pyparser/test/test_samples.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/test/test_samples.py (original) +++ pypy/dist/pypy/interpreter/pyparser/test/test_samples.py Wed Feb 28 18:30:48 2007 @@ -6,13 +6,12 @@ import py.test from pypy.interpreter.pyparser.pythonutil import python_parsefile, \ - pypy_parsefile, python_parse, pypy_parse + pypy_parsefile, pypy_parse, python_parse, get_grammar_file, PYTHON_VERSION from pypy.interpreter.pyparser import grammar from pypy.interpreter.pyparser.pythonlexer import TokenError -from pypy.interpreter.pyparser.pythonparse import PYTHON_VERSION, PYPY_VERSION grammar.DEBUG = False - +_, PYPY_VERSION = get_grammar_file("2.4") # these samples are skipped if the native version of Python does not match # the version of the grammar we use GRAMMAR_MISMATCH = PYTHON_VERSION != PYPY_VERSION Modified: pypy/dist/pypy/interpreter/pyparser/tuplebuilder.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/tuplebuilder.py (original) +++ pypy/dist/pypy/interpreter/pyparser/tuplebuilder.py Wed Feb 28 18:30:48 2007 @@ -1,6 +1,5 @@ -from grammar import AbstractBuilder, AbstractContext -from pytoken import tok_name, tok_rpunct, NEWLINE, INDENT, DEDENT, ENDMARKER +from grammar import AbstractBuilder, AbstractContext, Parser class StackElement: """wraps TupleBuilder's tuples""" @@ -53,16 +52,18 @@ class TupleBuilderContext(AbstractContext): def __init__(self, stackpos ): self.stackpos = stackpos - + class TupleBuilder(AbstractBuilder): """A builder that directly produce the AST""" - def __init__(self, rules=None, debug=0, lineno=True): - AbstractBuilder.__init__(self, rules, debug) + def __init__(self, parser, debug=0, lineno=True): + AbstractBuilder.__init__(self, parser, debug) # This attribute is here for convenience self.source_encoding = None self.lineno = lineno self.stack = [] + self.space_token = ( self.parser.tokens['NEWLINE'], self.parser.tokens['INDENT'], + self.parser.tokens['DEDENT'], self.parser.tokens['ENDMARKER'] ) def context(self): """Returns the state of the builder to be restored later""" @@ -80,7 +81,7 @@ nodes = expand_nodes( [self.stack[-1]] ) self.stack[-1] = NonTerminal( rule.codename, nodes ) return True - + def sequence(self, rule, source, elts_number): """ """ num = rule.codename @@ -97,8 +98,8 @@ def token(self, codename, value, source): lineno = source._token_lnum if value is None: - if codename not in ( NEWLINE, INDENT, DEDENT, ENDMARKER ): - value = tok_rpunct.get(codename, "unknown op") + if codename not in self.space_token: + value = self.parser.tok_rvalues.get(codename, "unknown op") else: value = '' self.stack.append( Terminal(codename, value, lineno) ) Modified: pypy/dist/pypy/interpreter/stablecompiler/transformer.py ============================================================================== --- pypy/dist/pypy/interpreter/stablecompiler/transformer.py (original) +++ pypy/dist/pypy/interpreter/stablecompiler/transformer.py Wed Feb 28 18:30:48 2007 @@ -26,9 +26,7 @@ # and replace OWNER, ORGANIZATION, and YEAR as appropriate. # make sure we import the parser with the correct grammar -from pypy.interpreter.pyparser import pythonparse - -import pypy.interpreter.pyparser.pythonparse as pythonparse +from pypy.interpreter.pyparser.pythonparse import make_pyparser from pypy.interpreter.stablecompiler.ast import * import parser @@ -36,15 +34,16 @@ import sys # Create parser from Grammar_stable, not current grammar. -stable_grammar, _ = pythonparse.get_grammar_file("stable") -stable_parser = pythonparse.python_grammar(stable_grammar) +# stable_grammar, _ = pythonparse.get_grammar_file("stable") +# stable_parser = pythonparse.python_grammar(stable_grammar) -sym_name = stable_parser.symbols.sym_name +stable_parser = make_pyparser('stable') class symbol: pass - -for value, name in sym_name.iteritems(): +sym_name = {} +for name, value in stable_parser.symbols.items(): + sym_name[value] = name setattr(symbol, name, value) # transforming is requiring a lot of recursion depth so make sure we have enough @@ -58,6 +57,7 @@ from consts import CO_VARARGS, CO_VARKEYWORDS from consts import OP_ASSIGN, OP_DELETE, OP_APPLY + def parseFile(path): f = open(path, "U") # XXX The parser API tolerates files without a trailing newline, @@ -130,14 +130,15 @@ for value, name in sym_name.items(): if hasattr(self, name): self._dispatch[value] = getattr(self, name) - self._dispatch[token.NEWLINE] = self.com_NEWLINE - self._atom_dispatch = {token.LPAR: self.atom_lpar, - token.LSQB: self.atom_lsqb, - token.LBRACE: self.atom_lbrace, - token.BACKQUOTE: self.atom_backquote, - token.NUMBER: self.atom_number, - token.STRING: self.atom_string, - token.NAME: self.atom_name, + + self._dispatch[stable_parser.tokens['NEWLINE']] = self.com_NEWLINE + self._atom_dispatch = {stable_parser.tokens['LPAR']: self.atom_lpar, + stable_parser.tokens['LSQB']: self.atom_lsqb, + stable_parser.tokens['LBRACE']: self.atom_lbrace, + stable_parser.tokens['BACKQUOTE']: self.atom_backquote, + stable_parser.tokens['NUMBER']: self.atom_number, + stable_parser.tokens['STRING']: self.atom_string, + stable_parser.tokens['NAME']: self.atom_name, } self.encoding = None @@ -206,7 +207,7 @@ def single_input(self, node): # NEWLINE | simple_stmt | compound_stmt NEWLINE n = node[0][0] - if n != token.NEWLINE: + if n != stable_parser.tokens['NEWLINE']: stmt = self.com_stmt(node[0]) else: stmt = Pass() @@ -216,14 +217,13 @@ doc = self.get_docstring(nodelist, symbol.file_input) stmts = [] for node in nodelist: - if node[0] != token.ENDMARKER and node[0] != token.NEWLINE: + if node[0] != stable_parser.tokens['ENDMARKER'] and node[0] != stable_parser.tokens['NEWLINE']: self.com_append_stmt(stmts, node) if doc is not None: assert isinstance(stmts[0], Discard) assert isinstance(stmts[0].expr, Const) del stmts[0] - return Module(doc, Stmt(stmts)) def eval_input(self, nodelist): @@ -238,8 +238,8 @@ item = self.atom_name(nodelist) i = 1 while i < listlen: - assert nodelist[i][0] == token.DOT - assert nodelist[i + 1][0] == token.NAME + assert nodelist[i][0] == stable_parser.tokens['DOT'] + assert nodelist[i + 1][0] == stable_parser.tokens['NAME'] item = Getattr(item, nodelist[i + 1][1]) i += 2 @@ -248,14 +248,14 @@ def decorator(self, nodelist): # '@' dotted_name [ '(' [arglist] ')' ] assert len(nodelist) in (3, 5, 6) - assert nodelist[0][0] == token.AT - assert nodelist[-1][0] == token.NEWLINE + assert nodelist[0][0] == stable_parser.tokens['AT'] + assert nodelist[-1][0] == stable_parser.tokens['NEWLINE'] assert nodelist[1][0] == symbol.dotted_name funcname = self.decorator_name(nodelist[1][1:]) if len(nodelist) > 3: - assert nodelist[2][0] == token.LPAR + assert nodelist[2][0] == stable_parser.tokens['LPAR'] expr = self.com_call_function(funcname, nodelist[3]) else: expr = funcname @@ -328,7 +328,7 @@ # classdef: 'class' NAME ['(' testlist ')'] ':' suite name = nodelist[1][1] doc = self.get_docstring(nodelist[-1]) - if nodelist[2][0] == token.COLON: + if nodelist[2][0] == stable_parser.tokens['COLON']: bases = [] else: bases = self.com_bases(nodelist[3]) @@ -397,7 +397,7 @@ exprNode = self.lookup_node(en)(en[1:]) if len(nodelist) == 1: return Discard(exprNode, lineno=exprNode.lineno) - if nodelist[1][0] == token.EQUAL: + if nodelist[1][0] == stable_parser.tokens['EQUAL']: nodesl = [] for i in range(0, len(nodelist) - 2, 2): nodesl.append(self.com_assign(nodelist[i], OP_ASSIGN)) @@ -414,9 +414,9 @@ if len(nodelist) == 1: start = 1 dest = None - elif nodelist[1][0] == token.RIGHTSHIFT: + elif nodelist[1][0] == stable_parser.tokens['RIGHTSHIFT']: assert len(nodelist) == 3 \ - or nodelist[3][0] == token.COMMA + or nodelist[3][0] == stable_parser.tokens['COMMA'] dest = self.com_node(nodelist[2]) start = 4 else: @@ -424,7 +424,7 @@ start = 1 for i in range(start, len(nodelist), 2): items.append(self.com_node(nodelist[i])) - if nodelist[-1][0] == token.COMMA: + if nodelist[-1][0] == stable_parser.tokens['COMMA']: return Print(items, dest, lineno=nodelist[0][2]) return Printnl(items, dest, lineno=nodelist[0][2]) @@ -482,15 +482,15 @@ assert nodelist[1][0] == symbol.dotted_name assert nodelist[2][1] == 'import' fromname = self.com_dotted_name(nodelist[1]) - if nodelist[3][0] == token.STAR: + if nodelist[3][0] == stable_parser.tokens['STAR']: return From(fromname, [('*', None)], lineno=nodelist[0][2]) else: - if nodelist[3][0] == token.LPAR: + if nodelist[3][0] == stable_parser.tokens['LPAR']: node = nodelist[4] else: node = nodelist[3] - if node[-1][0] == token.COMMA: + if node[-1][0] == stable_parser.tokens['COMMA']: self.syntaxerror("trailing comma not allowed without surrounding parentheses", node) return From(fromname, self.com_import_as_names(node), lineno=nodelist[0][2]) @@ -608,6 +608,7 @@ return self.com_generator_expression(test, nodelist[1]) return self.testlist(nodelist) + def test(self, nodelist): # test: or_test ['if' or_test 'else' test] | lambdef if len(nodelist) == 1: @@ -618,11 +619,13 @@ return self.com_node(nodelist[0]) elif len(nodelist) == 5 and nodelist[1][0] =='if': # Here we implement conditional expressions - return ast.CondExpr(nodelist[2], nodelist[0], nodelist[4], - nodelist[1].lineno) + # XXX: CPython's nodename is IfExp, not CondExpr + return CondExpr(delist[2], nodelist[0], nodelist[4], + nodelist[1].lineno) else: return self.com_binary(Or, nodelist) + def and_test(self, nodelist): # not_test ('and' not_test)* return self.com_binary(And, nodelist) @@ -634,6 +637,9 @@ assert len(nodelist) == 1 return self.com_node(nodelist[0]) + # XXX + # test = old_test + def or_test(self, nodelist): # or_test: and_test ('or' and_test)* return self.com_binary(Or, nodelist) @@ -658,7 +664,7 @@ # comp_op: '<' | '>' | '=' | '>=' | '<=' | '<>' | '!=' | '==' # | 'in' | 'not' 'in' | 'is' | 'is' 'not' n = nl[1] - if n[0] == token.NAME: + if n[0] == stable_parser.tokens['NAME']: type = n[1] if len(nl) == 3: if type == 'not': @@ -695,9 +701,9 @@ node = self.com_node(nodelist[0]) for i in range(2, len(nodelist), 2): right = self.com_node(nodelist[i]) - if nodelist[i-1][0] == token.LEFTSHIFT: + if nodelist[i-1][0] == stable_parser.tokens['LEFTSHIFT']: node = LeftShift([node, right], lineno=nodelist[1][2]) - elif nodelist[i-1][0] == token.RIGHTSHIFT: + elif nodelist[i-1][0] == stable_parser.tokens['RIGHTSHIFT']: node = RightShift([node, right], lineno=nodelist[1][2]) else: raise ValueError, "unexpected token: %s" % nodelist[i-1][0] @@ -707,9 +713,9 @@ node = self.com_node(nodelist[0]) for i in range(2, len(nodelist), 2): right = self.com_node(nodelist[i]) - if nodelist[i-1][0] == token.PLUS: + if nodelist[i-1][0] == stable_parser.tokens['PLUS']: node = Add([node, right], lineno=nodelist[1][2]) - elif nodelist[i-1][0] == token.MINUS: + elif nodelist[i-1][0] == stable_parser.tokens['MINUS']: node = Sub([node, right], lineno=nodelist[1][2]) else: raise ValueError, "unexpected token: %s" % nodelist[i-1][0] @@ -720,13 +726,13 @@ for i in range(2, len(nodelist), 2): right = self.com_node(nodelist[i]) t = nodelist[i-1][0] - if t == token.STAR: + if t == stable_parser.tokens['STAR']: node = Mul([node, right]) - elif t == token.SLASH: + elif t == stable_parser.tokens['SLASH']: node = Div([node, right]) - elif t == token.PERCENT: + elif t == stable_parser.tokens['PERCENT']: node = Mod([node, right]) - elif t == token.DOUBLESLASH: + elif t == stable_parser.tokens['DOUBLESLASH']: node = FloorDiv([node, right]) else: raise ValueError, "unexpected token: %s" % t @@ -738,11 +744,11 @@ t = elt[0] node = self.lookup_node(nodelist[-1])(nodelist[-1][1:]) # need to handle (unary op)constant here... - if t == token.PLUS: + if t == stable_parser.tokens['PLUS']: return UnaryAdd(node, lineno=elt[2]) - elif t == token.MINUS: + elif t == stable_parser.tokens['MINUS']: return UnarySub(node, lineno=elt[2]) - elif t == token.TILDE: + elif t == stable_parser.tokens['TILDE']: node = Invert(node, lineno=elt[2]) return node @@ -751,7 +757,7 @@ node = self.com_node(nodelist[0]) for i in range(1, len(nodelist)): elt = nodelist[i] - if elt[0] == token.DOUBLESTAR: + if elt[0] == stable_parser.tokens['DOUBLESTAR']: return Power([node, self.com_node(nodelist[i+1])], lineno=elt[2]) @@ -765,17 +771,17 @@ return n def atom_lpar(self, nodelist): - if nodelist[1][0] == token.RPAR: + if nodelist[1][0] == stable_parser.tokens['RPAR']: return Tuple(()) return self.com_node(nodelist[1]) def atom_lsqb(self, nodelist): - if nodelist[1][0] == token.RSQB: + if nodelist[1][0] == stable_parser.tokens['RSQB']: 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: + if nodelist[1][0] == stable_parser.tokens['RBRACE']: return Dict(()) return self.com_dictmaker(nodelist[1]) @@ -850,10 +856,10 @@ i = 0 while i < len(nodelist): node = nodelist[i] - if node[0] == token.STAR or node[0] == token.DOUBLESTAR: - if node[0] == token.STAR: + if node[0] == stable_parser.tokens['STAR'] or node[0] == stable_parser.tokens['DOUBLESTAR']: + if node[0] == stable_parser.tokens['STAR']: node = nodelist[i+1] - if node[0] == token.NAME: + if node[0] == stable_parser.tokens['NAME']: name = node[1] if name in names: self.syntaxerror("duplicate argument '%s' in function definition" % @@ -865,7 +871,7 @@ if i < len(nodelist): # should be DOUBLESTAR t = nodelist[i][0] - if t == token.DOUBLESTAR: + if t == stable_parser.tokens['DOUBLESTAR']: node = nodelist[i+1] else: raise ValueError, "unexpected token: %s" % t @@ -891,7 +897,7 @@ self.syntaxerror("non-default argument follows default argument",node) break - if nodelist[i][0] == token.EQUAL: + if nodelist[i][0] == stable_parser.tokens['EQUAL']: defaults.append(self.com_node(nodelist[i + 1])) i = i + 2 elif len(defaults): @@ -905,7 +911,7 @@ def com_fpdef(self, node): # fpdef: NAME | '(' fplist ')' - if node[1][0] == token.LPAR: + if node[1][0] == stable_parser.tokens['LPAR']: return self.com_fplist(node[2]) return node[1][1] @@ -922,7 +928,7 @@ # String together the dotted names and return the string name = "" for n in node: - if type(n) == type(()) and n[0] == 1: + if type(n) == type(()) and n[0] == stable_parser.tokens['NAME']: name = name + n[1] + '.' return name[:-1] @@ -933,7 +939,7 @@ if len(node) == 1: return dot, None assert node[1][1] == 'as' - assert node[2][0] == token.NAME + assert node[2][0] == stable_parser.tokens['NAME'] return dot, node[2][1] def com_dotted_as_names(self, node): @@ -947,11 +953,11 @@ def com_import_as_name(self, node): assert node[0] == symbol.import_as_name node = node[1:] - assert node[0][0] == token.NAME + assert node[0][0] == stable_parser.tokens['NAME'] if len(node) == 1: return node[0][1], None assert node[1][1] == 'as', node - assert node[2][0] == token.NAME + assert node[2][0] == stable_parser.tokens['NAME'] return node[0][1], node[2][1] def com_import_as_names(self, node): @@ -994,7 +1000,7 @@ expr1 = expr2 = None clauses.append((expr1, expr2, self.com_node(nodelist[i+2]))) - if node[0] == token.NAME: + if node[0] == stable_parser.tokens['NAME']: elseNode = self.com_node(nodelist[i+2]) return TryExcept(self.com_node(nodelist[2]), clauses, elseNode, lineno=nodelist[0][2]) @@ -1038,7 +1044,7 @@ primary = self.com_node(node[1]) for i in range(2, len(node)-1): ch = node[i] - if ch[0] == token.DOUBLESTAR: + if ch[0] == stable_parser.tokens['DOUBLESTAR']: self.syntaxerror( "can't assign to operator", node) primary = self.com_apply_trailer(primary, ch) return self.com_assign_trailer(primary, node[-1], @@ -1046,16 +1052,16 @@ node = node[1] elif t == symbol.atom: t = node[1][0] - if t == token.LPAR: + if t == stable_parser.tokens['LPAR']: node = node[2] - if node[0] == token.RPAR: + if node[0] == stable_parser.tokens['RPAR']: self.syntaxerror( "can't assign to ()", node) - elif t == token.LSQB: + elif t == stable_parser.tokens['LSQB']: node = node[2] - if node[0] == token.RSQB: + if node[0] == stable_parser.tokens['RSQB']: self.syntaxerror( "can't assign to []", node) return self.com_assign_list(node, assigning) - elif t == token.NAME: + elif t == stable_parser.tokens['NAME']: if node[1][1] == "__debug__": self.syntaxerror( "can not assign to __debug__", node ) if node[1][1] == "None": @@ -1081,7 +1087,7 @@ if i + 1 < len(node): if node[i + 1][0] == symbol.list_for: self.syntaxerror( "can't assign to list comprehension", node) - assert node[i + 1][0] == token.COMMA, node[i + 1] + assert node[i + 1][0] == stable_parser.tokens['COMMA'], node[i + 1] assigns.append(self.com_assign(node[i], assigning)) return AssList(assigns, lineno=extractLineNo(node)) @@ -1090,11 +1096,11 @@ def com_assign_trailer(self, primary, node, assigning): t = node[1][0] - if t == token.DOT: + if t == stable_parser.tokens['DOT']: return self.com_assign_attr(primary, node[2], assigning) - if t == token.LSQB: + if t == stable_parser.tokens['LSQB']: return self.com_subscriptlist(primary, node[2], assigning) - if t == token.LPAR: + if t == stable_parser.tokens['LPAR']: if assigning==OP_DELETE: self.syntaxerror( "can't delete function call", node) else: @@ -1142,7 +1148,7 @@ assert len(nodelist[i:]) == 1 return self.com_list_comprehension(values[0], nodelist[i]) - elif nodelist[i][0] == token.COMMA: + elif nodelist[i][0] == stable_parser.tokens['COMMA']: continue values.append(self.com_node(nodelist[i])) return List(values, lineno=lineno) @@ -1241,29 +1247,29 @@ def com_apply_trailer(self, primaryNode, nodelist): t = nodelist[1][0] - if t == token.LPAR: + if t == stable_parser.tokens['LPAR']: return self.com_call_function(primaryNode, nodelist[2]) - if t == token.DOT: + if t == stable_parser.tokens['DOT']: return self.com_select_member(primaryNode, nodelist[2]) - if t == token.LSQB: + if t == stable_parser.tokens['LSQB']: return self.com_subscriptlist(primaryNode, nodelist[2], OP_APPLY) self.syntaxerror( 'unknown node type: %s' % t, nodelist[1]) def com_select_member(self, primaryNode, nodelist): - if nodelist[0] != token.NAME: + if nodelist[0] != stable_parser.tokens['NAME']: self.syntaxerror( "member must be a name", nodelist[0]) return Getattr(primaryNode, nodelist[1], lineno=nodelist[2]) def com_call_function(self, primaryNode, nodelist): - if nodelist[0] == token.RPAR: + if nodelist[0] == stable_parser.tokens['RPAR']: return CallFunc(primaryNode, [], lineno=extractLineNo(nodelist)) args = [] kw = 0 len_nodelist = len(nodelist) for i in range(1, len_nodelist, 2): node = nodelist[i] - if node[0] == token.STAR or node[0] == token.DOUBLESTAR: + if node[0] == stable_parser.tokens['STAR'] or node[0] == stable_parser.tokens['DOUBLESTAR']: break kw, result = self.com_argument(node, kw) @@ -1277,7 +1283,7 @@ else: # No broken by star arg, so skip the last one we processed. i = i + 1 - if i < len_nodelist and nodelist[i][0] == token.COMMA: + if i < len_nodelist and nodelist[i][0] == stable_parser.tokens['COMMA']: # need to accept an application that looks like "f(a, b,)" i = i + 1 star_node = dstar_node = None @@ -1285,11 +1291,11 @@ tok = nodelist[i] ch = nodelist[i+1] i = i + 3 - if tok[0]==token.STAR: + if tok[0]==stable_parser.tokens['STAR']: if star_node is not None: self.syntaxerror( 'already have the varargs indentifier', tok ) star_node = self.com_node(ch) - elif tok[0]==token.DOUBLESTAR: + elif tok[0]==stable_parser.tokens['DOUBLESTAR']: if dstar_node is not None: self.syntaxerror( 'already have the kwargs indentifier', tok ) dstar_node = self.com_node(ch) @@ -1308,9 +1314,9 @@ return 0, self.com_node(nodelist[1]) result = self.com_node(nodelist[3]) n = nodelist[1] - while len(n) == 2 and n[0] != token.NAME: + while len(n) == 2 and n[0] != stable_parser.tokens['NAME']: n = n[1] - if n[0] != token.NAME: + if n[0] != stable_parser.tokens['NAME']: self.syntaxerror( "keyword can't be an expression (%s)"%n[0], n) node = Keyword(n[1], result, lineno=n[2]) return 1, node @@ -1324,8 +1330,8 @@ # backwards compat slice for '[i:j]' if len(nodelist) == 2: sub = nodelist[1] - if (sub[1][0] == token.COLON or \ - (len(sub) > 2 and sub[2][0] == token.COLON)) and \ + if (sub[1][0] == stable_parser.tokens['COLON'] or \ + (len(sub) > 2 and sub[2][0] == stable_parser.tokens['COLON'])) and \ sub[-1][0] != symbol.sliceop: return self.com_slice(primary, sub, assigning) @@ -1339,9 +1345,9 @@ # slice_item: expression | proper_slice | ellipsis ch = node[1] t = ch[0] - if t == token.DOT and node[2][0] == token.DOT: + if t == stable_parser.tokens['DOT'] and node[2][0] == stable_parser.tokens['DOT']: return Ellipsis() - if t == token.COLON or len(node) > 2: + if t == stable_parser.tokens['COLON'] or len(node) > 2: return self.com_sliceobj(node) return self.com_node(ch) @@ -1357,7 +1363,7 @@ items = [] - if node[1][0] == token.COLON: + if node[1][0] == stable_parser.tokens['COLON']: items.append(Const(None)) i = 2 else: @@ -1385,7 +1391,7 @@ # short_slice: [lower_bound] ":" [upper_bound] lower = upper = None if len(node) == 3: - if node[1][0] == token.COLON: + if node[1][0] == stable_parser.tokens['COLON']: upper = self.com_node(node[2]) else: lower = self.com_node(node[1]) @@ -1412,7 +1418,7 @@ return self.get_docstring(sub) return None if n == symbol.atom: - if node[0][0] == token.STRING: + if node[0][0] == stable_parser.tokens['STRING']: s = '' for t in node: s = s + eval(t[1]) @@ -1449,13 +1455,13 @@ # comp_op: '<' | '>' | '=' | '>=' | '<=' | '<>' | '!=' | '==' # | 'in' | 'not' 'in' | 'is' | 'is' 'not' _cmp_types = { - token.LESS : '<', - token.GREATER : '>', - token.EQEQUAL : '==', - token.EQUAL : '==', - token.LESSEQUAL : '<=', - token.GREATEREQUAL : '>=', - token.NOTEQUAL : '!=', + stable_parser.tokens['LESS'] : '<', + stable_parser.tokens['GREATER'] : '>', + stable_parser.tokens['EQEQUAL'] : '==', + stable_parser.tokens['EQUAL'] : '==', + stable_parser.tokens['LESSEQUAL'] : '<=', + stable_parser.tokens['GREATEREQUAL'] : '>=', + stable_parser.tokens['NOTEQUAL'] : '!=', } _assign_types = [ @@ -1474,20 +1480,20 @@ symbol.factor, ] -import types -_names = {} -for k, v in sym_name.items(): - _names[k] = v -for k, v in token.tok_name.items(): - _names[k] = v - -def debug_tree(tree): - l = [] - for elt in tree: - if type(elt) == types.IntType: - l.append(_names.get(elt, elt)) - elif type(elt) == types.StringType: - l.append(elt) - else: - l.append(debug_tree(elt)) - return l +# import types +# _names = {} +# for k, v in sym_name.items(): +# _names[k] = v +# for k, v in token.tok_name.items(): +# _names[k] = v +# +# def debug_tree(tree): +# l = [] +# for elt in tree: +# if type(elt) == types.IntType: +# l.append(_names.get(elt, elt)) +# elif type(elt) == types.StringType: +# l.append(elt) +# else: +# l.append(debug_tree(elt)) +# return l Added: pypy/dist/pypy/module/dyngram/__init__.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/dyngram/__init__.py Wed Feb 28 18:30:48 2007 @@ -0,0 +1,12 @@ +"""Mixed module for dynamic grammar modification""" + +from pypy.interpreter.mixedmodule import MixedModule + +class Module(MixedModule): + """dyngram module definition""" + + name = 'dyngram' + appleveldefs = {} + interpleveldefs = { + 'insert_grammar_rule' : 'pypy.interpreter.pycompiler.insert_grammar_rule', + } Modified: pypy/dist/pypy/module/recparser/__init__.py ============================================================================== --- pypy/dist/pypy/module/recparser/__init__.py (original) +++ pypy/dist/pypy/module/recparser/__init__.py Wed Feb 28 18:30:48 2007 @@ -47,7 +47,6 @@ 'source2ast' : "pyparser.source2ast", 'decode_string_literal': 'pyparser.decode_string_literal', 'install_compiler_hook' : 'pypy.interpreter.pycompiler.install_compiler_hook', - 'rules' : 'pypy.interpreter.pyparser.pythonparse.grammar_rules', } # Automatically exports each AST class Modified: pypy/dist/pypy/module/recparser/codegen.py ============================================================================== --- pypy/dist/pypy/module/recparser/codegen.py (original) +++ pypy/dist/pypy/module/recparser/codegen.py Wed Feb 28 18:30:48 2007 @@ -54,7 +54,7 @@ def get_size(self): s = 0 - for i in insns: + for i in self.insns: s += i.size() return s Modified: pypy/dist/pypy/module/recparser/compat.py ============================================================================== --- pypy/dist/pypy/module/recparser/compat.py (original) +++ pypy/dist/pypy/module/recparser/compat.py Wed Feb 28 18:30:48 2007 @@ -1,12 +1,17 @@ """Compatibility layer for CPython's parser module""" -from pythonparse import parse_python_source -from pythonutil import PYTHON_PARSER +from pypy.interpreter.pyparser.tuplebuilder import TupleBuilder +from pythonparse import make_pyparser +from pythonutil import pypy_parse +import symbol # XXX use PYTHON_PARSER.symbols ? from compiler import transformer, compile as pycompile +PYTHON_PARSER = make_pyparser() + def suite( source ): strings = [line+'\n' for line in source.split('\n')] - builder = parse_python_source( strings, PYTHON_PARSER, "file_input" ) + builder = TupleBuilder(PYTHON_PARSER) + PYTHON_PARSER.parse_source(source, 'exec', builder) nested_tuples = builder.stack[-1].as_tuple() if builder.source_encoding is not None: return (symbol.encoding_decl, nested_tuples, builder.source_encoding) @@ -16,7 +21,8 @@ def expr( source ): strings = [line+'\n' for line in source.split('\n')] - builder = parse_python_source( strings, PYTHON_PARSER, "eval_input" ) + builder = TupleBuilder(PYTHON_PARSER) + PYTHON_PARSER.parse_source(source, 'eval', builder) nested_tuples = builder.stack[-1].as_tuple() if builder.source_encoding is not None: return (symbol.encoding_decl, nested_tuples, builder.source_encoding) Added: pypy/dist/pypy/module/recparser/hooksamples/constchanger.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/recparser/hooksamples/constchanger.py Wed Feb 28 18:30:48 2007 @@ -0,0 +1,21 @@ +class ChangeConstVisitor: + def visitConst(self, node): + if node.value == 3: + node.value = 2 + + def defaultvisit(self, node): + for child in node.getChildNodes(): + child.accept(self) + + def __getattr__(self, attrname): + if attrname.startswith('visit'): + return self.defaultvisit + raise AttributeError(attrname) + +def threebecomestwo(ast, enc): + ast.accept(ChangeConstVisitor()) + return ast + +# install the hook +import parser +parser.install_compiler_hook(threebecomestwo) Added: pypy/dist/pypy/module/recparser/hooksamples/tracer.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/recparser/hooksamples/tracer.py Wed Feb 28 18:30:48 2007 @@ -0,0 +1,53 @@ +"""this one logs simple assignments and somewhat clearly shows +that we need a nice API to define "joinpoints". Maybe a SAX-like +(i.e. event-based) API ? + +XXX: crashes on everything else than simple assignment (AssAttr, etc.) +""" + +from parser import ASTPrintnl, ASTConst, ASTName, ASTAssign +from parser import install_compiler_hook, source2ast + +BEFORE_LOG_SOURCE = """if '%s' in locals() or '%s' in globals(): + print '(before) %s <--', locals().get('%s', globals().get('%s', '')) +""" +AFTER_LOG_SOURCE = "print '(after) %s <--', %s" + +def get_statements(source): + module = source2ast(source) + return module.node.nodes + +class Tracer: + def visitModule(self, module): + module.node = module.node.accept(self) + return module + + def default(self, node): + for child in node.getChildNodes(): + # let's cheat a bit + child.parent = node + child.accept(self) + return node + + def visitAssName(self, assname): + assign = assname + while not isinstance(assign, ASTAssign): + assign = assign.parent + stmt = assign.parent + varname = assname.name + before_stmts = get_statements(BEFORE_LOG_SOURCE % ((varname,) * 5)) + after_stmts = get_statements(AFTER_LOG_SOURCE % (varname, varname)) + stmt.insert_before(assign, before_stmts) + stmt.insert_after(assign, after_stmts) + return assname + + def __getattr__(self, attrname): + if attrname.startswith('visit'): + return self.default + raise AttributeError('No such attribute: %s' % attrname) + + +def _trace(ast, enc): + return ast.accept(Tracer()) + +install_compiler_hook(_trace) Modified: pypy/dist/pypy/module/recparser/pyparser.py ============================================================================== --- pypy/dist/pypy/module/recparser/pyparser.py (original) +++ pypy/dist/pypy/module/recparser/pyparser.py Wed Feb 28 18:30:48 2007 @@ -8,11 +8,13 @@ from pypy.interpreter.typedef import interp_attrproperty, GetSetProperty from pypy.interpreter.pycode import PyCode from pypy.interpreter.pyparser.syntaxtree import TokenNode, SyntaxNode, AbstractSyntaxVisitor -from pypy.interpreter.pyparser.pythonutil import PYTHON_PARSER +from pypy.interpreter.pyparser.pythonparse import make_pyparser from pypy.interpreter.pyparser.error import SyntaxError from pypy.interpreter.pyparser import grammar, symbol, pytoken from pypy.interpreter.argument import Arguments +# backward compat (temp) +PYTHON_PARSER = make_pyparser() __all__ = [ "ASTType", "STType", "suite", "expr" ] @@ -43,14 +45,17 @@ def visit_tokennode( self, node ): space = self.space + tokens = space.default_compiler.parser.tokens num = node.name lineno = node.lineno if node.value is not None: val = node.value else: - if num not in ( pytoken.NEWLINE, pytoken.INDENT, - pytoken.DEDENT, pytoken.ENDMARKER ): - val = pytoken.tok_rpunct[num] + if num != tokens['NEWLINE'] and \ + num != tokens['INDENT'] and \ + num != tokens['DEDENT'] and \ + num != tokens['ENDMARKER']: + val = space.default_compiler.parser.tok_rvalues[num] else: val = node.value or '' if self.line_info: @@ -145,11 +150,11 @@ totuple = interp2app(STType.descr_totuple), ) -def parse_python_source(space, source, goal): - builder = grammar.BaseGrammarBuilder(debug=False, rules=PYTHON_PARSER.rules) +def parse_python_source(space, source, mode): + builder = grammar.BaseGrammarBuilder(debug=False, parser=PYTHON_PARSER) builder.space = space try: - PYTHON_PARSER.parse_source(source, goal, builder ) + PYTHON_PARSER.parse_source(source, mode, builder ) return builder.stack[-1] except SyntaxError, e: raise OperationError(space.w_SyntaxError, @@ -157,14 +162,14 @@ def suite( space, source ): # make the annotator life easier (don't use str.splitlines()) - syntaxtree = parse_python_source( space, source, "file_input" ) + syntaxtree = parse_python_source( space, source, "exec" ) return space.wrap( STType(space, syntaxtree) ) suite.unwrap_spec = [ObjSpace, str] def expr( space, source ): # make the annotator life easier (don't use str.splitlines()) - syntaxtree = parse_python_source( space, source, "eval_input" ) + syntaxtree = parse_python_source( space, source, "eval" ) return space.wrap( STType(space, syntaxtree) ) expr.unwrap_spec = [ObjSpace, str] @@ -180,7 +185,7 @@ items = space.unpackiterable( w_sequence ) nodetype = space.int_w( items[0] ) is_syntax = True - if nodetype>=0 and nodetype=0 and nodetype < pytoken.N_TOKENS: is_syntax = False if is_syntax: nodes = [] @@ -201,11 +206,8 @@ def source2ast(space, source): - from pypy.interpreter.pyparser.pythonutil import AstBuilder, PYTHON_PARSER - builder = AstBuilder(space=space) - PYTHON_PARSER.parse_source(source, 'file_input', builder) - ast_tree = builder.rule_stack[-1] - return space.wrap(ast_tree) + from pypy.interpreter.pyparser.pythonutil import source2ast + return space.wrap(source2ast(source, 'exec', space=space)) source2ast.unwrap_spec = [ObjSpace, str] Added: pypy/dist/pypy/module/recparser/test/test_dyn_grammarrules.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/recparser/test/test_dyn_grammarrules.py Wed Feb 28 18:30:48 2007 @@ -0,0 +1,66 @@ +from pypy.conftest import gettestobjspace + +class AppTest_InsertGrammarRules: + def setup_class(cls): + space = gettestobjspace(usemodules=('dyngram', 'recparser')) + cls.space = space + + def test_do_while(self): + import dyngram, parser + + newrules = """ + compound_stmt: if_stmt | on_stmt | unless_stmt | dountil_stmt | while_stmt | for_stmt | try_stmt | with_stmt | funcdef | classdef + dountil_stmt: 'do' ':' suite 'until' test + unless_stmt: 'unless' test ':' suite + on_stmt: 'on' NAME '=' test ':' suite ['else' ':' suite] + """ + + def build_dountil_stmt(items): + """ 'do' ':' suite 'until' ':' test """ + lineno = items[0].lineno + suite = items[2] + test = items[-1] + while_stmt = parser.ASTWhile(parser.ASTNot(test), suite, None, lineno) + return parser.ASTStmt([suite, while_stmt], lineno) + + def build_unless_stmt(its): + """ 'unless' test ':' suite """ + lineno = its[0].lineno + return parser.ASTIf([(parser.ASTNot(its[1]), its[3])], None, lineno) + + def make_assignment(var, node): + # XXX: consts.OP_APPLY + return parser.ASTAssign([parser.ASTAssName('x', 0)], node) + + def build_on_stmt(items): + """ 'on' NAME = test ':' suite 'else' ':' suite""" + varname = items[1].value + test = items[3] + suite = items[5] + assign = make_assignment(varname, test) + if len(items) == 9: + else_ = items[-1] + else: + else_ = None + test = parser.ASTIf([(parser.ASTName(varname), suite)], else_, items[0].lineno) + return parser.ASTStmt([assign, test], items[0].lineno) + + dyngram.insert_grammar_rule(newrules, {'dountil_stmt' : build_dountil_stmt, + 'unless_stmt': build_unless_stmt, + 'on_stmt' : build_on_stmt, + }) + + # now we should be able to use do...until and unless statements + d = {} + exec ''' +a = 0 +do: + a += 1 +until True + +b = 0 +unless a == 2: b = 3 + ''' in d + assert d['a'] == 1 + assert d['b'] == 3 + Modified: pypy/dist/pypy/module/recparser/test/test_parser.py ============================================================================== --- pypy/dist/pypy/module/recparser/test/test_parser.py (original) +++ pypy/dist/pypy/module/recparser/test/test_parser.py Wed Feb 28 18:30:48 2007 @@ -15,3 +15,8 @@ def test_enc_minimal(self): import parser parser.suite("# -*- coding: koi8-u -*-*\ngreat()") + + def test_simple_ass_totuple(self): + import parser + parser.suite("a = 3").totuple() + From afayolle at codespeak.net Wed Feb 28 18:36:55 2007 From: afayolle at codespeak.net (afayolle at codespeak.net) Date: Wed, 28 Feb 2007 18:36:55 +0100 (CET) Subject: [pypy-svn] r39611 - pypy/dist/pypy/module/symbol Message-ID: <20070228173655.1A31A10123@code0.codespeak.net> Author: afayolle Date: Wed Feb 28 18:36:53 2007 New Revision: 39611 Modified: pypy/dist/pypy/module/symbol/__init__.py Log: forgot one file in the previous checkin Modified: pypy/dist/pypy/module/symbol/__init__.py ============================================================================== --- pypy/dist/pypy/module/symbol/__init__.py (original) +++ pypy/dist/pypy/module/symbol/__init__.py Wed Feb 28 18:36:53 2007 @@ -12,19 +12,19 @@ class Module(MixedModule): - """Non-terminal symbols of Python grammar.""" - - appleveldefs = {} - interpleveldefs = {} # see below + """Non-terminal symbols of Python grammar.""" + appleveldefs = {} + interpleveldefs = {} # see below # Export the values from our custom symbol module. # Skip negative values (the corresponding symbols are not visible in # pure Python). -from pypy.interpreter.pyparser.pythonparse import PYTHON_PARSER +from pypy.interpreter.pyparser.pythonparse import make_pyparser +parser = make_pyparser() sym_name = {} -for val, name in PYTHON_PARSER.symbols.sym_name.items(): +for name, val in parser.symbols.items(): if val >= 0: Module.interpleveldefs[name] = 'space.wrap(%d)' % val sym_name[val] = name From afayolle at codespeak.net Wed Feb 28 18:46:04 2007 From: afayolle at codespeak.net (afayolle at codespeak.net) Date: Wed, 28 Feb 2007 18:46:04 +0100 (CET) Subject: [pypy-svn] r39612 - pypy/branch/ast-experiments Message-ID: <20070228174604.A825110123@code0.codespeak.net> Author: afayolle Date: Wed Feb 28 18:46:02 2007 New Revision: 39612 Removed: pypy/branch/ast-experiments/ Log: branch merged with the main trunk From fijal at codespeak.net Wed Feb 28 23:19:31 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 28 Feb 2007 23:19:31 +0100 (CET) Subject: [pypy-svn] r39617 - pypy/extradoc/talk/rupy2007 Message-ID: <20070228221931.C85701011A@code0.codespeak.net> Author: fijal Date: Wed Feb 28 23:19:29 2007 New Revision: 39617 Modified: pypy/extradoc/talk/rupy2007/abstract.txt Log: Version send Modified: pypy/extradoc/talk/rupy2007/abstract.txt ============================================================================== --- pypy/extradoc/talk/rupy2007/abstract.txt (original) +++ pypy/extradoc/talk/rupy2007/abstract.txt Wed Feb 28 23:19:29 2007 @@ -1,6 +1,16 @@ +Speakers: Armin Rigo, Maciej Fijalkowski + Title: PyPy, the implementation of Python in Python -Abstract: We'd like to present the PyPy project, which is both -very very flexible compiler toolchain, which translates restricted subset -of python to variety of languages (C, LLVM, CLI, JVM, JavaScript...) and -implementation of a Python interpreter, with many novel features, including + +Abstract: We'd like to present the PyPy project, which is both: + +- A very very flexible compiler toolchain, which translates a restricted subset +of Python to a variety of languages (C, LLVM, CLI, JVM, JavaScript...) + +- An implementation of a Python interpreter, with many novel features, including Psyco-style specializing JIT, stackless-like coroutines and many others. + +The PyPy project has been funded for the last two years by the EU + +The PyPy is open source project, for more details about it see http://codespeak.net/pypy +