From santagada at codespeak.net Thu Mar 1 12:11:29 2007 From: santagada at codespeak.net (santagada at codespeak.net) Date: Thu, 1 Mar 2007 12:11:29 +0100 (CET) Subject: [pypy-svn] r39622 - in pypy/dist/pypy/lang/js: . js test/ecma Message-ID: <20070301111129.129EB10121@code0.codespeak.net> Author: santagada Date: Thu Mar 1 12:11:27 2007 New Revision: 39622 Modified: pypy/dist/pypy/lang/js/interpreter.py pypy/dist/pypy/lang/js/js/jsparse.js pypy/dist/pypy/lang/js/jsobj.py pypy/dist/pypy/lang/js/jsparser.py pypy/dist/pypy/lang/js/test/ecma/conftest.py pypy/dist/pypy/lang/js/test/ecma/shell.js Log: parser corrections, equality operator fully to the spec, py.test runner that reports why test failed, and some other misc changes Modified: pypy/dist/pypy/lang/js/interpreter.py ============================================================================== --- pypy/dist/pypy/lang/js/interpreter.py (original) +++ pypy/dist/pypy/lang/js/interpreter.py Thu Mar 1 12:11:27 2007 @@ -184,6 +184,7 @@ #Math w_math = W_Object(Class='Math') w_Global.Put('Math', w_math) + w_math.Put('__proto__', w_ObjPrototype) 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)) @@ -528,8 +529,49 @@ def AEC(x, y): """ Implements the Abstract Equality Comparison x == y - not following the specs yet + trying to be fully to the spec """ + type1 = x.type() + type2 = y.type() + if type1 == type2: + if type1 == "undefined" or type1 == "null": + return True + if type1 == "number": + n1 = x.ToNumber() + n2 = y.ToNumber() + nan_string = str(NaN) + if str(n1) == nan_string or str(n2) == nan_string: + return False + if n1 == n2: + return True + return False + elif type1 == "string": + return x.ToString() == y.ToString() + elif type1 == "boolean": + return x.ToBoolean() == x.ToBoolean() + return x == y + else: + #step 14 + if (type1 == "undefined" and type2 == "null") or \ + (type1 == "null" and type2 == "undefined"): + return True + if type1 == "number" and type2 == "string": + return AEC(x, W_Number(y.ToNumber())) + if type1 == "string" and type2 == "number": + return AEC(W_Number(x.ToNumber()), y) + if type1 == "boolean": + return AEC(W_Number(x.ToNumber()), y) + if type2 == "boolean": + return AEC(x, W_Number(y.ToNumber())) + if (type1 == "string" or type1 == "number") and \ + type2 == "object": + return AEC(x, y.ToPrimitive()) + if (type2 == "string" or type2 == "number") and \ + type1 == "object": + return AEC(x.ToPrimitive(), y) + return False + + objtype = x.GetValue().type() if objtype == y.GetValue().type(): if objtype == "undefined" or objtype == "null": Modified: pypy/dist/pypy/lang/js/js/jsparse.js ============================================================================== --- pypy/dist/pypy/lang/js/js/jsparse.js (original) +++ pypy/dist/pypy/lang/js/js/jsparse.js Thu Mar 1 12:11:27 2007 @@ -297,7 +297,7 @@ } if(typeof a[i].value == 'string'){ - val = a[i].value.replace(/'/g, "\\'") + val = a[i].value.replace(/\\/g, "\\\\").replace(/'/g, "\\'") } else { val = a[i].value+ ""; } Modified: pypy/dist/pypy/lang/js/jsobj.py ============================================================================== --- pypy/dist/pypy/lang/js/jsobj.py (original) +++ pypy/dist/pypy/lang/js/jsobj.py Thu Mar 1 12:11:27 2007 @@ -202,12 +202,12 @@ def internal_def_value(self, ctx, tryone, trytwo): t1 = self.Get(tryone) - if isinstance(t1, W_Object): + if isinstance(t1, W_PrimitiveObject): val = t1.Call(ctx, this=self) if isinstance(val, W_Primitive): return val t2 = self.Get(trytwo) - if isinstance(t2, W_Object): + if isinstance(t2, W_PrimitiveObject): val = t2.Call(ctx, this=self) if isinstance(val, W_Primitive): return val Modified: pypy/dist/pypy/lang/js/jsparser.py ============================================================================== --- pypy/dist/pypy/lang/js/jsparser.py (original) +++ pypy/dist/pypy/lang/js/jsparser.py Thu Mar 1 12:11:27 2007 @@ -44,12 +44,15 @@ retval = pipe.read() if not retval.startswith("{"): raise JsSyntaxError(retval) + if DEBUG: + print "received back:" + print retval return retval def unquote(t): if isinstance(t, Symbol): if t.symbol == "QUOTED_STRING": - t.additional_info = t.additional_info.strip("'").replace("\\'", "'") + t.additional_info = t.additional_info[1:-1].replace("\\'", "'").replace("\\\\", "\\") else: for i in t.children: unquote(i) @@ -68,7 +71,7 @@ return tree regexs, rules, ToAST = parse_ebnf(r""" - QUOTED_STRING: "'([^\']|\\\')*'";"""+""" + QUOTED_STRING: "'([^\\\']|\\[\\\'])*'";"""+""" IGNORE: " |\n"; data: | | ; dict: ["{"] (dictentry [","])* dictentry ["}"]; 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 Mar 1 12:11:27 2007 @@ -77,9 +77,13 @@ def run(self): ctx = JSTestFile.interp.global_context r3 = ctx.resolve_identifier('run_test').GetValue() - result = r3.Call(ctx=ctx, args=[W_Number(self.number),]).ToNumber() + w_test_array = ctx.resolve_identifier('testcases').GetValue() + w_test_number = W_Number(self.number) + result = r3.Call(ctx=ctx, args=[w_test_number,]).ToNumber() if result == 0: - raise Failed(msg="Results don't match") + w_test = w_test_array.Get(str(self.number)).GetValue() + w_reason = w_test.Get('reason').GetValue() + raise Failed(msg=w_reason.ToString()) elif result == -1: py.test.skip() 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 Thu Mar 1 12:11:27 2007 @@ -196,7 +196,8 @@ function run_test(tc) { // try { getTestCaseResult(testcases[tc].expect, testcases[tc].actual) - testcases[tc].reason += ( testcases[tc].passed ) ? "" : "wrong value "; + testcases[tc].reason += ( testcases[tc].passed ) ? "" : "wrong value expected: " + +testcases[tc].expect+" but got: "+ testcases[tc].actual; return testcases[tc].passed? 1:0; // } // catch(e) { From fijal at codespeak.net Thu Mar 1 12:31:03 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 1 Mar 2007 12:31:03 +0100 (CET) Subject: [pypy-svn] r39623 - pypy/dist/pypy/translator/goal Message-ID: <20070301113103.2867610107@code0.codespeak.net> Author: fijal Date: Thu Mar 1 12:31:01 2007 New Revision: 39623 Modified: pypy/dist/pypy/translator/goal/targetpypystandalone.py Log: Kill debug a bit Modified: pypy/dist/pypy/translator/goal/targetpypystandalone.py ============================================================================== --- pypy/dist/pypy/translator/goal/targetpypystandalone.py (original) +++ pypy/dist/pypy/translator/goal/targetpypystandalone.py Thu Mar 1 12:31:01 2007 @@ -12,13 +12,16 @@ thisdir = py.magic.autopath().dirpath() app_basic_example_path = str(thisdir.join("app_basic_example.py")) +DEBUG = False + try: this_dir = os.path.dirname(__file__) except NameError: this_dir = os.path.dirname(sys.argv[0]) -def debug(msg): - os.write(2, "debug: " + msg + '\n') +def debug(msg): + if DEBUG: + os.write(2, "debug: " + msg + '\n') # __________ Entry point __________ From santagada at codespeak.net Thu Mar 1 12:40:50 2007 From: santagada at codespeak.net (santagada at codespeak.net) Date: Thu, 1 Mar 2007 12:40:50 +0100 (CET) Subject: [pypy-svn] r39624 - in pypy/dist/pypy/lang/js: . test Message-ID: <20070301114050.96B7910123@code0.codespeak.net> Author: santagada Date: Thu Mar 1 12:40:47 2007 New Revision: 39624 Modified: pypy/dist/pypy/lang/js/interpreter.py pypy/dist/pypy/lang/js/test/test_interp.py Log: strict equality Modified: pypy/dist/pypy/lang/js/interpreter.py ============================================================================== --- pypy/dist/pypy/lang/js/interpreter.py (original) +++ pypy/dist/pypy/lang/js/interpreter.py Thu Mar 1 12:40:47 2007 @@ -595,6 +595,44 @@ def decision(self, ctx, op1, op2): return W_Boolean(not AEC(op1, op2)) +def SEC(x,y): + """ + Implements the Strict Equality Comparison x === y + trying to be fully to the spec + """ + type1 = x.type() + type2 = y.type() + if type1 != type2: + return False + if type1 == "undefined" or type1 == "null": + return True + if type1 == "number": + n1 = x.ToNumber() + n2 = y.ToNumber() + nan_string = str(NaN) + if str(n1) == nan_string or str(n2) == nan_string: + return False + if n1 == n2: + return True + return False + if type1 == "string": + return x.ToString() == y.ToString() + if type1 == "boolean": + return x.ToBoolean() == x.ToBoolean() + return x == y + +class StrictEq(BinaryComparisonOp): + opcode = 'STRICT_EQ' + + def decision(self, ctx, op1, op2): + return W_Boolean(SEC(op1, op2)) + +class StrictNe(BinaryComparisonOp): + opcode = 'STRICT_NE' + + def decision(self, ctx, op1, op2): + return W_Boolean(not SEC(op1, op2)) + class In(BinaryComparisonOp): opcode = 'IN' 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 Mar 1 12:40:47 2007 @@ -470,3 +470,11 @@ print(y) } """, ['5',]) + + def test_stricteq(self): + self.assert_prints(""" + print(2 === 2) + print(2 === 3) + print(2 !== 3) + print(2 !== 2) + """, ['true', 'false', 'true', 'false']) From santagada at codespeak.net Thu Mar 1 12:47:26 2007 From: santagada at codespeak.net (santagada at codespeak.net) Date: Thu, 1 Mar 2007 12:47:26 +0100 (CET) Subject: [pypy-svn] r39626 - pypy/dist/pypy/lang/js/test Message-ID: <20070301114726.BF2CE10123@code0.codespeak.net> Author: santagada Date: Thu Mar 1 12:47:23 2007 New Revision: 39626 Removed: pypy/dist/pypy/lang/js/test/autotestbase.py Modified: pypy/dist/pypy/lang/js/test/test_parser.py Log: started testing the parser again Modified: pypy/dist/pypy/lang/js/test/test_parser.py ============================================================================== --- pypy/dist/pypy/lang/js/test/test_parser.py (original) +++ pypy/dist/pypy/lang/js/test/test_parser.py Thu Mar 1 12:47:23 2007 @@ -2,30 +2,9 @@ from pypy.lang.js.test.test_interp import js_is_on_path import py -py.test.skip("FIX ME: new tests for the new parser") js_is_on_path() -def test_read_js_output(): - assert read_js_output("1+1").find("PLUS") > -1 - assert read_js_output(""" - function f(x) { - return (x); - } - """).find("RETURN") != -1 - py.test.raises(JsSyntaxError, "read_js_output(\"1+\")") - py.test.raises(JsSyntaxError, "read_js_output(\"xx xxx\")") - -def test_simple_parse(): - data = parse("1+1") - assert data['type'] == 'SCRIPT' - assert data['0']['type'] == 'SEMICOLON' - data = parse("function s(x) { return 1;}") - assert data['0']['body']['0']['value']['value'] == '1' - assert sorted(data.keys()) == ['0', 'funDecls', 'length', 'lineno', \ - 'tokenizer', 'type', 'varDecls'] - -def test_single_quote(): - "test if parser eats single quotes" - data = parse("x = '2'") - assert data['type'] == 'SCRIPT' +def test_quoting(): + read_js_output('x = "\'"') + read_js_output('x = "\\\\"') \ No newline at end of file From fijal at codespeak.net Thu Mar 1 13:46:42 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 1 Mar 2007 13:46:42 +0100 (CET) Subject: [pypy-svn] r39627 - pypy/dist/pypy/module/_ssl Message-ID: <20070301124642.F17D710117@code0.codespeak.net> Author: fijal Date: Thu Mar 1 13:46:41 2007 New Revision: 39627 Modified: pypy/dist/pypy/module/_ssl/__init__.py Log: (fijal, arigo, guido_w) - Raise import error instead of py.test.skip to be able to import socket on top of py.py Modified: pypy/dist/pypy/module/_ssl/__init__.py ============================================================================== --- pypy/dist/pypy/module/_ssl/__init__.py (original) +++ pypy/dist/pypy/module/_ssl/__init__.py Thu Mar 1 13:46:41 2007 @@ -1,6 +1,7 @@ -import py # FINISHME - more thinking needed -py.test.skip("The _ssl module is only usable when running on the exact " - "same platform from which the ssl.py was computed.") +#import py # FINISHME - more thinking needed +raise ImportError +#skip("The _ssl module is only usable when running on the exact " +# "same platform from which the ssl.py was computed.") # This module is imported by socket.py. It should *not* be used # directly. From fijal at codespeak.net Thu Mar 1 13:47:56 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 1 Mar 2007 13:47:56 +0100 (CET) Subject: [pypy-svn] r39628 - in pypy/dist/pypy/module/rsocket: . test Message-ID: <20070301124756.D1BF410117@code0.codespeak.net> Author: fijal Date: Thu Mar 1 13:47:54 2007 New Revision: 39628 Modified: pypy/dist/pypy/module/rsocket/interp_socket.py pypy/dist/pypy/module/rsocket/test/test_sock_app.py Log: (fijal, arigo, guido_w) Have errno as an argument of exception rather than a field. A bit more cpython compliant Modified: pypy/dist/pypy/module/rsocket/interp_socket.py ============================================================================== --- pypy/dist/pypy/module/rsocket/interp_socket.py (original) +++ pypy/dist/pypy/module/rsocket/interp_socket.py Thu Mar 1 13:47:54 2007 @@ -443,9 +443,11 @@ message = e.get_msg() w_module = space.getbuiltinmodule('_socket') w_exception_class = space.getattr(w_module, space.wrap(e.applevelerrcls)) - w_exception = space.call_function(w_exception_class, space.wrap(message)) if isinstance(e, SocketErrorWithErrno): - space.setattr(w_exception, space.wrap('errno'), space.wrap(e.errno)) + w_exception = space.call_function(w_exception_class, space.wrap(e.errno), + space.wrap(message)) + else: + w_exception = space.call_function(w_exception_class, space.wrap(message)) return OperationError(w_exception_class, w_exception) # ____________________________________________________________ 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 Thu Mar 1 13:47:54 2007 @@ -351,7 +351,6 @@ import socket s = socket.socket() - def test_getsetsockopt(self): import _socket as socket import struct @@ -423,3 +422,21 @@ foo = self.serv.accept() raises(error, raise_error) + +class AppTestErrno: + def setup_class(cls): + cls.space = space + + def test_errno(self): + from socket import socket, AF_INET, SOCK_STREAM, error + import errno + try: + s = socket(AF_INET, SOCK_STREAM) + import pypymagic + print pypymagic.pypy_repr(s) + s.accept() + except Exception, e: + assert len(e.args) == 2 + assert e.args[0] == errno.EINVAL + assert isinstance(e.args[1], str) + From rxe at codespeak.net Thu Mar 1 13:52:22 2007 From: rxe at codespeak.net (rxe at codespeak.net) Date: Thu, 1 Mar 2007 13:52:22 +0100 (CET) Subject: [pypy-svn] r39629 - pypy/dist/pypy/tool Message-ID: <20070301125222.8FED210117@code0.codespeak.net> Author: rxe Date: Thu Mar 1 13:52:21 2007 New Revision: 39629 Modified: pypy/dist/pypy/tool/slaveproc.py Log: make closing pipe more explicit Modified: pypy/dist/pypy/tool/slaveproc.py ============================================================================== --- pypy/dist/pypy/tool/slaveproc.py (original) +++ pypy/dist/pypy/tool/slaveproc.py Thu Mar 1 13:52:21 2007 @@ -22,6 +22,17 @@ raise EOFError return marshal.loads(s) + def forceclose(self): + try: + self.out.close() + except: + pass + + try: + self.inp.close() + except: + pass + class SlaveProcess(object): _broken = False @@ -40,6 +51,7 @@ def close(self): if not self._broken: assert self.cmd(None) == 'done' + self.exchg.forceclose() class Slave(object): From santagada at codespeak.net Thu Mar 1 14:05:56 2007 From: santagada at codespeak.net (santagada at codespeak.net) Date: Thu, 1 Mar 2007 14:05:56 +0100 (CET) Subject: [pypy-svn] r39630 - pypy/dist/pypy/lang/js/test/ecma Message-ID: <20070301130556.413AD1011A@code0.codespeak.net> Author: santagada Date: Thu Mar 1 14:05:55 2007 New Revision: 39630 Modified: pypy/dist/pypy/lang/js/test/ecma/conftest.py pypy/dist/pypy/lang/js/test/ecma/shell.js Log: tests finally run well I think 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 Mar 1 14:05:55 2007 @@ -30,12 +30,16 @@ class JSTestFile(py.test.collect.Module): def init_interp(cls): if hasattr(cls, 'interp'): - return + cls.testcases.PutValue(W_Array(), cls.interp.global_context) + cls.tc.PutValue(W_Number(0), cls.interp.global_context) + cls.interp = Interpreter() ctx = cls.interp.global_context shellpath = rootdir/'shell.js' t = load_source(shellpath.read()) t.execute(ctx) + cls.testcases = cls.interp.global_context.resolve_identifier('testcases') + cls.tc = cls.interp.global_context.resolve_identifier('tc') init_interp = classmethod(init_interp) def __init__(self, fspath, parent=None): @@ -58,18 +62,15 @@ except JsBaseExcept: raise Failed(msg="Javascript Error", excinfo=py.code.ExceptionInfo()) testcases = self.interp.global_context.resolve_identifier('testcases') + self.tc = self.interp.global_context.resolve_identifier('tc') testcount = testcases.GetValue().Get('length').GetValue().ToNumber() self.testcases = testcases - # result = [str(i) for i in range(len(values))] return range(testcount) 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): +class JSTestItem(py.test.collect.Item): def __init__(self, number, parent=None): super(JSTestItem, self).__init__(str(number), parent) self.number = number @@ -77,13 +78,10 @@ def run(self): ctx = JSTestFile.interp.global_context r3 = ctx.resolve_identifier('run_test').GetValue() - w_test_array = ctx.resolve_identifier('testcases').GetValue() w_test_number = W_Number(self.number) - result = r3.Call(ctx=ctx, args=[w_test_number,]).ToNumber() - if result == 0: - w_test = w_test_array.Get(str(self.number)).GetValue() - w_reason = w_test.Get('reason').GetValue() - raise Failed(msg=w_reason.ToString()) + result = r3.Call(ctx=ctx, args=[w_test_number,]).GetValue().ToString() + if result != "passed": + raise Failed(msg=result) elif result == -1: py.test.skip() 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 Thu Mar 1 14:05:55 2007 @@ -81,7 +81,8 @@ this.passed = getTestCaseResult( this.expect, this.actual ); if ( DEBUG ) { - print( "added " + this.description + " wich expects " + this.expect); + print( "added " + this.description + " wich expects " + this.expect + + " nr "+tc); } /* * testcases are solely maintained in the TestCase @@ -196,9 +197,9 @@ function run_test(tc) { // try { getTestCaseResult(testcases[tc].expect, testcases[tc].actual) - testcases[tc].reason += ( testcases[tc].passed ) ? "" : "wrong value expected: " + testcases[tc].reason += ( testcases[tc].passed ) ? "passed" : "wrong value expected: " +testcases[tc].expect+" but got: "+ testcases[tc].actual; - return testcases[tc].passed? 1:0; + return testcases[tc].reason; // } // catch(e) { // return -1; From fijal at codespeak.net Thu Mar 1 15:03:09 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 1 Mar 2007 15:03:09 +0100 (CET) Subject: [pypy-svn] r39632 - pypy/dist/pypy/lib/distributed/test Message-ID: <20070301140309.CF8E410117@code0.codespeak.net> Author: fijal Date: Thu Mar 1 15:03:08 2007 New Revision: 39632 Modified: pypy/dist/pypy/lib/distributed/test/test_distributed.py Log: Fix tests a bit 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 Thu Mar 1 15:03:08 2007 @@ -69,12 +69,36 @@ assert isinstance(fun, types.FunctionType) assert fun(2, 3) == 5 + def test_local_obj(self): + class A: + def __init__(self, x): + self.x = x + + def __len__(self): + return self.x + 8 + + from distributed.protocol import LocalProtocol + protocol = LocalProtocol() + wrap = protocol.wrap + unwrap = protocol.unwrap + item = unwrap(wrap(A(3))) + assert item.x == 3 + assert len(item) == 11 + +class AppTestDistributedTasklets(object): + def setup_class(cls): + cls.space = gettestobjspace(**{"objspace.std.withtproxy": True, + "usemodules":("_stackless",)}) + cls.w_test_env = cls.space.appexec([], """(): + from distributed import test_env + return test_env + """) + def test_remote_protocol_call(self): def f(x, y): return x + y - from distributed import test_env - protocol = test_env({"f": f}) + protocol = self.test_env({"f": f}) fun = protocol.get_remote("f") assert fun(2, 3) == 5 @@ -85,38 +109,20 @@ def f(x): return x + g() - from distributed import test_env - protocol = test_env({"f":f}) + protocol = self.test_env({"f":f}) fun = protocol.get_remote("f") assert fun(8) == 16 def test_remote_dict(self): #skip("Land of infinite recursion") - from distributed import test_env d = {'a':3} - protocol = test_env({'d':d}) + protocol = self.test_env({'d':d}) xd = protocol.get_remote('d') #assert d['a'] == xd['a'] assert d.keys() == xd.keys() assert d.values() == xd.values() assert d == xd - def test_local_obj(self): - class A: - def __init__(self, x): - self.x = x - - def __len__(self): - return self.x + 8 - - from distributed.protocol import LocalProtocol - protocol = LocalProtocol() - wrap = protocol.wrap - unwrap = protocol.unwrap - item = unwrap(wrap(A(3))) - assert item.x == 3 - assert len(item) == 11 - def test_remote_obj(self): class A: def __init__(self, x): @@ -126,8 +132,7 @@ return self.x + 8 a = A(3) - from distributed import test_env - protocol = test_env({'a':a}) + protocol = self.test_env({'a':a}) xa = protocol.get_remote("a") assert xa.x == 3 assert len(xa) == 11 @@ -146,8 +151,7 @@ a = A() - from distributed import test_env - protocol = test_env({'a':a}) + protocol = self.test_env({'a':a}) xa = protocol.get_remote('a') assert xa.__class__.__doc__ == 'xxx' assert xa.meth(x) == 4 @@ -164,9 +168,8 @@ def __call__(self): return [1,2,3] - from distributed import test_env a = A() - protocol = test_env({'a': a}) + protocol = self.test_env({'a': a}) xa = protocol.get_remote('a') xa.meth(B()) assert xa.perform() == 4 @@ -174,20 +177,17 @@ def test_frame(self): #skip("Land of infinite recursion") import sys - from distributed import test_env f = sys._getframe() - protocol = test_env({'f':f}) + protocol = self.test_env({'f':f}) xf = protocol.get_remote('f') assert f.f_globals.keys() == xf.f_globals.keys() assert f.f_locals.keys() == xf.f_locals.keys() def test_remote_exception(self): - from distributed import test_env - def raising(): 1/0 - protocol = test_env({'raising':raising}) + protocol = self.test_env({'raising':raising}) xr = protocol.get_remote('raising') try: xr() @@ -200,11 +200,9 @@ def test_instantiate_remote_type(self): skip("Land of infinite recursion") - from distributed import test_env - class C: pass - protocol = test_env({'C':C}) + protocol = self.test_env({'C':C}) xC = protocol.get_remote('C') xC() From fijal at codespeak.net Thu Mar 1 15:03:44 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 1 Mar 2007 15:03:44 +0100 (CET) Subject: [pypy-svn] r39633 - pypy/dist/pypy/lib/distributed/demo Message-ID: <20070301140344.D5CA910117@code0.codespeak.net> Author: fijal Date: Thu Mar 1 15:03:42 2007 New Revision: 39633 Added: pypy/dist/pypy/lib/distributed/demo/gsock.py Log: (fijal, guido) add a cool demo about lib/distributed Added: pypy/dist/pypy/lib/distributed/demo/gsock.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/lib/distributed/demo/gsock.py Thu Mar 1 15:03:42 2007 @@ -0,0 +1,38 @@ + +from distributed import RemoteProtocol, remote_loop + +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) + +def remote(): + from distributed.socklayer import socket_listener + send, receive = socket_listener() + remote_loop(RemoteProtocol(send, receive, globals())) + +def local(): + from distributed.socklayer import socket_connecter + send, receive = socket_connecter(('localhost', 12121)) + return RemoteProtocol(send, receive) + +import sys +if __name__ == '__main__': + if len(sys.argv) > 1 and sys.argv[1] == '-r': + remote() + else: + rp = local() + x = rp.get_remote("x") + try: + x.raising() + except: + import sys + import pdb + pdb.post_mortem(sys.exc_info()[2]) From fijal at codespeak.net Thu Mar 1 15:06:06 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 1 Mar 2007 15:06:06 +0100 (CET) Subject: [pypy-svn] r39634 - pypy/dist/pypy/lib/distributed Message-ID: <20070301140606.5AE051011E@code0.codespeak.net> Author: fijal Date: Thu Mar 1 15:06:04 2007 New Revision: 39634 Added: pypy/dist/pypy/lib/distributed/socklayer.py Log: Needed for demo Added: pypy/dist/pypy/lib/distributed/socklayer.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/lib/distributed/socklayer.py Thu Mar 1 15:06:04 2007 @@ -0,0 +1,37 @@ + +from pypeers.pipe.gsocket import GreenSocket +from socket import socket, AF_INET, SOCK_STREAM +import marshal +import sys + +TRACE = False +def trace(msg): + if TRACE: + print >>sys.stderr, msg + +def receive(conn): + all = [] + data = conn.recv(10000) + trace("received %s" % data) + return marshal.loads(data) + +def send(conn, data): + trace("sending %s" % (data,)) + conn.send(marshal.dumps(data)) + trace("done") + +def socket_listener(address=('', 12121)): + s = GreenSocket(AF_INET, SOCK_STREAM) + s.bind(address) + s.listen(1) + print "Waiting for connection" + conn, addr = s.accept() + + return lambda data : send(conn, data), lambda : receive(conn) + +def socket_connecter(address): + s = GreenSocket(AF_INET, SOCK_STREAM) + print "Connecting %s" % (address,) + s.connect(address) + + return lambda data : send(s, data), lambda : receive(s) From fijal at codespeak.net Thu Mar 1 15:06:29 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 1 Mar 2007 15:06:29 +0100 (CET) Subject: [pypy-svn] r39635 - pypy/dist/pypy/lib/distributed/test Message-ID: <20070301140629.7BF1110120@code0.codespeak.net> Author: fijal Date: Thu Mar 1 15:06:27 2007 New Revision: 39635 Added: pypy/dist/pypy/lib/distributed/test/__init__.py Log: From arigo at codespeak.net Thu Mar 1 19:58:48 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 1 Mar 2007 19:58:48 +0100 (CET) Subject: [pypy-svn] r39642 - pypy/dist/pypy/doc Message-ID: <20070301185848.EBCBC100D1@code0.codespeak.net> Author: arigo Date: Thu Mar 1 19:58:39 2007 New Revision: 39642 Modified: pypy/dist/pypy/doc/objspace.txt Log: More documentation about how the Standard Object Space works, at least at the level of multiple type implementations, multimethods, and slicing. Modified: pypy/dist/pypy/doc/objspace.txt ============================================================================== --- pypy/dist/pypy/doc/objspace.txt (original) +++ pypy/dist/pypy/doc/objspace.txt Thu Mar 1 19:58:39 2007 @@ -289,7 +289,7 @@ does some internal dispatching (similar to "Object/abstract.c" in CPython) and invokes a method of the proper W_XyzObject class that can do the operation. The operation itself is done with the primitives allowed by -RestrictedPython. The result is constructed as a wrapped object again. For +RPython. The result is constructed as a wrapped object again. For example, compare the following implementation of integer addition with the function "int_add()" in "Object/intobject.c": :: @@ -313,23 +313,15 @@ 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. +the whole C code, so the CPython team avoided it. (In our case it is an +optimization that we eventually made, but not hard-coded at this level - +see `object optimizations`_.) + +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. .. _StdObjSpace: ../objspace/std/ -.. _MultiMethod: theory.html#multimethods Object types @@ -358,26 +350,145 @@ "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 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`_. For -examples of having several implementations of the same type, see the `object -optimizations`_ page. +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 to provide *several* implementations of the +instances of the same Python type, by writing several ``W_XxxObject`` +classes. Every place that instantiates a new object of that Python type +can decide which ``W_XxxObject`` class to instantiate. For example, the +regular string implementation is ``W_StringObject``, but we also have a +``W_StringSliceObject`` class whose instances contain a string, a start +index, and a stop index; it is used as the result of a string slicing +operation to avoid the copy of all the characters in the slice into a +new buffer. + +From the user's point of view, the multiple internal ``W_XxxObject`` +classes are not visible: they are still all instances of exactly the +same Python type. PyPy knows that (e.g.) the application-level type of +its interpreter-level ``W_StringObject`` instances is "str" because +there is a ``typedef`` class attribute in ``W_StringObject`` which +points back to the string type specification from `stringtype.py`_; all +other implementations of strings use the same ``typedef`` from +`stringtype.py`_. + +For other examples of multiple implementations of the same Python type, +see the `object optimizations`_ page. .. _`listtype.py`: ../objspace/std/listtype.py +.. _`stringtype.py`: ../objspace/std/stringtype.py .. _`tupletype.py`: ../objspace/std/tupletype.py .. _`tupleobject.py`: ../objspace/std/tupleobject.py .. _`object optimizations`: object-optimizations.html +Multimethods +------------ + +The Standard Object Space allows multiple object implementations per +Python type - this is based on multimethods_, although the more precise +picture spans several levels in order to emulate the exact Python +semantics. + +Consider the example of the ``space.getitem(w_a, w_b)`` operation, +corresponding to the application-level syntax ``a[b]``. The Standard +Object Space contains a corresponding ``getitem`` multimethod and a +family of functions that implement the multimethod for various +combination of argument classes - more precisely, for various +combinations of the *interpreter-level* classes of the arguments. Here +are some examples of functions implementing the ``getitem`` +multimethod: + +* ``getitem__Tuple_ANY``: called when the first argument is a + W_TupleObject, this function converts its second argument to an + integer and performs tuple indexing. + +* ``getitem__Tuple_Slice``: called when the first argument is a + W_TupleObject and the second argument is a W_SliceObject. This + version takes precedence over the previous one if the indexing is + done with a slice object, and performs tuple slicing instead. + +* ``getitem__String_Slice``: called when the first argument is a + W_StringObject and the second argument is a slice object. When the + special string slices optimization is enabled, this returns an + instance of W_StringSliceObject. + +* ``getitem__StringSlice_ANY``: called when the first argument is a + W_StringSliceObject. This implementation adds the provided index to + the original start of the slice stored in the W_StringSliceObject + instance. This allows constructs like ``a = s[10:100]; print a[5]`` + to return the 15th character of ``s`` without having to perform any + buffer copying. + +Note how the multimethod dispatch logic helps writing new object +implementations without having to insert hooks into existing code. Note +first how we could have defined a regular method-based API that new +object implementations must provide, and call these methods from the +space operations. The problem with this approach is that some Python +operators are naturally binary or N-ary. Consider for example the +addition operation: for the basic string implementation it is a simple +concatenation-by-copy, but it can have a rather more subtle +implementation for strings done as ropes. It is also likely that +concatenating a basic string with a rope string could have its own +dedicated implementation - and yet another implementation for a rope +string with a basic string. With multimethods, we can have an +orthogonally-defined implementation for each combination. + +The multimethods mechanism also supports delegate functions, which are +converters between two object implementations. The dispatch logic knows +how to insert calls to delegates if it encounters combinations of +interp-level classes which is not directly implemented. For example, we +have no specific implementation for the concatenation of a basic string +and a StringSlice object; when the user adds two such strings, then the +StringSlice object is converted to a basic string (that is, a +temporarily copy is built), and the concatenation is performed on the +resulting pair of basic strings. This is similar to the C++ method +overloading resolution mechanism (but occurs at runtime). + +.. _multimethods: theory.html#multimethods + + +Multimethod slicing +------------------- + +The complete picture is more complicated because the Python object model +is based on *descriptors*: the types ``int``, ``str``, etc. must have +methods ``__add__``, ``__mul__``, etc. that take two arguments including +the ``self``. These methods must perform the operation or return +``NotImplemented`` if the second argument is not of a type that it +doesn't know how to handle. + +The Standard Object Space creates these methods by *slicing* the +multimethod tables. Each method is automatically generated from a +subset of the registered implementations of the corresponding +multimethod. This slicing is performed on the first argument, in order +to keep only the implementations whose first argument's +interpreter-level class matches the declared Python-level type. + +For example, in a baseline PyPy, ``int.__add__`` is just calling the +function ``add__Int_Int``, which is the only registered implementation +for ``add`` whose first argument is an implementation of the ``int`` +Python type. On the other hand, if we enable integers implemented as +tagged pointers, then there is another matching implementation: +``add__SmallInt_SmallInt``. In this case, the Python-level method +``int.__add__`` is implemented by trying to dispatch between these two +functions based on the interp-level type of the two arguments. + +Similarly, the reverse methods (``__radd__`` and others) are obtained by +slicing the multimethod tables to keep only the functions whose *second* +argument has the correct Python-level type. + +Slicing is actually a good way to reproduce the details of the object +model as seen in CPython: slicing is attempted for every Python types +for every multimethod, but the ``__xyz__`` Python methods are only put +into the Python type when the resulting slices are not empty. This is +how our ``int`` type has no ``__getitem__`` method, for example. +Additionally, slicing ensures that ``5 .__add__(6L)`` correctly returns +``NotImplemented`` (because this particular slice does not include +``add__Long_Long`` and there is no ``add__Int_Long``), which leads to +``6L.__radd__(5)`` being called, as in CPython. + + The Trace Object Space ====================== From fijal at codespeak.net Thu Mar 1 20:23:21 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 1 Mar 2007 20:23:21 +0100 (CET) Subject: [pypy-svn] r39643 - pypy/dist/pypy/lib/distributed/demo Message-ID: <20070301192321.6AEAD1006F@code0.codespeak.net> Author: fijal Date: Thu Mar 1 20:23:19 2007 New Revision: 39643 Modified: pypy/dist/pypy/lib/distributed/demo/gsock.py Log: (fijal, arigo, pedronis, arre) Minor improvements Modified: pypy/dist/pypy/lib/distributed/demo/gsock.py ============================================================================== --- pypy/dist/pypy/lib/distributed/demo/gsock.py (original) +++ pypy/dist/pypy/lib/distributed/demo/gsock.py Thu Mar 1 20:23:19 2007 @@ -20,7 +20,7 @@ def local(): from distributed.socklayer import socket_connecter - send, receive = socket_connecter(('localhost', 12121)) + send, receive = socket_connecter(('localhost', 12122)) return RemoteProtocol(send, receive) import sys From rxe at codespeak.net Thu Mar 1 20:31:36 2007 From: rxe at codespeak.net (rxe at codespeak.net) Date: Thu, 1 Mar 2007 20:31:36 +0100 (CET) Subject: [pypy-svn] r39644 - pypy/dist/pypy/translator/c/test Message-ID: <20070301193136.2C92A10125@code0.codespeak.net> Author: rxe Date: Thu Mar 1 20:31:33 2007 New Revision: 39644 Modified: pypy/dist/pypy/translator/c/test/test_newgc.py Log: (mwh, rxe) add a failing skipped test with collecting in dictionary resizing Modified: pypy/dist/pypy/translator/c/test/test_newgc.py ============================================================================== --- pypy/dist/pypy/translator/c/test/test_newgc.py (original) +++ pypy/dist/pypy/translator/c/test/test_newgc.py Thu Mar 1 20:31:33 2007 @@ -859,6 +859,35 @@ # the point is just not to segfault res = fn() + def test_dict_segfault(self): + py.test.skip("some gc collect failing - somehow") + class Element: + pass + + elements = [Element() for ii in range(10000)] + + def dostuff(): + reverse = {} + l = elements[:] + + for ii in elements: + reverse[ii] = ii + # print reverse.get(ii, None) + + for jj in range(100): + e = l[-1] + del reverse[e] + l.remove(e) + + def f(): + for ii in range(100): + print ii + dostuff() + + fn = self.getcompiled(f) + # the point is just not to segfault + res = fn() + class TestUsingStacklessFramework(TestUsingFramework): gcpolicy = "stacklessgc" From santagada at codespeak.net Fri Mar 2 03:23:59 2007 From: santagada at codespeak.net (santagada at codespeak.net) Date: Fri, 2 Mar 2007 03:23:59 +0100 (CET) Subject: [pypy-svn] r39647 - in pypy/dist/pypy/lang/js: . test Message-ID: <20070302022359.6B9EE1012D@code0.codespeak.net> Author: santagada Date: Fri Mar 2 03:23:54 2007 New Revision: 39647 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: with operator with test Modified: pypy/dist/pypy/lang/js/interpreter.py ============================================================================== --- pypy/dist/pypy/lang/js/interpreter.py (original) +++ pypy/dist/pypy/lang/js/interpreter.py Fri Mar 2 03:23:54 2007 @@ -969,6 +969,24 @@ self.expr.eval(ctx) return w_Undefined +class With(Statement): + opcode = "WITH" + + def from_tree(self, t): + self.object = get_obj(t, 'object') + self.body = get_obj(t, 'body') + + def execute(self, ctx): + obj = self.object.eval(ctx).GetValue().ToObject() + ctx.push_object(obj) + + try: + retval = self.body.execute(ctx) + finally: + ctx.pop_object() + return retval + + class WhileBase(Statement): def from_tree(self, t): self.condition = get_obj(t, 'condition') Modified: pypy/dist/pypy/lang/js/jsobj.py ============================================================================== --- pypy/dist/pypy/lang/js/jsobj.py (original) +++ pypy/dist/pypy/lang/js/jsobj.py Fri Mar 2 03:23:54 2007 @@ -437,7 +437,7 @@ self.variable = obj def pop_object(self): - """docstring for pop_object""" + """remove the last pushed object""" return self.scope.pop(0) def resolve_identifier(self, identifier): 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 Mar 2 03:23:54 2007 @@ -478,3 +478,21 @@ print(2 !== 3) print(2 !== 2) """, ['true', 'false', 'true', 'false']) + + def test_with(self): + self.assert_prints(""" + var mock = {x:2} + var x=4 + print(x) + try { + with(mock) { + print(x) + throw 3 + print("not reacheable") + } + } + catch(y){ + print(y) + } + print(x) + """, ['4', '2', '3', '4']) From cfbolz at codespeak.net Fri Mar 2 10:49:05 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 2 Mar 2007 10:49:05 +0100 (CET) Subject: [pypy-svn] r39652 - pypy/extradoc/sprintinfo/trillke-2007 Message-ID: <20070302094905.4EA2D10121@code0.codespeak.net> Author: cfbolz Date: Fri Mar 2 10:49:02 2007 New Revision: 39652 Added: pypy/extradoc/sprintinfo/trillke-2007/planning.txt Log: (all): invent lots of tasks Added: pypy/extradoc/sprintinfo/trillke-2007/planning.txt ============================================================================== --- (empty file) +++ pypy/extradoc/sprintinfo/trillke-2007/planning.txt Fri Mar 2 10:49:02 2007 @@ -0,0 +1,50 @@ +============================ +Trillke Sprint 2007 Planning +============================ + +People present: Michael, Arre, Stephan, Anto, Guido, Armin, Maciek, Bea, + Samuele, Georg, Alexander, Holger, Carl Friedrich, Anders + +Tutorial: Georg, Anders + + * think a bit about what needs to be done for 1.0 + + * move some of the external functions to the new interface (kill + suggested_primitive!!!) + + * Fix the rdict bug (Michael, Richard) + + * run application on top of PyPy and turn them into benchmarks: Guido, + Christian + + * object optimizations: ropes, list optimizations, cuckoo hashing, + tree-based dicts: after the tutorial, Holger, Armin, Carl Friedrich, Georg + + * improve the error messages of the rtyper + + * improve setups of temporary test directories + + * benchmarking: make nice graphs out of benchmark results + + * hunt the strange speed bottleneck of gencli/genjava: Anto, Samuele + + * fix application-level stackless code: Arre, Stephan + + * improve greensocks + + * have a minimal readline support for history and line editing: Armin, Holger + + * fix the javascript backend work in internet explorer: Guido, Maciek + + * make the usage of the js backend nicer + + * discuss code sharing between the js backend and gencli: Anto, Maciek + + * make genllvm less of a FrankenBackend + + * have a pypy with a gil and threading that works + + * object-level locking for a gil-less pypy + + * use no locking, multiple interpreters and shared memory instead of + object-level locks From fijal at codespeak.net Fri Mar 2 10:57:47 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 2 Mar 2007 10:57:47 +0100 (CET) Subject: [pypy-svn] r39653 - pypy/dist/pypy/module/_ssl/test Message-ID: <20070302095747.589B610131@code0.codespeak.net> Author: fijal Date: Fri Mar 2 10:57:44 2007 New Revision: 39653 Modified: pypy/dist/pypy/module/_ssl/test/test_ssl.py Log: Skip ssl tests Modified: pypy/dist/pypy/module/_ssl/test/test_ssl.py ============================================================================== --- pypy/dist/pypy/module/_ssl/test/test_ssl.py (original) +++ pypy/dist/pypy/module/_ssl/test/test_ssl.py Fri Mar 2 10:57:44 2007 @@ -1,5 +1,8 @@ from pypy.conftest import gettestobjspace import os +import py + +py.test.skip("Module not working yet") if os.name == "nt": from py.test import skip From arigo at codespeak.net Fri Mar 2 11:35:29 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 2 Mar 2007 11:35:29 +0100 (CET) Subject: [pypy-svn] r39654 - pypy/dist/pypy/translator/cli Message-ID: <20070302103529.20E2710126@code0.codespeak.net> Author: arigo Date: Fri Mar 2 11:35:26 2007 New Revision: 39654 Modified: pypy/dist/pypy/translator/cli/gencli.py Log: Mono's ilasm occasionally deadlocks. We set a timer to avoid blocking automated test runs forever. Modified: pypy/dist/pypy/translator/cli/gencli.py ============================================================================== --- pypy/dist/pypy/translator/cli/gencli.py (original) +++ pypy/dist/pypy/translator/cli/gencli.py Fri Mar 2 11:35:26 2007 @@ -80,7 +80,11 @@ ilasm = SDK.ilasm() tmpfile = self.tmpfile.strpath - self._exec_helper(ilasm, tmpfile, 'ilasm failed to assemble (%s):\n%s\n%s') + self._exec_helper(ilasm, tmpfile, + 'ilasm failed to assemble (%s):\n%s\n%s', + timeout = 900) + # Mono's ilasm occasionally deadlocks. We set a timer to avoid + # blocking automated test runs forever. exefile = tmpfile.replace('.il', '.exe') if getoption('verify'): @@ -88,8 +92,14 @@ self._exec_helper(peverify, exefile, 'peverify failed to verify (%s):\n%s\n%s') return exefile - def _exec_helper(self, helper, filename, msg): - proc = subprocess.Popen([helper, filename], stdout=subprocess.PIPE, stderr=subprocess.PIPE) + def _exec_helper(self, helper, filename, msg, timeout=None): + args = [helper, filename] + if timeout and not sys.platform.startswith('win'): + import os + from pypy.tool import autopath + watchdog = os.path.join(autopath.pypydir, 'tool', 'watchdog.py') + args[:0] = [sys.executable, watchdog, str(float(timeout))] + proc = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = proc.communicate() retval = proc.wait() assert retval == 0, msg % (filename, stdout, stderr) From mwh at codespeak.net Fri Mar 2 12:01:24 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 2 Mar 2007 12:01:24 +0100 (CET) Subject: [pypy-svn] r39656 - pypy/dist/pypy/translator/c/test Message-ID: <20070302110124.362561006E@code0.codespeak.net> Author: mwh Date: Fri Mar 2 12:01:13 2007 New Revision: 39656 Modified: pypy/dist/pypy/translator/c/test/test_standalone.py Log: a standalone version of the horrible dictionary bug Modified: pypy/dist/pypy/translator/c/test/test_standalone.py ============================================================================== --- pypy/dist/pypy/translator/c/test/test_standalone.py (original) +++ pypy/dist/pypy/translator/c/test/test_standalone.py Fri Mar 2 12:01:13 2007 @@ -118,3 +118,37 @@ out = py.process.cmdexec("%s 500" % exe) assert int(out) == 500*501/2 + +def test_dict_segfault(): + py.test.skip('segfaults :(') + class Element: + pass + + elements = [Element() for ii in range(10000)] + + def dostuff(): + reverse = {} + l = elements[:] + + for ii in elements: + reverse[ii] = ii#Element() + + for jj in range(100): + e = l[-1] + del reverse[e] + l.remove(e) + + def f(args): + for ii in range(100): + dostuff() + return 0 + + t = TranslationContext() + t.config.translation.gc = 'framework' + t.buildannotator().build_types(f, [s_list_of_strings]) + t.buildrtyper().specialize() + + cbuilder = CStandaloneBuilder(t, f, t.config) + cbuilder.generate_source() + cbuilder.compile() + data = cbuilder.cmdexec('') From hpk at codespeak.net Fri Mar 2 12:19:29 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Fri, 2 Mar 2007 12:19:29 +0100 (CET) Subject: [pypy-svn] r39657 - pypy/dist/pypy/interpreter Message-ID: <20070302111929.08B2F10071@code0.codespeak.net> Author: hpk Date: Fri Mar 2 12:19:26 2007 New Revision: 39657 Removed: pypy/dist/pypy/interpreter/autopath.py Modified: pypy/dist/pypy/interpreter/interactive.py pypy/dist/pypy/interpreter/main.py Log: these scripts are not run anymore directly (rather the pypy/bin/* ones) and so i don't see a use in using autopath here. Modified: pypy/dist/pypy/interpreter/interactive.py ============================================================================== --- pypy/dist/pypy/interpreter/interactive.py (original) +++ pypy/dist/pypy/interpreter/interactive.py Fri Mar 2 12:19:26 2007 @@ -1,5 +1,3 @@ -import autopath - from pypy.interpreter import error from pypy.interpreter import baseobjspace, module, main import sys Modified: pypy/dist/pypy/interpreter/main.py ============================================================================== --- pypy/dist/pypy/interpreter/main.py (original) +++ pypy/dist/pypy/interpreter/main.py Fri Mar 2 12:19:26 2007 @@ -1,4 +1,3 @@ -import autopath from pypy.interpreter import module, eval from pypy.interpreter.error import OperationError from pypy.interpreter.pycode import PyCode From guido at codespeak.net Fri Mar 2 12:45:24 2007 From: guido at codespeak.net (guido at codespeak.net) Date: Fri, 2 Mar 2007 12:45:24 +0100 (CET) Subject: [pypy-svn] r39658 - pypy/dist/pypy/translator/js/modules Message-ID: <20070302114524.0FB4B10070@code0.codespeak.net> Author: guido Date: Fri Mar 2 12:45:22 2007 New Revision: 39658 Modified: pypy/dist/pypy/translator/js/modules/mochikit.py Log: Trying to add some MochiKit.Signal stuff, not working yet. 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 Fri Mar 2 12:45:22 2007 @@ -2,12 +2,17 @@ """ mochikit wrappers """ -from pypy.rpython.extfunc import register_external +from pypy.rpython.extfunc import _callable, register_external +from pypy.translator.js.modules import dom + +# MochiKit.LoggingPane def createLoggingPane(var): pass register_external(createLoggingPane, args=[bool]) +# MochiKit.Logging + def log(data): print data register_external(log, args=None) @@ -28,10 +33,26 @@ print "FATAL:", data register_external(logFatal, args=None) +# MochiKit.DOM + def escapeHTML(data): return data register_external(escapeHTML, args=[str], result=str) +# MochiKit.Base + def serializeJSON(data): pass register_external(serializeJSON, args=None, result=str) + +# MochiKit.Signal + +def connect(src, signal, dest): + print 'connecting event %s' % (event,) +register_external(connect, args=[dom.EventTarget, str, _callable([dom.Event])], + result=int) + +def disconnect(id): + pass +register_external(disconnect, args=[int]) + From hpk at codespeak.net Fri Mar 2 12:48:05 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Fri, 2 Mar 2007 12:48:05 +0100 (CET) Subject: [pypy-svn] r39659 - pypy/dist/pypy/interpreter/test Message-ID: <20070302114805.7AE6310063@code0.codespeak.net> Author: hpk Date: Fri Mar 2 12:48:03 2007 New Revision: 39659 Removed: pypy/dist/pypy/interpreter/test/autopath.py Modified: pypy/dist/pypy/interpreter/test/test_compiler.py pypy/dist/pypy/interpreter/test/test_eval.py pypy/dist/pypy/interpreter/test/test_exceptcomp.py pypy/dist/pypy/interpreter/test/test_exec.py pypy/dist/pypy/interpreter/test/test_function.py pypy/dist/pypy/interpreter/test/test_gateway.py pypy/dist/pypy/interpreter/test/test_generator.py pypy/dist/pypy/interpreter/test/test_main.py pypy/dist/pypy/interpreter/test/test_module.py pypy/dist/pypy/interpreter/test/test_nestedscope.py pypy/dist/pypy/interpreter/test/test_objspace.py pypy/dist/pypy/interpreter/test/test_py.py pypy/dist/pypy/interpreter/test/test_pyframe.py pypy/dist/pypy/interpreter/test/test_raise.py pypy/dist/pypy/interpreter/test/test_special.py pypy/dist/pypy/interpreter/test/test_typedef.py Log: removing some more obsolete autopath usages on a sidenote Modified: pypy/dist/pypy/interpreter/test/test_compiler.py ============================================================================== --- pypy/dist/pypy/interpreter/test/test_compiler.py (original) +++ pypy/dist/pypy/interpreter/test/test_compiler.py Fri Mar 2 12:48:03 2007 @@ -1,5 +1,4 @@ import __future__ -import autopath import py, sys from pypy.interpreter.pycompiler import CPythonCompiler, PythonAstCompiler from pypy.interpreter.pycode import PyCode Modified: pypy/dist/pypy/interpreter/test/test_eval.py ============================================================================== --- pypy/dist/pypy/interpreter/test/test_eval.py (original) +++ pypy/dist/pypy/interpreter/test/test_eval.py Fri Mar 2 12:48:03 2007 @@ -1,5 +1,4 @@ -import autopath from pypy.interpreter.eval import Frame from pypy.interpreter.pycode import PyCode Modified: pypy/dist/pypy/interpreter/test/test_exceptcomp.py ============================================================================== --- pypy/dist/pypy/interpreter/test/test_exceptcomp.py (original) +++ pypy/dist/pypy/interpreter/test/test_exceptcomp.py Fri Mar 2 12:48:03 2007 @@ -2,7 +2,6 @@ New for PyPy - Could be incorporated into CPython regression tests. """ -import autopath class AppTestExceptionComp: Modified: pypy/dist/pypy/interpreter/test/test_exec.py ============================================================================== --- pypy/dist/pypy/interpreter/test/test_exec.py (original) +++ pypy/dist/pypy/interpreter/test/test_exec.py Fri Mar 2 12:48:03 2007 @@ -2,7 +2,6 @@ New for PyPy - Could be incorporated into CPython regression tests. """ -import autopath from pypy.tool.udir import udir 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 Fri Mar 2 12:48:03 2007 @@ -1,5 +1,4 @@ -import autopath import unittest from pypy.interpreter.function import Function, Method, descr_function_get from pypy.interpreter.pycode import PyCode Modified: pypy/dist/pypy/interpreter/test/test_gateway.py ============================================================================== --- pypy/dist/pypy/interpreter/test/test_gateway.py (original) +++ pypy/dist/pypy/interpreter/test/test_gateway.py Fri Mar 2 12:48:03 2007 @@ -1,5 +1,4 @@ -import autopath from pypy.interpreter import gateway from pypy.interpreter import argument import py Modified: pypy/dist/pypy/interpreter/test/test_generator.py ============================================================================== --- pypy/dist/pypy/interpreter/test/test_generator.py (original) +++ pypy/dist/pypy/interpreter/test/test_generator.py Fri Mar 2 12:48:03 2007 @@ -1,5 +1,4 @@ from __future__ import generators -import autopath class AppTestGenerator: Modified: pypy/dist/pypy/interpreter/test/test_main.py ============================================================================== --- pypy/dist/pypy/interpreter/test/test_main.py (original) +++ pypy/dist/pypy/interpreter/test/test_main.py Fri Mar 2 12:48:03 2007 @@ -1,4 +1,3 @@ -import autopath from cStringIO import StringIO import py Modified: pypy/dist/pypy/interpreter/test/test_module.py ============================================================================== --- pypy/dist/pypy/interpreter/test/test_module.py (original) +++ pypy/dist/pypy/interpreter/test/test_module.py Fri Mar 2 12:48:03 2007 @@ -1,5 +1,4 @@ -import autopath from pypy.interpreter.module import Module class TestModule: Modified: pypy/dist/pypy/interpreter/test/test_nestedscope.py ============================================================================== --- pypy/dist/pypy/interpreter/test/test_nestedscope.py (original) +++ pypy/dist/pypy/interpreter/test/test_nestedscope.py Fri Mar 2 12:48:03 2007 @@ -1,4 +1,3 @@ -import autopath class AppTestNestedScope: Modified: pypy/dist/pypy/interpreter/test/test_objspace.py ============================================================================== --- pypy/dist/pypy/interpreter/test/test_objspace.py (original) +++ pypy/dist/pypy/interpreter/test/test_objspace.py Fri Mar 2 12:48:03 2007 @@ -1,4 +1,3 @@ -import autopath from py.test import raises from pypy.interpreter.function import Function from pypy.interpreter.pycode import PyCode Modified: pypy/dist/pypy/interpreter/test/test_py.py ============================================================================== --- pypy/dist/pypy/interpreter/test/test_py.py (original) +++ pypy/dist/pypy/interpreter/test/test_py.py Fri Mar 2 12:48:03 2007 @@ -1,10 +1,10 @@ -import autopath from pypy.tool.udir import udir import py import sys +import pypy -pypypath = str(py.path.local(autopath.pypydir).join('bin', 'py.py')) +pypypath = py.path.local(pypy.__file__).dirpath("bin", "py.py") def test_executable(): """Ensures sys.executable points to the py.py script""" Modified: pypy/dist/pypy/interpreter/test/test_pyframe.py ============================================================================== --- pypy/dist/pypy/interpreter/test/test_pyframe.py (original) +++ pypy/dist/pypy/interpreter/test/test_pyframe.py Fri Mar 2 12:48:03 2007 @@ -1,4 +1,3 @@ -import autopath class AppTestPyFrame: Modified: pypy/dist/pypy/interpreter/test/test_raise.py ============================================================================== --- pypy/dist/pypy/interpreter/test/test_raise.py (original) +++ pypy/dist/pypy/interpreter/test/test_raise.py Fri Mar 2 12:48:03 2007 @@ -1,4 +1,3 @@ -import autopath class AppTestRaise: Modified: pypy/dist/pypy/interpreter/test/test_special.py ============================================================================== --- pypy/dist/pypy/interpreter/test/test_special.py (original) +++ pypy/dist/pypy/interpreter/test/test_special.py Fri Mar 2 12:48:03 2007 @@ -1,5 +1,4 @@ -import autopath class AppTestSpecialTestCase: def test_Ellipsis(self): Modified: pypy/dist/pypy/interpreter/test/test_typedef.py ============================================================================== --- pypy/dist/pypy/interpreter/test/test_typedef.py (original) +++ pypy/dist/pypy/interpreter/test/test_typedef.py Fri Mar 2 12:48:03 2007 @@ -1,4 +1,3 @@ -import autopath # this test isn't so much to test that the objspace interface *works* # -- it's more to test that it's *there* From fijal at codespeak.net Fri Mar 2 12:49:58 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 2 Mar 2007 12:49:58 +0100 (CET) Subject: [pypy-svn] r39660 - pypy/dist/pypy/rpython Message-ID: <20070302114958.E312510063@code0.codespeak.net> Author: fijal Date: Fri Mar 2 12:49:56 2007 New Revision: 39660 Modified: pypy/dist/pypy/rpython/extfunc.py Log: Postpone annotation() a bit Modified: pypy/dist/pypy/rpython/extfunc.py ============================================================================== --- pypy/dist/pypy/rpython/extfunc.py (original) +++ pypy/dist/pypy/rpython/extfunc.py Fri Mar 2 12:49:56 2007 @@ -27,12 +27,15 @@ class ExtFuncEntry(ExtRegistryEntry): def compute_result_annotation(self, *args_s): if self.signature_args is not None: - assert len(args_s) == len(self.signature_args),\ + signature_args = [annotation(arg, self.bookkeeper) + for arg in self.signature_args] + assert len(args_s) == len(signature_args),\ "Argument number mismatch" - for arg, expected in zip(args_s, self.signature_args): + for arg, expected in zip(args_s, signature_args): arg = unionof(arg, expected) assert expected.contains(arg) - return self.signature_result + signature_result = annotation(self.signature_result, self.bookkeeper) + return signature_result def specialize_call(self, hop): rtyper = hop.rtyper @@ -65,8 +68,8 @@ if args is None: signature_args = None else: - signature_args = [annotation(arg) for arg in args] - signature_result = annotation(result) + signature_args = args + signature_result = result name=export_name if llimpl: lltypeimpl = llimpl From arigo at codespeak.net Fri Mar 2 12:50:56 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 2 Mar 2007 12:50:56 +0100 (CET) Subject: [pypy-svn] r39661 - in pypy/dist/pypy/module: __builtin__ readline Message-ID: <20070302115056.18CC610068@code0.codespeak.net> Author: arigo Date: Fri Mar 2 12:50:52 2007 New Revision: 39661 Modified: pypy/dist/pypy/module/__builtin__/app_io.py pypy/dist/pypy/module/readline/__init__.py pypy/dist/pypy/module/readline/c_readline.py Log: (hpk, arigo) Link the readline module's readline() function with raw_input(). Should give basic (no-completion) readline support in a translated pypy-c. Modified: pypy/dist/pypy/module/__builtin__/app_io.py ============================================================================== --- pypy/dist/pypy/module/__builtin__/app_io.py (original) +++ pypy/dist/pypy/module/__builtin__/app_io.py Fri Mar 2 12:50:52 2007 @@ -35,22 +35,31 @@ On Unix, GNU readline is used if enabled. The prompt string, if given, is printed without a trailing newline before reading.""" try: - sys.stdin + stdin = sys.stdin except AttributeError: - raise RuntimeError("[raw_]input: lost sys.stdin"); + raise RuntimeError("[raw_]input: lost sys.stdin") try: - sys.stdout + stdout = sys.stdout except AttributeError: - raise RuntimeError("[raw_]input: lost sys.stdout"); + raise RuntimeError("[raw_]input: lost sys.stdout") + + # hook for the readline module + if (hasattr(sys, '__raw_input__') and + isinstance(stdin, file) and stdin.fileno() == 0 and stdin.isatty() and + isinstance(stdout, file) and stdout.fileno() == 1): + if prompt is None: + prompt = '' + return sys.__raw_input__(prompt) + if prompt is not None: - sys.stdout.write(prompt) + stdout.write(prompt) try: - flush = sys.stdout.flush + flush = stdout.flush except AttributeError: pass else: flush() - line = sys.stdin.readline() + line = stdin.readline() if not line: # inputting an empty line gives line == '\n' raise EOFError if line[-1] == '\n': Modified: pypy/dist/pypy/module/readline/__init__.py ============================================================================== --- pypy/dist/pypy/module/readline/__init__.py (original) +++ pypy/dist/pypy/module/readline/__init__.py Fri Mar 2 12:50:52 2007 @@ -10,9 +10,9 @@ """Importing this module enables command line editing using GNU readline.""" # the above line is the doc string of the translated module - def init(self, space): + def setup_after_space_initialization(self): from pypy.module.readline import c_readline - c_readline.setup_readline(space, self) + c_readline.setup_readline(self.space, self) interpleveldefs = { 'readline' : 'interp_readline.readline', Modified: pypy/dist/pypy/module/readline/c_readline.py ============================================================================== --- pypy/dist/pypy/module/readline/c_readline.py (original) +++ pypy/dist/pypy/module/readline/c_readline.py Fri Mar 2 12:50:52 2007 @@ -1,5 +1,7 @@ from ctypes import * from pypy.rpython.rctypes.tool.ctypes_platform import configure, Library +from pypy.interpreter.error import OperationError +from pypy.interpreter.gateway import ObjSpace, interp2app #------------------------------------------------------------ # configuration for binding to external readline library @@ -30,9 +32,15 @@ # special initialization of readline def setup_readline(space, w_module): - # XXX ... c_rl_initialize() - space.readline_func = readline_func - -def readline_func(s): - return c_readline(s) + # install sys.__raw_input__, a hook that will be used by raw_input() + space.setitem(space.sys.w_dict, space.wrap('__raw_input__'), + space.wrap(app_readline_func)) + +def readline_func(space, prompt): + res = c_readline(prompt) + if res is None: + raise OperationError(space.w_EOFError, space.w_None) + return space.wrap(res) +readline_func.unwrap_spec = [ObjSpace, str] +app_readline_func = interp2app(readline_func) From fijal at codespeak.net Fri Mar 2 12:51:38 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 2 Mar 2007 12:51:38 +0100 (CET) Subject: [pypy-svn] r39662 - pypy/dist/pypy/rpython Message-ID: <20070302115138.1B0881006E@code0.codespeak.net> Author: fijal Date: Fri Mar 2 12:51:36 2007 New Revision: 39662 Modified: pypy/dist/pypy/rpython/extfunc.py Log: Store the result Modified: pypy/dist/pypy/rpython/extfunc.py ============================================================================== --- pypy/dist/pypy/rpython/extfunc.py (original) +++ pypy/dist/pypy/rpython/extfunc.py Fri Mar 2 12:51:36 2007 @@ -27,15 +27,16 @@ class ExtFuncEntry(ExtRegistryEntry): def compute_result_annotation(self, *args_s): if self.signature_args is not None: - signature_args = [annotation(arg, self.bookkeeper) - for arg in self.signature_args] + self.signature_args = [annotation(arg, self.bookkeeper) + for arg in self.signature_args] assert len(args_s) == len(signature_args),\ "Argument number mismatch" for arg, expected in zip(args_s, signature_args): arg = unionof(arg, expected) assert expected.contains(arg) - signature_result = annotation(self.signature_result, self.bookkeeper) - return signature_result + self.signature_result = \ + annotation(self.signature_result, self.bookkeeper) + return self.signature_result def specialize_call(self, hop): rtyper = hop.rtyper From fijal at codespeak.net Fri Mar 2 12:53:06 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 2 Mar 2007 12:53:06 +0100 (CET) Subject: [pypy-svn] r39663 - pypy/dist/pypy/rpython Message-ID: <20070302115306.2C2B010070@code0.codespeak.net> Author: fijal Date: Fri Mar 2 12:53:02 2007 New Revision: 39663 Modified: pypy/dist/pypy/rpython/extfunc.py Log: Typo Modified: pypy/dist/pypy/rpython/extfunc.py ============================================================================== --- pypy/dist/pypy/rpython/extfunc.py (original) +++ pypy/dist/pypy/rpython/extfunc.py Fri Mar 2 12:53:02 2007 @@ -29,9 +29,9 @@ if self.signature_args is not None: self.signature_args = [annotation(arg, self.bookkeeper) for arg in self.signature_args] - assert len(args_s) == len(signature_args),\ + assert len(args_s) == len(self.signature_args),\ "Argument number mismatch" - for arg, expected in zip(args_s, signature_args): + for arg, expected in zip(args_s, self.signature_args): arg = unionof(arg, expected) assert expected.contains(arg) self.signature_result = \ From fijal at codespeak.net Fri Mar 2 13:09:00 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 2 Mar 2007 13:09:00 +0100 (CET) Subject: [pypy-svn] r39664 - in pypy/dist/pypy/annotation: . test Message-ID: <20070302120900.C0E871007C@code0.codespeak.net> Author: fijal Date: Fri Mar 2 13:08:58 2007 New Revision: 39664 Modified: pypy/dist/pypy/annotation/binaryop.py pypy/dist/pypy/annotation/test/test_annrpython.py Log: (fijal, guido) - unionof for two BasicExternals Modified: pypy/dist/pypy/annotation/binaryop.py ============================================================================== --- pypy/dist/pypy/annotation/binaryop.py (original) +++ pypy/dist/pypy/annotation/binaryop.py Fri Mar 2 13:08:58 2007 @@ -20,6 +20,7 @@ from pypy.annotation.model import add_knowntypedata, merge_knowntypedata from pypy.annotation.model import lltype_to_annotation from pypy.annotation.model import SomeGenericCallable +from pypy.annotation.model import SomeExternalBuiltin from pypy.annotation.bookkeeper import getbookkeeper from pypy.objspace.flow.model import Variable from pypy.annotation.listdef import ListDef @@ -747,6 +748,20 @@ return SomeExternalObject(ext1.knowntype) return SomeObject() +class __extend__(pairtype(SomeExternalBuiltin, SomeExternalBuiltin)): + def union((ext1, ext2)): + def commonsuperclass(cls1, cls2): + cls = cls2 + while not issubclass(cls1, cls): + cls = cls.__bases__[0] + return cls + + from pypy.rpython.ootypesystem.bltregistry import BasicExternal, ExternalType + cls = commonsuperclass(ext1.knowntype._class_, ext2.knowntype._class_) + if cls is BasicExternal: + return SomeObject() + return SomeExternalBuiltin(ExternalType(cls)) + # ____________________________________________________________ # annotation of low-level types from pypy.annotation.model import SomePtr, SomeOOInstance, SomeOOClass 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 Fri Mar 2 13:08:58 2007 @@ -2634,6 +2634,30 @@ s = a.build_types(fun, [bool]) assert isinstance(s, annmodel.SomeInteger) + def test_unionof_some_external_builtin(self): + from pypy.rpython.ootypesystem.bltregistry import BasicExternal + + class A(BasicExternal): + pass + + class B(A): + pass + + class C(A): + pass + + def f(x): + if x: + return B() + else: + return C() + + P = policy.AnnotatorPolicy() + P.allow_someobjects = False + a = self.RPythonAnnotator(policy=P) + s = a.build_types(f, [bool]) + assert isinstance(s, annmodel.SomeExternalBuiltin) + def g(n): return [0,1,2,n] @@ -2651,3 +2675,4 @@ class Freezing: def _freeze_(self): return True + From mwh at codespeak.net Fri Mar 2 13:21:33 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 2 Mar 2007 13:21:33 +0100 (CET) Subject: [pypy-svn] r39665 - in pypy/dist/pypy/rpython/memory/gctransform: . test Message-ID: <20070302122133.36B2B10069@code0.codespeak.net> Author: mwh Date: Fri Mar 2 13:21:29 2007 New Revision: 39665 Modified: pypy/dist/pypy/rpython/memory/gctransform/framework.py pypy/dist/pypy/rpython/memory/gctransform/test/test_framework.py Log: (mwh, rxe) fix the "rdict bug": it turned out that the framework gc didn't recognize zero_malloc and zero_malloc_varsize as being operations that could collect, and dictionary resizing was a function that only allocated via these operations. what was special about the test cases was that they did most of their allocations during resizing when there were no other references to the dict, most programs never see a collect there. this may just be a bug that could crash pypy-c, but it seems unlikely. Modified: pypy/dist/pypy/rpython/memory/gctransform/framework.py ============================================================================== --- pypy/dist/pypy/rpython/memory/gctransform/framework.py (original) +++ pypy/dist/pypy/rpython/memory/gctransform/framework.py Fri Mar 2 13:21:29 2007 @@ -16,7 +16,7 @@ class CollectAnalyzer(graphanalyze.GraphAnalyzer): def operation_is_true(self, op): return op.opname in ("malloc", "malloc_varsize", "gc__collect", - "gc_x_become") + "gc_x_become", "zero_malloc_varsize", "zero_malloc") ADDRESS_VOID_FUNC = lltype.FuncType([llmemory.Address], lltype.Void) Modified: pypy/dist/pypy/rpython/memory/gctransform/test/test_framework.py ============================================================================== --- pypy/dist/pypy/rpython/memory/gctransform/test/test_framework.py (original) +++ pypy/dist/pypy/rpython/memory/gctransform/test/test_framework.py Fri Mar 2 13:21:29 2007 @@ -1,5 +1,5 @@ from pypy.rpython.memory.gctransform.test.test_transform import rtype -from pypy.rpython.memory.gctransform.framework import FrameworkGCTransformer +from pypy.rpython.memory.gctransform.framework import FrameworkGCTransformer, CollectAnalyzer from pypy.rpython.lltypesystem import lltype from pypy.translator.c.gc import FrameworkGcPolicy from pypy.translator.translator import TranslationContext, graphof @@ -45,3 +45,11 @@ res = llinterp.eval_graph(entrygraph, [ll_argv]) assert ''.join(res.chars) == "2" + +def test_cancollect(): + S = lltype.GcStruct('S', ('x', lltype.Signed)) + def g(): + lltype.malloc(S, zero=True) + t = rtype(g, []) + gg = graphof(t, g) + assert CollectAnalyzer(t).analyze_direct_call(gg) From guido at codespeak.net Fri Mar 2 13:48:40 2007 From: guido at codespeak.net (guido at codespeak.net) Date: Fri, 2 Mar 2007 13:48:40 +0100 (CET) Subject: [pypy-svn] r39666 - pypy/dist/pypy/rpython Message-ID: <20070302124840.301E510126@code0.codespeak.net> Author: guido Date: Fri Mar 2 13:48:38 2007 New Revision: 39666 Modified: pypy/dist/pypy/rpython/extfunc.py Log: Revert changes Modified: pypy/dist/pypy/rpython/extfunc.py ============================================================================== --- pypy/dist/pypy/rpython/extfunc.py (original) +++ pypy/dist/pypy/rpython/extfunc.py Fri Mar 2 13:48:38 2007 @@ -27,15 +27,11 @@ class ExtFuncEntry(ExtRegistryEntry): def compute_result_annotation(self, *args_s): if self.signature_args is not None: - self.signature_args = [annotation(arg, self.bookkeeper) - for arg in self.signature_args] 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) - self.signature_result = \ - annotation(self.signature_result, self.bookkeeper) return self.signature_result def specialize_call(self, hop): @@ -69,8 +65,8 @@ if args is None: signature_args = None else: - signature_args = args - signature_result = result + signature_args = [annotation(arg, None) for arg in args] + signature_result = annotation(result, None) name=export_name if llimpl: lltypeimpl = llimpl From hpk at codespeak.net Fri Mar 2 13:51:43 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Fri, 2 Mar 2007 13:51:43 +0100 (CET) Subject: [pypy-svn] r39667 - pypy/dist/pypy/objspace/test Message-ID: <20070302125143.A778B10126@code0.codespeak.net> Author: hpk Date: Fri Mar 2 13:51:40 2007 New Revision: 39667 Removed: pypy/dist/pypy/objspace/test/autopath.py Modified: pypy/dist/pypy/objspace/test/test_descriptor.py pypy/dist/pypy/objspace/test/test_traceobjspace.py Log: remove some more autopath while waiting for translations Modified: pypy/dist/pypy/objspace/test/test_descriptor.py ============================================================================== --- pypy/dist/pypy/objspace/test/test_descriptor.py (original) +++ pypy/dist/pypy/objspace/test/test_descriptor.py Fri Mar 2 13:51:40 2007 @@ -1,4 +1,3 @@ -import autopath class AppTest_Descriptor: Modified: pypy/dist/pypy/objspace/test/test_traceobjspace.py ============================================================================== --- pypy/dist/pypy/objspace/test/test_traceobjspace.py (original) +++ pypy/dist/pypy/objspace/test/test_traceobjspace.py Fri Mar 2 13:51:40 2007 @@ -1,4 +1,3 @@ -import autopath from pypy.objspace import trace from pypy.tool import pydis from pypy.interpreter import gateway From bea at codespeak.net Fri Mar 2 13:55:39 2007 From: bea at codespeak.net (bea at codespeak.net) Date: Fri, 2 Mar 2007 13:55:39 +0100 (CET) Subject: [pypy-svn] r39670 - pypy/extradoc/publication Message-ID: <20070302125539.C735F10053@code0.codespeak.net> Author: bea Date: Fri Mar 2 13:55:38 2007 New Revision: 39670 Removed: pypy/extradoc/publication/limerick_pypypaper_200701.pdf pypy/extradoc/publication/pypy-ieee_janfeb2007.pdf Log: removed files From mwh at codespeak.net Fri Mar 2 14:04:35 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 2 Mar 2007 14:04:35 +0100 (CET) Subject: [pypy-svn] r39671 - in pypy/dist/pypy: config doc/config Message-ID: <20070302130435.9A06C1006E@code0.codespeak.net> Author: mwh Date: Fri Mar 2 14:04:32 2007 New Revision: 39671 Added: pypy/dist/pypy/doc/config/translation.backendopt.none.txt Modified: pypy/dist/pypy/config/translationoption.py Log: add a config option for turning off backend optimizations. Modified: pypy/dist/pypy/config/translationoption.py ============================================================================== --- pypy/dist/pypy/config/translationoption.py (original) +++ pypy/dist/pypy/config/translationoption.py Fri Mar 2 14:04:32 2007 @@ -157,6 +157,14 @@ "Remove operations that look like 'raise AssertionError', " "which lets the C optimizer remove the asserts", default=False), + + BoolOption("none", + "Do not run any backend optimizations", + requires=[('translation.backendopt.inline', False), + ('translation.backendopt.inline_threshold', 0), + ('translation.backendopt.merge_if_blocks', False), + ('translation.backendopt.mallocs', False), + ('translation.backendopt.constfold', False)]) ]), OptionDescription("cli", "GenCLI options", [ Added: pypy/dist/pypy/doc/config/translation.backendopt.none.txt ============================================================================== --- (empty file) +++ pypy/dist/pypy/doc/config/translation.backendopt.none.txt Fri Mar 2 14:04:32 2007 @@ -0,0 +1 @@ +Do not run any backend optimizations. From mwh at codespeak.net Fri Mar 2 14:26:18 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 2 Mar 2007 14:26:18 +0100 (CET) Subject: [pypy-svn] r39672 - pypy/dist/pypy/doc/config Message-ID: <20070302132618.9BD5A10074@code0.codespeak.net> Author: mwh Date: Fri Mar 2 14:26:17 2007 New Revision: 39672 Modified: pypy/dist/pypy/doc/config/translation.backendopt.mallocs.txt Log: fix a link Modified: pypy/dist/pypy/doc/config/translation.backendopt.mallocs.txt ============================================================================== --- pypy/dist/pypy/doc/config/translation.backendopt.mallocs.txt (original) +++ pypy/dist/pypy/doc/config/translation.backendopt.mallocs.txt Fri Mar 2 14:26:17 2007 @@ -24,6 +24,6 @@ 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" -`__. +read section 4.1 of the technical report on "Massive Parallelism and +Translation Aspects" which you can find on the `Technical reports page +<../index-report.html>`__. From rxe at codespeak.net Fri Mar 2 14:32:58 2007 From: rxe at codespeak.net (rxe at codespeak.net) Date: Fri, 2 Mar 2007 14:32:58 +0100 (CET) Subject: [pypy-svn] r39673 - pypy/dist/pypy/translator/c/test Message-ID: <20070302133258.BB72A10074@code0.codespeak.net> Author: rxe Date: Fri Mar 2 14:32:51 2007 New Revision: 39673 Modified: pypy/dist/pypy/translator/c/test/test_newgc.py pypy/dist/pypy/translator/c/test/test_standalone.py Log: clean up tests for seg faulting dictionary Modified: pypy/dist/pypy/translator/c/test/test_newgc.py ============================================================================== --- pypy/dist/pypy/translator/c/test/test_newgc.py (original) +++ pypy/dist/pypy/translator/c/test/test_newgc.py Fri Mar 2 14:32:51 2007 @@ -860,7 +860,8 @@ res = fn() def test_dict_segfault(self): - py.test.skip("some gc collect failing - somehow") + " was segfaulting at one point see rev 39665 for fix and details " + class Element: pass @@ -872,7 +873,6 @@ for ii in elements: reverse[ii] = ii - # print reverse.get(ii, None) for jj in range(100): e = l[-1] @@ -881,8 +881,8 @@ def f(): for ii in range(100): - print ii dostuff() + return 0 fn = self.getcompiled(f) # the point is just not to segfault Modified: pypy/dist/pypy/translator/c/test/test_standalone.py ============================================================================== --- pypy/dist/pypy/translator/c/test/test_standalone.py (original) +++ pypy/dist/pypy/translator/c/test/test_standalone.py Fri Mar 2 14:32:51 2007 @@ -118,37 +118,3 @@ out = py.process.cmdexec("%s 500" % exe) assert int(out) == 500*501/2 - -def test_dict_segfault(): - py.test.skip('segfaults :(') - class Element: - pass - - elements = [Element() for ii in range(10000)] - - def dostuff(): - reverse = {} - l = elements[:] - - for ii in elements: - reverse[ii] = ii#Element() - - for jj in range(100): - e = l[-1] - del reverse[e] - l.remove(e) - - def f(args): - for ii in range(100): - dostuff() - return 0 - - t = TranslationContext() - t.config.translation.gc = 'framework' - t.buildannotator().build_types(f, [s_list_of_strings]) - t.buildrtyper().specialize() - - cbuilder = CStandaloneBuilder(t, f, t.config) - cbuilder.generate_source() - cbuilder.compile() - data = cbuilder.cmdexec('') From gbrandl at codespeak.net Fri Mar 2 14:41:00 2007 From: gbrandl at codespeak.net (gbrandl at codespeak.net) Date: Fri, 2 Mar 2007 14:41:00 +0100 (CET) Subject: [pypy-svn] r39675 - pypy/dist/pypy/objspace/std Message-ID: <20070302134100.A3F9610084@code0.codespeak.net> Author: gbrandl Date: Fri Mar 2 14:40:58 2007 New Revision: 39675 Modified: pypy/dist/pypy/objspace/std/listmultiobject.py Log: (gbrandl, cfbolz): Better name for empty list method. Modified: pypy/dist/pypy/objspace/std/listmultiobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/listmultiobject.py (original) +++ pypy/dist/pypy/objspace/std/listmultiobject.py Fri Mar 2 14:40:58 2007 @@ -251,7 +251,7 @@ return "RListImplementation(%s)" % (self.list_w, ) class EmptyListImplementation(ListImplementation): - def make_impl(self, w_item): + def make_list_with_one_item(self, w_item): space = self.space if space.config.objspace.std.withfastslice: return SliceTrackingListImplementation(space, [w_item]) @@ -284,13 +284,13 @@ raise IndexError def insert(self, i, w_item): - return self.make_impl(w_item) + return self.make_list_with_one_item(w_item) def add(self, other): return other.copy() def append(self, w_item): - return self.make_impl(w_item) + return self.make_list_with_one_item(w_item) def extend(self, other): return other.copy() From afayolle at codespeak.net Fri Mar 2 14:47:20 2007 From: afayolle at codespeak.net (afayolle at codespeak.net) Date: Fri, 2 Mar 2007 14:47:20 +0100 (CET) Subject: [pypy-svn] r39676 - pypy/dist/pypy/module/recparser Message-ID: <20070302134720.02BF51006E@code0.codespeak.net> Author: afayolle Date: Fri Mar 2 14:47:18 2007 New Revision: 39676 Modified: pypy/dist/pypy/module/recparser/__init__.py pypy/dist/pypy/module/recparser/app_class.py Log: expose ASTVisitor in parser module Modified: pypy/dist/pypy/module/recparser/__init__.py ============================================================================== --- pypy/dist/pypy/module/recparser/__init__.py (original) +++ pypy/dist/pypy/module/recparser/__init__.py Fri Mar 2 14:47:18 2007 @@ -17,6 +17,7 @@ appleveldefs = { 'ParserError' : 'app_class.ParserError', + 'ASTVisitor': 'app_class.ASTVisitor', } interpleveldefs = { '__name__' : '(space.wrap("parser"))', Modified: pypy/dist/pypy/module/recparser/app_class.py ============================================================================== --- pypy/dist/pypy/module/recparser/app_class.py (original) +++ pypy/dist/pypy/module/recparser/app_class.py Fri Mar 2 14:47:18 2007 @@ -6,3 +6,180 @@ """Class ParserError Exception class for parser errors (I assume). """ + +class ASTVisitor(object): + """This is a visitor base class used to provide the visit + method in replacement of the former visitor.visit = walker.dispatch + It could also use to identify base type for visit arguments of AST nodes + """ + + def default(self, node): + for child in node.getChildNodes(): + child.accept(self) + return node + + def visitExpression(self, node): + return self.default(node) + + def visitEmptyNode(self, node): + return self.default(node) + + + def visitAbstractFunction(self, node): + return self.default( node ) + def visitAbstractTest(self, node): + return self.default( node ) + def visitAdd(self, node): + return self.default( node ) + def visitAnd(self, node): + return self.default( node ) + def visitAssAttr(self, node): + return self.default( node ) + def visitAssList(self, node): + return self.default( node ) + def visitAssName(self, node): + return self.default( node ) + def visitAssSeq(self, node): + return self.default( node ) + def visitAssTuple(self, node): + return self.default( node ) + def visitAssert(self, node): + return self.default( node ) + def visitAssign(self, node): + return self.default( node ) + def visitAugAssign(self, node): + return self.default( node ) + def visitBackquote(self, node): + return self.default( node ) + def visitBinaryOp(self, node): + return self.default( node ) + def visitBitOp(self, node): + return self.default( node ) + def visitBitand(self, node): + return self.default( node ) + def visitBitor(self, node): + return self.default( node ) + def visitBitxor(self, node): + return self.default( node ) + def visitBreak(self, node): + return self.default( node ) + def visitCallFunc(self, node): + return self.default( node ) + def visitClass(self, node): + return self.default( node ) + def visitCompare(self, node): + return self.default( node ) + def visitCondExpr(self, node): + return self.default( node ) + def visitConst(self, node): + return self.default( node ) + def visitContinue(self, node): + return self.default( node ) + def visitDecorators(self, node): + return self.default( node ) + def visitDict(self, node): + return self.default( node ) + def visitDiscard(self, node): + return self.default( node ) + def visitDiv(self, node): + return self.default( node ) + def visitEllipsis(self, node): + return self.default( node ) + def visitExec(self, node): + return self.default( node ) + def visitFloorDiv(self, node): + return self.default( node ) + def visitFor(self, node): + return self.default( node ) + def visitFrom(self, node): + return self.default( node ) + def visitFunction(self, node): + return self.default( node ) + def visitGenExpr(self, node): + return self.default( node ) + def visitGenExprFor(self, node): + return self.default( node ) + def visitGenExprIf(self, node): + return self.default( node ) + def visitGenExprInner(self, node): + return self.default( node ) + def visitGetattr(self, node): + return self.default( node ) + def visitGlobal(self, node): + return self.default( node ) + def visitIf(self, node): + return self.default( node ) + def visitImport(self, node): + return self.default( node ) + def visitInvert(self, node): + return self.default( node ) + def visitKeyword(self, node): + return self.default( node ) + def visitLambda(self, node): + return self.default( node ) + def visitLeftShift(self, node): + return self.default( node ) + def visitList(self, node): + return self.default( node ) + def visitListComp(self, node): + return self.default( node ) + def visitListCompFor(self, node): + return self.default( node ) + def visitListCompIf(self, node): + return self.default( node ) + def visitMod(self, node): + return self.default( node ) + def visitModule(self, node): + return self.default( node ) + def visitMul(self, node): + return self.default( node ) + def visitName(self, node): + return self.default( node ) + def visitNoneConst(self, node): + return self.default( node ) + def visitNot(self, node): + return self.default( node ) + def visitOr(self, node): + return self.default( node ) + def visitPass(self, node): + return self.default( node ) + def visitPower(self, node): + return self.default( node ) + def visitPrint(self, node): + return self.default( node ) + def visitPrintnl(self, node): + return self.default( node ) + def visitRaise(self, node): + return self.default( node ) + def visitReturn(self, node): + return self.default( node ) + def visitRightShift(self, node): + return self.default( node ) + def visitSlice(self, node): + return self.default( node ) + def visitSliceobj(self, node): + return self.default( node ) + def visitStmt(self, node): + return self.default( node ) + def visitSub(self, node): + return self.default( node ) + def visitSubscript(self, node): + return self.default( node ) + def visitTryExcept(self, node): + return self.default( node ) + def visitTryFinally(self, node): + return self.default( node ) + def visitTuple(self, node): + return self.default( node ) + def visitUnaryAdd(self, node): + return self.default( node ) + def visitUnaryOp(self, node): + return self.default( node ) + def visitUnarySub(self, node): + return self.default( node ) + def visitWhile(self, node): + return self.default( node ) + def visitWith(self, node): + return self.default( node ) + def visitYield(self, node): + return self.default( node ) From arigo at codespeak.net Fri Mar 2 14:54:33 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 2 Mar 2007 14:54:33 +0100 (CET) Subject: [pypy-svn] r39677 - pypy/dist/pypy/module/readline Message-ID: <20070302135433.9469A10113@code0.codespeak.net> Author: arigo Date: Fri Mar 2 14:54:30 2007 New Revision: 39677 Modified: pypy/dist/pypy/module/readline/c_readline.py Log: (hpk, arigo) Add history to the pypy-c prompt. Modified: pypy/dist/pypy/module/readline/c_readline.py ============================================================================== --- pypy/dist/pypy/module/readline/c_readline.py (original) +++ pypy/dist/pypy/module/readline/c_readline.py Fri Mar 2 14:54:30 2007 @@ -9,7 +9,7 @@ # class CConfig: _header_ = "" - _includes_ = ["readline/readline.h"] + _includes_ = ["readline/readline.h", "readline/history.h"] readline = Library('readline') cconfig = configure(CConfig) @@ -27,11 +27,27 @@ c_rl_initialize.argtypes = [] c_rl_initialize.restype = None +# void using_history(void) +c_using_history = libreadline.using_history +c_using_history.argtypes = [] +c_using_history.restype = None + +# void add_history(const char *) +c_add_history = libreadline.add_history +c_add_history.argtypes = [c_char_p] +c_add_history.restype = None + #------------------------------------------------------------ # special initialization of readline +class ReadlineState(object): + lastline = "" # XXX possibly temporary hack +readlinestate = ReadlineState() + def setup_readline(space, w_module): + c_using_history() + # XXX CPython initializes more stuff here c_rl_initialize() # install sys.__raw_input__, a hook that will be used by raw_input() space.setitem(space.sys.w_dict, space.wrap('__raw_input__'), @@ -41,6 +57,10 @@ res = c_readline(prompt) if res is None: raise OperationError(space.w_EOFError, space.w_None) + if res and res != readlinestate.lastline: + readlinestate.lastline = res + c_add_history(res) return space.wrap(res) + readline_func.unwrap_spec = [ObjSpace, str] app_readline_func = interp2app(readline_func) From santagada at codespeak.net Fri Mar 2 14:58:26 2007 From: santagada at codespeak.net (santagada at codespeak.net) Date: Fri, 2 Mar 2007 14:58:26 +0100 (CET) Subject: [pypy-svn] r39678 - in pypy/dist/pypy/lang/js: . test/ecma Message-ID: <20070302135826.052071013C@code0.codespeak.net> Author: santagada Date: Fri Mar 2 14:58:24 2007 New Revision: 39678 Modified: pypy/dist/pypy/lang/js/interpreter.py pypy/dist/pypy/lang/js/jsobj.py pypy/dist/pypy/lang/js/test/ecma/shell.js Log: new shift operators and math.pow Modified: pypy/dist/pypy/lang/js/interpreter.py ============================================================================== --- pypy/dist/pypy/lang/js/interpreter.py (original) +++ pypy/dist/pypy/lang/js/interpreter.py Fri Mar 2 14:58:24 2007 @@ -3,6 +3,7 @@ from pypy.lang.js.jsparser import parse, parse_bytecode from pypy.lang.js.jsobj import * from pypy.rlib.parsing.ebnfparse import Symbol, Nonterminal +from pypy.rlib.rarithmetic import r_uint class Node(object): opcode = None @@ -156,6 +157,9 @@ def floorjs(ctx, args, this): return W_Number(math.floor(args[0].ToNumber())) +def powjs(ctx, args, this): + return W_Number(math.pow(args[0].ToNumber(), args[1].ToNumber())) + def versionjs(ctx, args, this): return w_Undefined @@ -187,6 +191,7 @@ w_math.Put('__proto__', w_ObjPrototype) w_math.Put('abs', W_Builtin(absjs, Class='function')) w_math.Put('floor', W_Builtin(floorjs, Class='function')) + w_math.Put('pow', W_Builtin(powjs, Class='function')) w_math.Put('E', W_Number(math.e)) w_math.Put('PI', W_Number(math.pi)) @@ -351,6 +356,7 @@ r7 = None else: r7 = r6 + retval = r3.Call(ctx=ctx, args=r2.get_args(), this=r7) return retval @@ -482,6 +488,30 @@ s4 = self.right.eval(ctx).GetValue() return s4 +class Ursh(BinaryComparisonOp): + opcode = 'URSH' + + def decision(self, ctx, op1, op2): + a = op1.ToInt32() + b = op2.ToInt32() + return W_Number(r_uint(a) >> (r_uint(b) & 0x1F)) + +class Rsh(BinaryComparisonOp): + opcode = 'RSH' + + def decision(self, ctx, op1, op2): + a = op1.ToInt32() + b = op2.ToInt32() + return W_Number(a >> int(r_uint(b) & 0x1F)) + +class Lsh(BinaryComparisonOp): + opcode = 'LSH' + + def decision(self, ctx, op1, op2): + a = op1.ToInt32() + b = op2.ToInt32() + return W_Number(a << int(r_uint(b) & 0x1F)) + class Ge(BinaryComparisonOp): opcode = 'GE' @@ -842,6 +872,7 @@ ctx.variable.Put(var.name, w_Undefined) for fun in self.func_decl: ctx.variable.Put(fun.name, fun.eval(ctx)) + node = self Modified: pypy/dist/pypy/lang/js/jsobj.py ============================================================================== --- pypy/dist/pypy/lang/js/jsobj.py (original) +++ pypy/dist/pypy/lang/js/jsobj.py Fri Mar 2 14:58:24 2007 @@ -395,6 +395,12 @@ return 'number' def ToInt32(self): + strval = str(self.floatval) + if strval == str(NaN) or \ + strval == str(Infinity) or \ + strval == str(-Infinity): + return 0 + return int(self.floatval) class W_List(W_Root): 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 Fri Mar 2 14:58:24 2007 @@ -50,7 +50,7 @@ var PASSED = " PASSED!" var FAILED = " FAILED! expected: "; -var DEBUG = true; +var DEBUG = false; var DESCRIPTION; var EXPECTED; @@ -218,7 +218,7 @@ } function writeHeaderToLog( string ) { - print( string ); + // print( string ); } /* end of print functions */ From santagada at codespeak.net Fri Mar 2 15:04:09 2007 From: santagada at codespeak.net (santagada at codespeak.net) Date: Fri, 2 Mar 2007 15:04:09 +0100 (CET) Subject: [pypy-svn] r39679 - pypy/dist/pypy/lang/js Message-ID: <20070302140409.9127B10113@code0.codespeak.net> Author: santagada Date: Fri Mar 2 15:04:05 2007 New Revision: 39679 Modified: pypy/dist/pypy/lang/js/interpreter.py Log: the math here is wrong, waiting for support from rlib Modified: pypy/dist/pypy/lang/js/interpreter.py ============================================================================== --- pypy/dist/pypy/lang/js/interpreter.py (original) +++ pypy/dist/pypy/lang/js/interpreter.py Fri Mar 2 15:04:05 2007 @@ -494,7 +494,7 @@ def decision(self, ctx, op1, op2): a = op1.ToInt32() b = op2.ToInt32() - return W_Number(r_uint(a) >> (r_uint(b) & 0x1F)) + return W_Number(int(r_uint(a) >> (r_uint(b) & 0x1F))) class Rsh(BinaryComparisonOp): opcode = 'RSH' From arigo at codespeak.net Fri Mar 2 15:10:44 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 2 Mar 2007 15:10:44 +0100 (CET) Subject: [pypy-svn] r39680 - in pypy/dist/pypy: rlib rlib/test rpython/test Message-ID: <20070302141044.A736A10113@code0.codespeak.net> Author: arigo Date: Fri Mar 2 15:10:42 2007 New Revision: 39680 Modified: pypy/dist/pypy/rlib/rarithmetic.py pypy/dist/pypy/rlib/test/test_rarithmetic.py pypy/dist/pypy/rpython/test/test_rfloat.py Log: Support for direct casts between float and r_uint. Actually worked already during translation, but not on top of CPython. Modified: pypy/dist/pypy/rlib/rarithmetic.py ============================================================================== --- pypy/dist/pypy/rlib/rarithmetic.py (original) +++ pypy/dist/pypy/rlib/rarithmetic.py Fri Mar 2 15:10:42 2007 @@ -267,6 +267,8 @@ class signed_int(base_int): SIGNED = True def __new__(klass, val=0): + if type(val) is float: + val = long(val) if val > klass.MASK>>1 or val < -(klass.MASK>>1)-1: raise OverflowError("%s does not fit in signed %d-bit integer"%(val, klass.BITS)) if val < 0: @@ -277,6 +279,8 @@ class unsigned_int(base_int): SIGNED = False def __new__(klass, val=0): + if type(val) is float: + val = long(val) return super(unsigned_int, klass).__new__(klass, val & klass.MASK) typemap = {} Modified: pypy/dist/pypy/rlib/test/test_rarithmetic.py ============================================================================== --- pypy/dist/pypy/rlib/test/test_rarithmetic.py (original) +++ pypy/dist/pypy/rlib/test/test_rarithmetic.py Fri Mar 2 15:10:42 2007 @@ -139,6 +139,15 @@ res = res & mask assert res == cmp + def test_from_float(self): + assert r_uint(2.3) == 2 + assert r_uint(sys.maxint * 1.234) == long(sys.maxint * 1.234) + + def test_to_float(self): + assert float(r_uint(2)) == 2.0 + val = long(sys.maxint * 1.234) + assert float(r_uint(val)) == float(val) + def test_mixed_types(): types = [r_uint, r_ulonglong] for left in types: Modified: pypy/dist/pypy/rpython/test/test_rfloat.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_rfloat.py (original) +++ pypy/dist/pypy/rpython/test/test_rfloat.py Fri Mar 2 15:10:42 2007 @@ -1,6 +1,8 @@ +import sys from pypy.translator.translator import TranslationContext from pypy.rpython.test import snippet from pypy.rpython.test.tool import BaseRtypingTest, LLRtypeMixin, OORtypeMixin +from pypy.rlib.rarithmetic import r_uint class TestSnippet(object): @@ -58,6 +60,25 @@ res = self.interpret(fn, [2.34]) assert res == fn(2.34) + def test_to_r_uint(self): + def fn(x): + return r_uint(x) + + res = self.interpret(fn, [12.34]) + assert res == 12 + bigval = sys.maxint * 1.234 + res = self.interpret(fn, [bigval]) + assert long(res) == long(bigval) + + def test_from_r_uint(self): + def fn(n): + return float(r_uint(n)) / 2 + + res = self.interpret(fn, [41]) + assert res == 20.5 + res = self.interpret(fn, [-9]) + assert res == 0.5 * ((sys.maxint+1)*2 - 9) + class TestLLtype(BaseTestRfloat, LLRtypeMixin): From hpk at codespeak.net Fri Mar 2 15:12:37 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Fri, 2 Mar 2007 15:12:37 +0100 (CET) Subject: [pypy-svn] r39681 - in pypy/dist/pypy/objspace/std: . test Message-ID: <20070302141237.4D4E710121@code0.codespeak.net> Author: hpk Date: Fri Mar 2 15:12:33 2007 New Revision: 39681 Removed: pypy/dist/pypy/objspace/std/autopath.py pypy/dist/pypy/objspace/std/test/autopath.py Modified: pypy/dist/pypy/objspace/std/test/test_boolobject.py pypy/dist/pypy/objspace/std/test/test_complexobject.py pypy/dist/pypy/objspace/std/test/test_dictmultiobject.py pypy/dist/pypy/objspace/std/test/test_dictobject.py pypy/dist/pypy/objspace/std/test/test_dictproxy.py pypy/dist/pypy/objspace/std/test/test_dictstrobject.py pypy/dist/pypy/objspace/std/test/test_floatobject.py pypy/dist/pypy/objspace/std/test/test_instmethobject.py pypy/dist/pypy/objspace/std/test/test_intobject.py pypy/dist/pypy/objspace/std/test/test_iterobject.py pypy/dist/pypy/objspace/std/test/test_listmultiobject.py pypy/dist/pypy/objspace/std/test/test_listobject.py pypy/dist/pypy/objspace/std/test/test_longobject.py pypy/dist/pypy/objspace/std/test/test_multimethod.py pypy/dist/pypy/objspace/std/test/test_noneobject.py pypy/dist/pypy/objspace/std/test/test_rangeobject.py pypy/dist/pypy/objspace/std/test/test_set.py pypy/dist/pypy/objspace/std/test/test_sliceobject.py pypy/dist/pypy/objspace/std/test/test_smallintobject.py pypy/dist/pypy/objspace/std/test/test_stdobjspace.py pypy/dist/pypy/objspace/std/test/test_stringformat.py pypy/dist/pypy/objspace/std/test/test_stringobject.py pypy/dist/pypy/objspace/std/test/test_strjoinobject.py pypy/dist/pypy/objspace/std/test/test_strsliceobject.py pypy/dist/pypy/objspace/std/test/test_strutil.py pypy/dist/pypy/objspace/std/test/test_tupleobject.py pypy/dist/pypy/objspace/std/test/test_typeobject.py pypy/dist/pypy/objspace/std/test/test_unicodeobject.py pypy/dist/pypy/objspace/std/test/test_userobject.py Log: removing autopath from std object space and fixing an escaping issue in test_complexobject.py (hopefully) Modified: pypy/dist/pypy/objspace/std/test/test_boolobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/test/test_boolobject.py (original) +++ pypy/dist/pypy/objspace/std/test/test_boolobject.py Fri Mar 2 15:12:33 2007 @@ -1,4 +1,3 @@ -import autopath Modified: pypy/dist/pypy/objspace/std/test/test_complexobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/test/test_complexobject.py (original) +++ pypy/dist/pypy/objspace/std/test/test_complexobject.py Fri Mar 2 15:12:33 2007 @@ -1,4 +1,3 @@ -import autopath import py from pypy.objspace.std import complexobject as cobj from pypy.objspace.std import complextype as cobjtype @@ -60,7 +59,13 @@ class AppTestAppComplexTest: def setup_class(cls): - cls.w_helper = cls.space.appexec([], "():\n import sys\n sys.path.append('%s')\n import helper\n return helper" % (str(py.magic.autopath().dirpath()).replace('\\', '\\\\'), )) + cls.w_helper = cls.space.appexec([], """ + (): + import sys + sys.path.append(%r) + import helper + return helper + """ % (str(py.magic.autopath().dirpath()))) def test_div(self): h = self.helper Modified: pypy/dist/pypy/objspace/std/test/test_dictmultiobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/test/test_dictmultiobject.py (original) +++ pypy/dist/pypy/objspace/std/test/test_dictmultiobject.py Fri Mar 2 15:12:33 2007 @@ -1,4 +1,3 @@ -import autopath from pypy.interpreter.error import OperationError from pypy.objspace.std.dictmultiobject import \ W_DictMultiObject, setitem__DictMulti_ANY_ANY, getitem__DictMulti_ANY, \ Modified: pypy/dist/pypy/objspace/std/test/test_dictobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/test/test_dictobject.py (original) +++ pypy/dist/pypy/objspace/std/test/test_dictobject.py Fri Mar 2 15:12:33 2007 @@ -1,4 +1,3 @@ -import autopath from pypy.objspace.std.dictobject import W_DictObject from pypy.conftest import gettestobjspace Modified: pypy/dist/pypy/objspace/std/test/test_dictproxy.py ============================================================================== --- pypy/dist/pypy/objspace/std/test/test_dictproxy.py (original) +++ pypy/dist/pypy/objspace/std/test/test_dictproxy.py Fri Mar 2 15:12:33 2007 @@ -1,4 +1,3 @@ -import autopath class AppTestUserObject: Modified: pypy/dist/pypy/objspace/std/test/test_dictstrobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/test/test_dictstrobject.py (original) +++ pypy/dist/pypy/objspace/std/test/test_dictstrobject.py Fri Mar 2 15:12:33 2007 @@ -1,4 +1,3 @@ -import autopath from pypy.objspace.std.dictstrobject import W_DictStrObject, setitem__DictStr_ANY_ANY, getitem__DictStr_ANY from pypy.conftest import gettestobjspace from pypy.objspace.std.test import test_dictobject Modified: pypy/dist/pypy/objspace/std/test/test_floatobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/test/test_floatobject.py (original) +++ pypy/dist/pypy/objspace/std/test/test_floatobject.py Fri Mar 2 15:12:33 2007 @@ -1,4 +1,3 @@ -import autopath from pypy.objspace.std import floatobject as fobj from pypy.objspace.std.objspace import FailedToImplement import py Modified: pypy/dist/pypy/objspace/std/test/test_instmethobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/test/test_instmethobject.py (original) +++ pypy/dist/pypy/objspace/std/test/test_instmethobject.py Fri Mar 2 15:12:33 2007 @@ -1,4 +1,3 @@ -import autopath # NB. instmethobject.py has been removed, # but the following tests still make sense 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 Fri Mar 2 15:12:33 2007 @@ -1,5 +1,4 @@ import sys -import autopath from pypy.objspace.std import intobject as iobj from pypy.objspace.std.objspace import FailedToImplement from pypy.rlib.rarithmetic import r_uint Modified: pypy/dist/pypy/objspace/std/test/test_iterobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/test/test_iterobject.py (original) +++ pypy/dist/pypy/objspace/std/test/test_iterobject.py Fri Mar 2 15:12:33 2007 @@ -1,4 +1,3 @@ -import autopath from pypy.objspace.std.iterobject import W_SeqIterObject from pypy.interpreter.error import OperationError 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 Fri Mar 2 15:12:33 2007 @@ -1,4 +1,3 @@ -import autopath from pypy.interpreter.error import OperationError from pypy.objspace.std.listmultiobject import W_ListMultiObject, \ SliceTrackingListImplementation 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 Mar 2 15:12:33 2007 @@ -1,4 +1,4 @@ -import autopath, random +import random from pypy.objspace.std.listobject import W_ListObject from pypy.interpreter.error import OperationError Modified: pypy/dist/pypy/objspace/std/test/test_longobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/test/test_longobject.py (original) +++ pypy/dist/pypy/objspace/std/test/test_longobject.py Fri Mar 2 15:12:33 2007 @@ -1,4 +1,3 @@ -import autopath import py import sys from pypy.objspace.std import longobject as lobj Modified: pypy/dist/pypy/objspace/std/test/test_multimethod.py ============================================================================== --- pypy/dist/pypy/objspace/std/test/test_multimethod.py (original) +++ pypy/dist/pypy/objspace/std/test/test_multimethod.py Fri Mar 2 15:12:33 2007 @@ -1,4 +1,3 @@ -import autopath from py.test import raises from pypy.objspace.std import multimethod Modified: pypy/dist/pypy/objspace/std/test/test_noneobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/test/test_noneobject.py (original) +++ pypy/dist/pypy/objspace/std/test/test_noneobject.py Fri Mar 2 15:12:33 2007 @@ -1,4 +1,3 @@ -import autopath 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 Mar 2 15:12:33 2007 @@ -1,4 +1,4 @@ -import autopath, py +import py from pypy.conftest import gettestobjspace 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 Fri Mar 2 15:12:33 2007 @@ -7,7 +7,6 @@ This file just contains some basic tests that make sure, the implementation is not too wrong. """ -import autopath import py.test from pypy.objspace.std.setobject import W_SetObject, W_FrozensetObject from pypy.objspace.std.setobject import _initialize_set Modified: pypy/dist/pypy/objspace/std/test/test_sliceobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/test/test_sliceobject.py (original) +++ pypy/dist/pypy/objspace/std/test/test_sliceobject.py Fri Mar 2 15:12:33 2007 @@ -1,4 +1,3 @@ -import autopath class TestW_SliceObject: Modified: pypy/dist/pypy/objspace/std/test/test_smallintobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/test/test_smallintobject.py (original) +++ pypy/dist/pypy/objspace/std/test/test_smallintobject.py Fri Mar 2 15:12:33 2007 @@ -1,5 +1,4 @@ import sys, py -import autopath #from pypy.objspace.std.model import WITHSMALLINT #if not WITHSMALLINT: Modified: pypy/dist/pypy/objspace/std/test/test_stdobjspace.py ============================================================================== --- pypy/dist/pypy/objspace/std/test/test_stdobjspace.py (original) +++ pypy/dist/pypy/objspace/std/test/test_stdobjspace.py Fri Mar 2 15:12:33 2007 @@ -1,4 +1,3 @@ -import autopath from pypy.interpreter.error import OperationError Modified: pypy/dist/pypy/objspace/std/test/test_stringformat.py ============================================================================== --- pypy/dist/pypy/objspace/std/test/test_stringformat.py (original) +++ pypy/dist/pypy/objspace/std/test/test_stringformat.py Fri Mar 2 15:12:33 2007 @@ -1,4 +1,3 @@ -import autopath class AppTestStringObjectWithDict: Modified: pypy/dist/pypy/objspace/std/test/test_stringobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/test/test_stringobject.py (original) +++ pypy/dist/pypy/objspace/std/test/test_stringobject.py Fri Mar 2 15:12:33 2007 @@ -1,4 +1,3 @@ -import autopath from pypy.objspace.std import stringobject from pypy.objspace.std.stringobject import W_StringObject 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 Fri Mar 2 15:12:33 2007 @@ -1,4 +1,4 @@ -import autopath, py +import py from pypy.objspace.std.test import test_stringobject from pypy.conftest import gettestobjspace Modified: pypy/dist/pypy/objspace/std/test/test_strsliceobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/test/test_strsliceobject.py (original) +++ pypy/dist/pypy/objspace/std/test/test_strsliceobject.py Fri Mar 2 15:12:33 2007 @@ -1,4 +1,4 @@ -import autopath, py +import py from pypy.objspace.std.test import test_stringobject from pypy.conftest import gettestobjspace Modified: pypy/dist/pypy/objspace/std/test/test_strutil.py ============================================================================== --- pypy/dist/pypy/objspace/std/test/test_strutil.py (original) +++ pypy/dist/pypy/objspace/std/test/test_strutil.py Fri Mar 2 15:12:33 2007 @@ -1,4 +1,3 @@ -import autopath import py, random from pypy.objspace.std.strutil import * Modified: pypy/dist/pypy/objspace/std/test/test_tupleobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/test/test_tupleobject.py (original) +++ pypy/dist/pypy/objspace/std/test/test_tupleobject.py Fri Mar 2 15:12:33 2007 @@ -1,5 +1,4 @@ #from __future__ import nested_scopes -import autopath from pypy.objspace.std.tupleobject import W_TupleObject from pypy.interpreter.error import OperationError Modified: pypy/dist/pypy/objspace/std/test/test_typeobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/test/test_typeobject.py (original) +++ pypy/dist/pypy/objspace/std/test/test_typeobject.py Fri Mar 2 15:12:33 2007 @@ -1,4 +1,3 @@ -import autopath from pypy.objspace.std.objspace import * from pypy.objspace.std.stdtypedef import * 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 Fri Mar 2 15:12:33 2007 @@ -1,4 +1,4 @@ -import autopath, sys +import sys class AppTestUnicodeStringStdOnly: Modified: pypy/dist/pypy/objspace/std/test/test_userobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/test/test_userobject.py (original) +++ pypy/dist/pypy/objspace/std/test/test_userobject.py Fri Mar 2 15:12:33 2007 @@ -1,4 +1,3 @@ -import autopath class AppTestUserObject: From antocuni at codespeak.net Fri Mar 2 15:12:59 2007 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Fri, 2 Mar 2007 15:12:59 +0100 (CET) Subject: [pypy-svn] r39682 - pypy/dist/pypy/annotation Message-ID: <20070302141259.7967610121@code0.codespeak.net> Author: antocuni Date: Fri Mar 2 15:12:58 2007 New Revision: 39682 Modified: pypy/dist/pypy/annotation/builtin.py Log: (antocuni, pedronis) try to make the memory used by the annotator not linear in the length of the range(). Modified: pypy/dist/pypy/annotation/builtin.py ============================================================================== --- pypy/dist/pypy/annotation/builtin.py (original) +++ pypy/dist/pypy/annotation/builtin.py Fri Mar 2 15:12:58 2007 @@ -65,7 +65,7 @@ if step == 0: raise Exception, "range() with step zero" if s_start.is_constant() and s_stop.is_constant(): - if len(range(s_start.const, s_stop.const, step)) == 0: + if len(xrange(s_start.const, s_stop.const, step)) == 0: empty = True if empty: s_item = s_ImpossibleValue From cfbolz at codespeak.net Fri Mar 2 15:18:48 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 2 Mar 2007 15:18:48 +0100 (CET) Subject: [pypy-svn] r39683 - pypy/dist/pypy/doc/config Message-ID: <20070302141848.8F74510120@code0.codespeak.net> Author: cfbolz Date: Fri Mar 2 15:18:46 2007 New Revision: 39683 Added: pypy/dist/pypy/doc/config/objspace.std.withsmartresizablelist.txt Log: (cfbolz, gbrandl): add documentation for the new option Added: pypy/dist/pypy/doc/config/objspace.std.withsmartresizablelist.txt ============================================================================== --- (empty file) +++ pypy/dist/pypy/doc/config/objspace.std.withsmartresizablelist.txt Fri Mar 2 15:18:46 2007 @@ -0,0 +1,4 @@ +Enable a list implementation that overallocates only O(sqrt(n)) elements +instead of O(n) elements. See "Resizable Arrays in Optimal time and Space" +Brodnik, Carlsson, Demaine, Munro, Sedgewick, 1999 + From mwh at codespeak.net Fri Mar 2 15:20:16 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 2 Mar 2007 15:20:16 +0100 (CET) Subject: [pypy-svn] r39684 - pypy/dist/pypy/doc Message-ID: <20070302142016.707941013F@code0.codespeak.net> Author: mwh Date: Fri Mar 2 15:20:13 2007 New Revision: 39684 Modified: pypy/dist/pypy/doc/faq.txt Log: reword the first two FAQ entries Modified: pypy/dist/pypy/doc/faq.txt ============================================================================== --- pypy/dist/pypy/doc/faq.txt (original) +++ pypy/dist/pypy/doc/faq.txt Fri Mar 2 15:20:13 2007 @@ -12,12 +12,16 @@ What is PyPy? ------------- -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`_ . +PyPy is both: + + - a reimplementation of Python in Python, and + + - a framework for implementing interpreters and virtual machines for + programming languages, especially dynamic languages. + +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`_ . .. _`goal and architecture document`: architecture.html @@ -28,11 +32,16 @@ Is PyPy a drop in replacement for CPython? ------------------------------------------ -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. +Not completely, at least not yet. + +The mostly likely stumbling block for any given project is support for +`extension modules`_. PyPy supports a small but continually growing +number of extension modules, so far mostly those found in the standard +library. The `threading` support is also not perfectly complete. + +The language features (including builtin types and functions) are very +complete and well tested, so if your project does not use many +extension modules there is a good chance that it will work with PyPy. -------------------------------- On what platforms does PyPy run? From cfbolz at codespeak.net Fri Mar 2 15:24:51 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 2 Mar 2007 15:24:51 +0100 (CET) Subject: [pypy-svn] r39685 - in pypy/dist/pypy: config objspace/std objspace/std/test Message-ID: <20070302142451.031A910147@code0.codespeak.net> Author: cfbolz Date: Fri Mar 2 15:24:42 2007 New Revision: 39685 Added: pypy/dist/pypy/objspace/std/smartresizablelist.py Modified: pypy/dist/pypy/config/pypyoption.py pypy/dist/pypy/objspace/std/listmultiobject.py pypy/dist/pypy/objspace/std/test/test_listmultiobject.py Log: (cfbolz, gbrandl): implement list overallocation with O(sqrt(n)) elements. Modified: pypy/dist/pypy/config/pypyoption.py ============================================================================== --- pypy/dist/pypy/config/pypyoption.py (original) +++ pypy/dist/pypy/config/pypyoption.py Fri Mar 2 15:24:42 2007 @@ -182,6 +182,10 @@ "make list slicing lazy", default=False, requires=[("objspace.std.withmultilist", True)]), + BoolOption("withsmartresizablelist", + "only overallocate O(sqrt(n)) elements for lists", + 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/objspace/std/listmultiobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/listmultiobject.py (original) +++ pypy/dist/pypy/objspace/std/listmultiobject.py Fri Mar 2 15:24:42 2007 @@ -178,6 +178,12 @@ def make_implementation(self, list_w): space = self.space + if space.config.objspace.std.withsmartresizablelist: + from pypy.objspace.std.smartresizablelist import \ + SmartResizableListImplementation + impl = SmartResizableListImplementation(space) + impl.extend(RListImplementation(space, list_w)) + return impl if space.config.objspace.std.withfastslice: return SliceTrackingListImplementation(space, list_w) else: @@ -657,6 +663,7 @@ 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])): @@ -665,6 +672,12 @@ def make_implementation(space, list_w): if list_w: + if space.config.objspace.std.withsmartresizablelist: + from pypy.objspace.std.smartresizablelist import \ + SmartResizableListImplementation + impl = SmartResizableListImplementation(space) + impl.extend(RListImplementation(space, list_w)) + return impl if space.config.objspace.std.withfastslice: impl = SliceTrackingListImplementation(space, list_w) else: Added: pypy/dist/pypy/objspace/std/smartresizablelist.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/objspace/std/smartresizablelist.py Fri Mar 2 15:24:42 2007 @@ -0,0 +1,231 @@ +# implement resizable arrays +# see "Resizable Arrays in Optimal time and Space" +# Brodnik, Carlsson, Demaine, Munro, Sedgewick, 1999 + +from pypy.objspace.std.listmultiobject import ListImplementation +import sys +import math +LOG2 = math.log(2) +NBITS = int(math.log(sys.maxint) / LOG2) + 2 +LSBSTEPS = int(math.log(NBITS) / LOG2) + 1 + +def leftmost_set_bit(i): + # return int(math.log(i) / LOG2) + # do something fancy? + assert i > 0 + shift = NBITS // 2 + result = 0 + for x in range(LSBSTEPS): + newi = i >> shift + if newi: + result += shift + i = newi + shift //= 2 + return result + +def decompose(i, k): + halfk_lower = k // 2 + halfk_upper = halfk_lower + (k & 1) + mask1 = ((1 << halfk_lower) - 1) << halfk_upper + mask2 = ((1 << halfk_upper) - 1) + assert mask1 + mask2 == ((1 << k) - 1) + return ((i & mask1) >> halfk_upper), i & mask2 + +def find_block_index(i): + if i == 0: + return (0, 0) + k = leftmost_set_bit(i + 1) + b, e = decompose(i + 1, k) + x = k + m = (1 << (x // 2 + 1)) - 2 + (x & 1) * (1 << (x // 2)) + return m + b, e + +class FreeList(object): + def __init__(self): + self.freelist = {} + + def alloc(self, size): + l = self.freelist.get(size) + if l is not None and l: + return l.pop() + return [None] * size + + def dealloc(self, l): + size = len(l) + if size >= 2 ** 20: + return + if size in self.freelist: + self.freelist[size].append(l) + else: + self.freelist[size] = [l] + +class SmartResizableListImplementation(ListImplementation): + def __init__(self, space): + self._length = 0 + self.size_superblock = 1 + self.size_datablock = 1 + self.num_superblocks = 1 # "s" in the paper + self.num_datablocks = 1 # "d" in the paper + self.last_superblock_filled = 1 + self.index_last = 0 # number of elements occupying last data block + self.data_blocks = [[None] * 1] + self.space = space + + def length(self): + return self._length + + def grow(self, items=1): + data_blocks = self.data_blocks + self._length += items + idx = self.num_datablocks - 1 + assert idx >= 0 + free_in_last_datablock = len(data_blocks[idx]) - self.index_last + while items > free_in_last_datablock: + items -= free_in_last_datablock + free_in_last_datablock = self.grow_block() + self.index_last += items + return (self.num_datablocks - 1, self.index_last - 1) + + def grow_block(self): + data_blocks = self.data_blocks + if self.last_superblock_filled == self.size_superblock: + self.num_superblocks += 1 + if self.num_superblocks % 2 == 1: + self.size_superblock *= 2 + else: + self.size_datablock *= 2 + self.last_superblock_filled = 0 + if len(data_blocks) == self.num_datablocks: + data_blocks.append([None] * self.size_datablock) + self.last_superblock_filled += 1 + self.num_datablocks += 1 + self.index_last = 0 + return self.size_datablock + + def shrink(self, items=1): + if items > self._length: + raise ValueError("cannot shrink by more items than the list has") + self._length -= items + data_blocks = self.data_blocks + while items > self.index_last: + items -= self.index_last + self.shrink_block() + self.index_last -= items + idx = self.num_datablocks - 1 + assert idx >= 0 + data_block = data_blocks[idx] + while items: + idx = self.index_last - 1 + items + assert idx >= 0 + data_block[idx] = None + items -= 1 + + def shrink_block(self): + data_blocks = self.data_blocks + if len(data_blocks) > self.num_datablocks: + assert len(data_blocks) - self.num_datablocks == 1 + data_blocks.pop() + for i in range(self.index_last): #XXX consider when not to do this + idx = self.num_datablocks - 1 + assert idx >= 0 + data_blocks[idx][i] = None + self.num_datablocks -= 1 + self.last_superblock_filled -= 1 + if self.last_superblock_filled == 0: + self.num_superblocks -= 1 + if self.num_superblocks % 2 == 0: + self.size_superblock //= 2 + else: + self.size_datablock //= 2 + self.last_superblock_filled = self.size_superblock + self.index_last = len(data_blocks[-2]) + + def getitem(self, i): + a, b = find_block_index(i) + return self.getitem_raw(a, b) + + def getitem_raw(self, a, b): + assert a >= 0 + assert b >= 0 + return self.data_blocks[a][b] + + def setitem(self, i, value): + a, b = find_block_index(i) + return self.setitem_raw(a, b, value) + + def setitem_raw(self, a, b, value): + assert a >= 0 + assert b >= 0 + self.data_blocks[a][b] = value + + def getitem_slice(self, start, stop): + # XXX make default implementation? + l = stop - start + result = SmartResizableListImplementation(self.space) + result.grow(l) + for i in range(l): + result.setitem(i, self.getitem(i + start)) + return result + + def insert(self, i, w_item): + self.grow() + for x in range(self._length - 1, i - 1, -1): + self.setitem(x + 1, self.getitem(x)) + self.setitem(i, w_item) + return self + + def delitem(self, index): + for x in range(index + 1, self._length): + self.setitem(x - 1, self.getitem(x)) + self.shrink() + return self + + def delitem_slice(self, start, stop): + slicelength = stop - start + for x in range(stop, self._length): + self.setitem(x - slicelength, self.getitem(x)) + self.shrink(slicelength) + return self + + def append(self, w_item): + a, b = self.grow() + self.setitem_raw(a, b, w_item) + return self + + def extend(self, other): + selflength = self._length + length = other.length() + self.grow(length) + for i in range(length): + self.setitem(selflength + i, other.getitem(i)) + return self + +# special cases: + + def add(self, other): + result = self.copy() + result.extend(other) + return result + + def get_list_w(self): + l = self._length + result = [None] * l + for i in range(l): + result[i] = self.getitem(i) + return result + +# default implementations, can (but don't have to be) overridden: + + def copy(self): + from pypy.rlib.objectmodel import instantiate + result = instantiate(SmartResizableListImplementation) + result._length = self._length + result.size_superblock = self.size_superblock + result.size_datablock = self.size_datablock + result.num_superblocks = self.num_superblocks + result.num_datablocks = self.num_datablocks + result.last_superblock_filled = self.last_superblock_filled + result.index_last = self.index_last + result.data_blocks = [l[:] for l in self.data_blocks] + result.space = self.space + return result 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 Fri Mar 2 15:24:42 2007 @@ -114,3 +114,7 @@ impl2 = impl2.setitem(2, 5) assert impl2.getitem(2) == 5 +class AppTest_SmartListObject(test_listobject.AppTestW_ListObject): + def setup_class(cls): + cls.space = gettestobjspace(**{ + "objspace.std.withsmartresizablelist": True}) From fijal at codespeak.net Fri Mar 2 15:33:19 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 2 Mar 2007 15:33:19 +0100 (CET) Subject: [pypy-svn] r39686 - pypy/dist/pypy/translator/js Message-ID: <20070302143319.CE4B710120@code0.codespeak.net> Author: fijal Date: Fri Mar 2 15:33:16 2007 New Revision: 39686 Modified: pypy/dist/pypy/translator/js/asmgen.py pypy/dist/pypy/translator/js/database.py pypy/dist/pypy/translator/js/function.py pypy/dist/pypy/translator/js/jts.py pypy/dist/pypy/translator/js/metavm.py pypy/dist/pypy/translator/js/support.py Log: (fijal, antonio) Major cleanup, use more code from oosupport Modified: pypy/dist/pypy/translator/js/asmgen.py ============================================================================== --- pypy/dist/pypy/translator/js/asmgen.py (original) +++ pypy/dist/pypy/translator/js/asmgen.py Fri Mar 2 15:33:16 2007 @@ -113,12 +113,13 @@ real_args = ",".join(l) self.right_hand.append("%s ( %s )" % (func_name, real_args)) - def branch_if(self, arg, exitcase): + def branch_if(self, exitcase): def mapping(exitc): if exitc in ['True', 'False']: return exitc.lower() return exitc - + + arg = self.right_hand.pop() if hasattr(arg,'name'): arg_name = self.subst_table.get(arg.name, arg.name) else: @@ -153,6 +154,7 @@ self.codegenerator.openblock() def branch_else(self): + self.right_hand.pop() self.codegenerator.closeblock() self.codegenerator.write("else") self.codegenerator.openblock() @@ -163,10 +165,6 @@ def label(self, *args): self.codegenerator.openblock() - def branch(self, *args): - #self . codegenerator . closeblock () - pass - def change_name(self, from_name, to_name): # if isinstance(from_name,Variable) and isinstance(to_name,Variable): # self.subst_table[from_name.name] = to_name.name Modified: pypy/dist/pypy/translator/js/database.py ============================================================================== --- pypy/dist/pypy/translator/js/database.py (original) +++ pypy/dist/pypy/translator/js/database.py Fri Mar 2 15:33:16 2007 @@ -78,7 +78,7 @@ try: return self.function_names[graph] except KeyError: - real_name = self.name_manager.uniquename(name) + real_name = self.name_manager.uniquename(name, lenmax=1111111) self.function_names[graph] = real_name return real_name Modified: pypy/dist/pypy/translator/js/function.py ============================================================================== --- pypy/dist/pypy/translator/js/function.py (original) +++ pypy/dist/pypy/translator/js/function.py Fri Mar 2 15:33:16 2007 @@ -8,325 +8,40 @@ from pypy.rpython.lltypesystem.lltype import SignedLongLong, UnsignedLongLong from pypy.rpython.ootypesystem import ootype from pypy.translator.oosupport.metavm import Generator,InstructionList -from pypy.translator.cli.node import Node +from pypy.translator.oosupport import function from pypy.translator.js.log import log from types import FunctionType import re -class Function(Node, Generator): - def __init__(self, db, graph, name=None, is_method=False, is_entrypoint=False, _class = None): - self.db = db - self.cts = db.genoo.TypeSystem(db) - self.graph = graph - self.name = name or self.db.get_uniquename(self.graph, graph.name) - self.is_method = is_method - self.is_entrypoint = is_entrypoint - self.blocknum = {} - self._class = _class - self._set_args() - self._set_locals() - self.order = 0 - - def get_name(self): - return self.name - - def __hash__(self): - return hash(self.graph) - - def __eq__(self, other): - return self.graph == other.graph - - def __cmp__(self, other): - return cmp(self.order, other.order) - - def _is_return_block(self, block): - return self.graph.returnblock is block - - def _is_raise_block(self, block): - return self.graph.exceptblock is block - - def loop_render_block(self, block, stop_blocks = []): - # FIXME: This code is awfull, some refactoring please - if block in stop_blocks: - return - log("Rendering block %r"%block) - - handle_exc = (block.exitswitch == flowmodel.c_last_exception) - if handle_exc: - self.ilasm.begin_try() - - for op in block.operations: - self._render_op(op) - - if len(block.exits) == 0: - # return block - return_var = block.inputargs[0] - if return_var.concretetype is not Void: - self.load(return_var) - self.ilasm.ret() - elif block.exitswitch is None: - # single exit block - assert(len(block.exits) == 1) - link = block.exits[0] - self._setup_link(link) - self.render_block(link.target, stop_blocks) - elif block.exitswitch is flowmodel.c_last_exception: - # we've got exception block - raise NotImplementedError("Exception handling not implemented") - else: - if self.loops.has_key((True,block)) and self.loops.has_key((False,block)): - # double loop - #self.ilasm.branch_while - self.ilasm.branch_while_true() - self.ilasm.branch_if(block.exitswitch, self.loops[(True,block)]) - self._setup_link(block.exits[True]) - self.render_block(block.exits[True].target, stop_blocks+[block]) - self.ilasm.branch_else() - self._setup_link(block.exits[False]) - self.render_block(block.exits[False].target, stop_blocks+[block]) - self.ilasm.close_branch() - for op in block.operations: - self._render_op(op) - self.ilasm.close_branch() - elif self.loops.has_key((True, block)) or self.loops.has_key((False, block)): - # we've got loop - try: - loop_case = self.loops[(True, block)] - except KeyError: - loop_case = self.loops[(False, block)] - self.ilasm.branch_while(block.exitswitch, loop_case) - exit_case = block.exits[loop_case] - self._setup_link(exit_case) - self.render_block(exit_case.target, stop_blocks+[block]) - for op in block.operations: - self._render_op(op) - self.ilasm.close_branch() - exit_case = block.exits[not loop_case] - self._setup_link(exit_case) - #log ( ) - self.render_block(exit_case.target, stop_blocks+[block]) - #raise NotImplementedError ( "loop" ) - else: - # just a simple if - assert(len(block.exits) == 2) - self.ilasm.branch_if(block.exitswitch, True) - self._setup_link(block.exits[True]) - self.render_block(block.exits[True].target, stop_blocks) - self.ilasm.branch_else() - self._setup_link(block.exits[False]) - self.render_block(block.exits[False].target, stop_blocks) - self.ilasm.close_branch() - - def render_block_operations(self, block): - for op in block.operations: - self._render_op(op) - - def render_block(self, startblock): - """ Block rendering routine using for variable trick - """ - def basename(x): - return str(x).replace('.', '_')#[-1] - - self.ilasm.begin_for() - - block_map = {} - blocknum = 0 - - graph = self.graph - - for block in graph.iterblocks(): - block_map[block] = blocknum - blocknum += 1 - - for block in graph.iterblocks(): - self.ilasm.write_case(block_map[block]) - - is_exc_block = (block.exitswitch is flowmodel.c_last_exception) - - if is_exc_block: - self.ilasm.begin_try() - - self.render_block_operations(block) - if self._is_return_block(block): - return_var = block.inputargs[0] - #if return_var.concretetype is not Void: - self.load(return_var) - self.ilasm.ret() - elif self._is_raise_block(block): - self.ilasm.throw(block.inputargs[1]) - elif block.exitswitch is None: - self._setup_link(block.exits[0]) - self.ilasm.jump_block(block_map[block.exits[0].target]) - elif block.exitswitch is flowmodel.c_last_exception: - link = [i for i in block.exits if i.exitcase is None][0] - self._setup_link(link) - self.ilasm.jump_block(block_map[link.target]) - self.ilasm.catch() - first = False - for link in [i for i in block.exits if i.exitcase is not None]: - # XXX: Fix for 2.5 - class_name = str(link.exitcase) - m = re.search("'(.*?)'", class_name) - if not m: - real_name = class_name - else: - real_name = m.group(1) - s = "isinstanceof(exc, %s)"%basename(real_name) - if not first: - first = True - self.ilasm.branch_if_string(s) - else: - self.ilasm.branch_elsif_string(s) - self._setup_link(link, True) - self.ilasm.jump_block(block_map[link.target]) - # otherwise just re-raise it - self.ilasm.close_branch() - self.ilasm.throw_real("exc") - self.ilasm.close_branch() - elif len(block.exits) == 2: - self.ilasm.branch_if(block.exitswitch, True) - self._setup_link(block.exits[True]) - self.ilasm.jump_block(block_map[block.exits[True].target]) - self.ilasm.branch_else() - self._setup_link(block.exits[False]) - self.ilasm.jump_block(block_map[block.exits[False].target]) - self.ilasm.close_branch() +class BaseGenerator(object): + def load(self, v): + if isinstance(v, flowmodel.Variable): + if v.name in self.argset: + selftype, selfname = self.args[0] + if self.is_method and v.name == selfname: + self.ilasm.load_self() + else: + self.ilasm.load_arg(v) else: - raise TypeError("Unknow block.exitswitch type %r"%block.exitswitch) - - self.ilasm.end_for() - #self.render_operations( - - def render(self,ilasm): - if self.db.graph_name(self.graph) is not None and not self.is_method: - return # already rendered - - if self.is_method: - args = self.args[1:] # self is implicit - else: - args = self.args - - self.ilasm = ilasm - - #self.loops = LoopFinder(self.graph.startblock).loops - if self.is_method: - self.ilasm.begin_method(self.name, self._class, [i[1] for i in args]) - else: - self.ilasm.begin_function(self.name, args) - #log("loops: %r"%self.loops) - - # render all variables - - self.ilasm.set_locals(",".join(self.locals)) - - self.render_block(self.graph.startblock) - - self.ilasm.end_function() - if self.is_method: - pass # TODO + self.ilasm.load_local(v) + elif isinstance(v, flowmodel.Constant): + self.db.load_const(v.concretetype, v.value, self.ilasm) else: - self.db.record_function(self.graph, self.name) - - def _setup_link(self, link, is_exc_link = False): - target = link.target - for to_load, to_store in zip(link.args, target.inputargs): - if to_load.concretetype is not Void: - if is_exc_link and isinstance(to_load, flowmodel.Variable) and re.match("last_exc_value", to_load.name): - self.ilasm.load_str("exc") - else: - self.load(to_load) - self.store(to_store) - + assert False - def _set_locals(self): - # this code is partly borrowed from pypy.translator.c.funcgen.FunctionCodeGenerator - # TODO: refactoring to avoid code duplication - # and borrowed again from gencli - - graph = self.graph - mix = [graph.getreturnvar()] - for block in graph.iterblocks(): - self.blocknum[block] = len(self.blocknum) - mix.extend(block.inputargs) - - for op in block.operations: - mix.extend(op.args) - mix.append(op.result) - if getattr(op, "cleanup", None) is not None: - cleanup_finally, cleanup_except = op.cleanup - for cleanupop in cleanup_finally + cleanup_except: - mix.extend(cleanupop.args) - mix.append(cleanupop.result) - for link in block.exits: - mix.extend(link.getextravars()) - mix.extend(link.args) - - # filter only locals variables, i.e.: - # - must be variables - # - must appear only once - # - must not be function parameters - # - must not have 'void' type - - args = {} - for ctstype, name in self.args: - args[name] = True - - locals = [] - seen = {} - for v in mix: - is_var = isinstance(v, flowmodel.Variable) - if id(v) not in seen and is_var and v.name not in args: - locals.append(v.name) - seen[id(v)] = True - - self.locals = locals - - def _set_args(self): - args = self.graph.getargs() - self.args = map(self.cts.llvar_to_cts, args) - self.argset = set([argname for argtype, argname in self.args]) - - def _get_block_name(self, block): - return 'block%s' % self.blocknum[block] - - def _search_for_classes(self, op): - for arg in op.args: - lltype = None - if isinstance(arg, flowmodel.Variable): - lltype = arg.concretetype - elif isinstance(arg, flowmodel.Constant): - lltype = arg.value - - if isinstance(lltype, ootype._view) and isinstance(lltype._inst, ootype._instance): - lltype = lltype._inst._TYPE - - if isinstance(lltype, ootype.Instance): - self.db.pending_class(lltype) - - def _render_op(self, op): - # FIXME: what to do here? - instr_list = self.db.genoo.opcodes.get(op.opname, None) - if instr_list is not None: - #assert isinstance(instr_list, InstructionList) - instr_list.render(self, op) - else: - if getoption('nostop'): - log.WARNING('Unknown opcode: %s ' % op) - self.ilasm.opcode(str(op)) + def store(self, v): + if isinstance(v, flowmodel.Variable): + if v.concretetype is not Void: + self.ilasm.store_local(v) else: - assert False, 'Unknown opcode: %s ' % op - - def field_name(self, obj, field): - class_, type_ = obj._lookup_field(field) - assert type_ is not None, 'Cannot find the field %s in the object %s' % (field, obj) - - class_name = self.class_name(class_) - field_type = self.cts.lltype_to_cts(type_) - return (field_type, class_name, field) - - # following methods belongs to the Generator interface + self.ilasm.store_void() + else: + assert False + + def change_name(self, name, to_name): + self.ilasm.change_name(name, to_name) def add_comment(self, text): pass @@ -342,7 +57,7 @@ def call_graph(self, graph): self.db.pending_function(graph) - func_sig = self.function_signature(graph) + func_sig = self.function_signature(graph) self.ilasm.call(func_sig) def call_external(self, name, args): @@ -377,22 +92,6 @@ def downcast(self, TYPE): pass - - def load(self, v): - if isinstance(v, flowmodel.Variable): - if v.name in self.argset: - selftype, selfname = self.args[0] - if self.is_method and v.name == selfname: - self.ilasm.load_self() - else: - self.ilasm.load_arg(v) - else: - self.ilasm.load_local(v) - - elif isinstance(v, flowmodel.Constant): - self.db.load_const(v.concretetype, v.value, self.ilasm) - else: - assert False def load_special(self, v): # special case for loading value @@ -405,19 +104,7 @@ self.ilasm.load_str(name) else: self.load(v) - - def store(self, v): - if isinstance(v, flowmodel.Variable): - if v.concretetype is not Void: - self.ilasm.store_local(v) - else: - self.ilasm.store_void() - else: - assert False - - def change_name(self, name, to_name): - self.ilasm.change_name(name, to_name) - + def cast_function(self, name, num): self.ilasm.cast_function(name, num) @@ -440,3 +127,101 @@ self.load(base_obj) self.load(item) self.ilasm.list_getitem() + + def branch_unconditionally(self, target_label): + self.ilasm.jump_block(self.block_map[target_label]) + + def branch_conditionally(self, exitcase, target_label): + self.ilasm.branch_if(exitcase) + self.ilasm.jump_block(self.block_map[target_label]) + self.ilasm.close_branch() + +class Function(function.Function, BaseGenerator): + def __init__(self, db, graph, name=None, is_method=False, + is_entrypoint=False, _class=None): + self._class = _class + super(Function, self).__init__(db, graph, name, is_method, is_entrypoint) + self._set_args() + self._set_locals() + self.order = 0 + self.name = name or self.db.get_uniquename(self.graph, self.graph.name) + + def _setup_link(self, link, is_exc_link = False): + target = link.target + for to_load, to_store in zip(link.args, target.inputargs): + if to_load.concretetype is not Void: + if is_exc_link and isinstance(to_load, flowmodel.Variable) and re.match("last_exc_value", to_load.name): + self.ilasm.load_str("exc") + else: + self.load(to_load) + self.store(to_store) + + def _create_generator(self, ilasm): + return self + + def begin_render(self): + block_map = {} + for blocknum, block in enumerate(self.graph.iterblocks()): + block_map[self._get_block_name(block)] = blocknum + self.block_map = block_map + + if self.is_method: + args = self.args[1:] # self is implicit + else: + args = self.args + if self.is_method: + self.ilasm.begin_method(self.name, self._class, [i[1] for i in args]) + else: + self.ilasm.begin_function(self.name, args) + self.ilasm.set_locals(",".join([i[1] for i in self.locals])) + self.ilasm.begin_for() + + def render_return_block(self, block): + return_var = block.inputargs[0] + if return_var.concretetype is not Void: + self.load(return_var) + self.ilasm.ret() + else: + self.ilasm.load_void() + self.ilasm.ret() + + def end_render(self): + self.ilasm.end_for() + self.ilasm.end_function() + + def render_raise_block(self, block): + self.ilasm.throw(block.inputargs[1]) + + def end_try(self, target_label): + self.ilasm.jump_block(self.block_map[target_label]) + self.ilasm.catch() + #self.ilasm.close_branch() + + def record_ll_meta_exc(self, ll_meta_exc): + pass + + def begin_catch(self, llexitcase): + real_name = self.cts.lltype_to_cts(llexitcase._inst.class_._INSTANCE) + s = "isinstanceof(exc, %s)"%real_name + self.ilasm.branch_if_string(s) + + def end_catch(self, target_label): + """ Ends the catch block, and branchs to the given target_label as the + last item in the catch block """ + self.ilasm.close_branch() + + def store_exception_and_link(self, link): + self._setup_link(link, True) + self.ilasm.jump_block(self.block_map[self._get_block_name(link.target)]) + + def after_except_block(self): + #self.ilasm.close_branch() + self.ilasm.throw_real("exc") + self.ilasm.close_branch() + + def set_label(self, label): + self.ilasm.write_case(self.block_map[label]) + #self.ilasm.label(label) + + def begin_try(self): + self.ilasm.begin_try() Modified: pypy/dist/pypy/translator/js/jts.py ============================================================================== --- pypy/dist/pypy/translator/js/jts.py (original) +++ pypy/dist/pypy/translator/js/jts.py Fri Mar 2 15:33:16 2007 @@ -27,8 +27,11 @@ def __init__(self, db): self.db = db - def __class(self, name): - return name.replace(".", "_") + #def __class(self, name): + # return name.replace(".", "_") + + def escape_name(self, name): + return name.replace('.', '_') def llvar_to_cts(self, var): return 'var ', var.name @@ -36,7 +39,7 @@ def lltype_to_cts(self, t): if isinstance(t, ootype.Instance): self.db.pending_class(t) - return self.__class(t._name) + return self.escape_name(t._name) elif isinstance(t, ootype.List): return "Array" elif isinstance(t, lltype.Primitive): @@ -57,7 +60,8 @@ def graph_to_signature(self, graph, is_method = False, func_name = None): func_name = func_name or self.db.get_uniquename(graph,graph.name) - args = graph.getargs() + args = [arg for arg in graph.getargs() if + arg.concretetype is not ootype.Void] if is_method: args = args[1:] Modified: pypy/dist/pypy/translator/js/metavm.py ============================================================================== --- pypy/dist/pypy/translator/js/metavm.py (original) +++ pypy/dist/pypy/translator/js/metavm.py Fri Mar 2 15:33:16 2007 @@ -63,7 +63,8 @@ def _render_function(self, generator, graph, args): for func_arg in args[1:]: # push parameters - generator.load(func_arg) + if func_arg.concretetype is not ootype.Void: + generator.load(func_arg) generator.call_graph(graph) def _render_method(self, generator, method_name, args): Modified: pypy/dist/pypy/translator/js/support.py ============================================================================== --- pypy/dist/pypy/translator/js/support.py (original) +++ pypy/dist/pypy/translator/js/support.py Fri Mar 2 15:33:16 2007 @@ -55,10 +55,8 @@ self.predefined = set(predefined_classes_and_objects) - def uniquename(self, name): - #if self.js.compress and name != self.js.functions[0].func_name and is_optimized_function(name) and name.startswith("ll_issubclass__object_vtablePtr_object_vtablePtr"): - # name = 'f' - return NameManager.uniquename(self, name) + #def uniquename(self, name, lenmax=0): + # return NameManager.uniquename(self, , lenmax) def ensure_non_reserved(self, name): while name in self.reserved: From fijal at codespeak.net Fri Mar 2 15:41:16 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 2 Mar 2007 15:41:16 +0100 (CET) Subject: [pypy-svn] r39687 - pypy/dist/pypy/rpython Message-ID: <20070302144116.8343510134@code0.codespeak.net> Author: fijal Date: Fri Mar 2 15:41:14 2007 New Revision: 39687 Modified: pypy/dist/pypy/rpython/extfunc.py Log: Make it a bit more general Modified: pypy/dist/pypy/rpython/extfunc.py ============================================================================== --- pypy/dist/pypy/rpython/extfunc.py (original) +++ pypy/dist/pypy/rpython/extfunc.py Fri Mar 2 15:41:14 2007 @@ -79,9 +79,11 @@ FunEntry.__name__ = function.func_name def is_external(func): - if getattr(func.value._callable, 'suggested_primitive', False): + if hasattr(func, 'value'): + func = func.value + if getattr(func._callable, 'suggested_primitive', False): return True - if hasattr(func.value, '_entry'): - if isinstance(func.value._entry, ExtFuncEntry): + if hasattr(func, '_entry'): + if isinstance(func._entry, ExtFuncEntry): return True return False From fijal at codespeak.net Fri Mar 2 15:41:28 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 2 Mar 2007 15:41:28 +0100 (CET) Subject: [pypy-svn] r39688 - pypy/dist/pypy/translator/js Message-ID: <20070302144128.B3DF71013A@code0.codespeak.net> Author: fijal Date: Fri Mar 2 15:41:25 2007 New Revision: 39688 Modified: pypy/dist/pypy/translator/js/jts.py Log: Fix a test Modified: pypy/dist/pypy/translator/js/jts.py ============================================================================== --- pypy/dist/pypy/translator/js/jts.py (original) +++ pypy/dist/pypy/translator/js/jts.py Fri Mar 2 15:41:25 2007 @@ -14,6 +14,7 @@ from pypy.translator.js.log import log from types import FunctionType +from pypy.rpython.extfunc import is_external try: set @@ -97,7 +98,7 @@ # FIXME: It's not ok to use always empty list val = "[]" elif isinstance(_type,StaticMethod): - if hasattr(v, 'graph'): + if hasattr(v, 'graph') and not is_external(v): self.db.pending_function(v.graph) else: self.db.pending_abstract_function(v) From hpk at codespeak.net Fri Mar 2 15:42:56 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Fri, 2 Mar 2007 15:42:56 +0100 (CET) Subject: [pypy-svn] r39689 - pypy/dist/pypy/module/sys Message-ID: <20070302144256.7AD3B10134@code0.codespeak.net> Author: hpk Date: Fri Mar 2 15:42:53 2007 New Revision: 39689 Modified: pypy/dist/pypy/module/sys/state.py pypy/dist/pypy/module/sys/version.py Log: resolving the use of autopath here (translate seems to work, but i'll check if it fully works still) Modified: pypy/dist/pypy/module/sys/state.py ============================================================================== --- pypy/dist/pypy/module/sys/state.py (original) +++ pypy/dist/pypy/module/sys/state.py Fri Mar 2 15:42:53 2007 @@ -22,8 +22,8 @@ def setinitialpath(self, space): # Initialize the default path - from pypy.interpreter import autopath - srcdir = os.path.dirname(autopath.pypydir) + pypydir = os.path.dirname(os.path.abspath(pypy.__file__)) + srcdir = os.path.dirname(pypydir) path = getinitialpath(srcdir) self.w_path = space.newlist([space.wrap(p) for p in path]) Modified: pypy/dist/pypy/module/sys/version.py ============================================================================== --- pypy/dist/pypy/module/sys/version.py (original) +++ pypy/dist/pypy/module/sys/version.py Fri Mar 2 15:42:53 2007 @@ -2,7 +2,6 @@ Version numbers exposed by PyPy through the 'sys' module. """ import os -from pypy.interpreter import autopath CPYTHON_VERSION = (2, 4, 1, "alpha", 42) @@ -16,6 +15,10 @@ REV = "$LastChangedRevision$"[22:-2] +import pypy +pypydir = os.path.dirname(os.path.abspath(pypy.__file__)) +del pypy + # ____________________________________________________________ def get_api_version(space): @@ -66,11 +69,11 @@ # to depend on an external 'svn' executable in the path. rev = int(REV) try: - f = open(os.path.join(autopath.pypydir, '.svn', 'format'), 'r') + f = open(os.path.join(pypydir, '.svn', 'format'), 'r') format = int(f.readline().strip()) f.close() if format <= 6: # Old XML-format - f = open(os.path.join(autopath.pypydir, '.svn', 'entries'), 'r') + f = open(os.path.join(pypydir, '.svn', 'entries'), 'r') for line in f: line = line.strip() if line.startswith('committed-rev="') and line.endswith('"'): @@ -78,7 +81,7 @@ break f.close() else: # New format - f = open(os.path.join(autopath.pypydir, '.svn', 'entries'), 'r') + f = open(os.path.join(pypydir, '.svn', 'entries'), 'r') format = int(f.readline().strip()) for entry in f.read().split('\f'): lines = entry.split('\n') From guido at codespeak.net Fri Mar 2 15:44:26 2007 From: guido at codespeak.net (guido at codespeak.net) Date: Fri, 2 Mar 2007 15:44:26 +0100 (CET) Subject: [pypy-svn] r39690 - pypy/dist/pypy/rpython/ootypesystem Message-ID: <20070302144426.A11351013A@code0.codespeak.net> Author: guido Date: Fri Mar 2 15:44:22 2007 New Revision: 39690 Modified: pypy/dist/pypy/rpython/ootypesystem/bltregistry.py Log: intermediate checkin, allow compute_result_annotation not to have bookkeeper Modified: pypy/dist/pypy/rpython/ootypesystem/bltregistry.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/bltregistry.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/bltregistry.py Fri Mar 2 15:44:22 2007 @@ -206,6 +206,8 @@ _type_ = BasicExternal.__metaclass__ def compute_result_annotation(self): + if self.bookkeeper is None: + return annmodel.SomeExternalBuiltin(ExternalType(self.instance)) return annmodel.SomeExternalBuiltin(self.bookkeeper.getexternaldesc(self.instance)) def specialize_call(self, hop): From mwh at codespeak.net Fri Mar 2 15:47:02 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 2 Mar 2007 15:47:02 +0100 (CET) Subject: [pypy-svn] r39691 - pypy/dist/lib-python/modified-2.4.1 Message-ID: <20070302144702.ED0631013A@code0.codespeak.net> Author: mwh Date: Fri Mar 2 15:47:01 2007 New Revision: 39691 Added: pypy/dist/lib-python/modified-2.4.1/cmd.py - copied, changed from r39672, pypy/dist/lib-python/2.4.1/cmd.py Log: a modified cmd.py that copes with a present but incomplete readline module From santagada at codespeak.net Fri Mar 2 15:52:09 2007 From: santagada at codespeak.net (santagada at codespeak.net) Date: Fri, 2 Mar 2007 15:52:09 +0100 (CET) Subject: [pypy-svn] r39692 - in pypy/dist/pypy/lang/js: . test/ecma Message-ID: <20070302145209.B666D1013C@code0.codespeak.net> Author: santagada Date: Fri Mar 2 15:52:07 2007 New Revision: 39692 Modified: pypy/dist/pypy/lang/js/interpreter.py pypy/dist/pypy/lang/js/jsobj.py pypy/dist/pypy/lang/js/test/ecma/conftest.py Log: now the math should be working, but the tests are still failling Modified: pypy/dist/pypy/lang/js/interpreter.py ============================================================================== --- pypy/dist/pypy/lang/js/interpreter.py (original) +++ pypy/dist/pypy/lang/js/interpreter.py Fri Mar 2 15:52:07 2007 @@ -3,7 +3,6 @@ from pypy.lang.js.jsparser import parse, parse_bytecode from pypy.lang.js.jsobj import * from pypy.rlib.parsing.ebnfparse import Symbol, Nonterminal -from pypy.rlib.rarithmetic import r_uint class Node(object): opcode = None @@ -492,25 +491,25 @@ opcode = 'URSH' def decision(self, ctx, op1, op2): - a = op1.ToInt32() - b = op2.ToInt32() - return W_Number(int(r_uint(a) >> (r_uint(b) & 0x1F))) + a = op1.ToUInt32() + b = op2.ToUInt32() + return W_Number(a >> (b & 0x1F)) class Rsh(BinaryComparisonOp): opcode = 'RSH' def decision(self, ctx, op1, op2): a = op1.ToInt32() - b = op2.ToInt32() - return W_Number(a >> int(r_uint(b) & 0x1F)) + b = op2.ToUInt32() + return W_Number(a >> int(b & 0x1F)) class Lsh(BinaryComparisonOp): opcode = 'LSH' def decision(self, ctx, op1, op2): a = op1.ToInt32() - b = op2.ToInt32() - return W_Number(a << int(r_uint(b) & 0x1F)) + b = op2.ToUInt32() + return W_Number(a << int(b & 0x1F)) class Ge(BinaryComparisonOp): opcode = 'GE' Modified: pypy/dist/pypy/lang/js/jsobj.py ============================================================================== --- pypy/dist/pypy/lang/js/jsobj.py (original) +++ pypy/dist/pypy/lang/js/jsobj.py Fri Mar 2 15:52:07 2007 @@ -1,4 +1,5 @@ # encoding: utf-8 +from pypy.rlib.rarithmetic import r_uint DEBUG = False @@ -63,6 +64,9 @@ def ToInt32(self): return 0 + def ToUInt32(self): + return r_uint(0) + def Get(self, P): raise NotImplementedError @@ -368,7 +372,7 @@ class W_Number(W_Primitive): def __init__(self, floatval): - self.floatval = floatval + self.floatval = float(floatval) def ToString(self): if str(self.floatval) == str(NaN): @@ -402,6 +406,15 @@ return 0 return int(self.floatval) + + def ToUInt32(self): + strval = str(self.floatval) + if strval == str(NaN) or \ + strval == str(Infinity) or \ + strval == str(-Infinity): + return r_uint(0) + + return r_uint(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 Fri Mar 2 15:52:07 2007 @@ -63,7 +63,7 @@ raise Failed(msg="Javascript Error", excinfo=py.code.ExceptionInfo()) testcases = self.interp.global_context.resolve_identifier('testcases') self.tc = self.interp.global_context.resolve_identifier('tc') - testcount = testcases.GetValue().Get('length').GetValue().ToNumber() + testcount = testcases.GetValue().Get('length').GetValue().ToInt32() self.testcases = testcases return range(testcount) From cfbolz at codespeak.net Fri Mar 2 15:53:35 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 2 Mar 2007 15:53:35 +0100 (CET) Subject: [pypy-svn] r39693 - pypy/branch/rope-branch Message-ID: <20070302145335.5CC441014E@code0.codespeak.net> Author: cfbolz Date: Fri Mar 2 15:53:33 2007 New Revision: 39693 Added: pypy/branch/rope-branch/ - copied from r39692, pypy/dist/ Log: add a branch for ropes From gbrandl at codespeak.net Fri Mar 2 15:57:55 2007 From: gbrandl at codespeak.net (gbrandl at codespeak.net) Date: Fri, 2 Mar 2007 15:57:55 +0100 (CET) Subject: [pypy-svn] r39694 - in pypy/dist/pypy/objspace/std: . test Message-ID: <20070302145755.6BDA31014E@code0.codespeak.net> Author: gbrandl Date: Fri Mar 2 15:57:53 2007 New Revision: 39694 Modified: pypy/dist/pypy/objspace/std/smartresizablelist.py pypy/dist/pypy/objspace/std/test/test_listmultiobject.py Log: A small fix in smartlist.insert. Modified: pypy/dist/pypy/objspace/std/smartresizablelist.py ============================================================================== --- pypy/dist/pypy/objspace/std/smartresizablelist.py (original) +++ pypy/dist/pypy/objspace/std/smartresizablelist.py Fri Mar 2 15:57:53 2007 @@ -169,7 +169,7 @@ def insert(self, i, w_item): self.grow() - for x in range(self._length - 1, i - 1, -1): + for x in range(self._length - 2, i - 1, -1): self.setitem(x + 1, self.getitem(x)) self.setitem(i, w_item) return self 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 Fri Mar 2 15:57:53 2007 @@ -118,3 +118,9 @@ def setup_class(cls): cls.space = gettestobjspace(**{ "objspace.std.withsmartresizablelist": True}) + + def test_insert_some(self): + ls = [1,2,3,4,5,6,7] + for i in range(5): + ls.insert(0, i) + assert len(ls) == 12 From santagada at codespeak.net Fri Mar 2 15:58:40 2007 From: santagada at codespeak.net (santagada at codespeak.net) Date: Fri, 2 Mar 2007 15:58:40 +0100 (CET) Subject: [pypy-svn] r39695 - pypy/dist/pypy/lang/js Message-ID: <20070302145840.395E21014E@code0.codespeak.net> Author: santagada Date: Fri Mar 2 15:58:38 2007 New Revision: 39695 Modified: pypy/dist/pypy/lang/js/conftest.py Log: some py.test distributed stuff... lets see if it works as advertised :) Modified: pypy/dist/pypy/lang/js/conftest.py ============================================================================== --- pypy/dist/pypy/lang/js/conftest.py (original) +++ pypy/dist/pypy/lang/js/conftest.py Fri Mar 2 15:58:38 2007 @@ -1,5 +1,13 @@ import py +dist_hosts = ['localhost:/tmp/jspypy', 'localhost'] +dist_rsync_roots = ['../../../',] +# dist_remotepython = 'python2.4' +dist_nicelevel = 10 +dist_boxed = False +dist_maxwait = 1000 +dist_taskspernode = 10 + Option = py.test.config.Option option = py.test.config.addoptions("ecma compatibility tests", Option('', '--ecma', From hpk at codespeak.net Fri Mar 2 16:01:01 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Fri, 2 Mar 2007 16:01:01 +0100 (CET) Subject: [pypy-svn] r39696 - in pypy/dist/pypy: objspace/flow/test rlib rlib/rsre rlib/rsre/test rlib/test Message-ID: <20070302150101.CC1DB1014E@code0.codespeak.net> Author: hpk Date: Fri Mar 2 16:00:58 2007 New Revision: 39696 Removed: pypy/dist/pypy/objspace/flow/test/autopath.py pypy/dist/pypy/rlib/autopath.py pypy/dist/pypy/rlib/rsre/autopath.py pypy/dist/pypy/rlib/rsre/test/autopath.py pypy/dist/pypy/rlib/test/autopath.py Modified: pypy/dist/pypy/objspace/flow/test/test_framestate.py pypy/dist/pypy/objspace/flow/test/test_model.py pypy/dist/pypy/objspace/flow/test/test_objspace.py pypy/dist/pypy/rlib/rsre/rsre.py pypy/dist/pypy/rlib/rsre/test/test_rsre.py pypy/dist/pypy/rlib/test/test_listsort.py Log: remove more autopath Modified: pypy/dist/pypy/objspace/flow/test/test_framestate.py ============================================================================== --- pypy/dist/pypy/objspace/flow/test/test_framestate.py (original) +++ pypy/dist/pypy/objspace/flow/test/test_framestate.py Fri Mar 2 16:00:58 2007 @@ -1,5 +1,4 @@ -import autopath from py.test import raises from pypy.objspace.flow.model import * Modified: pypy/dist/pypy/objspace/flow/test/test_model.py ============================================================================== --- pypy/dist/pypy/objspace/flow/test/test_model.py (original) +++ pypy/dist/pypy/objspace/flow/test/test_model.py Fri Mar 2 16:00:58 2007 @@ -1,4 +1,4 @@ -import autopath, inspect +import inspect from pypy.objspace.flow.model import * Modified: pypy/dist/pypy/objspace/flow/test/test_objspace.py ============================================================================== --- pypy/dist/pypy/objspace/flow/test/test_objspace.py (original) +++ pypy/dist/pypy/objspace/flow/test/test_objspace.py Fri Mar 2 16:00:58 2007 @@ -1,4 +1,3 @@ -import autopath import py from pypy.objspace.flow.model import Constant, Block, Link, Variable, traverse from pypy.objspace.flow.model import flatten Modified: pypy/dist/pypy/rlib/rsre/rsre.py ============================================================================== --- pypy/dist/pypy/rlib/rsre/rsre.py (original) +++ pypy/dist/pypy/rlib/rsre/rsre.py Fri Mar 2 16:00:58 2007 @@ -1,4 +1,3 @@ -import autopath import os, sys, new # WARNING: this is all nicely RPython, but there is no RPython code around @@ -7,6 +6,12 @@ # # XXX However it's not even clear how to get such prebuilt regexps... +import rsre_core +rsre_core_filename = rsre_core.__file__ +if rsre_core_filename[-1] in 'oc': + rsre_core_filename = rsre_core_filename[:-1] +rsre_core_filename = os.path.abspath(rsre_core_filename) +del rsre_core def insert_sre_methods(locals, name): """A hack that inserts the SRE entry point methods into the 'locals' @@ -19,7 +24,7 @@ start - start position for searching and matching end - end position for searching and matching """ - filename = os.path.join(autopath.this_dir, 'rsre_core.py') + filename = rsre_core_filename rsre_core = new.module('pypy.rlib.rsre.rsre_core_' + name) rsre_core.__file__ = filename execfile(filename, rsre_core.__dict__) 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 Fri Mar 2 16:00:58 2007 @@ -1,5 +1,4 @@ """Interp-level rsre tests.""" -import autopath import sys from py.test import raises from pypy.rlib.rsre.rsre import SimpleStringState, set_unicode_db Modified: pypy/dist/pypy/rlib/test/test_listsort.py ============================================================================== --- pypy/dist/pypy/rlib/test/test_listsort.py (original) +++ pypy/dist/pypy/rlib/test/test_listsort.py Fri Mar 2 16:00:58 2007 @@ -1,4 +1,4 @@ -import autopath +import py from pypy.rlib.listsort import TimSort import random, os @@ -35,9 +35,7 @@ sorttest(lst1) def test_file(): - for fn in os.listdir(autopath.this_dir): - if fn.endswith('.py'): - f = open(os.path.join(autopath.this_dir, fn), 'r') - lines1 = f.readlines() - f.close() + for fn in py.magic.autopath().dirpath().listdir(): + if fn.ext == '.py': + lines1 = fn.readlines() sorttest(lines1) From antocuni at codespeak.net Fri Mar 2 16:06:05 2007 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Fri, 2 Mar 2007 16:06:05 +0100 (CET) Subject: [pypy-svn] r39697 - pypy/dist/pypy/rpython/microbench Message-ID: <20070302150605.084A21013C@code0.codespeak.net> Author: antocuni Date: Fri Mar 2 16:06:01 2007 New Revision: 39697 Added: pypy/dist/pypy/rpython/microbench/ pypy/dist/pypy/rpython/microbench/__init__.py (contents, props changed) pypy/dist/pypy/rpython/microbench/autopath.py - copied unchanged from r39485, pypy/dist/pypy/bin/autopath.py pypy/dist/pypy/rpython/microbench/list.py (contents, props changed) pypy/dist/pypy/rpython/microbench/microbench.py (contents, props changed) Log: (antocuni, pedronis) A tool for microbenchmarking rpython snippets. Added: pypy/dist/pypy/rpython/microbench/__init__.py ============================================================================== Added: pypy/dist/pypy/rpython/microbench/list.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/rpython/microbench/list.py Fri Mar 2 16:06:01 2007 @@ -0,0 +1,51 @@ +from pypy.rpython.microbench.microbench import MetaBench + +class ListAppend: + __metaclass__ = MetaBench + def init(): + return [] + args = ['obj', 'i'] + def loop(obj, i): + obj.append(i) + +class ListGetItem: + __metaclass__ = MetaBench + LOOPS = 100000000 + def init(): + obj = [] + for i in xrange(1000): + obj.append(i) + return obj + args = ['obj', 'i'] + def loop(obj, i): + return obj[i%1000] + +class ListSetItem: + __metaclass__ = MetaBench + LOOPS = 100000000 + def init(): + obj = [] + for i in xrange(1000): + obj.append(i) + return obj + args = ['obj', 'i'] + def loop(obj, i): + obj[i%1000] = i + +class FixedListGetItem: + __metaclass__ = MetaBench + LOOPS = 100000000 + def init(): + return [0] * 1000 + args = ['obj', 'i'] + def loop(obj, i): + return obj[i%1000] + +class FixedListSetItem: + __metaclass__ = MetaBench + LOOPS = 100000000 + def init(): + return [0] * 1000 + args = ['obj', 'i'] + def loop(obj, i): + obj[i%1000] = i Added: pypy/dist/pypy/rpython/microbench/microbench.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/rpython/microbench/microbench.py Fri Mar 2 16:06:01 2007 @@ -0,0 +1,105 @@ +import sys +import autopath +from time import clock +from py.compat import subprocess +from pypy.translator.interactive import Translation + +LOOPS = 10000000 + +class MetaBench(type): + def __new__(self, cls_name, bases, cls_dict): + loop = cls_dict['loop'] + loop.dont_inline = True + myglob = { + 'init': cls_dict['init'], + 'loop': loop, + 'LOOPS': cls_dict.get('LOOPS', LOOPS), + 'clock': clock, + } + args = ', '.join(cls_dict['args']) + source = """ +def %(cls_name)s(): + obj = init() + start = clock() + for i in xrange(LOOPS): + loop(%(args)s) + return clock() - start +""" % locals() + exec source in myglob + func = myglob[cls_name] + func.benchmark = True + return func + + +def run_benchmark(exe): + from pypy.translator.cli.test.runtest import CliFunctionWrapper + if isinstance(exe, CliFunctionWrapper): + stdout, stderr, retval = exe.run() + else: + assert isinstance(exe, str) + bench = subprocess.Popen(exe, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + stdout, stderr = bench.communicate() + retval = bench.wait() + + if retval != 0: + print 'Running benchmark failed' + print 'Standard Output:' + print stdout + print '-' * 40 + print 'Standard Error:' + print stderr + raise SystemExit(-1) + + mydict = {} + for line in stdout.splitlines(): + name, res = line.split(':') + mydict[name.strip()] = float(res) + return mydict + +def import_benchmarks(): + modules = sys.argv[1:] + if len(modules) == 0: + # import all the microbenchs + from glob import glob + for module in glob('*.py'): + if module not in ('__init__.py', 'autopath.py', 'microbench.py'): + modules.append(module) + + for module in modules: + module = module.rstrip('.py') + exec 'from %s import *' % module in globals() + +def main(): + import_benchmarks() + benchmarks = [] + for name, thing in globals().iteritems(): + if getattr(thing, 'benchmark', False): + benchmarks.append((name, thing)) + benchmarks.sort() + + def entry_point(argv): + for name, func in benchmarks: + print name, ':', func() + return 0 + + t = Translation(entry_point, standalone=True, backend='c') + c_exe = t.compile() + t = Translation(entry_point, standalone=True, backend='cli') + cli_exe = t.compile() + + c_res = run_benchmark(c_exe) + cli_res = run_benchmark(cli_exe) + + print 'benchmark genc gencli ratio' + print + for name, _ in benchmarks: + c_time = c_res[name] + cli_time = cli_res[name] + if c_time == 0: + ratio = '%10s' % '---' + else: + ratio = '%10.2f' % (cli_time/c_time) + print '%-25s %10.2f %10.2f %s' % (name, c_time, cli_time, ratio) + +if __name__ == '__main__': + main() From fijal at codespeak.net Fri Mar 2 16:06:58 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 2 Mar 2007 16:06:58 +0100 (CET) Subject: [pypy-svn] r39698 - pypy/dist/pypy/translator/oosupport Message-ID: <20070302150658.6E5941014F@code0.codespeak.net> Author: fijal Date: Fri Mar 2 16:06:53 2007 New Revision: 39698 Modified: pypy/dist/pypy/translator/oosupport/function.py Log: Append after_block to render Modified: pypy/dist/pypy/translator/oosupport/function.py ============================================================================== --- pypy/dist/pypy/translator/oosupport/function.py (original) +++ pypy/dist/pypy/translator/oosupport/function.py Fri Mar 2 16:06:53 2007 @@ -164,6 +164,11 @@ target_label = self._get_block_name(link.target) self.end_catch(target_label) + self.after_except_block() + + def after_except_block(): + pass + def record_ll_meta_exc(self, ll_meta_exc): self.db.constant_generator.record_const(ll_meta_exc) From gbrandl at codespeak.net Fri Mar 2 16:12:37 2007 From: gbrandl at codespeak.net (gbrandl at codespeak.net) Date: Fri, 2 Mar 2007 16:12:37 +0100 (CET) Subject: [pypy-svn] r39699 - in pypy/dist/pypy/objspace/std: . test Message-ID: <20070302151237.592B5100D1@code0.codespeak.net> Author: gbrandl Date: Fri Mar 2 16:12:35 2007 New Revision: 39699 Modified: pypy/dist/pypy/objspace/std/listmultiobject.py pypy/dist/pypy/objspace/std/test/test_listmultiobject.py Log: bug in StrList.delitem. Modified: pypy/dist/pypy/objspace/std/listmultiobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/listmultiobject.py (original) +++ pypy/dist/pypy/objspace/std/listmultiobject.py Fri Mar 2 16:12:35 2007 @@ -343,11 +343,11 @@ start += step return StrListImplementation(self.space, res) - def delitem(self, index): + def delitem(self, i): assert 0 <= i < len(self.strlist) if len(self.strlist) == 1: return self.space.fromcache(State).empty_impl - del self.strlist[index] + del self.strlist[i] return self def delitem_slice(self, start, stop): 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 Fri Mar 2 16:12:35 2007 @@ -21,6 +21,11 @@ l = ["1", "2", "3", "4", "5"] assert "StrListImplementation" in pypymagic.pypy_repr(l) + def test_strlist_delitem(self): + l = ["1", "2"] + del l[0] + assert l == ["2"] + def test_strlist_append(self): import pypymagic l = [] From cfbolz at codespeak.net Fri Mar 2 16:24:31 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 2 Mar 2007 16:24:31 +0100 (CET) Subject: [pypy-svn] r39705 - in pypy/branch/rope-branch/pypy: config objspace/std objspace/std/test Message-ID: <20070302152431.5AD8D10079@code0.codespeak.net> Author: cfbolz Date: Fri Mar 2 16:24:27 2007 New Revision: 39705 Added: pypy/branch/rope-branch/pypy/objspace/std/rope.py pypy/branch/rope-branch/pypy/objspace/std/ropeobject.py pypy/branch/rope-branch/pypy/objspace/std/test/test_rope.py pypy/branch/rope-branch/pypy/objspace/std/test/test_ropeobject.py Modified: pypy/branch/rope-branch/pypy/config/pypyoption.py pypy/branch/rope-branch/pypy/objspace/std/marshal_impl.py pypy/branch/rope-branch/pypy/objspace/std/model.py pypy/branch/rope-branch/pypy/objspace/std/objspace.py pypy/branch/rope-branch/pypy/objspace/std/stringtype.py pypy/branch/rope-branch/pypy/objspace/std/unicodeobject.py Log: a first go at implementing ropes. Modified: pypy/branch/rope-branch/pypy/config/pypyoption.py ============================================================================== --- pypy/branch/rope-branch/pypy/config/pypyoption.py (original) +++ pypy/branch/rope-branch/pypy/config/pypyoption.py Fri Mar 2 16:24:27 2007 @@ -123,6 +123,9 @@ BoolOption("withstrslice", "use strings optimized for slicing", default=False), + BoolOption("withrope", "use ropes as the string implementation", + default=False), + BoolOption("withstrdict", "use dictionaries optimized for string keys", default=False), Modified: pypy/branch/rope-branch/pypy/objspace/std/marshal_impl.py ============================================================================== --- pypy/branch/rope-branch/pypy/objspace/std/marshal_impl.py (original) +++ pypy/branch/rope-branch/pypy/objspace/std/marshal_impl.py Fri Mar 2 16:24:27 2007 @@ -303,11 +303,11 @@ m.atom_str(TYPE_STRING, s) def unmarshal_String(space, u, tc): - return W_StringObject(u.get_str()) + return space.wrap(u.get_str()) register(TYPE_STRING, unmarshal_String) def unmarshal_interned(space, u, tc): - w_ret = W_StringObject(u.get_str()) + w_ret = space.wrap(u.get_str()) u.stringtable_w.append(w_ret) w_intern = space.builtin.get('intern') space.call_function(w_intern, w_ret) @@ -495,7 +495,7 @@ string_to_buffer = app.interphook('string_to_buffer') def unmarshal_buffer(space, u, tc): - w_s = W_StringObject(u.get_str()) + w_s = space.wrap(u.get_str()) return string_to_buffer(space, w_s) register(TYPE_UNKNOWN, unmarshal_buffer) Modified: pypy/branch/rope-branch/pypy/objspace/std/model.py ============================================================================== --- pypy/branch/rope-branch/pypy/objspace/std/model.py (original) +++ pypy/branch/rope-branch/pypy/objspace/std/model.py Fri Mar 2 16:24:27 2007 @@ -17,6 +17,8 @@ "withmultidict" : ["dictmultiobject.W_DictMultiObject", "dictmultiobject.W_DictMultiIterObject"], "withmultilist" : ["listmultiobject.W_ListMultiObject"], + "withrope" : ["ropeobject.W_RopeObject", + "ropeobject.W_RopeIterObject"], "withrangelist" : ["rangeobject.W_RangeListObject", "rangeobject.W_RangeIterObject"], "withtproxy" : ["proxyobject.W_TransparentList", @@ -68,6 +70,7 @@ from pypy.objspace.std import dictmultiobject from pypy.objspace.std import listmultiobject from pypy.objspace.std import stringobject + from pypy.objspace.std import ropeobject from pypy.objspace.std import strsliceobject from pypy.objspace.std import strjoinobject from pypy.objspace.std import typeobject @@ -115,6 +118,7 @@ dictobject.W_DictObject: True, dictobject.W_DictIterObject: True, listobject.W_ListObject: True, + stringobject.W_StringObject: True, } for option, value in config.objspace.std: if option.startswith("with") and option in option_to_typename: @@ -132,6 +136,8 @@ if config.objspace.std.withmultilist: del self.typeorder[listobject.W_ListObject] + if config.objspace.std.withrope: + del self.typeorder[stringobject.W_StringObject] #check if we missed implementations from pypy.objspace.std.objspace import _registered_implementations @@ -179,9 +185,14 @@ (complexobject.W_ComplexObject, complexobject.delegate_Float2Complex), ] - self.typeorder[stringobject.W_StringObject] += [ - (unicodeobject.W_UnicodeObject, unicodeobject.delegate_String2Unicode), - ] + if not config.objspace.std.withrope: + self.typeorder[stringobject.W_StringObject] += [ + (unicodeobject.W_UnicodeObject, unicodeobject.delegate_String2Unicode), + ] + else: + self.typeorder[ropeobject.W_RopeObject] += [ + (unicodeobject.W_UnicodeObject, unicodeobject.delegate_String2Unicode), + ] if config.objspace.std.withstrslice: self.typeorder[strsliceobject.W_StringSliceObject] += [ Modified: pypy/branch/rope-branch/pypy/objspace/std/objspace.py ============================================================================== --- pypy/branch/rope-branch/pypy/objspace/std/objspace.py (original) +++ pypy/branch/rope-branch/pypy/objspace/std/objspace.py Fri Mar 2 16:24:27 2007 @@ -335,6 +335,9 @@ else: return self.newint(x) if isinstance(x, str): + if self.config.objspace.std.withrope: + from pypy.objspace.std.ropeobject import rope, W_RopeObject + return W_RopeObject(rope.LiteralStringNode(x)) return W_StringObject(x) if isinstance(x, unicode): return W_UnicodeObject([unichr(ord(u)) for u in x]) # xxx @@ -468,7 +471,11 @@ except ValueError: # chr(out-of-range) raise OperationError(self.w_ValueError, self.wrap("character code not in range(256)")) - return W_StringObject(''.join(chars)) + if self.config.objspace.std.withrope: + from pypy.objspace.std.ropeobject import W_RopeObject, rope + return W_RopeObject(rope.rope_from_charlist(chars)) + else: + return W_StringObject(''.join(chars)) def newunicode(self, chars): try: Added: pypy/branch/rope-branch/pypy/objspace/std/rope.py ============================================================================== --- (empty file) +++ pypy/branch/rope-branch/pypy/objspace/std/rope.py Fri Mar 2 16:24:27 2007 @@ -0,0 +1,782 @@ +import py +import sys + +NEW_NODE_WHEN_LENGTH = 16 +MAX_DEPTH = 32 # maybe should be smaller +MIN_SLICE_LENGTH = 64 +CONCATENATE_WHEN_MULTIPLYING = 128 + +def find_fib_index(l): + if l == 0: + return -1 + a, b = 1, 2 + i = 0 + while 1: + if a <= l < b: + return i + a, b = b, a + b + i += 1 + +class StringNode(object): + def length(self): + return 0 + + def depth(self): + return 0 + + def rebalance(self): + return self + + def flatten(self): + return '' + + def __add__(self, other): + return concatenate(self, other) + + def __getitem__(self, index): + if isinstance(index, slice): + start, stop, step = index.indices(self.length()) + # XXX sucks + slicelength = len(range(start, stop, step)) + return getslice(self, start, stop, step, slicelength) + return self.getitem(index) + + def getitem(self, index): + raise NotImplementedError("abstract base class") + + def getitem_slice(self, start, stop): + # XXX really horrible, in most cases + result = [] + for i in range(start, stop): + result.append(self.getitem(i)) + return rope_from_charlist(result) + + def view(self): + from pypy.translator.tool.pygame import graphclient + view([self]) + + def check_balanced(self): + return True + + +class LiteralStringNode(StringNode): + def __init__(self, s): + self.s = s + + def length(self): + return len(self.s) + + def flatten(self): + return self.s + + def getitem(self, index): + return self.s[index] + + def getitem_slice(self, start, stop): + return LiteralStringNode(self.s[start:stop]) + + def dot(self, seen, toplevel=False): + if self in seen: + return + seen[self] = True + addinfo = str(self.s).replace('"', "'") or "_" + if len(addinfo) > 10: + addinfo = addinfo[:3] + "..." + addinfo[-3:] + yield ('"%s" [shape=box,label="length: %s\\n%s"];' % ( + id(self), len(self.s), + repr(addinfo).replace('"', '').replace("\\", "\\\\"))) + + +class BinaryConcatNode(StringNode): + def __init__(self, left, right): + self.left = left + self.right = right + self.len = left.length() + right.length() + self._depth = max(left.depth(), right.depth()) + 1 + self.balanced = False + + def check_balanced(self): + if self.balanced: + return True + if not self.left.check_balanced() or not self.right.check_balanced(): + return False + left = self.left + right = self.right + llen = left.length() + rlen = right.length() + ldepth = left.depth() + rdepth = right.depth() + balanced = (find_fib_index(self.len // (NEW_NODE_WHEN_LENGTH / 2)) >= + self._depth) + self.balanced = balanced + return balanced + + def length(self): + return self.len + + def depth(self): + return self._depth + + def getitem(self, index): + llen = self.left.length() + if index >= llen: + return self.right.getitem(index - llen) + else: + return self.left.getitem(index) + + def flatten(self): + f = fringe(self) + return "".join([node.flatten() for node in f]) + + def rebalance(self): + return rebalance([self], self.len) + + def dot(self, seen, toplevel=False): + if self in seen: + return + seen[self] = True + if toplevel: + addition = ", fillcolor=red" + elif self.check_balanced(): + addition = ", fillcolor=yellow" + else: + addition = "" + yield '"%s" [shape=octagon,label="+\\ndepth=%s, length=%s"%s];' % ( + id(self), self._depth, self.len, addition) + for child in [self.left, self.right]: + yield '"%s" -> "%s";' % (id(self), id(child)) + for line in child.dot(seen): + yield line + +class SliceNode(StringNode): + def __init__(self, start, stop, node): + self.start = start + self.stop = stop + self.node = node + + def length(self): + return self.stop - self.start + + def getitem_slice(self, start, stop): + return self.node.getitem_slice(self.start + start, self.start + stop) + + def getitem(self, index): + return self.node.getitem(self.start + index) + + def flatten(self): + return self.node.flatten()[self.start: self.stop] + + def dot(self, seen, toplevel=False): + if self in seen: + return + seen[self] = True + yield '"%s" [shape=octagon,label="slice\\nstart=%s, stop=%s"];' % ( + id(self), self.start, self.stop) + yield '"%s" -> "%s";' % (id(self), id(self.node)) + for line in self.node.dot(seen): + yield line + +def concatenate(node1, node2): + if node1.length() == 0: + return node2 + if node2.length() == 0: + return node1 + if (isinstance(node2, LiteralStringNode) and + len(node2.s) <= NEW_NODE_WHEN_LENGTH): + if isinstance(node1, LiteralStringNode): + if len(node1.s) + len(node2.s) <= NEW_NODE_WHEN_LENGTH: + return LiteralStringNode(node1.s + node2.s) + elif isinstance(node1, BinaryConcatNode): + r = node1.right + if isinstance(r, LiteralStringNode): + if len(r.s) + len(node2.s) <= NEW_NODE_WHEN_LENGTH: + return BinaryConcatNode(node1.left, + LiteralStringNode(r.s + node2.s)) + result = BinaryConcatNode(node1, node2) + if result.depth() > MAX_DEPTH: #XXX better check + return result.rebalance() + return result + +def getslice(node, start, stop, step, slicelength): + start, stop, node = find_straddling(node, start, stop) + if step != 1: + # XXX optimize later using SeekableCharIterator + iter = SeekableCharIterator(node) + iter.seekforward(start) + result = [iter.next()] + for i in range(slicelength - 1): + iter.seekforward(step - 1) + result.append(iter.next()) + return rope_from_charlist(result) + return getslice_one(node, start, stop) + +def getslice_one(node, start, stop): + if isinstance(node, BinaryConcatNode): + if start == 0: + if stop == node.length(): + return node + return getslice_left(node, stop) + if stop == node.length(): + return getslice_right(node, start) + return concatenate( + getslice_right(node.left, start), + getslice_left(node.right, stop - node.left.length())) + else: + return getslice_primitive(node, start, stop) + +def find_straddling(node, start, stop): + while 1: + if isinstance(node, BinaryConcatNode): + llen = node.left.length() + if start >= llen: + node = node.right + start = start - llen + stop = stop - llen + continue + if stop <= llen: + node = node.left + continue + return start, stop, node + +def getslice_right(node, start): + while 1: + if start == 0: + return node + if isinstance(node, BinaryConcatNode): + llen = node.left.length() + if start >= llen: + node = node.right + start = start - llen + continue + else: + return concatenate(getslice_right(node.left, start), + node.right) + return getslice_primitive(node, start, node.length()) + +def getslice_left(node, stop): + while 1: + if stop == node.length(): + return node + if isinstance(node, BinaryConcatNode): + llen = node.left.length() + if stop <= llen: + node = node.left + continue + else: + return concatenate(node.left, + getslice_left(node.right, stop - llen)) + return getslice_primitive(node, 0, stop) + + +def getslice_primitive(node, start, stop): + if stop - start >= MIN_SLICE_LENGTH: + if isinstance(node, SliceNode): + return SliceNode(start + node.start, stop + node.start, + node.node) + return SliceNode(start, stop, node) + return node.getitem_slice(start, stop) + +def multiply(node, times): + if times <= 0: + return LiteralStringNode("") + if times == 1: + return node + end_length = node.length() * times + num_bits = 0 + mask = times + while mask: + num_bits += 1 + mask >>= 1 + result = node + mask = 1 << (num_bits - 2) + #import pdb; pdb.set_trace() + for i in range(num_bits - 1): + if mask & times: + if result.length() < CONCATENATE_WHEN_MULTIPLYING: + result = concatenate(result, result) + result = concatenate(result, node) + else: + result = BinaryConcatNode(result, result) + result = BinaryConcatNode(result, node) + else: + if result.length() < CONCATENATE_WHEN_MULTIPLYING: + result = concatenate(result, result) + else: + result = BinaryConcatNode(result, result) + mask >>= 1 + return result + +def join(node, l): + if node.length() == 0: + return rebalance(l) + nodelist = [None] * (2 * len(l) - 1) + length = 0 + for i in range(len(l)): + nodelist[2 * i] = l[i] + length += l[i].length() + for i in range(len(l) - 1): + nodelist[2 * i + 1] = node + length += (len(l) - 1) * node.length() + return rebalance(nodelist, length) + +def rebalance(nodelist, sizehint=-1): + if not nodelist: + return LiteralStringNode("") + nodelist.reverse() + if sizehint < 0: + sizehint = 0 + for node in nodelist: + sizehint += node.length() + l = [None] * (find_fib_index(sizehint) + 2) + stack = nodelist + i = 0 + curr = None + while stack: + curr = stack.pop() + while 1: + if isinstance(curr, BinaryConcatNode) and not curr.balanced: + stack.append(curr.right) + curr = curr.left + else: + i = orig_i = find_fib_index(curr.length()) + index = 0 + added = False + while index <= i: + if l[index] is not None: + curr = concatenate(l[index], curr) + l[index] = None + if index >= orig_i or not added: + i += 1 + added = True + index += 1 + if i == len(l): + return curr + l[i] = curr + break + for index in range(i + 1, len(l)): + if l[index] is not None: + curr = BinaryConcatNode(l[index], curr) + assert curr is not None + curr.check_balanced() + return curr + +# __________________________________________________________________________ +# construction from normal strings + +def rope_from_charlist(charlist): + nodelist = [] + size = 0 + for i in range(0, len(charlist), NEW_NODE_WHEN_LENGTH): + chars = charlist[i: min(len(charlist), i + NEW_NODE_WHEN_LENGTH)] + nodelist.append(LiteralStringNode("".join(chars))) + size += len(chars) + return rebalance(nodelist, size) + +# __________________________________________________________________________ +# searching + +def find_char(node, c, start=0, stop=-1): + offset = 0 + length = node.length() + if stop == -1: + stop = length + if start != 0 or stop != length: + newstart, newstop, node = find_straddling(node, start, stop) + offset = start - newstart + start = newstart + stop = newstop + if isinstance(node, LiteralStringNode): + result = node.s.find(c, start, stop) + if result == -1: + return -1 + return result + offset + elif isinstance(node, SliceNode): + return find_char(node.node, c, node.start + start, + node.start + stop) - node.start + offset + iter = CharIterator(node) + i = 0 + while i < stop: + try: + c2 = iter.next() + if i < start: + i += 1 + continue + if c == c2: + return i + offset + i += 1 + except StopIteration: + return -1 + return -1 + +def find(node, subnode, start=0, stop=-1): + + len1 = node.length() + if stop > len1 or stop == -1: + stop = len1 + substring = subnode.flatten() # stressful to do it as a node + len2 = len(substring) + if len2 == 1: + return find_char(node, substring[0], start, stop) + if len2 == 0: + if (stop - start) < 0: + return -1 + return start + restart = construct_restart_positions(substring) + return _find(node, substring, start, stop, restart) + +def _find(node, substring, start, stop, restart): + len2 = len(substring) + i = 0 + m = start + iter = SeekableCharIterator(node) + iter.seekforward(start) + c = iter.next() + while m + i < stop: + if c == substring[i]: + i += 1 + if i == len2: + return m + if m + i < stop: + c = iter.next() + else: + # mismatch, go back to the last possible starting pos + if i==0: + m += 1 + if m + i < stop: + c = iter.next() + else: + e = restart[i-1] + new_m = m + i - e + assert new_m <= m + i + seek = m + i - new_m + if seek: + iter.seekback(m + i - new_m) + c = iter.next() + m = new_m + i = e + return -1 + +def construct_restart_positions(s): + l = len(s) + restart = [0] * l + restart[0] = 0 + i = 1 + j = 0 + while i < l: + if s[i] == s[j]: + j += 1 + restart[i] = j + i += 1 + elif j>0: + j = restart[j-1] + else: + restart[i] = 0 + i += 1 + j = 0 + return restart + +def construct_restart_positions_node(node): + # really a bit overkill + l = node.length() + restart = [0] * l + restart[0] = 0 + i = 1 + j = 0 + iter1 = CharIterator(node) + iter1.next() + c1 = iter1.next() + iter2 = SeekableCharIterator(node) + c2 = iter2.next() + while i < l: + if c1 == c2: + j += 1 + if j != l: + c2 = iter2.next() + restart[i] = j + i += 1 + if i != l: + c1 = iter1.next() + else: + break + elif j>0: + new_j = restart[j-1] + assert new_j < j + iter2.seekback(j - new_j) + c2 = iter2.next() + j = new_j + else: + restart[i] = 0 + i += 1 + if i != l: + c1 = iter1.next() + else: + break + j = 0 + iter2 = SeekableCharIterator(node) + c2 = iter2.next() + return restart + +def view(objs): + from pypy.translator.tool.pygame import graphclient + content = ["digraph G{"] + seen = {} + for i, obj in enumerate(objs): + if obj is None: + content.append(str(i) + ";") + else: + content.extend(obj.dot(seen, toplevel=True)) + content.append("}") + p = py.test.ensuretemp("automaton").join("temp.dot") + p.write("\n".join(content)) + graphclient.display_dot_file(str(p)) + + +# __________________________________________________________________________ +# iteration + +class FringeIterator(object): + def __init__(self, node): + self.stack = [node] + + def next(self): + while self.stack: + curr = self.stack.pop() + while 1: + if isinstance(curr, BinaryConcatNode): + self.stack.append(curr.right) + curr = curr.left + else: + return curr + raise StopIteration + +def fringe(node): + result = [] + iter = FringeIterator(node) + while 1: + try: + result.append(iter.next()) + except StopIteration: + return result + +class SeekableFringeIterator(object): + def __init__(self, node): + self.stack = [node] + self.fringestack = [] + self.fringe = [] + + def next(self): + if self.fringestack: + result = self.fringestack.pop() + self.fringe.append(result) + return result + while self.stack: + curr = self.stack.pop() + while 1: + if isinstance(curr, BinaryConcatNode): + self.stack.append(curr.right) + curr = curr.left + else: + self.fringe.append(curr) + return curr + raise StopIteration + + def seekback(self): + result = self.fringe.pop() + self.fringestack.append(result) + return result + + +class CharIterator(object): + def __init__(self, node): + self.iter = FringeIterator(node) + self.node = None + self.nodelength = 0 + self.index = 0 + + def next(self): + node = self.node + if node is None: + while 1: + node = self.node = self.iter.next() + nodelength = self.nodelength = node.length() + if nodelength != 0: + break + self.index = 0 + index = self.index + result = self.node.getitem(index) + if self.index == self.nodelength - 1: + self.node = None + else: + self.index = index + 1 + return result + +class SeekableCharIterator(object): + def __init__(self, node): + self.iter = SeekableFringeIterator(node) + self.node = self.nextnode() + self.nodelength = self.node.length() + self.index = 0 + + def nextnode(self): + while 1: + node = self.node = self.iter.next() + nodelength = self.nodelength = node.length() + if nodelength != 0: + break + self.index = 0 + return node + + def next(self): + node = self.node + if node is None: + node = self.nextnode() + index = self.index + result = self.node.getitem(index) + if self.index == self.nodelength - 1: + self.node = None + self.index = index + 1 + return result + + def seekforward(self, numchars): + if numchars < (self.nodelength - self.index): + self.index += numchars + return + numchars -= self.nodelength - self.index + while 1: + node = self.iter.next() + length = node.length() + if length <= numchars: + numchars -= length + else: + self.index = numchars + self.node = node + self.nodelength = node.length() + return + + def seekback(self, numchars): + if numchars <= self.index: + self.index -= numchars + return + numchars -= self.index + self.iter.seekback() # for first item + while 1: + node = self.iter.seekback() + length = node.length() + if length < numchars: + numchars -= length + else: + self.index = length - numchars + self.node = self.iter.next() + self.nodelength = self.node.length() + return + +class FindIterator(object): + def __init__(self, node, sub, start=0, stop=-1): + self.node = node + len1 = self.length = node.length() + substring = self.substring = sub.flatten() # for now + len2 = len(substring) + self.search_length = len2 + if len2 == 0: + self.restart_positions = None + elif len2 == 1: + self.restart_positions = None + else: + self.restart_positions = construct_restart_positions(substring) + self.start = start + if stop == -1 or stop > len1: + stop = len1 + self.stop = stop + + def next(self): + if self.search_length == 0: + if (self.stop - self.start) < 0: + raise StopIteration + start = self.start + self.start += 1 + return start + elif self.search_length == 1: + result = find_char(self.node, self.substring[0], + self.start, self.stop) + if result == -1: + self.start = self.length + raise StopIteration + self.start = result + 1 + return result + if self.start >= self.stop: + raise StopIteration + result = _find(self.node, self.substring, self.start, + self.stop, self.restart_positions) + if result == -1: + self.start = self.length + raise StopIteration + self.start = result + self.search_length + return result + +# __________________________________________________________________________ +# comparison + + +def eq(node1, node2): + if node1 is node2: + return True + # could be cleverer and detect partial equalities + if node1.length() != node2.length(): + return False + iter1 = CharIterator(node1) + iter2 = CharIterator(node2) + while 1: + try: + c = iter1.next() + except StopIteration: + return True + if c != iter2.next(): + return False + +def compare(node1, node2): + len1 = node1.length() + len2 = node2.length() + if not len1: + if not len2: + return 0 + return -1 + if not len2: + return 1 + + if len1 < len2: + cmplen = len1 + else: + cmplen = len2 + i = 0 + iter1 = CharIterator(node1) + iter2 = CharIterator(node2) + while i < cmplen: + diff = ord(iter1.next()) - ord(iter2.next()) + if diff != 0: + return diff + i += 1 + return len1 - len2 + + +# __________________________________________________________________________ +# misc + + +def hash_rope(rope): + from pypy.rlib.rarithmetic import intmask + length = rope.length() + if length == 0: + x = -1 + else: + x = ord(rope.getitem(0)) << 7 + iter = CharIterator(rope) + while 1: + try: + x = (1000003*x) ^ ord(iter.next()) + except StopIteration: + break + x ^= length + if x == 0: + x = -1 + return intmask(x) + Added: pypy/branch/rope-branch/pypy/objspace/std/ropeobject.py ============================================================================== --- (empty file) +++ pypy/branch/rope-branch/pypy/objspace/std/ropeobject.py Fri Mar 2 16:24:27 2007 @@ -0,0 +1,1034 @@ +from pypy.objspace.std.objspace import * +from pypy.interpreter import gateway +from pypy.rlib.objectmodel import we_are_translated +from pypy.objspace.std.inttype import wrapint +from pypy.objspace.std.sliceobject import W_SliceObject +from pypy.objspace.std import slicetype +from pypy.objspace.std.listobject import W_ListObject +from pypy.objspace.std.noneobject import W_NoneObject +from pypy.objspace.std.tupleobject import W_TupleObject +from pypy.rlib.rarithmetic import ovfcheck + +from pypy.objspace.std import rope + +class W_RopeObject(W_Object): + from pypy.objspace.std.stringtype import str_typedef as typedef + + def __init__(w_self, node): + w_self._node = node + + def __repr__(w_self): + """ representation for debugging purposes """ + return "%s(%r)" % (w_self.__class__.__name__, w_self._node) + + def unwrap(w_self, space): + return w_self._node.flatten() + + def create_if_subclassed(w_self): + if type(w_self) == W_RopeObject: + return w_self + return W_RopeObject(w_self._node) + +W_RopeObject.empty = W_RopeObject(rope.LiteralStringNode("")) + +registerimplementation(W_RopeObject) + +class W_RopeIterObject(W_Object): + from pypy.objspace.std.itertype import iter_typedef as typedef + + def __init__(w_self, w_rope, index=0): + w_self.node = node = w_rope._node + w_self.char_iter = rope.CharIterator(node) + w_self.index = index + +registerimplementation(W_RopeIterObject) + +def wrap_rpystr(s): + return W_RopeObject(rope.LiteralStringNode(s)) + +def _is_generic(space, w_self, fun): + l = w_self._node.length() + if l == 0: + return space.w_False + iter = rope.CharIterator(w_self._node) + for i in range(l): + if not fun(iter.next()): + return space.w_False + return space.w_True +_is_generic._annspecialcase_ = "specialize:arg(2)" + +def _upper(ch): + if ch.islower(): + o = ord(ch) - 32 + return chr(o) + else: + return ch + +def _lower(ch): + if ch.isupper(): + o = ord(ch) + 32 + return chr(o) + else: + return ch + +_isspace = lambda c: c.isspace() +_isdigit = lambda c: c.isdigit() +_isalpha = lambda c: c.isalpha() +_isalnum = lambda c: c.isalnum() + +def str_isspace__Rope(space, w_self): + return _is_generic(space, w_self, _isspace) + +def str_isdigit__Rope(space, w_self): + return _is_generic(space, w_self, _isdigit) + +def str_isalpha__Rope(space, w_self): + return _is_generic(space, w_self, _isalpha) + +def str_isalnum__Rope(space, w_self): + return _is_generic(space, w_self, _isalnum) + +def str_isupper__Rope(space, w_self): + """Return True if all cased characters in S are uppercase and there is +at least one cased character in S, False otherwise.""" + l = w_self._node.length() + + if l == 0: + return space.w_False + cased = False + iter = rope.CharIterator(w_self._node) + for idx in range(l): + c = iter.next() + if c.islower(): + return space.w_False + elif not cased and c.isupper(): + cased = True + return space.newbool(cased) + +def str_islower__Rope(space, w_self): + """Return True if all cased characters in S are lowercase and there is +at least one cased character in S, False otherwise.""" + l = w_self._node.length() + + if l == 0: + return space.w_False + cased = False + iter = rope.CharIterator(w_self._node) + for idx in range(l): + c = iter.next() + if c.isupper(): + return space.w_False + elif not cased and c.islower(): + cased = True + return space.newbool(cased) + +def str_istitle__Rope(space, w_self): + """Return True if S is a titlecased string and there is at least one +character in S, i.e. uppercase characters may only follow uncased +characters and lowercase characters only cased ones. Return False +otherwise.""" + cased = False + previous_is_cased = False + + iter = rope.CharIterator(w_self._node) + for pos in range(0, w_self._node.length()): + ch = iter.next() + if ch.isupper(): + if previous_is_cased: + return space.w_False + previous_is_cased = True + cased = True + elif ch.islower(): + if not previous_is_cased: + return space.w_False + cased = True + else: + previous_is_cased = False + + return space.newbool(cased) + +def str_upper__Rope(space, w_self): + l = w_self._node.length() + res = [' '] * l + iter = rope.CharIterator(w_self._node) + for i in range(l): + ch = iter.next() + res[i] = _upper(ch) + + return W_RopeObject(rope.rope_from_charlist(res)) + +def str_lower__Rope(space, w_self): + l = w_self._node.length() + res = [' '] * l + iter = rope.CharIterator(w_self._node) + for i in range(l): + ch = iter.next() + res[i] = _lower(ch) + + return W_RopeObject(rope.rope_from_charlist(res)) + +def str_swapcase__Rope(space, w_self): + l = w_self._node.length() + res = [' '] * l + iter = rope.CharIterator(w_self._node) + for i in range(l): + ch = iter.next() + if ch.isupper(): + o = ord(ch) + 32 + res[i] = chr(o) + elif ch.islower(): + o = ord(ch) - 32 + res[i] = chr(o) + else: + res[i] = ch + + return W_RopeObject(rope.rope_from_charlist(res)) + + +def str_capitalize__Rope(space, w_self): + node = w_self._node + length = node.length() + buffer = [' '] * length + if length > 0: + iter = rope.CharIterator(node) + ch = iter.next() + if ch.islower(): + o = ord(ch) - 32 + buffer[0] = chr(o) + else: + buffer[0] = ch + + for i in range(1, length): + ch = iter.next() + if ch.isupper(): + o = ord(ch) + 32 + buffer[i] = chr(o) + else: + buffer[i] = ch + else: + return W_RopeObject.empty + + return W_RopeObject(rope.rope_from_charlist(buffer)) + +def str_title__Rope(space, w_self): + node = w_self._node + length = node.length() + buffer = [' '] * length + prev_letter = ' ' + + iter = rope.CharIterator(node) + for pos in range(0, length): + ch = iter.next() + if not prev_letter.isalpha(): + buffer[pos] = _upper(ch) + else: + buffer[pos] = _lower(ch) + + prev_letter = buffer[pos] + + return W_RopeObject(rope.rope_from_charlist(buffer)) + +def str_split__Rope_None_ANY(space, w_self, w_none, w_maxsplit=-1): + maxsplit = space.int_w(w_maxsplit) + res_w = [] + node = w_self._node + length = node.length() + i = 0 + iter = rope.CharIterator(node) + while True: + # find the beginning of the next word + while i < length: + if not iter.next().isspace(): + break # found + i += 1 + else: + break # end of string, finished + + # find the end of the word + if maxsplit == 0: + j = length # take all the rest of the string + else: + j = i + 1 + while j < length and not iter.next().isspace(): + j += 1 + maxsplit -= 1 # NB. if it's already < 0, it stays < 0 + + # the word is value[i:j] + res_w.append(W_RopeObject(rope.getslice_one(node, i, j))) + + # continue to look from the character following the space after the word + i = j + 1 + + return space.newlist(res_w) + + +def str_split__Rope_Rope_ANY(space, w_self, w_by, w_maxsplit=-1): + maxsplit = space.int_w(w_maxsplit) + res_w = [] + start = 0 + selfnode = w_self._node + bynode = w_by._node + iter = rope.FindIterator(selfnode, bynode) + bylen = bynode.length() + if bylen == 0: + raise OperationError(space.w_ValueError, space.wrap("empty separator")) + + while maxsplit != 0: + try: + next = iter.next() + except StopIteration: + break + res_w.append(W_RopeObject(rope.getslice_one(selfnode, start, next))) + start = next + bylen + maxsplit -= 1 # NB. if it's already < 0, it stays < 0 + + res_w.append(W_RopeObject(rope.getslice_one( + selfnode, start, selfnode.length()))) + return space.newlist(res_w) + +def str_rsplit__Rope_None_ANY(space, w_self, w_none, w_maxsplit=-1): + # XXX works but flattens + maxsplit = space.int_w(w_maxsplit) + res_w = [] + value = w_self._node.flatten() + i = len(value)-1 + while True: + # starting from the end, find the end of the next word + while i >= 0: + if not value[i].isspace(): + break # found + i -= 1 + else: + break # end of string, finished + + # find the start of the word + # (more precisely, 'j' will be the space character before the word) + if maxsplit == 0: + j = -1 # take all the rest of the string + else: + j = i - 1 + while j >= 0 and not value[j].isspace(): + j -= 1 + maxsplit -= 1 # NB. if it's already < 0, it stays < 0 + + # the word is value[j+1:i+1] + j1 = j + 1 + assert j1 >= 0 + res_w.append(wrap_rpystr(value[j1:i+1])) + + # continue to look from the character before the space before the word + i = j - 1 + + res_w.reverse() + return space.newlist(res_w) + +def str_rsplit__Rope_Rope_ANY(space, w_self, w_by, w_maxsplit=-1): + # XXX works but flattens + maxsplit = space.int_w(w_maxsplit) + res_w = [] + value = w_self._node.flatten() + end = len(value) + by = w_by._node.flatten() + bylen = len(by) + if bylen == 0: + raise OperationError(space.w_ValueError, space.wrap("empty separator")) + + while maxsplit != 0: + next = value.rfind(by, 0, end) + if next < 0: + break + res_w.append(wrap_rpystr(value[next+bylen: end])) + end = next + maxsplit -= 1 # NB. if it's already < 0, it stays < 0 + + res_w.append(wrap_rpystr(value[:end])) + res_w.reverse() + return space.newlist(res_w) + +def str_join__Rope_ANY(space, w_self, w_list): + list_w = space.unpackiterable(w_list) + str_w = space.str_w + if list_w: + self = w_self._node + listlen = 0 + reslen = 0 + 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_w)) + raise OperationError( + space.w_TypeError, + space.wrap("sequence item %d: expected string, %s " + "found" % (i, space.type(w_s).name))) + assert isinstance(w_s, W_RopeObject) + l.append(w_s._node) + return W_RopeObject(rope.join(w_self._node, l)) + else: + return W_RopeObject.empty + +def str_rjust__Rope_ANY_ANY(space, w_self, w_arg, w_fillchar): + u_arg = space.int_w(w_arg) + selfnode = w_self._node + fillchar = space.str_w(w_fillchar) + if len(fillchar) != 1: + raise OperationError(space.w_TypeError, + space.wrap("rjust() argument 2 must be a single character")) + + d = u_arg - selfnode.length() + if d > 0: + fillchar = fillchar[0] # annotator hint: it's a single character + resultnode = rope.concatenate(rope.LiteralStringNode(d * fillchar), + selfnode) + return W_RopeObject(resultnode) + else: + return W_RopeObject(selfnode) + +def str_ljust__Rope_ANY_ANY(space, w_self, w_arg, w_fillchar): + u_arg = space.int_w(w_arg) + selfnode = w_self._node + fillchar = space.str_w(w_fillchar) + if len(fillchar) != 1: + raise OperationError(space.w_TypeError, + space.wrap("rjust() argument 2 must be a single character")) + + d = u_arg - selfnode.length() + if d > 0: + fillchar = fillchar[0] # annotator hint: it's a single character + resultnode = rope.concatenate(selfnode, + rope.LiteralStringNode(d * fillchar)) + return W_RopeObject(resultnode) + else: + return W_RopeObject(selfnode) + + +def _convert_idx_params(space, w_self, w_sub, w_start, w_end): + self = w_self._node + sub = w_sub._node + w_len = space.wrap(self.length()) + w_start = slicetype.adapt_bound(space, w_start, w_len) + w_end = slicetype.adapt_bound(space, w_end, w_len) + + start = space.int_w(w_start) + end = space.int_w(w_end) + assert start >= 0 + assert end >= 0 + + return (self, sub, start, end) + +def contains__Rope_Rope(space, w_self, w_sub): + self = w_self._node + sub = w_sub._node + return space.newbool(rope.find(self, sub) >= 0) + +def str_find__Rope_Rope_ANY_ANY(space, w_self, w_sub, w_start, w_end): + + (self, sub, start, end) = _convert_idx_params(space, w_self, w_sub, w_start, w_end) + res = rope.find(self, sub, start, end) + return wrapint(space, res) + +def str_rfind__Rope_Rope_ANY_ANY(space, w_self, w_sub, w_start, w_end): + # XXX works but flattens + (self, sub, start, end) = _convert_idx_params(space, w_self, w_sub, w_start, w_end) + self = self.flatten() + sub = sub.flatten() + res = self.rfind(sub, start, end) + return wrapint(space, res) + +def str_index__Rope_Rope_ANY_ANY(space, w_self, w_sub, w_start, w_end): + + (self, sub, start, end) = _convert_idx_params(space, w_self, w_sub, w_start, w_end) + res = rope.find(self, sub, start, end) + if res < 0: + raise OperationError(space.w_ValueError, + space.wrap("substring not found in string.index")) + + return wrapint(space, res) + + +def str_rindex__Rope_Rope_ANY_ANY(space, w_self, w_sub, w_start, w_end): + (self, sub, start, end) = _convert_idx_params(space, w_self, w_sub, w_start, w_end) + # XXX works but flattens + self = self.flatten() + sub = sub.flatten() + res = self.rfind(sub, start, end) + if res < 0: + raise OperationError(space.w_ValueError, + space.wrap("substring not found in string.rindex")) + + return wrapint(space, res) + + +def str_replace__Rope_Rope_Rope_ANY(space, w_self, w_sub, w_by, w_maxsplit=-1): + + node = w_self._node + length = node.length() + sub = w_sub._node + by = w_by._node + maxsplit = space.int_w(w_maxsplit) + if maxsplit == 0: + return w_self.create_if_subclassed() + + if not sub.length(): + upper = node.length() + if maxsplit > 0 and maxsplit < upper + 2: + upper = maxsplit - 1 + assert upper >= 0 + substrings = [by] + iter = rope.CharIterator(node) + for i in range(upper): + substrings.append(rope.LiteralStringNode(iter.next())) + substrings.append(by) + substrings.append(rope.getslice_one(node, upper, length)) + return W_RopeObject(rope.rebalance(substrings)) + startidx = 0 + substrings = [] + iter = rope.FindIterator(node, sub) + try: + foundidx = iter.next() + except StopIteration: + return w_self.create_if_subclassed() + while maxsplit != 0: + substrings.append(rope.getslice_one(node, startidx, foundidx)) + startidx = foundidx + sub.length() + try: + foundidx = iter.next() + except StopIteration: + break + maxsplit = maxsplit - 1 + substrings.append(rope.getslice_one(node, startidx, length)) + return W_RopeObject(rope.join(by, substrings)) + +def _strip(space, w_self, w_chars, left, right): + "internal function called by str_xstrip methods" + node = w_self._node + length = node.length() + u_chars = space.str_w(w_chars) + + lpos = 0 + rpos = length + + if left: + #print "while %d < %d and -%s- in -%s-:"%(lpos, rpos, u_self[lpos],w_chars) + iter = rope.CharIterator(node) + while lpos < rpos and iter.next() in u_chars: + lpos += 1 + + if right: + # XXX improve this + while rpos > lpos and node.getitem(rpos - 1) in u_chars: + rpos -= 1 + + return W_RopeObject(rope.getslice_one(node, lpos, rpos)) + +def _strip_none(space, w_self, left, right): + "internal function called by str_xstrip methods" + node = w_self._node + length = node.length() + + lpos = 0 + rpos = length + + if left: + #print "while %d < %d and -%s- in -%s-:"%(lpos, rpos, u_self[lpos],w_chars) + iter = rope.CharIterator(node) + while lpos < rpos and iter.next().isspace(): + lpos += 1 + + if right: + # XXX fix this + while rpos > lpos and node.getitem(rpos - 1).isspace(): + rpos -= 1 + + assert rpos >= lpos # annotator hint, don't remove + return W_RopeObject(rope.getslice_one(node, lpos, rpos)) + +def str_strip__Rope_Rope(space, w_self, w_chars): + return _strip(space, w_self, w_chars, left=1, right=1) + +def str_strip__Rope_None(space, w_self, w_chars): + return _strip_none(space, w_self, left=1, right=1) + +def str_rstrip__Rope_Rope(space, w_self, w_chars): + return _strip(space, w_self, w_chars, left=0, right=1) + +def str_rstrip__Rope_None(space, w_self, w_chars): + return _strip_none(space, w_self, left=0, right=1) + + +def str_lstrip__Rope_Rope(space, w_self, w_chars): + return _strip(space, w_self, w_chars, left=1, right=0) + +def str_lstrip__Rope_None(space, w_self, w_chars): + return _strip_none(space, w_self, left=1, right=0) + + + +def str_center__Rope_ANY_ANY(space, w_self, w_arg, w_fillchar): + node = w_self._node + length = node.length() + arg = space.int_w(w_arg) + fillchar = space.str_w(w_fillchar) + if len(fillchar) != 1: + raise OperationError(space.w_TypeError, + space.wrap("center() argument 2 must be a single character")) + + d = arg - length + if d>0: + offset = d//2 + fillcharnode = rope.LiteralStringNode(fillchar) + pre = rope.multiply(fillcharnode, offset) + post = rope.multiply(fillcharnode, (d - offset)) + centered = rope.rebalance([pre, node, post]) + return W_RopeObject(centered) + else: + return w_self.create_if_subclassed() + +def str_count__Rope_Rope_ANY_ANY(space, w_self, w_arg, w_start, w_end): + selfnode = w_self._node + length = selfnode.length() + argnode = w_arg._node + + w_start = slicetype.adapt_bound(space, w_start, space.wrap(length)) + w_end = slicetype.adapt_bound(space, w_end, space.wrap(length)) + u_start = space.int_w(w_start) + u_end = space.int_w(w_end) + assert u_start >= 0 + assert u_end >= 0 + iter = rope.FindIterator(selfnode, argnode, u_start, u_end) + i = 0 + while 1: + try: + index = iter.next() + except StopIteration: + break + i += 1 + return wrapint(space, i) + +def str_endswith__Rope_Rope_ANY_ANY(space, w_self, w_suffix, w_start, w_end): + (self, suffix, start, end) = _convert_idx_params(space, w_self, + w_suffix, w_start, w_end) + if suffix.length() == 0: + return space.w_True + if self.length() == 0: + return space.w_False + begin = end - suffix.length() + if begin < start: + return space.w_False + iter1 = rope.SeekableCharIterator(self) + iter1.seekforward(begin) + iter2 = rope.CharIterator(suffix) + for i in range(suffix.length()): + if iter1.next() != iter2.next(): + return space.w_False + return space.w_True + +def str_startswith__Rope_Rope_ANY_ANY(space, w_self, w_prefix, w_start, w_end): + (self, prefix, start, end) = _convert_idx_params(space, w_self, + w_prefix, w_start, w_end) + if prefix.length() == 0: + return space.w_True + if self.length() == 0: + return space.w_False + stop = start + prefix.length() + if stop > end: + return space.w_False + iter1 = rope.SeekableCharIterator(self) + iter1.seekforward(start) + iter2 = rope.CharIterator(prefix) + for i in range(prefix.length()): + if iter1.next() != iter2.next(): + return space.w_False + return space.w_True + + +def _tabindent(node, tabsize): + "calculates distance after the token to the next tabstop" + # XXX implement reverse char iterator + length = node.length() + distance = tabsize + if length: + distance = 0 + offset = length + + while 1: + # no sophisticated linebreak support now + # '\r' just for passing adapted CPython test + char = node.getitem(offset - 1) + if char == "\n" or char == "\r": + break + distance += 1 + offset -= 1 + if offset == 0: + break + + #the same like distance = len(u_token) - (offset + 1) + distance = (tabsize - distance) % tabsize + if distance == 0: + return tabsize + + return distance + + +def str_expandtabs__Rope_ANY(space, w_self, w_tabsize): + node = w_self._node + length = node.length() + if length == 0: + return W_RopeObject.empty + tabsize = space.int_w(w_tabsize) + + expanded = [] + iter = rope.FindIterator(node, rope.LiteralStringNode("\t")) + #split = u_self.split("\t") + #u_expanded = oldtoken = split.pop(0) + + #for token in split: + # u_expanded += " " * _tabindent(oldtoken,u_tabsize) + token + # oldtoken = token + start = 0 + try: + start = iter.next() + last = rope.getslice_one(node, 0, start) + start += 1 + except StopIteration: + return w_self.create_if_subclassed() + expanded.append(last) + while 1: + expanded.append(rope.multiply(rope.LiteralStringNode(" "), + _tabindent(last, tabsize))) + try: + next = iter.next() + except StopIteration: + break + last = rope.getslice_one(node, start, next) + expanded.append(last) + start = next + 1 + + expanded.append(rope.getslice_one(node, start, length)) + return W_RopeObject(rope.rebalance(expanded)) + + +def str_splitlines__Rope_ANY(space, w_self, w_keepends): + #import pdb; pdb.set_trace() + keepends = bool(space.int_w(w_keepends)) # truth value, but type checked + node = w_self._node + length = node.length() + if length == 0: + return space.newlist([]) + + strs_w = [] + iter = rope.CharIterator(node) + i = j = 0 + last = " " + char = iter.next() + while i < length: + # Find a line and append it + while char != '\n' and char != '\r': + try: + i += 1 + last = char + char = iter.next() + except StopIteration: + break + # Skip the line break reading CRLF as one line break + eol = i + i += 1 + last = char + try: + char = iter.next() + except StopIteration: + pass + else: + if last == '\r' and char == '\n': + i += 1 + try: + last = char + char = iter.next() + except StopIteration: + pass + if keepends: + eol = i + strs_w.append(W_RopeObject(rope.getslice_one(node, j, eol))) + j = i + + if j == 0: + strs_w.append(w_self.create_if_subclassed()) + elif j < length: + strs_w.append(W_RopeObject(rope.getslice_one(node, j, length))) + + return space.newlist(strs_w) + +def str_zfill__Rope_ANY(space, w_self, w_width): + node = w_self._node + length = node.length() + width = space.int_w(w_width) + + if length >= width: + return w_self.create_if_subclassed() + zero = rope.LiteralStringNode("0") + if length == 0: + return W_RopeObject(rope.multiply(zero, width)) + + middle = width - length + firstchar = node.getitem(0) + if length > 0 and (firstchar == '+' or firstchar == '-'): + return W_RopeObject(rope.rebalance( + [rope.LiteralStringNode(firstchar), + rope.multiply(zero, middle), + rope.getslice_one(node, 1, length)])) + else: + middle = width - length + return W_RopeObject(rope.concatenate( + rope.multiply(zero, middle), node)) + +def str_w__Rope(space, w_str): + return w_str._node.flatten() + +def hash__Rope(space, w_str): + node = w_str._node + x = rope.hash_rope(node) + return wrapint(space, x) + +def lt__Rope_Rope(space, w_str1, w_str2): + n1 = w_str1._node + n2 = w_str2._node + return space.newbool(rope.compare(n1, n2) < 0) + +def le__Rope_Rope(space, w_str1, w_str2): + n1 = w_str1._node + n2 = w_str2._node + return space.newbool(rope.compare(n1, n2) <= 0) + +def eq__Rope_Rope(space, w_str1, w_str2): + n1 = w_str1._node + n2 = w_str2._node + return space.newbool(rope.eq(n1, n2)) + +def ne__Rope_Rope(space, w_str1, w_str2): + n1 = w_str1._node + n2 = w_str2._node + return space.newbool(not rope.eq(n1, n2)) + +def gt__Rope_Rope(space, w_str1, w_str2): + n1 = w_str1._node + n2 = w_str2._node + return space.newbool(rope.compare(n1, n2) > 0) + +def ge__Rope_Rope(space, w_str1, w_str2): + n1 = w_str1._node + n2 = w_str2._node + return space.newbool(rope.compare(n1, n2) >= 0) + +def getitem__Rope_ANY(space, w_str, w_index): + ival = space.int_w(w_index) + node = w_str._node + slen = node.length() + if ival < 0: + ival += slen + if ival < 0 or ival >= slen: + exc = space.call_function(space.w_IndexError, + space.wrap("string index out of range")) + raise OperationError(space.w_IndexError, exc) + return wrap_rpystr(node.getitem(ival)) + +def getitem__Rope_Slice(space, w_str, w_slice): + node = w_str._node + length = node.length() + start, stop, step, sl = w_slice.indices4(space, length) + if sl == 0: + return W_RopeObject.empty + return W_RopeObject(rope.getslice(node, start, stop, step, sl)) + +def mul_string_times(space, w_str, w_times): + try: + mul = space.int_w(w_times) + except OperationError, e: + if e.match(space, space.w_TypeError): + raise FailedToImplement + raise + if mul <= 0: + return W_RopeObject.empty + node = w_str._node + length = node.length() + try: + buflen = ovfcheck(mul * length) + except OverflowError: + raise OperationError( + space.w_OverflowError, + space.wrap("repeated string is too long: %d %d" % (input_len, mul))) + return W_RopeObject(rope.multiply(node, mul)) + +def mul__Rope_ANY(space, w_str, w_times): + return mul_string_times(space, w_str, w_times) + +def mul__ANY_Rope(space, w_times, w_str): + return mul_string_times(space, w_str, w_times) + +def add__Rope_Rope(space, w_left, w_right): + right = w_right._node + left = w_left._node + return W_RopeObject(rope.concatenate(left, right)) + +def len__Rope(space, w_str): + return space.wrap(w_str._node.length()) + +def str__Rope(space, w_str): + if type(w_str) is W_RopeObject: + return w_str + return W_RopeObject(w_str._node) + +def iter__Rope(space, w_list): + return W_RopeIterObject(w_list) + +def ord__Rope(space, w_str): + node = w_str._node + if node.length() != 1: + raise OperationError( + space.w_TypeError, + space.wrap("ord() expected a character, but string " + "of length %d found"%(len(w_str._value),))) + return space.wrap(ord(node.flatten()[0])) + +def getnewargs__Rope(space, w_str): + return space.newtuple([W_RopeObject(w_str._node)]) + +def repr__Rope(space, w_str): + node = w_str._node + length = node.length() + + i = 0 + buf = [' '] * (length * 4 + 2) # safely overallocate + + quote = "'" + if rope.find_char(node, quote) != -1 and rope.find_char(node, '"') == -1: + quote = '"' + + buf[0] = quote + + iter = rope.CharIterator(node) + while 1: + try: + c = iter.next() + i += 1 + except StopIteration: + break + bs_char = None # character quoted by backspace + + if c == '\\' or c == quote: + bs_char = c + elif c == '\t': bs_char = 't' + elif c == '\r': bs_char = 'r' + elif c == '\n': bs_char = 'n' + elif not '\x20' <= c < '\x7f': + n = ord(c) + buf[i] = '\\' + i += 1 + buf[i] = 'x' + i += 1 + buf[i] = "0123456789abcdef"[n>>4] + i += 1 + buf[i] = "0123456789abcdef"[n&0xF] + else: + buf[i] = c + + if bs_char is not None: + buf[i] = '\\' + i += 1 + buf[i] = bs_char + + i += 1 + buf[i] = quote + + return W_RopeObject(rope.rope_from_charlist(buf[:i+1])) + + +app = gateway.applevel(r''' + def str_translate__Rope_ANY_ANY(s, table, deletechars=''): + """charfilter - unicode handling is not implemented + + Return a copy of the string where all characters occurring + in the optional argument deletechars are removed, and the + remaining characters have been mapped through the given translation table, + which must be a string of length 256""" + + if len(table) != 256: + raise ValueError("translation table must be 256 characters long") + + L = [ table[ord(s[i])] for i in range(len(s)) if s[i] not in deletechars ] + return ''.join(L) + + def str_decode__Rope_ANY_ANY(str, encoding=None, errors=None): + import codecs + if encoding is None and errors is None: + return unicode(str) + elif errors is None: + return codecs.getdecoder(encoding)(str)[0] + else: + return codecs.getdecoder(encoding)(str, errors)[0] + + def str_encode__Rope_ANY_ANY(str, encoding=None, errors=None): + import codecs + if encoding is None and errors is None: + return unicode(str) + elif errors is None: + return codecs.getencoder(encoding)(str)[0] + else: + return codecs.getencoder(encoding)(str, errors)[0] +''', filename=__file__) + +# this one should do the import of _formatting: +app2 = gateway.applevel(''' + import _formatting + + def mod__Rope_ANY(format, values): + if isinstance(values, tuple): + return _formatting.format(format, values, None) + else: + # CPython's logic for deciding if ""%values is + # an error (1 value, 0 %-formatters) or not + # (values is of a mapping type) + if (hasattr(values, '__getitem__') + and not isinstance(values, basestring)): + return _formatting.format(format, (values,), values) + else: + return _formatting.format(format, (values,), None) +''', filename=__file__) + +str_translate__Rope_ANY_ANY = app.interphook('str_translate__Rope_ANY_ANY') +str_decode__Rope_ANY_ANY = app.interphook('str_decode__Rope_ANY_ANY') +str_encode__Rope_ANY_ANY = app.interphook('str_encode__Rope_ANY_ANY') +mod__Rope_ANY = app2.interphook('mod__Rope_ANY') + +# methods of the iterator + +def iter__RopeIter(space, w_ropeiter): + return w_ropeiter + +def next__RopeIter(space, w_ropeiter): + if w_ropeiter.node is None: + raise OperationError(space.w_StopIteration, space.w_None) + try: + char = w_ropeiter.char_iter.next() + w_item = wrap_rpystr(char) + except StopIteration: + w_ropeiter.node = None + w_ropeiter.char_iter = None + raise OperationError(space.w_StopIteration, space.w_None) + w_ropeiter.index += 1 + return w_item + +def len__RopeIter(space, w_ropeiter): + if w_ropeiter.node is None: + return wrapint(space, 0) + index = w_ropeiter.index + length = w_ropeiter.node.length() + result = length - index + if result < 0: + return wrapint(space, 0) + return wrapint(space, result) + +# register all methods +from pypy.objspace.std import stringtype +register_all(vars(), stringtype) Modified: pypy/branch/rope-branch/pypy/objspace/std/stringtype.py ============================================================================== --- pypy/branch/rope-branch/pypy/objspace/std/stringtype.py (original) +++ pypy/branch/rope-branch/pypy/objspace/std/stringtype.py Fri Mar 2 16:24:27 2007 @@ -4,6 +4,7 @@ from sys import maxint def sliced(space, s, start, stop): + assert not space.config.objspace.std.withrope if space.config.objspace.std.withstrslice: from pypy.objspace.std.strsliceobject import W_StringSliceObject from pypy.objspace.std.stringobject import W_StringObject @@ -17,6 +18,7 @@ return W_StringObject(s[start:stop]) def joined(space, strlist): + assert not space.config.objspace.std.withrope if space.config.objspace.std.withstrjoin: from pypy.objspace.std.strjoinobject import W_StringJoinObject return W_StringJoinObject(strlist) @@ -222,9 +224,15 @@ if space.is_w(w_stringtype, space.w_str): return w_obj # XXX might be reworked when space.str() typechecks value = space.str_w(w_obj) - w_obj = space.allocate_instance(W_StringObject, w_stringtype) - W_StringObject.__init__(w_obj, value) - return w_obj + if space.config.objspace.std.withrope: + from pypy.objspace.std.ropeobject import rope, W_RopeObject + w_obj = space.allocate_instance(W_RopeObject, w_stringtype) + W_RopeObject.__init__(w_obj, rope.LiteralStringNode(value)) + return w_obj + else: + w_obj = space.allocate_instance(W_StringObject, w_stringtype) + W_StringObject.__init__(w_obj, value) + return w_obj # ____________________________________________________________ Added: pypy/branch/rope-branch/pypy/objspace/std/test/test_rope.py ============================================================================== --- (empty file) +++ pypy/branch/rope-branch/pypy/objspace/std/test/test_rope.py Fri Mar 2 16:24:27 2007 @@ -0,0 +1,307 @@ +import random +from pypy.objspace.std.rope import * + +def make_random_string(operations=10, slicing=True): + seed = random.randrange(10000) + print seed + random.seed(seed) + st = "abc" + curr = LiteralStringNode(st) + if slicing: + choice = [0, 1, 2] + else: + choice = [0, 1] + for i in range(operations): + a = (chr(random.randrange(ord('a'), ord('z') + 1)) * + random.randrange(500)) + c = random.choice(choice) + if c == 0: + curr = curr + LiteralStringNode(a) + st = st + a + elif c == 1: + curr = LiteralStringNode(a) + curr + st = a + st + else: + if len(st) < 10: + continue + start = random.randrange(len(st) // 3) + stop = random.randrange(len(st) // 3 * 2, len(st)) + curr = curr[start: stop] + st = st[start: stop] + return curr, st + + +def test_add(): + s = (LiteralStringNode("a" * 32) + LiteralStringNode("bc" * 32) + + LiteralStringNode("d" * 32) + LiteralStringNode("ef" * 32) + + LiteralStringNode("")) + assert s.depth() == 3 + assert s.flatten() == "".join([c * 32 for c in "a", "bc", "d", "ef"]) + s = s.rebalance() + assert s.flatten() == "".join([c * 32 for c in "a", "bc", "d", "ef"]) + +def test_dont_rebalance_again(): + s = (LiteralStringNode("a" * 32) + LiteralStringNode("b" * 32) + + LiteralStringNode("d" * 32) + LiteralStringNode("e" * 32) + + LiteralStringNode("")) + assert s.depth() == 3 + assert s.flatten() == "".join([c * 32 for c in "abde"]) + s = s.rebalance() + assert s.check_balanced() + assert s.balanced + assert s.flatten() == "".join([c * 32 for c in "abde"]) + +def test_random_addition_test(): + seed = random.randrange(10000) + print seed # 4443 + st = "abc" + curr = LiteralStringNode(st) + for i in range(1000): + a = (chr(random.randrange(ord('a'), ord('z') + 1)) * + random.randrange(100)) + if random.choice([0, 1]): + curr = curr + LiteralStringNode(a) + st = st + a + else: + curr = LiteralStringNode(a) + curr + st = a + st + assert curr.flatten() == st + curr = curr.rebalance() + assert curr.flatten() == st + +def test_getitem(): + result = "".join([c * 32 for c in "a", "bc", "d", "ef"]) + s1 = (LiteralStringNode("a" * 32) + LiteralStringNode("bc" * 32) + + LiteralStringNode("d" * 32) + LiteralStringNode("ef" * 32) + + LiteralStringNode("")) + s2 = s1.rebalance() + for i in range(len(result)): + for s in [s1, s2]: + assert s[i] == result[i] + +def test_getslice(): + result = "".join([c * 32 for c in "a", "bc", "d", "ef"]) + s1 = (LiteralStringNode("a" * 32) + LiteralStringNode("bc" * 32) + + LiteralStringNode("d" * 32) + LiteralStringNode("ef" * 32) + + LiteralStringNode("")) + s2 = s1.rebalance() + for s in [s1, s2]: + for start in range(0, len(result)): + for stop in range(start, len(result)): + assert s[start:stop].flatten() == result[start:stop] + +def test_getslice_step(): + s1 = (LiteralStringNode("abcde") + LiteralStringNode("fghijklm") + + LiteralStringNode("nopqrstu") + LiteralStringNode("vwxyz") + + LiteralStringNode("zyxwvut") + LiteralStringNode("srqpomnlk")) + s2 = s1.rebalance() + result = s1.flatten() + assert s2.flatten() == result + for s in [s1, s2]: + for start in range(0, len(result)): + for stop in range(start, len(result)): + for step in range(1, stop - start): + assert s[start:stop:step].flatten() == result[start:stop:step] + + +def test_random_addition_and_slicing(): + seed = random.randrange(10000) + print seed + random.seed(seed) + st = "abc" + curr = LiteralStringNode(st) + last = None + all = [] + for i in range(1000): + a = (chr(random.randrange(ord('a'), ord('z') + 1)) * + random.randrange(500)) + last = curr + all.append(curr) + c = random.choice([0, 1, 2]) + if c == 0: + curr = curr + LiteralStringNode(a) + st = st + a + elif c == 1: + curr = LiteralStringNode(a) + curr + st = a + st + else: + if len(st) < 10: + continue + # get a significant portion of the string + #import pdb; pdb.set_trace() + start = random.randrange(len(st) // 3) + stop = random.randrange(len(st) // 3 * 2, len(st)) + curr = curr[start: stop] + st = st[start: stop] + assert curr.flatten() == st + curr = curr.rebalance() + assert curr.flatten() == st + +def test_iteration(): + rope, real_st = make_random_string(200) + iter = CharIterator(rope) + for c in real_st: + c2 = iter.next() + assert c2 == c + py.test.raises(StopIteration, iter.next) + +def test_multiply(): + strs = [(LiteralStringNode("a"), "a"), (LiteralStringNode("abc"), "abc"), + make_random_string(500)] + times = range(100) + for i in range(9, 30): + times.append(i ** 2 - 1) + times.append(i ** 2) + times.append(i ** 2 + 1) + times.append(i ** 2 + 2) + for r, st in strs: + for i in times: + r2 = multiply(r, i) + assert r2.flatten() == st * i + +def test_join(): + seps = [(LiteralStringNode("a"), "a"), (LiteralStringNode("abc"), "abc"), + (LiteralStringNode("d"), "d"), (LiteralStringNode(""), "")] + l, strs = zip(*[(LiteralStringNode("x"), "x"), + (LiteralStringNode("xyz"), "xyz"), + (LiteralStringNode("w"), "w")]) + l = list(l) + for s, st in seps: + node = join(s, l) + result1 = node.flatten() + result2 = st.join(strs) + for i in range(node.length()): + assert result1[i] == result2[i] + +def test_join_random(): + l, strs = zip(*[make_random_string(10 * i) for i in range(1, 5)]) + l = list(l) + seps = [(LiteralStringNode("a"), "a"), (LiteralStringNode("abc"), "abc"), + make_random_string(500)] + for s, st in seps: + node = join(s, l) + result1 = node.flatten() + result2 = st.join(strs) + for i in range(node.length()): + assert result1[i] == result2[i] + +def test_seekbackward(): + rope = BinaryConcatNode(BinaryConcatNode(LiteralStringNode("abc"), + LiteralStringNode("def")), + LiteralStringNode("ghi")) + iter = SeekableCharIterator(rope) + for c in "abcdefgh": + c2 = iter.next() + assert c2 == c + for i in range(7): + iter.seekback(i) + for c in "abcdefghi"[-1-i:-1]: + c2 = iter.next() + assert c2 == c + c2 = iter.next() + assert c2 == "i" + py.test.raises(StopIteration, iter.next) + +def test_seekforward(): + rope = BinaryConcatNode(BinaryConcatNode(LiteralStringNode("abc"), + LiteralStringNode("def")), + LiteralStringNode("ghi")) + rope = rope + rope + result = rope.flatten() + for j in range(len(result) - 1): + for i in range(len(result) - 1 - j): + iter = SeekableCharIterator(rope) +# if (j, i) == (3, 1): +# import pdb; pdb.set_trace() + for c in result[:j]: + c2 = iter.next() + assert c2 == c + iter.seekforward(i) + for c in result[i + j:]: + c2 = iter.next() + assert c2 == c + py.test.raises(StopIteration, iter.next) + +def test_find_char(): + rope, st = make_random_string() + rope = rope[10:100] + st = st[10:100] + for i in range(len(st)): + print i + for j in range(i + 1, len(st)): + c = st[i:j][(j - i) // 2] + pos = find_char(rope, c, i, j) + assert pos == st.find(c, i, j) + +def test_find_char_bugs(): + r = find_char(LiteralStringNode("ascii"), " ", 0, 5) + assert r == -1 + r = find_char(LiteralStringNode("a"), "a") + assert r == 0 + + +def test_restart_positions(): + restart = construct_restart_positions_node( + BinaryConcatNode(LiteralStringNode("aba"), LiteralStringNode("bcabab"))) + assert restart == [0, 0, 1, 2, 0, 1, 2, 3, 4] + restart = construct_restart_positions("ababcabab") + assert restart == [0, 0, 1, 2, 0, 1, 2, 3, 4] + +def test_find(): + node = BinaryConcatNode(LiteralStringNode("aba"), + LiteralStringNode("bcabab")) + pos = find(node, LiteralStringNode("abc"), 0, node.length()) + assert pos == 2 + node = BinaryConcatNode(LiteralStringNode("btffp"), + LiteralStringNode("bacbb")) + pos = find(node, LiteralStringNode("a"), 0, node.length()) + assert pos == 6 + +def test_fromcharlist(): + for i in range(0, 100, 10): + chars = ["a"] * 50 + ["b"] * i + node = rope_from_charlist(chars) + assert node.flatten() == "a" * 50 + "b" * i + assert rope_from_charlist([]).flatten() == "" + +def test_find_iterator(): + for searchstring in ["abc", "a", "", "x", "xyz"]: + node = join(LiteralStringNode(searchstring), + [LiteralStringNode("cde" * i) for i in range(1, 10)]) + # node.view() + iter = FindIterator(node, LiteralStringNode(searchstring)) + s = node.flatten() + assert s == searchstring.join(["cde" * i for i in range(1, 10)]) + start = 0 + while 1: + r2 = s.find(searchstring, start) + try: + r1 = iter.next() + except StopIteration: + assert r2 == -1 + break + assert r1 == r2 + start = r2 + max(len(searchstring), 1) + +def test_hash(): + from pypy.rlib.rarithmetic import _hash_string + rope, st = make_random_string() + assert hash_rope(rope) == _hash_string(st) + +def test_equality(): + l = [make_random_string() for i in range(3)] + l.append((LiteralStringNode(""), "")) + for rope1, st1 in l: + for rope2, st2 in l: + assert eq(rope1, rope2) == (st1 == st2) + +def test_compare_random(): + l = [make_random_string() for i in range(3)] + l.append((LiteralStringNode(""), "")) + for rope1, st1 in l: + for rope2, st2 in l: + c = compare(rope1, rope2) + if c: + c = c // abs(c) + assert c == cmp(st1, st2) + Added: pypy/branch/rope-branch/pypy/objspace/std/test/test_ropeobject.py ============================================================================== --- (empty file) +++ pypy/branch/rope-branch/pypy/objspace/std/test/test_ropeobject.py Fri Mar 2 16:24:27 2007 @@ -0,0 +1,27 @@ +import py + +from pypy.objspace.std.test import test_stringobject, test_unicodeobject +from pypy.conftest import gettestobjspace + +class AppTestRopeObject(test_stringobject.AppTestStringObject): + + def setup_class(cls): + cls.space = gettestobjspace(**{"objspace.std.withrope": True}) + +class AppTestRopeUnicode(object): + + def setup_class(cls): + cls.space = gettestobjspace(**{"objspace.std.withrope": True}) + + def test_startswith(self): + assert "abc".startswith("a", 0, 2147483647) + +class AppTestUnicodeRopeStdOnly(test_unicodeobject.AppTestUnicodeStringStdOnly): + + def setup_class(cls): + cls.space = gettestobjspace(**{"objspace.std.withrope": True}) + +class AppTestUnicodeRope(test_unicodeobject.AppTestUnicodeString): + + def setup_class(cls): + cls.space = gettestobjspace(**{"objspace.std.withrope": True}) Modified: pypy/branch/rope-branch/pypy/objspace/std/unicodeobject.py ============================================================================== --- pypy/branch/rope-branch/pypy/objspace/std/unicodeobject.py (original) +++ pypy/branch/rope-branch/pypy/objspace/std/unicodeobject.py Fri Mar 2 16:24:27 2007 @@ -1,6 +1,7 @@ from pypy.objspace.std.objspace import * from pypy.interpreter import gateway from pypy.objspace.std.stringobject import W_StringObject +from pypy.objspace.std.ropeobject import W_RopeObject from pypy.objspace.std.noneobject import W_NoneObject from pypy.objspace.std.sliceobject import W_SliceObject from pypy.rlib.rarithmetic import intmask, ovfcheck @@ -100,11 +101,17 @@ def add__String_Unicode(space, w_left, w_right): return space.add(space.call_function(space.w_unicode, w_left) , w_right) +add__Rope_Unicode = add__String_Unicode + def add__Unicode_String(space, w_left, w_right): return space.add(w_left, space.call_function(space.w_unicode, w_right)) +add__Unicode_Rope = add__Unicode_String + def contains__String_Unicode(space, w_container, w_item): return space.contains(space.call_function(space.w_unicode, w_container), w_item ) +contains__Rope_Unicode = contains__String_Unicode + def _find(self, sub, start, end): if len(sub) == 0: @@ -388,6 +395,7 @@ def unicode_strip__Unicode_String(space, w_self, w_chars): return space.call_method(w_self, 'strip', space.call_function(space.w_unicode, w_chars)) +unicode_strip__Unicode_Rope = unicode_strip__Unicode_String def unicode_lstrip__Unicode_None(space, w_self, w_chars): return _strip_none(space, w_self, 1, 0) @@ -397,6 +405,8 @@ return space.call_method(w_self, 'lstrip', space.call_function(space.w_unicode, w_chars)) +unicode_lstrip__Unicode_Rope = unicode_lstrip__Unicode_String + def unicode_rstrip__Unicode_None(space, w_self, w_chars): return _strip_none(space, w_self, 0, 1) def unicode_rstrip__Unicode_Unicode(space, w_self, w_chars): @@ -405,6 +415,8 @@ return space.call_method(w_self, 'rstrip', space.call_function(space.w_unicode, w_chars)) +unicode_rstrip__Unicode_Rope = unicode_rstrip__Unicode_String + def unicode_capitalize__Unicode(space, w_self): input = w_self._value if len(input) == 0: @@ -999,41 +1011,49 @@ import stringtype W_UnicodeObject = W_UnicodeObject from pypy.objspace.std.stringobject import W_StringObject + from pypy.objspace.std.ropeobject import W_RopeObject def str_strip__String_Unicode(space, w_self, w_chars): return space.call_method(space.call_function(space.w_unicode, w_self), 'strip', w_chars) + str_strip__Rope_Unicode = str_strip__String_Unicode def str_lstrip__String_Unicode(space, w_self, w_chars): return space.call_method(space.call_function(space.w_unicode, w_self), 'lstrip', w_chars) + str_lstrip__Rope_Unicode = str_lstrip__String_Unicode def str_rstrip__String_Unicode(space, w_self, w_chars): return space.call_method(space.call_function(space.w_unicode, w_self), 'rstrip', w_chars) + str_rstrip__Rope_Unicode = str_rstrip__String_Unicode def str_count__String_Unicode_ANY_ANY(space, w_self, w_substr, w_start, w_end): return space.call_method(space.call_function(space.w_unicode, w_self), 'count', w_substr, w_start, w_end) + str_count__Rope_Unicode_ANY_ANY = str_count__String_Unicode_ANY_ANY def str_find__String_Unicode_ANY_ANY(space, w_self, w_substr, w_start, w_end): return space.call_method(space.call_function(space.w_unicode, w_self), 'find', w_substr, w_start, w_end) + str_find__Rope_Unicode_ANY_ANY = str_find__String_Unicode_ANY_ANY def str_rfind__String_Unicode_ANY_ANY(space, w_self, w_substr, w_start, w_end): return space.call_method(space.call_function(space.w_unicode, w_self), 'rfind', w_substr, w_start, w_end) + str_rfind__Rope_Unicode_ANY_ANY = str_rfind__String_Unicode_ANY_ANY def str_index__String_Unicode_ANY_ANY(space, w_self, w_substr, w_start, w_end): return space.call_method(space.call_function(space.w_unicode, w_self), 'index', w_substr, w_start, w_end) + str_index__Rope_Unicode_ANY_ANY = str_index__String_Unicode_ANY_ANY def str_rindex__String_Unicode_ANY_ANY(space, w_self, w_substr, w_start, w_end): return space.call_method(space.call_function(space.w_unicode, w_self), 'rindex', w_substr, w_start, w_end) - + str_rindex__Rope_Unicode_ANY_ANY = str_rindex__String_Unicode_ANY_ANY def str_replace__String_Unicode_Unicode_ANY(space, w_self, w_old, w_new, w_maxsplit): return space.call_method(space.call_function(space.w_unicode, w_self), 'replace', w_old, w_new, w_maxsplit) - + str_replace__Rope_Unicode_Unicode_ANY = str_replace__String_Unicode_Unicode_ANY def str_split__String_Unicode_ANY(space, w_self, w_delim, w_maxsplit): return space.call_method(space.call_function(space.w_unicode, w_self), 'split', w_delim, w_maxsplit) - + str_split__Rope_Unicode_ANY = str_split__String_Unicode_ANY def str_rsplit__String_Unicode_ANY(space, w_self, w_delim, w_maxsplit): return space.call_method(space.call_function(space.w_unicode, w_self), 'rsplit', w_delim, w_maxsplit) - + str_rsplit__Rope_Unicode_ANY = str_rsplit__String_Unicode_ANY register_all(vars(), stringtype) From arigo at codespeak.net Fri Mar 2 16:38:21 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 2 Mar 2007 16:38:21 +0100 (CET) Subject: [pypy-svn] r39708 - pypy/dist/pypy/doc/config Message-ID: <20070302153821.CB8981012D@code0.codespeak.net> Author: arigo Date: Fri Mar 2 16:38:20 2007 New Revision: 39708 Added: pypy/dist/pypy/doc/config/objspace.opcodes.CALL_METHOD.txt (contents, props changed) pypy/dist/pypy/doc/config/objspace.usemodules._cslib.txt (contents, props changed) pypy/dist/pypy/doc/config/objspace.usemodules.cclp.txt (contents, props changed) Log: Three missing option docs. Added: pypy/dist/pypy/doc/config/objspace.opcodes.CALL_METHOD.txt ============================================================================== --- (empty file) +++ pypy/dist/pypy/doc/config/objspace.opcodes.CALL_METHOD.txt Fri Mar 2 16:38:20 2007 @@ -0,0 +1,8 @@ +Enable a pair of bytecodes that speed up method calls. +See ``pypy.interpreter.callmethod`` for a description. + +The goal is to avoid creating the bound method object in the common +case. So far, this only works for calls with no keyword, no ``*arg`` +and no ``**arg`` but it would be easy to extend. + +Gives the best results combined with --objspace-std-withshadowtracking. Added: pypy/dist/pypy/doc/config/objspace.usemodules._cslib.txt ============================================================================== --- (empty file) +++ pypy/dist/pypy/doc/config/objspace.usemodules._cslib.txt Fri Mar 2 16:38:20 2007 @@ -0,0 +1 @@ +Use the '_cslib' module (internal support for the constraint solver). Added: pypy/dist/pypy/doc/config/objspace.usemodules.cclp.txt ============================================================================== --- (empty file) +++ pypy/dist/pypy/doc/config/objspace.usemodules.cclp.txt Fri Mar 2 16:38:20 2007 @@ -0,0 +1 @@ +Use the 'cclp' module (for the logic object space). From mwh at codespeak.net Fri Mar 2 16:38:52 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 2 Mar 2007 16:38:52 +0100 (CET) Subject: [pypy-svn] r39709 - pypy/dist/pypy/translator/benchmark Message-ID: <20070302153852.E8F1410147@code0.codespeak.net> Author: mwh Date: Fri Mar 2 16:38:48 2007 New Revision: 39709 Modified: pypy/dist/pypy/translator/benchmark/bench-custom.py pypy/dist/pypy/translator/benchmark/benchmarks.py pypy/dist/pypy/translator/benchmark/result.py Log: allow benchmarks to indicate that they failed. 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 Fri Mar 2 16:38:48 2007 @@ -40,7 +40,7 @@ for i in range(int(options.runcount)): for exe in exes: for b in benchmarks: - benchmark_result.result(exe).run_benchmark(b, verbose=True) + benchmark_result.result(exe, allowcreate=True).run_benchmark(b, verbose=True) pickle.dump(benchmark_result, open(options.picklefile, 'wb')) Modified: pypy/dist/pypy/translator/benchmark/benchmarks.py ============================================================================== --- pypy/dist/pypy/translator/benchmark/benchmarks.py (original) +++ pypy/dist/pypy/translator/benchmark/benchmarks.py Fri Mar 2 16:38:48 2007 @@ -1,5 +1,8 @@ import os, sys, time, pickle, re, py +class BenchmarkFailed(Exception): + pass + PYSTONE_CMD = 'from test import pystone;pystone.main(%s)' PYSTONE_PATTERN = 'This machine benchmarks at' PYSTONE_ASCENDING_GOOD = True @@ -13,17 +16,20 @@ if line.startswith(pattern): break else: - print repr(txt) - print 'warning: this is not valid output' - return 99999.0 + raise BenchmarkFailed return float(line.split()[len(pattern.split())]) class Benchmark(object): def __init__(self, name, runner, asc_good, units): self.name = name - self.run = runner + self._run = runner self.asc_good = asc_good self.units = units + def run(self, exe): + try: + return self._run(exe) + except BenchmarkFailed: + return '-FAILED-' def run_cmd(cmd): #print "running", cmd @@ -47,15 +53,14 @@ def run_translate(executable='/usr/local/bin/python'): translate = py.magic.autopath().dirpath().dirpath().join('goal').join('translate.py') - argstr = 'sh -c "time %s %s --text --batch --backendopt --no-compile targetrpystonedalone.py > /dev/null 2>/dev/null" 2>&1 | grep real' - cmd = argstr%(executable, translate) - txt = run_cmd(cmd) - m = re.match('real\s+(?P\\d+)m(?P\\d+\\.\\d+)s', txt) - if not m: - print repr(txt) - print 'ow' - return 99999.0 - return 1000*(float(m.group('mins'))*60 + float(m.group('secs'))) + target = py.magic.autopath().dirpath().dirpath().join('goal').join('targetrpystonedalone.py') + argstr = '%s %s --text --batch --backendopt --no-compile %s > /dev/null 2> /dev/null' + T = time.time() + status = os.system(argstr%(executable, translate, target)) + r = time.time() - T + if status: + raise BenchmarkFailed(status) + return r BENCHMARKS = [Benchmark('richards', run_richards, RICHARDS_ASCENDING_GOOD, 'ms'), Benchmark('pystone', run_pystone, PYSTONE_ASCENDING_GOOD, ''), Modified: pypy/dist/pypy/translator/benchmark/result.py ============================================================================== --- pypy/dist/pypy/translator/benchmark/result.py (original) +++ pypy/dist/pypy/translator/benchmark/result.py Fri Mar 2 16:38:48 2007 @@ -12,8 +12,8 @@ self.benchmarks = {} self.max_results = max_results - def result(self, exe): - if exe in self.benchmarks: + def result(self, exe, allowcreate=False): + if exe in self.benchmarks or not allowcreate: return self.benchmarks[exe] else: r = self.benchmarks[exe] = BenchmarkResult(exe, self.max_results) @@ -89,6 +89,9 @@ new_result = benchmark.run(self.exe_name) if verbose: print new_result + self.run_counts[benchmark.name] = self.run_counts.get(benchmark.name, 0) + 1 + if new_result == '-FAILED-': + return self.benchmarks.setdefault(benchmark.name, []).append(new_result) if benchmark.name in self.best_benchmarks: old_result = self.best_benchmarks[benchmark.name] @@ -97,7 +100,6 @@ else: new_result = min(new_result, old_result) self.best_benchmarks[benchmark.name] = new_result - self.run_counts[benchmark.name] = self.run_counts.get(benchmark.name, 0) + 1 def getstat(self, *args): # oh for supplied-p! From mwh at codespeak.net Fri Mar 2 16:40:53 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 2 Mar 2007 16:40:53 +0100 (CET) Subject: [pypy-svn] r39710 - pypy/dist/pypy/doc Message-ID: <20070302154053.0C092100CD@code0.codespeak.net> Author: mwh Date: Fri Mar 2 16:40:48 2007 New Revision: 39710 Modified: pypy/dist/pypy/doc/faq.txt Log: typo Modified: pypy/dist/pypy/doc/faq.txt ============================================================================== --- pypy/dist/pypy/doc/faq.txt (original) +++ pypy/dist/pypy/doc/faq.txt Fri Mar 2 16:40:48 2007 @@ -37,7 +37,7 @@ The mostly likely stumbling block for any given project is support for `extension modules`_. PyPy supports a small but continually growing number of extension modules, so far mostly those found in the standard -library. The `threading` support is also not perfectly complete. +library. The `threading`_ support is also not perfectly complete. The language features (including builtin types and functions) are very complete and well tested, so if your project does not use many From fijal at codespeak.net Fri Mar 2 16:41:11 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 2 Mar 2007 16:41:11 +0100 (CET) Subject: [pypy-svn] r39711 - pypy/dist/pypy/lib/distributed/demo Message-ID: <20070302154111.798B21013A@code0.codespeak.net> Author: fijal Date: Fri Mar 2 16:41:06 2007 New Revision: 39711 Removed: pypy/dist/pypy/lib/distributed/demo/show.py Log: Remove deprecated demo From ac at codespeak.net Fri Mar 2 17:06:24 2007 From: ac at codespeak.net (ac at codespeak.net) Date: Fri, 2 Mar 2007 17:06:24 +0100 (CET) Subject: [pypy-svn] r39714 - pypy/dist/pypy/lib Message-ID: <20070302160624.262AD100AB@code0.codespeak.net> Author: ac Date: Fri Mar 2 17:06:21 2007 New Revision: 39714 Modified: pypy/dist/pypy/lib/stackless_new.py Log: (stedi67, arre) stackless_new now passes all tests :-) Modified: pypy/dist/pypy/lib/stackless_new.py ============================================================================== --- pypy/dist/pypy/lib/stackless_new.py (original) +++ pypy/dist/pypy/lib/stackless_new.py Fri Mar 2 17:06:21 2007 @@ -39,7 +39,9 @@ if normal: _squeue.append(value) else: + _squeue.rotate(-1) _squeue.appendleft(value) + _squeue.rotate(1) def _scheduler_contains(value): try: @@ -50,11 +52,14 @@ def _scheduler_switch(current, next): global _last_task + prev = _last_task + if (_schedule_callback is not None and + prev is not next): + _schedule_callback(prev, next) _last_task = next - if _schedule_callback is not None: - _schedule_callback(current, next) assert not next.blocked - next.switch() + if next is not current: + next.switch() return current @@ -78,7 +83,7 @@ self.traceback = exp_traceback def raise_(self): - raise self.type(self.value) + raise self.type, self.value, self.traceback class channel(object): """ @@ -140,7 +145,10 @@ self.balance -= 1 self.queue.append(receiver) receiver.blocked = True - schedule_remove() + _scheduler_remove(getcurrent()) + schedule() + assert not receiver.blocked + msg = receiver.tempval if isinstance(msg, bomb): msg.raise_() @@ -177,8 +185,10 @@ self.queue.append(sender) sender.blocked = True self.balance += 1 - schedule_remove() - + _scheduler_remove(getcurrent()) + schedule() + assert not sender.blocked + class tasklet(coroutine): """ A tasklet object represents a tiny task in a Python thread. @@ -186,6 +196,7 @@ New tasklets can be created with methods from the stackless module. """ + tempval = None def __new__(cls, func=None, label=''): return super(tasklet,cls).__new__(cls) @@ -195,7 +206,7 @@ def _init(self, func=None, label=''): global _global_task_id - self.tempval = func + self.func = func self.alive = False self.blocked = False self._task_id = _global_task_id @@ -220,7 +231,7 @@ """ if not callable(func): raise TypeError('tasklet function must be a callable') - self.tempval = func + self.func = func def kill(self): """ @@ -232,16 +243,28 @@ """ if not self.is_zombie: coroutine.kill(self) + _scheduler_remove(self) self.alive = False def setup(self, *argl, **argd): """ supply the parameters for the callable """ - if self.tempval is None: + if self.func is None: raise TypeError('cframe function must be callable') - coroutine.bind(self,self.tempval,*argl,**argd) - self.tempval = None + func = self.func + def _func(): + try: + try: + func(*argl, **argd) + except TaskletExit: + pass + finally: + _scheduler_remove(self) + self.alive = False + + self.func = None + coroutine.bind(self, _func) self.alive = True _scheduler_append(self) return self @@ -274,6 +297,7 @@ else: return curr +_run_calls = [] def run(): """ run_watchdog(timeout) -- run tasklets until they are all @@ -287,12 +311,14 @@ Please note that the 'timeout' feature is not yet implemented """ - r = schedule_remove() - if _last_task and _schedule_callback is not None: - _schedule_callback(_last_task, getcurrent()) - while _squeue: - r = schedule() - _scheduler_append(getcurrent()) + curr = getcurrent() + _run_calls.append(curr) + _scheduler_remove(curr) + try: + schedule() + assert not _squeue + finally: + _scheduler_append(curr) def schedule_remove(retval=None): """ @@ -305,7 +331,8 @@ r = schedule(retval) return r -def schedule(retval=None, prev=None): + +def schedule(retval=None): """ schedule(retval=stackless.current) -- switch to the next runnable tasklet. The return value for this call is retval, with the current @@ -314,40 +341,24 @@ """ mtask = getmain() curr = getcurrent() - if _squeue: - task = _squeue[0] - _squeue.rotate(-1) - if task is not curr and task.is_alive: - c = prev or curr - r = _scheduler_switch(c, task) - curr = getcurrent() - if not task.is_alive: - if _squeue: - pt = _squeue.pop() - if pt.is_alive: - _scheduler_append(pt) - else: - coroutine.kill(task) - else: - if curr is not mtask: - r = _scheduler_switch(curr, mtask) - return retval or r - r = schedule(prev=task) - return retval or r - return r - elif task is curr: - if len(_squeue) > 1: - if _squeue[0] is _squeue[-1]: - _squeue.pop() - r = schedule() - return retval or r - return retval or curr - elif not task.is_alive: - _scheduler_remove(task) - if not _squeue: - _scheduler_append(mtask) - return retval or curr - return retval or curr + if retval is None: + retval = curr + while True: + if _squeue: + if _squeue[0] is curr: + # If the current is at the head, skip it. + _squeue.rotate(-1) + + task = _squeue[0] + #_squeue.rotate(-1) + elif _run_calls: + task = _run_calls.pop() + else: + raise RuntimeError('No runnable tasklets left.') + _scheduler_switch(curr, task) + if curr is _last_task: + # We are in the tasklet we want to resume at this point. + return retval def _init(): global _main_tasklet @@ -380,6 +391,7 @@ _main_coroutine = _main_tasklet _main_tasklet = TaskletProxy(_main_tasklet) assert _main_tasklet.is_alive and not _main_tasklet.is_zombie + _last_task = _main_tasklet tasklet._init.im_func(_main_tasklet, label='main') _squeue = deque() _scheduler_append(_main_tasklet) From ac at codespeak.net Fri Mar 2 17:07:53 2007 From: ac at codespeak.net (ac at codespeak.net) Date: Fri, 2 Mar 2007 17:07:53 +0100 (CET) Subject: [pypy-svn] r39715 - pypy/dist/pypy/lib/app_test Message-ID: <20070302160753.C9C48100AB@code0.codespeak.net> Author: ac Date: Fri Mar 2 17:07:51 2007 New Revision: 39715 Modified: pypy/dist/pypy/lib/app_test/test_stackless.py Log: (stedi67, arre) Enable all tests for stackless_new. Modified: pypy/dist/pypy/lib/app_test/test_stackless.py ============================================================================== --- pypy/dist/pypy/lib/app_test/test_stackless.py (original) +++ pypy/dist/pypy/lib/app_test/test_stackless.py Fri Mar 2 17:07:51 2007 @@ -80,7 +80,7 @@ assert s == 's%s' % i assert r == 'r%s' % i - def test_counter(self): + def test_send_counter(self): import random numbers = range(20) @@ -104,6 +104,31 @@ numbers.sort() assert rlist == numbers + def test_receive_counter(self): + import random + + numbers = range(20) + random.shuffle(numbers) + + rlist = [] + def counter(n, ch): + for i in xrange(n): + stackless.schedule() + ch.receive() + rlist.append(n) + + ch = stackless.channel() + for each in numbers: + stackless.tasklet(counter)(each, ch) + + stackless.run() + + while ch.balance: + ch.send(None) + + numbers.sort() + assert rlist == numbers + def test_scheduling_cleanup(self): rlist = [] def f(): @@ -373,6 +398,7 @@ maintask = stackless.getmain() stackless.run() assert res == ['A_1', 'A_2', 'B_1', 'B_2'] + assert len(cb) == 5 assert cb[0] == (maintask, t1) assert cb[1] == (t1, t2) assert cb[2] == (t2, t1) @@ -491,13 +517,6 @@ A tasklets/channels adaptation of the test_wait_two from the logic object space """ - # there are still problems with scheduling. Apparently, - # some leftover tasklets in the queue are messing - # things up. This test runs fine, when being alone - # in a test file - if not SHOW_STRANGE: - pypy_skip("still problems with scheduling") - def sleep(X, Y): dprint('twt_S ==== 1') value = X.receive() @@ -534,23 +553,6 @@ dprint('twt ==== 4') assert value == (2, 42) - def test_noop(self): - """ - this test is from pypy/lib/test2. - Left it in for documentation purposes. - "switch" is not officially in the tasklet interface. It it just - an implementation detail, that tasklets are descendents from - coroutines, which do have a 'switch' method - """ - skip("this test does not make sense at the moment") - main = stackless.getcurrent() - - def switch_to_main(): - main.switch() - - t = stackless.tasklet(switch_to_main)() - stackless.run() - From ac at codespeak.net Fri Mar 2 17:08:12 2007 From: ac at codespeak.net (ac at codespeak.net) Date: Fri, 2 Mar 2007 17:08:12 +0100 (CET) Subject: [pypy-svn] r39716 - pypy/dist/pypy/lib Message-ID: <20070302160812.15401100E9@code0.codespeak.net> Author: ac Date: Fri Mar 2 17:08:10 2007 New Revision: 39716 Added: pypy/dist/pypy/lib/stackless_old.py - copied unchanged from r39652, pypy/dist/pypy/lib/stackless.py Removed: pypy/dist/pypy/lib/stackless.py Log: (stedi67, arre) Move old stackless.py out of the way. From fijal at codespeak.net Fri Mar 2 17:08:17 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 2 Mar 2007 17:08:17 +0100 (CET) Subject: [pypy-svn] r39717 - pypy/dist/pypy/lib/distributed Message-ID: <20070302160817.E8DB310136@code0.codespeak.net> Author: fijal Date: Fri Mar 2 17:08:14 2007 New Revision: 39717 Modified: pypy/dist/pypy/lib/distributed/socklayer.py Log: Make socklayer working (provided greensock2 is on path) Modified: pypy/dist/pypy/lib/distributed/socklayer.py ============================================================================== --- pypy/dist/pypy/lib/distributed/socklayer.py (original) +++ pypy/dist/pypy/lib/distributed/socklayer.py Fri Mar 2 17:08:14 2007 @@ -1,5 +1,6 @@ from pypeers.pipe.gsocket import GreenSocket +from pypeers.msgstruct import decodemessage, message from socket import socket, AF_INET, SOCK_STREAM import marshal import sys @@ -9,29 +10,39 @@ if TRACE: print >>sys.stderr, msg -def receive(conn): - all = [] - data = conn.recv(10000) - trace("received %s" % data) - return marshal.loads(data) - -def send(conn, data): - trace("sending %s" % (data,)) - conn.send(marshal.dumps(data)) - trace("done") +class SocketWrapper(object): + def __init__(self, conn): + self.buffer = "" + self.conn = conn + + def receive(self): + msg, self.buffer = decodemessage(self.buffer) + while msg is None: + self.buffer += self.conn.recv(8192) + msg, self.buffer = decodemessage(self.buffer) + assert msg[0] == 'c' + trace("received %s" % msg[1]) + return marshal.loads(msg[1]) + + def send(self, data): + trace("sending %s" % (data,)) + self.conn.sendall(message('c', marshal.dumps(data))) + trace("done") -def socket_listener(address=('', 12121)): +def socket_listener(address=('', 12122)): s = GreenSocket(AF_INET, SOCK_STREAM) s.bind(address) s.listen(1) print "Waiting for connection" conn, addr = s.accept() - - return lambda data : send(conn, data), lambda : receive(conn) + + sw = SocketWrapper(conn) + return sw.send, sw.receive def socket_connecter(address): s = GreenSocket(AF_INET, SOCK_STREAM) print "Connecting %s" % (address,) s.connect(address) - return lambda data : send(s, data), lambda : receive(s) + sw = SocketWrapper(s) + return sw.send, sw.receive From fijal at codespeak.net Fri Mar 2 17:08:40 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 2 Mar 2007 17:08:40 +0100 (CET) Subject: [pypy-svn] r39718 - in pypy/dist/pypy/lib/distributed: . test Message-ID: <20070302160840.8EF6F100DF@code0.codespeak.net> Author: fijal Date: Fri Mar 2 17:08:39 2007 New Revision: 39718 Modified: pypy/dist/pypy/lib/distributed/objkeeper.py pypy/dist/pypy/lib/distributed/test/test_distributed.py Log: Explicitely disallow instantiating of remote types Modified: pypy/dist/pypy/lib/distributed/objkeeper.py ============================================================================== --- pypy/dist/pypy/lib/distributed/objkeeper.py (original) +++ pypy/dist/pypy/lib/distributed/objkeeper.py Fri Mar 2 17:08:39 2007 @@ -11,6 +11,10 @@ _, _, tb = sys.exc_info() GetSetDescriptor = type(type(tb).tb_frame) +class noninstantiabletype(object): + def __new__(cls, *args, **kwargs): + raise NotImplementedError("Cannot instantiate remote type") + class ObjKeeper(object): def __init__(self, exported_names = {}): self.exported_objects = [] # list of object that we've exported outside @@ -52,10 +56,10 @@ def fake_remote_type(self, protocol, type_id, _name, _dict): print "Faking type %s as %s" % (_name, type_id) # create and register new type - d = dict([(key, None) for key in _dict]) + d = dict([(key, None) for key in _dict if key != '__new__']) if '__doc__' in _dict: d['__doc__'] = protocol.unwrap(_dict['__doc__']) - tp = type(_name, (object,), d) + tp = type(_name, (noninstantiabletype,), d) # Make sure we cannot instantiate the remote type self.remote_types[type_id] = tp for key, value in _dict.items(): 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 Fri Mar 2 17:08:39 2007 @@ -199,10 +199,10 @@ raise AssertionError("Did not raise") def test_instantiate_remote_type(self): - skip("Land of infinite recursion") + #skip("Land of infinite recursion") class C: pass protocol = self.test_env({'C':C}) xC = protocol.get_remote('C') - xC() + raises(NotImplementedError, "xC()") From santagada at codespeak.net Fri Mar 2 17:11:57 2007 From: santagada at codespeak.net (santagada at codespeak.net) Date: Fri, 2 Mar 2007 17:11:57 +0100 (CET) Subject: [pypy-svn] r39719 - pypy/dist/pypy/lang/js Message-ID: <20070302161157.6FB0C100DF@code0.codespeak.net> Author: santagada Date: Fri Mar 2 17:11:54 2007 New Revision: 39719 Modified: pypy/dist/pypy/lang/js/conftest.py Log: py.test distributed stuff Modified: pypy/dist/pypy/lang/js/conftest.py ============================================================================== --- pypy/dist/pypy/lang/js/conftest.py (original) +++ pypy/dist/pypy/lang/js/conftest.py Fri Mar 2 17:11:54 2007 @@ -1,7 +1,7 @@ import py -dist_hosts = ['localhost:/tmp/jspypy', 'localhost'] -dist_rsync_roots = ['../../../',] +dist_hosts = ['localhost', 'localhost'] +# dist_rsync_roots = [,] # dist_remotepython = 'python2.4' dist_nicelevel = 10 dist_boxed = False From gbrandl at codespeak.net Fri Mar 2 17:16:57 2007 From: gbrandl at codespeak.net (gbrandl at codespeak.net) Date: Fri, 2 Mar 2007 17:16:57 +0100 (CET) Subject: [pypy-svn] r39720 - pypy/dist/pypy/objspace/std Message-ID: <20070302161657.4A30F100CD@code0.codespeak.net> Author: gbrandl Date: Fri Mar 2 17:16:55 2007 New Revision: 39720 Modified: pypy/dist/pypy/objspace/std/listmultiobject.py pypy/dist/pypy/objspace/std/smartresizablelist.py Log: Fix in strlist.getitem_slice_step. Modified: pypy/dist/pypy/objspace/std/listmultiobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/listmultiobject.py (original) +++ pypy/dist/pypy/objspace/std/listmultiobject.py Fri Mar 2 17:16:55 2007 @@ -337,7 +337,7 @@ assert 0 <= start < len(self.strlist) assert 0 <= stop < len(self.strlist) assert slicelength > 0 - res = [0] * slicelength + res = [""] * slicelength for i in range(slicelength): res[i] = self.strlist[start] start += step Modified: pypy/dist/pypy/objspace/std/smartresizablelist.py ============================================================================== --- pypy/dist/pypy/objspace/std/smartresizablelist.py (original) +++ pypy/dist/pypy/objspace/std/smartresizablelist.py Fri Mar 2 17:16:55 2007 @@ -159,7 +159,6 @@ self.data_blocks[a][b] = value def getitem_slice(self, start, stop): - # XXX make default implementation? l = stop - start result = SmartResizableListImplementation(self.space) result.grow(l) From ac at codespeak.net Fri Mar 2 17:19:27 2007 From: ac at codespeak.net (ac at codespeak.net) Date: Fri, 2 Mar 2007 17:19:27 +0100 (CET) Subject: [pypy-svn] r39721 - in pypy/dist/pypy/lib: . app_test Message-ID: <20070302161927.B5939100CD@code0.codespeak.net> Author: ac Date: Fri Mar 2 17:19:25 2007 New Revision: 39721 Added: pypy/dist/pypy/lib/stackless.py - copied, changed from r39714, pypy/dist/pypy/lib/stackless_new.py Removed: pypy/dist/pypy/lib/stackless_new.py Modified: pypy/dist/pypy/lib/app_test/test_stackless.py pypy/dist/pypy/lib/app_test/test_stackless_pickling.py Log: (stedi67, arre) Use the new and refactored stackless module as the default one. Modified: pypy/dist/pypy/lib/app_test/test_stackless.py ============================================================================== --- pypy/dist/pypy/lib/app_test/test_stackless.py (original) +++ pypy/dist/pypy/lib/app_test/test_stackless.py Fri Mar 2 17:19:25 2007 @@ -7,14 +7,9 @@ from py.test import skip try: import stackless - stackless_c = True - if 'coroutine' in dir(stackless): - stackless_c = False - raise ImportError("We are running pypy-c") except ImportError: - stackless_c = False try: - from pypy.lib import stackless_new as stackless + from pypy.lib import stackless except ImportError, e: skip('cannot import stackless: %s' % (e,)) @@ -24,11 +19,6 @@ if SHOW_STRANGE: print txt -def pypy_skip(txt): - "don't skip, if we are running with CStackless" - if not stackless_c: - skip(txt) - class Test_Stackless: def test_simple(self): Modified: pypy/dist/pypy/lib/app_test/test_stackless_pickling.py ============================================================================== --- pypy/dist/pypy/lib/app_test/test_stackless_pickling.py (original) +++ pypy/dist/pypy/lib/app_test/test_stackless_pickling.py Fri Mar 2 17:19:25 2007 @@ -5,14 +5,9 @@ from py.test import skip try: import stackless - stackless_c = True - if 'coroutine' in dir(stackless): - stackless_c = False - raise ImportError("We are running pypy-c") except ImportError: - stackless_c = False try: - from pypy.lib import stackless_new as stackless + from pypy.lib import stackless as stackless except ImportError, e: skip('cannot import stackless: %s' % (e,)) From antocuni at codespeak.net Fri Mar 2 17:27:46 2007 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Fri, 2 Mar 2007 17:27:46 +0100 (CET) Subject: [pypy-svn] r39722 - pypy/dist/pypy/rpython/microbench Message-ID: <20070302162746.0521D100DF@code0.codespeak.net> Author: antocuni Date: Fri Mar 2 17:27:44 2007 New Revision: 39722 Added: pypy/dist/pypy/rpython/microbench/dict.py (contents, props changed) pypy/dist/pypy/rpython/microbench/indirect.py (contents, props changed) pypy/dist/pypy/rpython/microbench/rdict.py (contents, props changed) Modified: pypy/dist/pypy/rpython/microbench/list.py pypy/dist/pypy/rpython/microbench/microbench.py Log: (antocuni, pedronis) some more microbenchmarks Added: pypy/dist/pypy/rpython/microbench/dict.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/rpython/microbench/dict.py Fri Mar 2 17:27:44 2007 @@ -0,0 +1,65 @@ +from pypy.rpython.microbench.microbench import MetaBench + +class str_dict__set_item: + __metaclass__ = MetaBench + + def init(): + return {} + args = ['obj', 'i'] + def loop(obj, i): + obj['foo'] = i + obj['bar'] = i + +class str_dict__get_item: + __metaclass__ = MetaBench + + def init(): + return {'foo': 0, 'bar': 1} + args = ['obj', 'i'] + def loop(obj, i): + return obj['foo'] + obj['bar'] + +class int_dict__set_item: + __metaclass__ = MetaBench + + def init(): + return {} + args = ['obj', 'i'] + def loop(obj, i): + obj[42] = i + obj[43] = i + +class int_dict__get_item: + __metaclass__ = MetaBench + + def init(): + return {42: 0, 43: 1} + args = ['obj', 'i'] + def loop(obj, i): + return obj[42] + obj[43] + + +class Foo: + pass + +obj1 = Foo() +obj2 = Foo() + +class obj_dict__set_item: + __metaclass__ = MetaBench + + def init(): + return {} + args = ['obj', 'i'] + def loop(obj, i): + obj[obj1] = i + obj[obj2] = i + +class obj_dict__get_item: + __metaclass__ = MetaBench + + def init(): + return {obj1: 0, obj2: 1} + args = ['obj', 'i'] + def loop(obj, i): + return obj[obj1] + obj[obj2] Added: pypy/dist/pypy/rpython/microbench/indirect.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/rpython/microbench/indirect.py Fri Mar 2 17:27:44 2007 @@ -0,0 +1,24 @@ +from pypy.rpython.microbench.microbench import MetaBench + +def f1(x): + return x + +def f2(x): + return x+1 + +def f3(x): + return x+2 + +def f4(x): + return x+3 + +FUNCS = [f1, f2, f3, f4] + +class indirect__call: + __metaclass__ = MetaBench + + def init(): + return FUNCS + args = ['obj', 'i'] + def loop(obj, i): + return obj[i%4](i) Modified: pypy/dist/pypy/rpython/microbench/list.py ============================================================================== --- pypy/dist/pypy/rpython/microbench/list.py (original) +++ pypy/dist/pypy/rpython/microbench/list.py Fri Mar 2 17:27:44 2007 @@ -1,6 +1,6 @@ from pypy.rpython.microbench.microbench import MetaBench -class ListAppend: +class list__append: __metaclass__ = MetaBench def init(): return [] @@ -8,7 +8,7 @@ def loop(obj, i): obj.append(i) -class ListGetItem: +class list__get_item: __metaclass__ = MetaBench LOOPS = 100000000 def init(): @@ -20,7 +20,7 @@ def loop(obj, i): return obj[i%1000] -class ListSetItem: +class list__set_item: __metaclass__ = MetaBench LOOPS = 100000000 def init(): @@ -32,7 +32,7 @@ def loop(obj, i): obj[i%1000] = i -class FixedListGetItem: +class fixed_list__get_item: __metaclass__ = MetaBench LOOPS = 100000000 def init(): @@ -41,7 +41,7 @@ def loop(obj, i): return obj[i%1000] -class FixedListSetItem: +class fixed_list__set_item: __metaclass__ = MetaBench LOOPS = 100000000 def init(): Modified: pypy/dist/pypy/rpython/microbench/microbench.py ============================================================================== --- pypy/dist/pypy/rpython/microbench/microbench.py (original) +++ pypy/dist/pypy/rpython/microbench/microbench.py Fri Mar 2 17:27:44 2007 @@ -90,7 +90,7 @@ c_res = run_benchmark(c_exe) cli_res = run_benchmark(cli_exe) - print 'benchmark genc gencli ratio' + print 'benchmark genc gencli ratio' print for name, _ in benchmarks: c_time = c_res[name] @@ -99,7 +99,7 @@ ratio = '%10s' % '---' else: ratio = '%10.2f' % (cli_time/c_time) - print '%-25s %10.2f %10.2f %s' % (name, c_time, cli_time, ratio) + print '%-32s %10.2f %10.2f %s' % (name, c_time, cli_time, ratio) if __name__ == '__main__': main() Added: pypy/dist/pypy/rpython/microbench/rdict.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/rpython/microbench/rdict.py Fri Mar 2 17:27:44 2007 @@ -0,0 +1,70 @@ +from pypy.rlib.objectmodel import r_dict +from pypy.rpython.microbench.microbench import MetaBench + +class Obj: + def __init__(self, x): + self.x = x + +def myhash(obj): + return obj.x + +def mycmp(obj1, obj2): + return obj1.x == obj2.x + +class Space: + def myhash(self, obj): + return obj.x + + def mycmp(self, obj1, obj2): + return obj1.x == obj2.x + + def _freeze_(self): + return True + +space = Space() +obj1 = Obj(1) +obj2 = Obj(2) + +class r_dict__set_item: + __metaclass__ = MetaBench + + def init(): + return r_dict(mycmp, myhash) + args = ['obj', 'i'] + def loop(obj, i): + obj[obj1] = i + obj[obj2] = i + +class r_dict__get_item: + __metaclass__ = MetaBench + + def init(): + res = r_dict(mycmp, myhash) + res[obj1] = 42 + res[obj2] = 43 + return res + args = ['obj', 'i'] + def loop(obj, i): + return obj[obj1] + obj[obj2] + +class r_dict__frozen_pbc__set_item: + __metaclass__ = MetaBench + + def init(): + return r_dict(space.mycmp, space.myhash) + args = ['obj', 'i'] + def loop(obj, i): + obj[obj1] = i + obj[obj2] = i + +class r_dict__frozen_pbc__get_item: + __metaclass__ = MetaBench + + def init(): + res = r_dict(space.mycmp, space.myhash) + res[obj1] = 42 + res[obj2] = 43 + return res + args = ['obj', 'i'] + def loop(obj, i): + return obj[obj1] + obj[obj2] From mwh at codespeak.net Fri Mar 2 17:35:04 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 2 Mar 2007 17:35:04 +0100 (CET) Subject: [pypy-svn] r39723 - pypy/dist/pypy/translator/benchmark Message-ID: <20070302163504.8A83A10071@code0.codespeak.net> Author: mwh Date: Fri Mar 2 17:35:02 2007 New Revision: 39723 Modified: pypy/dist/pypy/translator/benchmark/bench-custom.py pypy/dist/pypy/translator/benchmark/benchmarks.py Log: add a docutils benchmark. as this seems to require a svn docutils, you have to tell it where your docutils svn checkout is, and some hair to allow benchmarks to refuse to run. 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 Fri Mar 2 17:35:02 2007 @@ -21,7 +21,13 @@ else: benchmark_result = BenchmarkResultSet() - benchmarks = [b for b in BENCHMARKS if b.name in options.benchmarks] + benchmarks = [] + for b in BENCHMARKS: + if b.name in options.benchmarks: + if not b.check(): + print "can't run %s benchmark for some reason"%(b.name,) + else: + benchmarks.append(b) exes = get_executables(args) pythons = 'python2.5 python2.4 python2.3'.split() @@ -59,9 +65,10 @@ if __name__ == '__main__': from optparse import OptionParser parser = OptionParser() + default_benches = ','.join([b.name for b in BENCHMARKS if b.check()]) parser.add_option( '--benchmarks', dest='benchmarks', - default=','.join([b.name for b in BENCHMARKS]) + default=default_benches, ) parser.add_option( '--pickle', dest='picklefile', Modified: pypy/dist/pypy/translator/benchmark/benchmarks.py ============================================================================== --- pypy/dist/pypy/translator/benchmark/benchmarks.py (original) +++ pypy/dist/pypy/translator/benchmark/benchmarks.py Fri Mar 2 17:35:02 2007 @@ -20,11 +20,12 @@ return float(line.split()[len(pattern.split())]) class Benchmark(object): - def __init__(self, name, runner, asc_good, units): + def __init__(self, name, runner, asc_good, units, check=lambda:True): self.name = name self._run = runner self.asc_good = asc_good self.units = units + self.check = check def run(self, exe): try: return self._run(exe) @@ -62,9 +63,39 @@ raise BenchmarkFailed(status) return r +def run_docutils(executable='/usr/local/bin/python'): + docutilssvnpathfile = py.magic.autopath().dirpath().join("docutilssvnpath") + docutilssvnpath = docutilssvnpathfile.read().strip() + translatetxt = py.magic.autopath().dirpath().dirpath().dirpath().join('doc').join('translation.txt') + command = """import sys +sys.path[0:0] = ['%s', '%s/extras'] +from docutils.core import publish_cmdline +publish_cmdline(writer_name='html') +"""%(docutilssvnpath, docutilssvnpath) + T = time.time() + pid = os.fork() + if not pid: + davenull = os.open('/dev/null', os.O_RDWR) + os.dup2(davenull, 0) + os.dup2(davenull, 1) + os.dup2(davenull, 2) + status = os.spawnv(os.P_WAIT, executable, [executable, '-c', command, str(translatetxt)]) + os._exit(status) + else: + status = os.waitpid(pid, 0)[1] + r = time.time() - T + if status: + raise BenchmarkFailed(status) + return r + +def check_docutils(): + docutilssvnpathfile = py.magic.autopath().dirpath().join("docutilssvnpath") + return docutilssvnpathfile.check() + BENCHMARKS = [Benchmark('richards', run_richards, RICHARDS_ASCENDING_GOOD, 'ms'), Benchmark('pystone', run_pystone, PYSTONE_ASCENDING_GOOD, ''), Benchmark('translate', run_translate, RICHARDS_ASCENDING_GOOD, 'ms'), + Benchmark('docutils', run_docutils, RICHARDS_ASCENDING_GOOD, 'ms', check_docutils), ] BENCHMARKS_BY_NAME = {} From fijal at codespeak.net Fri Mar 2 17:44:06 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 2 Mar 2007 17:44:06 +0100 (CET) Subject: [pypy-svn] r39724 - in pypy/dist/pypy/translator/js/examples/console: . data test Message-ID: <20070302164406.1C7A5100B5@code0.codespeak.net> Author: fijal Date: Fri Mar 2 17:44:04 2007 New Revision: 39724 Added: pypy/dist/pypy/translator/js/examples/console/session.py pypy/dist/pypy/translator/js/examples/console/test/test_session.py Modified: pypy/dist/pypy/translator/js/examples/console/client.py pypy/dist/pypy/translator/js/examples/console/console.py pypy/dist/pypy/translator/js/examples/console/data/console.html pypy/dist/pypy/translator/js/examples/console/test/test_console.py Log: Add some improvements to console example 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 Mar 2 17:44:04 2007 @@ -20,20 +20,13 @@ def refresh_console(msg): inp_elem = dom.document.getElementById("inp") - inp_elem.disabled = False + #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) + exported_methods.refresh_empty(glob.sess_id, refresh_console) add_text(data) elif msg[0] == 'disconnect': dom.document.getElementById("error").innerHTML = "ERROR! disconnected" @@ -44,7 +37,7 @@ def empty_callback(msg): inp_elem = dom.document.getElementById("inp") - inp_elem.disabled = False + #inp_elem.disabled = False inp_elem.scrollIntoView() def keypressed(key): @@ -53,12 +46,11 @@ inp_elem = dom.document.getElementById("inp") cmd = inp_elem.value inp_elem.value = '' - inp_elem.disabled = True - add_text(glob.prompt + cmd + "\n") + add_text(cmd + "\n") #if not cmd: # exported_methods.refresh(glob.sess_id, cmd, empty_callback) #else: - exported_methods.refresh(glob.sess_id, cmd, refresh_console) + exported_methods.refresh(glob.sess_id, cmd + "\n", refresh_console) def console_onload(): createLoggingPane(True) 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 Fri Mar 2 17:44:04 2007 @@ -9,6 +9,7 @@ from pypy.translator.js.main import rpython2javascript from pypy.translator.js.lib.support import callback from pypy.translator.js import commproxy +from pypy.translator.js.examples.console.session import Interpreter commproxy.USE_MOCHIKIT = True @@ -19,35 +20,18 @@ import client return rpython2javascript(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 a 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 + ip = Interpreter("python") + self.sessions[ip.pid] = ip + return ip.pid def update_session(self, pid, to_write=None): - pipe = self.sessions[pid] - return interact(pipe, to_write) + ip = self.sessions[pid] + return ip.interact(to_write) # We hack here, cause in exposed methods we don't have global 'server' # state @@ -61,6 +45,7 @@ @callback(retval=[str]) def refresh(self, pid=0, to_write=""): + print "Refresh %s" % to_write try: return ["refresh", sessions.update_session(int(pid), to_write)] except KeyError: @@ -68,6 +53,7 @@ @callback(retval=[str]) def refresh_empty(self, pid=0): + print "Empty refresh" try: return ["refresh", sessions.update_session(int(pid), None)] except KeyError: Modified: pypy/dist/pypy/translator/js/examples/console/data/console.html ============================================================================== --- pypy/dist/pypy/translator/js/examples/console/data/console.html (original) +++ pypy/dist/pypy/translator/js/examples/console/data/console.html Fri Mar 2 17:44:04 2007 @@ -1,7 +1,7 @@ - + Console Added: pypy/dist/pypy/translator/js/examples/console/session.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/js/examples/console/session.py Fri Mar 2 17:44:04 2007 @@ -0,0 +1,81 @@ + +""" In this file we define all necessary stuff +build around subprocess to run python console in it +""" + +TIMEOUT = 10 + +""" The idea behind is that we create xmlhttprequest immediataly +and reply with new data (if available) or reply anyway +after TIMEOUT +""" + +import py +import subprocess +from Queue import Queue +from pypeers.greensock2 import autogreenlet, sleep, wait, meetingpoint +from pypeers.pipe.fd import FDInput + +def timeout_read(fd, timeout): + read = [] + giver, accepter = meetingpoint() + + def timeout_fun(): + sleep(timeout) + giver.give(None) + g_read.interrupt() + + def read_fun(): + giver.give(fd.recv(1024)) + g_timer.interrupt() + + g_timer = autogreenlet(timeout_fun) + g_read = autogreenlet(read_fun) + return accepter.accept() + +class Interpreter(object): + def __init__(self, python, timeout=TIMEOUT): + pipe = subprocess.Popen([python, "-u", "-i"], stdout=subprocess.PIPE, + stdin=subprocess.PIPE, stderr=subprocess.STDOUT, + close_fds=True, bufsize=0) + self.pipe = pipe + self.read_fd = FDInput(self.pipe.stdout.fileno()) + self.pid = pipe.pid + self.timeout = timeout + + def interact(self, to_write=None): + if to_write is not None: + self.pipe.stdin.write(to_write) + return timeout_read(self.read_fd, self.timeout) + + def close(self): + self.pipe.stdin.close() + # XXX: some sane way of doing wait here? (note that wait + # is blocking, which means it eats all our clean interface) + #self.pipe.wait() + +class InterpreterManager(object): + pass + +#class Sessions(object): +# def __init__(self): +# self.sessions = {} + +# def new_session(self, python="python"): +# 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) + + +#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 "" Modified: pypy/dist/pypy/translator/js/examples/console/test/test_console.py ============================================================================== --- pypy/dist/pypy/translator/js/examples/console/test/test_console.py (original) +++ pypy/dist/pypy/translator/js/examples/console/test/test_console.py Fri Mar 2 17:44:04 2007 @@ -4,6 +4,8 @@ def test_run_console(): """ Check if we can read anything """ + import py + py.test.skip("XXX") pipe = console.run_console("python") pipe.stdin.close() t = False Added: pypy/dist/pypy/translator/js/examples/console/test/test_session.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/js/examples/console/test/test_session.py Fri Mar 2 17:44:04 2007 @@ -0,0 +1,35 @@ + +""" Various tests around interpreter in a subprocess +""" + +from pypeers.greensock2 import autogreenlet, wait, sleep, ConnexionClosed +from pypeers.pipe.fd import FDInput +from pypy.translator.js.examples.console.session import Interpreter +import py + +def test_greensock_reader_timeouter(): + i = Interpreter("python", timeout=3) + while not i.interact().endswith(">>> "): + pass + assert i.interact() is None + assert i.interact("a\n") is not None + +def test_two_interpreters(): + i = Interpreter("python", timeout=3) + i2 = Interpreter("python", timeout=3) + while not i.interact().endswith(">>> "): + pass + while not i2.interact().endswith(">>> "): + pass + l = [] + + def f(): + l.append(i.interact("import time;time.sleep(1)\n")) + def g(): + l.append(i2.interact("a\n")) + + g_f = autogreenlet(f) + g_g = autogreenlet(g) + wait() + assert len(l) == 2 + assert l[1].startswith(">>") From guido at codespeak.net Fri Mar 2 17:49:39 2007 From: guido at codespeak.net (guido at codespeak.net) Date: Fri, 2 Mar 2007 17:49:39 +0100 (CET) Subject: [pypy-svn] r39725 - in pypy/dist/pypy/translator/js: examples jssrc lib modules Message-ID: <20070302164939.3D70610060@code0.codespeak.net> Author: guido Date: Fri Mar 2 17:49:37 2007 New Revision: 39725 Modified: pypy/dist/pypy/translator/js/examples/pythonconsole.py pypy/dist/pypy/translator/js/jssrc/misc.js pypy/dist/pypy/translator/js/lib/server.py pypy/dist/pypy/translator/js/modules/mochikit.py Log: (fijal, guido) Fixed python console on IE, in the process we switched to using MochiKit's Signal module for event handling, added HTTP headers to make sure IE doesn't cache JSON responses, and fixed some getitem accesses on strings (which are not supported by IE). 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 Fri Mar 2 17:49:37 2007 @@ -12,7 +12,8 @@ import sys, os, cStringIO from cgi import parse_qs -from pypy.translator.js.modules.dom import setTimeout, document +from pypy.translator.js.modules.dom import setTimeout, document, window +from pypy.translator.js.modules.mochikit import connect, disconnect from pypy.rpython.ootypesystem.bltregistry import MethodDesc, BasicExternal from pypy.translator.js import commproxy from pypy.rpython.extfunc import _callable @@ -38,7 +39,7 @@

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

-

+    
@@ -57,7 +58,13 @@ def add_text(text): data_elem = document.getElementById("data") - data_elem.appendChild(document.createTextNode(text)) + lines = text.split('\n') + lines.pop() + for line in lines: + pre = document.createElement('pre') + pre.style.margin = '0px' + pre.appendChild(document.createTextNode(line)) + data_elem.appendChild(pre) class Storage(object): def __init__(self): @@ -67,7 +74,7 @@ storage = Storage() def keypressed(key): - kc = key.keyCode + kc = key._event.keyCode if kc == ord("\r"): inp_elem = document.getElementById("inp") cmd = inp_elem.value @@ -88,7 +95,7 @@ storage.level = 0 def setup_page(): - document.onkeypress = keypressed + connect(document, 'onkeypress', keypressed) document.getElementById("inp").focus() class Server(HTTPServer, BasicExternal): @@ -177,6 +184,12 @@ self.send_response(200) self.send_header("Content-type", content_type) self.send_header("Content-length", len(data)) + self.send_header('Expires', 'Mon, 26 Jul 1997 05:00:00 GMT') + self.send_header('Last-Modified', + time.strftime("%a, %d %b %Y %H:%M:%S GMT")) + self.send_header('Cache-Control', 'no-cache, must-revalidate') + self.send_header('Cache-Control', 'post-check=0, pre-check=0') + self.send_header('Pragma', 'no-cache') self.end_headers() self.wfile.write(data) Modified: pypy/dist/pypy/translator/js/jssrc/misc.js ============================================================================== --- pypy/dist/pypy/translator/js/jssrc/misc.js (original) +++ pypy/dist/pypy/translator/js/jssrc/misc.js Fri Mar 2 17:49:37 2007 @@ -49,11 +49,11 @@ } function startswith(s1, s2) { - if (s1.lengths1.length) { + if (s2.length > s1.length) { return(false); } - for (i = s1.length-s2.length; i Author: cfbolz Date: Fri Mar 2 17:58:59 2007 New Revision: 39726 Modified: pypy/branch/rope-branch/pypy/objspace/std/ropeobject.py pypy/branch/rope-branch/pypy/objspace/std/test/test_ropeobject.py Log: fix a bug, thanks armin for spotting Modified: pypy/branch/rope-branch/pypy/objspace/std/ropeobject.py ============================================================================== --- pypy/branch/rope-branch/pypy/objspace/std/ropeobject.py (original) +++ pypy/branch/rope-branch/pypy/objspace/std/ropeobject.py Fri Mar 2 17:58:59 2007 @@ -857,7 +857,7 @@ except OverflowError: raise OperationError( space.w_OverflowError, - space.wrap("repeated string is too long: %d %d" % (input_len, mul))) + space.wrap("repeated string is too long: %d %d" % (length, mul))) return W_RopeObject(rope.multiply(node, mul)) def mul__Rope_ANY(space, w_str, w_times): Modified: pypy/branch/rope-branch/pypy/objspace/std/test/test_ropeobject.py ============================================================================== --- pypy/branch/rope-branch/pypy/objspace/std/test/test_ropeobject.py (original) +++ pypy/branch/rope-branch/pypy/objspace/std/test/test_ropeobject.py Fri Mar 2 17:58:59 2007 @@ -8,6 +8,10 @@ def setup_class(cls): cls.space = gettestobjspace(**{"objspace.std.withrope": True}) + def test_mul_overflow(self): + import sys + raises(OverflowError, '"abcdefg" * (sys.maxint // 2)') + class AppTestRopeUnicode(object): def setup_class(cls): From xoraxax at codespeak.net Fri Mar 2 18:01:43 2007 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Fri, 2 Mar 2007 18:01:43 +0100 (CET) Subject: [pypy-svn] r39728 - in pypy/dist/pypy/objspace/std: . test Message-ID: <20070302170143.A583E100B5@code0.codespeak.net> Author: xoraxax Date: Fri Mar 2 18:01:40 2007 New Revision: 39728 Modified: pypy/dist/pypy/objspace/std/listmultiobject.py pypy/dist/pypy/objspace/std/test/test_listmultiobject.py Log: (xorAxAx, a. sigfridsson) Implemented the ChunkListImplementation that is using fixed sized lists internally as chunks. Modified: pypy/dist/pypy/objspace/std/listmultiobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/listmultiobject.py (original) +++ pypy/dist/pypy/objspace/std/listmultiobject.py Fri Mar 2 18:01:40 2007 @@ -184,6 +184,8 @@ impl = SmartResizableListImplementation(space) impl.extend(RListImplementation(space, list_w)) return impl + if space.config.objspace.std.withchunklist: + return ChunkedListImplementation(space, list_w) if space.config.objspace.std.withfastslice: return SliceTrackingListImplementation(space, list_w) else: @@ -256,6 +258,143 @@ def __repr__(self): return "RListImplementation(%s)" % (self.list_w, ) + +CHUNK_SIZE_BITS = 4 +CHUNK_SIZE = 2**CHUNK_SIZE_BITS + +class ChunkedListImplementation(ListImplementation): + """ A list of chunks that allow extend operations to be cheaper + because only a smaller list has to be resized. + Invariant: Every element of self.chunks is a list of wrapped objects. + Each of those lists has exactly CHUNK_SIZE elements. + """ + + def __init__(self, space, list_w=None, chunks=None, length=-1): + ListImplementation.__init__(self, space) + if list_w is not None: + self.chunks = [] + self._length = 0 + self._grow(len(list_w)) + i = 0 + for w_elem in list_w: + self.setitem(i, w_elem) + i += 1 + else: + self.chunks = chunks + self._length = length + + def _grow(self, how_much=1): + free_slots = -self._length % CHUNK_SIZE + if free_slots < how_much: + to_allocate = how_much - free_slots + for _ in range(0, (to_allocate / CHUNK_SIZE) + 1): + self.chunks.append([None] * CHUNK_SIZE) + self._length += how_much + + def length(self): + return self._length + + def getitem(self, i): + return self.chunks[i >> CHUNK_SIZE_BITS][i & (CHUNK_SIZE - 1)] + + def _get_chunks_slice(self, start, stop): + assert start >= 0 and stop >= 0 + current_chunk = [None] * CHUNK_SIZE + chunks = [current_chunk] + element_index = 0 + for i in range(start, stop): + if element_index == CHUNK_SIZE: + current_chunk = [None] * CHUNK_SIZE + chunks.append(current_chunk) + element_index = 0 + current_chunk[element_index] = self.getitem(i) + element_index += 1 + return chunks + + def getitem_slice(self, start, stop): + assert start >= 0 + assert stop >= 0 + delta = stop - start + if start % CHUNK_SIZE == 0 and stop % CHUNK_SIZE == 0: + first_chunk = start >> CHUNK_SIZE_BITS + last_chunk = stop >> CHUNK_SIZE_BITS + chunks = [chunk[:] for chunk in self.chunks[first_chunk:last_chunk]] + return ChunkedListImplementation(self.space, chunks=chunks, length=delta) + + return ChunkedListImplementation(self.space, chunks=self._get_chunks_slice(start, stop), + length=delta) + + + def delitem(self, i): + length = self._length + if length == 1: + return self.space.fromcache(State).empty_impl + + assert i >= 0 + for j in range(i + 1, length): + self.setitem(j - 1, self.getitem(j)) + + self._length -= 1 + return self + + def delitem_slice(self, start, stop): + length = self._length + + if length == stop and start == 0: + return self.space.fromcache(State).empty_impl + + assert start >= 0 + assert stop >= 0 + + delta = stop - start + for j in range(start + delta, length): + self.setitem(j - delta, self.getitem(j)) + first_unneeded_chunk = ((length - delta) >> CHUNK_SIZE) + 1 + assert first_unneeded_chunk >= 0 + del self.chunks[first_unneeded_chunk:] + + self._length -= delta + return self + + def setitem(self, i, w_item): + assert i >= 0 + chunk = self.chunks[i >> CHUNK_SIZE_BITS] + chunk[i & (CHUNK_SIZE - 1)] = w_item + + return self + + def insert(self, i, w_item): + assert i >= 0 + + self._grow() + for j in range(i, self._length): + self.setitem(j + 1, self.getitem(j)) + self.setitem(i, w_item) + + return self + + def append(self, w_item): + self._grow() + self.setitem(self._length - 1, w_item) + + return self + + def extend(self, other): + other_length = other.length() + old_length = self._length + self._grow(other_length) + for idx in range(0, other_length): + self.setitem(old_length + idx, other.getitem(idx)) + + return self + + def get_list_w(self): + return [self.getitem(idx) for idx in range(0, self._length)] + + def __repr__(self): + return "ChunkedListImplementation(%s)" % (self.get_list_w(), ) + + class EmptyListImplementation(ListImplementation): def make_list_with_one_item(self, w_item): space = self.space @@ -678,7 +817,9 @@ impl = SmartResizableListImplementation(space) impl.extend(RListImplementation(space, list_w)) return impl - if space.config.objspace.std.withfastslice: + if space.config.objspace.std.withchunklist: + return ChunkedListImplementation(space, list_w) + elif space.config.objspace.std.withfastslice: impl = SliceTrackingListImplementation(space, list_w) else: w_type = space.type(list_w[0]) @@ -884,7 +1025,7 @@ start, stop, step, slicelength = w_slice.indices4( space, w_list.implementation.length()) - if slicelength==0: + if slicelength == 0: return if step < 0: 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 Fri Mar 2 18:01:40 2007 @@ -129,3 +129,8 @@ for i in range(5): ls.insert(0, i) assert len(ls) == 12 + +class AppTest_ChunkListObject(test_listobject.AppTestW_ListObject): + def setup_class(cls): + cls.space = gettestobjspace(**{"objspace.std.withchunklist": True}) + From fijal at codespeak.net Fri Mar 2 18:06:54 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 2 Mar 2007 18:06:54 +0100 (CET) Subject: [pypy-svn] r39730 - in pypy/dist/pypy/lib/distributed: . test Message-ID: <20070302170654.68197100AB@code0.codespeak.net> Author: fijal Date: Fri Mar 2 18:06:52 2007 New Revision: 39730 Modified: pypy/dist/pypy/lib/distributed/objkeeper.py pypy/dist/pypy/lib/distributed/protocol.py pypy/dist/pypy/lib/distributed/test/test_distributed.py Log: Make classmethods work remotely Modified: pypy/dist/pypy/lib/distributed/objkeeper.py ============================================================================== --- pypy/dist/pypy/lib/distributed/objkeeper.py (original) +++ pypy/dist/pypy/lib/distributed/objkeeper.py Fri Mar 2 18:06:52 2007 @@ -11,18 +11,18 @@ _, _, tb = sys.exc_info() GetSetDescriptor = type(type(tb).tb_frame) -class noninstantiabletype(object): - def __new__(cls, *args, **kwargs): - raise NotImplementedError("Cannot instantiate remote type") +class RemoteBase(object): + pass class ObjKeeper(object): def __init__(self, exported_names = {}): self.exported_objects = [] # list of object that we've exported outside self.exported_names = exported_names # dictionary of visible objects - self.exported_types = {} # list of exported types + self.exported_types = {} # dict of exported types self.remote_types = {} self.remote_objects = {} self.exported_types_id = 0 # unique id of exported types + self.exported_types_reverse = {} # reverse dict of exported types def register_object(self, obj): # XXX: At some point it makes sense not to export them again and again... @@ -30,7 +30,7 @@ return len(self.exported_objects) - 1 def ignore(self, key, value): - if key in ('__dict__', '__weakref__', '__class__', '__new__'): + if key in ('__dict__', '__weakref__', '__class__'): return True if isinstance(value, GetSetDescriptor): return True @@ -42,6 +42,7 @@ except KeyError: print "Registering type %s as %s" % (tp, self.exported_types_id) self.exported_types[tp] = self.exported_types_id + self.exported_types_reverse[self.exported_types_id] = tp tp_id = self.exported_types_id self.exported_types_id += 1 @@ -56,15 +57,21 @@ def fake_remote_type(self, protocol, type_id, _name, _dict): print "Faking type %s as %s" % (_name, type_id) # create and register new type - d = dict([(key, None) for key in _dict if key != '__new__']) + d = dict([(key, None) for key in _dict]) + # some stuff needs to go first... if '__doc__' in _dict: d['__doc__'] = protocol.unwrap(_dict['__doc__']) - tp = type(_name, (noninstantiabletype,), d) + tp = type(_name, (RemoteBase,), d) + tp.__metaremote__ = type_id # Make sure we cannot instantiate the remote type self.remote_types[type_id] = tp for key, value in _dict.items(): if key != '__doc__': setattr(tp, key, protocol.unwrap(value)) + #elif key == '__new__': + # import pdb + # pdb.set_trace() + # tp.new = 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 Fri Mar 2 18:06:52 2007 @@ -41,7 +41,7 @@ except ImportError: raise ImportError("Cannot work without transparent proxy functionality") -from distributed.objkeeper import ObjKeeper +from distributed.objkeeper import ObjKeeper, RemoteBase import sys # XXX We do not make any garbage collection. We'll need it at some point @@ -91,6 +91,7 @@ 'tp' : None, 'fr' : types.FrameType, 'tb' : types.TracebackType, + 'reg' : RemoteBase } type_letters = dict([(value, key) for key, value in letter_types.items()]) assert len(type_letters) == len(letter_types) @@ -131,6 +132,10 @@ id = self.keeper.register_object(obj) return (self.type_letters[tp], id) elif tp is type: + if isinstance(obj, RemoteBase): + import pdb + pdb.set_trace() + return "reg", obj.__metaremote__ try: return self.type_letters[tp], self.type_letters[obj] except KeyError: @@ -156,6 +161,8 @@ tp = self.letter_types[tp_letter] if tp is None: return self.keeper.get_object(obj_data) + elif tp is RemoteBase: + return self.keeper.exported_types_reverse[obj_data] elif tp in self.immutable_primitives: return obj_data # this is the object elif tp is tuple: @@ -179,6 +186,9 @@ name = self.unwrap(w_name) self_ = self.unwrap(w_self) if self_: + if not tp: + setattr(self_, name, classmethod(self.unwrap(w_func))) + return getattr(self_, name) return getattr(tp, name).__get__(self_, tp) func = self.unwrap(w_func) setattr(tp, name, func) @@ -368,4 +378,13 @@ 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 send_trace(data): + print "Sending %s" % (data,) + out.send(data) + + def receive_trace(): + data = inp.receive() + print "Received %s" % (data,) + return data + return RemoteProtocol(send_trace, receive_trace) 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 Fri Mar 2 18:06:52 2007 @@ -198,11 +198,25 @@ else: raise AssertionError("Did not raise") + def test_remote_classmethod(self): + class A: + z = 8 + + @classmethod + def x(cls): + return cls.z + + a = A() + protocol = self.test_env({'a':a}) + xa = protocol.get_remote("a") + res = xa.x() + assert res == 8 + def test_instantiate_remote_type(self): - #skip("Land of infinite recursion") + skip("Doesn't work yet") class C: pass protocol = self.test_env({'C':C}) xC = protocol.get_remote('C') - raises(NotImplementedError, "xC()") + xC() From xoraxax at codespeak.net Fri Mar 2 18:07:18 2007 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Fri, 2 Mar 2007 18:07:18 +0100 (CET) Subject: [pypy-svn] r39731 - pypy/dist/pypy/config Message-ID: <20070302170718.976A410113@code0.codespeak.net> Author: xoraxax Date: Fri Mar 2 18:07:16 2007 New Revision: 39731 Modified: pypy/dist/pypy/config/pypyoption.py Log: Oops, there is a new option as well of course. Modified: pypy/dist/pypy/config/pypyoption.py ============================================================================== --- pypy/dist/pypy/config/pypyoption.py (original) +++ pypy/dist/pypy/config/pypyoption.py Fri Mar 2 18:07:16 2007 @@ -182,6 +182,10 @@ "make list slicing lazy", default=False, requires=[("objspace.std.withmultilist", True)]), + BoolOption("withchunklist", + "introducing a new nesting level to slow down list operations", + default=False, + requires=[("objspace.std.withmultilist", True)]), BoolOption("withsmartresizablelist", "only overallocate O(sqrt(n)) elements for lists", default=False, From fijal at codespeak.net Fri Mar 2 18:09:17 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 2 Mar 2007 18:09:17 +0100 (CET) Subject: [pypy-svn] r39732 - pypy/dist/pypy/lib/pyontology/test Message-ID: <20070302170917.1EDF0100B5@code0.codespeak.net> Author: fijal Date: Fri Mar 2 18:09:15 2007 New Revision: 39732 Modified: pypy/dist/pypy/lib/pyontology/test/test_ontology.py Log: This is not needed 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 Fri Mar 2 18:09:15 2007 @@ -1,5 +1,5 @@ # tests for the Ontology class -import autopath + import py from pypy.conftest import gettestobjspace From hpk at codespeak.net Fri Mar 2 18:20:01 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Fri, 2 Mar 2007 18:20:01 +0100 (CET) Subject: [pypy-svn] r39733 - pypy/dist/pypy/tool/bench Message-ID: <20070302172001.5E5C21010C@code0.codespeak.net> Author: hpk Date: Fri Mar 2 18:19:59 2007 New Revision: 39733 Added: pypy/dist/pypy/tool/bench/ pypy/dist/pypy/tool/bench/__init__.py (contents, props changed) pypy/dist/pypy/tool/bench/benchmark_report.css - copied unchanged from r39700, user/hpk/bench/benchmark_report.css pypy/dist/pypy/tool/bench/benchmark_report.py - copied unchanged from r39713, user/hpk/bench/benchmark_report.py pypy/dist/pypy/tool/bench/benchmark_test_data2.txt - copied unchanged from r39700, user/hpk/bench/benchmark_test_data2.txt pypy/dist/pypy/tool/bench/test_benchmark_report.py - copied unchanged from r39703, user/hpk/bench/test_benchmark_report.py Log: adding a set of benchmark-display resulted files, to be refactored (somewhat originating from code that we/merlinux provided to bzr people for displaying their benchmark result) Added: pypy/dist/pypy/tool/bench/__init__.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/tool/bench/__init__.py Fri Mar 2 18:19:59 2007 @@ -0,0 +1 @@ + From hpk at codespeak.net Fri Mar 2 18:24:03 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Fri, 2 Mar 2007 18:24:03 +0100 (CET) Subject: [pypy-svn] r39734 - pypy/dist/pypy/tool/bench Message-ID: <20070302172403.D309810060@code0.codespeak.net> Author: hpk Date: Fri Mar 2 18:24:01 2007 New Revision: 39734 Added: pypy/dist/pypy/tool/bench/htmlreport.py - copied, changed from r39733, pypy/dist/pypy/tool/bench/benchmark_report.py pypy/dist/pypy/tool/bench/result.py - copied, changed from r39733, pypy/dist/pypy/tool/bench/benchmark_report.py Removed: pypy/dist/pypy/tool/bench/benchmark_report.py Log: renaming, separating things a bit into two files From hpk at codespeak.net Fri Mar 2 18:24:45 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Fri, 2 Mar 2007 18:24:45 +0100 (CET) Subject: [pypy-svn] r39735 - pypy/dist/pypy/tool/bench Message-ID: <20070302172445.DB14C10069@code0.codespeak.net> Author: hpk Date: Fri Mar 2 18:24:42 2007 New Revision: 39735 Modified: pypy/dist/pypy/tool/bench/test_benchmark_report.py Log: fixing import Modified: pypy/dist/pypy/tool/bench/test_benchmark_report.py ============================================================================== --- pypy/dist/pypy/tool/bench/test_benchmark_report.py (original) +++ pypy/dist/pypy/tool/bench/test_benchmark_report.py Fri Mar 2 18:24:42 2007 @@ -1,6 +1,6 @@ import os import py -from benchmark_report import ( +from htmlreport import ( PerfResult, PerfTable, PerfResultCollection, PerfResultDelta, Page ) From hpk at codespeak.net Fri Mar 2 18:27:38 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Fri, 2 Mar 2007 18:27:38 +0100 (CET) Subject: [pypy-svn] r39736 - pypy/dist/pypy/tool/bench Message-ID: <20070302172738.DE77A10120@code0.codespeak.net> Author: hpk Date: Fri Mar 2 18:27:37 2007 New Revision: 39736 Modified: pypy/dist/pypy/tool/bench/htmlreport.py pypy/dist/pypy/tool/bench/result.py Log: moving PerfTable to the "model" instead of the "view" htmlreport.py Modified: pypy/dist/pypy/tool/bench/htmlreport.py ============================================================================== --- pypy/dist/pypy/tool/bench/htmlreport.py (original) +++ pypy/dist/pypy/tool/bench/htmlreport.py Fri Mar 2 18:27:37 2007 @@ -11,140 +11,10 @@ import py pyhtml = py.xml.html -from result import PerfResult, PerfResultDelta, PerfResultCollection - -class PerfTable: - """parses performance history data files and yields PerfResult objects - through the get_results method. - - if an branch is given, it is used to get more information for each - revision we have data from. - """ - branch = None - - def __init__(self, iterlines = []): - """:param iterline: lines of performance history data, - e.g., history_file.realdlines() - """ - self._revision_cache = {} - self.results = list(self.parse(iterlines)) - - def parse(self, iterlines): - """parse lines like - --date 1152625530.0 hacker at canonical.com-20..6dc - 1906ms bzrlib....one_add_kernel_like_tree - """ - date = None - revision_id = None - for line in iterlines: - line = line.strip() - if not line: - continue - if line.startswith('--date'): - _, date, revision_id = line.split(None, 2) - date = float(date) - continue - perfresult = PerfResult(date=date, revision_id=revision_id) - elapsed_time, test_id = line.split(None, 1) - perfresult.elapsed_time = int(elapsed_time[:-2]) - perfresult.test_id = test_id.strip() - yield self.annotate(perfresult) - - def add_lines(self, lines): - """add lines of performance history data """ - - self.results += list(self.parse(lines)) - - def get_time_for_revision_id(self, revision_id): - """return the data of the revision or 0""" - if revision_id in self._revision_cache: - return self._revision_cache[revision_id][1].timestamp - return 0 - - def get_time(self, revision_id): - """return revision date or the date of recording the - performance history data""" - - t = self.get_time_for_revision_id(revision_id) - if t: - return t - result = list(self.get_results(revision_ids=[revision_id], - sorted_by_rev_date=False))[0] - return result.date - - count = py.std.itertools.count() - def annotate(self, result): - """Try to put extra information for each revision on the - PerfResult objects. These informations are retrieved from a - branch object. - """ - #if self.branch is None: - # return result - class Branch: - revision_id = result.revision_id - nick = "fake" - - self.branch = Branch() - result.revision = self.count.next() - result.revision_date = "01/01/2007" - result.message = "fake log message" - result.timestamp = 1231231.0 - return result - - - revision_id = result.revision_id - if revision_id in self._revision_cache: - revision, rev, nick = self._revision_cache[revision_id] - else: - revision = self.branch.revision_id_to_revno(revision_id) - rev = self.branch.repository.get_revision(revision_id) - nick = self.branch._get_nick() - self._revision_cache[revision_id] = (revision, rev, nick) - - result.revision = revision - result.committer = rev.committer - result.message = rev.message - result.timstamp = rev.timestamp - # XXX no format_date, but probably this whole function - # goes away soon - result.revision_date = format_date(rev.timestamp, rev.timezone or 0) - result.nick = nick - return result - - def get_results(self, test_ids=None, revision_ids=None, - sorted_by_rev_date=True): - # XXX we might want to build indexes for speed - for result in self.results: - if test_ids and result.test_id not in test_ids: - continue - if revision_ids and result.revision_id not in revision_ids: - continue - yield result - - def list_values_of(self, attr): - """return a list of unique values of the specified attribute - of PerfResult objects""" - return dict.fromkeys((getattr(r, attr) for r in self.results)).keys() - - def get_testid2collections(self): - """return a mapping of test_id to list of PerfResultCollection - sorted by revision""" - - test_ids = self.list_values_of('test_id') - - testid2resultcollections = {} - for test_id in test_ids: - revnos = {} - for result in self.get_results(test_ids=[test_id]): - revnos.setdefault(result.revision, []).append(result) - for revno, results in revnos.iteritems(): - collection = PerfResultCollection(results) - l = testid2resultcollections.setdefault(test_id, []) - l.append(collection) - # sort collection list by revision number - for collections in testid2resultcollections.itervalues(): - collections.sort(lambda x,y: cmp(x.revision, y.revision)) - return testid2resultcollections +from result import ( + PerfResult, PerfResultDelta, PerfResultCollection, + PerfTable +) class Page: Modified: pypy/dist/pypy/tool/bench/result.py ============================================================================== --- pypy/dist/pypy/tool/bench/result.py (original) +++ pypy/dist/pypy/tool/bench/result.py Fri Mar 2 18:27:37 2007 @@ -1,4 +1,6 @@ +import py + class PerfResult: """Holds information about a benchmark run of a particular test run.""" @@ -102,3 +104,135 @@ else: self.percent = float(m2-m1) / float(m1) +class PerfTable: + """parses performance history data files and yields PerfResult objects + through the get_results method. + + if an branch is given, it is used to get more information for each + revision we have data from. + """ + branch = None + + def __init__(self, iterlines = []): + """:param iterline: lines of performance history data, + e.g., history_file.realdlines() + """ + self._revision_cache = {} + self.results = list(self.parse(iterlines)) + + def parse(self, iterlines): + """parse lines like + --date 1152625530.0 hacker at canonical.com-20..6dc + 1906ms bzrlib....one_add_kernel_like_tree + """ + date = None + revision_id = None + for line in iterlines: + line = line.strip() + if not line: + continue + if line.startswith('--date'): + _, date, revision_id = line.split(None, 2) + date = float(date) + continue + perfresult = PerfResult(date=date, revision_id=revision_id) + elapsed_time, test_id = line.split(None, 1) + perfresult.elapsed_time = int(elapsed_time[:-2]) + perfresult.test_id = test_id.strip() + yield self.annotate(perfresult) + + def add_lines(self, lines): + """add lines of performance history data """ + + self.results += list(self.parse(lines)) + + def get_time_for_revision_id(self, revision_id): + """return the data of the revision or 0""" + if revision_id in self._revision_cache: + return self._revision_cache[revision_id][1].timestamp + return 0 + + def get_time(self, revision_id): + """return revision date or the date of recording the + performance history data""" + + t = self.get_time_for_revision_id(revision_id) + if t: + return t + result = list(self.get_results(revision_ids=[revision_id], + sorted_by_rev_date=False))[0] + return result.date + + count = py.std.itertools.count() + def annotate(self, result): + """Try to put extra information for each revision on the + PerfResult objects. These informations are retrieved from a + branch object. + """ + #if self.branch is None: + # return result + class Branch: + revision_id = result.revision_id + nick = "fake" + + self.branch = Branch() + result.revision = self.count.next() + result.revision_date = "01/01/2007" + result.message = "fake log message" + result.timestamp = 1231231.0 + return result + + + revision_id = result.revision_id + if revision_id in self._revision_cache: + revision, rev, nick = self._revision_cache[revision_id] + else: + revision = self.branch.revision_id_to_revno(revision_id) + rev = self.branch.repository.get_revision(revision_id) + nick = self.branch._get_nick() + self._revision_cache[revision_id] = (revision, rev, nick) + + result.revision = revision + result.committer = rev.committer + result.message = rev.message + result.timstamp = rev.timestamp + # XXX no format_date, but probably this whole function + # goes away soon + result.revision_date = format_date(rev.timestamp, rev.timezone or 0) + result.nick = nick + return result + + def get_results(self, test_ids=None, revision_ids=None, + sorted_by_rev_date=True): + # XXX we might want to build indexes for speed + for result in self.results: + if test_ids and result.test_id not in test_ids: + continue + if revision_ids and result.revision_id not in revision_ids: + continue + yield result + + def list_values_of(self, attr): + """return a list of unique values of the specified attribute + of PerfResult objects""" + return dict.fromkeys((getattr(r, attr) for r in self.results)).keys() + + def get_testid2collections(self): + """return a mapping of test_id to list of PerfResultCollection + sorted by revision""" + + test_ids = self.list_values_of('test_id') + + testid2resultcollections = {} + for test_id in test_ids: + revnos = {} + for result in self.get_results(test_ids=[test_id]): + revnos.setdefault(result.revision, []).append(result) + for revno, results in revnos.iteritems(): + collection = PerfResultCollection(results) + l = testid2resultcollections.setdefault(test_id, []) + l.append(collection) + # sort collection list by revision number + for collections in testid2resultcollections.itervalues(): + collections.sort(lambda x,y: cmp(x.revision, y.revision)) + return testid2resultcollections From fijal at codespeak.net Fri Mar 2 18:30:40 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 2 Mar 2007 18:30:40 +0100 (CET) Subject: [pypy-svn] r39737 - in pypy/dist/pypy/lib/distributed: . test Message-ID: <20070302173040.D691610120@code0.codespeak.net> Author: fijal Date: Fri Mar 2 18:30:38 2007 New Revision: 39737 Modified: pypy/dist/pypy/lib/distributed/objkeeper.py pypy/dist/pypy/lib/distributed/protocol.py pypy/dist/pypy/lib/distributed/test/test_distributed.py Log: Remote type instantiation works! Modified: pypy/dist/pypy/lib/distributed/objkeeper.py ============================================================================== --- pypy/dist/pypy/lib/distributed/objkeeper.py (original) +++ pypy/dist/pypy/lib/distributed/objkeeper.py Fri Mar 2 18:30:38 2007 @@ -14,12 +14,15 @@ class RemoteBase(object): pass +from types import FunctionType + class ObjKeeper(object): def __init__(self, exported_names = {}): self.exported_objects = [] # list of object that we've exported outside self.exported_names = exported_names # dictionary of visible objects self.exported_types = {} # dict of exported types self.remote_types = {} + self.reverse_remote_types = {} self.remote_objects = {} self.exported_types_id = 0 # unique id of exported types self.exported_types_reverse = {} # reverse dict of exported types @@ -62,12 +65,16 @@ if '__doc__' in _dict: d['__doc__'] = protocol.unwrap(_dict['__doc__']) tp = type(_name, (RemoteBase,), d) - tp.__metaremote__ = type_id # Make sure we cannot instantiate the remote type self.remote_types[type_id] = tp + self.reverse_remote_types[tp] = type_id for key, value in _dict.items(): if key != '__doc__': - setattr(tp, key, protocol.unwrap(value)) + v = protocol.unwrap(value) + if isinstance(v, FunctionType): + setattr(tp, key, staticmethod(v)) + else: + setattr(tp, key, v) #elif key == '__new__': # import pdb # pdb.set_trace() Modified: pypy/dist/pypy/lib/distributed/protocol.py ============================================================================== --- pypy/dist/pypy/lib/distributed/protocol.py (original) +++ pypy/dist/pypy/lib/distributed/protocol.py Fri Mar 2 18:30:38 2007 @@ -132,10 +132,8 @@ id = self.keeper.register_object(obj) return (self.type_letters[tp], id) elif tp is type: - if isinstance(obj, RemoteBase): - import pdb - pdb.set_trace() - return "reg", obj.__metaremote__ + if issubclass(obj, RemoteBase): + return "reg", self.keeper.reverse_remote_types[obj] try: return self.type_letters[tp], self.type_letters[obj] except KeyError: @@ -379,12 +377,12 @@ remote_protocol = RemoteProtocol(inp.send, out.receive, exported_names) t = tasklet(remote_loop)(remote_protocol) - def send_trace(data): - print "Sending %s" % (data,) - out.send(data) + #def send_trace(data): + # print "Sending %s" % (data,) + # out.send(data) - def receive_trace(): - data = inp.receive() - print "Received %s" % (data,) - return data - return RemoteProtocol(send_trace, receive_trace) + #def receive_trace(): + # data = inp.receive() + # print "Received %s" % (data,) + # return data + return RemoteProtocol(out.send, inp.receive) 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 Fri Mar 2 18:30:38 2007 @@ -213,10 +213,16 @@ assert res == 8 def test_instantiate_remote_type(self): - skip("Doesn't work yet") + #skip("Doesn't work yet") class C: - pass + def __init__(self, y): + self.y = y + + def x(self): + return self.y protocol = self.test_env({'C':C}) xC = protocol.get_remote('C') - xC() + res = xC(3).x() + assert res == 3 + From guido at codespeak.net Fri Mar 2 18:31:52 2007 From: guido at codespeak.net (guido at codespeak.net) Date: Fri, 2 Mar 2007 18:31:52 +0100 (CET) Subject: [pypy-svn] r39738 - pypy/dist/pypy/translator/benchmark Message-ID: <20070302173152.D7E2810120@code0.codespeak.net> Author: guido Date: Fri Mar 2 18:31:50 2007 New Revision: 39738 Modified: pypy/dist/pypy/translator/benchmark/benchmarks.py Log: Added function to run some Templess (http://templess.johnnydebris.net) code for benchmarking. Modified: pypy/dist/pypy/translator/benchmark/benchmarks.py ============================================================================== --- pypy/dist/pypy/translator/benchmark/benchmarks.py (original) +++ pypy/dist/pypy/translator/benchmark/benchmarks.py Fri Mar 2 18:31:50 2007 @@ -92,10 +92,37 @@ docutilssvnpathfile = py.magic.autopath().dirpath().join("docutilssvnpath") return docutilssvnpathfile.check() +def run_templess(executable='/usr/local/bin/python'): + """ run some script in the templess package + + templess is some simple templating language, to check out use + 'svn co http://johnnydebris.net/templess/trunk templess' + """ + here = py.magic.autopath().dirpath() + pypath = py.__package__.getpath().dirpath() + templessdir = here.join('templess') + testscript = templessdir.join('test/oneshot.py') + command = 'PYTHONPATH="%s:%s" "%s" "%s" 100' % (here, pypath, + executable, testscript) + txt = run_cmd(command) + try: + result = float([line for line in txt.split('\n') if line.strip()][-1]) + except ValueError: + raise IOError(txt) + return result + +def check_templess(): + templessdir = py.magic.autopath().dirpath().join('templess') + return templessdir.check() + + BENCHMARKS = [Benchmark('richards', run_richards, RICHARDS_ASCENDING_GOOD, 'ms'), Benchmark('pystone', run_pystone, PYSTONE_ASCENDING_GOOD, ''), Benchmark('translate', run_translate, RICHARDS_ASCENDING_GOOD, 'ms'), - Benchmark('docutils', run_docutils, RICHARDS_ASCENDING_GOOD, 'ms', check_docutils), + Benchmark('docutils', run_docutils, RICHARDS_ASCENDING_GOOD, + 'ms', check_docutils), + Benchmark('templess', run_templess, RICHARDS_ASCENDING_GOOD, + 'ms', check_templess), ] BENCHMARKS_BY_NAME = {} From mwh at codespeak.net Fri Mar 2 18:37:18 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 2 Mar 2007 18:37:18 +0100 (CET) Subject: [pypy-svn] r39739 - pypy/dist/pypy/translator/benchmark Message-ID: <20070302173718.3AB6C10110@code0.codespeak.net> Author: mwh Date: Fri Mar 2 18:37:16 2007 New Revision: 39739 Modified: pypy/dist/pypy/translator/benchmark/benchmarks.py Log: new way of failing Modified: pypy/dist/pypy/translator/benchmark/benchmarks.py ============================================================================== --- pypy/dist/pypy/translator/benchmark/benchmarks.py (original) +++ pypy/dist/pypy/translator/benchmark/benchmarks.py Fri Mar 2 18:37:16 2007 @@ -38,7 +38,7 @@ r = pipe.read() status = pipe.close() if status: - print "warning: %r had exit status %s"%(cmd, status) + raise BenchmarkFailed(status) return r def run_pystone(executable='/usr/local/bin/python', n=''): From mwh at codespeak.net Fri Mar 2 18:39:25 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 2 Mar 2007 18:39:25 +0100 (CET) Subject: [pypy-svn] r39740 - pypy/dist/pypy/translator/benchmark Message-ID: <20070302173925.10CCF100C9@code0.codespeak.net> Author: mwh Date: Fri Mar 2 18:39:23 2007 New Revision: 39740 Modified: pypy/dist/pypy/translator/benchmark/benchmarks.py Log: those aren't milliseconds, are they? Modified: pypy/dist/pypy/translator/benchmark/benchmarks.py ============================================================================== --- pypy/dist/pypy/translator/benchmark/benchmarks.py (original) +++ pypy/dist/pypy/translator/benchmark/benchmarks.py Fri Mar 2 18:39:23 2007 @@ -120,9 +120,9 @@ Benchmark('pystone', run_pystone, PYSTONE_ASCENDING_GOOD, ''), Benchmark('translate', run_translate, RICHARDS_ASCENDING_GOOD, 'ms'), Benchmark('docutils', run_docutils, RICHARDS_ASCENDING_GOOD, - 'ms', check_docutils), + 's', check_docutils), Benchmark('templess', run_templess, RICHARDS_ASCENDING_GOOD, - 'ms', check_templess), + 's', check_templess), ] BENCHMARKS_BY_NAME = {} From arigo at codespeak.net Fri Mar 2 18:45:01 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 2 Mar 2007 18:45:01 +0100 (CET) Subject: [pypy-svn] r39741 - in pypy/branch/rope-branch/pypy: module/marshal/test objspace/std Message-ID: <20070302174501.5C05F10120@code0.codespeak.net> Author: arigo Date: Fri Mar 2 18:44:59 2007 New Revision: 39741 Modified: pypy/branch/rope-branch/pypy/module/marshal/test/test_marshal.py pypy/branch/rope-branch/pypy/objspace/std/marshal_impl.py Log: (cfbolz, arigo) More precise marshal/unmarshal tests - check for the exact type of the final object. Fix the corresponding marshalling bug for Rope. Modified: pypy/branch/rope-branch/pypy/module/marshal/test/test_marshal.py ============================================================================== --- pypy/branch/rope-branch/pypy/module/marshal/test/test_marshal.py (original) +++ pypy/branch/rope-branch/pypy/module/marshal/test/test_marshal.py Fri Mar 2 18:44:59 2007 @@ -12,12 +12,12 @@ print "case: %-30s func=None" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) - assert x == case + assert x == case and type(x) is type(case) f = StringIO.StringIO() marshal.dump(case, f) f.seek(0) x = marshal.load(f) - assert x == case + assert x == case and type(x) is type(case) def test_False(self): import sys @@ -31,12 +31,12 @@ print "case: %-30s func=False" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) - assert x == case + assert x == case and type(x) is type(case) f = StringIO.StringIO() marshal.dump(case, f) f.seek(0) x = marshal.load(f) - assert x == case + assert x == case and type(x) is type(case) def test_True(self): import sys @@ -50,12 +50,12 @@ print "case: %-30s func=True" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) - assert x == case + assert x == case and type(x) is type(case) f = StringIO.StringIO() marshal.dump(case, f) f.seek(0) x = marshal.load(f) - assert x == case + assert x == case and type(x) is type(case) def test_StopIteration(self): import sys @@ -69,12 +69,12 @@ print "case: %-30s func=StopIteration" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) - assert x == case + assert x == case and type(x) is type(case) f = StringIO.StringIO() marshal.dump(case, f) f.seek(0) x = marshal.load(f) - assert x == case + assert x == case and type(x) is type(case) def test_Ellipsis(self): import sys @@ -88,12 +88,12 @@ print "case: %-30s func=Ellipsis" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) - assert x == case + assert x == case and type(x) is type(case) f = StringIO.StringIO() marshal.dump(case, f) f.seek(0) x = marshal.load(f) - assert x == case + assert x == case and type(x) is type(case) def test_42(self): import sys @@ -107,12 +107,12 @@ print "case: %-30s func=42" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) - assert x == case + assert x == case and type(x) is type(case) f = StringIO.StringIO() marshal.dump(case, f) f.seek(0) x = marshal.load(f) - assert x == case + assert x == case and type(x) is type(case) def test__minus_17(self): import sys @@ -126,12 +126,12 @@ print "case: %-30s func=_minus_17" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) - assert x == case + assert x == case and type(x) is type(case) f = StringIO.StringIO() marshal.dump(case, f) f.seek(0) x = marshal.load(f) - assert x == case + assert x == case and type(x) is type(case) def test_sys_dot_maxint(self): import sys @@ -145,12 +145,12 @@ print "case: %-30s func=sys_dot_maxint" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) - assert x == case + assert x == case and type(x) is type(case) f = StringIO.StringIO() marshal.dump(case, f) f.seek(0) x = marshal.load(f) - assert x == case + assert x == case and type(x) is type(case) def test__minus_1_dot_25(self): import sys @@ -164,12 +164,12 @@ print "case: %-30s func=_minus_1_dot_25" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) - assert x == case + assert x == case and type(x) is type(case) f = StringIO.StringIO() marshal.dump(case, f) f.seek(0) x = marshal.load(f) - assert x == case + assert x == case and type(x) is type(case) def test__minus_1_dot_25__2(self): import sys @@ -183,12 +183,12 @@ print "case: %-30s func=_minus_1_dot_25__2" % (case, ) s = marshal.dumps(case, 2); assert len(s) in (9, 17) x = marshal.loads(s) - assert x == case + assert x == case and type(x) is type(case) f = StringIO.StringIO() marshal.dump(case, f) f.seek(0) x = marshal.load(f) - assert x == case + assert x == case and type(x) is type(case) def test_2_plus_5j(self): import sys @@ -202,12 +202,12 @@ print "case: %-30s func=2_plus_5j" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) - assert x == case + assert x == case and type(x) is type(case) f = StringIO.StringIO() marshal.dump(case, f) f.seek(0) x = marshal.load(f) - assert x == case + assert x == case and type(x) is type(case) def test_2_plus_5j__2(self): import sys @@ -221,12 +221,12 @@ print "case: %-30s func=2_plus_5j__2" % (case, ) s = marshal.dumps(case, 2); assert len(s) in (9, 17) x = marshal.loads(s) - assert x == case + assert x == case and type(x) is type(case) f = StringIO.StringIO() marshal.dump(case, f) f.seek(0) x = marshal.load(f) - assert x == case + assert x == case and type(x) is type(case) def test_42L(self): import sys @@ -240,12 +240,12 @@ print "case: %-30s func=42L" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) - assert x == case + assert x == case and type(x) is type(case) f = StringIO.StringIO() marshal.dump(case, f) f.seek(0) x = marshal.load(f) - assert x == case + assert x == case and type(x) is type(case) def test__minus_1234567890123456789012345678901234567890L(self): import sys @@ -259,12 +259,12 @@ print "case: %-30s func=_minus_1234567890123456789012345678901234567890L" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) - assert x == case + assert x == case and type(x) is type(case) f = StringIO.StringIO() marshal.dump(case, f) f.seek(0) x = marshal.load(f) - assert x == case + assert x == case and type(x) is type(case) def test_hello_____not_interned(self): import sys @@ -278,12 +278,12 @@ print "case: %-30s func=hello_____not_interned" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) - assert x == case + assert x == case and type(x) is type(case) f = StringIO.StringIO() marshal.dump(case, f) f.seek(0) x = marshal.load(f) - assert x == case + assert x == case and type(x) is type(case) def test__Quote_hello_Quote_(self): import sys @@ -297,12 +297,12 @@ print "case: %-30s func=_Quote_hello_Quote_" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) - assert x == case + assert x == case and type(x) is type(case) f = StringIO.StringIO() marshal.dump(case, f) f.seek(0) x = marshal.load(f) - assert x == case + assert x == case and type(x) is type(case) def test__brace__ecarb_(self): import sys @@ -316,12 +316,12 @@ print "case: %-30s func=_brace__ecarb_" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) - assert x == case + assert x == case and type(x) is type(case) f = StringIO.StringIO() marshal.dump(case, f) f.seek(0) x = marshal.load(f) - assert x == case + assert x == case and type(x) is type(case) def test__brace_1_comma__2_ecarb_(self): import sys @@ -335,12 +335,12 @@ print "case: %-30s func=_brace_1_comma__2_ecarb_" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) - assert x == case + assert x == case and type(x) is type(case) f = StringIO.StringIO() marshal.dump(case, f) f.seek(0) x = marshal.load(f) - assert x == case + assert x == case and type(x) is type(case) def test__list__tsil_(self): import sys @@ -354,12 +354,12 @@ print "case: %-30s func=_list__tsil_" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) - assert x == case + assert x == case and type(x) is type(case) f = StringIO.StringIO() marshal.dump(case, f) f.seek(0) x = marshal.load(f) - assert x == case + assert x == case and type(x) is type(case) def test__list_3_comma__4_tsil_(self): import sys @@ -373,12 +373,12 @@ print "case: %-30s func=_list_3_comma__4_tsil_" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) - assert x == case + assert x == case and type(x) is type(case) f = StringIO.StringIO() marshal.dump(case, f) f.seek(0) x = marshal.load(f) - assert x == case + assert x == case and type(x) is type(case) def test__dict__tcid_(self): import sys @@ -392,12 +392,12 @@ print "case: %-30s func=_dict__tcid_" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) - assert x == case + assert x == case and type(x) is type(case) f = StringIO.StringIO() marshal.dump(case, f) f.seek(0) x = marshal.load(f) - assert x == case + assert x == case and type(x) is type(case) def test__dict_5_colon__6_comma__7_colon__8_tcid_(self): import sys @@ -411,12 +411,12 @@ print "case: %-30s func=_dict_5_colon__6_comma__7_colon__8_tcid_" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) - assert x == case + assert x == case and type(x) is type(case) f = StringIO.StringIO() marshal.dump(case, f) f.seek(0) x = marshal.load(f) - assert x == case + assert x == case and type(x) is type(case) def test_func_dot_func_code(self): import sys @@ -430,12 +430,12 @@ print "case: %-30s func=func_dot_func_code" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) - assert x == case + assert x == case and type(x) is type(case) f = StringIO.StringIO() marshal.dump(case, f) f.seek(0) x = marshal.load(f) - assert x == case + assert x == case and type(x) is type(case) def test_scopefunc_dot_func_code(self): import sys @@ -449,12 +449,12 @@ print "case: %-30s func=scopefunc_dot_func_code" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) - assert x == case + assert x == case and type(x) is type(case) f = StringIO.StringIO() marshal.dump(case, f) f.seek(0) x = marshal.load(f) - assert x == case + assert x == case and type(x) is type(case) def test_u_quote_hello_quote_(self): import sys @@ -468,12 +468,12 @@ print "case: %-30s func=u_quote_hello_quote_" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) - assert x == case + assert x == case and type(x) is type(case) f = StringIO.StringIO() marshal.dump(case, f) f.seek(0) x = marshal.load(f) - assert x == case + assert x == case and type(x) is type(case) def test_buffer_brace_hello_ecarb_(self): import sys @@ -487,12 +487,12 @@ print "case: %-30s func=buffer_brace_hello_ecarb_" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) - assert x == case + assert x == case and type(x) is type(case) f = StringIO.StringIO() marshal.dump(case, f) f.seek(0) x = marshal.load(f) - assert x == case + assert x == case and type(x) is type(case) def test_buffer_brace_u_quote_unicode_comma__too_quote__ecarb_(self): import sys @@ -506,12 +506,12 @@ print "case: %-30s func=buffer_brace_u_quote_unicode_comma__too_quote__ecarb_" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) - assert x == case + assert x == case and type(x) is type(case) f = StringIO.StringIO() marshal.dump(case, f) f.seek(0) x = marshal.load(f) - assert x == case + assert x == case and type(x) is type(case) def test_set_brace__ecarb_(self): import sys @@ -525,12 +525,12 @@ print "case: %-30s func=set_brace__ecarb_" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) - assert x == case + assert x == case and type(x) is type(case) f = StringIO.StringIO() marshal.dump(case, f) f.seek(0) x = marshal.load(f) - assert x == case + assert x == case and type(x) is type(case) def test_set_brace__list_1_comma__2_tsil__ecarb_(self): import sys @@ -544,12 +544,12 @@ print "case: %-30s func=set_brace__list_1_comma__2_tsil__ecarb_" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) - assert x == case + assert x == case and type(x) is type(case) f = StringIO.StringIO() marshal.dump(case, f) f.seek(0) x = marshal.load(f) - assert x == case + assert x == case and type(x) is type(case) def test_frozenset_brace__ecarb_(self): import sys @@ -563,12 +563,12 @@ print "case: %-30s func=frozenset_brace__ecarb_" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) - assert x == case + assert x == case and type(x) is type(case) f = StringIO.StringIO() marshal.dump(case, f) f.seek(0) x = marshal.load(f) - assert x == case + assert x == case and type(x) is type(case) def test_frozenset_brace__list_3_comma__4_tsil__ecarb_(self): import sys @@ -582,12 +582,12 @@ print "case: %-30s func=frozenset_brace__list_3_comma__4_tsil__ecarb_" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) - assert x == case + assert x == case and type(x) is type(case) f = StringIO.StringIO() marshal.dump(case, f) f.seek(0) x = marshal.load(f) - assert x == case + assert x == case and type(x) is type(case) class AppTestMultiDict(object): @@ -597,3 +597,8 @@ 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 + +class AppTestRope(AppTestMarshal): + def setup_class(cls): + from pypy.conftest import gettestobjspace + cls.space = gettestobjspace(**{"objspace.std.withrope": True}) Modified: pypy/branch/rope-branch/pypy/objspace/std/marshal_impl.py ============================================================================== --- pypy/branch/rope-branch/pypy/objspace/std/marshal_impl.py (original) +++ pypy/branch/rope-branch/pypy/objspace/std/marshal_impl.py Fri Mar 2 18:44:59 2007 @@ -28,6 +28,7 @@ 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.ropeobject import W_RopeObject from pypy.objspace.std.typeobject import W_TypeObject from pypy.objspace.std.longobject import W_LongObject from pypy.objspace.std.noneobject import W_NoneObject @@ -302,6 +303,8 @@ else: m.atom_str(TYPE_STRING, s) +marshal_w__Rope = marshal_w__String + def unmarshal_String(space, u, tc): return space.wrap(u.get_str()) register(TYPE_STRING, unmarshal_String) From arigo at codespeak.net Fri Mar 2 19:20:50 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 2 Mar 2007 19:20:50 +0100 (CET) Subject: [pypy-svn] r39744 - pypy/branch/rope-branch/pypy/objspace/std/test Message-ID: <20070302182050.11BC6100C5@code0.codespeak.net> Author: arigo Date: Fri Mar 2 19:20:48 2007 New Revision: 39744 Modified: pypy/branch/rope-branch/pypy/objspace/std/test/test_ropeobject.py Log: Split bug. Fails yet, but checking it in is ok because it's a branch (according to cfbolz). Modified: pypy/branch/rope-branch/pypy/objspace/std/test/test_ropeobject.py ============================================================================== --- pypy/branch/rope-branch/pypy/objspace/std/test/test_ropeobject.py (original) +++ pypy/branch/rope-branch/pypy/objspace/std/test/test_ropeobject.py Fri Mar 2 19:20:48 2007 @@ -12,6 +12,13 @@ import sys raises(OverflowError, '"abcdefg" * (sys.maxint // 2)') + def test_split_bug(self): + s = '/home/arigo/svn/pypy/branch/rope-branch/pypy/bin' + s += '/pypy' + lst = s.split('/') + assert lst == ['', 'home', 'arigo', 'svn', 'pypy', + 'branch', 'rope-branch', 'pypy', 'bin', 'pypy'] + class AppTestRopeUnicode(object): def setup_class(cls): From cfbolz at codespeak.net Fri Mar 2 19:51:10 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 2 Mar 2007 19:51:10 +0100 (CET) Subject: [pypy-svn] r39745 - pypy/dist/pypy/objspace/std/test Message-ID: <20070302185110.339B6100FC@code0.codespeak.net> Author: cfbolz Date: Fri Mar 2 19:51:08 2007 New Revision: 39745 Added: pypy/dist/pypy/objspace/std/test/test_resizable.py Log: additional tests for the smart resizable list Added: pypy/dist/pypy/objspace/std/test/test_resizable.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/objspace/std/test/test_resizable.py Fri Mar 2 19:51:08 2007 @@ -0,0 +1,110 @@ +import py +from pypy.objspace.std.smartresizablelist import * + +def test_leftmost_set_bit(): + assert leftmost_set_bit(2) == 1 + assert leftmost_set_bit(3) == 1 + assert leftmost_set_bit(4) == 2 + assert leftmost_set_bit(5) == 2 + assert leftmost_set_bit(6) == 2 + assert leftmost_set_bit(7) == 2 + assert leftmost_set_bit(8) == 3 + assert leftmost_set_bit(9) == 3 + assert leftmost_set_bit(10) == 3 + assert leftmost_set_bit(11) == 3 + assert leftmost_set_bit(12) == 3 + assert leftmost_set_bit(13) == 3 + assert leftmost_set_bit(14) == 3 + assert leftmost_set_bit(15) == 3 + assert leftmost_set_bit(2 ** 18 + 1) == 18 + +def test_decompose(): + for i in range(1, 500): + k = leftmost_set_bit(i) + b, e = decompose(i, k) + hk = k // 2 + (k & 1) + assert (b << hk) + e + (1 << k) == i + +SIZE = 700 +def test_grow(): + l = SmartResizableListImplementation(None) + for i in range(SIZE): +# import pdb; pdb.set_trace() + pos = l.grow() + assert l.length() == i + 1 + assert pos == find_block_index(i) + l.setitem(i, "hello" + str(i)) + for j in range(i + 1): + assert l.getitem(j) == "hello" + str(j) + +def test_grow_steps(): + for step in range(2, 100, 10): + l = SmartResizableListImplementation(None) + for m in range(0, SIZE, step): + pos = l.grow(step) + assert pos == find_block_index(m + step - 1) + assert l.length() == m + step + for i in range(m, m + step): + l.setitem(i, "hello" + str(i)) + for j in range(m + 1): + assert l.getitem(j) == "hello" + str(j) + +def test_shrink(): + l = SmartResizableListImplementation(None) + for i in range(2): + l.grow(SIZE) + for i in range(SIZE): + l.setitem(i, i + 42) + for i in range(SIZE): + l.shrink() + assert l.length() == SIZE - i - 1 + for j in range(l.length()): + assert l.getitem(j) == j + 42 + py.test.raises(ValueError, l.shrink) + +def test_shrink_sets_none(): + l = SmartResizableListImplementation(None) + for i in range(SIZE): + l.grow(2) + assert l.getitem(i) == None + assert l.getitem(i + 1) == None + l.setitem(i, i) + l.setitem(i + 1, i + 1) + l.shrink() + assert l.getitem(i) == i + +def test_shrink_steps(): + for step in range(2, 100, 10): + l = SmartResizableListImplementation(None) + l.grow(SIZE) + for i in range(SIZE): + l.setitem(i, "hello" + str(i)) + for m in range(0, SIZE - step, step): + pos = l.shrink(step) + assert l.length() == SIZE - m - step + for i in range(l.length()): + assert l.getitem(i) == "hello" + str(i) + +def test_random(): + import random + l = SmartResizableListImplementation(None) + for i in range(1000): + previous = l.length() + print i, previous + c = random.randrange(2) + if c == 0 or l.length() == 0: + items = random.randrange(1, SIZE) + l.grow(items) + assert l.length() == previous + items + for i in range(previous, previous + items): + assert l.getitem(i) is None + l.setitem(i, i + 42) + else: + items = random.randrange(1, l.length() + 1) + l.shrink(items) + assert l.length() == previous - items + if l.length() > 5: + for i in range(l.length() - 5, l.length()): + assert l.getitem(i) == i + 42 + for i in range(l.length()): + assert l.getitem(i) == i + 42 From arigo at codespeak.net Fri Mar 2 20:08:03 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 2 Mar 2007 20:08:03 +0100 (CET) Subject: [pypy-svn] r39746 - pypy/dist/pypy/translator/oosupport Message-ID: <20070302190803.27C7910106@code0.codespeak.net> Author: arigo Date: Fri Mar 2 20:08:00 2007 New Revision: 39746 Modified: pypy/dist/pypy/translator/oosupport/function.py Log: Typo. Modified: pypy/dist/pypy/translator/oosupport/function.py ============================================================================== --- pypy/dist/pypy/translator/oosupport/function.py (original) +++ pypy/dist/pypy/translator/oosupport/function.py Fri Mar 2 20:08:00 2007 @@ -166,7 +166,7 @@ self.after_except_block() - def after_except_block(): + def after_except_block(self): pass def record_ll_meta_exc(self, ll_meta_exc): From cfbolz at codespeak.net Fri Mar 2 20:19:20 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 2 Mar 2007 20:19:20 +0100 (CET) Subject: [pypy-svn] r39747 - in pypy/branch/rope-branch/pypy/objspace/std: . test Message-ID: <20070302191920.D9AAB10063@code0.codespeak.net> Author: cfbolz Date: Fri Mar 2 20:19:19 2007 New Revision: 39747 Modified: pypy/branch/rope-branch/pypy/objspace/std/rope.py pypy/branch/rope-branch/pypy/objspace/std/ropeobject.py pypy/branch/rope-branch/pypy/objspace/std/test/test_rope.py Log: fix rope bug -- indeed some sort of normalization problem Modified: pypy/branch/rope-branch/pypy/objspace/std/rope.py ============================================================================== --- pypy/branch/rope-branch/pypy/objspace/std/rope.py (original) +++ pypy/branch/rope-branch/pypy/objspace/std/rope.py Fri Mar 2 20:19:19 2007 @@ -198,9 +198,8 @@ return result def getslice(node, start, stop, step, slicelength): - start, stop, node = find_straddling(node, start, stop) if step != 1: - # XXX optimize later using SeekableCharIterator + start, stop, node = find_straddling(node, start, stop) iter = SeekableCharIterator(node) iter.seekforward(start) result = [iter.next()] @@ -211,6 +210,7 @@ return getslice_one(node, start, stop) def getslice_one(node, start, stop): + start, stop, node = find_straddling(node, start, stop) if isinstance(node, BinaryConcatNode): if start == 0: if stop == node.length(): Modified: pypy/branch/rope-branch/pypy/objspace/std/ropeobject.py ============================================================================== --- pypy/branch/rope-branch/pypy/objspace/std/ropeobject.py (original) +++ pypy/branch/rope-branch/pypy/objspace/std/ropeobject.py Fri Mar 2 20:19:19 2007 @@ -268,11 +268,11 @@ start = 0 selfnode = w_self._node bynode = w_by._node - iter = rope.FindIterator(selfnode, bynode) bylen = bynode.length() if bylen == 0: raise OperationError(space.w_ValueError, space.wrap("empty separator")) + iter = rope.FindIterator(selfnode, bynode) while maxsplit != 0: try: next = iter.next() Modified: pypy/branch/rope-branch/pypy/objspace/std/test/test_rope.py ============================================================================== --- pypy/branch/rope-branch/pypy/objspace/std/test/test_rope.py (original) +++ pypy/branch/rope-branch/pypy/objspace/std/test/test_rope.py Fri Mar 2 20:19:19 2007 @@ -90,6 +90,14 @@ for stop in range(start, len(result)): assert s[start:stop].flatten() == result[start:stop] +def test_getslice_bug(): + s1 = LiteralStringNode("/home/arigo/svn/pypy/branch/rope-branch/pypy/bin") + s2 = LiteralStringNode("/pypy") + s = s1 + s2 + r = getslice_one(s, 1, 5) + assert r.flatten() == "home" + + def test_getslice_step(): s1 = (LiteralStringNode("abcde") + LiteralStringNode("fghijklm") + LiteralStringNode("nopqrstu") + LiteralStringNode("vwxyz") + From arigo at codespeak.net Fri Mar 2 20:30:55 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 2 Mar 2007 20:30:55 +0100 (CET) Subject: [pypy-svn] r39748 - pypy/dist/pypy/translator/goal Message-ID: <20070302193055.E212B1010C@code0.codespeak.net> Author: arigo Date: Fri Mar 2 20:30:53 2007 New Revision: 39748 Modified: pypy/dist/pypy/translator/goal/app_main.py pypy/dist/pypy/translator/goal/targetpypystandalone.py Log: Move DEBUG to app_main. I think that now this hides the "debug:"s that are expected and shows the "debug:"s that should not occur unless something went very wrong. 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 Fri Mar 2 20:30:53 2007 @@ -15,6 +15,8 @@ import sys, os +DEBUG = False # dump exceptions before calling the except hook + originalexcepthook = sys.__excepthook__ def run_toplevel(f, *fargs, **fkwds): @@ -61,9 +63,8 @@ except: etype, evalue, etraceback = sys.exc_info() try: - # XXX extra debugging info in case the code below goes very wrong - # XXX (temporary) - if hasattr(sys, 'stderr'): + # extra debugging info in case the code below goes very wrong + if DEBUG and hasattr(sys, 'stderr'): s = getattr(etype, '__name__', repr(etype)) print >> sys.stderr, "debug: exception-type: ", s print >> sys.stderr, "debug: exception-value:", str(evalue) Modified: pypy/dist/pypy/translator/goal/targetpypystandalone.py ============================================================================== --- pypy/dist/pypy/translator/goal/targetpypystandalone.py (original) +++ pypy/dist/pypy/translator/goal/targetpypystandalone.py Fri Mar 2 20:30:53 2007 @@ -12,16 +12,13 @@ thisdir = py.magic.autopath().dirpath() app_basic_example_path = str(thisdir.join("app_basic_example.py")) -DEBUG = False - try: this_dir = os.path.dirname(__file__) except NameError: this_dir = os.path.dirname(sys.argv[0]) def debug(msg): - if DEBUG: - os.write(2, "debug: " + msg + '\n') + os.write(2, "debug: " + msg + '\n') # __________ Entry point __________ @@ -32,9 +29,9 @@ w_call_startup_gateway = space.wrap(gateway.interp2app(call_startup)) def entry_point(argv): - debug("entry point starting") - for arg in argv: - debug(" argv -> " + arg) + #debug("entry point starting") + #for arg in argv: + # debug(" argv -> " + arg) try: try: space.call_function(w_run_toplevel, w_call_startup_gateway) From fijal at codespeak.net Fri Mar 2 20:43:59 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 2 Mar 2007 20:43:59 +0100 (CET) Subject: [pypy-svn] r39750 - pypy/dist/pypy/lang/js Message-ID: <20070302194359.419B1100E6@code0.codespeak.net> Author: fijal Date: Fri Mar 2 20:43:57 2007 New Revision: 39750 Modified: pypy/dist/pypy/lang/js/conftest.py Log: Py.test distributed config should go somewhere higher, ie home dir. Modified: pypy/dist/pypy/lang/js/conftest.py ============================================================================== --- pypy/dist/pypy/lang/js/conftest.py (original) +++ pypy/dist/pypy/lang/js/conftest.py Fri Mar 2 20:43:57 2007 @@ -1,13 +1,5 @@ import py -dist_hosts = ['localhost', 'localhost'] -# dist_rsync_roots = [,] -# dist_remotepython = 'python2.4' -dist_nicelevel = 10 -dist_boxed = False -dist_maxwait = 1000 -dist_taskspernode = 10 - Option = py.test.config.Option option = py.test.config.addoptions("ecma compatibility tests", Option('', '--ecma', From cfbolz at codespeak.net Fri Mar 2 21:02:48 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 2 Mar 2007 21:02:48 +0100 (CET) Subject: [pypy-svn] r39751 - pypy/branch/rope-branch/pypy/objspace/std Message-ID: <20070302200248.95BC3100FC@code0.codespeak.net> Author: cfbolz Date: Fri Mar 2 21:02:47 2007 New Revision: 39751 Modified: pypy/branch/rope-branch/pypy/objspace/std/model.py pypy/branch/rope-branch/pypy/objspace/std/objspace.py Log: obscure, obscure: magically import those classes not in the typeorder too Modified: pypy/branch/rope-branch/pypy/objspace/std/model.py ============================================================================== --- pypy/branch/rope-branch/pypy/objspace/std/model.py (original) +++ pypy/branch/rope-branch/pypy/objspace/std/model.py Fri Mar 2 21:02:47 2007 @@ -114,7 +114,7 @@ self.typeorder[setobject.W_FrozensetObject] = [] self.typeorder[setobject.W_SetIterObject] = [] - imported_but_not_registered = { + self.imported_but_not_registered = { dictobject.W_DictObject: True, dictobject.W_DictIterObject: True, listobject.W_ListObject: True, @@ -127,7 +127,7 @@ if value: self.typeorder[implcls] = [] else: - imported_but_not_registered[implcls] = True + self.imported_but_not_registered[implcls] = True if (config.objspace.std.withstrdict or config.objspace.std.withmultidict): @@ -143,7 +143,7 @@ from pypy.objspace.std.objspace import _registered_implementations for implcls in _registered_implementations: assert (implcls in self.typeorder or - implcls in imported_but_not_registered), ( + implcls in self.imported_but_not_registered), ( "please add %r in StdTypeModel.typeorder" % (implcls,)) Modified: pypy/branch/rope-branch/pypy/objspace/std/objspace.py ============================================================================== --- pypy/branch/rope-branch/pypy/objspace/std/objspace.py (original) +++ pypy/branch/rope-branch/pypy/objspace/std/objspace.py Fri Mar 2 21:02:47 2007 @@ -155,6 +155,8 @@ # hack to avoid imports in the time-critical functions below for cls in self.model.typeorder: globals()[cls.__name__] = cls + for cls in self.model.imported_but_not_registered: + globals()[cls.__name__] = cls # singletons self.w_None = W_NoneObject() From arigo at codespeak.net Fri Mar 2 21:05:15 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 2 Mar 2007 21:05:15 +0100 (CET) Subject: [pypy-svn] r39752 - pypy/branch/rope-branch/pypy/objspace/std Message-ID: <20070302200515.348A410107@code0.codespeak.net> Author: arigo Date: Fri Mar 2 21:05:12 2007 New Revision: 39752 Modified: pypy/branch/rope-branch/pypy/objspace/std/rope.py Log: A minor optimization that makes the flow space happier. Modified: pypy/branch/rope-branch/pypy/objspace/std/rope.py ============================================================================== --- pypy/branch/rope-branch/pypy/objspace/std/rope.py (original) +++ pypy/branch/rope-branch/pypy/objspace/std/rope.py Fri Mar 2 21:05:12 2007 @@ -282,8 +282,8 @@ if times == 1: return node end_length = node.length() * times - num_bits = 0 - mask = times + num_bits = 2 + mask = times >> 2 while mask: num_bits += 1 mask >>= 1 From arigo at codespeak.net Fri Mar 2 21:22:21 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 2 Mar 2007 21:22:21 +0100 (CET) Subject: [pypy-svn] r39753 - in pypy/branch/rope-branch/pypy/objspace/std: . test Message-ID: <20070302202221.E6584100C3@code0.codespeak.net> Author: arigo Date: Fri Mar 2 21:22:19 2007 New Revision: 39753 Modified: pypy/branch/rope-branch/pypy/objspace/std/ropeobject.py pypy/branch/rope-branch/pypy/objspace/std/test/test_ropeobject.py Log: Typo with test. Modified: pypy/branch/rope-branch/pypy/objspace/std/ropeobject.py ============================================================================== --- pypy/branch/rope-branch/pypy/objspace/std/ropeobject.py (original) +++ pypy/branch/rope-branch/pypy/objspace/std/ropeobject.py Fri Mar 2 21:22:19 2007 @@ -888,7 +888,7 @@ raise OperationError( space.w_TypeError, space.wrap("ord() expected a character, but string " - "of length %d found"%(len(w_str._value),))) + "of length %d found"% (w_str._node.length(),))) return space.wrap(ord(node.flatten()[0])) def getnewargs__Rope(space, w_str): Modified: pypy/branch/rope-branch/pypy/objspace/std/test/test_ropeobject.py ============================================================================== --- pypy/branch/rope-branch/pypy/objspace/std/test/test_ropeobject.py (original) +++ pypy/branch/rope-branch/pypy/objspace/std/test/test_ropeobject.py Fri Mar 2 21:22:19 2007 @@ -19,6 +19,14 @@ assert lst == ['', 'home', 'arigo', 'svn', 'pypy', 'branch', 'rope-branch', 'pypy', 'bin', 'pypy'] + def test_ord(self): + s = '' + s += '0' + assert ord(s) == 48 + raises(TypeError, ord, '') + s += '3' + raises(TypeError, ord, s) + class AppTestRopeUnicode(object): def setup_class(cls): From arigo at codespeak.net Sat Mar 3 00:25:24 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 3 Mar 2007 00:25:24 +0100 (CET) Subject: [pypy-svn] r39756 - pypy/branch/rope-branch/pypy/objspace/std Message-ID: <20070302232524.529D2100F8@code0.codespeak.net> Author: arigo Date: Sat Mar 3 00:25:21 2007 New Revision: 39756 Modified: pypy/branch/rope-branch/pypy/objspace/std/ropeobject.py Log: Translation fix. More to come. Modified: pypy/branch/rope-branch/pypy/objspace/std/ropeobject.py ============================================================================== --- pypy/branch/rope-branch/pypy/objspace/std/ropeobject.py (original) +++ pypy/branch/rope-branch/pypy/objspace/std/ropeobject.py Sat Mar 3 00:25:21 2007 @@ -25,7 +25,7 @@ return w_self._node.flatten() def create_if_subclassed(w_self): - if type(w_self) == W_RopeObject: + if type(w_self) is W_RopeObject: return w_self return W_RopeObject(w_self._node) From santagada at codespeak.net Sat Mar 3 05:41:27 2007 From: santagada at codespeak.net (santagada at codespeak.net) Date: Sat, 3 Mar 2007 05:41:27 +0100 (CET) Subject: [pypy-svn] r39757 - pypy/dist/pypy/lang/js Message-ID: <20070303044127.44814100A7@code0.codespeak.net> Author: santagada Date: Sat Mar 3 05:41:24 2007 New Revision: 39757 Added: pypy/dist/pypy/lang/js/operations.py Modified: pypy/dist/pypy/lang/js/interpreter.py Log: separeted the operations from the rest of the interpreter Modified: pypy/dist/pypy/lang/js/interpreter.py ============================================================================== --- pypy/dist/pypy/lang/js/interpreter.py (original) +++ pypy/dist/pypy/lang/js/interpreter.py Sat Mar 3 05:41:24 2007 @@ -1,98 +1,7 @@ import math from pypy.lang.js.jsparser import parse, parse_bytecode -from pypy.lang.js.jsobj import * -from pypy.rlib.parsing.ebnfparse import Symbol, Nonterminal - -class Node(object): - opcode = None - def __init__(self, t=None, type='', value='', lineno=0, start=0, end=0): - if t is None: - self.type = type - self.value = value - self.lineno = lineno - self.start = start - self.end = end - else: - self.type = get_string(t, 'type') - self.value = get_string(t, 'value') - self.lineno = int(get_string(t, 'lineno')) - - try: - self.start = int(get_string(t, 'start')) - except ValueError, e: - self.start = 0 - try: - self.end = int(get_string(t, 'end')) - except Exception, e: - self.end = 0 - self.from_tree(t) - - def eval(self, ctx): - if DEBUG: - print self - raise NotImplementedError - - def execute(self, ctx): - raise NotImplementedError - - def get_literal(self): - raise NotImplementedError - - def get_args(self, ctx): - raise NotImplementedError - - def __str__(self): - return ""%(self.opcode, self.value) - -class Statement(Node): - pass - -class Expression(Statement): - def eval(self, ctx): - return W_Root() - - def execute(self, ctx): - return self.eval(ctx) - -class ListOp(Expression): - def from_tree(self, t): - self.list = get_objects(t) - -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): - self.left = get_obj(t,'0') - self.right = get_obj(t, '1') - -class BinaryComparisonOp(BinaryOp): - def eval(self, ctx): - s2 = self.left.eval(ctx).GetValue() - s4 = self.right.eval(ctx).GetValue() - if DEBUG: - print "bincomp, op1 and op2 ", s2, s4 - return self.decision(ctx, s2, s4) - - 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 +from pypy.lang.js.operations import * def writer(x): print x @@ -177,8 +86,7 @@ w_Function.Put('constructor', w_Function) #Object stuff - w_Object = W_Builtin(Prototype=w_Function) - w_Object.set_builtin_call(objectconstructor) + w_Object = W_Builtin(objectconstructor, Prototype=w_Function) w_Object.Put('length', W_Number(1), ro=True, dd=True) w_Object.Put('prototype', w_ObjPrototype, dd=True, de=True, ro=True) w_ObjPrototype.Put('constructor', w_Object) @@ -231,956 +139,6 @@ """run the interpreter""" return script.execute(self.global_context) -class PropertyInit(BinaryOp): - opcode = 'PROPERTY_INIT' - -class Array(ListOp): - opcode = 'ARRAY_INIT' - - def eval(self, ctx): - #d = dict(enumerate(self.items)) - array = W_Array() - for i in range(len(self.list)): - array.Put(str(i), self.list[i].eval(ctx).GetValue()) - return array - - -class Assign(BinaryOp): - opcode = 'ASSIGN' - - def eval(self, ctx): - v1 = self.left.eval(ctx) - v3 = self.right.eval(ctx).GetValue() - op = self.value - if op == "=": - val = v3 - elif op == "*": - val = Mult().mathop(ctx, v1.GetValue(), v3) - elif op == "+": - 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() - - v1.PutValue(val, ctx) - return val - -class Block(Statement): - opcode = 'BLOCK' - - def from_tree(self, t): - self.nodes = get_objects(t) - - def execute(self, ctx): - try: - last = w_Undefined - for node in self.nodes: - last = node.execute(ctx) - return last - except ExecutionReturned, e: - if e.type == 'return': - return e.value - 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(',') - self.targtype = pieces[0] - self.targlineno = pieces[1] - self.targstart = pieces[2] - -class Break(Unconditional): - opcode = 'BREAK' - - def execute(self, ctx): - raise ExecutionReturned('break', None, None) - -class Continue(Unconditional): - opcode = 'CONTINUE' - - def execute(self, ctx): - raise ExecutionReturned('continue', None, None) - -class Call(BinaryOp): - opcode = 'CALL' - - def eval(self, ctx): - if DEBUG: - print "calling", self.left, self.right - r1 = self.left.eval(ctx) - r2 = self.right.eval(ctx) - r3 = r1.GetValue() - if isinstance(r1, W_Reference): - r6 = r1.GetBase() - else: - r6 = None - if isinstance(r2, ActivationObject): - r7 = None - else: - r7 = r6 - - retval = r3.Call(ctx=ctx, args=r2.get_args(), this=r7) - return retval - -class Comma(BinaryOp): - opcode = 'COMMA' - - def eval(self, ctx): - self.left.eval(ctx) - return self.right.eval(ctx) - -class Conditional(Expression): - opcode = 'CONDITIONAL' - - def from_tree(self, t): - self.logicalexpr = get_obj(t, '0') - self.trueop = get_obj(t, '1') - self.falseop = get_obj(t, '2') - - def eval(self, ctx): - if self.logicalexpr.eval(ctx).GetValue().ToBoolean(): - return self.trueop.eval(ctx).GetValue() - else: - return self.falseop.eval(ctx).GetValue() - -class Dot(BinaryOp): - opcode = 'DOT' - - def eval(self, ctx): - w_obj = self.left.eval(ctx).GetValue().ToObject() - name = self.right.eval(ctx).GetPropertyName() - return W_Reference(name, w_obj) - -class Function(Expression): - opcode = 'FUNCTION' - - def from_tree(self, t): - self.name = get_string(t, 'name') - self.body = get_obj(t, 'body') - params = get_string(t, 'params') - if params == '': - self.params = [] - else: - self.params = params.split(',') - - def eval(self, ctx): - w_obj = W_Object(ctx=ctx, callfunc = self) - return w_obj - -class Identifier(Expression): - opcode = 'IDENTIFIER' - - def from_tree(self, t): - self.name = get_string(t,'value') - self.initializer = get_obj(t, 'initializer') - - def __str__(self): - return ""%(str(self.name), str(self.initializer)) - - def eval(self, ctx): - if self.initializer is not astundef: - ref = ctx.resolve_identifier(self.name) - ref.PutValue(self.initializer.eval(ctx).GetValue(), ctx) - return ctx.resolve_identifier(self.name) - - def get_literal(self): - return self.name - -class This(Identifier): - opcode = "THIS" - -class If(Statement): - opcode = 'IF' - - def from_tree(self, t): - self.condition = get_obj(t, 'condition') - self.thenPart = get_obj(t, 'thenPart') - self.elsePart = get_obj(t, 'elsePart') - - def execute(self, ctx): - temp = self.condition.eval(ctx).GetValue() - if temp.ToBoolean(): - return self.thenPart.execute(ctx) - else: - return self.elsePart.execute(ctx) - -class Group(UnaryOp): - opcode = 'GROUP' - - def eval(self, ctx): - return self.expr.eval(ctx) - -def ARC(ctx, x, y): - """ - Implements the Abstract Relational Comparison x < y - Still not 100% to the spec - """ - # TODO complete the funcion with strings comparison - s1 = x.ToPrimitive(ctx, 'Number') - s2 = y.ToPrimitive(ctx, 'Number') - if not (isinstance(s1, W_String) and isinstance(s2, W_String)): - s4 = s1.ToNumber() - s5 = s2.ToNumber() - if s4 == NaN or s5 == NaN: - return -1 - if s4 < s5: - return 1 - else: - return 0 - else: - return -1 - -class Or(BinaryLogicOp): - opcode = 'OR' - - def eval(self, ctx): - s2 = self.left.eval(ctx).GetValue() - if s2.ToBoolean(): - return s2 - s4 = self.right.eval(ctx).GetValue() - return s4 - -class And(BinaryLogicOp): - opcode = 'AND' - - def eval(self, ctx): - s2 = self.left.eval(ctx).GetValue() - if not s2.ToBoolean(): - return s2 - s4 = self.right.eval(ctx).GetValue() - return s4 - -class Ursh(BinaryComparisonOp): - opcode = 'URSH' - - def decision(self, ctx, op1, op2): - a = op1.ToUInt32() - b = op2.ToUInt32() - return W_Number(a >> (b & 0x1F)) - -class Rsh(BinaryComparisonOp): - opcode = 'RSH' - - def decision(self, ctx, op1, op2): - a = op1.ToInt32() - b = op2.ToUInt32() - return W_Number(a >> int(b & 0x1F)) - -class Lsh(BinaryComparisonOp): - opcode = 'LSH' - - def decision(self, ctx, op1, op2): - a = op1.ToInt32() - b = op2.ToUInt32() - return W_Number(a << int(b & 0x1F)) - -class Ge(BinaryComparisonOp): - opcode = 'GE' - - def decision(self, ctx, op1, op2): - s5 = ARC(ctx, op1, op2) - if DEBUG: - print ">= ARC result:", s5 - if s5 in (-1, 1): - return W_Boolean(False) - else: - return W_Boolean(True) - -class Gt(BinaryComparisonOp): - opcode = 'GT' - - def decision(self, ctx, op1, op2): - s5 = ARC(ctx, op2, op1) - if DEBUG: - print "> ARC result:", s5 - if s5 == -1: - return W_Boolean(False) - else: - return W_Boolean(s5) - -class Le(BinaryComparisonOp): - opcode = 'LE' - - def decision(self, ctx, op1, op2): - s5 = ARC(ctx, op2, op1) - if s5 in (-1, 1): - return W_Boolean(False) - else: - return W_Boolean(True) - -class Lt(BinaryComparisonOp): - opcode = 'LT' - - def decision(self, ctx, op1, op2): - s5 = ARC(ctx, op1, op2) - if s5 == -1: - return W_Boolean(False) - else: - return W_Boolean(s5) - -def AEC(x, y): - """ - Implements the Abstract Equality Comparison x == y - trying to be fully to the spec - """ - type1 = x.type() - type2 = y.type() - if type1 == type2: - if type1 == "undefined" or type1 == "null": - return True - if type1 == "number": - n1 = x.ToNumber() - n2 = y.ToNumber() - nan_string = str(NaN) - if str(n1) == nan_string or str(n2) == nan_string: - return False - if n1 == n2: - return True - return False - elif type1 == "string": - return x.ToString() == y.ToString() - elif type1 == "boolean": - return x.ToBoolean() == x.ToBoolean() - return x == y - else: - #step 14 - if (type1 == "undefined" and type2 == "null") or \ - (type1 == "null" and type2 == "undefined"): - return True - if type1 == "number" and type2 == "string": - return AEC(x, W_Number(y.ToNumber())) - if type1 == "string" and type2 == "number": - return AEC(W_Number(x.ToNumber()), y) - if type1 == "boolean": - return AEC(W_Number(x.ToNumber()), y) - if type2 == "boolean": - return AEC(x, W_Number(y.ToNumber())) - if (type1 == "string" or type1 == "number") and \ - type2 == "object": - return AEC(x, y.ToPrimitive()) - if (type2 == "string" or type2 == "number") and \ - type1 == "object": - return AEC(x.ToPrimitive(), y) - return False - - - objtype = x.GetValue().type() - if objtype == y.GetValue().type(): - if objtype == "undefined" or objtype == "null": - return True - - if isinstance(x, W_String) and isinstance(y, W_String): - r = x.ToString() == y.ToString() - else: - r = x.ToNumber() == y.ToNumber() - return r - -class Eq(BinaryComparisonOp): - opcode = 'EQ' - - def decision(self, ctx, op1, op2): - return W_Boolean(AEC(op1, op2)) - -class Ne(BinaryComparisonOp): - opcode = 'NE' - - def decision(self, ctx, op1, op2): - return W_Boolean(not AEC(op1, op2)) - -def SEC(x,y): - """ - Implements the Strict Equality Comparison x === y - trying to be fully to the spec - """ - type1 = x.type() - type2 = y.type() - if type1 != type2: - return False - if type1 == "undefined" or type1 == "null": - return True - if type1 == "number": - n1 = x.ToNumber() - n2 = y.ToNumber() - nan_string = str(NaN) - if str(n1) == nan_string or str(n2) == nan_string: - return False - if n1 == n2: - return True - return False - if type1 == "string": - return x.ToString() == y.ToString() - if type1 == "boolean": - return x.ToBoolean() == x.ToBoolean() - return x == y - -class StrictEq(BinaryComparisonOp): - opcode = 'STRICT_EQ' - - def decision(self, ctx, op1, op2): - return W_Boolean(SEC(op1, op2)) - -class StrictNe(BinaryComparisonOp): - opcode = 'STRICT_NE' - - def decision(self, ctx, op1, op2): - return W_Boolean(not SEC(op1, op2)) - - -class In(BinaryComparisonOp): - opcode = 'IN' - - def decision(self, ctx, op1, op2): - if not isinstance(op2, W_Object): - raise ThrowException(W_String("TypeError")) - 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' - - 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 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' - - def eval(self, ctx): - w_obj = self.left.eval(ctx).GetValue().ToObject() - name= self.right.eval(ctx).GetValue().ToString() - return W_Reference(name, w_obj) - -class List(ListOp): - opcode = 'LIST' - - def eval(self, ctx): - return W_List([node.eval(ctx).GetValue() for node in self.list]) - -class Minus(BinaryComparisonOp): - opcode = 'MINUS' - - def decision(self, ctx, op1, op2): - x = op1.ToNumber() - y = op2.ToNumber() - return W_Number(x - y) - -class New(UnaryOp): - opcode = 'NEW' - - def eval(self, ctx): - x = self.expr.eval(ctx).GetValue() - if not isinstance(x, W_PrimitiveObject): - raise TypeError() - - return x.Construct(ctx=ctx) - -class NewWithArgs(BinaryOp): - opcode = 'NEW_WITH_ARGS' - - def eval(self, ctx): - x = self.left.eval(ctx).GetValue() - if not isinstance(x, W_PrimitiveObject): - raise TypeError() - args = self.right.eval(ctx).get_args() - return x.Construct(ctx=ctx, args=args) - -class Null(Expression): - opcode = 'NULL' - - def from_tree(self, t): - pass - - def eval(self, ctx): - return w_Null - -class Number(Expression): - opcode = 'NUMBER' - - def from_tree(self, t): - self.num = float(get_string(t, 'value')) - - def eval(self, ctx): - return W_Number(self.num) - -class ObjectInit(ListOp): - opcode = 'OBJECT_INIT' - - def eval(self, ctx): - w_obj = W_Object() - for prop in self.list: - if DEBUG: - print prop.left - name = prop.left.value - w_expr = prop.right.eval(ctx).GetValue() - w_obj.Put(name, w_expr) - return w_obj - -class BinaryNumberOp(BinaryOp): - def eval(self, ctx): - nleft = self.left.eval(ctx).GetValue().ToPrimitive(ctx, 'Number') - nright = self.right.eval(ctx).GetValue().ToPrimitive(ctx, 'Number') - result = self.mathop(ctx, nleft, nright) - if DEBUG: - print self.left, nleft, self.opcode, self.right, nright, '=', result - return result - -class Plus(BinaryNumberOp): - opcode = 'PLUS' - - def mathop(self, ctx, nleft, nright): - if isinstance(nleft, W_String) or isinstance(nright, W_String): - sleft = nleft.ToString() - sright = nright.ToString() - return W_String(sleft + sright) - else: - fleft = nleft.ToNumber() - fright = nright.ToNumber() - return W_Number(fleft + fright) - -class Mult(BinaryNumberOp): - opcode = 'MUL' - - def mathop(self, ctx, nleft, nright): - fleft = nleft.ToNumber() - 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' - - def mathop(self, ctx, nleft, nright): - fleft = nleft.ToNumber() - fright = nright.ToNumber() - return W_Number(fleft / fright) - -class Minus(BinaryNumberOp): - opcode = 'MINUS' - - def mathop(self, ctx, nleft, nright): - fleft = nleft.ToNumber() - fright = nright.ToNumber() - return W_Number(fleft - fright) - - -class Script(Statement): - opcode = 'SCRIPT' - - def from_tree(self, t): - f = get_tree_item(t, 'funDecls') - if f.symbol == "dict": - func_decl = [from_tree(f),] - elif f.symbol == "list": - func_decl = [from_tree(x) for x in f.children] - else: - func_decl = [] - - v = get_tree_item(t, 'varDecls') - if v.symbol == "dict": - var_decl = [from_tree(v),] - elif v.symbol == "list": - var_decl = [from_tree(x) for x in v.children] - else: - var_decl = [] - - self.nodes = get_objects(t) - self.var_decl = var_decl - self.func_decl = func_decl - - def execute(self, ctx): - for var in self.var_decl: - 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 - for node in self.nodes: - last = node.execute(ctx) - return last - except Exception, e: - if isinstance(e, ExecutionReturned) and e.type == 'return': - return e.value - else: - print "exeception in line: %s, on: %s"%(node.lineno, node.value) - raise - -class Semicolon(Statement): - opcode = 'SEMICOLON' - - def from_tree(self, t): - self.expr = get_obj(t, 'expression') - - def execute(self, ctx): - if self.expr is None: - return w_Undefined - return self.expr.execute(ctx) - -class String(Expression): - opcode = 'STRING' - - def from_tree(self, t): - self.strval = get_string(t, 'value') - - def eval(self, ctx): - return W_String(self.strval) - - def get_literal(self): - return W_String(self.strval).ToString() - -class Return(Statement): - opcode = 'RETURN' - - def from_tree(self, t): - self.expr = get_obj(t, 'value') - - def execute(self, ctx): - if isinstance(self.expr, Undefined): - raise ExecutionReturned('return', None, None) - else: - raise ExecutionReturned('return', self.expr.eval(ctx), None) - -class Throw(Statement): - opcode = 'THROW' - - def from_tree(self, t): - self.exception = get_obj(t, 'exception') - - def execute(self, ctx): - raise ThrowException(self.exception.eval(ctx)) - -class Try(Statement): - opcode = 'TRY' - - def from_tree(self, t): - self.tryblock = get_obj(t, 'tryBlock') - self.finallyblock = get_obj(t, 'finallyBlock') - catch = get_tree_item(t, 'catchClauses') - if catch is not None: - #multiple catch clauses is a spidermonkey extension - self.catchblock = get_obj(catch, 'block') - self.catchparam = get_string(catch, 'varName') - else: - self.catchblock = None - self.catchparam = None - - def execute(self, ctx): - e = None - tryresult = w_Undefined - try: - tryresult = self.tryblock.execute(ctx) - except ThrowException, excpt: - e = excpt - if self.catchblock is not None: - obj = W_Object() - obj.Put(self.catchparam, e.exception) - ctx.push_object(obj) - tryresult = self.catchblock.execute(ctx) - ctx.pop_object() - - if self.finallyblock is not None: - tryresult = self.finallyblock.execute(ctx) - - #if there is no catchblock reraise the exception - if (e is not None) and (self.catchblock is None): - raise e - - return tryresult - -class Typeof(UnaryOp): - opcode = 'TYPEOF' - - def eval(self, ctx): - val = self.expr.eval(ctx) - if isinstance(val, W_Reference) and val.GetBase() is None: - return W_String("undefined") - return W_String(val.GetValue().type()) - -class Undefined(Statement): - def execute(self, ctx): - return None - -class Vars(Statement): - opcode = 'VAR' - - def from_tree(self, t): - self.nodes = get_objects(t) - - def execute(self, ctx): - for var in self.nodes: - var.execute(ctx) - -class Void(UnaryOp): - opcode = 'VOID' - - def eval(self, ctx): - self.expr.eval(ctx) - return w_Undefined - -class With(Statement): - opcode = "WITH" - - def from_tree(self, t): - self.object = get_obj(t, 'object') - self.body = get_obj(t, 'body') - - def execute(self, ctx): - obj = self.object.eval(ctx).GetValue().ToObject() - ctx.push_object(obj) - - try: - retval = self.body.execute(ctx) - finally: - ctx.pop_object() - return retval - - -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: - 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' - - def from_tree(self, t): - self.setup = get_obj(t, 'setup') - self.condition = get_obj(t, 'condition') - self.update = get_obj(t, 'update') - self.body = get_obj(t, 'body') - - def execute(self, ctx): - self.setup.eval(ctx).GetValue() - while self.condition.eval(ctx).ToBoolean(): - try: - self.body.execute(ctx) - self.update.eval(ctx) - except ExecutionReturned, e: - if e.type == 'break': - break - elif e.type == 'continue': - self.update.eval(ctx) - continue - -class Boolean(Expression): - def from_tree(self, t): - if self.opcode == 'TRUE': - self.bool = True - else: - self.bool = False - - def eval(self, ctx): - return W_Boolean(self.bool) - -class BTrue(Boolean): - opcode = 'TRUE' - -class BFalse(Boolean): - opcode = 'FALSE' - -class Not(UnaryOp): - opcode = 'NOT' - - def eval(self, ctx): - return W_Boolean(not self.expr.eval(ctx).GetValue().ToBoolean()) - -class UMinus(UnaryOp): - 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) - if isinstance(item, Nonterminal): - return from_tree(item) - else: - return astundef - -def get_string(t, string): - simb = get_tree_item(t, string) - if isinstance(simb, Symbol): - return str(simb.additional_info) - else: - return '' - -def get_objects(t): - item = get_tree_item(t, 'length') - if item is None: - return [] - lgt = int(item.additional_info) - output = [get_obj(t, str(i)) for i in range(lgt)] - return output - -def get_tree_item(t, name): - for x in t.children: - if isinstance(x.children[0], Symbol): - 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): - if i.opcode is not None: - opcodedict[i.opcode] = i - -def from_tree(t): - if t is None: - return None - opcode = get_string(t, 'type') - if opcode in opcodedict: - return opcodedict[opcode](t) - 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 = [] Added: pypy/dist/pypy/lang/js/operations.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/lang/js/operations.py Sat Mar 3 05:41:24 2007 @@ -0,0 +1,1071 @@ +# encoding: utf-8 +""" +operations.py +Implements the javascript operations nodes for the interpretation tree +""" + +from pypy.lang.js.jsobj import * +from pypy.rlib.parsing.ebnfparse import Symbol, Nonterminal + + +class Node(object): + """ + Node is the base class for all the other nodes, the opcode parameter + is used to match the AST operation to the efective execution node. + """ + opcode = None + def __init__(self, t=None, type='', value='', lineno=0, start=0, end=0): + """ + Not to be overriden by subclasses, this method thakes the basic node + information from the AST needed for tracing and debuging. if you want + to override behavior for the creation of a node do it on the from_tree + call. + """ + if t is None: + self.type = type + self.value = value + self.lineno = lineno + self.start = start + self.end = end + else: + self.type = get_string(t, 'type') + self.value = get_string(t, 'value') + self.lineno = int(get_string(t, 'lineno')) + + try: + self.start = int(get_string(t, 'start')) + except ValueError, e: + self.start = 0 + try: + self.end = int(get_string(t, 'end')) + except Exception, e: + self.end = 0 + self.from_tree(t) + + def from_tree(t): + """ + Initializes the content from the AST specific for each node type + """ + raise NotImplementedError + + def eval(self, ctx): + """ + Used for expression evaluation + """ + if DEBUG: + print self + raise NotImplementedError + + def execute(self, ctx): + """ + Called on statament execution + """ + raise NotImplementedError + + def get_literal(self): + raise NotImplementedError + + def get_args(self, ctx): + raise NotImplementedError + + def __str__(self): + return ""%(self.opcode, self.value) + +class Statement(Node): + pass + +class Expression(Statement): + def eval(self, ctx): + return W_Root() + + def execute(self, ctx): + return self.eval(ctx) + +class ListOp(Expression): + def from_tree(self, t): + self.list = get_objects(t) + +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): + self.left = get_obj(t,'0') + self.right = get_obj(t, '1') + +class BinaryComparisonOp(BinaryOp): + def eval(self, ctx): + s2 = self.left.eval(ctx).GetValue() + s4 = self.right.eval(ctx).GetValue() + if DEBUG: + print "bincomp, op1 and op2 ", s2, s4 + return self.decision(ctx, s2, s4) + + 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 + +class PropertyInit(BinaryOp): + opcode = 'PROPERTY_INIT' + +class Array(ListOp): + opcode = 'ARRAY_INIT' + + def eval(self, ctx): + #d = dict(enumerate(self.items)) + array = W_Array() + for i in range(len(self.list)): + array.Put(str(i), self.list[i].eval(ctx).GetValue()) + return array + + +class Assign(BinaryOp): + opcode = 'ASSIGN' + + def eval(self, ctx): + v1 = self.left.eval(ctx) + v3 = self.right.eval(ctx).GetValue() + op = self.value + if op == "=": + val = v3 + elif op == "*": + val = Mult().mathop(ctx, v1.GetValue(), v3) + elif op == "+": + 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() + + v1.PutValue(val, ctx) + return val + +class Block(Statement): + opcode = 'BLOCK' + + def from_tree(self, t): + self.nodes = get_objects(t) + + def execute(self, ctx): + try: + last = w_Undefined + for node in self.nodes: + last = node.execute(ctx) + return last + except ExecutionReturned, e: + if e.type == 'return': + return e.value + 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(',') + self.targtype = pieces[0] + self.targlineno = pieces[1] + self.targstart = pieces[2] + +class Break(Unconditional): + opcode = 'BREAK' + + def execute(self, ctx): + raise ExecutionReturned('break', None, None) + +class Continue(Unconditional): + opcode = 'CONTINUE' + + def execute(self, ctx): + raise ExecutionReturned('continue', None, None) + +class Call(BinaryOp): + opcode = 'CALL' + + def eval(self, ctx): + if DEBUG: + print "calling", self.left, self.right + r1 = self.left.eval(ctx) + r2 = self.right.eval(ctx) + r3 = r1.GetValue() + if isinstance(r1, W_Reference): + r6 = r1.GetBase() + else: + r6 = None + if isinstance(r2, ActivationObject): + r7 = None + else: + r7 = r6 + + retval = r3.Call(ctx=ctx, args=r2.get_args(), this=r7) + return retval + +class Comma(BinaryOp): + opcode = 'COMMA' + + def eval(self, ctx): + self.left.eval(ctx) + return self.right.eval(ctx) + +class Conditional(Expression): + opcode = 'CONDITIONAL' + + def from_tree(self, t): + self.logicalexpr = get_obj(t, '0') + self.trueop = get_obj(t, '1') + self.falseop = get_obj(t, '2') + + def eval(self, ctx): + if self.logicalexpr.eval(ctx).GetValue().ToBoolean(): + return self.trueop.eval(ctx).GetValue() + else: + return self.falseop.eval(ctx).GetValue() + +class Dot(BinaryOp): + opcode = 'DOT' + + def eval(self, ctx): + w_obj = self.left.eval(ctx).GetValue().ToObject() + name = self.right.eval(ctx).GetPropertyName() + return W_Reference(name, w_obj) + +class Function(Expression): + opcode = 'FUNCTION' + + def from_tree(self, t): + self.name = get_string(t, 'name') + self.body = get_obj(t, 'body') + params = get_string(t, 'params') + if params == '': + self.params = [] + else: + self.params = params.split(',') + + def eval(self, ctx): + w_obj = W_Object(ctx=ctx, callfunc = self) + return w_obj + +class Identifier(Expression): + opcode = 'IDENTIFIER' + + def from_tree(self, t): + self.name = get_string(t,'value') + self.initializer = get_obj(t, 'initializer') + + def __str__(self): + return ""%(str(self.name), str(self.initializer)) + + def eval(self, ctx): + if self.initializer is not astundef: + ref = ctx.resolve_identifier(self.name) + ref.PutValue(self.initializer.eval(ctx).GetValue(), ctx) + return ctx.resolve_identifier(self.name) + + def get_literal(self): + return self.name + +class This(Identifier): + opcode = "THIS" + +class If(Statement): + opcode = 'IF' + + def from_tree(self, t): + self.condition = get_obj(t, 'condition') + self.thenPart = get_obj(t, 'thenPart') + self.elsePart = get_obj(t, 'elsePart') + + def execute(self, ctx): + temp = self.condition.eval(ctx).GetValue() + if temp.ToBoolean(): + return self.thenPart.execute(ctx) + else: + return self.elsePart.execute(ctx) + +class Group(UnaryOp): + opcode = 'GROUP' + + def eval(self, ctx): + return self.expr.eval(ctx) + +def ARC(ctx, x, y): + """ + Implements the Abstract Relational Comparison x < y + Still not fully to the spec + """ + # TODO complete the funcion with strings comparison + s1 = x.ToPrimitive(ctx, 'Number') + s2 = y.ToPrimitive(ctx, 'Number') + if not (isinstance(s1, W_String) and isinstance(s2, W_String)): + s4 = s1.ToNumber() + s5 = s2.ToNumber() + if s4 == NaN or s5 == NaN: + return -1 + if s4 < s5: + return 1 + else: + return 0 + else: + return -1 + +class Or(BinaryLogicOp): + opcode = 'OR' + + def eval(self, ctx): + s2 = self.left.eval(ctx).GetValue() + if s2.ToBoolean(): + return s2 + s4 = self.right.eval(ctx).GetValue() + return s4 + +class And(BinaryLogicOp): + opcode = 'AND' + + def eval(self, ctx): + s2 = self.left.eval(ctx).GetValue() + if not s2.ToBoolean(): + return s2 + s4 = self.right.eval(ctx).GetValue() + return s4 + +class Ursh(BinaryComparisonOp): + opcode = 'URSH' + + def decision(self, ctx, op1, op2): + a = op1.ToUInt32() + b = op2.ToUInt32() + return W_Number(a >> (b & 0x1F)) + +class Rsh(BinaryComparisonOp): + opcode = 'RSH' + + def decision(self, ctx, op1, op2): + a = op1.ToInt32() + b = op2.ToUInt32() + return W_Number(a >> int(b & 0x1F)) + +class Lsh(BinaryComparisonOp): + opcode = 'LSH' + + def decision(self, ctx, op1, op2): + a = op1.ToInt32() + b = op2.ToUInt32() + return W_Number(a << int(b & 0x1F)) + +class Ge(BinaryComparisonOp): + opcode = 'GE' + + def decision(self, ctx, op1, op2): + s5 = ARC(ctx, op1, op2) + if DEBUG: + print ">= ARC result:", s5 + if s5 in (-1, 1): + return W_Boolean(False) + else: + return W_Boolean(True) + +class Gt(BinaryComparisonOp): + opcode = 'GT' + + def decision(self, ctx, op1, op2): + s5 = ARC(ctx, op2, op1) + if DEBUG: + print "> ARC result:", s5 + if s5 == -1: + return W_Boolean(False) + else: + return W_Boolean(s5) + +class Le(BinaryComparisonOp): + opcode = 'LE' + + def decision(self, ctx, op1, op2): + s5 = ARC(ctx, op2, op1) + if s5 in (-1, 1): + return W_Boolean(False) + else: + return W_Boolean(True) + +class Lt(BinaryComparisonOp): + opcode = 'LT' + + def decision(self, ctx, op1, op2): + s5 = ARC(ctx, op1, op2) + if s5 == -1: + return W_Boolean(False) + else: + return W_Boolean(s5) + +def AEC(x, y): + """ + Implements the Abstract Equality Comparison x == y + trying to be fully to the spec + """ + type1 = x.type() + type2 = y.type() + if type1 == type2: + if type1 == "undefined" or type1 == "null": + return True + if type1 == "number": + n1 = x.ToNumber() + n2 = y.ToNumber() + nan_string = str(NaN) + if str(n1) == nan_string or str(n2) == nan_string: + return False + if n1 == n2: + return True + return False + elif type1 == "string": + return x.ToString() == y.ToString() + elif type1 == "boolean": + return x.ToBoolean() == x.ToBoolean() + return x == y + else: + #step 14 + if (type1 == "undefined" and type2 == "null") or \ + (type1 == "null" and type2 == "undefined"): + return True + if type1 == "number" and type2 == "string": + return AEC(x, W_Number(y.ToNumber())) + if type1 == "string" and type2 == "number": + return AEC(W_Number(x.ToNumber()), y) + if type1 == "boolean": + return AEC(W_Number(x.ToNumber()), y) + if type2 == "boolean": + return AEC(x, W_Number(y.ToNumber())) + if (type1 == "string" or type1 == "number") and \ + type2 == "object": + return AEC(x, y.ToPrimitive()) + if (type2 == "string" or type2 == "number") and \ + type1 == "object": + return AEC(x.ToPrimitive(), y) + return False + + + objtype = x.GetValue().type() + if objtype == y.GetValue().type(): + if objtype == "undefined" or objtype == "null": + return True + + if isinstance(x, W_String) and isinstance(y, W_String): + r = x.ToString() == y.ToString() + else: + r = x.ToNumber() == y.ToNumber() + return r + +class Eq(BinaryComparisonOp): + opcode = 'EQ' + + def decision(self, ctx, op1, op2): + return W_Boolean(AEC(op1, op2)) + +class Ne(BinaryComparisonOp): + opcode = 'NE' + + def decision(self, ctx, op1, op2): + return W_Boolean(not AEC(op1, op2)) + +def SEC(x,y): + """ + Implements the Strict Equality Comparison x === y + trying to be fully to the spec + """ + type1 = x.type() + type2 = y.type() + if type1 != type2: + return False + if type1 == "undefined" or type1 == "null": + return True + if type1 == "number": + n1 = x.ToNumber() + n2 = y.ToNumber() + nan_string = str(NaN) + if str(n1) == nan_string or str(n2) == nan_string: + return False + if n1 == n2: + return True + return False + if type1 == "string": + return x.ToString() == y.ToString() + if type1 == "boolean": + return x.ToBoolean() == x.ToBoolean() + return x == y + +class StrictEq(BinaryComparisonOp): + opcode = 'STRICT_EQ' + + def decision(self, ctx, op1, op2): + return W_Boolean(SEC(op1, op2)) + +class StrictNe(BinaryComparisonOp): + opcode = 'STRICT_NE' + + def decision(self, ctx, op1, op2): + return W_Boolean(not SEC(op1, op2)) + + +class In(BinaryComparisonOp): + opcode = 'IN' + + def decision(self, ctx, op1, op2): + if not isinstance(op2, W_Object): + raise ThrowException(W_String("TypeError")) + 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' + + 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 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' + + def eval(self, ctx): + w_obj = self.left.eval(ctx).GetValue().ToObject() + name= self.right.eval(ctx).GetValue().ToString() + return W_Reference(name, w_obj) + +class List(ListOp): + opcode = 'LIST' + + def eval(self, ctx): + return W_List([node.eval(ctx).GetValue() for node in self.list]) + +class Minus(BinaryComparisonOp): + opcode = 'MINUS' + + def decision(self, ctx, op1, op2): + x = op1.ToNumber() + y = op2.ToNumber() + return W_Number(x - y) + +class New(UnaryOp): + opcode = 'NEW' + + def eval(self, ctx): + x = self.expr.eval(ctx).GetValue() + if not isinstance(x, W_PrimitiveObject): + raise TypeError() + + return x.Construct(ctx=ctx) + +class NewWithArgs(BinaryOp): + opcode = 'NEW_WITH_ARGS' + + def eval(self, ctx): + x = self.left.eval(ctx).GetValue() + if not isinstance(x, W_PrimitiveObject): + raise TypeError() + args = self.right.eval(ctx).get_args() + return x.Construct(ctx=ctx, args=args) + +class Null(Expression): + opcode = 'NULL' + + def from_tree(self, t): + pass + + def eval(self, ctx): + return w_Null + +class Number(Expression): + opcode = 'NUMBER' + + def from_tree(self, t): + self.num = float(get_string(t, 'value')) + + def eval(self, ctx): + return W_Number(self.num) + +class ObjectInit(ListOp): + opcode = 'OBJECT_INIT' + + def eval(self, ctx): + w_obj = W_Object() + for prop in self.list: + if DEBUG: + print prop.left + name = prop.left.value + w_expr = prop.right.eval(ctx).GetValue() + w_obj.Put(name, w_expr) + return w_obj + +class BinaryNumberOp(BinaryOp): + def eval(self, ctx): + nleft = self.left.eval(ctx).GetValue().ToPrimitive(ctx, 'Number') + nright = self.right.eval(ctx).GetValue().ToPrimitive(ctx, 'Number') + result = self.mathop(ctx, nleft, nright) + if DEBUG: + print self.left, nleft, self.opcode, self.right, nright, '=', result + return result + +class Plus(BinaryNumberOp): + opcode = 'PLUS' + + def mathop(self, ctx, nleft, nright): + if isinstance(nleft, W_String) or isinstance(nright, W_String): + sleft = nleft.ToString() + sright = nright.ToString() + return W_String(sleft + sright) + else: + fleft = nleft.ToNumber() + fright = nright.ToNumber() + return W_Number(fleft + fright) + +class Mult(BinaryNumberOp): + opcode = 'MUL' + + def mathop(self, ctx, nleft, nright): + fleft = nleft.ToNumber() + 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' + + def mathop(self, ctx, nleft, nright): + fleft = nleft.ToNumber() + fright = nright.ToNumber() + return W_Number(fleft / fright) + +class Minus(BinaryNumberOp): + opcode = 'MINUS' + + def mathop(self, ctx, nleft, nright): + fleft = nleft.ToNumber() + fright = nright.ToNumber() + return W_Number(fleft - fright) + + +class Script(Statement): + opcode = 'SCRIPT' + + def from_tree(self, t): + f = get_tree_item(t, 'funDecls') + if f.symbol == "dict": + func_decl = [from_tree(f),] + elif f.symbol == "list": + func_decl = [from_tree(x) for x in f.children] + else: + func_decl = [] + + v = get_tree_item(t, 'varDecls') + if v.symbol == "dict": + var_decl = [from_tree(v),] + elif v.symbol == "list": + var_decl = [from_tree(x) for x in v.children] + else: + var_decl = [] + + self.nodes = get_objects(t) + self.var_decl = var_decl + self.func_decl = func_decl + + def execute(self, ctx): + for var in self.var_decl: + 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 + for node in self.nodes: + last = node.execute(ctx) + return last + except Exception, e: + if isinstance(e, ExecutionReturned) and e.type == 'return': + return e.value + else: + print "exeception in line: %s, on: %s"%(node.lineno, node.value) + raise + +class Semicolon(Statement): + opcode = 'SEMICOLON' + + def from_tree(self, t): + self.expr = get_obj(t, 'expression') + + def execute(self, ctx): + if self.expr is None: + return w_Undefined + return self.expr.execute(ctx) + +class String(Expression): + opcode = 'STRING' + + def from_tree(self, t): + self.strval = get_string(t, 'value') + + def eval(self, ctx): + return W_String(self.strval) + + def get_literal(self): + return W_String(self.strval).ToString() + +class Return(Statement): + opcode = 'RETURN' + + def from_tree(self, t): + self.expr = get_obj(t, 'value') + + def execute(self, ctx): + if isinstance(self.expr, Undefined): + raise ExecutionReturned('return', None, None) + else: + raise ExecutionReturned('return', self.expr.eval(ctx), None) + +class Throw(Statement): + opcode = 'THROW' + + def from_tree(self, t): + self.exception = get_obj(t, 'exception') + + def execute(self, ctx): + raise ThrowException(self.exception.eval(ctx)) + +class Try(Statement): + opcode = 'TRY' + + def from_tree(self, t): + self.tryblock = get_obj(t, 'tryBlock') + self.finallyblock = get_obj(t, 'finallyBlock') + catch = get_tree_item(t, 'catchClauses') + if catch is not None: + #multiple catch clauses is a spidermonkey extension + self.catchblock = get_obj(catch, 'block') + self.catchparam = get_string(catch, 'varName') + else: + self.catchblock = None + self.catchparam = None + + def execute(self, ctx): + e = None + tryresult = w_Undefined + try: + tryresult = self.tryblock.execute(ctx) + except ThrowException, excpt: + e = excpt + if self.catchblock is not None: + obj = W_Object() + obj.Put(self.catchparam, e.exception) + ctx.push_object(obj) + tryresult = self.catchblock.execute(ctx) + ctx.pop_object() + + if self.finallyblock is not None: + tryresult = self.finallyblock.execute(ctx) + + #if there is no catchblock reraise the exception + if (e is not None) and (self.catchblock is None): + raise e + + return tryresult + +class Typeof(UnaryOp): + opcode = 'TYPEOF' + + def eval(self, ctx): + val = self.expr.eval(ctx) + if isinstance(val, W_Reference) and val.GetBase() is None: + return W_String("undefined") + return W_String(val.GetValue().type()) + +class Undefined(Statement): + def execute(self, ctx): + return None + +class Vars(Statement): + opcode = 'VAR' + + def from_tree(self, t): + self.nodes = get_objects(t) + + def execute(self, ctx): + for var in self.nodes: + var.execute(ctx) + +class Void(UnaryOp): + opcode = 'VOID' + + def eval(self, ctx): + self.expr.eval(ctx) + return w_Undefined + +class With(Statement): + opcode = "WITH" + + def from_tree(self, t): + self.object = get_obj(t, 'object') + self.body = get_obj(t, 'body') + + def execute(self, ctx): + obj = self.object.eval(ctx).GetValue().ToObject() + ctx.push_object(obj) + + try: + retval = self.body.execute(ctx) + finally: + ctx.pop_object() + return retval + + +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: + 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' + + def from_tree(self, t): + self.setup = get_obj(t, 'setup') + self.condition = get_obj(t, 'condition') + self.update = get_obj(t, 'update') + self.body = get_obj(t, 'body') + + def execute(self, ctx): + self.setup.eval(ctx).GetValue() + while self.condition.eval(ctx).ToBoolean(): + try: + self.body.execute(ctx) + self.update.eval(ctx) + except ExecutionReturned, e: + if e.type == 'break': + break + elif e.type == 'continue': + self.update.eval(ctx) + continue + +class Boolean(Expression): + def from_tree(self, t): + if self.opcode == 'TRUE': + self.bool = True + else: + self.bool = False + + def eval(self, ctx): + return W_Boolean(self.bool) + +class BTrue(Boolean): + opcode = 'TRUE' + +class BFalse(Boolean): + opcode = 'FALSE' + +class Not(UnaryOp): + opcode = 'NOT' + + def eval(self, ctx): + return W_Boolean(not self.expr.eval(ctx).GetValue().ToBoolean()) + +class UMinus(UnaryOp): + 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) + if isinstance(item, Nonterminal): + return from_tree(item) + else: + return astundef + +def get_string(t, string): + simb = get_tree_item(t, string) + if isinstance(simb, Symbol): + return str(simb.additional_info) + else: + return '' + +def get_objects(t): + item = get_tree_item(t, 'length') + if item is None: + return [] + lgt = int(item.additional_info) + output = [get_obj(t, str(i)) for i in range(lgt)] + return output + +def get_tree_item(t, name): + for x in t.children: + if isinstance(x.children[0], Symbol): + 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): + if i.opcode is not None: + opcodedict[i.opcode] = i + +def from_tree(t): + if t is None: + return None + opcode = get_string(t, 'type') + if opcode in opcodedict: + return opcodedict[opcode](t) + else: + raise NotImplementedError("Dont know how to handle %s" % opcode) From arigo at codespeak.net Sat Mar 3 08:57:19 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 3 Mar 2007 08:57:19 +0100 (CET) Subject: [pypy-svn] r39758 - pypy/branch/rope-branch/pypy/objspace/std Message-ID: <20070303075719.8225E10061@code0.codespeak.net> Author: arigo Date: Sat Mar 3 08:57:17 2007 New Revision: 39758 Modified: pypy/branch/rope-branch/pypy/objspace/std/rope.py Log: * translation fixes * remove tabs Modified: pypy/branch/rope-branch/pypy/objspace/std/rope.py ============================================================================== --- pypy/branch/rope-branch/pypy/objspace/std/rope.py (original) +++ pypy/branch/rope-branch/pypy/objspace/std/rope.py Sat Mar 3 08:57:17 2007 @@ -73,6 +73,7 @@ return self.s[index] def getitem_slice(self, start, stop): + assert 0 <= start <= stop return LiteralStringNode(self.s[start:stop]) def dot(self, seen, toplevel=False): @@ -90,7 +91,7 @@ class BinaryConcatNode(StringNode): def __init__(self, left, right): self.left = left - self.right = right + self.right = right self.len = left.length() + right.length() self._depth = max(left.depth(), right.depth()) + 1 self.balanced = False @@ -150,9 +151,10 @@ class SliceNode(StringNode): def __init__(self, start, stop, node): + assert 0 <= start <= stop self.start = start - self.stop = stop - self.node = node + self.stop = stop + self.node = node def length(self): return self.stop - self.start @@ -385,6 +387,7 @@ offset = start - newstart start = newstart stop = newstop + assert 0 <= start <= stop if isinstance(node, LiteralStringNode): result = node.s.find(c, start, stop) if result == -1: @@ -537,7 +540,7 @@ class FringeIterator(object): def __init__(self, node): self.stack = [node] - + def next(self): while self.stack: curr = self.stack.pop() @@ -563,7 +566,7 @@ self.stack = [node] self.fringestack = [] self.fringe = [] - + def next(self): if self.fringestack: result = self.fringestack.pop() From mwh at codespeak.net Sat Mar 3 09:49:02 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Sat, 3 Mar 2007 09:49:02 +0100 (CET) Subject: [pypy-svn] r39759 - in pypy/dist/pypy: jit/codegen/ppc jit/codegen/ppc/ppcgen jit/codegen/ppc/ppcgen/test translator/asm Message-ID: <20070303084902.463E110069@code0.codespeak.net> Author: mwh Date: Sat Mar 3 09:48:59 2007 New Revision: 39759 Added: pypy/dist/pypy/jit/codegen/ppc/ppcgen/ - copied from r39758, pypy/dist/pypy/translator/asm/ppcgen/ Removed: pypy/dist/pypy/translator/asm/ Modified: pypy/dist/pypy/jit/codegen/ppc/ppcgen/assembler.py pypy/dist/pypy/jit/codegen/ppc/ppcgen/func_builder.py pypy/dist/pypy/jit/codegen/ppc/ppcgen/ppc_assembler.py pypy/dist/pypy/jit/codegen/ppc/ppcgen/ppc_field.py pypy/dist/pypy/jit/codegen/ppc/ppcgen/ppc_form.py pypy/dist/pypy/jit/codegen/ppc/ppcgen/rassemblermaker.py pypy/dist/pypy/jit/codegen/ppc/ppcgen/test/test_field.py pypy/dist/pypy/jit/codegen/ppc/ppcgen/test/test_form.py pypy/dist/pypy/jit/codegen/ppc/ppcgen/test/test_func_builder.py pypy/dist/pypy/jit/codegen/ppc/ppcgen/test/test_ppc.py pypy/dist/pypy/jit/codegen/ppc/ppcgen/test/test_rassemblermaker.py pypy/dist/pypy/jit/codegen/ppc/ppcgen/util.py pypy/dist/pypy/jit/codegen/ppc/rgenop.py Log: finally, move the ppc generation code into the jit/codegen/ppc directory and kill translator/asm. paris really was a long time ago. Modified: pypy/dist/pypy/jit/codegen/ppc/ppcgen/assembler.py ============================================================================== --- pypy/dist/pypy/translator/asm/ppcgen/assembler.py (original) +++ pypy/dist/pypy/jit/codegen/ppc/ppcgen/assembler.py Sat Mar 3 09:48:59 2007 @@ -1,5 +1,5 @@ import os -from pypy.translator.asm.ppcgen import form +from pypy.jit.codegen.ppc.ppcgen import form # don't be fooled by the fact that there's some separation between a # generic assembler class and a PPC assembler class... there's @@ -47,7 +47,7 @@ def assemble(self, dump=os.environ.has_key('PPY_DEBUG')): insns = self.assemble0(dump) - from pypy.translator.asm.ppcgen import asmfunc + from pypy.jit.codegen.ppc.ppcgen import asmfunc c = asmfunc.AsmCode(len(insns)*4) for i in insns: c.emit(i) Modified: pypy/dist/pypy/jit/codegen/ppc/ppcgen/func_builder.py ============================================================================== --- pypy/dist/pypy/translator/asm/ppcgen/func_builder.py (original) +++ pypy/dist/pypy/jit/codegen/ppc/ppcgen/func_builder.py Sat Mar 3 09:48:59 2007 @@ -1,6 +1,6 @@ -from pypy.translator.asm.ppcgen.ppc_assembler import MyPPCAssembler -from pypy.translator.asm.ppcgen.symbol_lookup import lookup -from pypy.translator.asm.ppcgen.regname import * +from pypy.jit.codegen.ppc.ppcgen.ppc_assembler import MyPPCAssembler +from pypy.jit.codegen.ppc.ppcgen.symbol_lookup import lookup +from pypy.jit.codegen.ppc.ppcgen.regname import * def load_arg(code, argi, typecode): rD = r3+argi Modified: pypy/dist/pypy/jit/codegen/ppc/ppcgen/ppc_assembler.py ============================================================================== --- pypy/dist/pypy/translator/asm/ppcgen/ppc_assembler.py (original) +++ pypy/dist/pypy/jit/codegen/ppc/ppcgen/ppc_assembler.py Sat Mar 3 09:48:59 2007 @@ -1,7 +1,7 @@ -from pypy.translator.asm.ppcgen.ppc_form import PPCForm as Form -from pypy.translator.asm.ppcgen.ppc_field import ppc_fields -from pypy.translator.asm.ppcgen.assembler import Assembler -from pypy.translator.asm.ppcgen.symbol_lookup import lookup +from pypy.jit.codegen.ppc.ppcgen.ppc_form import PPCForm as Form +from pypy.jit.codegen.ppc.ppcgen.ppc_field import ppc_fields +from pypy.jit.codegen.ppc.ppcgen.assembler import Assembler +from pypy.jit.codegen.ppc.ppcgen.symbol_lookup import lookup A = Form("frD", "frA", "frB", "XO3", "Rc") A1 = Form("frD", "frB", "XO3", "Rc") @@ -808,7 +808,7 @@ r.reverse() return ''.join(map(str, r)) -from pypy.translator.asm.ppcgen.regname import * +from pypy.jit.codegen.ppc.ppcgen.regname import * def main(): Modified: pypy/dist/pypy/jit/codegen/ppc/ppcgen/ppc_field.py ============================================================================== --- pypy/dist/pypy/translator/asm/ppcgen/ppc_field.py (original) +++ pypy/dist/pypy/jit/codegen/ppc/ppcgen/ppc_field.py Sat Mar 3 09:48:59 2007 @@ -1,5 +1,5 @@ -from pypy.translator.asm.ppcgen.field import Field -from pypy.translator.asm.ppcgen import regname +from pypy.jit.codegen.ppc.ppcgen.field import Field +from pypy.jit.codegen.ppc.ppcgen import regname fields = { # bit margins are *inclusive*! (and bit 0 is # most-significant, 31 least significant) Modified: pypy/dist/pypy/jit/codegen/ppc/ppcgen/ppc_form.py ============================================================================== --- pypy/dist/pypy/translator/asm/ppcgen/ppc_form.py (original) +++ pypy/dist/pypy/jit/codegen/ppc/ppcgen/ppc_form.py Sat Mar 3 09:48:59 2007 @@ -1,5 +1,5 @@ -from pypy.translator.asm.ppcgen.form import Form -from pypy.translator.asm.ppcgen.ppc_field import ppc_fields +from pypy.jit.codegen.ppc.ppcgen.form import Form +from pypy.jit.codegen.ppc.ppcgen.ppc_field import ppc_fields class PPCForm(Form): fieldmap = ppc_fields Modified: pypy/dist/pypy/jit/codegen/ppc/ppcgen/rassemblermaker.py ============================================================================== --- pypy/dist/pypy/translator/asm/ppcgen/rassemblermaker.py (original) +++ pypy/dist/pypy/jit/codegen/ppc/ppcgen/rassemblermaker.py Sat Mar 3 09:48:59 2007 @@ -1,6 +1,6 @@ from pypy.tool.sourcetools import compile2 from pypy.rlib.rarithmetic import r_uint -from pypy.translator.asm.ppcgen.form import IDesc, IDupDesc +from pypy.jit.codegen.ppc.ppcgen.form import IDesc, IDupDesc ## "opcode": ( 0, 5), ## "rA": (11, 15, 'unsigned', regname._R), Modified: pypy/dist/pypy/jit/codegen/ppc/ppcgen/test/test_field.py ============================================================================== --- pypy/dist/pypy/translator/asm/ppcgen/test/test_field.py (original) +++ pypy/dist/pypy/jit/codegen/ppc/ppcgen/test/test_field.py Sat Mar 3 09:48:59 2007 @@ -1,6 +1,6 @@ import autopath -from pypy.translator.asm.ppcgen.field import Field +from pypy.jit.codegen.ppc.ppcgen.field import Field from py.test import raises import random Modified: pypy/dist/pypy/jit/codegen/ppc/ppcgen/test/test_form.py ============================================================================== --- pypy/dist/pypy/translator/asm/ppcgen/test/test_form.py (original) +++ pypy/dist/pypy/jit/codegen/ppc/ppcgen/test/test_form.py Sat Mar 3 09:48:59 2007 @@ -1,11 +1,11 @@ import autopath -from pypy.translator.asm.ppcgen.ppc_assembler import b +from pypy.jit.codegen.ppc.ppcgen.ppc_assembler import b import random import sys -from pypy.translator.asm.ppcgen.form import Form, FormException -from pypy.translator.asm.ppcgen.field import Field -from pypy.translator.asm.ppcgen.assembler import Assembler +from pypy.jit.codegen.ppc.ppcgen.form import Form, FormException +from pypy.jit.codegen.ppc.ppcgen.field import Field +from pypy.jit.codegen.ppc.ppcgen.assembler import Assembler # 0 31 # +-------------------------------+ Modified: pypy/dist/pypy/jit/codegen/ppc/ppcgen/test/test_func_builder.py ============================================================================== --- pypy/dist/pypy/translator/asm/ppcgen/test/test_func_builder.py (original) +++ pypy/dist/pypy/jit/codegen/ppc/ppcgen/test/test_func_builder.py Sat Mar 3 09:48:59 2007 @@ -1,11 +1,11 @@ import py import random, sys, os -from pypy.translator.asm.ppcgen.ppc_assembler import MyPPCAssembler -from pypy.translator.asm.ppcgen.symbol_lookup import lookup -from pypy.translator.asm.ppcgen.func_builder import make_func -from pypy.translator.asm.ppcgen import form, func_builder -from pypy.translator.asm.ppcgen.regname import * +from pypy.jit.codegen.ppc.ppcgen.ppc_assembler import MyPPCAssembler +from pypy.jit.codegen.ppc.ppcgen.symbol_lookup import lookup +from pypy.jit.codegen.ppc.ppcgen.func_builder import make_func +from pypy.jit.codegen.ppc.ppcgen import form, func_builder +from pypy.jit.codegen.ppc.ppcgen.regname import * class TestFuncBuilderTest(object): def setup_class(cls): @@ -78,7 +78,7 @@ f = make_func(a, "O", "O") assert f(1) == 1 b = MyPPCAssembler() - from pypy.translator.asm.ppcgen import util + from pypy.jit.codegen.ppc.ppcgen import util # eurgh!: b.load_word(r0, util.access_at(id(f.code), 8) + f.FAST_ENTRY_LABEL) b.mtctr(r0) Modified: pypy/dist/pypy/jit/codegen/ppc/ppcgen/test/test_ppc.py ============================================================================== --- pypy/dist/pypy/translator/asm/ppcgen/test/test_ppc.py (original) +++ pypy/dist/pypy/jit/codegen/ppc/ppcgen/test/test_ppc.py Sat Mar 3 09:48:59 2007 @@ -1,10 +1,10 @@ import py import random, sys, os -from pypy.translator.asm.ppcgen.ppc_assembler import BasicPPCAssembler, MyPPCAssembler -from pypy.translator.asm.ppcgen.symbol_lookup import lookup -from pypy.translator.asm.ppcgen.regname import * -from pypy.translator.asm.ppcgen import form, pystructs +from pypy.jit.codegen.ppc.ppcgen.ppc_assembler import BasicPPCAssembler, MyPPCAssembler +from pypy.jit.codegen.ppc.ppcgen.symbol_lookup import lookup +from pypy.jit.codegen.ppc.ppcgen.regname import * +from pypy.jit.codegen.ppc.ppcgen import form, pystructs class TestDisassemble(object): Modified: pypy/dist/pypy/jit/codegen/ppc/ppcgen/test/test_rassemblermaker.py ============================================================================== --- pypy/dist/pypy/translator/asm/ppcgen/test/test_rassemblermaker.py (original) +++ pypy/dist/pypy/jit/codegen/ppc/ppcgen/test/test_rassemblermaker.py Sat Mar 3 09:48:59 2007 @@ -1,5 +1,5 @@ -from pypy.translator.asm.ppcgen.rassemblermaker import make_rassembler -from pypy.translator.asm.ppcgen.ppc_assembler import PPCAssembler +from pypy.jit.codegen.ppc.ppcgen.rassemblermaker import make_rassembler +from pypy.jit.codegen.ppc.ppcgen.ppc_assembler import PPCAssembler RPPCAssembler = make_rassembler(PPCAssembler) Modified: pypy/dist/pypy/jit/codegen/ppc/ppcgen/util.py ============================================================================== --- pypy/dist/pypy/translator/asm/ppcgen/util.py (original) +++ pypy/dist/pypy/jit/codegen/ppc/ppcgen/util.py Sat Mar 3 09:48:59 2007 @@ -1,5 +1,5 @@ -from pypy.translator.asm.ppcgen.ppc_assembler import MyPPCAssembler -from pypy.translator.asm.ppcgen.func_builder import make_func +from pypy.jit.codegen.ppc.ppcgen.ppc_assembler import MyPPCAssembler +from pypy.jit.codegen.ppc.ppcgen.func_builder import make_func from regname import * 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 Sat Mar 3 09:48:59 2007 @@ -14,8 +14,8 @@ from pypy.jit.codegen.ppc.regalloc import RegisterAllocation 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 +from pypy.jit.codegen.ppc.ppcgen.rassemblermaker import make_rassembler +from pypy.jit.codegen.ppc.ppcgen.ppc_assembler import MyPPCAssembler from pypy.jit.codegen.i386.rgenop import gc_malloc_fnaddr @@ -1246,7 +1246,7 @@ return self.MachineCodeBlock(65536) # XXX supposed infinite for now def close_mc(self, mc): -## from pypy.translator.asm.ppcgen.asmfunc import get_ppcgen +## from pypy.jit.codegen.ppc.ppcgen.asmfunc import get_ppcgen ## print '!!!!', cast(mc._data, c_void_p).value ## print '!!!!', mc._data.contents[0] ## get_ppcgen().flush2(cast(mc._data, c_void_p).value, From arigo at codespeak.net Sat Mar 3 10:03:17 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 3 Mar 2007 10:03:17 +0100 (CET) Subject: [pypy-svn] r39760 - pypy/dist/pypy/doc/config Message-ID: <20070303090317.67FE510060@code0.codespeak.net> Author: arigo Date: Sat Mar 3 10:03:14 2007 New Revision: 39760 Added: pypy/dist/pypy/doc/config/objspace.std.withchunklist.txt (contents, props changed) Log: Minimal doc. Added: pypy/dist/pypy/doc/config/objspace.std.withchunklist.txt ============================================================================== --- (empty file) +++ pypy/dist/pypy/doc/config/objspace.std.withchunklist.txt Sat Mar 3 10:03:14 2007 @@ -0,0 +1 @@ +Implement lists by grouping elements by fixed-size chunks. From arigo at codespeak.net Sat Mar 3 10:05:51 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 3 Mar 2007 10:05:51 +0100 (CET) Subject: [pypy-svn] r39761 - in pypy/dist/pypy: config doc/config objspace/std objspace/std/test Message-ID: <20070303090551.08B2110060@code0.codespeak.net> Author: arigo Date: Sat Mar 3 10:05:48 2007 New Revision: 39761 Added: pypy/dist/pypy/doc/config/objspace.std.withbucketdict.txt (contents, props changed) pypy/dist/pypy/objspace/std/dictbucket.py (contents, props changed) pypy/dist/pypy/objspace/std/test/test_dictbucket.py (contents, props changed) Modified: pypy/dist/pypy/config/pypyoption.py pypy/dist/pypy/objspace/std/dictmultiobject.py pypy/dist/pypy/objspace/std/objspace.py pypy/dist/pypy/objspace/std/test/test_dictmultiobject.py Log: Implement general dictionaries as a hash table whose collision resolution is via chained lists instead of open addressing. Enable with --objspace-std-withbucketdict. It replaces the r_dict implementation for general dictionaries (but doesn't change string dicts, at least so far). Modified: pypy/dist/pypy/config/pypyoption.py ============================================================================== --- pypy/dist/pypy/config/pypyoption.py (original) +++ pypy/dist/pypy/config/pypyoption.py Sat Mar 3 10:05:48 2007 @@ -143,6 +143,12 @@ default=False, requires=[("objspace.std.withmultidict", True)]), + BoolOption("withbucketdict", + "use dictionaries with chained hash tables " + "(default is open addressing)", + default=False, + requires=[("objspace.std.withmultidict", True)]), + BoolOption("withrangelist", "enable special range list implementation that does not " "actually create the full list until the resulting " Added: pypy/dist/pypy/doc/config/objspace.std.withbucketdict.txt ============================================================================== --- (empty file) +++ pypy/dist/pypy/doc/config/objspace.std.withbucketdict.txt Sat Mar 3 10:05:48 2007 @@ -0,0 +1,2 @@ +Implement general dictionaries as a hash table whose collision +resolution is via chained lists instead of open addressing. Added: pypy/dist/pypy/objspace/std/dictbucket.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/objspace/std/dictbucket.py Sat Mar 3 10:05:48 2007 @@ -0,0 +1,164 @@ +from pypy.objspace.std.dictmultiobject import DictImplementation +from pypy.objspace.std.dictmultiobject import IteratorImplementation + + +class BucketNode: + def __init__(self, hash, w_key, w_value, next): + self.hash = hash + self.w_key = w_key + self.w_value = w_value + self.next = next + + +DISTRIBUTE = 9 + + +class BucketDictImplementation(DictImplementation): + + def __init__(self, space): + self.space = space + self.len = 0 + self.table = [None] * 4 + + def __repr__(self): + bs = [] + for node in self.table: + count = 0 + while node is not None: + count += 1 + node = node.next + bs.append(str(count)) + return "%s<%s>" % (self.__class__.__name__, ', '.join(bs)) + + def get(self, w_key): + space = self.space + hash = space.hash_w(w_key) + index = (hash * DISTRIBUTE) & (len(self.table) - 1) + node = self.table[index] + while node is not None: + if node.hash == hash and space.eq_w(w_key, node.w_key): + return node.w_value + node = node.next + return None + + def setitem(self, w_key, w_value): + space = self.space + hash = space.hash_w(w_key) + index = (hash * DISTRIBUTE) & (len(self.table) - 1) + node = head = self.table[index] + while node is not None: + if node.hash == hash and space.eq_w(w_key, node.w_key): + node.w_value = w_value + return self + node = node.next + self.table[index] = BucketNode(hash, w_key, w_value, head) + self.len += 1 + if self.len > len(self.table): + self._resize() + return self + + def setitem_str(self, w_key, w_value, shadows_type=True): + return self.setitem(w_key, w_value) + + def delitem(self, w_key): + space = self.space + hash = space.hash_w(w_key) + index = (hash * DISTRIBUTE) & (len(self.table) - 1) + node = self.table[index] + prev = None + while node is not None: + if node.hash == hash and space.eq_w(w_key, node.w_key): + self.len -= 1 + if self.len == 0: + return self.space.emptydictimpl + if prev is None: + self.table[index] = node.next + else: + prev.next = node.next + if self.len < len(self.table) // 2: + self._resize() + return self + prev = node + node = node.next + raise KeyError + + def length(self): + return self.len + + def _resize(self): + newsize = 4 + while newsize < self.len: + newsize *= 2 + newtable = [None] * newsize + for node in self.table: + while node is not None: + newindex = (node.hash * DISTRIBUTE) & (newsize - 1) + next = node.next + node.next = newtable[newindex] + newtable[newindex] = node + node = next + self.table = newtable + + def iteritems(self): + return BucketDictItemIteratorImplementation(self.space, self) + def iterkeys(self): + return BucketDictKeyIteratorImplementation(self.space, self) + def itervalues(self): + return BucketDictValueIteratorImplementation(self.space, self) + + def keys(self): + result_w = [] + for node in self.table: + while node is not None: + result_w.append(node.w_key) + node = node.next + return result_w + + def values(self): + result_w = [] + for node in self.table: + while node is not None: + result_w.append(node.w_value) + node = node.next + return result_w + + def items(self): + space = self.space + result_w = [] + for node in self.table: + while node is not None: + w_item = space.newtuple([node.w_key, node.w_value]) + result_w.append(w_item) + node = node.next + return result_w + + +class BucketDictIteratorImplementation(IteratorImplementation): + def __init__(self, space, dictimplementation): + IteratorImplementation.__init__(self, space, dictimplementation) + self.index = 0 + self.node = None + + def next_entry(self): + node = self.node + while node is None: + table = self.dictimplementation.table + if self.index >= len(table): + return None + node = table[self.index] + self.index += 1 + self.node = node.next + return self.get_result(node) + + +class BucketDictKeyIteratorImplementation(BucketDictIteratorImplementation): + def get_result(self, node): + return node.w_key + +class BucketDictValueIteratorImplementation(BucketDictIteratorImplementation): + def get_result(self, node): + return node.w_value + +class BucketDictItemIteratorImplementation(BucketDictIteratorImplementation): + def get_result(self, node): + return self.space.newtuple([node.w_key, node.w_value]) Modified: pypy/dist/pypy/objspace/std/dictmultiobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/dictmultiobject.py (original) +++ pypy/dist/pypy/objspace/std/dictmultiobject.py Sat Mar 3 10:05:48 2007 @@ -143,7 +143,8 @@ return StrDictImplementation(self.space).setitem_str(w_key, w_value) #return SmallStrDictImplementation(self.space, w_key, w_value) else: - return RDictImplementation(self.space).setitem(w_key, w_value) + space = self.space + return space.DefaultDictImpl(space).setitem(w_key, w_value) #return SmallDictImplementation(self.space, w_key, w_value) def setitem_str(self, w_key, w_value, shadows_type=True): return StrDictImplementation(self.space).setitem_str(w_key, w_value) @@ -205,7 +206,7 @@ i += 1 def _convert_to_rdict(self): - newimpl = RDictImplementation(self.space) + newimpl = self.space.DefaultDictImpl(self.space) i = 0 while 1: entry = self.entries[i] @@ -296,13 +297,13 @@ i += 1 def _convert_to_rdict(self): - newimpl = RDictImplementation(self.space) + newimpl = self.space.DefaultDictImpl(self.space) i = 0 while 1: entry = self.entries[i] if entry.w_value is None: break - newimpl.content[self.space.wrap(entry.key)] = entry.w_value + newimpl.setitem(self.space.wrap(entry.key), entry.w_value) i += 1 return newimpl @@ -450,7 +451,7 @@ def _as_rdict(self): - newimpl = RDictImplementation(self.space) + newimpl = self.space.DefaultDictImpl(self.space) for k, w_v in self.content.items(): newimpl.setitem(self.space.wrap(k), w_v) return newimpl @@ -762,7 +763,7 @@ if as_strdict: newimpl = StrDictImplementation(self.space) else: - newimpl = RDictImplementation(self.space) + newimpl = self.space.DefaultDictImpl(self.space) for k, i in self.structure.keys.items(): if i >= 0: newimpl.setitem_str(self.space.wrap(k), self.entries[i]) Modified: pypy/dist/pypy/objspace/std/objspace.py ============================================================================== --- pypy/dist/pypy/objspace/std/objspace.py (original) +++ pypy/dist/pypy/objspace/std/objspace.py Sat Mar 3 10:05:48 2007 @@ -127,6 +127,11 @@ from pypy.objspace.std import dictmultiobject self.DictObjectCls = dictmultiobject.W_DictMultiObject self.emptydictimpl = dictmultiobject.EmptyDictImplementation(self) + if self.config.objspace.std.withbucketdict: + from pypy.objspace.std import dictbucket + self.DefaultDictImpl = dictbucket.BucketDictImplementation + else: + self.DefaultDictImpl = dictmultiobject.RDictImplementation else: from pypy.objspace.std import dictobject self.DictObjectCls = dictobject.W_DictObject Added: pypy/dist/pypy/objspace/std/test/test_dictbucket.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/objspace/std/test/test_dictbucket.py Sat Mar 3 10:05:48 2007 @@ -0,0 +1,10 @@ +from pypy.objspace.std.dictbucket import BucketDictImplementation +from pypy.objspace.std.test import test_dictmultiobject + + +Base = test_dictmultiobject.TestRDictImplementation + +class TestBucketDictImplementation(Base): + ImplementionClass = BucketDictImplementation + DevolvedClass = BucketDictImplementation + DefaultDictImpl = BucketDictImplementation Modified: pypy/dist/pypy/objspace/std/test/test_dictmultiobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/test/test_dictmultiobject.py (original) +++ pypy/dist/pypy/objspace/std/test/test_dictmultiobject.py Sat Mar 3 10:05:48 2007 @@ -69,6 +69,7 @@ self.space = FakeSpace() self.space.emptydictimpl = EmptyDictImplementation(self.space) self.space.DictObjectCls = W_DictMultiObject + self.space.DefaultDictImpl = RDictImplementation def test_stressdict(self): from random import randint @@ -86,11 +87,13 @@ ImplementionClass = RDictImplementation DevolvedClass = RDictImplementation EmptyClass = EmptyDictImplementation + DefaultDictImpl = RDictImplementation def setup_method(self,method): self.space = FakeSpace() self.space.DictObjectCls = W_DictMultiObject self.space.emptydictimpl = EmptyDictImplementation(self.space) + self.space.DefaultDictImpl = self.DefaultDictImpl self.string = self.space.wrap("fish") self.string2 = self.space.wrap("fish2") self.impl = self.get_impl() From cfbolz at codespeak.net Sat Mar 3 10:45:03 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sat, 3 Mar 2007 10:45:03 +0100 (CET) Subject: [pypy-svn] r39762 - pypy/extradoc/sprintinfo/trillke-2007 Message-ID: <20070303094503.BC04910061@code0.codespeak.net> Author: cfbolz Date: Sat Mar 3 10:45:01 2007 New Revision: 39762 Modified: pypy/extradoc/sprintinfo/trillke-2007/planning.txt Log: (all): planning for today Modified: pypy/extradoc/sprintinfo/trillke-2007/planning.txt ============================================================================== --- pypy/extradoc/sprintinfo/trillke-2007/planning.txt (original) +++ pypy/extradoc/sprintinfo/trillke-2007/planning.txt Sat Mar 3 10:45:01 2007 @@ -5,42 +5,56 @@ People present: Michael, Arre, Stephan, Anto, Guido, Armin, Maciek, Bea, Samuele, Georg, Alexander, Holger, Carl Friedrich, Anders -Tutorial: Georg, Anders +Tutorial: Georg, Anders DONE * think a bit about what needs to be done for 1.0 - * move some of the external functions to the new interface (kill - suggested_primitive!!!) + * move some of the external functions to the new interface (Samuele, Anto) - * Fix the rdict bug (Michael, Richard) + * Fix the rdict bug DONE * run application on top of PyPy and turn them into benchmarks: Guido, Christian + - templess is now a pypy benchmark (5-6x) + - docutils is now a pypy benchmark (5-6x) + - gadfly is working with old-style classes * object optimizations: ropes, list optimizations, cuckoo hashing, tree-based dicts: after the tutorial, Holger, Armin, Carl Friedrich, Georg + - ropes DONE (but slow) + - chunked list DONE + - multilist broken?! (Alexander, Carl Friedrich) + - O(sqrt(n)) DONE but is slow and uses too much memory + - move string interpolation to rpython (Holger, Stephan) + - chained hash table (Armin), NEARLY DONE + - discuss global dict lookup ideas (Armin, Georg) * improve the error messages of the rtyper * improve setups of temporary test directories - * benchmarking: make nice graphs out of benchmark results + * benchmarking: make nice graphs out of benchmark results IN-PROGRESS + (Michael, Holger) - * hunt the strange speed bottleneck of gencli/genjava: Anto, Samuele + * hunt the strange speed bottleneck of gencli: DONE - * fix application-level stackless code: Arre, Stephan + * fix application-level stackless code: DONE * improve greensocks - * have a minimal readline support for history and line editing: Armin, Holger + * have a minimal readline support for history and line editing: DONE + - get completion working - * fix the javascript backend work in internet explorer: Guido, Maciek + * fix the javascript backend work in internet explorer: IN-PROGRESS + (Guido, Maciek) - * make the usage of the js backend nicer + * make the usage of the js backend nicer (Guido, Maciek) - * discuss code sharing between the js backend and gencli: Anto, Maciek + * discuss code sharing between the js backend and gencli: MOSTLY DONE - * make genllvm less of a FrankenBackend + * make genllvm less of a FrankenBackend (Richard, half of Michael), IN-PROGRESS + + * use "const" for immutable structures * have a pypy with a gil and threading that works From mwh at codespeak.net Sat Mar 3 11:21:16 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Sat, 3 Mar 2007 11:21:16 +0100 (CET) Subject: [pypy-svn] r39763 - pypy/dist/pypy/translator/benchmark Message-ID: <20070303102116.9EE0310061@code0.codespeak.net> Author: mwh Date: Sat Mar 3 11:21:07 2007 New Revision: 39763 Modified: pypy/dist/pypy/translator/benchmark/bench-custom.py Log: add a --verbose options (which doesn't actually do anything yet, erm) and a --no-cpython option. 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 Sat Mar 3 11:21:07 2007 @@ -41,7 +41,8 @@ refs = {} - exes = full_pythons + exes + if not options.nocpython: + exes = full_pythons + exes for i in range(int(options.runcount)): for exe in exes: @@ -82,5 +83,13 @@ '--relto', dest='relto', default=None, ) + parser.add_option( + '-v', '--verbose', action='store_true', dest='verbose', + default=None, + ) + parser.add_option( + '--no-cpython', action='store_true', dest='nocpython', + default=None, + ) options, args = parser.parse_args(sys.argv[1:]) main(options, args) From mwh at codespeak.net Sat Mar 3 11:22:18 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Sat, 3 Mar 2007 11:22:18 +0100 (CET) Subject: [pypy-svn] r39764 - pypy/dist/pypy/translator/benchmark Message-ID: <20070303102218.67DAF10061@code0.codespeak.net> Author: mwh Date: Sat Mar 3 11:22:14 2007 New Revision: 39764 Modified: pypy/dist/pypy/translator/benchmark/benchmarks.py Log: fake out the unicodedata for the docutils benchmark Modified: pypy/dist/pypy/translator/benchmark/benchmarks.py ============================================================================== --- pypy/dist/pypy/translator/benchmark/benchmarks.py (original) +++ pypy/dist/pypy/translator/benchmark/benchmarks.py Sat Mar 3 11:22:14 2007 @@ -68,6 +68,7 @@ docutilssvnpath = docutilssvnpathfile.read().strip() translatetxt = py.magic.autopath().dirpath().dirpath().dirpath().join('doc').join('translation.txt') command = """import sys +sys.modules['unicodedata'] = sys # docutils need 'import unicodedata' to work, but no more... sys.path[0:0] = ['%s', '%s/extras'] from docutils.core import publish_cmdline publish_cmdline(writer_name='html') From fijal at codespeak.net Sat Mar 3 11:26:30 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 3 Mar 2007 11:26:30 +0100 (CET) Subject: [pypy-svn] r39765 - pypy/dist/pypy/translator/js/examples/bnb Message-ID: <20070303102630.B7E0110069@code0.codespeak.net> Author: fijal Date: Sat Mar 3 11:26:27 2007 New Revision: 39765 Modified: pypy/dist/pypy/translator/js/examples/bnb/start_bnb.py Log: use mochikit by default 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 Sat Mar 3 11:26:27 2007 @@ -11,6 +11,9 @@ from pypy.translator.js.modules.mochikit import log, logWarning,\ createLoggingPane, logDebug from pypy.translator.js.examples.bnb.bnb import exported_methods +from pypy.translator.js import commproxy + +commproxy.USE_MOCHIKIT = True import time import os From fijal at codespeak.net Sat Mar 3 11:27:31 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 3 Mar 2007 11:27:31 +0100 (CET) Subject: [pypy-svn] r39766 - pypy/dist/pypy/translator/js Message-ID: <20070303102731.623EE10069@code0.codespeak.net> Author: fijal Date: Sat Mar 3 11:27:28 2007 New Revision: 39766 Modified: pypy/dist/pypy/translator/js/commproxy.py Log: Misunderstanding when applying patch Modified: pypy/dist/pypy/translator/js/commproxy.py ============================================================================== --- pypy/dist/pypy/translator/js/commproxy.py (original) +++ pypy/dist/pypy/translator/js/commproxy.py Sat Mar 3 11:27:28 2007 @@ -14,7 +14,9 @@ str = "" for(i in data) { if (data[i]) { - if (str.length != 0) { + if (str.length == 0) { + str += "?"; + } else { str += "&"; } str += escape(i) + "=" + escape(data[i].toString()); @@ -38,9 +40,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()); From fijal at codespeak.net Sat Mar 3 11:36:39 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 3 Mar 2007 11:36:39 +0100 (CET) Subject: [pypy-svn] r39768 - in pypy/dist/pypy/translator/js/examples: console/test test Message-ID: <20070303103639.B629410069@code0.codespeak.net> Author: fijal Date: Sat Mar 3 11:36:36 2007 New Revision: 39768 Modified: pypy/dist/pypy/translator/js/examples/console/test/test_console.py pypy/dist/pypy/translator/js/examples/console/test/test_session.py pypy/dist/pypy/translator/js/examples/test/test_examples.py Log: Add skips in a case when no greensock is found Modified: pypy/dist/pypy/translator/js/examples/console/test/test_console.py ============================================================================== --- pypy/dist/pypy/translator/js/examples/console/test/test_console.py (original) +++ pypy/dist/pypy/translator/js/examples/console/test/test_console.py Sat Mar 3 11:36:36 2007 @@ -1,11 +1,12 @@ +import py +py.test.skip("XXX") + from pypy.translator.js.examples.console import console def test_run_console(): """ Check if we can read anything """ - import py - py.test.skip("XXX") pipe = console.run_console("python") pipe.stdin.close() t = False Modified: pypy/dist/pypy/translator/js/examples/console/test/test_session.py ============================================================================== --- pypy/dist/pypy/translator/js/examples/console/test/test_session.py (original) +++ pypy/dist/pypy/translator/js/examples/console/test/test_session.py Sat Mar 3 11:36:36 2007 @@ -2,11 +2,15 @@ """ Various tests around interpreter in a subprocess """ -from pypeers.greensock2 import autogreenlet, wait, sleep, ConnexionClosed -from pypeers.pipe.fd import FDInput -from pypy.translator.js.examples.console.session import Interpreter import py +try: + from pypeers.greensock2 import autogreenlet, wait, sleep, ConnexionClosed + from pypeers.pipe.fd import FDInput +except ImportError: + py.test.skip("greensock wasn't found") +from pypy.translator.js.examples.console.session import Interpreter + def test_greensock_reader_timeouter(): i = Interpreter("python", timeout=3) while not i.interact().endswith(">>> "): 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 Sat Mar 3 11:36:36 2007 @@ -27,6 +27,10 @@ def test_console_2_build(): - from pypy.translator.js.examples.console import console, client + try: + from pypy.translator.js.examples.console import console, client + except ImportError: + py.test.skip("greensock wasn't found") + assert rpython2javascript(client, console.FUNCTION_LIST, use_pdb=False) From gbrandl at codespeak.net Sat Mar 3 11:40:23 2007 From: gbrandl at codespeak.net (gbrandl at codespeak.net) Date: Sat, 3 Mar 2007 11:40:23 +0100 (CET) Subject: [pypy-svn] r39769 - in pypy/dist/pypy/objspace/std: . test Message-ID: <20070303104023.A794010069@code0.codespeak.net> Author: gbrandl Date: Sat Mar 3 11:40:21 2007 New Revision: 39769 Modified: pypy/dist/pypy/objspace/std/listmultiobject.py pypy/dist/pypy/objspace/std/smartresizablelist.py pypy/dist/pypy/objspace/std/test/test_listmultiobject.py pypy/dist/pypy/objspace/std/test/test_listobject.py Log: Some more listmultiobject special cases for empty lists, some new tests, use the freelist in the smartresizablelist. more tests to follow. Modified: pypy/dist/pypy/objspace/std/listmultiobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/listmultiobject.py (original) +++ pypy/dist/pypy/objspace/std/listmultiobject.py Sat Mar 3 11:40:21 2007 @@ -9,12 +9,26 @@ from pypy.rlib.listsort import TimSort +# ListImplementations + +# An empty list always is an EmptyListImplementation. +# +# RDictImplementation -- standard implementation +# StrListImplementation -- lists consisting only of strings +# ChunkedListImplementation -- when having set the withchunklist option +# SmartResizableListImplementation -- when having set the +# withsmartresizablelist option +# RangeImplementation -- constructed by range() +# SliceTrackingListImplementation -- when having set the withfastslice option +# SliceListImplementation -- slices of a SliceTrackingListImplementation + + class ListImplementation(object): def __init__(self, space): self.space = space -# A list implementation should implement the following methods: +# A list implementation must implement the following methods: ## def length(self): ## pass @@ -25,9 +39,12 @@ ## def getitem_slice(self, start, stop): ## pass +## def get_list_w(self): +## pass + -# the following operations return the list implementation that should -# be used after the call +# 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: @@ -49,16 +66,12 @@ def extend(self, other): pass - -# special cases: + # special case def add(self, other): pass -## def get_list_w(self): -## pass - -# default implementations, can (but don't have to be) overridden: +# Default implementations, can (but don't have to be) overridden: def reverse(self): l = self.length() @@ -122,7 +135,7 @@ 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 make_implementation(self.space, list_w) return impl def i_insert(self, i, w_item): @@ -131,7 +144,7 @@ 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 make_implementation(self.space, list_w) return impl def i_append(self, w_item): @@ -139,7 +152,7 @@ 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 make_implementation(self.space, list_w) return impl def i_add(self, other): @@ -147,7 +160,7 @@ 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 make_implementation(self.space, list_w1 + list_w2) return impl def i_extend(self, other): @@ -155,7 +168,7 @@ 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 make_implementation(self.space, list_w1 + list_w2) return impl def i_delitem(self, i): @@ -163,7 +176,7 @@ if impl is None: list_w = self.get_list_w() del list_w[i] - return self.make_implementation(list_w) + return make_implementation(self.space, list_w) return impl def i_delitem_slice(self, start, stop): @@ -173,24 +186,9 @@ assert 0 <= start < len(list_w) assert 0 <= stop <= len(list_w) del list_w[start:stop] - return self.make_implementation(list_w) + return make_implementation(self.space, list_w) return impl - def make_implementation(self, list_w): - space = self.space - if space.config.objspace.std.withsmartresizablelist: - from pypy.objspace.std.smartresizablelist import \ - SmartResizableListImplementation - impl = SmartResizableListImplementation(space) - impl.extend(RListImplementation(space, list_w)) - return impl - if space.config.objspace.std.withchunklist: - return ChunkedListImplementation(space, list_w) - 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): @@ -474,7 +472,7 @@ def getitem_slice_step(self, start, stop, step, slicelength): assert 0 <= start < len(self.strlist) - assert 0 <= stop < len(self.strlist) + assert 0 <= stop <= len(self.strlist) assert slicelength > 0 res = [""] * slicelength for i in range(slicelength): @@ -810,31 +808,33 @@ return True def make_implementation(space, list_w): - if list_w: - if space.config.objspace.std.withsmartresizablelist: - from pypy.objspace.std.smartresizablelist import \ - SmartResizableListImplementation - impl = SmartResizableListImplementation(space) - impl.extend(RListImplementation(space, list_w)) - return impl - if space.config.objspace.std.withchunklist: - return ChunkedListImplementation(space, list_w) - elif 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) + if not list_w: + return space.fromcache(State).empty_impl + if space.config.objspace.std.withsmartresizablelist: + from pypy.objspace.std.smartresizablelist import \ + SmartResizableListImplementation + impl = SmartResizableListImplementation(space) + impl.extend(RListImplementation(space, list_w)) + return impl + if space.config.objspace.std.withchunklist: + return ChunkedListImplementation(space, list_w) + elif space.config.objspace.std.withfastslice: + return SliceTrackingListImplementation(space, list_w) else: - impl = space.fromcache(State).empty_impl - return impl + # check if it's strings only + 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] + return StrListImplementation(space, strlist) + else: + return RListImplementation(space, list_w) def convert_list_w(space, list_w): - impl = make_implementation(space, list_w) + if not list_w: + impl = space.fromcache(State).empty_impl + else: + impl = make_implementation(space, list_w) return W_ListMultiObject(space, impl) @@ -898,6 +898,8 @@ length = w_list.implementation.length() start, stop, step, slicelength = w_slice.indices4(space, length) assert slicelength >= 0 + if slicelength == 0: + return W_ListMultiObject(space) if step == 1 and 0 <= start <= stop: return W_ListMultiObject( space, @@ -940,6 +942,8 @@ if e.match(space, space.w_TypeError): raise FailedToImplement raise + if times <= 0: + return W_ListMultiObject(space) return W_ListMultiObject(space, w_list.implementation.mul(times)) def mul__ListMulti_ANY(space, w_list, w_times): @@ -955,8 +959,11 @@ if e.match(space, space.w_TypeError): raise FailedToImplement raise - # XXX could be more efficient? - w_list.implementation = w_list.implementation.mul(times) + if times <= 0: + w_list.implementation = space.fromcache(State).empty_impl + else: + # 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): @@ -1018,16 +1025,23 @@ 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) + if length == 1: + w_list.implementation = space.fromcache(State).empty_impl + else: + 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()) + length = w_list.implementation.length() + start, stop, step, slicelength = w_slice.indices4(space, length) if slicelength == 0: return + if slicelength == length: + w_list.implementation = space.fromcache(State).empty_impl + return space.w_None + if step < 0: start = start + step * (slicelength-1) step = -step Modified: pypy/dist/pypy/objspace/std/smartresizablelist.py ============================================================================== --- pypy/dist/pypy/objspace/std/smartresizablelist.py (original) +++ pypy/dist/pypy/objspace/std/smartresizablelist.py Sat Mar 3 11:40:21 2007 @@ -45,7 +45,7 @@ self.freelist = {} def alloc(self, size): - l = self.freelist.get(size) + l = self.freelist.get(size, None) if l is not None and l: return l.pop() return [None] * size @@ -59,6 +59,8 @@ else: self.freelist[size] = [l] +freelist = FreeList() + class SmartResizableListImplementation(ListImplementation): def __init__(self, space): self._length = 0 @@ -96,7 +98,7 @@ self.size_datablock *= 2 self.last_superblock_filled = 0 if len(data_blocks) == self.num_datablocks: - data_blocks.append([None] * self.size_datablock) + data_blocks.append(freelist.alloc(self.size_datablock)) self.last_superblock_filled += 1 self.num_datablocks += 1 self.index_last = 0 @@ -124,7 +126,7 @@ data_blocks = self.data_blocks if len(data_blocks) > self.num_datablocks: assert len(data_blocks) - self.num_datablocks == 1 - data_blocks.pop() + freelist.dealloc(data_blocks.pop()) for i in range(self.index_last): #XXX consider when not to do this idx = self.num_datablocks - 1 assert idx >= 0 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 Sat Mar 3 11:40:21 2007 @@ -124,12 +124,6 @@ cls.space = gettestobjspace(**{ "objspace.std.withsmartresizablelist": True}) - def test_insert_some(self): - ls = [1,2,3,4,5,6,7] - for i in range(5): - ls.insert(0, i) - assert len(ls) == 12 - class AppTest_ChunkListObject(test_listobject.AppTestW_ListObject): def setup_class(cls): cls.space = gettestobjspace(**{"objspace.std.withchunklist": True}) 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 Sat Mar 3 11:40:21 2007 @@ -340,6 +340,7 @@ assert self.space.eq_w(self.space.le(w_list4, w_list3), self.space.w_True) + class AppTestW_ListObject: def test_call_list(self): assert list('') == [] @@ -347,27 +348,41 @@ assert list((1, 2)) == [1, 2] l = [] assert list(l) is not l + assert list(range(10)) == range(10) def test_explicit_new_init(self): l = l0 = list.__new__(list) l.__init__([1,2]) assert l is l0 - assert l ==[1,2] - list.__init__(l,[1,2,3]) + assert l == [1,2] + list.__init__(l, [1,2,3]) + assert l is l0 + assert l == [1,2,3] + list.__init__(l, ['a', 'b', 'c']) assert l is l0 - assert l ==[1,2,3] - + assert l == ['a', 'b', 'c'] + def test_extend_list(self): l = l0 = [1] l.extend([2]) assert l is l0 assert l == [1,2] + l = ['a'] + l.extend('b') + assert l == ['a', 'b'] + l = ['a'] + l.extend([0]) + assert l == ['a', 0] + l = range(10) + l.extend([10]) + assert l == range(11) def test_extend_tuple(self): l = l0 = [1] l.extend((2,)) assert l is l0 assert l == [1,2] + l = ['a'] def test_extend_iterable(self): l = l0 = [1] @@ -412,7 +427,7 @@ l = [ 'a' ] l.sort(key = lower) assert l == [ 'a' ] - + def test_sort_reversed(self): l = range(10) l.sort(reverse = True) @@ -429,7 +444,7 @@ 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 @@ -449,16 +464,23 @@ raises(IndexError, "del l[len(l)]") raises(IndexError, "del l[-len(l)-1]") - def test_extended_slice(self): + def test_getitem_slice(self): l = range(10) del l[::2] - assert l ==[1,3,5,7,9] + assert l == [1,3,5,7,9] l[-2::-1] = l[:-1] - assert l ==[7,5,3,1,9] + assert l == [7,5,3,1,9] del l[-1:2:-1] - assert l ==[7,5,3] + assert l == [7,5,3] del l[:2] - assert l ==[3] + assert l == [3] + + l = [0] + assert l[1:] == [] + assert l[1::2] == [] + l = [''] + assert l[1:] == [] + assert l[1::2] == [] def test_delall(self): l = l0 = [1,2,3] @@ -546,6 +568,11 @@ c.insert(-2, 'Z') assert ''.join(c) == 'XhYello worZld' + ls = [1,2,3,4,5,6,7] + for i in range(5): + ls.insert(0, i) + assert len(ls) == 12 + def test_pop(self): c = list('hello world') s = '' From gbrandl at codespeak.net Sat Mar 3 12:09:17 2007 From: gbrandl at codespeak.net (gbrandl at codespeak.net) Date: Sat, 3 Mar 2007 12:09:17 +0100 (CET) Subject: [pypy-svn] r39770 - in pypy/dist/pypy/objspace/std: . test Message-ID: <20070303110917.4E83510060@code0.codespeak.net> Author: gbrandl Date: Sat Mar 3 12:09:13 2007 New Revision: 39770 Modified: pypy/dist/pypy/objspace/std/listmultiobject.py pypy/dist/pypy/objspace/std/test/test_listobject.py Log: Another assertion fix and more tests, for strings and ranges. Modified: pypy/dist/pypy/objspace/std/listmultiobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/listmultiobject.py (original) +++ pypy/dist/pypy/objspace/std/listmultiobject.py Sat Mar 3 12:09:13 2007 @@ -472,7 +472,8 @@ def getitem_slice_step(self, start, stop, step, slicelength): assert 0 <= start < len(self.strlist) - assert 0 <= stop <= len(self.strlist) + # stop is -1 e.g. for [2:-1:-1] + assert -1 <= stop <= len(self.strlist) assert slicelength > 0 res = [""] * slicelength for i in range(slicelength): 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 Sat Mar 3 12:09:13 2007 @@ -383,12 +383,18 @@ assert l is l0 assert l == [1,2] l = ['a'] + l.extend(('b',)) + assert l == ['a', 'b'] 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] + l = l0 = ['a'] + l.extend(iter(['b', 'c', 'd'])) + assert l == ['a', 'b', 'c', 'd'] + assert l is l0 def test_sort(self): l = l0 = [1, 5, 3, 0] @@ -452,6 +458,11 @@ assert l[-2] == 6 raises(IndexError, "l[len(l)]") raises(IndexError, "l[-len(l)-1]") + l = ['a', 'b', 'c'] + assert l[0] == 'a' + assert l[-1] == 'c' + assert l[-2] == 'b' + raises(IndexError, "l[len(l)]") def test_delitem(self): l = [1, 2, 3, 4, 5, 6, 9] @@ -463,9 +474,24 @@ assert l == [2, 3, 4, 6] raises(IndexError, "del l[len(l)]") raises(IndexError, "del l[-len(l)-1]") + + l = l0 = ['a', 'b', 'c'] + del l[0] + assert l == ['b', 'c'] + del l[-1] + assert l == ['b'] + del l[-1] + assert l == [] + assert l is l0 + raises(IndexError, "del l[0]") + + l = range(10) + del l[5] + assert l == [0, 1, 2, 3, 4, 6, 7, 8, 9] def test_getitem_slice(self): l = range(10) + assert l[::] == l del l[::2] assert l == [1,3,5,7,9] l[-2::-1] = l[:-1] @@ -474,19 +500,33 @@ assert l == [7,5,3] del l[:2] assert l == [3] - - l = [0] assert l[1:] == [] assert l[1::2] == [] + assert l[::] == l + assert l[0::-2] == l + assert l[-1::-5] == l + l = [''] assert l[1:] == [] assert l[1::2] == [] + assert l[::] == l + assert l[0::-5] == l + assert l[-1::-5] == l + l.extend(['a', 'b']) + assert l[::-1] == ['b', 'a', ''] + assert l[:-1:-1] == ['b', 'a', ''] def test_delall(self): l = l0 = [1,2,3] del l[:] assert l is l0 assert l == [] + l = ['a', 'b'] + del l[:] + assert l == [] + l = range(5) + del l[:] + assert l == [] def test_iadd(self): l = l0 = [1,2,3] @@ -494,6 +534,14 @@ assert l is l0 assert l == [1,2,3,4,5] + l = l0 = ['a', 'b', 'c'] + l1 = l[:] + l += ['d'] + assert l is l0 + assert l == ['a', 'b', 'c', 'd'] + l1 += [0] + assert l1 == ['a', 'b', 'c', 0] + def test_iadd_iterable(self): l = l0 = [1,2,3] l += iter([4,5]) @@ -512,8 +560,27 @@ l *= (-1) assert l is l0 assert l == [] + + l = l0 = ['a', 'b'] + l *= 2 + assert l is l0 + assert l == ['a', 'b', 'a', 'b'] + l *= 0 + assert l is l0 + assert l == [] + l = ['a'] + l *= -5 + assert l == [] + + l = range(2) + l *= 2 + assert l == [0, 1, 0, 1] def test_index(self): + c = range(10) + assert c.index(0) == 0 + raises(ValueError, c.index, 10) + c = list('hello world') assert c.index('l') == 2 raises(ValueError, c.index, '!') @@ -529,6 +596,10 @@ raises(TypeError, c.index, 'c', 0, 4.3) raises(TypeError, c.index, 'c', 1.0, 5.6) + c = [0, 2, 4] + assert c.index(0) == 0 + raises(ValueError, c.index, 3) + def test_ass_slice(self): l = range(6) l[1:3] = 'abc' @@ -540,6 +611,27 @@ l[:] = [] assert l == [] + l = l0 = ['a', 'b'] + l[1:1] = ['ae'] + assert l == ['a', 'ae', 'b'] + l[1:100] = ['B'] + assert l == ['a', 'B'] + l[:] = [] + assert l == [] + assert l is l0 + + def test_ass_extended_slice(self): + l = l0 = ['a', 'b', 'c'] + l[::-1] = ['a', 'b', 'c'] + assert l == ['c', 'b', 'a'] + l[::-2] = [0, 1] + assert l == [1, 'b', 0] + l[-1:5:2] = [2] + assert l == [1, 'b', 2] + l[:-1:2] = [0] + assert l == [0, 'b', 2] + assert l is l0 + def test_recursive_repr(self): l = [] assert repr(l) == '[]' @@ -554,6 +646,17 @@ l.append('Z') assert l == ['X', 'Y', 'Z'] + l = [] + l.append(0) + assert l == [0] + for x in range(1, 5): + l.append(x) + assert l == range(5) + + l = range(4) + l.append(4) + assert l == range(5) + def test_count(self): c = list('hello') assert c.count('l') == 2 @@ -568,7 +671,7 @@ c.insert(-2, 'Z') assert ''.join(c) == 'XhYello worZld' - ls = [1,2,3,4,5,6,7] + ls = [1, 2, 3, 4, 5, 6, 7] for i in range(5): ls.insert(0, i) assert len(ls) == 12 @@ -582,6 +685,10 @@ raises(IndexError, c.pop) assert len(c) == 0 + l = range(10) + l.pop() + assert l == range(9) + def test_remove(self): c = list('hello world') c.remove('l') @@ -593,6 +700,12 @@ raises(ValueError, c.remove, 'l') assert ''.join(c) == 'heo word' + l = range(5) + l.remove(2) + assert l == [0, 1, 3, 4] + l = [0, 3, 5] + raises(ValueError, c.remove, 2) + def test_reverse(self): c = list('hello world') c.reverse() From gbrandl at codespeak.net Sat Mar 3 12:10:12 2007 From: gbrandl at codespeak.net (gbrandl at codespeak.net) Date: Sat, 3 Mar 2007 12:10:12 +0100 (CET) Subject: [pypy-svn] r39771 - in pypy/dist/pypy/objspace/std: . test Message-ID: <20070303111012.7FC7610063@code0.codespeak.net> Author: gbrandl Date: Sat Mar 3 12:10:10 2007 New Revision: 39771 Modified: pypy/dist/pypy/objspace/std/listmultiobject.py pypy/dist/pypy/objspace/std/test/test_listobject.py Log: Fix the test. Modified: pypy/dist/pypy/objspace/std/listmultiobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/listmultiobject.py (original) +++ pypy/dist/pypy/objspace/std/listmultiobject.py Sat Mar 3 12:10:10 2007 @@ -472,7 +472,7 @@ def getitem_slice_step(self, start, stop, step, slicelength): assert 0 <= start < len(self.strlist) - # stop is -1 e.g. for [2:-1:-1] + # stop is -1 e.g. for [2::-1] assert -1 <= stop <= len(self.strlist) assert slicelength > 0 res = [""] * slicelength 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 Sat Mar 3 12:10:10 2007 @@ -514,7 +514,6 @@ assert l[-1::-5] == l l.extend(['a', 'b']) assert l[::-1] == ['b', 'a', ''] - assert l[:-1:-1] == ['b', 'a', ''] def test_delall(self): l = l0 = [1,2,3] From rxe at codespeak.net Sat Mar 3 12:11:17 2007 From: rxe at codespeak.net (rxe at codespeak.net) Date: Sat, 3 Mar 2007 12:11:17 +0100 (CET) Subject: [pypy-svn] r39772 - pypy/dist/pypy/translator/llvm Message-ID: <20070303111117.7F0D710060@code0.codespeak.net> Author: rxe Date: Sat Mar 3 12:11:12 2007 New Revision: 39772 Modified: pypy/dist/pypy/translator/llvm/database.py pypy/dist/pypy/translator/llvm/opwriter.py Log: (mwh, rxe) tentatively remove some hacks Modified: pypy/dist/pypy/translator/llvm/database.py ============================================================================== --- pypy/dist/pypy/translator/llvm/database.py (original) +++ pypy/dist/pypy/translator/llvm/database.py Sat Mar 3 12:11:12 2007 @@ -269,11 +269,7 @@ if isinstance(type_, lltype.Primitive): return self.primitives[type_] elif isinstance(type_, lltype.Ptr): - if isinstance(type_.TO, lltype.FixedSizeArray): - # hack copied from genc - return self.repr_type(type_.TO.OF) + '*' - else: - return self.repr_type(type_.TO) + '*' + return self.repr_type(type_.TO) + '*' else: raise TypeError("cannot represent %r" %(type_,)) Modified: pypy/dist/pypy/translator/llvm/opwriter.py ============================================================================== --- pypy/dist/pypy/translator/llvm/opwriter.py (original) +++ pypy/dist/pypy/translator/llvm/opwriter.py Sat Mar 3 12:11:12 2007 @@ -333,41 +333,33 @@ 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)], getptr=getptr) + opr.argrefs[0], [("uint", index)]) 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") + tmpvar = self._tmp() + self.codewriter.getelementptr(tmpvar, opr.argtypes[0], + opr.argrefs[0], [("uint", index)]) + # get element ptr gets a pointer to the right type, except the generated code really expected + # an array of size 1... so we just cast it + element_type = self.db.repr_type(op.result.concretetype.TO.OF)+'*' + self.codewriter.cast(opr.retref, element_type, tmpvar, opr.rettype) def getsubstruct(self, opr): index = getindexhelper(opr.op.args[1].value, opr.op.args[0].concretetype.TO) assert opr.rettype != "void" - 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) + opr.argrefs[0], indices) def setfield(self, opr): op = opr.op @@ -375,12 +367,8 @@ 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)], getptr=getptr) + opr.argrefs[0], [("uint", index)]) self.codewriter.store(opr.argtypes[2], opr.argrefs[2], tmpvar) else: self._skipped(opr) @@ -397,28 +385,21 @@ tmpvar = self._tmp() indices = arrayindices(opr.op.args[0]) + [(indextype, index)] - ARRAYTYPE = opr.op.args[0].concretetype.TO - getptr = not isinstance(ARRAYTYPE, lltype.FixedSizeArray) - self.codewriter.getelementptr(tmpvar, arraytype, array, indices, getptr=getptr) + self.codewriter.getelementptr(tmpvar, arraytype, array, indices) 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) + self.codewriter.getelementptr(opr.retref, arraytype, array, indices) def getarraysubstruct(self, opr): array, index = opr.argrefs arraytype, indextype = opr.argtypes indices = arrayindices(opr.op.args[0]) + [(indextype, index)] - 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) + self.codewriter.getelementptr(opr.retref, arraytype, array, indices) def setarrayitem(self, opr): array, index, valuevar = opr.argrefs @@ -430,9 +411,7 @@ return indices = arrayindices(opr.op.args[0]) + [(indextype, index)] - ARRAYTYPE = opr.op.args[0].concretetype.TO - getptr = not isinstance(ARRAYTYPE, lltype.FixedSizeArray) - self.codewriter.getelementptr(tmpvar, arraytype, array, indices, getptr=getptr) + self.codewriter.getelementptr(tmpvar, arraytype, array, indices) self.codewriter.store(valuetype, valuevar, tmpvar) bare_setarrayitem = setarrayitem From arigo at codespeak.net Sat Mar 3 12:22:12 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 3 Mar 2007 12:22:12 +0100 (CET) Subject: [pypy-svn] r39773 - pypy/dist/pypy/objspace/std Message-ID: <20070303112212.737F710060@code0.codespeak.net> Author: arigo Date: Sat Mar 3 12:22:08 2007 New Revision: 39773 Modified: pypy/dist/pypy/objspace/std/listmultiobject.py Log: (cfbolz, arigo) Small changes to get the intention clearer. Modified: pypy/dist/pypy/objspace/std/listmultiobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/listmultiobject.py (original) +++ pypy/dist/pypy/objspace/std/listmultiobject.py Sat Mar 3 12:22:08 2007 @@ -1,8 +1,6 @@ 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 @@ -40,7 +38,7 @@ ## pass ## def get_list_w(self): -## pass +## => returns an RPython list of all wrapped items # The following operations return the list implementation that should @@ -49,27 +47,27 @@ # the operation it can return None for the following ones: def setitem(self, i, w_item): - pass + return None def insert(self, i, w_item): - pass + return None def delitem(self, index): - pass + return None def delitem_slice(self, start, stop): - pass + return None def append(self, w_item): - pass + return None def extend(self, other): - pass + return None # special case def add(self, other): - pass + return None # Default implementations, can (but don't have to be) overridden: From arigo at codespeak.net Sat Mar 3 12:23:06 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 3 Mar 2007 12:23:06 +0100 (CET) Subject: [pypy-svn] r39774 - in pypy/dist/pypy: config doc/config objspace/std objspace/std/test Message-ID: <20070303112306.A9E1710063@code0.codespeak.net> Author: arigo Date: Sat Mar 3 12:23:04 2007 New Revision: 39774 Added: pypy/dist/pypy/doc/config/objspace.std.sharesmallstr.txt (contents, props changed) pypy/dist/pypy/doc/config/objspace.std.withprebuiltchar.txt (contents, props changed) Modified: pypy/dist/pypy/config/pypyoption.py pypy/dist/pypy/objspace/std/marshal_impl.py pypy/dist/pypy/objspace/std/objspace.py pypy/dist/pypy/objspace/std/stringobject.py pypy/dist/pypy/objspace/std/stringtype.py pypy/dist/pypy/objspace/std/strjoinobject.py pypy/dist/pypy/objspace/std/strsliceobject.py pypy/dist/pypy/objspace/std/test/test_stringobject.py Log: (cfbolz, arigo) Prebuild the empty string and single-character strings. Controlled by two new option, --objspace-std-sharesmallstr and --objspace-std-withprebuiltchar. Modified: pypy/dist/pypy/config/pypyoption.py ============================================================================== --- pypy/dist/pypy/config/pypyoption.py (original) +++ pypy/dist/pypy/config/pypyoption.py Sat Mar 3 12:23:04 2007 @@ -123,6 +123,15 @@ BoolOption("withstrslice", "use strings optimized for slicing", default=False), + BoolOption("withprebuiltchar", + "use prebuilt single-character string objects", + default=False), + + BoolOption("sharesmallstr", + "always reuse the prebuilt string objects " + "(the empty string and potentially single-char strings)", + default=False), + BoolOption("withstrdict", "use dictionaries optimized for string keys", default=False), Added: pypy/dist/pypy/doc/config/objspace.std.sharesmallstr.txt ============================================================================== Added: pypy/dist/pypy/doc/config/objspace.std.withprebuiltchar.txt ============================================================================== Modified: pypy/dist/pypy/objspace/std/marshal_impl.py ============================================================================== --- pypy/dist/pypy/objspace/std/marshal_impl.py (original) +++ pypy/dist/pypy/objspace/std/marshal_impl.py Sat Mar 3 12:23:04 2007 @@ -303,11 +303,11 @@ m.atom_str(TYPE_STRING, s) def unmarshal_String(space, u, tc): - return W_StringObject(u.get_str()) + return space.wrap(u.get_str()) register(TYPE_STRING, unmarshal_String) def unmarshal_interned(space, u, tc): - w_ret = W_StringObject(u.get_str()) + w_ret = space.wrap(u.get_str()) u.stringtable_w.append(w_ret) w_intern = space.builtin.get('intern') space.call_function(w_intern, w_ret) @@ -495,7 +495,7 @@ string_to_buffer = app.interphook('string_to_buffer') def unmarshal_buffer(space, u, tc): - w_s = W_StringObject(u.get_str()) + w_s = space.wrap(u.get_str()) return string_to_buffer(space, w_s) register(TYPE_UNKNOWN, unmarshal_buffer) Modified: pypy/dist/pypy/objspace/std/objspace.py ============================================================================== --- pypy/dist/pypy/objspace/std/objspace.py (original) +++ pypy/dist/pypy/objspace/std/objspace.py Sat Mar 3 12:23:04 2007 @@ -340,7 +340,8 @@ else: return self.newint(x) if isinstance(x, str): - return W_StringObject(x) + from pypy.objspace.std.stringtype import wrapstr + return wrapstr(self, x) if isinstance(x, unicode): return W_UnicodeObject([unichr(ord(u)) for u in x]) # xxx if isinstance(x, float): @@ -473,7 +474,7 @@ except ValueError: # chr(out-of-range) raise OperationError(self.w_ValueError, self.wrap("character code not in range(256)")) - return W_StringObject(''.join(chars)) + return self.wrap(''.join(chars)) def newunicode(self, chars): try: Modified: pypy/dist/pypy/objspace/std/stringobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/stringobject.py (original) +++ pypy/dist/pypy/objspace/std/stringobject.py Sat Mar 3 12:23:04 2007 @@ -11,7 +11,7 @@ from pypy.objspace.std.noneobject import W_NoneObject from pypy.objspace.std.tupleobject import W_TupleObject -from pypy.objspace.std.stringtype import sliced, joined +from pypy.objspace.std.stringtype import sliced, joined, wrapstr, wrapchar class W_StringObject(W_Object): @@ -27,9 +27,12 @@ def unwrap(w_self, space): return w_self._value - registerimplementation(W_StringObject) +W_StringObject.EMPTY = W_StringObject('') +W_StringObject.PREBUILT = [W_StringObject(chr(i)) for i in range(256)] +del i + def _is_generic(space, w_self, fun): v = w_self._value @@ -336,7 +339,7 @@ l.append(space.str_w(w_s)) return space.wrap(self.join(l)) else: - return space.wrap("") + return W_StringObject.EMPTY def str_rjust__String_ANY_ANY(space, w_self, w_arg, w_fillchar): @@ -532,7 +535,7 @@ else: u_centered = u_self - return W_StringObject(u_centered) + return wrapstr(space, u_centered) def str_count__String_String_ANY_ANY(space, w_self, w_arg, w_start, w_end): u_self = w_self._value @@ -610,7 +613,7 @@ u_expanded += " " * _tabindent(oldtoken,u_tabsize) + token oldtoken = token - return W_StringObject(u_expanded) + return wrapstr(space, u_expanded) def str_splitlines__String_ANY(space, w_self, w_keepends): @@ -736,7 +739,7 @@ exc = space.call_function(space.w_IndexError, space.wrap("string index out of range")) raise OperationError(space.w_IndexError, exc) - return W_StringObject(str[ival]) + return wrapchar(space, str[ival]) def getitem__String_Slice(space, w_str, w_slice): w = space.wrap @@ -744,13 +747,13 @@ length = len(s) start, stop, step, sl = w_slice.indices4(space, length) if sl == 0: - str = "" + return W_StringObject.EMPTY elif step == 1: assert start >= 0 and stop >= 0 return sliced(space, s, start, stop) else: str = "".join([s[start + i*step] for i in range(sl)]) - return W_StringObject(str) + return wrapstr(space, str) def mul_string_times(space, w_str, w_times): try: @@ -760,7 +763,7 @@ raise FailedToImplement raise if mul <= 0: - return space.wrap('') + return W_StringObject.EMPTY input = w_str._value input_len = len(input) try: @@ -789,7 +792,7 @@ def str__String(space, w_str): if type(w_str) is W_StringObject: return w_str - return W_StringObject(w_str._value) + return wrapstr(space, w_str._value) def iter__String(space, w_list): from pypy.objspace.std import iterobject @@ -805,7 +808,7 @@ return space.wrap(ord(u_str)) def getnewargs__String(space, w_str): - return space.newtuple([W_StringObject(w_str._value)]) + return space.newtuple([wrapstr(space, w_str._value)]) def repr__String(space, w_str): s = w_str._value Modified: pypy/dist/pypy/objspace/std/stringtype.py ============================================================================== --- pypy/dist/pypy/objspace/std/stringtype.py (original) +++ pypy/dist/pypy/objspace/std/stringtype.py Sat Mar 3 12:23:04 2007 @@ -3,26 +3,44 @@ from sys import maxint +def wrapstr(space, s): + from pypy.objspace.std.stringobject import W_StringObject + if space.config.objspace.std.sharesmallstr: + if space.config.objspace.std.withprebuiltchar: + # share characters and empty string + if len(s) <= 1: + if len(s) == 0: + return W_StringObject.EMPTY + else: + s = s[0] # annotator hint: a single char + return wrapchar(space, s) + else: + # only share the empty string + if len(s) == 0: + return W_StringObject.EMPTY + return W_StringObject(s) + +def wrapchar(space, c): + from pypy.objspace.std.stringobject import W_StringObject + if space.config.objspace.std.withprebuiltchar: + return W_StringObject.PREBUILT[ord(c)] + else: + return W_StringObject(c) + def sliced(space, s, start, stop): if space.config.objspace.std.withstrslice: from pypy.objspace.std.strsliceobject import W_StringSliceObject - from pypy.objspace.std.stringobject import W_StringObject # XXX heuristic, should be improved! if (stop - start) > len(s) * 0.20 + 40: return W_StringSliceObject(s, start, stop) - else: - return W_StringObject(s[start:stop]) - else: - from pypy.objspace.std.stringobject import W_StringObject - return W_StringObject(s[start:stop]) + return wrapstr(space, s[start:stop]) def joined(space, strlist): if space.config.objspace.std.withstrjoin: from pypy.objspace.std.strjoinobject import W_StringJoinObject return W_StringJoinObject(strlist) else: - from pypy.objspace.std.stringobject import W_StringObject - return W_StringObject("".join(strlist)) + return wrapstr(space, "".join(strlist)) str_join = SMM('join', 2, doc='S.join(sequence) -> string\n\nReturn a string which is' Modified: pypy/dist/pypy/objspace/std/strjoinobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/strjoinobject.py (original) +++ pypy/dist/pypy/objspace/std/strjoinobject.py Sat Mar 3 12:23:04 2007 @@ -2,7 +2,7 @@ from pypy.objspace.std.stringobject import W_StringObject from pypy.objspace.std.unicodeobject import delegate_String2Unicode -from pypy.objspace.std.stringtype import joined +from pypy.objspace.std.stringtype import joined, wrapstr class W_StringJoinObject(W_Object): from pypy.objspace.std.stringtype import str_typedef as typedef @@ -32,10 +32,10 @@ registerimplementation(W_StringJoinObject) def delegate_join2str(space, w_strjoin): - return W_StringObject(w_strjoin.force()) + return wrapstr(space, w_strjoin.force()) def delegate_join2unicode(space, w_strjoin): - w_str = W_StringObject(w_strjoin.force()) + w_str = wrapstr(space, w_strjoin.force()) return delegate_String2Unicode(space, w_str) def len__StringJoin(space, w_self): Modified: pypy/dist/pypy/objspace/std/strsliceobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/strsliceobject.py (original) +++ pypy/dist/pypy/objspace/std/strsliceobject.py Sat Mar 3 12:23:04 2007 @@ -5,6 +5,8 @@ from pypy.objspace.std import slicetype from pypy.objspace.std.inttype import wrapint +from pypy.objspace.std.stringtype import wrapstr, wrapchar + class W_StringSliceObject(W_Object): from pypy.objspace.std.stringtype import str_typedef as typedef @@ -33,10 +35,10 @@ def delegate_slice2str(space, w_strslice): - return W_StringObject(w_strslice.force()) + return wrapstr(space, w_strslice.force()) def delegate_slice2unicode(space, w_strslice): - w_str = W_StringObject(w_strslice.force()) + w_str = wrapstr(space, w_strslice.force()) return delegate_String2Unicode(space, w_str) # ____________________________________________________________ @@ -118,14 +120,14 @@ exc = space.call_function(space.w_IndexError, space.wrap("string index out of range")) raise OperationError(space.w_IndexError, exc) - return W_StringObject(w_str.str[w_str.start + ival]) + return wrapchar(space, w_str.str[w_str.start + ival]) def getitem__StringSlice_Slice(space, w_str, w_slice): w = space.wrap length = w_str.stop - w_str.start start, stop, step, sl = w_slice.indices4(space, length) if sl == 0: - str = "" + return W_StringObject.EMPTY else: s = w_str.str start = w_str.start + start @@ -135,7 +137,7 @@ return W_StringSliceObject(s, start, stop) else: str = "".join([s[start + i*step] for i in range(sl)]) - return W_StringObject(str) + return wrapstr(space, str) def len__StringSlice(space, w_str): return space.wrap(w_str.stop - w_str.start) Modified: pypy/dist/pypy/objspace/std/test/test_stringobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/test/test_stringobject.py (original) +++ pypy/dist/pypy/objspace/std/test/test_stringobject.py Sat Mar 3 12:23:04 2007 @@ -1,6 +1,6 @@ from pypy.objspace.std import stringobject from pypy.objspace.std.stringobject import W_StringObject - +from pypy.conftest import gettestobjspace class TestW_StringObject: @@ -624,3 +624,17 @@ assert type(s.lstrip()) is str assert type(s.center(3)) is str assert type(s.splitlines()[0]) is str + + +class AppTestPrebuilt(AppTestStringObject): + def setup_class(cls): + cls.space = gettestobjspace(**{"objspace.std.withprebuiltchar": True}) + +class AppTestShare(AppTestStringObject): + def setup_class(cls): + cls.space = gettestobjspace(**{"objspace.std.sharesmallstr": True}) + +class AppTestPrebuiltShare(AppTestStringObject): + def setup_class(cls): + cls.space = gettestobjspace(**{"objspace.std.withprebuiltchar": True, + "objspace.std.sharesmallstr": True}) From mwh at codespeak.net Sat Mar 3 12:24:24 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Sat, 3 Mar 2007 12:24:24 +0100 (CET) Subject: [pypy-svn] r39775 - pypy/dist/pypy/translator/llvm/backendopt Message-ID: <20070303112424.6F16410060@code0.codespeak.net> Author: mwh Date: Sat Mar 3 12:24:21 2007 New Revision: 39775 Removed: pypy/dist/pypy/translator/llvm/backendopt/exception.py Log: (rxe, mwh) remove llvm's now-unused copy of the exception transformer. From xoraxax at codespeak.net Sat Mar 3 12:27:48 2007 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sat, 3 Mar 2007 12:27:48 +0100 (CET) Subject: [pypy-svn] r39776 - pypy/dist/pypy/translator/microbench Message-ID: <20070303112748.90B3310060@code0.codespeak.net> Author: xoraxax Date: Sat Mar 3 12:27:45 2007 New Revision: 39776 Modified: pypy/dist/pypy/translator/microbench/test_bltn.py Log: Add another isinstance microbench. 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 Sat Mar 3 12:27:45 2007 @@ -46,3 +46,12 @@ isinstance(1, int) isinstance("foo", basestring) +def test_isinstance3(): + b2 = baz() + for x in xrange(100000): + isinstance(b2, (bar, baz)) + isinstance(b2, (bar, baz)) + isinstance(b2, (bar, baz)) + isinstance(b2, (bar, baz)) + isinstance(b2, (bar, baz)) + From xoraxax at codespeak.net Sat Mar 3 12:28:57 2007 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sat, 3 Mar 2007 12:28:57 +0100 (CET) Subject: [pypy-svn] r39777 - in pypy/dist/pypy/objspace/std: . test Message-ID: <20070303112857.3C86310060@code0.codespeak.net> Author: xoraxax Date: Sat Mar 3 12:28:54 2007 New Revision: 39777 Modified: pypy/dist/pypy/objspace/std/listmultiobject.py pypy/dist/pypy/objspace/std/test/test_listmultiobject.py Log: Fixed a few remaining bugs in the ChunkList. Modified: pypy/dist/pypy/objspace/std/listmultiobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/listmultiobject.py (original) +++ pypy/dist/pypy/objspace/std/listmultiobject.py Sat Mar 3 12:28:54 2007 @@ -283,14 +283,16 @@ free_slots = -self._length % CHUNK_SIZE if free_slots < how_much: to_allocate = how_much - free_slots - for _ in range(0, (to_allocate / CHUNK_SIZE) + 1): + while to_allocate > 0: self.chunks.append([None] * CHUNK_SIZE) + to_allocate -= CHUNK_SIZE self._length += how_much def length(self): return self._length def getitem(self, i): + assert i < self._length return self.chunks[i >> CHUNK_SIZE_BITS][i & (CHUNK_SIZE - 1)] def _get_chunks_slice(self, start, stop): @@ -343,9 +345,10 @@ assert stop >= 0 delta = stop - start + for j in range(start + delta, length): self.setitem(j - delta, self.getitem(j)) - first_unneeded_chunk = ((length - delta) >> CHUNK_SIZE) + 1 + first_unneeded_chunk = ((length - delta) >> CHUNK_SIZE_BITS) + 1 assert first_unneeded_chunk >= 0 del self.chunks[first_unneeded_chunk:] @@ -361,9 +364,10 @@ def insert(self, i, w_item): assert i >= 0 + length = self._length self._grow() - for j in range(i, self._length): + for j in range(length - 1, 0, -1): self.setitem(j + 1, self.getitem(j)) self.setitem(i, w_item) 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 Sat Mar 3 12:28:54 2007 @@ -124,7 +124,23 @@ cls.space = gettestobjspace(**{ "objspace.std.withsmartresizablelist": True}) + +def _set_chunk_size_bits(bits): + from pypy.conftest import option + if not option.runappdirect: + from pypy.objspace.std import listmultiobject + old_value = listmultiobject.CHUNK_SIZE_BITS + listmultiobject.CHUNK_SIZE_BITS = bits + listmultiobject.CHUNK_SIZE = 2**bits + return old_value + return -1 + class AppTest_ChunkListObject(test_listobject.AppTestW_ListObject): + def setup_class(cls): cls.space = gettestobjspace(**{"objspace.std.withchunklist": True}) + cls.chunk_size_bits = _set_chunk_size_bits(2) + + def teardown_class(cls): + _set_chunk_size_bits(cls.chunk_size_bits) From mwh at codespeak.net Sat Mar 3 12:29:23 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Sat, 3 Mar 2007 12:29:23 +0100 (CET) Subject: [pypy-svn] r39778 - in pypy/dist/pypy/translator/llvm: . backendopt Message-ID: <20070303112923.55ED510063@code0.codespeak.net> Author: mwh Date: Sat Mar 3 12:29:21 2007 New Revision: 39778 Removed: pypy/dist/pypy/translator/llvm/backendopt/mergemallocs.py Modified: pypy/dist/pypy/translator/llvm/funcnode.py Log: (mwh, rxe) remove the long disabled mergemallocs llvm-backendopt. could be resurrected as a general pypy backendopt one day? Modified: pypy/dist/pypy/translator/llvm/funcnode.py ============================================================================== --- pypy/dist/pypy/translator/llvm/funcnode.py (original) +++ pypy/dist/pypy/translator/llvm/funcnode.py Sat Mar 3 12:29:21 2007 @@ -42,10 +42,6 @@ self.graph = value.graph self.bad_switch_block = False - #XXX experimental - #from pypy.translator.llvm.backendopt.mergemallocs import merge_mallocs - #merge_mallocs(self.db.translator, self.graph, self.ref) - def __str__(self): return "" %(self.ref,) From rxe at codespeak.net Sat Mar 3 12:33:48 2007 From: rxe at codespeak.net (rxe at codespeak.net) Date: Sat, 3 Mar 2007 12:33:48 +0100 (CET) Subject: [pypy-svn] r39779 - pypy/dist/pypy/translator/llvm Message-ID: <20070303113348.1D67C10068@code0.codespeak.net> Author: rxe Date: Sat Mar 3 12:33:46 2007 New Revision: 39779 Modified: pypy/dist/pypy/translator/llvm/structnode.py Log: this is needed to pass subarray tests Modified: pypy/dist/pypy/translator/llvm/structnode.py ============================================================================== --- pypy/dist/pypy/translator/llvm/structnode.py (original) +++ pypy/dist/pypy/translator/llvm/structnode.py Sat Mar 3 12:33:46 2007 @@ -199,6 +199,11 @@ self.get_ref(), pos) + def setup(self): + if isinstance(self.value, lltype._subarray): + return + super(FixedSizeArrayNode, self).setup() + class StructVarsizeNode(StructNode): """ A varsize struct constant. Can simply contain From mwh at codespeak.net Sat Mar 3 12:34:28 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Sat, 3 Mar 2007 12:34:28 +0100 (CET) Subject: [pypy-svn] r39780 - pypy/dist/pypy/translator/llvm/backendopt Message-ID: <20070303113428.AFCEB10068@code0.codespeak.net> Author: mwh Date: Sat Mar 3 12:34:26 2007 New Revision: 39780 Removed: pypy/dist/pypy/translator/llvm/backendopt/ Log: (mwh, rxe) and hey, the llvm/backendopt directory goes away From mwh at codespeak.net Sat Mar 3 12:38:29 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Sat, 3 Mar 2007 12:38:29 +0100 (CET) Subject: [pypy-svn] r39781 - pypy/dist/pypy/translator/llvm/llvmcapi Message-ID: <20070303113829.9CD3E10068@code0.codespeak.net> Author: mwh Date: Sat Mar 3 12:38:28 2007 New Revision: 39781 Removed: pypy/dist/pypy/translator/llvm/llvmcapi/ Log: (rxe, mwh) remove one of the several attempts at a python extension for the LLVM code generation interface. From mwh at codespeak.net Sat Mar 3 12:41:54 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Sat, 3 Mar 2007 12:41:54 +0100 (CET) Subject: [pypy-svn] r39782 - pypy/dist/pypy/translator/llvm/wrapable user/ericvrp/wrapable Message-ID: <20070303114154.1775D10061@code0.codespeak.net> Author: mwh Date: Sat Mar 3 12:41:53 2007 New Revision: 39782 Added: user/ericvrp/wrapable/ - copied from r39781, pypy/dist/pypy/translator/llvm/wrapable/ Removed: pypy/dist/pypy/translator/llvm/wrapable/ Log: (rxe, mwh) move pypy/translator/llvm/wrapable to eric's /svn/user dir. From mwh at codespeak.net Sat Mar 3 12:49:00 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Sat, 3 Mar 2007 12:49:00 +0100 (CET) Subject: [pypy-svn] r39783 - pypy/dist/pypy/translator/llvm/pyllvm Message-ID: <20070303114900.63CF710061@code0.codespeak.net> Author: mwh Date: Sat Mar 3 12:48:58 2007 New Revision: 39783 Removed: pypy/dist/pypy/translator/llvm/pyllvm/ Log: (rxe, mwh) arigo's comment to rev 36072: Skip the pyllvm test. Should be removed at some point. The modern way to do this is jit/codegen/llvm. Some point would seem to be now :-) From guido at codespeak.net Sat Mar 3 12:49:46 2007 From: guido at codespeak.net (guido at codespeak.net) Date: Sat, 3 Mar 2007 12:49:46 +0100 (CET) Subject: [pypy-svn] r39784 - pypy/dist/pypy/translator/js/examples/bnb Message-ID: <20070303114946.A13FA10069@code0.codespeak.net> Author: guido Date: Sat Mar 3 12:49:44 2007 New Revision: 39784 Modified: pypy/dist/pypy/translator/js/examples/bnb/start_bnb.py Log: (guido, fijal) Some changes to get IE more supported, given the current results I'm not sure if we'll ever have anything remotely usable though... 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 Sat Mar 3 12:49:44 2007 @@ -7,9 +7,9 @@ import py from pypy.translator.js.main import rpython2javascript -from pypy.translator.js.modules.dom import document +from pypy.translator.js.modules.dom import document, window from pypy.translator.js.modules.mochikit import log, logWarning,\ - createLoggingPane, logDebug + createLoggingPane, logDebug, connect from pypy.translator.js.examples.bnb.bnb import exported_methods from pypy.translator.js import commproxy @@ -71,8 +71,11 @@ #except IndexError: stats.n_sprites += 1 img = document.createElement("img") - img.setAttribute("src", self.filenames[icon_code]) - img.setAttribute("style", 'position:absolute; left:'+x+'px; top:'+y+'px; visibility:visible') + img.src = self.filenames[icon_code] + img.style.position = 'absolute' + img.style.left = x + 'px' + img.style.top = y + 'px' + img.style.visibility = 'visible' document.getElementById("playfield").appendChild(img) try: self.sprites[s].style.visibility = "hidden" @@ -138,24 +141,31 @@ km = KeyManager() def appendPlayfield(msg): + body = document.getElementsByTagName('body')[0] bgcolor = '#000' - document.body.setAttribute('bgcolor', bgcolor) + body.style.backgroundColor = 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') + div.id = 'playfield' + div.style.width = msg['width'] + div.style.height = msg['height'] + div.style.position = 'absolute' + div.style.top = '0px' + div.style.left = '0px' + div.appendChild(document.createTextNode('foobar?')) + #document.body.childNodes.insert(0, div) - document.body.appendChild(div) + body.appendChild(div) def appendPlayfieldXXX(): bgcolor = '#000000' document.body.setAttribute('bgcolor', bgcolor) div = document.createElement("div") - div.setAttribute("id", "playfield") - div.setAttribute('width', 500) - div.setAttribute('height', 250) - div.setAttribute('style', 'position:absolute; top:0px; left:0px') + div.id = 'playfield' + div.style.width = 500 + div.style.height = 250 + div.style.position = 'absolute' + div.style.top = '0px' + div.style.left = '0px' document.body.appendChild(div) def process_message(msg): @@ -211,6 +221,7 @@ def keydown(key): #c = chr(int(key.keyCode)).lower() #c = int(key.keyCode) + key = key._event try: c = key.keyCode if c > ord('0') and c < ord('9'): @@ -224,6 +235,7 @@ log(str(e)) def keyup(key): + key = key._event c = key.keyCode if c > ord('0') and c < ord('9'): pass #don't print warning @@ -249,8 +261,8 @@ def session_dispatcher(sessionid): player.sessionid = sessionid - document.onkeydown = keydown - document.onkeyup = keyup + connect(document, 'onkeydown', keydown) + connect(document, 'onkeyup', keyup) exported_methods.get_message(player.sessionid, player.id, "", bnb_dispatcher) From fijal at codespeak.net Sat Mar 3 13:37:55 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 3 Mar 2007 13:37:55 +0100 (CET) Subject: [pypy-svn] r39787 - pypy/dist/pypy/translator/js/examples/console Message-ID: <20070303123755.E01B210061@code0.codespeak.net> Author: fijal Date: Sat Mar 3 13:37:52 2007 New Revision: 39787 Modified: pypy/dist/pypy/translator/js/examples/console/client.py pypy/dist/pypy/translator/js/examples/console/console.py pypy/dist/pypy/translator/js/examples/console/session.py Log: Multiple console thingie is working, but (WARNING!) not if you run them in one browser 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 Sat Mar 3 13:37:52 2007 @@ -53,7 +53,7 @@ exported_methods.refresh(glob.sess_id, cmd + "\n", refresh_console) def console_onload(): - createLoggingPane(True) + #createLoggingPane(True) inp_elem = dom.document.getElementById("inp") inp_elem.focus() dom.document.onkeypress = keypressed 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 Sat Mar 3 13:37:52 2007 @@ -10,11 +10,14 @@ from pypy.translator.js.lib.support import callback from pypy.translator.js import commproxy from pypy.translator.js.examples.console.session import Interpreter +from pypeers.httpserver import GreenHTTPServer commproxy.USE_MOCHIKIT = True FUNCTION_LIST = ["console_onload"] +class Ignore(Exception): + pass def js_source(): import client @@ -23,15 +26,25 @@ class Sessions(object): def __init__(self): self.sessions = {} + self.updating = {} def new_session(self): ip = Interpreter("python") self.sessions[ip.pid] = ip + self.updating[ip.pid] = False return ip.pid def update_session(self, pid, to_write=None): ip = self.sessions[pid] - return ip.interact(to_write) + if self.updating[pid]: + ip.write_only(to_write) + raise Ignore() + self.updating[pid] = True + ret = ip.interact(to_write) + self.updating[pid] = False + if not ret: + return "" + return ret # We hack here, cause in exposed methods we don't have global 'server' # state @@ -45,20 +58,23 @@ @callback(retval=[str]) def refresh(self, pid=0, to_write=""): - print "Refresh %s" % to_write + #print "Refresh %s %d" % (to_write, int(pid)) try: return ["refresh", sessions.update_session(int(pid), to_write)] except KeyError: return ["disconnected"] + except Ignore: + return ["ignore"] @callback(retval=[str]) def refresh_empty(self, pid=0): - print "Empty refresh" + #print "Empty refresh %d" % int(pid) try: return ["refresh", sessions.update_session(int(pid), None)] except KeyError: return ["disconnected"] - + except Ignore: + return ["ignore"] exported_methods = ExportedMethods() @@ -79,5 +95,6 @@ if __name__ == '__main__': addr = ('', 8007) - httpd = server.create_server(server_address=addr, handler=Handler) + httpd = server.create_server(server_address=addr, handler=Handler, + server=GreenHTTPServer) httpd.serve_forever() Modified: pypy/dist/pypy/translator/js/examples/console/session.py ============================================================================== --- pypy/dist/pypy/translator/js/examples/console/session.py (original) +++ pypy/dist/pypy/translator/js/examples/console/session.py Sat Mar 3 13:37:52 2007 @@ -13,25 +13,9 @@ import py import subprocess from Queue import Queue -from pypeers.greensock2 import autogreenlet, sleep, wait, meetingpoint +from pypeers.greensock2 import autogreenlet, Timer, wait, meetingpoint,\ + Interrupted from pypeers.pipe.fd import FDInput - -def timeout_read(fd, timeout): - read = [] - giver, accepter = meetingpoint() - - def timeout_fun(): - sleep(timeout) - giver.give(None) - g_read.interrupt() - - def read_fun(): - giver.give(fd.recv(1024)) - g_timer.interrupt() - - g_timer = autogreenlet(timeout_fun) - g_read = autogreenlet(read_fun) - return accepter.accept() class Interpreter(object): def __init__(self, python, timeout=TIMEOUT): @@ -43,10 +27,24 @@ self.pid = pipe.pid self.timeout = timeout + def timeout_read(self, fd, timeout): + timer = Timer(timeout) + try: + data = fd.recv(1024) + except Interrupted: + data = None + else: + timer.stop() + return data + + def write_only(self, to_write): + if to_write: + self.pipe.stdin.write(to_write) + def interact(self, to_write=None): if to_write is not None: self.pipe.stdin.write(to_write) - return timeout_read(self.read_fd, self.timeout) + return self.timeout_read(self.read_fd, self.timeout) def close(self): self.pipe.stdin.close() From arigo at codespeak.net Sat Mar 3 13:47:55 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 3 Mar 2007 13:47:55 +0100 (CET) Subject: [pypy-svn] r39790 - pypy/dist/pypy/config Message-ID: <20070303124755.D1F2F10061@code0.codespeak.net> Author: arigo Date: Sat Mar 3 13:47:52 2007 New Revision: 39790 Modified: pypy/dist/pypy/config/pypyoption.py Log: * 'withprebuiltchar' is a clear win. * 'sharesmallstr' makes no consistent difference on richards, more benchmarking needed... Modified: pypy/dist/pypy/config/pypyoption.py ============================================================================== --- pypy/dist/pypy/config/pypyoption.py (original) +++ pypy/dist/pypy/config/pypyoption.py Sat Mar 3 13:47:52 2007 @@ -228,6 +228,7 @@ ("objspace.std.withrangelist", True), ("objspace.std.withmethodcache", True), # ("objspace.std.withfastslice", True), + ("objspace.std.withprebuiltchar", True), ("objspace.std.optimized_int_add", True), ], cmdline="--faassen", negation=False), From cfbolz at codespeak.net Sat Mar 3 13:48:25 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sat, 3 Mar 2007 13:48:25 +0100 (CET) Subject: [pypy-svn] r39791 - in pypy/branch/rope-branch/pypy/objspace/std: . test Message-ID: <20070303124825.7A1C710061@code0.codespeak.net> Author: cfbolz Date: Sat Mar 3 13:48:23 2007 New Revision: 39791 Modified: pypy/branch/rope-branch/pypy/objspace/std/rope.py pypy/branch/rope-branch/pypy/objspace/std/test/test_rope.py Log: use the rpython hash cache when hashing LiteralStringNode Modified: pypy/branch/rope-branch/pypy/objspace/std/rope.py ============================================================================== --- pypy/branch/rope-branch/pypy/objspace/std/rope.py (original) +++ pypy/branch/rope-branch/pypy/objspace/std/rope.py Sat Mar 3 13:48:23 2007 @@ -767,9 +767,19 @@ def hash_rope(rope): from pypy.rlib.rarithmetic import intmask + from pypy.rlib.objectmodel import we_are_translated length = rope.length() if length == 0: x = -1 + elif isinstance(rope, LiteralStringNode): + if we_are_translated(): + x = hash(s) # to use the hash cache in rpython strings + else: + # to make sure we get the same hash as rpython (otherwise + # translation will freeze W_DictObjects where we can't find the + # keys any more!) + x = _hash_string(s) + return hash(rope.s) else: x = ord(rope.getitem(0)) << 7 iter = CharIterator(rope) Modified: pypy/branch/rope-branch/pypy/objspace/std/test/test_rope.py ============================================================================== --- pypy/branch/rope-branch/pypy/objspace/std/test/test_rope.py (original) +++ pypy/branch/rope-branch/pypy/objspace/std/test/test_rope.py Sat Mar 3 13:48:23 2007 @@ -293,8 +293,9 @@ def test_hash(): from pypy.rlib.rarithmetic import _hash_string - rope, st = make_random_string() - assert hash_rope(rope) == _hash_string(st) + for i in range(10): + rope, st = make_random_string() + assert hash_rope(rope) == _hash_string(st) def test_equality(): l = [make_random_string() for i in range(3)] From mwh at codespeak.net Sat Mar 3 13:52:44 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Sat, 3 Mar 2007 13:52:44 +0100 (CET) Subject: [pypy-svn] r39792 - pypy/dist/pypy/translator/llvm/test Message-ID: <20070303125244.E84CB10061@code0.codespeak.net> Author: mwh Date: Sat Mar 3 13:52:41 2007 New Revision: 39792 Modified: pypy/dist/pypy/translator/llvm/test/test_gc.py Log: (rxe, mwh) rewrite an insane line, and enable the refcounting test again (it passes now, no idea when it started doing so) Modified: pypy/dist/pypy/translator/llvm/test/test_gc.py ============================================================================== --- pypy/dist/pypy/translator/llvm/test/test_gc.py (original) +++ pypy/dist/pypy/translator/llvm/test/test_gc.py Sat Mar 3 13:52:41 2007 @@ -21,7 +21,7 @@ n = 5000 result = tuple_getitem(n) assert f(n) == result - get_heap_size = getattr(mod, "GC_get_heap_size_wrapper") + get_heap_size = mod.GC_get_heap_size_wrapper heap_size_start = get_heap_size() for i in range(0,25): assert f(n) == result @@ -41,7 +41,6 @@ assert f(5000) == tuple_getitem(5000) def test_ref(): - py.test.skip("broken by r32613, partially fixed by r32619 but not really") def tuple_getitem(n): x = 666 i = 0 From rxe at codespeak.net Sat Mar 3 13:55:15 2007 From: rxe at codespeak.net (rxe at codespeak.net) Date: Sat, 3 Mar 2007 13:55:15 +0100 (CET) Subject: [pypy-svn] r39793 - pypy/dist/pypy/translator/llvm/test Message-ID: <20070303125515.35EB510061@code0.codespeak.net> Author: rxe Date: Sat Mar 3 13:55:13 2007 New Revision: 39793 Modified: pypy/dist/pypy/translator/llvm/test/test_gc.py Log: (mwh, rxe) - remove a redundant comment and XXX Modified: pypy/dist/pypy/translator/llvm/test/test_gc.py ============================================================================== --- pypy/dist/pypy/translator/llvm/test/test_gc.py (original) +++ pypy/dist/pypy/translator/llvm/test/test_gc.py Sat Mar 3 13:55:13 2007 @@ -5,10 +5,6 @@ from pypy.translator.llvm.test.runtest import * def test_GC_malloc(): - #XXX how to get to gcpolicy? - #if not use_boehm_gc: - # py.test.skip("test_GC_malloc skipped because Boehm collector library was not found") - # return def tuple_getitem(n): x = 666 i = 0 From mwh at codespeak.net Sat Mar 3 13:57:25 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Sat, 3 Mar 2007 13:57:25 +0100 (CET) Subject: [pypy-svn] r39794 - pypy/dist/pypy/translator/llvm/demo Message-ID: <20070303125725.E485610061@code0.codespeak.net> Author: mwh Date: Sat Mar 3 13:57:22 2007 New Revision: 39794 Removed: pypy/dist/pypy/translator/llvm/demo/ Log: (rxe, mwh) kill the llvm/demo directory. all the demos are elsewhere, or obsolete. From xoraxax at codespeak.net Sat Mar 3 14:00:21 2007 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sat, 3 Mar 2007 14:00:21 +0100 (CET) Subject: [pypy-svn] r39795 - pypy/dist/pypy/translator/microbench Message-ID: <20070303130021.3D61A10061@code0.codespeak.net> Author: xoraxax Date: Sat Mar 3 14:00:15 2007 New Revision: 39795 Added: pypy/dist/pypy/translator/microbench/test_list.py Log: Added list microbench. Added: pypy/dist/pypy/translator/microbench/test_list.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/microbench/test_list.py Sat Mar 3 14:00:15 2007 @@ -0,0 +1,48 @@ + +iterations = 500000 + +d_x = {} +it_range = range(iterations) + + +def test_list_append(): + l = [] + for x in it_range: + l.append(x) + + +def test_list_setitem(): + l = range(iterations / 2) + idx = iterations / 2 - 200 + for x in it_range: + l[idx] = x + l[idx - 300] = x + l[idx - 42] = x + l[idx + 3] = x + + +def test_list_slice(): + l = range(iterations / 2) + l.append("foo") + for x in range(500): + l[42:420] + l[500:76:-3] + +def test_list_getitem(): + l = range(iterations / 2) + l.append("foo") + idx = iterations / 43 + for x in it_range: + l[8] + l[idx] + l[3] + + +def test_list_extend(): + l = range(iterations / 2) + l.append("foo") + k = l[:] + for x in range(50): + t = l[:] + t.extend(k) + From rxe at codespeak.net Sat Mar 3 14:09:19 2007 From: rxe at codespeak.net (rxe at codespeak.net) Date: Sat, 3 Mar 2007 14:09:19 +0100 (CET) Subject: [pypy-svn] r39796 - in pypy/dist/pypy/translator: . llvm llvm/test Message-ID: <20070303130919.3D68A1005A@code0.codespeak.net> Author: rxe Date: Sat Mar 3 14:09:17 2007 New Revision: 39796 Modified: pypy/dist/pypy/translator/driver.py pypy/dist/pypy/translator/llvm/genllvm.py pypy/dist/pypy/translator/llvm/test/test_gc.py Log: (mwh, rxe) get rid of a redundant and misleading gcpolicy option Modified: pypy/dist/pypy/translator/driver.py ============================================================================== --- pypy/dist/pypy/translator/driver.py (original) +++ pypy/dist/pypy/translator/driver.py Sat Mar 3 14:09:17 2007 @@ -474,9 +474,7 @@ from pypy.translator.llvm import genllvm - # XXX Need more options for policies/llvm-backendoptions here? - self.llvmgen = genllvm.GenLLVM(translator, self.config.translation.gc, - self.standalone) + self.llvmgen = genllvm.GenLLVM(translator, self.standalone) llvm_filename = self.llvmgen.gen_llvm_source(self.entry_point) self.log.info("written: %s" % (llvm_filename,)) Modified: pypy/dist/pypy/translator/llvm/genllvm.py ============================================================================== --- pypy/dist/pypy/translator/llvm/genllvm.py (original) +++ pypy/dist/pypy/translator/llvm/genllvm.py Sat Mar 3 14:09:17 2007 @@ -24,18 +24,12 @@ # see create_codewriter() below function_count = {} - def __init__(self, translator, gcpolicy, standalone, + def __init__(self, translator, standalone, debug=False, logging=True, stackless=False): # reset counters LLVMNode.nodename_count = {} - if gcpolicy is None: - gcpolicy = "boehm" - - self.gcpolicy = gcpolicy - - self.standalone = standalone self.translator = translator @@ -76,15 +70,16 @@ create ll file for c file create codewriter """ - # please dont ask! + # XXX please dont ask! from pypy.translator.c.genc import CStandaloneBuilder - from pypy.translator.c import gc cbuild = CStandaloneBuilder(self.translator, func, config=self.config) cbuild.stackless = self.stackless c_db = cbuild.generate_graphs_for_llinterp() self.db = Database(self, self.translator) - self.db.gcpolicy = GcPolicy.new(self.db, self.gcpolicy) + + # XXX hardcoded for now + self.db.gcpolicy = GcPolicy.new(self.db, 'boehm') # get entry point entry_point = self.get_entry_point(func) @@ -354,7 +349,6 @@ # create genllvm gen = GenLLVM(translator, - gcpolicy, standalone, debug=debug, logging=logging, Modified: pypy/dist/pypy/translator/llvm/test/test_gc.py ============================================================================== --- pypy/dist/pypy/translator/llvm/test/test_gc.py (original) +++ pypy/dist/pypy/translator/llvm/test/test_gc.py Sat Mar 3 14:09:17 2007 @@ -1,9 +1,11 @@ import sys import py - from pypy.translator.llvm.test.runtest import * +def setup_module(mod): + py.test.skip('skipping somewhat futile tests') + def test_GC_malloc(): def tuple_getitem(n): x = 666 From rxe at codespeak.net Sat Mar 3 14:16:48 2007 From: rxe at codespeak.net (rxe at codespeak.net) Date: Sat, 3 Mar 2007 14:16:48 +0100 (CET) Subject: [pypy-svn] r39797 - in pypy/dist/pypy/translator/llvm: . test Message-ID: <20070303131648.D1F7A1005A@code0.codespeak.net> Author: rxe Date: Sat Mar 3 14:16:46 2007 New Revision: 39797 Modified: pypy/dist/pypy/translator/llvm/genllvm.py pypy/dist/pypy/translator/llvm/test/runtest.py pypy/dist/pypy/translator/llvm/test/test_stackless.py Log: (mwh, rxe) shuffle code around a bit, the genllvm_compile() is only ever called from tests. now we can do some refactoring Modified: pypy/dist/pypy/translator/llvm/genllvm.py ============================================================================== --- pypy/dist/pypy/translator/llvm/genllvm.py (original) +++ pypy/dist/pypy/translator/llvm/genllvm.py Sat Mar 3 14:16:46 2007 @@ -17,7 +17,6 @@ from pypy.translator.llvm.externs2ll import setup_externs, generate_llfile 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, postfix class GenLLVM(object): @@ -294,70 +293,3 @@ for s in stats: log('STATS %s' % str(s)) -#______________________________________________________________________________ - -def genllvm_compile(function, - annotation, - - # genllvm options - gcpolicy=None, - standalone=False, - stackless=False, - - # debug options - view=False, - debug=False, - logging=False, - log_source=False, - - # pass to compile - optimize=True, - **kwds): - - """ helper for genllvm """ - - assert llvm_is_on_path() - - # annotate/rtype - from pypy.translator.translator import TranslationContext - from pypy.translator.backendopt.all import backend_optimizations - from pypy.config.pypyoption import get_pypy_config - config = get_pypy_config(translating=True) - config.translation.gc = 'boehm' - translator = TranslationContext(config=config) - translator.buildannotator().build_types(function, annotation) - translator.buildrtyper().specialize() - - # use backend optimizations? - if optimize: - backend_optimizations(translator, raisingop2direct_call=True) - else: - backend_optimizations(translator, - raisingop2direct_call=True, - inline_threshold=0, - mallocs=False, - merge_if_blocks=False, - constfold=False) - - # note: this is without stackless and policy transforms - if view or conftest.option.view: - translator.view() - - if stackless: - from pypy.translator.transform import insert_ll_stackcheck - insert_ll_stackcheck(translator) - - # create genllvm - gen = GenLLVM(translator, - standalone, - debug=debug, - logging=logging, - stackless=stackless) - - filename = gen.gen_llvm_source(function) - - log_source = kwds.pop("log_source", False) - if log_source: - log(open(filename).read()) - - return gen.compile_llvm_source(optimize=optimize, **kwds) 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 Mar 3 14:16:46 2007 @@ -1,7 +1,8 @@ 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, llvm_version, gcc_version +from pypy.translator.llvm.genllvm import GenLLVM + optimize_tests = False MINIMUM_LLVM_VERSION = 1.9 @@ -11,6 +12,8 @@ run_isolated_only = True do_not_isolate = False +from pypy import conftest + def _cleanup(leave=0): # no test should ever need more than 5 compiled functions if leave: @@ -46,6 +49,74 @@ return False return True +#______________________________________________________________________________ + +def genllvm_compile(function, + annotation, + + # genllvm options + gcpolicy=None, + standalone=False, + stackless=False, + + # debug options + view=False, + debug=False, + logging=False, + log_source=False, + + # pass to compile + optimize=True, + **kwds): + + """ helper for genllvm """ + + assert llvm_is_on_path() + + # annotate/rtype + from pypy.translator.translator import TranslationContext + from pypy.translator.backendopt.all import backend_optimizations + from pypy.config.pypyoption import get_pypy_config + config = get_pypy_config(translating=True) + config.translation.gc = 'boehm' + translator = TranslationContext(config=config) + translator.buildannotator().build_types(function, annotation) + translator.buildrtyper().specialize() + + # use backend optimizations? + if optimize: + backend_optimizations(translator, raisingop2direct_call=True) + else: + backend_optimizations(translator, + raisingop2direct_call=True, + inline_threshold=0, + mallocs=False, + merge_if_blocks=False, + constfold=False) + + # note: this is without stackless and policy transforms + if view or conftest.option.view: + translator.view() + + if stackless: + from pypy.translator.transform import insert_ll_stackcheck + insert_ll_stackcheck(translator) + + # create genllvm + gen = GenLLVM(translator, + standalone, + debug=debug, + logging=logging, + stackless=stackless) + + filename = gen.gen_llvm_source(function) + + log_source = kwds.pop("log_source", False) + if log_source: + log(open(filename).read()) + + return gen.compile_llvm_source(optimize=optimize, **kwds) + def compile_test(function, annotation, isolate=True, **kwds): " returns module and compiled function " if llvm_test(): Modified: pypy/dist/pypy/translator/llvm/test/test_stackless.py ============================================================================== --- pypy/dist/pypy/translator/llvm/test/test_stackless.py (original) +++ pypy/dist/pypy/translator/llvm/test/test_stackless.py Sat Mar 3 14:16:46 2007 @@ -15,9 +15,11 @@ os.write(1, str(fn()) + "\n") return 0 - exe_path = genllvm_compile(entry_point, [s_list_of_strings], optimize=False, - exe_name="stacktest", standalone=True, - stackless=True, logging=False) + # XXX run this with interactive + #exe_path = genllvm_compile(entry_point, [s_list_of_strings], optimize=False, + # exe_name="stacktest", standalone=True, + # stackless=True, logging=False) + res = os.system(exe_path) return int(res.strip()) From cfbolz at codespeak.net Sat Mar 3 14:17:18 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sat, 3 Mar 2007 14:17:18 +0100 (CET) Subject: [pypy-svn] r39798 - in pypy/branch/rope-branch/pypy/objspace/std: . test Message-ID: <20070303131718.4D32B10061@code0.codespeak.net> Author: cfbolz Date: Sat Mar 3 14:17:16 2007 New Revision: 39798 Modified: pypy/branch/rope-branch/pypy/objspace/std/rope.py pypy/branch/rope-branch/pypy/objspace/std/test/test_rope.py Log: fix typos and write a test Modified: pypy/branch/rope-branch/pypy/objspace/std/rope.py ============================================================================== --- pypy/branch/rope-branch/pypy/objspace/std/rope.py (original) +++ pypy/branch/rope-branch/pypy/objspace/std/rope.py Sat Mar 3 14:17:16 2007 @@ -766,20 +766,19 @@ def hash_rope(rope): - from pypy.rlib.rarithmetic import intmask + from pypy.rlib.rarithmetic import intmask, _hash_string from pypy.rlib.objectmodel import we_are_translated length = rope.length() if length == 0: x = -1 elif isinstance(rope, LiteralStringNode): if we_are_translated(): - x = hash(s) # to use the hash cache in rpython strings + return hash(rope.s) # to use the hash cache in rpython strings else: # to make sure we get the same hash as rpython (otherwise # translation will freeze W_DictObjects where we can't find the # keys any more!) - x = _hash_string(s) - return hash(rope.s) + return _hash_string(rope.s) else: x = ord(rope.getitem(0)) << 7 iter = CharIterator(rope) Modified: pypy/branch/rope-branch/pypy/objspace/std/test/test_rope.py ============================================================================== --- pypy/branch/rope-branch/pypy/objspace/std/test/test_rope.py (original) +++ pypy/branch/rope-branch/pypy/objspace/std/test/test_rope.py Sat Mar 3 14:17:16 2007 @@ -296,6 +296,12 @@ for i in range(10): rope, st = make_random_string() assert hash_rope(rope) == _hash_string(st) + rope = LiteralStringNode(st) + assert hash_rope(rope) == _hash_string(st) + charlist = [chr(random.randrange(0, 256)) for i in range(10)] + st = "".join(charlist) + rope = LiteralStringNode(st) + assert hash_rope(rope) == _hash_string(st) def test_equality(): l = [make_random_string() for i in range(3)] From guido at codespeak.net Sat Mar 3 14:21:35 2007 From: guido at codespeak.net (guido at codespeak.net) Date: Sat, 3 Mar 2007 14:21:35 +0100 (CET) Subject: [pypy-svn] r39799 - pypy/dist/pypy/translator/microbench Message-ID: <20070303132135.A7E331005A@code0.codespeak.net> Author: guido Date: Sat Mar 3 14:21:33 2007 New Revision: 39799 Added: pypy/dist/pypy/translator/microbench/test_formatting.py Log: Microbenchmark for string formatting. Added: pypy/dist/pypy/translator/microbench/test_formatting.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/microbench/test_formatting.py Sat Mar 3 14:21:33 2007 @@ -0,0 +1,28 @@ +iterations = 100000 + +def test_simple_formatting(): + i = 0 + while i < iterations: + '%s - %s - %s' % ('foo', 'bar', 'baz') + i += 1 + +def test_dict_formatting(): + i = 0 + d = {'foo': 'bar', 'baz': 'qux'} + while i < iterations: + '%(foo)s - %(baz)s' % d + i += 1 + +def test_number_formatting(): + i = 0 + while i < iterations: + '%04d %g %2f' % (10, 10.1234, 10.1234) + i += 1 + +def test_repr_formatting(): + i = 0 + d = {'foo': 'bar', 'baz': 'qux'} + while i < iterations: + '%r' % (d,) + i += 1 + From rxe at codespeak.net Sat Mar 3 14:29:23 2007 From: rxe at codespeak.net (rxe at codespeak.net) Date: Sat, 3 Mar 2007 14:29:23 +0100 (CET) Subject: [pypy-svn] r39800 - in pypy/dist/pypy/translator/llvm: . test Message-ID: <20070303132923.C43CF1005A@code0.codespeak.net> Author: rxe Date: Sat Mar 3 14:29:21 2007 New Revision: 39800 Modified: pypy/dist/pypy/translator/llvm/genllvm.py pypy/dist/pypy/translator/llvm/opwriter.py pypy/dist/pypy/translator/llvm/test/runtest.py Log: (mwh, rxe) kill/rationalize some flags Modified: pypy/dist/pypy/translator/llvm/genllvm.py ============================================================================== --- pypy/dist/pypy/translator/llvm/genllvm.py (original) +++ pypy/dist/pypy/translator/llvm/genllvm.py Sat Mar 3 14:29:21 2007 @@ -24,7 +24,7 @@ function_count = {} def __init__(self, translator, standalone, - debug=False, logging=True, stackless=False): + debug=True, logging=True, stackless=False): # reset counters LLVMNode.nodename_count = {} @@ -35,12 +35,10 @@ self.config = translator.config self.stackless = stackless - # the debug flag is for creating comments of every operation - # that may be executed - self.debug = debug + # the debug flag is for creating comments of every operation that may be executed + self.debug = debug - # the logging flag is for logging information statistics in the build - # process + # the logging flag is for logging information statistics in the build process self.logging = logging self.source_generated = False Modified: pypy/dist/pypy/translator/llvm/opwriter.py ============================================================================== --- pypy/dist/pypy/translator/llvm/opwriter.py (original) +++ pypy/dist/pypy/translator/llvm/opwriter.py Sat Mar 3 14:29:21 2007 @@ -128,7 +128,10 @@ meth = getattr(self, op.opname, None) if not meth: raise Exception, "operation %s not found" % op.opname - self.codewriter.comment(str(op)) + + # XXX bit unclean + if self.db.genllvm.debug: + self.codewriter.comment(str(op)) meth(opr) def _generic_pow(self, opr, onestr): 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 Mar 3 14:29:21 2007 @@ -53,15 +53,9 @@ def genllvm_compile(function, annotation, - - # genllvm options - gcpolicy=None, - standalone=False, - stackless=False, # debug options - view=False, - debug=False, + debug=True, logging=False, log_source=False, @@ -95,19 +89,15 @@ constfold=False) # note: this is without stackless and policy transforms - if view or conftest.option.view: + if conftest.option.view: translator.view() - if stackless: - from pypy.translator.transform import insert_ll_stackcheck - insert_ll_stackcheck(translator) - # create genllvm + standalone = False gen = GenLLVM(translator, standalone, debug=debug, - logging=logging, - stackless=stackless) + logging=logging) filename = gen.gen_llvm_source(function) @@ -130,7 +120,7 @@ _cleanup(leave=3) optimize = kwds.pop('optimize', optimize_tests) mod, fn = genllvm_compile(function, annotation, optimize=optimize, - logging=False, isolate=isolate, **kwds) + isolate=isolate, **kwds) if isolate: ext_modules.append(mod) return mod, fn From asigfrid at codespeak.net Sat Mar 3 14:34:05 2007 From: asigfrid at codespeak.net (asigfrid at codespeak.net) Date: Sat, 3 Mar 2007 14:34:05 +0100 (CET) Subject: [pypy-svn] r39801 - pypy/dist/pypy/translator/goal Message-ID: <20070303133405.DDCC21005A@code0.codespeak.net> Author: asigfrid Date: Sat Mar 3 14:34:04 2007 New Revision: 39801 Modified: pypy/dist/pypy/translator/goal/app_main.py Log: Issue 145 resolved (asigfrid, arre) Added -m option to pypy-c Fixed bug in processing -c option 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 Sat Mar 3 14:34:04 2007 @@ -9,6 +9,7 @@ -S do not 'import site' on initialization -u unbuffered binary stdout and stderr -h, --help show this help message and exit + -m library module to be run as a script (terminates option list) --version print the PyPy version --info print translation information about this PyPy executable """ @@ -176,6 +177,7 @@ run_command = False import_site = True i = 0 + run_module = False while i < len(argv): arg = argv[i] if not arg.startswith('-'): @@ -183,7 +185,7 @@ if arg == '-i': go_interactive = True elif arg == '-c': - if i >= len(argv): + if i+1 >= len(argv): print_error('Argument expected for the -c option') return 2 run_command = True @@ -203,6 +205,13 @@ return 0 elif arg == '-S': import_site = False + elif arg == '-m': + i += 1 + if i >= len(argv): + print_error('Argument expected for the -m option') + return 2 + run_module = True + break elif arg == '--': i += 1 break # terminates option list @@ -246,6 +255,11 @@ def run_it(): exec cmd in mainmodule.__dict__ success = run_toplevel(run_it) + elif run_module: + def run_it(): + import runpy + runpy.run_module(sys.argv[0], None, '__main__', True) + success = run_toplevel(run_it) else: scriptdir = resolvedirof(sys.argv[0]) sys.path.insert(0, scriptdir) From antocuni at codespeak.net Sat Mar 3 14:46:29 2007 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Sat, 3 Mar 2007 14:46:29 +0100 (CET) Subject: [pypy-svn] r39802 - in pypy/dist/pypy: rpython rpython/lltypesystem/module rpython/module rpython/module/test rpython/ootypesystem/module translator/c translator/c/test Message-ID: <20070303134629.47D631005A@code0.codespeak.net> Author: antocuni Date: Sat Mar 3 14:46:27 2007 New Revision: 39802 Removed: pypy/dist/pypy/rpython/module/ll_math.py pypy/dist/pypy/rpython/module/test/test_ll_math.py Modified: pypy/dist/pypy/rpython/extfunc.py pypy/dist/pypy/rpython/extfunctable.py pypy/dist/pypy/rpython/lltypesystem/module/ll_math.py pypy/dist/pypy/rpython/ootypesystem/module/ll_math.py pypy/dist/pypy/translator/c/extfunc.py pypy/dist/pypy/translator/c/node.py pypy/dist/pypy/translator/c/test/test_extfunc.py Log: (antocuni, pedronis) Kill the old rpython/module/ll_math.py module and use the new way for declaring external functions. Things are slightly less messy now... Modified: pypy/dist/pypy/rpython/extfunc.py ============================================================================== --- pypy/dist/pypy/rpython/extfunc.py (original) +++ pypy/dist/pypy/rpython/extfunc.py Sat Mar 3 14:46:27 2007 @@ -1,10 +1,9 @@ - from pypy.rpython.extregistry import ExtRegistryEntry from pypy.rpython.lltypesystem.lltype import typeOf from pypy.objspace.flow.model import Constant from pypy.annotation.model import unionof from pypy.annotation.signature import annotation -from pypy.annotation import model as annmodel + import py class _callable(object): @@ -20,12 +19,15 @@ # we defer a bit annotation here def compute_result_annotation(self): + from pypy.annotation import model as annmodel return annmodel.SomeGenericCallable([annotation(i, self.bookkeeper) for i in self.instance.args], annotation(self.instance.result, self.bookkeeper)) class ExtFuncEntry(ExtRegistryEntry): def compute_result_annotation(self, *args_s): + if hasattr(self, 'ann_hook'): + self.ann_hook() if self.signature_args is not None: assert len(args_s) == len(self.signature_args),\ "Argument number mismatch" @@ -46,20 +48,33 @@ ll_result = r_result.lowleveltype name = getattr(self, 'name', None) or self.instance.__name__ method_name = rtyper.type_system.name[:2] + 'typeimpl' + fake_method_name = rtyper.type_system.name[:2] + 'typefakeimpl' impl = getattr(self, method_name, None) + fakeimpl = getattr(self, fake_method_name, self.instance) if impl: obj = rtyper.getannmixlevel().delayedfunction( impl.im_func, self.signature_args, self.signature_result) else: obj = rtyper.type_system.getexternalcallable(args_ll, ll_result, - name, _entry=self, _callable=self.instance) + name, _entry=self, _callable=fakeimpl) vlist = [hop.inputconst(typeOf(obj), obj)] + hop.inputargs(*args_r) hop.exception_is_here() return hop.genop('direct_call', vlist, r_result) def register_external(function, args, result=None, export_name=None, - llimpl=None, ooimpl=None): - + llimpl=None, ooimpl=None, + llfakeimpl=None, oofakeimpl=None, + annotation_hook=None): + """ + function: the RPython function that will be rendered as an external function (e.g.: math.floor) + args: a list containing the annotation of the arguments + result: surprisingly enough, the annotation of the result + export_name: the name of the function as it will be seen by the backends + llimpl, ooimpl: optional; if provided, these RPython functions are called instead of the target function + llfakeimpl, oofakeimpl: optional; if provided, they are called by the llinterpreter + annotationhook: optional; a callable that is called during annotation, useful for genc hacks + """ + class FunEntry(ExtFuncEntry): _about_ = function if args is None: @@ -72,6 +87,12 @@ lltypeimpl = llimpl if ooimpl: ootypeimpl = ooimpl + if llfakeimpl: + lltypefakeimpl = llfakeimpl + if oofakeimpl: + ootypefakeimpl = oofakeimpl + if annotation_hook: + ann_hook = staticmethod(annotation_hook) if export_name: FunEntry.__name__ = export_name Modified: pypy/dist/pypy/rpython/extfunctable.py ============================================================================== --- pypy/dist/pypy/rpython/extfunctable.py (original) +++ pypy/dist/pypy/rpython/extfunctable.py Sat Mar 3 14:46:27 2007 @@ -173,18 +173,6 @@ 'OS_WAITPID') return SomeTuple((SomeInteger(),)*2) -def frexpannotation(*args): - from pypy.annotation.model import SomeInteger, SomeTuple, SomeFloat - from pypy.rpython.lltypesystem.module.ll_math import ll_frexp_result - record_call(ll_frexp_result, (SomeFloat(), SomeInteger()), 'MATH_FREXP') - return SomeTuple((SomeFloat(), SomeInteger())) - -def modfannotation(*args): - from pypy.annotation.model import SomeTuple, SomeFloat - from pypy.rpython.lltypesystem.module.ll_math import ll_modf_result - record_call(ll_modf_result, (SomeFloat(), SomeFloat()), 'MATH_MODF') - return SomeTuple((SomeFloat(), SomeFloat())) - def strnullannotation(*args): from pypy.annotation.model import SomeString return SomeString(can_be_None=True) @@ -243,28 +231,6 @@ declare(time.clock , float , 'll_time/clock') declare(time.sleep , noneannotation, 'll_time/sleep') -# ___________________________ -# math functions - -declare(math.frexp , frexpannotation, 'll_math/frexp') -declare(math.atan2 , float , 'll_math/atan2') -declare(math.fmod , float , 'll_math/fmod') -declare(math.floor , float , 'll_math/floor') -declare(math.ldexp , float , 'll_math/ldexp') -declare(math.modf , modfannotation, 'll_math/modf') -declare(math.hypot , float , 'll_math/hypot') -declare(math.pow , float , 'll_math/pow') - -# the following functions all take one float, return one float -# and are part of math.h -simple_math_functions = [ - 'acos', 'asin', 'atan', 'ceil', 'cos', 'cosh', 'exp', 'fabs', - 'floor', 'log', 'log10', 'sin', 'sinh', 'sqrt', 'tan', 'tanh' - ] - -for name in simple_math_functions: - declare(getattr(math, name), float, 'll_math/%s' % name) - # ___________________________________________________________ # win/NT hack: patch ntpath.isabs() to be RPythonic @@ -325,3 +291,54 @@ AssertionError : True, RuntimeError : True, } + + + +# ______________________________________________________________ +# this declarations use the new interface for external functions +# all the above declaration should me moved here at some point. + +from extfunc import register_external + +# ___________________________ +# math functions + +from pypy.rpython.lltypesystem.module import ll_math +from pypy.rpython.ootypesystem.module import ll_math as oo_math + +# the following functions all take one float, return one float +# and are part of math.h +simple_math_functions = [ + 'acos', 'asin', 'atan', 'ceil', 'cos', 'cosh', 'exp', 'fabs', + 'floor', 'log', 'log10', 'sin', 'sinh', 'sqrt', 'tan', 'tanh' + ] +for name in simple_math_functions: + register_external(getattr(math, name), [float], float, "ll_math.ll_math_%s" % name) + +def frexp_hook(): + from pypy.annotation.model import SomeInteger, SomeTuple, SomeFloat + from pypy.rpython.lltypesystem.module.ll_math import ll_frexp_result + record_call(ll_frexp_result, (SomeFloat(), SomeInteger()), 'MATH_FREXP') + +def modf_hook(): + from pypy.annotation.model import SomeTuple, SomeFloat + from pypy.rpython.lltypesystem.module.ll_math import ll_modf_result + record_call(ll_modf_result, (SomeFloat(), SomeFloat()), 'MATH_MODF') + +complex_math_functions = [ + ('frexp', [float], (float, int), frexp_hook), + ('atan2', [float], float, None), + ('fmod', [float, float], float, None), + ('ldexp', [float, int], float, None), + ('modf', [float], (float, float), modf_hook), + ('hypot', [float, float], float, None), + ('pow', [float, float], float, None), + ] + +for name, args, res, hook in complex_math_functions: + func = getattr(math, name) + llfake = getattr(ll_math, 'll_math_%s' % name, None) + oofake = getattr(oo_math, 'll_math_%s' % name, None) + register_external(func, args, res, 'll_math.ll_math_%s' % name, + llfakeimpl=llfake, oofakeimpl=oofake, + annotation_hook = hook) Modified: pypy/dist/pypy/rpython/lltypesystem/module/ll_math.py ============================================================================== --- pypy/dist/pypy/rpython/lltypesystem/module/ll_math.py (original) +++ pypy/dist/pypy/rpython/lltypesystem/module/ll_math.py Sat Mar 3 14:46:27 2007 @@ -1,7 +1,5 @@ import math - from pypy.rpython.lltypesystem import lltype, rtupletype -from pypy.tool.staticmethods import ClassMethods FREXP_RESULT = rtupletype.TUPLE_TYPE([lltype.Float, lltype.Signed]).TO MODF_RESULT = rtupletype.TUPLE_TYPE([lltype.Float, lltype.Float]).TO @@ -18,15 +16,10 @@ tup.item1 = intpart return tup -class Implementation: - __metaclass__ = ClassMethods - - def ll_math_frexp(cls, x): - mantissa, exponent = math.frexp(x) - return ll_frexp_result(mantissa, exponent) - ll_math_frexp.suggested_primitive = True - - def ll_math_modf(cls, x): - fracpart, intpart = math.modf(x) - return ll_modf_result(fracpart, intpart) - ll_math_modf.suggested_primitive = True +def ll_math_frexp(cls, x): + mantissa, exponent = math.frexp(x) + return ll_frexp_result(mantissa, exponent) + +def ll_math_modf(cls, x): + fracpart, intpart = math.modf(x) + return ll_modf_result(fracpart, intpart) Modified: pypy/dist/pypy/rpython/ootypesystem/module/ll_math.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/module/ll_math.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/module/ll_math.py Sat Mar 3 14:46:27 2007 @@ -1,7 +1,5 @@ import math - from pypy.rpython.ootypesystem import ootype -from pypy.tool.staticmethods import ClassMethods FREXP_RESULT = ootype.Record({"item0": ootype.Float, "item1": ootype.Signed}) MODF_RESULT = ootype.Record({"item0": ootype.Float, "item1": ootype.Float}) @@ -18,15 +16,11 @@ tup.item1 = intpart return tup -class Implementation: - __metaclass__ = ClassMethods +def ll_math_frexp(cls, x): + mantissa, exponent = math.frexp(x) + return ll_frexp_result(mantissa, exponent) + +def ll_math_modf(cls, x): + fracpart, intpart = math.modf(x) + return ll_modf_result(fracpart, intpart) - def ll_math_frexp(cls, x): - mantissa, exponent = math.frexp(x) - return ll_frexp_result(mantissa, exponent) - ll_math_frexp.suggested_primitive = True - - def ll_math_modf(cls, x): - fracpart, intpart = math.modf(x) - return ll_modf_result(fracpart, intpart) - ll_math_modf.suggested_primitive = True Modified: pypy/dist/pypy/translator/c/extfunc.py ============================================================================== --- pypy/dist/pypy/translator/c/extfunc.py (original) +++ pypy/dist/pypy/translator/c/extfunc.py Sat Mar 3 14:46:27 2007 @@ -5,12 +5,11 @@ from pypy.rpython.lltypesystem.rstr import STR, mallocstr from pypy.rpython.lltypesystem import rstr from pypy.rpython.lltypesystem import rlist -from pypy.rpython.module import ll_time, ll_math, ll_os +from pypy.rpython.module import ll_time, ll_os from pypy.rpython.module import ll_stackless, ll_stack from pypy.rpython.lltypesystem.module.ll_os import STAT_RESULT, PIPE_RESULT from pypy.rpython.lltypesystem.module.ll_os import WAITPID_RESULT from pypy.rpython.lltypesystem.module.ll_os import Implementation as impl -from pypy.rpython.lltypesystem.module import ll_math as ll_math2 from pypy.rpython.lltypesystem.module import ll_strtod from pypy.rlib import ros @@ -64,13 +63,6 @@ ll_time.ll_time_clock: 'LL_time_clock', ll_time.ll_time_sleep: 'LL_time_sleep', ll_time.ll_time_time: 'LL_time_time', - ll_math.ll_math_pow: 'LL_math_pow', - ll_math2.Implementation.ll_math_frexp.im_func: 'LL_math_frexp', - ll_math.ll_math_atan2: 'LL_math_atan2', - ll_math.ll_math_fmod : 'LL_math_fmod', - ll_math.ll_math_ldexp: 'LL_math_ldexp', - ll_math2.Implementation.ll_math_modf.im_func: 'LL_math_modf', - ll_math.ll_math_hypot: 'LL_math_hypot', ll_strtod.Implementation.ll_strtod_parts_to_float: 'LL_strtod_parts_to_float', ll_strtod.Implementation.ll_strtod_formatd: @@ -93,13 +85,20 @@ #______________________________________________________ # insert 'simple' math functions into EXTERNALs table: -simple_math_functions = [ +# XXX: messy, messy, messy +# this interacts in strange ways with node.select_function_code_generators, +# because it fakes to be an ll_* function. + +math_functions = [ 'acos', 'asin', 'atan', 'ceil', 'cos', 'cosh', 'exp', 'fabs', - 'floor', 'log', 'log10', 'sin', 'sinh', 'sqrt', 'tan', 'tanh' + 'floor', 'log', 'log10', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', + 'frexp', 'pow', 'atan2', 'fmod', 'ldexp', 'modf', 'hypot' ] -for name in simple_math_functions: - EXTERNALS[getattr(ll_math, 'll_math_%s' % name)] = 'LL_math_%s' % name +import math +for name in math_functions: + EXTERNALS['ll_math.ll_math_%s' % name] = 'LL_math_%s' % name + #______________________________________________________ @@ -110,13 +109,14 @@ return None def predeclare_common_types(db, rtyper): + from pypy.rpython.lltypesystem.module import ll_math # Common types yield ('RPyString', STR) LIST_OF_STR = find_list_of_str(rtyper) if LIST_OF_STR is not None: yield ('RPyListOfString', LIST_OF_STR) - yield ('RPyFREXP_RESULT', ll_math2.FREXP_RESULT) - yield ('RPyMODF_RESULT', ll_math2.MODF_RESULT) + yield ('RPyFREXP_RESULT', ll_math.FREXP_RESULT) + yield ('RPyMODF_RESULT', ll_math.MODF_RESULT) yield ('RPySTAT_RESULT', STAT_RESULT) yield ('RPyPIPE_RESULT', PIPE_RESULT) yield ('RPyWAITPID_RESULT', WAITPID_RESULT) Modified: pypy/dist/pypy/translator/c/node.py ============================================================================== --- pypy/dist/pypy/translator/c/node.py (original) +++ pypy/dist/pypy/translator/c/node.py Sat Mar 3 14:46:27 2007 @@ -688,7 +688,10 @@ funcgen.implementation_end() def select_function_code_generators(fnobj, db, functionname): - if fnobj._callable in extfunc.EXTERNALS: + if hasattr(fnobj, '_entry'): + db.externalfuncs[fnobj._entry.name] = fnobj + return [] + elif fnobj._callable in extfunc.EXTERNALS: # 'fnobj' is one of the ll_xyz() functions with the suggested_primitive # flag in pypy.rpython.module.*. The corresponding C wrappers are # written by hand in src/ll_*.h, and declared in extfunc.EXTERNALS. Modified: pypy/dist/pypy/translator/c/test/test_extfunc.py ============================================================================== --- pypy/dist/pypy/translator/c/test/test_extfunc.py (original) +++ pypy/dist/pypy/translator/c/test/test_extfunc.py Sat Mar 3 14:46:27 2007 @@ -7,7 +7,7 @@ from pypy.rlib import ros def test_all_suggested_primitives(): - for modulename in ['ll_math', 'll_os', 'll_os_path', 'll_time']: + for modulename in ['ll_os', 'll_os_path', 'll_time']: mod = __import__('pypy.rpython.module.%s' % modulename, None, None, ['__doc__']) for func in mod.__dict__.values(): From cfbolz at codespeak.net Sat Mar 3 14:49:26 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sat, 3 Mar 2007 14:49:26 +0100 (CET) Subject: [pypy-svn] r39803 - in pypy/branch/rope-branch/pypy/objspace/std: . test Message-ID: <20070303134926.6CD2610061@code0.codespeak.net> Author: cfbolz Date: Sat Mar 3 14:49:24 2007 New Revision: 39803 Modified: pypy/branch/rope-branch/pypy/objspace/std/ropeobject.py pypy/branch/rope-branch/pypy/objspace/std/test/test_ropeobject.py Log: add hash cache to rope objects Modified: pypy/branch/rope-branch/pypy/objspace/std/ropeobject.py ============================================================================== --- pypy/branch/rope-branch/pypy/objspace/std/ropeobject.py (original) +++ pypy/branch/rope-branch/pypy/objspace/std/ropeobject.py Sat Mar 3 14:49:24 2007 @@ -16,6 +16,7 @@ def __init__(w_self, node): w_self._node = node + w_self._w_hash = None def __repr__(w_self): """ representation for debugging purposes """ @@ -787,9 +788,12 @@ return w_str._node.flatten() def hash__Rope(space, w_str): - node = w_str._node - x = rope.hash_rope(node) - return wrapint(space, x) + w_hash = w_str._w_hash + if w_hash is None: + node = w_str._node + x = rope.hash_rope(node) + w_hash = node._w_hash = wrapint(space, x) + return w_hash def lt__Rope_Rope(space, w_str1, w_str2): n1 = w_str1._node Modified: pypy/branch/rope-branch/pypy/objspace/std/test/test_ropeobject.py ============================================================================== --- pypy/branch/rope-branch/pypy/objspace/std/test/test_ropeobject.py (original) +++ pypy/branch/rope-branch/pypy/objspace/std/test/test_ropeobject.py Sat Mar 3 14:49:24 2007 @@ -27,6 +27,18 @@ s += '3' raises(TypeError, ord, s) + def test_hash_twice(self): + # check that we have the same hash as CPython for at least 31 bits + # (but don't go checking CPython's special case -1) + # check twice to catch hash cache problems` + s1 = 'hello' + s2 = 'hello world!' + assert hash(s1) & 0x7fffffff == 0x347697fd + assert hash(s1) & 0x7fffffff == 0x347697fd + assert hash(s2) & 0x7fffffff == 0x2f0bb411 + assert hash(s2) & 0x7fffffff == 0x2f0bb411 + + class AppTestRopeUnicode(object): def setup_class(cls): From arigo at codespeak.net Sat Mar 3 14:53:59 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 3 Mar 2007 14:53:59 +0100 (CET) Subject: [pypy-svn] r39804 - in pypy/dist/pypy: interpreter translator Message-ID: <20070303135359.8E8B61005A@code0.codespeak.net> Author: arigo Date: Sat Mar 3 14:53:49 2007 New Revision: 39804 Modified: pypy/dist/pypy/interpreter/mixedmodule.py pypy/dist/pypy/translator/geninterplevel.py Log: (pedronis, arigo) Give a proper __module__ to the classes and functions defined in a geninterped app-level part of a mixed module. Modified: pypy/dist/pypy/interpreter/mixedmodule.py ============================================================================== --- pypy/dist/pypy/interpreter/mixedmodule.py (original) +++ pypy/dist/pypy/interpreter/mixedmodule.py Sat Mar 3 14:53:49 2007 @@ -20,6 +20,15 @@ self.lazy = True self.__class__.buildloaders() + def get_applevel_name(cls): + """ NOT_RPYTHON """ + if cls.applevel_name is not None: + return cls.applevel_name + else: + pkgroot = cls.__module__ + return pkgroot.split('.')[-1] + get_applevel_name = classmethod(get_applevel_name) + def get(self, name): space = self.space w_value = self.getdictvalue_w(space, name) @@ -80,10 +89,11 @@ # applevel/interplevel definitions cls.loaders = loaders = {} pkgroot = cls.__module__ + appname = cls.get_applevel_name() for name, spec in cls.interpleveldefs.items(): loaders[name] = getinterpevalloader(pkgroot, spec) for name, spec in cls.appleveldefs.items(): - loaders[name] = getappfileloader(pkgroot, spec) + loaders[name] = getappfileloader(pkgroot, appname, spec) assert '__file__' not in loaders if cls.expose__file__attribute: loaders['__file__'] = cls.get__file__ @@ -169,7 +179,7 @@ return ifileloader applevelcache = {} -def getappfileloader(pkgroot, spec): +def getappfileloader(pkgroot, appname, spec): """ NOT_RPYTHON """ # hum, it's a bit more involved, because we usually # want the import at applevel @@ -186,7 +196,7 @@ file.close() if fn.endswith('.pyc') or fn.endswith('.pyo'): fn = fn[:-1] - app = gateway.applevel(source, filename=fn) + app = gateway.applevel(source, filename=fn, modname=appname) applevelcache[impbase] = app def afileloader(space): @@ -211,10 +221,7 @@ fullname = "%s.%s" % (basepath, name) Module = __import__(fullname, None, None, ["Module"]).Module - if Module.applevel_name is not None: - appname = Module.applevel_name - else: - appname = name + appname = Module.get_applevel_name() mod = Module(space, space.wrap(appname)) res = new.module(appname) sys.modules[appname] = res Modified: pypy/dist/pypy/translator/geninterplevel.py ============================================================================== --- pypy/dist/pypy/translator/geninterplevel.py (original) +++ pypy/dist/pypy/translator/geninterplevel.py Sat Mar 3 14:53:49 2007 @@ -72,7 +72,7 @@ log = py.log.Producer("geninterp") py.log.setconsumer("geninterp", ansi_log) -GI_VERSION = '1.1.21' # bump this for substantial changes +GI_VERSION = '1.1.22' # bump this for substantial changes # ____________________________________________________________ try: From rxe at codespeak.net Sat Mar 3 15:04:41 2007 From: rxe at codespeak.net (rxe at codespeak.net) Date: Sat, 3 Mar 2007 15:04:41 +0100 (CET) Subject: [pypy-svn] r39805 - pypy/dist/pypy/translator/llvm Message-ID: <20070303140441.10F1410060@code0.codespeak.net> Author: rxe Date: Sat Mar 3 15:04:38 2007 New Revision: 39805 Modified: pypy/dist/pypy/translator/llvm/database.py pypy/dist/pypy/translator/llvm/extfuncnode.py Log: (antocuni, rxe) intermediate checkin to make external functions work while the way of doing external functions changes Modified: pypy/dist/pypy/translator/llvm/database.py ============================================================================== --- pypy/dist/pypy/translator/llvm/database.py (original) +++ pypy/dist/pypy/translator/llvm/database.py Sat Mar 3 15:04:38 2007 @@ -27,7 +27,6 @@ self._pendingsetup = [] self._tmpcount = 1 self.helper2ptr = {} - self.externalfuncs = {} self.primitives = Primitives(self) @@ -59,7 +58,9 @@ if isinstance(type_, lltype.FuncType): if getattr(value._callable, "suggested_primitive", False): node = ExternalFuncNode(self, value) - self.externalfuncs[node.callable] = value + elif hasattr(value, '_entry'): + node = ExternalFuncNode(self, value, value._entry.name) + elif getattr(value, 'external', None) == 'C': node = SimplerExternalFuncNode(self, value) else: Modified: pypy/dist/pypy/translator/llvm/extfuncnode.py ============================================================================== --- pypy/dist/pypy/translator/llvm/extfuncnode.py (original) +++ pypy/dist/pypy/translator/llvm/extfuncnode.py Sat Mar 3 15:04:38 2007 @@ -51,14 +51,18 @@ class ExternalFuncNode(ConstantLLVMNode): - def __init__(self, db, value): + def __init__(self, db, value, extname=None): self.db = db self.value = value name = value._callable.__name__ - assert name.startswith("ll") + #assert name.startswith("ll") self.callable = value._callable - mapped_name = EXTERNALS[self.callable] + if extname is not None: + mapped_name = EXTERNALS[extname] + else: + mapped_name = EXTERNALS[self.callable] + self.ref = self.make_ref("%", mapped_name) def setup(self): From arigo at codespeak.net Sat Mar 3 15:06:51 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 3 Mar 2007 15:06:51 +0100 (CET) Subject: [pypy-svn] r39806 - pypy/dist/pypy/jit/timeshifter Message-ID: <20070303140651.D95C710060@code0.codespeak.net> Author: arigo Date: Sat Mar 3 15:06:50 2007 New Revision: 39806 Modified: pypy/dist/pypy/jit/timeshifter/hrtyper.py Log: (pedronis, arigo) Skip all the tests depending on the timeshifter in the trunk (we'll break them soon). Modified: pypy/dist/pypy/jit/timeshifter/hrtyper.py ============================================================================== --- pypy/dist/pypy/jit/timeshifter/hrtyper.py (original) +++ pypy/dist/pypy/jit/timeshifter/hrtyper.py Sat Mar 3 15:06:50 2007 @@ -53,6 +53,8 @@ py.log.setconsumer("timeshifter", ansi_log) def __init__(self, hannotator, rtyper, RGenOp): + import py; py.test.skip("PENDING MERGE FROM THE BRANCH") + RPythonTyper.__init__(self, hannotator, type_system=HintTypeSystem.instance) self.rtyper = rtyper From arigo at codespeak.net Sat Mar 3 15:12:00 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 3 Mar 2007 15:12:00 +0100 (CET) Subject: [pypy-svn] r39807 - in pypy/dist/pypy: rpython translator/c Message-ID: <20070303141200.CC4FB10060@code0.codespeak.net> Author: arigo Date: Sat Mar 3 15:11:58 2007 New Revision: 39807 Modified: pypy/dist/pypy/rpython/llinterp.py pypy/dist/pypy/translator/c/exceptiontransform.py Log: (pedronis, arigo) Merge a small change from the JIT branch (the part of r37966 outside pypy.jit): use a Struct instead of an RPython class to hold the current exception state. Modified: pypy/dist/pypy/rpython/llinterp.py ============================================================================== --- pypy/dist/pypy/rpython/llinterp.py (original) +++ pypy/dist/pypy/rpython/llinterp.py Sat Mar 3 15:11: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/dist/pypy/translator/c/exceptiontransform.py ============================================================================== --- pypy/dist/pypy/translator/c/exceptiontransform.py (original) +++ pypy/dist/pypy/translator/c/exceptiontransform.py Sat Mar 3 15:11: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 @@ -143,11 +144,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) @@ -155,6 +153,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) @@ -288,11 +295,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 @@ -327,7 +333,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) @@ -374,7 +380,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 mwh at codespeak.net Sat Mar 3 15:31:09 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Sat, 3 Mar 2007 15:31:09 +0100 (CET) Subject: [pypy-svn] r39808 - in pypy/dist/pypy: config translator translator/llvm translator/llvm/test Message-ID: <20070303143109.418C810060@code0.codespeak.net> Author: mwh Date: Sat Mar 3 15:31:06 2007 New Revision: 39808 Modified: pypy/dist/pypy/config/translationoption.py pypy/dist/pypy/translator/driver.py pypy/dist/pypy/translator/llvm/genllvm.py pypy/dist/pypy/translator/llvm/opwriter.py pypy/dist/pypy/translator/llvm/test/runtest.py Log: (mwh, rxe) Make the llvm tests use the driver machinery to run the tests. Add a few llvm-translation specific options. Some associated insanity reduction. Modified: pypy/dist/pypy/config/translationoption.py ============================================================================== --- pypy/dist/pypy/config/translationoption.py (original) +++ pypy/dist/pypy/config/translationoption.py Sat Mar 3 15:31:06 2007 @@ -167,6 +167,12 @@ ('translation.backendopt.constfold', False)]) ]), + OptionDescription("llvm", "GenLLVM options", [ + BoolOption("debug", "Include the llops in the source as comments", default=False), + BoolOption("logging", "Log how long the various parts of llvm generation take", default=False), + BoolOption("isolate", "Peform an isolated import", default=True), + ]), + OptionDescription("cli", "GenCLI options", [ BoolOption("trace_calls", "Trace function calls", default=False, cmdline="--cli-trace-calls") Modified: pypy/dist/pypy/translator/driver.py ============================================================================== --- pypy/dist/pypy/translator/driver.py (original) +++ pypy/dist/pypy/translator/driver.py Sat Mar 3 15:31:06 2007 @@ -490,7 +490,7 @@ self.c_entryp = gen.compile_llvm_source(exe_name=exe_name) self.create_exe() else: - _, self.c_entryp = gen.compile_llvm_source() + self.c_module, self.c_entryp = gen.compile_llvm_source() # task_compile_llvm = taskdef(task_compile_llvm, ['source_llvm'], Modified: pypy/dist/pypy/translator/llvm/genllvm.py ============================================================================== --- pypy/dist/pypy/translator/llvm/genllvm.py (original) +++ pypy/dist/pypy/translator/llvm/genllvm.py Sat Mar 3 15:31:06 2007 @@ -23,8 +23,7 @@ # see create_codewriter() below function_count = {} - def __init__(self, translator, standalone, - debug=True, logging=True, stackless=False): + def __init__(self, translator, standalone): # reset counters LLVMNode.nodename_count = {} @@ -33,13 +32,6 @@ self.translator = translator self.config = translator.config - self.stackless = stackless - - # the debug flag is for creating comments of every operation that may be executed - self.debug = debug - - # the logging flag is for logging information statistics in the build process - self.logging = logging self.source_generated = False @@ -70,7 +62,7 @@ # XXX please dont ask! from pypy.translator.c.genc import CStandaloneBuilder cbuild = CStandaloneBuilder(self.translator, func, config=self.config) - cbuild.stackless = self.stackless + #cbuild.stackless = self.stackless c_db = cbuild.generate_graphs_for_llinterp() self.db = Database(self, self.translator) @@ -229,13 +221,12 @@ codewriter.ret("sbyte*", "null") codewriter.closefunc() - def compile_llvm_source(self, optimize=True, exe_name=None, isolate=False): + def compile_llvm_source(self, optimize=True, exe_name=None): assert self.source_generated assert hasattr(self, "filename") if exe_name is not None: assert self.standalone - assert not isolate return buildllvm.make_module_from_llvm(self, self.filename, optimize=optimize, exe_name=exe_name) @@ -251,11 +242,11 @@ pyxfile=pyxfile, optimize=optimize) - mod, wrap_fun = self.get_module(isolate=isolate, *info) + mod, wrap_fun = self.get_module(*info) return mod, wrap_fun - def get_module(self, modname, dirpath, isolate=False): - if isolate: + def get_module(self, modname, dirpath): + if self.config.translation.llvm.isolate: mod = Isolate((dirpath, modname)) else: from pypy.translator.tool.cbuild import import_module_from_directory @@ -265,7 +256,7 @@ return mod, wrap_fun def _checkpoint(self, msg=None): - if not self.logging: + if not self.config.translation.llvm.logging: return if msg: t = (time.time() - self.starttime) @@ -276,7 +267,7 @@ def _print_node_stats(self): # disable node stats output - if not self.logging: + if not self.config.translation.llvm.logging: return nodecount = {} Modified: pypy/dist/pypy/translator/llvm/opwriter.py ============================================================================== --- pypy/dist/pypy/translator/llvm/opwriter.py (original) +++ pypy/dist/pypy/translator/llvm/opwriter.py Sat Mar 3 15:31:06 2007 @@ -130,7 +130,7 @@ raise Exception, "operation %s not found" % op.opname # XXX bit unclean - if self.db.genllvm.debug: + if self.db.genllvm.config.translation.llvm.debug: self.codewriter.comment(str(op)) meth(opr) 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 Mar 3 15:31:06 2007 @@ -34,13 +34,10 @@ def llvm_test(): if not llvm_is_on_path(): py.test.skip("could not find one of llvm-as or llvm-gcc") - return False 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_ver, MINIMUM_LLVM_VERSION)) - return False - return True def gcc3_test(): gcc_ver = gcc_version() @@ -57,73 +54,57 @@ # debug options debug=True, logging=False, - log_source=False, + isolate=True, # pass to compile optimize=True, - **kwds): + extra_opts={}): """ helper for genllvm """ - assert llvm_is_on_path() - - # annotate/rtype - from pypy.translator.translator import TranslationContext - from pypy.translator.backendopt.all import backend_optimizations + from pypy.translator.driver import TranslationDriver from pypy.config.pypyoption import get_pypy_config - config = get_pypy_config(translating=True) - config.translation.gc = 'boehm' - translator = TranslationContext(config=config) - translator.buildannotator().build_types(function, annotation) - translator.buildrtyper().specialize() - - # use backend optimizations? - if optimize: - backend_optimizations(translator, raisingop2direct_call=True) - else: - backend_optimizations(translator, - raisingop2direct_call=True, - inline_threshold=0, - mallocs=False, - merge_if_blocks=False, - constfold=False) - - # note: this is without stackless and policy transforms + config = get_pypy_config({}, translating=True) + options = { + 'translation.backend': 'llvm', + 'translation.llvm.debug': debug, + 'translation.llvm.logging': logging, + 'translation.llvm.isolate': isolate, + 'translation.backendopt.none': not optimize, + 'translation.gc': 'boehm', + } + options.update(extra_opts) + config.set(**options) + driver = TranslationDriver(config=config) + driver.setup(function, annotation) + driver.annotate() if conftest.option.view: translator.view() - - # create genllvm - standalone = False - gen = GenLLVM(translator, - standalone, - debug=debug, - logging=logging) - - filename = gen.gen_llvm_source(function) - - log_source = kwds.pop("log_source", False) - if log_source: - log(open(filename).read()) - - return gen.compile_llvm_source(optimize=optimize, **kwds) + driver.rtype() + if conftest.option.view: + translator.view() + driver.compile() + if conftest.option.view: + translator.view() + return driver.c_module, driver.c_entryp def compile_test(function, annotation, isolate=True, **kwds): " returns module and compiled function " - if llvm_test(): - if run_isolated_only and not isolate: - py.test.skip("skipping not isolated test") - - # turn off isolation? - isolate = isolate and not do_not_isolate - - # maintain only 3 isolated process (if any) - _cleanup(leave=3) - optimize = kwds.pop('optimize', optimize_tests) - mod, fn = genllvm_compile(function, annotation, optimize=optimize, - isolate=isolate, **kwds) - if isolate: - ext_modules.append(mod) - return mod, fn + llvm_test() + if run_isolated_only and not isolate: + py.test.skip("skipping not isolated test") + + # turn off isolation? + isolate = isolate and not do_not_isolate + + # maintain only 3 isolated process (if any) + _cleanup(leave=3) + optimize = kwds.pop('optimize', optimize_tests) + mod, fn = genllvm_compile(function, annotation, optimize=optimize, + isolate=isolate, **kwds) + if isolate: + ext_modules.append(mod) + return mod, fn def compile_function(function, annotation, isolate=True, **kwds): " returns compiled function " From antocuni at codespeak.net Sat Mar 3 15:40:40 2007 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Sat, 3 Mar 2007 15:40:40 +0100 (CET) Subject: [pypy-svn] r39809 - pypy/dist/pypy/rpython Message-ID: <20070303144040.DF65210069@code0.codespeak.net> Author: antocuni Date: Sat Mar 3 15:40:38 2007 New Revision: 39809 Modified: pypy/dist/pypy/rpython/extfunctable.py Log: fix the translation Modified: pypy/dist/pypy/rpython/extfunctable.py ============================================================================== --- pypy/dist/pypy/rpython/extfunctable.py (original) +++ pypy/dist/pypy/rpython/extfunctable.py Sat Mar 3 15:40:38 2007 @@ -327,7 +327,7 @@ complex_math_functions = [ ('frexp', [float], (float, int), frexp_hook), - ('atan2', [float], float, None), + ('atan2', [float, float], float, None), ('fmod', [float, float], float, None), ('ldexp', [float, int], float, None), ('modf', [float], (float, float), modf_hook), From mwh at codespeak.net Sat Mar 3 15:40:50 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Sat, 3 Mar 2007 15:40:50 +0100 (CET) Subject: [pypy-svn] r39810 - pypy/dist/pypy/translator/llvm/test Message-ID: <20070303144050.E90321006F@code0.codespeak.net> Author: mwh Date: Sat Mar 3 15:40:48 2007 New Revision: 39810 Modified: pypy/dist/pypy/translator/llvm/test/test_stackless.py Log: (rxe, mwh) move top-level skip before now-failing import... Modified: pypy/dist/pypy/translator/llvm/test/test_stackless.py ============================================================================== --- pypy/dist/pypy/translator/llvm/test/test_stackless.py (original) +++ pypy/dist/pypy/translator/llvm/test/test_stackless.py Sat Mar 3 15:40:48 2007 @@ -4,9 +4,9 @@ from pypy.rlib.rstack import stack_unwind, stack_frames_depth, stack_too_big from pypy.rlib.rstack import yield_current_frame_to_caller -from pypy.translator.llvm.genllvm import genllvm_compile import py py.test.skip("not there yet!") +from pypy.translator.llvm.genllvm import genllvm_compile class StacklessTest(object): From rxe at codespeak.net Sat Mar 3 15:44:45 2007 From: rxe at codespeak.net (rxe at codespeak.net) Date: Sat, 3 Mar 2007 15:44:45 +0100 (CET) Subject: [pypy-svn] r39811 - pypy/dist/pypy/translator/llvm Message-ID: <20070303144445.35F8F10069@code0.codespeak.net> Author: rxe Date: Sat Mar 3 15:44:43 2007 New Revision: 39811 Modified: pypy/dist/pypy/translator/llvm/externs2ll.py Log: (mwh, rxe) seems we need this to compile with llvm-gcc4, and some miscell tidies Modified: pypy/dist/pypy/translator/llvm/externs2ll.py ============================================================================== --- pypy/dist/pypy/translator/llvm/externs2ll.py (original) +++ pypy/dist/pypy/translator/llvm/externs2ll.py Sat Mar 3 15:44:43 2007 @@ -41,9 +41,12 @@ if llvm_gcc_version() < 4.0: emit_llvm = '' else: - emit_llvm = '-emit-llvm -O3' - cmd = "llvm-gcc %s %s -S %s.c -o %s.ll 2>&1" % ( - includes, emit_llvm, plain, plain) + emit_llvm = '-emit-llvm -O0' + + # XXX localize this + include_path = '-I/sw/include' + cmd = "llvm-gcc %s %s %s -S %s.c -o %s.ll 2>&1" % ( + include_path, includes, emit_llvm, plain, plain) os.system(cmd) llcode = open(plain + '.ll').read() @@ -70,7 +73,7 @@ line = line.rstrip() # find function names, declare them with the default calling convertion - if line[-1:] == '{': + if '(' in line and line[-1:] == '{': returntype, s = line.split(' ', 1) funcname , s = s.split('(', 1) funcnames[funcname] = True @@ -114,10 +117,7 @@ rtyper = db.translator.rtyper from pypy.translator.c.extfunc import predeclare_all - # hacks to make predeclare_all work - # XXX Rationalise this - db.standalone = True - + # hacks to make predeclare_all work decls = list(predeclare_all(c_db, rtyper)) for c_name, obj in decls: From hpk at codespeak.net Sat Mar 3 15:57:07 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sat, 3 Mar 2007 15:57:07 +0100 (CET) Subject: [pypy-svn] r39812 - pypy/dist/pypy/lib Message-ID: <20070303145707.5868A10069@code0.codespeak.net> Author: hpk Date: Sat Mar 3 15:57:05 2007 New Revision: 39812 Modified: pypy/dist/pypy/lib/_formatting.py Log: (stepha, holger) slight tweaks/more precise exception catching Modified: pypy/dist/pypy/lib/_formatting.py ============================================================================== --- pypy/dist/pypy/lib/_formatting.py (original) +++ pypy/dist/pypy/lib/_formatting.py Sat Mar 3 15:57:05 2007 @@ -447,16 +447,16 @@ class FmtIter(object): def __init__(self, fmt): self.fmt = fmt + self._fmtlength = len(fmt) self.i = 0 def __iter__(self): return self def next(self): - try: - c = self.fmt[self.i] - except IndexError: - raise StopIteration + if self.i >= self._fmtlength: + raise StopIteration + c = self.fmt[self.i] self.i += 1 return c @@ -477,41 +477,42 @@ else: format_registry = str_format_registry - fmtiter = FmtIter(fmt) valueiter = iter(values) + fmtiter = FmtIter(fmt) r = [] - try: - for c in fmtiter: - if c == '%': + for c in fmtiter: + if c == '%': + try: t = parse_fmt(fmtiter, valueiter, valuedict) - try: - f = format_registry[t[0]] - except KeyError: - char = t[0] - if isinstance(char, unicode): - char = char.encode(sys.getdefaultencoding(), 'replace') - raise ValueError("unsupported format character " - "'%s' (0x%x) at index %d" - % (char, ord(t[0]), fmtiter.i - 1)) - # Trying to translate this using the flow space. - # Currently, star args give a problem there, - # so let's be explicit about the args: - # r.append(f(*t).format()) - char, flags, width, prec, value = t - try: - r.append(f(char, flags, width, prec, value).format()) - except NeedUnicodeFormattingError: - # Switch to using the unicode formatters and retry. - do_unicode = True - format_registry = unicode_format_registry - f = format_registry[t[0]] - r.append(f(char, flags, width, prec, value).format()) - + except StopIteration: + raise ValueError, "incomplete format" + try: + f = format_registry[t[0]] + except KeyError: + char = t[0] + if isinstance(char, unicode): + char = char.encode(sys.getdefaultencoding(), 'replace') + raise ValueError("unsupported format character " + "'%s' (0x%x) at index %d" + % (char, ord(t[0]), fmtiter.i - 1)) + # Trying to translate this using the flow space. + # Currently, star args give a problem there, + # so let's be explicit about the args: + # r.append(f(*t).format()) + char, flags, width, prec, value = t + try: + result = f(char, flags, width, prec, value).format() + except NeedUnicodeFormattingError: + # Switch to using the unicode formatters and retry. + do_unicode = True + format_registry = unicode_format_registry + f = format_registry[t[0]] + r.append(f(char, flags, width, prec, value).format()) else: - # efficiency hack: - r.append(c + fmtiter.skip_to_fmt()) - except StopIteration: - raise ValueError, "incomplete format" + r.append(result) + else: + # efficiency hack: + r.append(c + fmtiter.skip_to_fmt()) try: valueiter.next() except StopIteration: From rxe at codespeak.net Sat Mar 3 16:04:04 2007 From: rxe at codespeak.net (rxe at codespeak.net) Date: Sat, 3 Mar 2007 16:04:04 +0100 (CET) Subject: [pypy-svn] r39813 - in pypy/dist/pypy/translator: . llvm Message-ID: <20070303150404.78BBE1005A@code0.codespeak.net> Author: rxe Date: Sat Mar 3 16:04:01 2007 New Revision: 39813 Modified: pypy/dist/pypy/translator/driver.py pypy/dist/pypy/translator/llvm/genllvm.py Log: (mwh, rxe) start making the interface between genllvm and driver sane(r) Modified: pypy/dist/pypy/translator/driver.py ============================================================================== --- pypy/dist/pypy/translator/driver.py (original) +++ pypy/dist/pypy/translator/driver.py Sat Mar 3 16:04:01 2007 @@ -476,7 +476,7 @@ self.llvmgen = genllvm.GenLLVM(translator, self.standalone) - llvm_filename = self.llvmgen.gen_llvm_source(self.entry_point) + llvm_filename = self.llvmgen.gen_source(self.entry_point) self.log.info("written: %s" % (llvm_filename,)) # task_source_llvm = taskdef(task_source_llvm, @@ -487,10 +487,10 @@ gen = self.llvmgen if self.standalone: exe_name = (self.exe_name or 'testing') % self.get_info() - self.c_entryp = gen.compile_llvm_source(exe_name=exe_name) + self.c_entryp = gen.compile_standalone(exe_name) self.create_exe() else: - self.c_module, self.c_entryp = gen.compile_llvm_source() + self.c_module, self.c_entryp = gen.compile_module() # task_compile_llvm = taskdef(task_compile_llvm, ['source_llvm'], Modified: pypy/dist/pypy/translator/llvm/genllvm.py ============================================================================== --- pypy/dist/pypy/translator/llvm/genllvm.py (original) +++ pypy/dist/pypy/translator/llvm/genllvm.py Sat Mar 3 16:04:01 2007 @@ -33,9 +33,7 @@ self.config = translator.config - self.source_generated = False - - def gen_llvm_source(self, func): + def gen_source(self, func): self._checkpoint() codewriter = self.setup(func) @@ -48,7 +46,6 @@ # write bottom part of llvm file self.write_implementations(codewriter) - self.source_generated = True self._checkpoint('done') codewriter.close() return self.filename @@ -221,29 +218,17 @@ codewriter.ret("sbyte*", "null") codewriter.closefunc() - def compile_llvm_source(self, optimize=True, exe_name=None): - assert self.source_generated - - assert hasattr(self, "filename") - if exe_name is not None: - assert self.standalone - return buildllvm.make_module_from_llvm(self, self.filename, - optimize=optimize, - exe_name=exe_name) - else: - assert not self.standalone + def compile_module(self): + assert not self.standalone - # use pyrex to create module for CPython - postfix = '' - basename = self.filename.purebasename + '_wrapper' + postfix + '.pyx' - pyxfile = self.filename.new(basename = basename) - write_pyx_wrapper(self, pyxfile) - info = buildllvm.make_module_from_llvm(self, self.filename, - pyxfile=pyxfile, - optimize=optimize) - - mod, wrap_fun = self.get_module(*info) - return mod, wrap_fun + # use pyrex to create module for CPython + postfix = '' + basename = self.filename.purebasename + '_wrapper' + postfix + '.pyx' + pyxfile = self.filename.new(basename = basename) + write_pyx_wrapper(self, pyxfile) + info = buildllvm.make_module_from_llvm(self, self.filename, pyxfile=pyxfile) + mod, wrap_fun = self.get_module(*info) + return mod, wrap_fun def get_module(self, modname, dirpath): if self.config.translation.llvm.isolate: @@ -255,6 +240,11 @@ wrap_fun = getattr(mod, 'pypy_' + self.entry_func_name + "_wrapper") return mod, wrap_fun + def compile_standalone(self, exe_name): + assert self.standalone + return buildllvm.make_module_from_llvm(self, self.filename, + exe_name=exe_name) + def _checkpoint(self, msg=None): if not self.config.translation.llvm.logging: return From rxe at codespeak.net Sat Mar 3 16:20:38 2007 From: rxe at codespeak.net (rxe at codespeak.net) Date: Sat, 3 Mar 2007 16:20:38 +0100 (CET) Subject: [pypy-svn] r39814 - pypy/dist/pypy/translator/llvm Message-ID: <20070303152038.53D8110060@code0.codespeak.net> Author: rxe Date: Sat Mar 3 16:20:36 2007 New Revision: 39814 Modified: pypy/dist/pypy/translator/llvm/buildllvm.py pypy/dist/pypy/translator/llvm/genllvm.py Log: (mwh, rxe) start sanitizing build interface Modified: pypy/dist/pypy/translator/llvm/buildllvm.py ============================================================================== --- pypy/dist/pypy/translator/llvm/buildllvm.py (original) +++ pypy/dist/pypy/translator/llvm/buildllvm.py Sat Mar 3 16:20:36 2007 @@ -4,6 +4,7 @@ import py from pypy.translator.llvm.log import log +from pypy.translator.llvm.pyxwrapper import write_pyx_wrapper from pypy.translator.tool import stdoutcapture from pypy.translator.tool.cbuild import make_c_from_pyxfile @@ -77,6 +78,18 @@ log.build(cmd) py.process.cmdexec(cmd) + +def build_module(genllvm): + # use pyrex to create module for CPython + postfix = '' + basename = genllvm.filename.purebasename + '_wrapper' + postfix + '.pyx' + pyxfile = genllvm.filename.new(basename = basename) + write_pyx_wrapper(genllvm, pyxfile) + return make_module_from_llvm(genllvm, genllvm.filename, pyxfile=pyxfile) + +def build_standalone(genllvm, exename): + return make_module_from_llvm(genllvm, genllvm.filename, exe_name=exename) + def make_module_from_llvm(genllvm, llvmfile, pyxfile=None, optimize=True, exe_name=None, profile=False, cleanup=False, use_gcc=True): @@ -101,12 +114,12 @@ 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)] - object_files = ["-L%s/lib" % distutils.sysconfig.EXEC_PREFIX] + object_files = ["-L/sw/lib"] library_files = genllvm.db.gcpolicy.gc_libraries() gc_libs = ' '.join(['-l' + lib for lib in library_files]) if sys.platform == 'darwin': - libdir = distutils.sysconfig.EXEC_PREFIX + "/lib" + libdir = '/sw/' + "/lib" gc_libs_path = '-L%s -ldl' % libdir else: gc_libs_path = '-static' @@ -122,7 +135,7 @@ cmds.append("as %s.s -o %s.o" % (b, b)) if exe_name: - cmd = "gcc %s.o %s %s -lm -pipe -o %s" % (b, gc_libs_path, gc_libs, exe_name) + cmd = "gcc -O3 %s.o %s %s -lm -pipe -o %s" % (b, gc_libs_path, gc_libs, exe_name) cmds.append(cmd) object_files.append("%s.o" % b) else: Modified: pypy/dist/pypy/translator/llvm/genllvm.py ============================================================================== --- pypy/dist/pypy/translator/llvm/genllvm.py (original) +++ pypy/dist/pypy/translator/llvm/genllvm.py Sat Mar 3 16:20:36 2007 @@ -4,7 +4,6 @@ from pypy.translator.llvm import buildllvm from pypy.translator.llvm.database import Database -from pypy.translator.llvm.pyxwrapper import write_pyx_wrapper from pypy.rpython.rmodel import inputconst from pypy.rpython.typesystem import getfunctionptr from pypy.rpython.lltypesystem import lltype @@ -48,6 +47,7 @@ self._checkpoint('done') codewriter.close() + return self.filename def setup(self, func): @@ -221,13 +221,8 @@ def compile_module(self): assert not self.standalone - # use pyrex to create module for CPython - postfix = '' - basename = self.filename.purebasename + '_wrapper' + postfix + '.pyx' - pyxfile = self.filename.new(basename = basename) - write_pyx_wrapper(self, pyxfile) - info = buildllvm.make_module_from_llvm(self, self.filename, pyxfile=pyxfile) - mod, wrap_fun = self.get_module(*info) + modname, dirpath = buildllvm.build_module(self) + mod, wrap_fun = self.get_module(modname, dirpath) return mod, wrap_fun def get_module(self, modname, dirpath): @@ -242,8 +237,7 @@ def compile_standalone(self, exe_name): assert self.standalone - return buildllvm.make_module_from_llvm(self, self.filename, - exe_name=exe_name) + return buildllvm.build_standalone(self, exe_name) def _checkpoint(self, msg=None): if not self.config.translation.llvm.logging: From fijal at codespeak.net Sat Mar 3 16:25:19 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 3 Mar 2007 16:25:19 +0100 (CET) Subject: [pypy-svn] r39815 - in pypy/dist/pypy/rpython: . ootypesystem/test Message-ID: <20070303152519.CBF4C10061@code0.codespeak.net> Author: fijal Date: Sat Mar 3 16:25:18 2007 New Revision: 39815 Modified: pypy/dist/pypy/rpython/ootypesystem/test/test_bltann.py pypy/dist/pypy/rpython/rexternalobj.py Log: convert_from_to for BasicExternal and a test 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 Sat Mar 3 16:25:18 2007 @@ -7,10 +7,11 @@ from pypy.objspace.flow import FlowObjSpace from pypy.annotation.annrpython import RPythonAnnotator import exceptions -from pypy.rpython.ootypesystem.bltregistry import BasicExternal, ExternalType, MethodDesc +from pypy.rpython.ootypesystem.bltregistry import BasicExternal, ExternalType, MethodDesc, described from pypy.rpython.ootypesystem.ootype import Signed, _static_meth, StaticMethod, Void from pypy.rpython.test.test_llinterp import interpret from pypy.annotation.signature import annotation +from pypy.translator.translator import TranslationContext class C(BasicExternal): pass @@ -166,3 +167,28 @@ assert isinstance(res, float) res = interpret(callback_field, [0], type_system="ootype") assert res == 8.3 + +def test_mixed_classes(): + from pypy.rpython.extfunc import register_external + class One(BasicExternal): + pass + + class Two(One): + pass + + def g(one): + return 3 + register_external(g, args=[One], result=int) + + def f(x): + if x: + return g(One()) + return g(Two()) + + t = TranslationContext() + a = t.buildannotator() + s = a.build_types(f, [bool]) + a.simplify() + typer = t.buildrtyper(type_system="ootype") + typer.specialize() + #res = interpret(f, [True], type_system="ootype") Modified: pypy/dist/pypy/rpython/rexternalobj.py ============================================================================== --- pypy/dist/pypy/rpython/rexternalobj.py (original) +++ pypy/dist/pypy/rpython/rexternalobj.py Sat Mar 3 16:25:18 2007 @@ -5,9 +5,10 @@ from pypy.rpython.extfunctable import typetable from pypy.rpython import rbuiltin from pypy.rpython.module.support import init_opaque_object -from pypy.objspace.flow.model import Constant +from pypy.objspace.flow.model import Constant, Variable from pypy.rpython import extregistry from pypy.annotation.signature import annotation +from pypy.annotation.pairtype import pairtype class __extend__(annmodel.SomeExternalObject): @@ -136,3 +137,14 @@ def rtype_is_true(self, hop): vlist = hop.inputargs(self) return hop.genop('ptr_nonzero', vlist, resulttype=lltype.Bool) + +class __extend__(pairtype(ExternalBuiltinRepr, ExternalBuiltinRepr)): + def convert_from_to((from_, to), v, llops): + type_from = from_.knowntype._class_ + type_to = to.knowntype._class_ + if issubclass(type_from, type_to): + v.concretetype=to.knowntype + return v + return NotImplemented + + From hpk at codespeak.net Sat Mar 3 16:27:01 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sat, 3 Mar 2007 16:27:01 +0100 (CET) Subject: [pypy-svn] r39816 - pypy/dist/pypy/lib Message-ID: <20070303152701.0897B10068@code0.codespeak.net> Author: hpk Date: Sat Mar 3 16:26:59 2007 New Revision: 39816 Modified: pypy/dist/pypy/lib/_formatting.py Log: (stephan, holger) beginning to factor out Value Access for string interpolation, in order to move code to RPython Modified: pypy/dist/pypy/lib/_formatting.py ============================================================================== --- pypy/dist/pypy/lib/_formatting.py (original) +++ pypy/dist/pypy/lib/_formatting.py Sat Mar 3 16:26:59 2007 @@ -19,16 +19,9 @@ f_zero = 0 -def value_next(valueiter): - try: - return valueiter.next() - except StopIteration: - raise TypeError('not enough arguments for format string') - - -def peel_num(c, fmtiter, valueiter): +def peel_num(c, fmtiter, valuebox): if c == '*': - v = value_next(valueiter) + v = valuebox.next() if not isinstance(v, int): raise TypeError, "* wants int" return fmtiter.next(), v @@ -61,9 +54,9 @@ return c, flags -def parse_fmt(fmtiter, valueiter, valuedict): +def parse_fmt(fmtiter, valuebox): """return (char, flags, width, prec, value) - partially consumes fmtiter & valueiter""" + partially consumes fmtiter & valuebox""" c = fmtiter.next() value = None gotvalue = False @@ -79,13 +72,13 @@ elif c == '(': pcount += 1 n += c - value = valuedict[n] + value = valuebox.getitem(n) gotvalue = True c = fmtiter.next() c, flags = peel_flags(c, fmtiter) - c, width = peel_num(c, fmtiter, valueiter) + c, width = peel_num(c, fmtiter, valuebox) if c == '.': - c, prec = peel_num(fmtiter.next(), fmtiter, valueiter) + c, prec = peel_num(fmtiter.next(), fmtiter, valuebox) else: prec = None if c in 'hlL': @@ -100,7 +93,7 @@ value = '%' c = 's' else: - value = value_next(valueiter) + value = valuebox.next() return (c, flags, width, prec, value) @@ -472,18 +465,20 @@ def format(fmt, values, valuedict=None, do_unicode=False): + vb = ValueGetter(values, valuedict) + return _format(fmt, vb, do_unicode) + +def _format(fmt, valuebox, do_unicode=False): if do_unicode: format_registry = unicode_format_registry else: format_registry = str_format_registry - - valueiter = iter(values) fmtiter = FmtIter(fmt) r = [] for c in fmtiter: if c == '%': try: - t = parse_fmt(fmtiter, valueiter, valuedict) + t = parse_fmt(fmtiter, valuebox) except StopIteration: raise ValueError, "incomplete format" try: @@ -513,15 +508,34 @@ else: # efficiency hack: r.append(c + fmtiter.skip_to_fmt()) - try: - valueiter.next() - except StopIteration: - pass - else: - if valuedict is None: - raise TypeError('not all arguments converted ' - 'during string formatting') + valuebox.check_consumed() + if do_unicode: return u''.join(r) return ''.join(r) + +class ValueGetter: + """ statefull accesstor to Interpolation Values. """ + + def __init__(self, values, valuedict): + self._values = values + self._valuedict = valuedict + self._valueindex = 0 + + def check_consumed(self): + if (self._valueindex < len(self._values) and + self._valuedict is None): + raise TypeError('not all arguments converted ' + 'during string formatting') + + def next(self): + if self._valueindex >= len(self._values): + raise TypeError('not enough arguments for format string') + val = self._values[self._valueindex] + self._valueindex += 1 + return val + + def getitem(self, key): + return self._valuedict[key] + From cfbolz at codespeak.net Sat Mar 3 16:28:56 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sat, 3 Mar 2007 16:28:56 +0100 (CET) Subject: [pypy-svn] r39817 - in pypy/branch/rope-branch/pypy/objspace/std: . test Message-ID: <20070303152856.D684F10068@code0.codespeak.net> Author: cfbolz Date: Sat Mar 3 16:28:53 2007 New Revision: 39817 Modified: pypy/branch/rope-branch/pypy/objspace/std/ropeobject.py pypy/branch/rope-branch/pypy/objspace/std/test/test_ropeobject.py Log: fix typo and add a very hackish test for it, testing implementation details Modified: pypy/branch/rope-branch/pypy/objspace/std/ropeobject.py ============================================================================== --- pypy/branch/rope-branch/pypy/objspace/std/ropeobject.py (original) +++ pypy/branch/rope-branch/pypy/objspace/std/ropeobject.py Sat Mar 3 16:28:53 2007 @@ -792,7 +792,7 @@ if w_hash is None: node = w_str._node x = rope.hash_rope(node) - w_hash = node._w_hash = wrapint(space, x) + w_hash = w_str._w_hash = wrapint(space, x) return w_hash def lt__Rope_Rope(space, w_str1, w_str2): Modified: pypy/branch/rope-branch/pypy/objspace/std/test/test_ropeobject.py ============================================================================== --- pypy/branch/rope-branch/pypy/objspace/std/test/test_ropeobject.py (original) +++ pypy/branch/rope-branch/pypy/objspace/std/test/test_ropeobject.py Sat Mar 3 16:28:53 2007 @@ -27,14 +27,16 @@ s += '3' raises(TypeError, ord, s) - def test_hash_twice(self): + def test_hash_cache(self): # check that we have the same hash as CPython for at least 31 bits # (but don't go checking CPython's special case -1) # check twice to catch hash cache problems` s1 = 'hello' s2 = 'hello world!' + assert hash(s1) is hash(s1) # does the caching actually work? assert hash(s1) & 0x7fffffff == 0x347697fd assert hash(s1) & 0x7fffffff == 0x347697fd + assert hash(s2) is hash(s2) # does the caching actually work? assert hash(s2) & 0x7fffffff == 0x2f0bb411 assert hash(s2) & 0x7fffffff == 0x2f0bb411 From rxe at codespeak.net Sat Mar 3 16:59:16 2007 From: rxe at codespeak.net (rxe at codespeak.net) Date: Sat, 3 Mar 2007 16:59:16 +0100 (CET) Subject: [pypy-svn] r39818 - pypy/dist/pypy/translator/llvm Message-ID: <20070303155916.3E7B410060@code0.codespeak.net> Author: rxe Date: Sat Mar 3 16:59:15 2007 New Revision: 39818 Modified: pypy/dist/pypy/translator/llvm/buildllvm.py pypy/dist/pypy/translator/llvm/genllvm.py Log: (mwh, rxe) sanitize a little bit how we build/compile Modified: pypy/dist/pypy/translator/llvm/buildllvm.py ============================================================================== --- pypy/dist/pypy/translator/llvm/buildllvm.py (original) +++ pypy/dist/pypy/translator/llvm/buildllvm.py Sat Mar 3 16:59:15 2007 @@ -45,22 +45,6 @@ gcc_version = lambda: _exe_version2('gcc') llvm_gcc_version = lambda: _exe_version2('llvm-gcc') -def optimizations(simple, use_gcc): - - if simple: - opts = "-globaldce -adce -deadtypeelim -simplifycfg -raiseallocs " \ - "-simplifycfg -mem2reg -simplifycfg -verify " - else: -# opts = """-verify -lowersetjmp -funcresolve -raiseallocs -simplifycfg -mem2reg -globalopt -globaldce -ipconstprop -deadargelim -instcombine -simplifycfg -basiccg -prune-eh -inline -simplify-libcalls -basiccg -argpromotion -raise -tailduplicate -simplifycfg -scalarrepl -instcombine -break-crit-edges -condprop -tailcallelim -simplifycfg -reassociate -loopsimplify -licm -lcssa -loop-unswitch -instcombine -indvars -loop-unroll -instcombine -lowerswitch -instcombine -load-vn -gcse -sccp -instcombine -break-crit-edges -condprop -dse -mergereturn -adce -simplifycfg -deadtypeelim -constmerge -verify""" - cmd = "gccas /dev/null -o /dev/null -debug-pass=Arguments 2>&1" - gccas_output = os.popen(cmd) - opts = gccas_output.read()[17:-1] + " " - opts += "-globalopt -constmerge -ipsccp -deadargelim -inline " \ - "-instcombine -scalarrepl -globalsmodref-aa -licm -load-vn " \ - "-gcse -instcombine -simplifycfg -globaldce " - #opts += "-inline-threshold=200 " #default: 200 - return opts - def compile_module(module, source_files, object_files, library_files): open("%s_setup.py" % module, "w").write(str(py.code.Source( @@ -78,127 +62,172 @@ log.build(cmd) py.process.cmdexec(cmd) +class Builder(object): -def build_module(genllvm): - # use pyrex to create module for CPython - postfix = '' - basename = genllvm.filename.purebasename + '_wrapper' + postfix + '.pyx' - pyxfile = genllvm.filename.new(basename = basename) - write_pyx_wrapper(genllvm, pyxfile) - return make_module_from_llvm(genllvm, genllvm.filename, pyxfile=pyxfile) - -def build_standalone(genllvm, exename): - return make_module_from_llvm(genllvm, genllvm.filename, exe_name=exename) - -def make_module_from_llvm(genllvm, llvmfile, - pyxfile=None, optimize=True, exe_name=None, - profile=False, cleanup=False, use_gcc=True): - - if exe_name: - use_gcc = genllvm.config.translation.llvm_via_c - - # where we are building - dirpath = llvmfile.dirpath() - - # change into dirpath and store current path to change back - lastdir = str(py.path.local()) - os.chdir(str(dirpath)) - - b = llvmfile.purebasename - - # run llvm assembler and optimizer - simple_optimizations = not optimize - opts = optimizations(simple_optimizations, use_gcc) - 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)] - - object_files = ["-L/sw/lib"] - library_files = genllvm.db.gcpolicy.gc_libraries() - gc_libs = ' '.join(['-l' + lib for lib in library_files]) - - if sys.platform == 'darwin': - libdir = '/sw/' + "/lib" - gc_libs_path = '-L%s -ldl' % libdir - else: - gc_libs_path = '-static' + def __init__(self, genllvm): + self.genllvm = genllvm + self.cmds = [] + + def optimizations(self): + cmd = "gccas /dev/null -o /dev/null -debug-pass=Arguments 2>&1" + gccas_output = os.popen(cmd) + opts = gccas_output.read()[17:-1] + " " + + # these were added by Chris Lattner for some old verison of llvm + # opts += "-globalopt -constmerge -ipsccp -deadargelim -inline " \ + # "-instcombine -scalarrepl -globalsmodref-aa -licm -load-vn " \ + # "-gcse -instcombine -simplifycfg -globaldce " + + # added try to reduce the amount of excessive inlining by us, llvm and gcc + # opts += "-inline-threshold=175 " #default: 200 + return opts + + def compile_bytecode(self, b): + # run llvm assembler and optimizer + opts = self.optimizations() + + if llvm_version() < 2.0: + self.cmds.append("llvm-as < %s.ll | opt %s -f -o %s.bc" % (b, opts, b)) + else: + # we generate 1.x .ll files, so upgrade these first + self.cmds.append("llvm-upgrade < %s.ll | llvm-as | opt %s -f -o %s.bc" % (b, opts, b)) + + def make_module(self): + # use pyrex to create module for CPython + postfix = '' + basename = self.genllvm.filename.purebasename + '_wrapper' + postfix + '.pyx' + pyxfile = self.genllvm.filename.new(basename = basename) + write_pyx_wrapper(self.genllvm, pyxfile) + + llvmfile = self.genllvm.filename + + # change into dirpath and store current path to change back + dirpath = llvmfile.dirpath() + lastdir = py.path.local() + dirpath.chdir() + + b = llvmfile.purebasename + + # generate the llvm bytecode from ll file + self.compile_bytecode(b) + + object_files = ["-L/sw/lib"] + library_files = self.genllvm.db.gcpolicy.gc_libraries() + gc_libs = ' '.join(['-l' + lib for lib in library_files]) + + if sys.platform == 'darwin': + libdir = '/sw/' + "/lib" + gc_libs_path = '-L%s -ldl' % libdir + else: + gc_libs_path = '-static' - if pyxfile: modname = pyxfile.purebasename source_files = ["%s.c" % modname] - else: + + use_gcc = True #self.genllvm.config.translation.llvm_via_c + if not use_gcc: + self.cmds.append("llc %s.bc -f -o %s.s" % (b, b)) + self.cmds.append("as %s.s -o %s.o" % (b, b)) + object_files.append("%s.o" % b) + else: + self.cmds.append("llc %s.bc -march=c -f -o %s.c" % (b, b)) + source_files.append("%s.c" % b) + + try: + c = stdoutcapture.Capture(mixed_out_err = True) + log.build("working in", py.path.local()) + try: + try: + for cmd in self.cmds: + log.build(cmd) + py.process.cmdexec(cmd) + make_c_from_pyxfile(pyxfile) + compile_module(modname, source_files, object_files, library_files) + + finally: + foutput, ferror = c.done() + except: + data = 'OUTPUT:\n' + foutput.read() + '\n\nERROR:\n' + ferror.read() + fdump = open("%s.errors" % modname, "w") + fdump.write(data) + fdump.close() + log.build(data) + raise + finally: + os.chdir(str(lastdir)) + + return modname, str(dirpath) + + def make_standalone(self, exe_name): + llvmfile = self.genllvm.filename + + # change into dirpath and store current path to change back + dirpath = llvmfile.dirpath() + lastdir = py.path.local() + dirpath.chdir() + + b = llvmfile.purebasename + + # generate the llvm bytecode from ll file + self.compile_bytecode(b) + #compile_objects(b) + + object_files = ["-L/sw/lib"] + library_files = self.genllvm.db.gcpolicy.gc_libraries() + gc_libs = ' '.join(['-l' + lib for lib in library_files]) + + if sys.platform == 'darwin': + libdir = '/sw/' + "/lib" + gc_libs_path = '-L%s -ldl' % libdir + else: + gc_libs_path = '-static' + source_files = [] - if not use_gcc: - cmds.append("llc %s.bc -f -o %s.s" % (b, b)) - cmds.append("as %s.s -o %s.o" % (b, b)) + use_gcc = self.genllvm.config.translation.llvm_via_c + + if not use_gcc: + self.cmds.append("llc %s.bc -f -o %s.s" % (b, b)) + self.cmds.append("as %s.s -o %s.o" % (b, b)) - if exe_name: cmd = "gcc -O3 %s.o %s %s -lm -pipe -o %s" % (b, gc_libs_path, gc_libs, exe_name) - cmds.append(cmd) - object_files.append("%s.o" % b) - else: - cmds.append("llc %s.bc -march=c -f -o %s.c" % (b, b)) - if exe_name: - if genllvm.config.translation.profopt is not None: + self.cmds.append(cmd) + object_files.append("%s.o" % b) + else: + self.cmds.append("llc %s.bc -march=c -f -o %s.c" % (b, b)) + if self.genllvm.config.translation.profopt is not None: cmd = "gcc -fprofile-generate %s.c -c -O3 -pipe -o %s.o" % (b, b) - cmds.append(cmd) + self.cmds.append(cmd) cmd = "gcc -fprofile-generate %s.o %s %s -lm -pipe -o %s_gen" % \ (b, gc_libs_path, gc_libs, exe_name) - cmds.append(cmd) - cmds.append("./%s_gen %s"%(exe_name, genllvm.config.translation.profopt)) + self.cmds.append(cmd) + self.cmds.append("./%s_gen %s"%(exe_name, self.genllvm.config.translation.profopt)) cmd = "gcc -fprofile-use %s.c -c -O3 -pipe -o %s.o" % (b, b) - cmds.append(cmd) + self.cmds.append(cmd) cmd = "gcc -fprofile-use %s.o %s %s -lm -pipe -o %s" % \ (b, gc_libs_path, gc_libs, exe_name) else: - cmd = "gcc %s.c -c -O3 -pipe" % b - if profile: - cmd += ' -pg' - else: - cmd += ' -fomit-frame-pointer' - cmds.append(cmd) + cmd = "gcc %s.c -c -O3 -pipe -fomit-frame-pointer" % b + self.cmds.append(cmd) cmd = "gcc %s.o %s %s -lm -pipe -o %s" % (b, gc_libs_path, gc_libs, exe_name) - if profile: - cmd += ' -pg' - cmds.append(cmd) - source_files.append("%s.c" % b) - - if cleanup and exe_name and not profile: - cmds.append('strip ' + exe_name) - upx = os.popen('which upx 2>&1').read() - # compress file - if upx and not upx.startswith('which'): - cmds.append('upx ' + exe_name) - - try: - c = stdoutcapture.Capture(mixed_out_err = True) - log.build("working in", py.path.local()) + self.cmds.append(cmd) + source_files.append("%s.c" % b) + try: + c = stdoutcapture.Capture(mixed_out_err = True) + log.build("working in", py.path.local()) try: - for cmd in cmds: - log.build(cmd) - py.process.cmdexec(cmd) - if pyxfile: - make_c_from_pyxfile(pyxfile) - compile_module(modname, source_files, object_files, library_files) - finally: - foutput, ferror = c.done() - except: - data = 'OUTPUT:\n' + foutput.read() + '\n\nERROR:\n' + ferror.read() - if pyxfile: - fdump = open("%s.errors" % modname, "w") - fdump.write(data) - fdump.close() - log.build(data) - raise - finally: - os.chdir(str(lastdir)) - - if pyxfile: - return modname, str(dirpath) + try: + for cmd in self.cmds: + log.build(cmd) + py.process.cmdexec(cmd) + finally: + foutput, ferror = c.done() + except: + data = 'OUTPUT:\n' + foutput.read() + '\n\nERROR:\n' + ferror.read() + log.build(data) + raise + finally: + lastdir.chdir() - if exe_name: - exe_path = str(llvmfile.dirpath().join(exe_name)) - return exe_path + return str(llvmfile.dirpath().join(exe_name)) Modified: pypy/dist/pypy/translator/llvm/genllvm.py ============================================================================== --- pypy/dist/pypy/translator/llvm/genllvm.py (original) +++ pypy/dist/pypy/translator/llvm/genllvm.py Sat Mar 3 16:59:15 2007 @@ -220,8 +220,8 @@ def compile_module(self): assert not self.standalone - - modname, dirpath = buildllvm.build_module(self) + + modname, dirpath = buildllvm.Builder(self).make_module() mod, wrap_fun = self.get_module(modname, dirpath) return mod, wrap_fun @@ -237,7 +237,7 @@ def compile_standalone(self, exe_name): assert self.standalone - return buildllvm.build_standalone(self, exe_name) + return buildllvm.Builder(self).make_standalone(exe_name) def _checkpoint(self, msg=None): if not self.config.translation.llvm.logging: From cfbolz at codespeak.net Sat Mar 3 17:07:28 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sat, 3 Mar 2007 17:07:28 +0100 (CET) Subject: [pypy-svn] r39819 - in pypy/dist/pypy: config doc/config interpreter module/__builtin__ objspace/std Message-ID: <20070303160728.1FF4010068@code0.codespeak.net> Author: cfbolz Date: Sat Mar 3 17:07:26 2007 New Revision: 39819 Added: pypy/dist/pypy/doc/config/objspace.honor__builtins__.txt Modified: pypy/dist/pypy/config/pypyoption.py pypy/dist/pypy/interpreter/pyframe.py pypy/dist/pypy/interpreter/pyopcode.py pypy/dist/pypy/module/__builtin__/__init__.py pypy/dist/pypy/objspace/std/objspace.py Log: (arigo, pedronis, cfbolz): disable by default the jumping-through-hoops that CPython does for picking the builtins a frame is using. Modified: pypy/dist/pypy/config/pypyoption.py ============================================================================== --- pypy/dist/pypy/config/pypyoption.py (original) +++ pypy/dist/pypy/config/pypyoption.py Sat Mar 3 17:07:26 2007 @@ -99,6 +99,10 @@ BoolOption("usepycfiles", "Write and read pyc files when importing", default=True), + BoolOption("honor__builtins__", + "Honor the __builtins__ key of a module dictionary", + default=False), + OptionDescription("std", "Standard Object Space Options", [ BoolOption("withtproxy", "support transparent proxies", default=False, cmdline='--with-transparent-proxy'), Added: pypy/dist/pypy/doc/config/objspace.honor__builtins__.txt ============================================================================== Modified: pypy/dist/pypy/interpreter/pyframe.py ============================================================================== --- pypy/dist/pypy/interpreter/pyframe.py (original) +++ pypy/dist/pypy/interpreter/pyframe.py Sat Mar 3 17:07:26 2007 @@ -52,12 +52,19 @@ self.valuestack_w = [None] * code.co_stacksize self.valuestackdepth = 0 self.blockstack = [] - self.builtin = space.builtin.pick_builtin(w_globals) + if space.config.objspace.honor__builtins__: + self.builtin = space.builtin.pick_builtin(w_globals) # regular functions always have CO_OPTIMIZED and CO_NEWLOCALS. # class bodies only have CO_NEWLOCALS. self.initialize_frame_scopes(closure) self.fastlocals_w = [None]*self.numlocals self.f_lineno = self.pycode.co_firstlineno + + def get_builtin(self): + if self.space.config.objspace.honor__builtins__: + return self.builtin + else: + return self.space.builtin def initialize_frame_scopes(self, closure): # regular functions always have CO_OPTIMIZED and CO_NEWLOCALS. @@ -187,7 +194,7 @@ tup_state = [ w(self.f_back), - w(self.builtin), + w(self.get_builtin()), w(self.pycode), w_valuestack, w_blockstack, @@ -441,7 +448,7 @@ return pytraceback.offset2lineno(self.pycode, self.last_instr) def fget_f_builtins(space, self): - return self.builtin.getdict() + return self.get_builtin().getdict() def fget_f_back(space, self): return self.space.wrap(self.f_back) @@ -490,7 +497,9 @@ return space.w_None def fget_f_restricted(space, self): - return space.wrap(self.builtin is not space.builtin) + if space.config.objspace.honor__builtins__: + return space.wrap(self.builtin is not space.builtin) + return space.w_False # ____________________________________________________________ Modified: pypy/dist/pypy/interpreter/pyopcode.py ============================================================================== --- pypy/dist/pypy/interpreter/pyopcode.py (original) +++ pypy/dist/pypy/interpreter/pyopcode.py Sat Mar 3 17:07:26 2007 @@ -507,7 +507,8 @@ w_compile_flags = f.space.wrap(flags) w_resulttuple = prepare_exec(f.space, f.space.wrap(f), w_prog, w_globals, w_locals, - w_compile_flags, f.space.wrap(f.builtin), + w_compile_flags, + f.space.wrap(f.get_builtin()), f.space.gettypeobject(PyCode.typedef)) w_prog, w_globals, w_locals = f.space.unpacktuple(w_resulttuple, 3) @@ -541,7 +542,7 @@ w_name = f.popvalue() w_metaclass = find_metaclass(f.space, w_bases, w_methodsdict, f.w_globals, - f.space.wrap(f.builtin)) + f.space.wrap(f.get_builtin())) w_newclass = f.space.call_function(w_metaclass, w_name, w_bases, w_methodsdict) f.pushvalue(w_newclass) @@ -607,7 +608,7 @@ w_value = f.space.finditem(f.w_globals, w_varname) if w_value is None: # not in the globals, now look in the built-ins - w_value = f.builtin.getdictvalue(f.space, w_varname) + w_value = f.get_builtin().getdictvalue(f.space, w_varname) if w_value is None: varname = f.space.str_w(w_varname) message = "global name '%s' is not defined" % varname @@ -697,7 +698,7 @@ w_modulename = f.getname_w(nameindex) modulename = f.space.str_w(w_modulename) w_fromlist = f.popvalue() - w_import = f.builtin.getdictvalue_w(f.space, '__import__') + w_import = f.get_builtin().getdictvalue_w(f.space, '__import__') if w_import is None: raise OperationError(space.w_ImportError, space.wrap("__import__ not found")) Modified: pypy/dist/pypy/module/__builtin__/__init__.py ============================================================================== --- pypy/dist/pypy/module/__builtin__/__init__.py (original) +++ pypy/dist/pypy/module/__builtin__/__init__.py Sat Mar 3 17:07:26 2007 @@ -135,6 +135,8 @@ def pick_builtin(self, w_globals): "Look up the builtin module to use from the __builtins__ global" + # pick the __builtins__ roughly in the same way CPython does it + # this is obscure and slow space = self.space try: w_builtin = space.getitem(w_globals, space.wrap('__builtins__')) Modified: pypy/dist/pypy/objspace/std/objspace.py ============================================================================== --- pypy/dist/pypy/objspace/std/objspace.py (original) +++ pypy/dist/pypy/objspace/std/objspace.py Sat Mar 3 17:07:26 2007 @@ -95,9 +95,9 @@ assert isinstance(w_globals, W_DictMultiObject) w_value = w_globals.implementation.get_builtin_indexed(num) if w_value is None: - w_builtins = f.builtin - assert isinstance(w_builtins, Module) - w_builtin_dict = w_builtins.w_dict + builtins = f.get_builtin() + assert isinstance(builtins, Module) + w_builtin_dict = builtins.w_dict assert isinstance(w_builtin_dict, W_DictMultiObject) w_value = w_builtin_dict.implementation.get_builtin_indexed(num) ## if w_value is not None: From fijal at codespeak.net Sat Mar 3 17:12:06 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 3 Mar 2007 17:12:06 +0100 (CET) Subject: [pypy-svn] r39820 - pypy/dist/pypy/translator/js Message-ID: <20070303161206.F2A8B1006F@code0.codespeak.net> Author: fijal Date: Sat Mar 3 17:12:04 2007 New Revision: 39820 Modified: pypy/dist/pypy/translator/js/commproxy.py Log: Provide more flexibility in base?_url Modified: pypy/dist/pypy/translator/js/commproxy.py ============================================================================== --- pypy/dist/pypy/translator/js/commproxy.py (original) +++ pypy/dist/pypy/translator/js/commproxy.py Sat Mar 3 17:12:04 2007 @@ -102,6 +102,9 @@ self.name = name self.use_xml = use_xml self.base_url = base_url + obj = self.ext_obj._TYPE._class_ + if not base_url and hasattr(obj, '_render_base_path'): + self.base_url = obj._render_base_path self.method = method def render(self, ilasm): @@ -132,8 +135,8 @@ 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}) + ilasm.codegenerator.write(MOCHIKIT_BODY % {'class':self.name, 'method':method_name,\ + 'args':','.join(real_args), 'data':data, 'call':url}) else: if not self.use_xml: callback_body = CALLBACK_BODY From fijal at codespeak.net Sat Mar 3 17:12:47 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 3 Mar 2007 17:12:47 +0100 (CET) Subject: [pypy-svn] r39821 - in pypy/dist/pypy/translator/js/lib: . test Message-ID: <20070303161247.CADED1006E@code0.codespeak.net> Author: fijal Date: Sat Mar 3 17:12:45 2007 New Revision: 39821 Added: pypy/dist/pypy/translator/js/lib/test/test_server_g.py Modified: pypy/dist/pypy/translator/js/lib/server.py pypy/dist/pypy/translator/js/lib/test/test_server.py Log: New handlers (stolen from build tool) and some tests 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 Mar 3 17:12:45 2007 @@ -15,6 +15,34 @@ pass them to caller """ +import traceback + +HTTP_STATUS_MESSAGES = { + 200: 'OK', + 204: 'No Content', + 301: 'Moved permanently', + 302: 'Found', + 304: 'Not modified', + 401: 'Unauthorized', + 403: 'Forbidden', + 404: 'Not found', + 500: 'Server error', + 501: 'Not implemented', +} + +class HTTPError(Exception): + """ raised on HTTP errors """ + def __init__(self, status, data=None): + self.status = status + self.message = HTTP_STATUS_MESSAGES[status] + self.data = data + + def __str__(self): + data = '' + if self.data: + data = ' (%s)' % (self.data,) + return '' % (self.status, self.message, data) + from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler import re @@ -35,7 +63,88 @@ commproxy.USE_MOCHIKIT = False -class ExportedMethods(BasicExternal): +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): + """ traverse path relative to self + + 'path' is the path requested by the client, split on '/', but + relative from the current object: parent Collection items may have + removed items (they will have, actually, unless 'self' is the root + of the website) from the beginning on traversal to 'self' + + path is split on '/', the first item is removed and used to do + 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 callable with .exposed set to True) + + if path equals '', a lookup for 'index' is done + + can be overridden in subclasses to implement different path + handling (PATH_INFO-like stuff) + """ + name = path.pop(0) + if name == '': + name = 'index' + name = name.replace(".", "_") + resource = getattr(self, name, None) + 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): + raise HTTPError(500) # no PATH_INFO allowed for non-Collection + return resource.traverse(path, orgpath) + else: + 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 ExportedMethods(BasicExternal, Collection): + _render_base_path = "exported_methods" + def traverse(self, path, orgpath): + """ traverse path relative to self + + 'path' is the path requested by the client, split on '/', but + relative from the current object: parent Collection items may have + removed items (they will have, actually, unless 'self' is the root + of the website) from the beginning on traversal to 'self' + + path is split on '/', the first item is removed and used to do + 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 callable with .exposed set to True) + + if path equals '', a lookup for 'index' is done + + can be overridden in subclasses to implement different path + handling (PATH_INFO-like stuff) + """ + name = path.pop(0) + name = name.replace(".", "_") + resource = getattr(self, name, None) + if not resource: + raise HTTPError(404) + return lambda **args : ('text/json', json.write(resource(**args))) _render_xmlhttp = True exported_methods = ExportedMethods() @@ -114,18 +223,31 @@ def __call__(self): return open(str(self.path)).read() -class StaticDir(object): +class FsFile(object): + exposed = True + debug = False + def __init__(self, path, content_type="text/html"): + self._path = path + self._content_type = content_type + + _data = None + def __call__(self): + if self._data is None or self.debug: + self._data = self._path.read() + return ({'Content-Type': self._content_type}, self._data) + +class StaticDir(Collection): exposed = True def __init__(self, path, type=None): self.path = path self.type = type - def __call__(self, path): - data = open(os.path.join(str(self.path), str(path))).read() + def traverse(self, path, orgpath): + data = open(os.path.join(str(self.path), *path)).read() if self.type: - return self.type, data - return data + return lambda : self.type, data + return lambda : data def create_server(server_address = ('', 8000), handler=TestHandler, server=HTTPServer): @@ -166,3 +288,105 @@ Handler = TestHandler # deprecate TestHandler name + +class NewHandler(BaseHTTPRequestHandler): + """ BaseHTTPRequestHandler that does object publishing + """ + + application = None # attach web root (Collection object) here!! + bufsize = 1024 + + def do_GET(self, send_body=True): + """ perform a request """ + path, query = self.process_path(self.path) + _, args = parse_url("?" + query) + try: + resource = self.find_resource(path) + # XXX strange hack + if hasattr(resource, 'im_self'): + resource.im_self.server = self.server + retval = resource(**args) + if isinstance(retval, str): + headers = {'Content-Type': 'text/html'} + data = retval + else: + headers, data = retval + if isinstance(headers, str): + headers = {'Content-Type': headers} + 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, send_body) + + do_POST = do_GET + + def do_HEAD(self): + return self.do_GET(False) + + def process_path(self, path): + """ split the path in a path and a query part# + + returns a tuple (path, query), where path is a string and + query a dictionary containing the GET vars (URL decoded and such) + """ + path = path.split('?') + if len(path) > 2: + raise ValueError('illegal path %s' % (path,)) + p = path[0] + q = len(path) > 1 and path[1] or '' + return p, q + + def find_resource(self, path): + """ find the resource for a given path + """ + if not path: + raise HTTPError(301, '/') + assert path.startswith('/') + chunks = path.split('/') + chunks.pop(0) # empty item + 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 + body = 'Redirecting to %s' % (e.data,) + else: + body = 'Error: %s (%s)' % (e.status, e.message) + return 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) + if (isinstance(body, str) and + not 'content-length' in [k.lower() for k in headers]): + headers['Content-Length'] = len(body) + 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'): + while 1: + data = body.read(self.bufsize) + if data == '': + break + self.wfile.write(data) + else: + raise ValueError('body is not a plain string or file-like object') 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 Mar 3 17:12:45 2007 @@ -57,6 +57,7 @@ def test_static_directory(): + py.test.skip("Fails") import thread tmpdir = py.test.ensuretemp("server_static_dir") tmpdir.ensure("a", dir=1) Added: pypy/dist/pypy/translator/js/lib/test/test_server_g.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/js/lib/test/test_server_g.py Sat Mar 3 17:12:45 2007 @@ -0,0 +1,115 @@ +import py +from pypy.translator.js.lib.server import * + +class NonInitHandler(NewHandler): + request_version = '1.0' + + def __init__(self): + pass + + def log_request(self, code='-', size='-'): + pass + +class SomePage(object): + """ test resource """ + exposed = True + def __call__(self, handler, path, query): + return ('text/plain', 'foo') + +def build_app_structure(): + app = Collection() + app.sub = Collection() + app.sub = Collection() + app.sub.index = SomePage() + return app + +class TestCollection(object): + def test_traverse(self): + app = build_app_structure() + assert app.traverse(['sub', 'index'], '/sub/index') is app.sub.index + assert app.traverse(['sub', ''], '/sub/') is app.sub.index + try: + app.traverse(['sub'], '/sub') + except HTTPError, e: + assert e.status == 301 + assert e.data == '/sub/' + else: + py.test.fail('should have redirected') + # 404 errors (first -> no index) + py.test.raises(HTTPError, "app.traverse([''], '/')") + py.test.raises(HTTPError, "app.traverse(['other', ''], '/other/')") + +class TestResource(object): + pass + +class TestHandler(object): + def setup_method(self, method): + self.handler = NonInitHandler() + self.handler.wfile = self.wfile = py.std.StringIO.StringIO() + + def test_process_path(self): + path, query = self.handler.process_path('') + assert path == '' + assert query == '' + + path, query = self.handler.process_path('/foo') + assert path == '/foo' + assert query == '' + + path, query = self.handler.process_path('/foo?bar') + assert path == '/foo' + assert query == 'bar' + + py.test.raises(ValueError, "self.handler.process_path('/foo?bar?baz')") + + def test_find_resource(self): + app = build_app_structure() + self.handler.application = app + assert self.handler.find_resource('/sub/index') is app.sub.index + assert self.handler.find_resource('/sub/') is app.sub.index + try: + self.handler.find_resource('/sub') + except HTTPError, e: + assert e.status == 301 + assert e.data == '/sub/' + else: + py.test.raises('should have raised a redirect') + try: + self.handler.find_resource('') + except HTTPError, e: + assert e.status == 301 + assert e.data == '/' + else: + py.test.raises('should have raised a redirect') + py.test.raises(HTTPError, "self.handler.find_resource('/foo/')") + + def test_response(self): + self.handler.response(200, {'Content-Type': 'text/plain'}, 'foo') + response = self.wfile.getvalue() + assert response.startswith('HTTP/1.0 200 OK') + assert 'Content-Type: text/plain\r\n' in response + assert 'Content-Length: 3\r\n' in response + assert response.endswith('\r\n\r\nfoo') + + def test_get_response_file(self): + rfile = py.std.StringIO.StringIO() + rfile.write('foo\nbar\nbaz') + rfile.seek(0) + self.handler.response(200, {'Content-Type': 'text/plain'}, rfile) + response = self.wfile.getvalue() + assert response.endswith('\r\n\r\nfoo\nbar\nbaz') + + def test_get_response_wrong_body(self): + py.test.raises(ValueError, "self.handler.response(200, {}, u'xxx')") + +class TestFsFile(object): + 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()#None, '/bar/foo.txt', '') + assert ret[0] == {'Content-Type': 'text/plain'} + assert ret[1] == 'foo' + + From fijal at codespeak.net Sat Mar 3 17:13:46 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 3 Mar 2007 17:13:46 +0100 (CET) Subject: [pypy-svn] r39822 - in pypy/dist/pypy/translator/js/examples: . console console/data console/test Message-ID: <20070303161346.0755C10068@code0.codespeak.net> Author: fijal Date: Sat Mar 3 17:13:44 2007 New Revision: 39822 Modified: pypy/dist/pypy/translator/js/examples/console/client.py pypy/dist/pypy/translator/js/examples/console/console.py pypy/dist/pypy/translator/js/examples/console/data/console.html pypy/dist/pypy/translator/js/examples/console/session.py pypy/dist/pypy/translator/js/examples/console/test/test_console.py pypy/dist/pypy/translator/js/examples/over_client.py pypy/dist/pypy/translator/js/examples/overmind.py Log: Improve greatly a console example 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 Sat Mar 3 17:13:44 2007 @@ -4,7 +4,8 @@ from pypy.translator.js.examples.console.console import exported_methods class Glob(object): - pass + def __init__(self): + self.console_running = False glob = Glob() @@ -18,12 +19,17 @@ data_elem.removeChild(data_elem.childNodes[0]) data_elem.appendChild(dom.document.createTextNode(data)) +def set_text(txt): + data_elem = dom.document.getElementById("data") + while data_elem.childNodes: + data_elem.removeChild(data_elem.childNodes[0]) + data_elem.appendChild(dom.document.createTextNode(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": + inp_elem.scrollIntoView() data = msg[1] log(data) exported_methods.refresh_empty(glob.sess_id, refresh_console) @@ -52,10 +58,30 @@ #else: exported_methods.refresh(glob.sess_id, cmd + "\n", refresh_console) -def console_onload(): - #createLoggingPane(True) +def nothing(msg): + pass + +def cleanup_console(): + inp_elem = dom.document.getElementById("inp") + inp_elem.disabled = True + set_text("") + exported_methods.kill_console(glob.sess_id, nothing) + +def load_console(python="python"): + if glob.console_running: + cleanup_console() inp_elem = dom.document.getElementById("inp") + main = dom.document.getElementById("main") + main.style.visibility = "visible" + inp_elem.disabled = False inp_elem.focus() + glob.console_running = True + exported_methods.get_console(python, set_sessid) + +def console_onload(): + #createLoggingPane(True) + #inp_elem = dom.document.getElementById("inp") + #inp_elem.focus() dom.document.onkeypress = keypressed - exported_methods.get_console(set_sessid) + #exported_methods.get_console("python", set_sessid) 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 Sat Mar 3 17:13:44 2007 @@ -14,7 +14,7 @@ commproxy.USE_MOCHIKIT = True -FUNCTION_LIST = ["console_onload"] +FUNCTION_LIST = ["load_console", "console_onload"] class Ignore(Exception): pass @@ -23,13 +23,26 @@ import client return rpython2javascript(client, FUNCTION_LIST) +def line_split(ret, max_len): + to_ret = [] + for line in ret.split("\n"): + if len(line) > max_len: + to_ret += [line[i*max_len:(i+1)*max_len] for i in + range(len(line)/max_len - 1)] + i += 1 + else: + i = 0 + to_ret.append(line[i*max_len:]) + return "\n".join(to_ret) + + class Sessions(object): def __init__(self): self.sessions = {} self.updating = {} - def new_session(self): - ip = Interpreter("python") + def new_session(self, python="python"): + ip = Interpreter(python) self.sessions[ip.pid] = ip self.updating[ip.pid] = False return ip.pid @@ -44,16 +57,23 @@ self.updating[pid] = False if not ret: return "" - return ret + MAX_LEN = 80 + return line_split(ret, MAX_LEN) + + def kill_session(self, pid): + ip = self.sessions[pid] + ip.pipe.stdin.close() + del self.sessions[pid] + del self.updating[pid] # 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() + @callback(args=[str], retval=int) + def get_console(self, python="python"): + retval = sessions.new_session(python) return retval @callback(retval=[str]) @@ -76,23 +96,34 @@ except Ignore: return ["ignore"] + @callback() + def kill_console(self, pid=0): + sessions.kill_session(int(pid)) + exported_methods = ExportedMethods() -class Handler(server.Handler): +static_dir = py.path.local(__file__).dirpath().join("data") + +class Root(server.Collection): exported_methods = exported_methods - static_dir = py.path.local(__file__).dirpath().join("data") - index = server.Static(static_dir.join("console.html")) + #index = server.Static(static_dir.join("console.html")) + index = server.FsFile(static_dir.join("console.html")) MochiKit = server.StaticDir('MochiKit') def source_js(self): - if hasattr(self.server, 'source'): - source = self.server.source + if hasattr(self.server, 'source_console'): + source = self.server.source_console else: source = js_source() - self.server.source = source + self.server.source_console = source return "text/javascript", source source_js.exposed = True +class Handler(server.NewHandler): + application = Root() + application.some = Root() + application.other = Root() + if __name__ == '__main__': addr = ('', 8007) httpd = server.create_server(server_address=addr, handler=Handler, Modified: pypy/dist/pypy/translator/js/examples/console/data/console.html ============================================================================== --- pypy/dist/pypy/translator/js/examples/console/data/console.html (original) +++ pypy/dist/pypy/translator/js/examples/console/data/console.html Sat Mar 3 17:13:44 2007 @@ -7,9 +7,18 @@ -

Python console

-

-   >>> 
-   

+ + \ No newline at end of file Modified: pypy/dist/pypy/translator/js/examples/console/session.py ============================================================================== --- pypy/dist/pypy/translator/js/examples/console/session.py (original) +++ pypy/dist/pypy/translator/js/examples/console/session.py Sat Mar 3 17:13:44 2007 @@ -30,7 +30,7 @@ def timeout_read(self, fd, timeout): timer = Timer(timeout) try: - data = fd.recv(1024) + data = fd.recv(10024) except Interrupted: data = None else: Modified: pypy/dist/pypy/translator/js/examples/console/test/test_console.py ============================================================================== --- pypy/dist/pypy/translator/js/examples/console/test/test_console.py (original) +++ pypy/dist/pypy/translator/js/examples/console/test/test_console.py Sat Mar 3 17:13:44 2007 @@ -1,12 +1,18 @@ -import py -py.test.skip("XXX") +def test_line_skip(): + from pypy.translator.js.examples.console.console import line_split -from pypy.translator.js.examples.console import console + assert line_split("asdf", 80) == "asdf" + assert line_split("a b c d", 3) == "a b\n c d" + assert line_split("a b c d e f g h i j", 3) == "a b\n c \nd e\n f \ng h\n i j" def test_run_console(): """ Check if we can read anything """ + import py + py.test.skip("XXX") + + from pypy.translator.js.examples.console import console pipe = console.run_console("python") pipe.stdin.close() t = False 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 Sat Mar 3 17:13:44 2007 @@ -2,16 +2,12 @@ """ Client side of overmind.py """ -from pypy.translator.js.examples.overmind import exported_methods from pypy.translator.js.modules import dom 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) - def bnb_redirect(): loc = dom.window.location new_loc = loc.protocol + "//" + loc.hostname + ":7070" 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 Sat Mar 3 17:13:44 2007 @@ -10,47 +10,36 @@ from pypy.rpython.extfunc import _callable from pypy.rpython.ootypesystem.bltregistry import described from pypy.translator.js.main import rpython2javascript +from pypy.translator.js.examples.console import console import os import py -FUNCTION_LIST = ['launch_console', 'bnb_redirect'] +FUNCTION_LIST = ['bnb_redirect'] TIMEOUT = 300 pids = [] -def launch_console_in_new_prcess(): - from pypy.translator.js.examples import pythonconsole - httpd = server.create_server(server_address=('', 0), - handler=pythonconsole.RequestHandler, - server=pythonconsole.Server) - port = httpd.server_port - pythonconsole.httpd = httpd - pid = server.start_server_in_new_process(httpd, timeout=TIMEOUT) - del httpd - pids.append(pid) - 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_prcess() - -exported_methods = ExportedMethods() +#def launch_console_in_new_prcess(): +# from pypy.translator.js.examples import pythonconsole +# httpd = server.create_server(server_address=('', 0), +# handler=pythonconsole.RequestHandler, +# server=pythonconsole.Server) +# port = httpd.server_port +# pythonconsole.httpd = httpd +# pid = server.start_server_in_new_process(httpd, timeout=TIMEOUT) +# del httpd +# pids.append(pid) +# return port 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() - console = server.Static(os.path.join(static_dir, "launcher.html")) - terminal = server.Static(os.path.join(static_dir, "terminal.html")) - exported_methods = exported_methods +class Root(server.Collection): + static_dir = py.path.local(__file__).dirpath().join("data") + index = server.FsFile(static_dir.join("index.html")) + terminal = server.Static(static_dir.join("terminal.html")) + console = console.Root() def source_js(self): if hasattr(self.server, 'source'): @@ -70,12 +59,18 @@ ''' - bnb.exposed = True + bnb.exposed = True + +class Handler(server.NewHandler): + application = Root() + #console = server.Static(os.path.join(static_dir, "launcher.html")) if __name__ == '__main__': try: addr = ('', 8008) - httpd = server.create_server(server_address=addr, handler=Handler) + from pypeers.httpserver import GreenHTTPServer + httpd = server.create_server(server_address=addr, handler=Handler, + server=GreenHTTPServer) httpd.serve_forever() except KeyboardInterrupt: for pid in pids: From fijal at codespeak.net Sat Mar 3 17:15:19 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 3 Mar 2007 17:15:19 +0100 (CET) Subject: [pypy-svn] r39823 - pypy/dist/pypy/translator/js/modules/test Message-ID: <20070303161519.C8E881006E@code0.codespeak.net> Author: fijal Date: Sat Mar 3 17:15:16 2007 New Revision: 39823 Modified: pypy/dist/pypy/translator/js/modules/test/test_mochikit.py Log: One 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 Mar 3 17:15:16 2007 @@ -7,3 +7,8 @@ def x(): escapeHTML("xxx") + "xxx" assert js_source([x], use_pdb=False).find("escapeHTML (") != -1 + + def test_serialize_json(self): + def x(): + return serializeJSON(3) + serializeJSON("aaa") + serializeJSON([1]) + assert js_source([x]) From rxe at codespeak.net Sat Mar 3 17:17:19 2007 From: rxe at codespeak.net (rxe at codespeak.net) Date: Sat, 3 Mar 2007 17:17:19 +0100 (CET) Subject: [pypy-svn] r39824 - pypy/dist/pypy/translator/llvm Message-ID: <20070303161719.3493A10068@code0.codespeak.net> Author: rxe Date: Sat Mar 3 17:17:15 2007 New Revision: 39824 Modified: pypy/dist/pypy/translator/llvm/buildllvm.py Log: (mwh, rxe) baby refactors Modified: pypy/dist/pypy/translator/llvm/buildllvm.py ============================================================================== --- pypy/dist/pypy/translator/llvm/buildllvm.py (original) +++ pypy/dist/pypy/translator/llvm/buildllvm.py Sat Mar 3 17:17:15 2007 @@ -92,6 +92,25 @@ # we generate 1.x .ll files, so upgrade these first self.cmds.append("llvm-upgrade < %s.ll | llvm-as | opt %s -f -o %s.bc" % (b, opts, b)) + def execute_cmds(self): + c = stdoutcapture.Capture(mixed_out_err=True) + log.build("working in", py.path.local()) + try: + try: + for cmd in self.cmds: + log.build(cmd) + py.process.cmdexec(cmd) + + finally: + foutput, ferror = c.done() + except: + data = 'OUTPUT:\n' + foutput.read() + '\n\nERROR:\n' + ferror.read() + fdump = open("%s.errors" % modname, "w") + fdump.write(data) + fdump.close() + log.build(data) + raise + def make_module(self): # use pyrex to create module for CPython postfix = '' @@ -134,27 +153,12 @@ source_files.append("%s.c" % b) try: - c = stdoutcapture.Capture(mixed_out_err = True) - log.build("working in", py.path.local()) - try: - try: - for cmd in self.cmds: - log.build(cmd) - py.process.cmdexec(cmd) - make_c_from_pyxfile(pyxfile) - compile_module(modname, source_files, object_files, library_files) - - finally: - foutput, ferror = c.done() - except: - data = 'OUTPUT:\n' + foutput.read() + '\n\nERROR:\n' + ferror.read() - fdump = open("%s.errors" % modname, "w") - fdump.write(data) - fdump.close() - log.build(data) - raise + self.execute_cmds() + make_c_from_pyxfile(pyxfile) + compile_module(modname, source_files, object_files, library_files) + finally: - os.chdir(str(lastdir)) + lastdir.chdir() return modname, str(dirpath) @@ -214,19 +218,7 @@ source_files.append("%s.c" % b) try: - c = stdoutcapture.Capture(mixed_out_err = True) - log.build("working in", py.path.local()) - try: - try: - for cmd in self.cmds: - log.build(cmd) - py.process.cmdexec(cmd) - finally: - foutput, ferror = c.done() - except: - data = 'OUTPUT:\n' + foutput.read() + '\n\nERROR:\n' + ferror.read() - log.build(data) - raise + self.execute_cmds() finally: lastdir.chdir() From antocuni at codespeak.net Sat Mar 3 17:27:42 2007 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Sat, 3 Mar 2007 17:27:42 +0100 (CET) Subject: [pypy-svn] r39825 - pypy/dist/pypy/translator/cli/test Message-ID: <20070303162742.10DD31005A@code0.codespeak.net> Author: antocuni Date: Sat Mar 3 17:27:41 2007 New Revision: 39825 Modified: pypy/dist/pypy/translator/cli/test/runtest.py Log: this should have been checked in with revision 39697 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 Mar 3 17:27:41 2007 @@ -10,6 +10,8 @@ from pypy.rpython.ootypesystem import ootype from pypy.annotation.model import lltype_to_annotation from pypy.translator.backendopt.all import backend_optimizations +from pypy.translator.backendopt.checkvirtual import check_virtual_methods +from pypy.rpython.ootypesystem import ootype from pypy.translator.cli.option import getoption from pypy.translator.cli.gencli import GenCli @@ -163,16 +165,17 @@ t.view() t.buildrtyper(type_system="ootype").specialize() + check_virtual_methods(ootype.ROOT) backend_opt_default = dict( raisingop2direct_call=False, - inline_threshold=0, - mallocs=False, - merge_if_blocks=False, + inline_threshold=1, + mallocs=True, + merge_if_blocks=True, constfold=True, heap2stack=False, clever_malloc_removal=False) backend_opt_default.update(backend_opt) - backend_optimizations(t, **backend_opt_default) + #backend_optimizations(t, **backend_opt_default) main_graph = t.graphs[0] @@ -190,7 +193,7 @@ def __init__(self, exe_name): self._exe = exe_name - def __call__(self, *args): + def run(self, *args): if self._exe is None: py.test.skip("Compilation disabled") @@ -204,8 +207,11 @@ stderr=subprocess.PIPE, env=env) stdout, stderr = mono.communicate() retval = mono.wait() - assert retval == 0, stderr + return stdout, stderr, retval + def __call__(self, *args): + stdout, stderr, retval = self.run(*args) + assert retval == 0, stderr res = eval(stdout.strip()) if isinstance(res, tuple): res = StructTuple(res) # so tests can access tuple elements with .item0, .item1, etc. From antocuni at codespeak.net Sat Mar 3 17:29:23 2007 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Sat, 3 Mar 2007 17:29:23 +0100 (CET) Subject: [pypy-svn] r39826 - pypy/dist/pypy/translator/cli/test Message-ID: <20070303162923.8761A1005A@code0.codespeak.net> Author: antocuni Date: Sat Mar 3 17:29:21 2007 New Revision: 39826 Modified: pypy/dist/pypy/translator/cli/test/test_dotnet.py Log: this has been forgot in my wd for ages... Modified: pypy/dist/pypy/translator/cli/test/test_dotnet.py ============================================================================== --- pypy/dist/pypy/translator/cli/test/test_dotnet.py (original) +++ pypy/dist/pypy/translator/cli/test/test_dotnet.py Sat Mar 3 17:29:21 2007 @@ -242,6 +242,13 @@ return unbox(x[0], ootype.Signed) + unbox(x[1], ootype.Signed) assert self.interpret(fn, []) == 42+43 + def test_array_setitem_None(self): + def fn(): + x = init_array(System.Object, box(42), box(43)) + x[0] = None + return x[0] + assert self.interpret(fn, []) is None + def test_array_length(self): def fn(): x = init_array(System.Object, box(42), box(43)) From antocuni at codespeak.net Sat Mar 3 17:32:35 2007 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Sat, 3 Mar 2007 17:32:35 +0100 (CET) Subject: [pypy-svn] r39827 - in pypy/dist/pypy/translator: cli cli/src cli/test oosupport Message-ID: <20070303163235.0E44F10063@code0.codespeak.net> Author: antocuni Date: Sat Mar 3 17:32:33 2007 New Revision: 39827 Modified: pypy/dist/pypy/translator/cli/cts.py pypy/dist/pypy/translator/cli/function.py pypy/dist/pypy/translator/cli/metavm.py pypy/dist/pypy/translator/cli/src/pypylib.cs pypy/dist/pypy/translator/cli/test/test_dict.py pypy/dist/pypy/translator/oosupport/metavm.py Log: make iteration over dict of voids working Modified: pypy/dist/pypy/translator/cli/cts.py ============================================================================== --- pypy/dist/pypy/translator/cli/cts.py (original) +++ pypy/dist/pypy/translator/cli/cts.py Sat Mar 3 17:32:33 2007 @@ -28,7 +28,6 @@ PYPY_DICT_OF_VOID = '[pypylib]pypy.runtime.DictOfVoid`2<%s, int32>' PYPY_DICT_VOID_VOID = '[pypylib]pypy.runtime.DictVoidVoid' PYPY_DICT_ITEMS_ITERATOR = '[pypylib]pypy.runtime.DictItemsIterator`2<%s, %s>' -PYPY_DICT_VOID_ITEMS_ITERATOR = '[pypylib]pypy.runtime.DictOfVoidItemsIterator`1<%s>' PYPY_STRING_BUILDER = '[pypylib]pypy.runtime.StringBuilder' _lltype_to_cts = { @@ -177,10 +176,9 @@ key_type = self.lltype_to_cts(t._KEYTYPE) value_type = self.lltype_to_cts(t._VALUETYPE) if key_type == 'void': - assert False, 'iteration on dicts with void keys is not supported, yet' + key_type = 'int32' # placeholder if value_type == 'void': value_type = 'int32' # placeholder - return self.__class(PYPY_DICT_ITEMS_ITERATOR % (key_type, value_type), include_class) return _get_from_dict(_lltype_to_cts, t, 'Unknown type %s' % t) @@ -248,8 +246,13 @@ else: METH = oopspec.get_method(TYPE, name) class_name = self.lltype_to_cts(TYPE) - ret_type = self.lltype_to_cts(METH.RESULT) - ret_type = dict_of_void_ll_copy_hack(TYPE, ret_type) + if isinstance(TYPE, ootype.Dict) and TYPE._KEYTYPE is ootype.Void and \ + TYPE._VALUETYPE is ootype.Void and name_or_desc == 'll_get_items_iterator': + # ugly, ugly special case + ret_type = 'class ' + PYPY_DICT_ITEMS_ITERATOR % ('int32', 'int32') + else: + ret_type = self.lltype_to_cts(METH.RESULT) + ret_type = dict_of_void_ll_copy_hack(TYPE, ret_type) generic_types = getattr(TYPE, '_generic_types', {}) arg_types = [self.lltype_to_cts(arg) for arg in METH.ARGS if arg is not ootype.Void and \ Modified: pypy/dist/pypy/translator/cli/function.py ============================================================================== --- pypy/dist/pypy/translator/cli/function.py (original) +++ pypy/dist/pypy/translator/cli/function.py Sat Mar 3 17:32:33 2007 @@ -259,6 +259,8 @@ def load(self, v): if isinstance(v, flowmodel.Variable): + if v.concretetype is ootype.Void: + return # ignore it if v.name in self.argset: selftype, selfname = self.args[0] if self.is_method and v.name == selfname: Modified: pypy/dist/pypy/translator/cli/metavm.py ============================================================================== --- pypy/dist/pypy/translator/cli/metavm.py (original) +++ pypy/dist/pypy/translator/cli/metavm.py Sat Mar 3 17:32:33 2007 @@ -85,8 +85,10 @@ # be a value on the stack, and we need to explicitly pop # it. if isinstance(this.concretetype, ootype.DictItemsIterator) and \ - this.concretetype._VALUETYPE is ootype.Void and \ - method_name == 'll_current_value': + ((this.concretetype._VALUETYPE is ootype.Void and \ + method_name == 'll_current_value') or \ + (this.concretetype._KEYTYPE is ootype.Void and \ + method_name == 'll_current_key')): generator.ilasm.pop() def _render_primitive_function(self, generator, callee, op): Modified: pypy/dist/pypy/translator/cli/src/pypylib.cs ============================================================================== --- pypy/dist/pypy/translator/cli/src/pypylib.cs (original) +++ pypy/dist/pypy/translator/cli/src/pypylib.cs Sat Mar 3 17:32:33 2007 @@ -509,13 +509,11 @@ public bool ll_contains() { return false; } public void ll_clear() { } - //XXX ll_get_items_iterator is not supported, yet - /* - public DictVoidVoidItemsIterator ll_get_items_iterator() + public DictItemsIterator ll_get_items_iterator() { - return new DictVoidVoidItemsIterator(); + List> foo = new List>(); + return new DictItemsIterator(foo.GetEnumerator()); } - */ } public class DictItemsIterator Modified: pypy/dist/pypy/translator/cli/test/test_dict.py ============================================================================== --- pypy/dist/pypy/translator/cli/test/test_dict.py (original) +++ pypy/dist/pypy/translator/cli/test/test_dict.py Sat Mar 3 17:32:33 2007 @@ -11,8 +11,7 @@ class TestCliEmptyDict(CliTest, oodict.BaseTestEmptyDict): - def test_iterate_over_empty_dict(self): - py.test.skip("Iteration over empty dict is not supported, yet") + pass class TestCliConstantDict(CliTest, oodict.BaseTestConstantDict): pass Modified: pypy/dist/pypy/translator/oosupport/metavm.py ============================================================================== --- pypy/dist/pypy/translator/oosupport/metavm.py (original) +++ pypy/dist/pypy/translator/oosupport/metavm.py Sat Mar 3 17:32:33 2007 @@ -356,6 +356,8 @@ op.args[0].value._hints['_suggested_external'] generator.ilasm.new(op.args[0].value._name.split('.')[-1]) except (KeyError, AttributeError): + if op.args[0].value is ootype.Void: + return generator.new(op.args[0].value) class BranchUnconditionally(MicroInstruction): From rxe at codespeak.net Sat Mar 3 17:49:15 2007 From: rxe at codespeak.net (rxe at codespeak.net) Date: Sat, 3 Mar 2007 17:49:15 +0100 (CET) Subject: [pypy-svn] r39828 - pypy/dist/pypy/translator/llvm Message-ID: <20070303164915.47FE610063@code0.codespeak.net> Author: rxe Date: Sat Mar 3 17:49:13 2007 New Revision: 39828 Modified: pypy/dist/pypy/translator/llvm/buildllvm.py Log: (mwh, rxe) progress - can now run without using llvms cbe for tests Modified: pypy/dist/pypy/translator/llvm/buildllvm.py ============================================================================== --- pypy/dist/pypy/translator/llvm/buildllvm.py (original) +++ pypy/dist/pypy/translator/llvm/buildllvm.py Sat Mar 3 17:49:13 2007 @@ -112,12 +112,6 @@ raise def make_module(self): - # use pyrex to create module for CPython - postfix = '' - basename = self.genllvm.filename.purebasename + '_wrapper' + postfix + '.pyx' - pyxfile = self.genllvm.filename.new(basename = basename) - write_pyx_wrapper(self.genllvm, pyxfile) - llvmfile = self.genllvm.filename # change into dirpath and store current path to change back @@ -130,31 +124,39 @@ # generate the llvm bytecode from ll file self.compile_bytecode(b) - object_files = ["-L/sw/lib"] library_files = self.genllvm.db.gcpolicy.gc_libraries() gc_libs = ' '.join(['-l' + lib for lib in library_files]) + object_files = ["-L/sw/lib"] if sys.platform == 'darwin': - libdir = '/sw/' + "/lib" + libdir = '/sw/lib' gc_libs_path = '-L%s -ldl' % libdir else: gc_libs_path = '-static' - modname = pyxfile.purebasename - source_files = ["%s.c" % modname] - - use_gcc = True #self.genllvm.config.translation.llvm_via_c + use_gcc = False #self.genllvm.config.translation.llvm_via_c if not use_gcc: - self.cmds.append("llc %s.bc -f -o %s.s" % (b, b)) + self.cmds.append("llc -relocation-model=pic %s.bc -f -o %s.s" % (b, b)) self.cmds.append("as %s.s -o %s.o" % (b, b)) object_files.append("%s.o" % b) else: self.cmds.append("llc %s.bc -march=c -f -o %s.c" % (b, b)) - source_files.append("%s.c" % b) + self.cmds.append("gcc %s.c -c -O2" % b) + object_files.append("%s.o" % b) try: self.execute_cmds() + + # use pyrex to create module for CPython + basename = self.genllvm.filename.purebasename + '_wrapper.pyx' + pyxfile = self.genllvm.filename.new(basename = basename) + write_pyx_wrapper(self.genllvm, pyxfile) + + modname = pyxfile.purebasename + source_files = ["%s.c" % modname] + make_c_from_pyxfile(pyxfile) + compile_module(modname, source_files, object_files, library_files) finally: @@ -162,7 +164,7 @@ return modname, str(dirpath) - def make_standalone(self, exe_name): + def make_standalone(self, exename): llvmfile = self.genllvm.filename # change into dirpath and store current path to change back @@ -174,7 +176,6 @@ # generate the llvm bytecode from ll file self.compile_bytecode(b) - #compile_objects(b) object_files = ["-L/sw/lib"] library_files = self.genllvm.db.gcpolicy.gc_libraries() @@ -194,7 +195,7 @@ self.cmds.append("llc %s.bc -f -o %s.s" % (b, b)) self.cmds.append("as %s.s -o %s.o" % (b, b)) - cmd = "gcc -O3 %s.o %s %s -lm -pipe -o %s" % (b, gc_libs_path, gc_libs, exe_name) + cmd = "gcc -O3 %s.o %s %s -lm -pipe -o %s" % (b, gc_libs_path, gc_libs, exename) self.cmds.append(cmd) object_files.append("%s.o" % b) else: @@ -203,17 +204,17 @@ cmd = "gcc -fprofile-generate %s.c -c -O3 -pipe -o %s.o" % (b, b) self.cmds.append(cmd) cmd = "gcc -fprofile-generate %s.o %s %s -lm -pipe -o %s_gen" % \ - (b, gc_libs_path, gc_libs, exe_name) + (b, gc_libs_path, gc_libs, exename) self.cmds.append(cmd) - self.cmds.append("./%s_gen %s"%(exe_name, self.genllvm.config.translation.profopt)) + self.cmds.append("./%s_gen %s" % (exename, self.genllvm.config.translation.profopt)) cmd = "gcc -fprofile-use %s.c -c -O3 -pipe -o %s.o" % (b, b) self.cmds.append(cmd) cmd = "gcc -fprofile-use %s.o %s %s -lm -pipe -o %s" % \ - (b, gc_libs_path, gc_libs, exe_name) + (b, gc_libs_path, gc_libs, exename) else: cmd = "gcc %s.c -c -O3 -pipe -fomit-frame-pointer" % b self.cmds.append(cmd) - cmd = "gcc %s.o %s %s -lm -pipe -o %s" % (b, gc_libs_path, gc_libs, exe_name) + cmd = "gcc %s.o %s %s -lm -pipe -o %s" % (b, gc_libs_path, gc_libs, exename) self.cmds.append(cmd) source_files.append("%s.c" % b) @@ -222,4 +223,4 @@ finally: lastdir.chdir() - return str(llvmfile.dirpath().join(exe_name)) + return str(dirpath.join(exename)) From ac at codespeak.net Sat Mar 3 18:05:06 2007 From: ac at codespeak.net (ac at codespeak.net) Date: Sat, 3 Mar 2007 18:05:06 +0100 (CET) Subject: [pypy-svn] r39830 - pypy/dist/pypy/module/_file Message-ID: <20070303170506.2A76D10060@code0.codespeak.net> Author: ac Date: Sat Mar 3 18:05:04 2007 New Revision: 39830 Modified: pypy/dist/pypy/module/_file/interp_file.py Log: issue137 in-progress (asigfrid arre) This checks for EINTR when calling methods on stream objects. This solves using Ctrl-C at the prompt. We may want to make checks in more places. Modified: pypy/dist/pypy/module/_file/interp_file.py ============================================================================== --- pypy/dist/pypy/module/_file/interp_file.py (original) +++ pypy/dist/pypy/module/_file/interp_file.py Sat Mar 3 18:05:04 2007 @@ -1,11 +1,13 @@ import py from pypy.rlib import streamio +from errno import EINTR from pypy.interpreter.error import OperationError from pypy.interpreter.gateway import ObjSpace, W_Root, NoneNotWrapped, applevel from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.typedef import TypeDef from pypy.interpreter.gateway import interp2app +from pypy.interpreter.miscutils import Action import os @@ -13,6 +15,14 @@ def wrap_oserror_as_ioerror(space, e): assert isinstance(e, OSError) errno = e.errno + if errno == EINTR: + # A signal was sent to the process and interupted + # a systemcall. We want to trigger running of + # any installed interrupt handlers. + # XXX: is there a better way? + ec = space.getexecutioncontext() + Action.perform_actions(space.pending_actions) + Action.perform_actions(ec.pending_actions) try: msg = os.strerror(errno) except ValueError: From rxe at codespeak.net Sat Mar 3 18:06:58 2007 From: rxe at codespeak.net (rxe at codespeak.net) Date: Sat, 3 Mar 2007 18:06:58 +0100 (CET) Subject: [pypy-svn] r39831 - pypy/dist/pypy/translator/llvm/test Message-ID: <20070303170658.5833010060@code0.codespeak.net> Author: rxe Date: Sat Mar 3 18:06:55 2007 New Revision: 39831 Modified: pypy/dist/pypy/translator/llvm/test/test_lltype.py Log: upgrade a test a tiny bit Modified: pypy/dist/pypy/translator/llvm/test/test_lltype.py ============================================================================== --- pypy/dist/pypy/translator/llvm/test/test_lltype.py (original) +++ pypy/dist/pypy/translator/llvm/test/test_lltype.py Sat Mar 3 18:06:55 2007 @@ -386,6 +386,7 @@ assert res == 0 + 10 + 30 + 1000 def test_direct_fieldptr(): + gcc3_test() S = GcStruct('S', ('x', Signed), ('y', Signed)) def llf(n): s = malloc(S) @@ -393,7 +394,6 @@ a[0] = n return s.y - py.test.skip("wip") fn = compile_function(llf, [int]) res = fn(34) assert res == 34 From hpk at codespeak.net Sat Mar 3 18:21:22 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sat, 3 Mar 2007 18:21:22 +0100 (CET) Subject: [pypy-svn] r39835 - pypy/dist/pypy/lib Message-ID: <20070303172122.1FE5010060@code0.codespeak.net> Author: hpk Date: Sat Mar 3 18:21:20 2007 New Revision: 39835 Removed: pypy/dist/pypy/lib/_float_formatting.py Modified: pypy/dist/pypy/lib/_formatting.py Log: remove _float_formatting (shifted to user/mwh/pypy-formatting) and traces of its (commented out) usage Modified: pypy/dist/pypy/lib/_formatting.py ============================================================================== --- pypy/dist/pypy/lib/_formatting.py (original) +++ pypy/dist/pypy/lib/_formatting.py Sat Mar 3 18:21:20 2007 @@ -196,8 +196,6 @@ def isnan(v): return v != v*1.0 or (v == 1.0 and v == 2.0) -from _float_formatting import flonum2digits - class FloatFormatter(Formatter): def eDigits(self, ds): ds = ds[:self.prec + 1] + ['0'] * (self.prec + 1 - len(ds)) @@ -244,11 +242,6 @@ return FloatGFormatter('g', self.flags, self.width, self.prec, self.value).format() return self._formatd('f', v) - #ds, k = flonum2digits(v) - #digits = self.fDigits(ds, k) - #if not self.flags.f_alt: - # digits = digits.rstrip('.') - #return digits # system specific formatting. Linux does 3, Windows does 4... # XXX this works only when we use geninterp! @@ -263,10 +256,6 @@ class FloatEFormatter(FloatFormatter): def _format(self, v): return self._formatd('e', v) - #ds, k = flonum2digits(v) - #digits = self.eDigits(ds) - #return "%%s%%c%%+0%dd" % _EF %(digits, self.char, k-1) - class FloatGFormatter(FloatFormatter): # The description of %g in the Python documentation lies @@ -275,23 +264,6 @@ # (One has to wonder who might care). def _format(self, v): return self._formatd('g', v) - ## the following is btw. correct for marshal, now: - #ds, k = flonum2digits(v) - #ds = ds[:self.prec] # XXX rounding! - #if -4 < k <= self.prec: - # if k < 0: - # self.prec -= k # grow prec for extra zeros - # digits = self.fDigits(ds, k) - # if not self.flags.f_alt: - # digits = digits.rstrip('0').rstrip('.') - # r = digits - #else: - # digits = self.eDigits(ds) - # if not self.flags.f_alt: - # digits = digits.rstrip('0').rstrip('.') - # r = "%%se%%+0%dd" % _EF %(digits, k-1) - #return r - class HexFormatter(Formatter): # NB: this has 2.4 semantics wrt. negative values From pedronis at codespeak.net Sat Mar 3 18:44:01 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 3 Mar 2007 18:44:01 +0100 (CET) Subject: [pypy-svn] r39836 - pypy/dist/pypy/objspace Message-ID: <20070303174401.C5D2A10060@code0.codespeak.net> Author: pedronis Date: Sat Mar 3 18:44:00 2007 New Revision: 39836 Modified: pypy/dist/pypy/objspace/taint.py Log: one more step trying to make tain translatable Modified: pypy/dist/pypy/objspace/taint.py ============================================================================== --- pypy/dist/pypy/objspace/taint.py (original) +++ pypy/dist/pypy/objspace/taint.py Sat Mar 3 18:44:00 2007 @@ -205,6 +205,27 @@ self.wrap(app_taint_look)) patch_space_in_place(self, 'taint', proxymaker) + # XXX may leak info, perfomance hit + from pypy.objspace.std.typeobject import W_TypeObject + + def taint_lookup(w_obj, name): + if isinstance(w_obj, W_Tainted): + w_obj = w_obj.w_obj + w_type = self.type(w_obj) + assert isinstance(w_type, W_TypeObject) + return w_type.lookup(name) + + def taint_lookup_in_type_where(w_obj, name): + if isinstance(w_obj, W_Tainted): + w_type = w_obj.w_obj + else: + w_type = w_obj + assert isinstance(w_type, W_TypeObject) + return w_type.lookup_where(name) + + self.lookup = taint_lookup + self.lookup_in_type_where = taint_lookup_in_type_where + Space = TaintSpace From hpk at codespeak.net Sat Mar 3 18:52:10 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sat, 3 Mar 2007 18:52:10 +0100 (CET) Subject: [pypy-svn] r39837 - pypy/dist/pypy/lib Message-ID: <20070303175210.D75AD10061@code0.codespeak.net> Author: hpk Date: Sat Mar 3 18:52:08 2007 New Revision: 39837 Modified: pypy/dist/pypy/lib/_formatting.py Log: (stephan, holger) move value access logic to its own class ValueGetter and ValueBox. This should be helpful for transforming the (currently applevel) code to RPython. (see comment at beginning of file as well) Modified: pypy/dist/pypy/lib/_formatting.py ============================================================================== --- pypy/dist/pypy/lib/_formatting.py (original) +++ pypy/dist/pypy/lib/_formatting.py Sat Mar 3 18:52:08 2007 @@ -6,6 +6,14 @@ # (1) rounding isn't always right (see comments in _float_formatting). # (2) something goes wrong in the f_alt case of %g handling. # (3) it's really, really slow. +# +# XXX regarding moving the below code to RPython (mostly): +# ValueGetter and ValueBox were introduced to encapsulate +# dealing with (wrapped/unwrapped) values. The rest +# of the source code appears to be rather RPython except +# for the usage of rpython-level unicode strings. + + import sys class _Flags(object): @@ -19,12 +27,12 @@ f_zero = 0 -def peel_num(c, fmtiter, valuebox): +def peel_num(c, fmtiter, valuegetter): if c == '*': - v = valuebox.next() - if not isinstance(v, int): + v = valuegetter.nextvalue() + if not v.isint(): raise TypeError, "* wants int" - return fmtiter.next(), v + return fmtiter.next(), v.maybe_int() n = '' while c in '0123456789': n += c @@ -54,9 +62,9 @@ return c, flags -def parse_fmt(fmtiter, valuebox): +def parse_fmt(fmtiter, valuegetter): """return (char, flags, width, prec, value) - partially consumes fmtiter & valuebox""" + partially consumes fmtiter & valuegetter""" c = fmtiter.next() value = None gotvalue = False @@ -72,13 +80,13 @@ elif c == '(': pcount += 1 n += c - value = valuebox.getitem(n) + value = valuegetter.getitem(n) gotvalue = True c = fmtiter.next() c, flags = peel_flags(c, fmtiter) - c, width = peel_num(c, fmtiter, valuebox) + c, width = peel_num(c, fmtiter, valuegetter) if c == '.': - c, prec = peel_num(fmtiter.next(), fmtiter, valuebox) + c, prec = peel_num(fmtiter.next(), fmtiter, valuegetter) else: prec = None if c in 'hlL': @@ -90,10 +98,10 @@ if not gotvalue: if c == '%': # did YOU realize that "%4%"%() == ' %'?? - value = '%' + value = valuegetter.makevalue('%') c = 's' else: - value = valuebox.next() + value = valuegetter.nextvalue() return (c, flags, width, prec, value) @@ -101,12 +109,12 @@ pass class Formatter(object): - def __init__(self, char, flags, width, prec, value): + def __init__(self, char, flags, width, prec, valuebox): self.char = char self.flags = flags self.width = width self.prec = prec - self.value = value + self.valuebox = valuebox def numeric_preprocess(self, v): # negative zeroes? @@ -159,32 +167,13 @@ return r -def funcFormatter(*funcs): - """NOT_RPYTHON""" - class _F(Formatter): - def format(self): - r = self.value - for f in funcs: - r = f(r) - return self.std_wp(r) - return _F - - -def maybe_int(value): - try: - inter = value.__int__ - except AttributeError: - raise TypeError, "int argument required" - return inter() - - -def maybe_float(value): - try: - floater = value.__float__ - except AttributeError: - raise TypeError, "float argument required" - return floater() +class ReprFormatter(Formatter): + def format(self): + return self.std_wp(self.valuebox.repr()) +class PercentFormatter(Formatter): + def format(self): + return '%' # isinf isn't too hard... def isinf(v): @@ -221,7 +210,7 @@ return ''.join(ds) def format(self): - v = maybe_float(self.value) + v = self.valuebox.maybe_float() if isnan(v): return 'nan' elif isinf(v): @@ -240,7 +229,7 @@ def _format(self, v): if v/1e25 > 1e25: return FloatGFormatter('g', self.flags, self.width, - self.prec, self.value).format() + self.prec, self.valuebox).format() return self._formatd('f', v) # system specific formatting. Linux does 3, Windows does 4... @@ -268,7 +257,7 @@ class HexFormatter(Formatter): # NB: this has 2.4 semantics wrt. negative values def format(self): - v, sign = self.numeric_preprocess(maybe_int(self.value)) + v, sign = self.numeric_preprocess(self.valuebox.maybe_int()) r = hex(v)[2:] if r[-1]=="L": # workaround weird behavior of CPython's hex @@ -288,7 +277,7 @@ class OctFormatter(Formatter): # NB: this has 2.4 semantics wrt. negative values def format(self): - v, sign = self.numeric_preprocess(maybe_int(self.value)) + v, sign = self.numeric_preprocess(self.valuebox.maybe_int()) r = oct(v) if r[-1] == "L": r = r[:-1] @@ -302,7 +291,7 @@ class IntFormatter(Formatter): # NB: this has 2.4 semantics wrt. negative values (for %u) def format(self): - v, sign = self.numeric_preprocess(maybe_int(self.value)) + v, sign = self.numeric_preprocess(self.valuebox.maybe_int()) r = str(v) if self.prec is not None and len(r) < self.prec: r = '0'*(self.prec - len(r)) + r @@ -311,15 +300,15 @@ class CharFormatter(Formatter): def format(self): - if isinstance(self.value, str): - v = self.value + if self.valuebox.isstr(): + v = self.valuebox.str() if len(v) != 1: raise TypeError, "%c requires int or char" - elif isinstance(self.value, unicode): + elif self.valuebox.isunicode(): raise NeedUnicodeFormattingError else: - i = maybe_int(self.value) + i = self.valuebox.maybe_int() if not 0 <= i <= 255: raise OverflowError("OverflowError: unsigned byte " "integer is greater than maximum") @@ -329,9 +318,9 @@ class StringFormatter(Formatter): def format(self): - if isinstance(self.value, unicode): + if self.valuebox.isunicode(): raise NeedUnicodeFormattingError - return self.std_wp(str(self.value)) + return self.std_wp(self.valuebox.str()) @@ -350,33 +339,30 @@ 'G':FloatGFormatter, 'c':CharFormatter, 's':StringFormatter, - 'r':funcFormatter(repr), + 'r':ReprFormatter, # this *can* get accessed, by e.g. '%()4%'%{'':1}. # The usual %% case has to be handled specially as it # doesn't consume a value. - '%':funcFormatter(lambda x:'%'), + '%':PercentFormatter, } class UnicodeStringFormatter(Formatter): def format(self): - if isinstance(self.value, unicode): - return self.std_wp(self.value) - if hasattr(self.value,'__unicode__'): - return self.std_wp(self.value.__unicode__()) - return self.std_wp(str(self.value)) + uval = self.valuebox.unicode() + return self.std_wp(uval) class UnicodeCharFormatter(Formatter): def format(self): - if isinstance(self.value, unicode): - v = self.value + if self.valuebox.isunicode(): + v = self.valuebox.unicode() if len(v) != 1: raise TypeError, "%c requires int or unicode char" - elif isinstance(self.value, str): - v = unicode(self.value) + elif self.valuebox.isstr(): + v = unicode(self.valuebox.str()) if len(v) != 1: raise TypeError, "%c requires int or unicode char" else: - i = maybe_int(self.value) + i = self.valuebox.maybe_int() if not 0 <= i <= sys.maxunicode: raise OverflowError("OverflowError: unsigned byte " "integer is greater than maximum") @@ -399,16 +385,14 @@ u'G':FloatGFormatter, u'c':UnicodeCharFormatter, u's':UnicodeStringFormatter, - u'r':funcFormatter(repr), + u'r':ReprFormatter, # this *can* get accessed, by e.g. '%()4%'%{'':1}. # The usual %% case has to be handled specially as it # doesn't consume a value. - u'%':funcFormatter(lambda x:u'%'), + u'%':PercentFormatter, } -del funcFormatter # don't irritate flow space - class FmtIter(object): def __init__(self, fmt): self.fmt = fmt @@ -440,7 +424,7 @@ vb = ValueGetter(values, valuedict) return _format(fmt, vb, do_unicode) -def _format(fmt, valuebox, do_unicode=False): +def _format(fmt, valuegetter, do_unicode=False): if do_unicode: format_registry = unicode_format_registry else: @@ -450,7 +434,7 @@ for c in fmtiter: if c == '%': try: - t = parse_fmt(fmtiter, valuebox) + t = parse_fmt(fmtiter, valuegetter) except StopIteration: raise ValueError, "incomplete format" try: @@ -480,8 +464,7 @@ else: # efficiency hack: r.append(c + fmtiter.skip_to_fmt()) - valuebox.check_consumed() - + valuegetter.check_consumed() if do_unicode: return u''.join(r) return ''.join(r) @@ -501,13 +484,52 @@ raise TypeError('not all arguments converted ' 'during string formatting') - def next(self): + def makevalue(self, string): + return ValueBox(string) + + def nextvalue(self): if self._valueindex >= len(self._values): raise TypeError('not enough arguments for format string') val = self._values[self._valueindex] self._valueindex += 1 - return val + return ValueBox(val) def getitem(self, key): - return self._valuedict[key] + return ValueBox(self._valuedict[key]) +class ValueBox: + def __init__(self, value): + self._value = value + def str(self): + return str(self._value) + def repr(self): + return repr(self._value) + + def isint(self): + return isinstance(self._value, int) + def isunicode(self): + return isinstance(self._value, unicode) + + def maybe_int(self): + try: + inter = self._value.__int__ + except AttributeError: + raise TypeError, "int argument required" + return inter() + + def maybe_float(self): + try: + floater = self._value.__float__ + except AttributeError: + raise TypeError, "float argument required" + return floater() + + def __str__(self): + raise ValueError("use self.str()") + + def unicode(self): + if self.isunicode(): + return self._value + if hasattr(self._value,'__unicode__'): + return self._value.__unicode__() + return unicode(self.str()) From antocuni at codespeak.net Sat Mar 3 18:57:23 2007 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Sat, 3 Mar 2007 18:57:23 +0100 (CET) Subject: [pypy-svn] r39838 - in pypy/dist/pypy: rpython translator/c translator/c/test translator/llvm Message-ID: <20070303175723.47E7410061@code0.codespeak.net> Author: antocuni Date: Sat Mar 3 18:56:54 2007 New Revision: 39838 Modified: pypy/dist/pypy/rpython/extfunc.py pypy/dist/pypy/translator/c/node.py pypy/dist/pypy/translator/c/test/test_standalone.py pypy/dist/pypy/translator/llvm/database.py Log: (antocuni, pedronis) fix the translation again. We don't want to attach _entry to the functions, because they doesn't compare equal and can confuse backends. Modified: pypy/dist/pypy/rpython/extfunc.py ============================================================================== --- pypy/dist/pypy/rpython/extfunc.py (original) +++ pypy/dist/pypy/rpython/extfunc.py Sat Mar 3 18:56:54 2007 @@ -56,7 +56,7 @@ impl.im_func, self.signature_args, self.signature_result) else: obj = rtyper.type_system.getexternalcallable(args_ll, ll_result, - name, _entry=self, _callable=fakeimpl) + name, _external_name=self.name, _callable=fakeimpl) vlist = [hop.inputconst(typeOf(obj), obj)] + hop.inputargs(*args_r) hop.exception_is_here() return hop.genop('direct_call', vlist, r_result) @@ -84,13 +84,13 @@ signature_result = annotation(result, None) name=export_name if llimpl: - lltypeimpl = llimpl + lltypeimpl = staticmethod(llimpl) if ooimpl: - ootypeimpl = ooimpl + ootypeimpl = staticmethd(ooimpl) if llfakeimpl: - lltypefakeimpl = llfakeimpl + lltypefakeimpl = staticmethod(llfakeimpl) if oofakeimpl: - ootypefakeimpl = oofakeimpl + ootypefakeimpl = staticmethod(oofakeimpl) if annotation_hook: ann_hook = staticmethod(annotation_hook) @@ -104,7 +104,6 @@ func = func.value if getattr(func._callable, 'suggested_primitive', False): return True - if hasattr(func, '_entry'): - if isinstance(func._entry, ExtFuncEntry): - return True + if hasattr(func, '_external_name'): + return True return False Modified: pypy/dist/pypy/translator/c/node.py ============================================================================== --- pypy/dist/pypy/translator/c/node.py (original) +++ pypy/dist/pypy/translator/c/node.py Sat Mar 3 18:56:54 2007 @@ -688,8 +688,8 @@ funcgen.implementation_end() def select_function_code_generators(fnobj, db, functionname): - if hasattr(fnobj, '_entry'): - db.externalfuncs[fnobj._entry.name] = fnobj + if hasattr(fnobj, '_external_name'): + db.externalfuncs[fnobj._external_name] = fnobj return [] elif fnobj._callable in extfunc.EXTERNALS: # 'fnobj' is one of the ll_xyz() functions with the suggested_primitive Modified: pypy/dist/pypy/translator/c/test/test_standalone.py ============================================================================== --- pypy/dist/pypy/translator/c/test/test_standalone.py (original) +++ pypy/dist/pypy/translator/c/test/test_standalone.py Sat Mar 3 18:56:54 2007 @@ -118,3 +118,20 @@ out = py.process.cmdexec("%s 500" % exe) assert int(out) == 500*501/2 +def test_frexp(): + import math + def entry_point(argv): + m, e = math.frexp(0) + x, y = math.frexp(0) + print m, x + return 0 + + t = TranslationContext() + t.buildannotator().build_types(entry_point, [s_list_of_strings]) + t.buildrtyper().specialize() + + cbuilder = CStandaloneBuilder(t, entry_point, t.config) + cbuilder.generate_source() + cbuilder.compile() + data = cbuilder.cmdexec('hi there') + assert map(float, data.split()) == [0.0, 0.0] Modified: pypy/dist/pypy/translator/llvm/database.py ============================================================================== --- pypy/dist/pypy/translator/llvm/database.py (original) +++ pypy/dist/pypy/translator/llvm/database.py Sat Mar 3 18:56:54 2007 @@ -58,8 +58,8 @@ if isinstance(type_, lltype.FuncType): if getattr(value._callable, "suggested_primitive", False): node = ExternalFuncNode(self, value) - elif hasattr(value, '_entry'): - node = ExternalFuncNode(self, value, value._entry.name) + elif hasattr(value, '_external_name'): + node = ExternalFuncNode(self, value, value._external_name) elif getattr(value, 'external', None) == 'C': node = SimplerExternalFuncNode(self, value) From arigo at codespeak.net Sat Mar 3 19:09:27 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 3 Mar 2007 19:09:27 +0100 (CET) Subject: [pypy-svn] r39839 - in pypy/branch/rope-branch/pypy/objspace/std: . test Message-ID: <20070303180927.EEFFC1005A@code0.codespeak.net> Author: arigo Date: Sat Mar 3 19:09:27 2007 New Revision: 39839 Modified: pypy/branch/rope-branch/pypy/objspace/std/rope.py pypy/branch/rope-branch/pypy/objspace/std/test/test_rope.py Log: (cfbolz, arigo) Test and temporary fix for it. We're going to hack more on it but it passes the tests now. Modified: pypy/branch/rope-branch/pypy/objspace/std/rope.py ============================================================================== --- pypy/branch/rope-branch/pypy/objspace/std/rope.py (original) +++ pypy/branch/rope-branch/pypy/objspace/std/rope.py Sat Mar 3 19:09:27 2007 @@ -322,42 +322,51 @@ return rebalance(nodelist, length) def rebalance(nodelist, sizehint=-1): - if not nodelist: - return LiteralStringNode("") nodelist.reverse() if sizehint < 0: sizehint = 0 for node in nodelist: sizehint += node.length() + if sizehint == 0: + return LiteralStringNode("") + + # this code is based on the Fibonacci identity: + # sum(fib(i) for i in range(n+1)) == fib(n+2) l = [None] * (find_fib_index(sizehint) + 2) stack = nodelist i = 0 curr = None while stack: curr = stack.pop() - while 1: - if isinstance(curr, BinaryConcatNode) and not curr.balanced: - stack.append(curr.right) - curr = curr.left + while isinstance(curr, BinaryConcatNode) and not curr.balanced: + stack.append(curr.right) + curr = curr.left + + currlen = curr.length() + if currlen == 0: + continue + i = 0 + a, b = 1, 2 + while not (currlen < b and l[i] is None): + if l[i] is not None: + curr = concatenate(l[i], curr) + l[i] = None + currlen = curr.length() else: - i = orig_i = find_fib_index(curr.length()) - index = 0 - added = False - while index <= i: - if l[index] is not None: - curr = concatenate(l[index], curr) - l[index] = None - if index >= orig_i or not added: - i += 1 - added = True - index += 1 - if i == len(l): - return curr - l[i] = curr - break - for index in range(i + 1, len(l)): + i += 1 + a, b = b, a+b + if i == len(l): + return curr + l[i] = curr + + #for index in range(i + 1, len(l)): + curr = None + for index in range(len(l)): if l[index] is not None: - curr = BinaryConcatNode(l[index], curr) + if curr is None: + curr = l[index] + else: + curr = BinaryConcatNode(l[index], curr) assert curr is not None curr.check_balanced() return curr Modified: pypy/branch/rope-branch/pypy/objspace/std/test/test_rope.py ============================================================================== --- pypy/branch/rope-branch/pypy/objspace/std/test/test_rope.py (original) +++ pypy/branch/rope-branch/pypy/objspace/std/test/test_rope.py Sat Mar 3 19:09:27 2007 @@ -181,6 +181,13 @@ for i in range(node.length()): assert result1[i] == result2[i] + strings = ['', '<', + '/home/arigo/svn/pypy/branch/rope-branch/py/code/source.py', + ':', '213', '>'] + l = [LiteralStringNode(s) for s in strings] + node = join(LiteralStringNode(""), l) + assert node.flatten() == ''.join(strings) + def test_join_random(): l, strs = zip(*[make_random_string(10 * i) for i in range(1, 5)]) l = list(l) From arigo at codespeak.net Sat Mar 3 19:27:19 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 3 Mar 2007 19:27:19 +0100 (CET) Subject: [pypy-svn] r39840 - pypy/branch/rope-branch/pypy/objspace/std Message-ID: <20070303182719.A8D0310061@code0.codespeak.net> Author: arigo Date: Sat Mar 3 19:27:18 2007 New Revision: 39840 Modified: pypy/branch/rope-branch/pypy/objspace/std/rope.py Log: (cfbolz, arigo) Clean up and optimize rebalance(). Modified: pypy/branch/rope-branch/pypy/objspace/std/rope.py ============================================================================== --- pypy/branch/rope-branch/pypy/objspace/std/rope.py (original) +++ pypy/branch/rope-branch/pypy/objspace/std/rope.py Sat Mar 3 19:27:18 2007 @@ -334,8 +334,9 @@ # sum(fib(i) for i in range(n+1)) == fib(n+2) l = [None] * (find_fib_index(sizehint) + 2) stack = nodelist - i = 0 - curr = None + empty_up_to = len(l) + a = b = sys.maxint + first_node = None while stack: curr = stack.pop() while isinstance(curr, BinaryConcatNode) and not curr.balanced: @@ -345,28 +346,36 @@ currlen = curr.length() if currlen == 0: continue - i = 0 - a, b = 1, 2 - while not (currlen < b and l[i] is None): - if l[i] is not None: - curr = concatenate(l[i], curr) - l[i] = None - currlen = curr.length() - else: - i += 1 + + if currlen < a: + # we can put 'curr' to its preferred location, which is in + # the known empty part at the beginning of 'l' + a, b = 1, 2 + empty_up_to = 0 + while not (currlen < b): + empty_up_to += 1 a, b = b, a+b - if i == len(l): + else: + # sweep all elements up to the preferred location for 'curr' + while not (currlen < b and l[empty_up_to] is None): + if l[empty_up_to] is not None: + curr = concatenate(l[empty_up_to], curr) + l[empty_up_to] = None + currlen = curr.length() + else: + empty_up_to += 1 + a, b = b, a+b + + if empty_up_to == len(l): return curr - l[i] = curr + l[empty_up_to] = curr + first_node = curr - #for index in range(i + 1, len(l)): - curr = None - for index in range(len(l)): + # sweep all elements + curr = first_node + for index in range(empty_up_to + 1, len(l)): if l[index] is not None: - if curr is None: - curr = l[index] - else: - curr = BinaryConcatNode(l[index], curr) + curr = BinaryConcatNode(l[index], curr) assert curr is not None curr.check_balanced() return curr From rxe at codespeak.net Sat Mar 3 19:35:50 2007 From: rxe at codespeak.net (rxe at codespeak.net) Date: Sat, 3 Mar 2007 19:35:50 +0100 (CET) Subject: [pypy-svn] r39841 - in pypy/dist/pypy/translator/llvm: . test Message-ID: <20070303183550.6EF5B1006E@code0.codespeak.net> Author: rxe Date: Sat Mar 3 19:35:49 2007 New Revision: 39841 Modified: pypy/dist/pypy/translator/llvm/node.py pypy/dist/pypy/translator/llvm/structnode.py pypy/dist/pypy/translator/llvm/test/test_lltype.py Log: (mwh, rxe) implement get_childref() on FixedSizeArrayNode Modified: pypy/dist/pypy/translator/llvm/node.py ============================================================================== --- pypy/dist/pypy/translator/llvm/node.py (original) +++ pypy/dist/pypy/translator/llvm/node.py Sat Mar 3 19:35:49 2007 @@ -59,9 +59,13 @@ __slots__ = "".split() def get_ref(self): - """ Returns a reference as used for operations in blocks. """ + """ Returns a reference as used for operations in blocks for pbc. """ return self.ref + def get_childref(self, index): + """ Returns a reference as used for operations in blocks for internals of a pbc. """ + raise AttributeError("Must be implemented in subclass") + def get_pbcref(self, toptr): """ Returns a reference as a pointer used per pbc. """ return self.ref Modified: pypy/dist/pypy/translator/llvm/structnode.py ============================================================================== --- pypy/dist/pypy/translator/llvm/structnode.py (original) +++ pypy/dist/pypy/translator/llvm/structnode.py Sat Mar 3 19:35:49 2007 @@ -51,6 +51,11 @@ def __str__(self): return "" % self.ref + def setup(self): + fields = self._fields() + if fields: + self.db.prepare_type(fields[0]) + def writedatatypedecl(self, codewriter): codewriter.fixedarraydef(self.ref, self.struct.length, @@ -186,24 +191,21 @@ return "%s [\n %s\n ]\n" % (self.get_typerepr(), all_values) def get_childref(self, index): - pos = 0 - found = False - for name in self.structtype._names_without_voids(): - if name == index: - found = True - break - pos += 1 - - return "getelementptr(%s* %s, int 0, int %s)" %( + ptr_type = self.db.repr_type(self.structtype.OF) + '*' + to_one_type = self.db.repr_type(lltype.FixedSizeArray(self.structtype.OF, 1)) + '*' + ptr = "getelementptr(%s* %s, int 0, int %s)" % ( self.get_typerepr(), self.get_ref(), - pos) + index) + return "cast(%s %s to %s)" % (ptr_type, ptr, to_one_type) def setup(self): if isinstance(self.value, lltype._subarray): - return - super(FixedSizeArrayNode, self).setup() - + p, c = lltype.parentlink(self.value) + if p is not None: + self.db.prepare_constant(lltype.typeOf(p), p) + else: + super(FixedSizeArrayNode, self).setup() class StructVarsizeNode(StructNode): """ A varsize struct constant. Can simply contain Modified: pypy/dist/pypy/translator/llvm/test/test_lltype.py ============================================================================== --- pypy/dist/pypy/translator/llvm/test/test_lltype.py (original) +++ pypy/dist/pypy/translator/llvm/test/test_lltype.py Sat Mar 3 19:35:49 2007 @@ -352,6 +352,7 @@ assert res == -1 def test_direct_arrayitems(): + py.test.skip("wip") for a in [malloc(GcArray(Signed), 5), malloc(FixedSizeArray(Signed, 5), immortal=True)]: a[0] = 0 @@ -372,7 +373,6 @@ finally: a[n] = saved - py.test.skip("wip") fn = compile_function(llf, [int]) res = fn(0) assert res == 1000 + 10 + 30 + 40 @@ -398,8 +398,21 @@ res = fn(34) assert res == 34 +def test_prebuilt_simple_subarrays(): + a2 = malloc(FixedSizeArray(Signed, 5), immortal=True) + a2[1] = 42 + p2 = direct_ptradd(direct_arrayitems(a2), 1) + def llf(): + a2[1] += 100 + return p2[0] + + fn = compile_function(llf, []) + res = fn() + assert res == 142 + def test_prebuilt_subarrays(): - a1 = malloc(GcArray(Signed), 5) + py.test.skip("wip") + a1 = malloc(GcArray(Signed), 5, zero=True) a2 = malloc(FixedSizeArray(Signed, 5), immortal=True) s = malloc(GcStruct('S', ('x', Signed), ('y', Signed))) a1[3] = 7000 @@ -417,53 +430,7 @@ s.y += 1 return p1[0] + p2[0] + p3[0] + p4[0] - py.test.skip("wip") fn = compile_function(llf, []) res = fn() assert res == 8765 -def test_pystruct(): - PS1 = PyStruct('PS1', ('head', PyObject), ('x', Signed), - hints = {'inline_head': True}) - class mytype(object): - pass - mytype_ptr = pyobjectptr(mytype) - def llf(): - p = malloc(PS1, flavor='cpy', extra_args=(mytype_ptr,)) - return cast_pointer(Ptr(PyObject), p) - - py.test.skip("wip") - fn = compile_function(llf) - res = fn() - assert type(res).__name__.endswith('mytype') - -def test_pystruct_prebuilt(): - py.test.skip("wip") - PS1 = PyStruct('PS1', ('head', PyObject), ('x', Signed), - hints = {'inline_head': True}) - class mytype(object): - pass - - def llsetup(phead): - "Called when the CPython ext module is imported." - p = cast_pointer(Ptr(PS1), phead) - p.x = 27 - - mytype_ptr = pyobjectptr(mytype) - p = malloc(PS1, flavor='cpy', extra_args=(mytype_ptr,)) - p.x = -5 # overridden by llsetup() - - def llf(): - return p.x - - def process(t): - rtyper = t.buildrtyper() - rtyper.specialize() - llsetup_ptr = rtyper.annotate_helper_fn(llsetup, [Ptr(PyObject)]) - phead = cast_pointer(Ptr(PyObject), p) - phead._obj.setup_fnptr = llsetup_ptr - - self.process = process - fn = compile_function(llf) - res = fn() - assert res == 27 From antocuni at codespeak.net Sat Mar 3 19:36:20 2007 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Sat, 3 Mar 2007 19:36:20 +0100 (CET) Subject: [pypy-svn] r39842 - in pypy/dist/pypy/rpython: . lltypesystem/module ootypesystem/module Message-ID: <20070303183620.882B910070@code0.codespeak.net> Author: antocuni Date: Sat Mar 3 19:36:18 2007 New Revision: 39842 Added: pypy/dist/pypy/rpython/extfuncregistry.py (contents, props changed) Modified: pypy/dist/pypy/rpython/extfunctable.py pypy/dist/pypy/rpython/lltypesystem/module/ll_math.py pypy/dist/pypy/rpython/ootypesystem/module/ll_math.py Log: (antocuni, pedronis) trying again to fix the translation. Maybe this time we got it :-) Added: pypy/dist/pypy/rpython/extfuncregistry.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/rpython/extfuncregistry.py Sat Mar 3 19:36:18 2007 @@ -0,0 +1,50 @@ +# this registry use the new interface for external functions +# all the above declarations in extfunctable should be moved here at some point. + +import math +from extfunc import register_external + +# ___________________________ +# math functions + +from pypy.rpython.lltypesystem.module import ll_math +from pypy.rpython.ootypesystem.module import ll_math as oo_math + +# the following functions all take one float, return one float +# and are part of math.h +simple_math_functions = [ + 'acos', 'asin', 'atan', 'ceil', 'cos', 'cosh', 'exp', 'fabs', + 'floor', 'log', 'log10', 'sin', 'sinh', 'sqrt', 'tan', 'tanh' + ] +for name in simple_math_functions: + register_external(getattr(math, name), [float], float, "ll_math.ll_math_%s" % name) + +def frexp_hook(): + from pypy.rpython.extfunctable import record_call + from pypy.annotation.model import SomeInteger, SomeTuple, SomeFloat + from pypy.rpython.lltypesystem.module.ll_math import ll_frexp_result + record_call(ll_frexp_result, (SomeFloat(), SomeInteger()), 'MATH_FREXP') + +def modf_hook(): + from pypy.rpython.extfunctable import record_call + from pypy.annotation.model import SomeTuple, SomeFloat + from pypy.rpython.lltypesystem.module.ll_math import ll_modf_result + record_call(ll_modf_result, (SomeFloat(), SomeFloat()), 'MATH_MODF') + +complex_math_functions = [ + ('frexp', [float], (float, int), frexp_hook), + ('atan2', [float, float], float, None), + ('fmod', [float, float], float, None), + ('ldexp', [float, int], float, None), + ('modf', [float], (float, float), modf_hook), + ('hypot', [float, float], float, None), + ('pow', [float, float], float, None), + ] + +for name, args, res, hook in complex_math_functions: + func = getattr(math, name) + llfake = getattr(ll_math, 'll_math_%s' % name, None) + oofake = getattr(oo_math, 'll_math_%s' % name, None) + register_external(func, args, res, 'll_math.ll_math_%s' % name, + llfakeimpl=llfake, oofakeimpl=oofake, + annotation_hook = hook) Modified: pypy/dist/pypy/rpython/extfunctable.py ============================================================================== --- pypy/dist/pypy/rpython/extfunctable.py (original) +++ pypy/dist/pypy/rpython/extfunctable.py Sat Mar 3 19:36:18 2007 @@ -1,9 +1,9 @@ """ information table about external functions for annotation/rtyping and backends """ + import os import time -import math import types from pypy.rlib.rarithmetic import r_longlong @@ -292,53 +292,3 @@ RuntimeError : True, } - - -# ______________________________________________________________ -# this declarations use the new interface for external functions -# all the above declaration should me moved here at some point. - -from extfunc import register_external - -# ___________________________ -# math functions - -from pypy.rpython.lltypesystem.module import ll_math -from pypy.rpython.ootypesystem.module import ll_math as oo_math - -# the following functions all take one float, return one float -# and are part of math.h -simple_math_functions = [ - 'acos', 'asin', 'atan', 'ceil', 'cos', 'cosh', 'exp', 'fabs', - 'floor', 'log', 'log10', 'sin', 'sinh', 'sqrt', 'tan', 'tanh' - ] -for name in simple_math_functions: - register_external(getattr(math, name), [float], float, "ll_math.ll_math_%s" % name) - -def frexp_hook(): - from pypy.annotation.model import SomeInteger, SomeTuple, SomeFloat - from pypy.rpython.lltypesystem.module.ll_math import ll_frexp_result - record_call(ll_frexp_result, (SomeFloat(), SomeInteger()), 'MATH_FREXP') - -def modf_hook(): - from pypy.annotation.model import SomeTuple, SomeFloat - from pypy.rpython.lltypesystem.module.ll_math import ll_modf_result - record_call(ll_modf_result, (SomeFloat(), SomeFloat()), 'MATH_MODF') - -complex_math_functions = [ - ('frexp', [float], (float, int), frexp_hook), - ('atan2', [float, float], float, None), - ('fmod', [float, float], float, None), - ('ldexp', [float, int], float, None), - ('modf', [float], (float, float), modf_hook), - ('hypot', [float, float], float, None), - ('pow', [float, float], float, None), - ] - -for name, args, res, hook in complex_math_functions: - func = getattr(math, name) - llfake = getattr(ll_math, 'll_math_%s' % name, None) - oofake = getattr(oo_math, 'll_math_%s' % name, None) - register_external(func, args, res, 'll_math.ll_math_%s' % name, - llfakeimpl=llfake, oofakeimpl=oofake, - annotation_hook = hook) Modified: pypy/dist/pypy/rpython/lltypesystem/module/ll_math.py ============================================================================== --- pypy/dist/pypy/rpython/lltypesystem/module/ll_math.py (original) +++ pypy/dist/pypy/rpython/lltypesystem/module/ll_math.py Sat Mar 3 19:36:18 2007 @@ -16,10 +16,10 @@ tup.item1 = intpart return tup -def ll_math_frexp(cls, x): +def ll_math_frexp(x): mantissa, exponent = math.frexp(x) return ll_frexp_result(mantissa, exponent) -def ll_math_modf(cls, x): +def ll_math_modf(x): fracpart, intpart = math.modf(x) return ll_modf_result(fracpart, intpart) Modified: pypy/dist/pypy/rpython/ootypesystem/module/ll_math.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/module/ll_math.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/module/ll_math.py Sat Mar 3 19:36:18 2007 @@ -16,11 +16,11 @@ tup.item1 = intpart return tup -def ll_math_frexp(cls, x): +def ll_math_frexp(x): mantissa, exponent = math.frexp(x) return ll_frexp_result(mantissa, exponent) -def ll_math_modf(cls, x): +def ll_math_modf(x): fracpart, intpart = math.modf(x) return ll_modf_result(fracpart, intpart) From rxe at codespeak.net Sat Mar 3 19:38:22 2007 From: rxe at codespeak.net (rxe at codespeak.net) Date: Sat, 3 Mar 2007 19:38:22 +0100 (CET) Subject: [pypy-svn] r39843 - pypy/dist/pypy/translator/llvm Message-ID: <20070303183822.0590010074@code0.codespeak.net> Author: rxe Date: Sat Mar 3 19:38:21 2007 New Revision: 39843 Modified: pypy/dist/pypy/translator/llvm/buildllvm.py Log: (mwh, rxe) back to kludging llvm Modified: pypy/dist/pypy/translator/llvm/buildllvm.py ============================================================================== --- pypy/dist/pypy/translator/llvm/buildllvm.py (original) +++ pypy/dist/pypy/translator/llvm/buildllvm.py Sat Mar 3 19:38:21 2007 @@ -105,7 +105,7 @@ foutput, ferror = c.done() except: data = 'OUTPUT:\n' + foutput.read() + '\n\nERROR:\n' + ferror.read() - fdump = open("%s.errors" % modname, "w") + fdump = open("%s.errors" % self.genllvm.filename, "w") fdump.write(data) fdump.close() log.build(data) @@ -134,7 +134,7 @@ else: gc_libs_path = '-static' - use_gcc = False #self.genllvm.config.translation.llvm_via_c + use_gcc = True #self.genllvm.config.translation.llvm_via_c if not use_gcc: self.cmds.append("llc -relocation-model=pic %s.bc -f -o %s.s" % (b, b)) self.cmds.append("as %s.s -o %s.o" % (b, b)) From antocuni at codespeak.net Sun Mar 4 09:37:02 2007 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Sun, 4 Mar 2007 09:37:02 +0100 (CET) Subject: [pypy-svn] r39844 - pypy/dist/pypy/module/clr Message-ID: <20070304083702.AD5B610060@code0.codespeak.net> Author: antocuni Date: Sun Mar 4 09:37:00 2007 New Revision: 39844 Modified: pypy/dist/pypy/module/clr/interp_clr.py Log: forgot to commit this long time ago 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 Sun Mar 4 09:37:00 2007 @@ -125,6 +125,7 @@ b_prop = b_propertyinfos[i] get_name = None set_name = None + is_static = False if b_prop.get_CanRead(): get_meth = b_prop.GetGetMethod() get_name = get_meth.get_Name() From antocuni at codespeak.net Sun Mar 4 09:38:21 2007 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Sun, 4 Mar 2007 09:38:21 +0100 (CET) Subject: [pypy-svn] r39845 - pypy/dist/pypy/rpython Message-ID: <20070304083821.AB65210060@code0.codespeak.net> Author: antocuni Date: Sun Mar 4 09:38:19 2007 New Revision: 39845 Modified: pypy/dist/pypy/rpython/extfunc.py Log: (antocuni, pedronis) aargh... we forgot to commit this :-( Modified: pypy/dist/pypy/rpython/extfunc.py ============================================================================== --- pypy/dist/pypy/rpython/extfunc.py (original) +++ pypy/dist/pypy/rpython/extfunc.py Sun Mar 4 09:38:19 2007 @@ -53,7 +53,7 @@ fakeimpl = getattr(self, fake_method_name, self.instance) if impl: obj = rtyper.getannmixlevel().delayedfunction( - impl.im_func, self.signature_args, self.signature_result) + impl, self.signature_args, self.signature_result) else: obj = rtyper.type_system.getexternalcallable(args_ll, ll_result, name, _external_name=self.name, _callable=fakeimpl) From antocuni at codespeak.net Sun Mar 4 09:40:07 2007 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Sun, 4 Mar 2007 09:40:07 +0100 (CET) Subject: [pypy-svn] r39846 - pypy/dist/pypy/annotation Message-ID: <20070304084007.3588410060@code0.codespeak.net> Author: antocuni Date: Sun Mar 4 09:40:04 2007 New Revision: 39846 Modified: pypy/dist/pypy/annotation/annrpython.py Log: (antocuni, pedronis) and also this. Sorry for the spam, it's entirely my (antocuni) fault Modified: pypy/dist/pypy/annotation/annrpython.py ============================================================================== --- pypy/dist/pypy/annotation/annrpython.py (original) +++ pypy/dist/pypy/annotation/annrpython.py Sun Mar 4 09:40:04 2007 @@ -23,6 +23,7 @@ def __init__(self, translator=None, policy=None, bookkeeper=None): import pypy.rpython.ootypesystem.ooregistry # has side effects import pypy.rpython.ootypesystem.bltregistry # has side effects + import pypy.rpython.extfuncregistry # has side effects import pypy.rlib.nonconst # has side effects if translator is None: From antocuni at codespeak.net Sun Mar 4 10:12:01 2007 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Sun, 4 Mar 2007 10:12:01 +0100 (CET) Subject: [pypy-svn] r39847 - in pypy/dist/pypy: rpython/test translator/cli translator/cli/test Message-ID: <20070304091201.79E6810060@code0.codespeak.net> Author: antocuni Date: Sun Mar 4 10:11:59 2007 New Revision: 39847 Modified: pypy/dist/pypy/rpython/test/test_remptydict.py pypy/dist/pypy/translator/cli/cts.py pypy/dist/pypy/translator/cli/test/test_dict.py Log: Make dict of voids working better Modified: pypy/dist/pypy/rpython/test/test_remptydict.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_remptydict.py (original) +++ pypy/dist/pypy/rpython/test/test_remptydict.py Sun Mar 4 10:11:59 2007 @@ -31,4 +31,11 @@ pass class TestOOtype(BaseTestRemptydict, OORtypeMixin): - pass + def test_almost_empty_dict(self): + def f(flag): + d = {} + if flag: + d[None] = None + return None in d + assert self.interpret(f, [True]) is True + assert self.interpret(f, [False]) is False Modified: pypy/dist/pypy/translator/cli/cts.py ============================================================================== --- pypy/dist/pypy/translator/cli/cts.py (original) +++ pypy/dist/pypy/translator/cli/cts.py Sun Mar 4 10:11:59 2007 @@ -244,15 +244,22 @@ if isinstance(TYPE, ootype.StaticMethod): METH = TYPE else: - METH = oopspec.get_method(TYPE, name) + METH = oopspec.get_method(TYPE, name) class_name = self.lltype_to_cts(TYPE) - if isinstance(TYPE, ootype.Dict) and TYPE._KEYTYPE is ootype.Void and \ - TYPE._VALUETYPE is ootype.Void and name_or_desc == 'll_get_items_iterator': - # ugly, ugly special case - ret_type = 'class ' + PYPY_DICT_ITEMS_ITERATOR % ('int32', 'int32') + if isinstance(TYPE, ootype.Dict): + KEY = TYPE._KEYTYPE + VALUE = TYPE._VALUETYPE + name = name_or_desc + if KEY is ootype.Void and VALUE is ootype.Void and name == 'll_get_items_iterator': + # ugly, ugly special case + ret_type = 'class ' + PYPY_DICT_ITEMS_ITERATOR % ('int32', 'int32') + elif VALUE is ootype.Void and METH.RESULT is ootype.Dict.VALUETYPE_T: + ret_type = 'void' + else: + ret_type = self.lltype_to_cts(METH.RESULT) + ret_type = dict_of_void_ll_copy_hack(TYPE, ret_type) else: ret_type = self.lltype_to_cts(METH.RESULT) - ret_type = dict_of_void_ll_copy_hack(TYPE, ret_type) generic_types = getattr(TYPE, '_generic_types', {}) arg_types = [self.lltype_to_cts(arg) for arg in METH.ARGS if arg is not ootype.Void and \ Modified: pypy/dist/pypy/translator/cli/test/test_dict.py ============================================================================== --- pypy/dist/pypy/translator/cli/test/test_dict.py (original) +++ pypy/dist/pypy/translator/cli/test/test_dict.py Sun Mar 4 10:11:59 2007 @@ -9,6 +9,13 @@ def test_recursive(self): py.test.skip("CLI doesn't support recursive dicts") + def test_dict_of_void_special_case(self): + def fn(n): + d = {} + for i in xrange(n): + d[i] = None + return d[0] + assert self.interpret(fn, [2]) is None class TestCliEmptyDict(CliTest, oodict.BaseTestEmptyDict): pass From hpk at codespeak.net Sun Mar 4 10:13:20 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sun, 4 Mar 2007 10:13:20 +0100 (CET) Subject: [pypy-svn] r39848 - pypy/dist/pypy/tool/bench Message-ID: <20070304091320.4A75210061@code0.codespeak.net> Author: hpk Date: Sun Mar 4 10:13:18 2007 New Revision: 39848 Added: pypy/dist/pypy/tool/bench/bench-unix.benchmark_result Removed: pypy/dist/pypy/tool/bench/benchmark_test_data2.txt Log: adding pypy benchmark/build data removing other non-related one Added: pypy/dist/pypy/tool/bench/bench-unix.benchmark_result ============================================================================== --- (empty file) +++ pypy/dist/pypy/tool/bench/bench-unix.benchmark_result Sun Mar 4 10:13:18 2007 @@ -0,0 +1,8427 @@ +(dp0 +S'./pypy-cli-35609_pystone' +p1 +I3 +sS'./pypy-c-39324-faassen_richards' +p2 +I8 +sS'./pypy-c-39302-faassen_richards' +p3 +I9 +sS'./pypy-c-37044_richards' +p4 +I10 +sS'./pypy-c-36395-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p5 +I10 +sS'./pypy-llvm-35010-objspace-std-withstrdict-x86_pystone' +p6 +I10 +sS'./pypy-llvm-39247-faassen-c-prof_pystone' +p7 +I10 +sS'./pypy-llvm-35824-objspace-std-withstrdict-x86_richards' +p8 +I10 +sS'./pypy-c-35463-stackless--objspace-std-withstrdict--prof_pystone' +p9 +I10 +sS'./pypy-llvm-36066-faassen-x86_richards' +p10 +I10 +sS'./pypy-llvm-35010-objspace-std-withstrdict-c_richards' +p11 +I10 +sS'./pypy-c-36446-objspace-std-withstrdict--prof_richards' +p12 +I10 +sS'./pypy-c-36628-stackless--objspace-std-withstrdict--prof_pystone' +p13 +I10 +sS'./pypy-c-36344_richards' +p14 +I10 +sS'./pypy-c-36030_richards' +p15 +I10 +sS'./pypy-c-37415-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p16 +I10 +sS'./pypy-c-38651-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p17 +I10 +sS'./pypy-c-35557_pystone' +p18 +I10 +sS'./pypy-llvm-36009-faassen-c-prof_pystone' +p19 +I10 +sS'./pypy-c-38529-objspace-std-withstrdict--prof_richards' +p20 +I10 +sS'./pypy-c-36158-stackless--objspace-std-withstrdict--prof_richards' +p21 +I10 +sS'./pypy-c-35906-gc=framework--objspace-std-withstrdict--prof_pystone' +p22 +I10 +sS'./pypy-llvm-35065-objspace-std-withstrdict-c_richards' +p23 +I10 +sS'./pypy-cli-35544_richards' +p24 +I5 +sS'./pypy-c-35944-objspace-std-withstrdict--prof_pystone' +p25 +I10 +sS'./pypy-c-39218-objspace-std-withfastslice_pystone' +p26 +I10 +sS'./pypy-llvm-36066-faassen-c-prof_richards' +p27 +I10 +sS'./pypy-llvm-39348-faassen-c_pystone' +p28 +I7 +sS'./pypy-c-36859_pystone' +p29 +I10 +sS'./pypy-llvm-36082-faassen-c-prof_richards' +p30 +I10 +sS'./pypy-c-35609-objspace-std-withstrdict--prof_richards' +p31 +I10 +sS'./pypy-c-35923_richards' +p32 +I10 +sS'./pypy-llvm-35867-objspace-std-withstrdict-c-prof_pystone' +p33 +I10 +sS'./pypy-c-39374-stackless--objspace-std-withmultidict--prof_richards' +p34 +I6 +sS'./pypy-c-39474-objspace-std-withfastslice_pystone' +p35 +I4 +sS'./pypy-c-37310-stackless--objspace-std-withstrdict--prof_richards' +p36 +I10 +sS'./pypy-llvm-34976-objspace-std-withstrdict-c_pystone' +p37 +I10 +sS'./pypy-llvm-35771-objspace-std-withstrdict-c-prof_richards' +p38 +I10 +sS'./pypy-c-38994-faassen_richards' +p39 +I10 +sS'./pypy-cli-37163_pystone' +p40 +I10 +sS'./pypy-llvm-35944-faassen-c_pystone' +p41 +I10 +sS'./pypy-llvm-35837-objspace-std-withstrdict-c-prof_pystone' +p42 +I10 +sS'./pypy-c-35824-objspace-std-withstrdict--prof_richards' +p43 +I10 +sS'./pypy-llvm-38994-faassen-c_pystone' +p44 +I10 +sS'./pypy-llvm-unknown-objspace-std-withstrdict-c-prof_richards' +p45 +I8 +sS'./pypy-llvm-36446-faassen-x86_pystone' +p46 +I10 +sS'./pypy-c-35837-stackless--objspace-std-withstrdict--prof_pystone' +p47 +I10 +sS'./pypy-c-37084-objspace-std-withstrdict--prof_richards' +p48 +I10 +sS'./pypy-llvm-35923-objspace-std-withstrdict-x86_richards' +p49 +I10 +sS'./pypy-c-39247-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p50 +I10 +sS'./pypy-c-39072_richards' +p51 +I10 +sS'./pypy-llvm-36158-faassen-c-prof_richards' +p52 +I10 +sS'./pypy-c-35944-stackless--objspace-std-withstrdict--prof_pystone' +p53 +I10 +sS'./pypy-c-36182-objspace-std-withstrdict--prof_pystone' +p54 +I10 +sS'./pypy-c-36113-stackless--objspace-std-withstrdict--prof_pystone' +p55 +I10 +sS'./pypy-llvm-35906-objspace-opcodes-CALL_LIKELY_BUILTIN-c_pystone' +p56 +I10 +sS'./pypy-c-38140-objspace-std-withstrdict--prof_richards' +p57 +I10 +sS'./pypy-c-35512-stackless--objspace-std-withstrdict--prof_richards' +p58 +I10 +sS'./pypy-c-36113_richards' +p59 +I10 +sS'./pypy-c-38870_pystone' +p60 +I10 +sS'./pypy-c-35988-gc=framework--objspace-std-withstrdict--prof_richards' +p61 +I10 +sS'./pypy-llvm-36182-faassen-c_pystone' +p62 +I10 +sS'./pypy-c-34593-stackless--objspace-std-withstrdict--prof_richards' +p63 +I10 +sS'./pypy-c-39188-stackless--objspace-std-withmultidict--prof_richards' +p64 +I10 +sS'./pypy-c-35350_pystone' +p65 +I10 +sS'./pypy-c-35277-stackless--objspace-std-withstrdict--prof_richards' +p66 +I10 +sS'./pypy-c-35237-gc=framework--objspace-std-withstrdict--prof_richards' +p67 +I10 +sS'./pypy-llvm-39247-faassen-c-prof_richards' +p68 +I10 +sS'./pypy-c-35771-stackless--objspace-std-withstrdict--prof_pystone' +p69 +I10 +sS'./pypy-c-37111-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p70 +I10 +sS'./pypy-c-36977-objspace-std-withstrdict--prof_pystone' +p71 +I10 +sS'./pypy-llvm-39324-faassen-c_pystone' +p72 +I8 +sS'./pypy-c-38140-stackless--objspace-std-withstrdict--prof_pystone' +p73 +I10 +sS'./pypy-c-36395-gc=framework--objspace-std-withstrdict--prof_richards' +p74 +I10 +sS'./pypy-llvm-35944-faassen-x86_richards' +p75 +I10 +sS'./pypy-c-38529-faassen_pystone' +p76 +I10 +sS'./pypy-llvm-39374-faassen-c-prof_richards' +p77 +I6 +sS'./pypy-c-35237-stackless--objspace-std-withstrdict--prof_pystone' +p78 +I10 +sS'./pypy-llvm-39302-faassen-c-prof_pystone' +p79 +I9 +sS'./pypy-c-39374-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p80 +I6 +sS'./pypy-c-36082-stackless--objspace-std-withstrdict--prof_richards' +p81 +I10 +sS'./pypy-c-36052_richards' +p82 +I10 +sS'./pypy-c-38870-objspace-std-withstrdict--prof_richards' +p83 +I10 +sS'./pypy-c-35544-gc=framework--objspace-std-withstrdict--prof_richards' +p84 +I10 +sS'./pypy-c-35988-stackless--objspace-std-withstrdict--prof_pystone' +p85 +I10 +sS'./pypy-c-37111-stackless--objspace-std-withstrdict--prof_richards' +p86 +I10 +sS'./pypy-llvm-36220-faassen-c-prof_richards' +p87 +I10 +sS'./pypy-c-36893-objspace-std-withstrdict--prof_pystone' +p88 +I10 +sS'./pypy-llvm-39247-faassen-c_pystone' +p89 +I10 +sS'./pypy-c-34882-objspace-std-withstrdict--prof_pystone' +p90 +I10 +sS'./pypy-c-37310-faassen_richards' +p91 +I10 +sS'./pypy-c-35713-objspace-std-withstrdict--prof_richards' +p92 +I10 +sS'./pypy-c-39474-stackless--objspace-std-withmultidict--prof_pystone' +p93 +I4 +sS'./pypy-c-36395-gc=framework--objspace-std-withstrdict--prof_pystone' +p94 +I10 +sS'./pypy-cli-35713_richards' +p95 +I10 +sS'./pypy-c-39474_richards' +p96 +I4 +sS'./pypy-llvm-39247-faassen-x86_pystone' +p97 +I10 +sS'./pypy-c-35944-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p98 +I10 +sS'./pypy-llvm-36082-faassen-x86_pystone' +p99 +I10 +sS'./pypy-llvm-35982-faassen-x86_richards' +p100 +I10 +sS'./pypy-c-39547-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p101 +I3 +sS'./pypy-c-35837-stackless--objspace-std-withstrdict--prof_richards' +p102 +I10 +sS'./pypy-c-36977_pystone' +p103 +I10 +sS'./pypy-c-39218_richards' +p104 +I10 +sS'./pypy-c-35923-objspace-std-withstrdict--prof_richards' +p105 +I10 +sS'./pypy-cli-38529_richards' +p106 +I3 +sS'./pypy-c-39324_richards' +p107 +I8 +sS'./pypy-c-37454-objspace-std-withstrdict--prof_richards' +p108 +I10 +sS'./pypy-c-39374-stackless--objspace-std-withmultidict--prof_pystone' +p109 +I6 +sS'./pypy-c-38870-objspace-std-withfastslice_richards' +p110 +I10 +sS'./pypy-c-34593-objspace-std-withstrdict--prof_richards' +p111 +I10 +sS'./pypy-llvm-36344-faassen-x86_pystone' +p112 +I10 +sS'./pypy-c-39218_pystone' +p113 +I10 +sS'./pypy-llvm-35963-faassen-c_richards' +p114 +I10 +sS'./pypy-c-39547-objspace-std-withfastslice_pystone' +p115 +I3 +sS'./pypy-c-36113-gc=framework--objspace-std-withstrdict--prof_pystone' +p116 +I10 +sS'./pypy-c-34593_richards' +p117 +I10 +sS'./pypy-c-36182-stackless--objspace-std-withstrdict--prof_pystone' +p118 +I10 +sS'./pypy-c-35350-gc=framework--objspace-std-withstrdict--prof_richards' +p119 +I10 +sS'./pypy-llvm-35979-faassen-c-prof_richards' +p120 +I10 +sS'./pypy-c-36113-stackless--objspace-std-withstrdict--prof_richards' +p121 +I10 +sS'./pypy-c-35824-objspace-std-withstrdict--prof_pystone' +p122 +I10 +sS'./pypy-c-36175-objspace-std-withstrdict--prof_richards' +p123 +I10 +sS'./pypy-c-36158-gc=framework--objspace-std-withstrdict--prof_pystone' +p124 +I10 +sS'./pypy-llvm-39617-faassen-c-prof_pystone' +p125 +I2 +sS'./pypy-c-37310-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p126 +I10 +sS'./pypy-llvm-35095-objspace-std-withstrdict-x86_richards' +p127 +I10 +sS'./pypy-c-39247-faassen_richards' +p128 +I10 +sS'./pypy-llvm-35923-objspace-opcodes-CALL_LIKELY_BUILTIN-c-prof_richards' +p129 +I10 +sS'./pypy-c-38529-objspace-std-withstrdict--prof_pystone' +p130 +I10 +sS'./pypy-cli-36977_pystone' +p131 +I10 +sS'./pypy-c-38769-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p132 +I10 +sS'./pypy-c-37367-objspace-std-withstrdict--prof_pystone' +p133 +I10 +sS'./pypy-c-36030_pystone' +p134 +I10 +sS'./pypy-c-39218-stackless--objspace-std-withmultidict--prof_richards' +p135 +I10 +sS'./pypy-c-37415-objspace-std-withstrdict--prof_pystone' +p136 +I10 +sS'./pypy-c-36066-objspace-std-withstrdict--prof_pystone' +p137 +I10 +sS'./pypy-c-36790-stackless--objspace-std-withstrdict--prof_richards' +p138 +I10 +sS'./pypy-c-35982-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p139 +I10 +sS'./pypy-llvm-36220-faassen-x86_pystone' +p140 +I10 +sS'./pypy-c-36628-gc=framework--objspace-std-withstrdict--prof_richards' +p141 +I10 +sS'./pypy-cli-39374_pystone' +p142 +I6 +sS'./pypy-c-35658-stackless--objspace-std-withstrdict--prof_pystone' +p143 +I10 +sS'./pypy-llvm-35867-objspace-std-withstrdict-x86_pystone' +p144 +I10 +sS'./pypy-cli-37415_pystone' +p145 +I10 +sS'./pypy-c-35837_richards' +p146 +I10 +sS'./pypy-cli-37084_pystone' +p147 +I10 +sS'./pypy-cli-35923_richards' +p148 +I10 +sS'./pypy-c-39646_pystone' +p149 +I1 +sS'./pypy-llvm-36100-faassen-c-prof_pystone' +p150 +I10 +sS'./pypy-llvm-35095-objspace-std-withstrdict-c_pystone' +p151 +I10 +sS'./pypy-llvm-35906-objspace-std-withstrdict-c-prof_richards' +p152 +I10 +sS'./pypy-llvm-35143-objspace-std-withstrdict-c_richards' +p153 +I10 +sS'./pypy-c-37243-objspace-std-withstrdict--prof_pystone' +p154 +I10 +sS'./pypy-c-35065-objspace-std-withstrdict--prof_richards' +p155 +I10 +sS'./pypy-c-35143_pystone' +p156 +I10 +sS'./pypy-c-38222_richards' +p157 +I10 +sS'./pypy-c-39547-gc=framework--objspace-std-withmultidict--prof_pystone' +p158 +I3 +sS'./pypy-c-36009_richards' +p159 +I10 +sS'./pypy-llvm-35183-objspace-std-withstrdict-c_richards' +p160 +I10 +sS'./pypy-c-35512-stackless--objspace-std-withstrdict--prof_pystone' +p161 +I10 +sS'./pypy-c-35277-objspace-std-withstrdict--prof_richards' +p162 +I10 +sS'./pypy-llvm-36220-faassen-x86_richards' +p163 +I10 +sS'./pypy-c-37647-stackless--objspace-std-withstrdict--prof_pystone' +p164 +I10 +sS'./pypy-c-36030-objspace-std-withstrdict--prof_pystone' +p165 +I10 +sS'./pypy-c-38651-stackless--objspace-std-withstrdict--prof_richards' +p166 +I10 +sS'./pypy-c-39072-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p167 +I10 +sS'./pypy-c-36395-objspace-std-withstrdict--prof_richards' +p168 +I10 +sS'./pypy-c-39072-objspace-std-withfastslice_richards' +p169 +I10 +sS'./pypy-c-39324-objspace-std-withfastslice_pystone' +p170 +I8 +sS'./pypy-cli-36113_richards' +p171 +I10 +sS'./pypy-c-35217-gc=framework--objspace-std-withstrdict--prof_pystone' +p172 +I10 +sS'./pypy-c-35968-stackless--objspace-std-withstrdict--prof_richards' +p173 +I10 +sS'./pypy-c-36977_richards' +p174 +I10 +sS'./pypy-c-36182_pystone' +p175 +I10 +sS'./pypy-c-39302-stackless--objspace-std-withmultidict--prof_richards' +p176 +I9 +sS'./pypy-llvm-36030-faassen-c-prof_richards' +p177 +I10 +sS'./pypy-c-35771-objspace-std-withstrdict--prof_richards' +p178 +I10 +sS'./pypy-c-34593-prof_richards' +p179 +I10 +sS'./pypy-cli-35968_richards' +p180 +I7 +sS'./pypy-cli-37044_richards' +p181 +I10 +sS'./pypy-llvm-35982-faassen-c_richards' +p182 +I10 +sS'./pypy-c-36100-stackless--objspace-std-withstrdict--prof_pystone' +p183 +I10 +sS'./pypy-cli-35906_richards' +p184 +I10 +sS'./pypy-c-39147-gc=framework--objspace-std-withmultidict--prof_richards' +p185 +I10 +sS'./pypy-c-39348-gc=framework--objspace-std-withmultidict--prof_pystone' +p186 +I7 +sS'./pypy-llvm-unknown-objspace-std-withstrdict-c-prof_pystone' +p187 +I8 +sS'./pypy-c-35350_richards' +p188 +I10 +sS'./pypy-c-34948-objspace-std-withstrdict--prof_pystone' +p189 +I10 +sS'./pypy-c-38334_richards' +p190 +I10 +sS'./pypy-c-36030-gc=framework--objspace-std-withstrdict--prof_richards' +p191 +I10 +sS'./pypy-c-39324-gc=framework--objspace-std-withmultidict--prof_richards' +p192 +I8 +sS'./pypy-c-35411-objspace-std-withstrdict--prof_pystone' +p193 +I10 +sS'./pypy-llvm-38769-faassen-x86_pystone' +p194 +I10 +sS'./pypy-llvm-34948-objspace-std-withstrdict-c_richards' +p195 +I10 +sS'./pypy-cli-36790_pystone' +p196 +I10 +sS'./pypy-llvm-39147-faassen-c-prof_pystone' +p197 +I10 +sS'./pypy-llvm-36158-faassen-c_pystone' +p198 +I10 +sS'./pypy-c-37647_pystone' +p199 +I10 +sS'./pypy-c-35906-objspace-std-withstrdict--prof_pystone' +p200 +I10 +sS'./pypy-llvm-36009-faassen-x86_pystone' +p201 +I10 +sS'./pypy-c-38140-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p202 +I10 +sS'./pypy-c-35512_pystone' +p203 +I10 +sS'./pypy-c-35713-objspace-std-withstrdict--prof_pystone' +p204 +I10 +sS'./pypy-llvm-39147-faassen-x86_richards' +p205 +I10 +sS'./pypy-cli-35775_richards' +p206 +I10 +sS'./pypy-c-36628-objspace-std-withstrdict--prof_richards' +p207 +I10 +sS'./pypy-c-37647-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p208 +I10 +sS'./pypy-c-35183-stackless--objspace-std-withstrdict--prof_pystone' +p209 +I10 +sS'./pypy-c-37367-gc=framework--objspace-std-withstrdict--prof_pystone' +p210 +I10 +sS'./pypy-cli-35944_richards' +p211 +I9 +sS'./pypy-llvm-34976-objspace-std-withstrdict-c_richards' +p212 +I10 +sS'./pypy-llvm-39072-faassen-c_richards' +p213 +I10 +sS'./pypy-llvm-35095-objspace-std-withstrdict-x86_pystone' +p214 +I10 +sS'./pypy-c-36344-gc=framework--objspace-std-withstrdict--prof_richards' +p215 +I10 +sS'./pypy-c-37647-gc=framework--objspace-std-withstrdict--prof_pystone' +p216 +I10 +sS'./pypy-c-36446-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p217 +I10 +sS'./pypy-llvm-35183-objspace-std-withstrdict-x86_richards' +p218 +I10 +sS'./pypy-c-36175_richards' +p219 +I10 +sS'./pypy-c-37503-gc=framework--objspace-std-withstrdict--prof_richards' +p220 +I10 +sS'./pypy-cli-36790_richards' +p221 +I10 +sS'./pypy-cli-37243_pystone' +p222 +I10 +sS'./pypy-c-39218-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p223 +I10 +sS'./pypy-c-38140_richards' +p224 +I10 +sS'./pypy-llvm-35183-objspace-std-withstrdict-x86_pystone' +p225 +I10 +sS'./pypy-c-35968-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p226 +I10 +sS'./pypy-c-35609-gc=framework--objspace-std-withstrdict--prof_pystone' +p227 +I10 +sS'./pypy-c-36859-objspace-std-withstrdict--prof_pystone' +p228 +I10 +sS'./pypy-c-35658-objspace-std-withstrdict--prof_pystone' +p229 +I10 +sS'./pypy-c-35544-gc=framework--objspace-std-withstrdict--prof_pystone' +p230 +I10 +sS'./pypy-llvm-35923-objspace-std-withstrdict-c-prof_pystone' +p231 +I10 +sS'./pypy-c-36030-stackless--objspace-std-withstrdict--prof_pystone' +p232 +I10 +sS'./pypy-c-35237_pystone' +p233 +I10 +sS'./pypy-cli-37707_richards' +p234 +I10 +sS'./pypy-c-37163-gc=framework--objspace-std-withstrdict--prof_richards' +p235 +I10 +sS'./pypy-c-39247-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p236 +I10 +sS'./pypy-c-39147-objspace-std-withmultidict--prof_pystone' +p237 +I10 +sS'./pypy-c-35906-stackless--prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p238 +I10 +sS'./pypy-c-36539-objspace-std-withstrdict--prof_richards' +p239 +I10 +sS'./pypy-c-37782-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p240 +I10 +sS'./pypy-c-35906-stackless--prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p241 +I10 +sS'./pypy-llvm-39374-faassen-c_richards' +p242 +I6 +sS'./pypy-llvm-35988-faassen-c_pystone' +p243 +I10 +sS'./pypy-c-39218-faassen_richards' +p244 +I10 +sS'./pypy-cli-35713~_richards' +p245 +I1 +sS'./pypy-cli-39247_pystone' +p246 +I10 +sS'./pypy-c-36790-stackless--objspace-std-withstrdict--prof_pystone' +p247 +I10 +sS'./pypy-c-39247-objspace-std-withmultidict--prof_richards' +p248 +I10 +sS'./pypy-llvm-35143-objspace-std-withstrdict-c_pystone' +p249 +I10 +sS'./pypy-c-35237-stackless--objspace-std-withstrdict--prof_richards' +p250 +I10 +sS'./pypy-c-39474-objspace-std-withfastslice_richards' +p251 +I4 +sS'./pypy-c-37163-objspace-std-withstrdict--prof_pystone' +p252 +I10 +sS'./pypy-cli-39348_pystone' +p253 +I7 +sS'./pypy-llvm-39474-faassen-c-prof_richards' +p254 +I4 +sS'./pypy-c-36052-stackless--objspace-std-withstrdict--prof_richards' +p255 +I10 +sS'./pypy-c-37367-gc=framework--objspace-std-withstrdict--prof_richards' +p256 +I10 +sS'./pypy-c-35713_pystone' +p257 +I10 +sS'./pypy-c-36893-stackless--objspace-std-withstrdict--prof_pystone' +p258 +I10 +sS'./pypy-c-37503-objspace-std-withstrdict--prof_richards' +p259 +I10 +sS'./pypy-c-35411-objspace-std-withstrdict--prof_richards' +p260 +I10 +sS'./pypy-c-36539-gc=framework--objspace-std-withstrdict--prof_richards' +p261 +I10 +sS'./pypy-llvm-35968-faassen-c-prof_pystone' +p262 +I10 +sS'./pypy-c-35771-gc=framework--objspace-std-withstrdict--prof_pystone' +p263 +I10 +sS'./pypy-c-35095-objspace-std-withstrdict--prof_richards' +p264 +I10 +sS'./pypy-c-39348_pystone' +p265 +I7 +sS'./pypy-c-35411-stackless--objspace-std-withstrdict--prof_pystone' +p266 +I10 +sS'./pypy-c-35277-objspace-std-withstrdict--prof_pystone' +p267 +I10 +sS'./pypy-c-35837-gc=framework--objspace-std-withstrdict--prof_richards' +p268 +I10 +sS'./pypy-llvm-39302-faassen-c-prof_richards' +p269 +I9 +sS'./pypy-c-37367-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p270 +I10 +sS'./pypy-llvm-35906-objspace-std-withstrdict-c-prof_pystone' +p271 +I10 +sS'./pypy-llvm-36113-faassen-c-prof_pystone' +p272 +I10 +sS'./pypy-llvm-35010-objspace-std-withstrdict-x86_richards' +p273 +I10 +sS'./pypy-llvm-36136-faassen-c_pystone' +p274 +I10 +sS'./pypy-c-36790-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p275 +I10 +sS'./pypy-c-37647-gc=framework--objspace-std-withstrdict--prof_richards' +p276 +I10 +sS'./pypy-llvm-35906-objspace-opcodes-CALL_LIKELY_BUILTIN-x86_richards' +p277 +I10 +sS'./pypy-llvm-39072-faassen-c-prof_richards' +p278 +I10 +sS'./pypy-c-38651_pystone' +p279 +I10 +sS'./pypy-llvm-35968-faassen-c_pystone' +p280 +I10 +sS'./pypy-c-35065_pystone' +p281 +I10 +sS'./pypy-cli-35512_pystone' +p282 +I6 +sS'./pypy-llvm-38994-faassen-c-prof_richards' +p283 +I10 +sS'./pypy-llvm-39547-faassen-c-prof_pystone' +p284 +I3 +sS'./pypy-c-39324-faassen_pystone' +p285 +I8 +sS'./pypy-c-unknown-objspace-std-withstrdict--prof_richards' +p286 +I2 +sS'./pypy-c-36082-gc=framework--objspace-std-withstrdict--prof_pystone' +p287 +I10 +sS'./pypy-cli-39147_richards' +p288 +I10 +sS'./pypy-llvm-36113-faassen-c_richards' +p289 +I10 +sS'./pypy-c-39646-stackless--objspace-std-withmultidict--prof_pystone' +p290 +I1 +sS'./pypy-c-39547-objspace-std-withfastslice_richards' +p291 +I3 +sS'./pypy-cli-35979_pystone' +p292 +I6 +sS'./pypy-cli-35982_richards' +p293 +I5 +sS'./pypy-llvm-36100-faassen-c_richards' +p294 +I10 +sS'./pypy-c-34976_richards' +p295 +I10 +sS'./pypy-llvm-36344-faassen-c_richards' +p296 +I10 +sS'./pypy-c-36158-gc=framework--objspace-std-withstrdict--prof_richards' +p297 +I10 +sS'./pypy-c-39617-faassen_richards' +p298 +I2 +sS'./pypy-c-36628-objspace-std-withstrdict--prof_pystone' +p299 +I10 +sS'./pypy-c-36790-gc=framework--objspace-std-withstrdict--prof_richards' +p300 +I10 +sS'./pypy-c-37707-faassen_richards' +p301 +I10 +sS'./pypy-c-37367-faassen_pystone' +p302 +I10 +sS'./pypy-c-35979-stackless--objspace-std-withstrdict--prof_richards' +p303 +I10 +sS'./pypy-c-36082_pystone' +p304 +I10 +sS'./pypy-c-35968_richards' +p305 +I10 +sS'./pypy-llvm-39072-faassen-c_pystone' +p306 +I10 +sS'./pypy-c-35544_pystone' +p307 +I10 +sS'./pypy-c-38140-faassen_pystone' +p308 +I10 +sS'./pypy-cli-39218_pystone' +p309 +I10 +sS'./pypy-llvm-35963-faassen-c-prof_richards' +p310 +I10 +sS'./pypy-c-37243-objspace-std-withstrdict--prof_richards' +p311 +I10 +sS'./pypy-c-38994-objspace-std-withfastslice_pystone' +p312 +I10 +sS'./pypy-c-39617-gc=framework--objspace-std-withmultidict--prof_pystone' +p313 +I2 +sS'./pypy-llvm-35824-objspace-std-withstrdict-c_pystone' +p314 +I10 +sS'./pypy-c-38651-objspace-std-withfastslice_richards' +p315 +I10 +sS'./pypy-c-36175_pystone' +p316 +I10 +sS'./pypy-llvm-35824-objspace-std-withstrdict-c_richards' +p317 +I10 +sS'./pypy-c-36066-stackless--objspace-std-withstrdict--prof_richards' +p318 +I10 +sS'./pypy-llvm-35968-faassen-x86_pystone' +p319 +I10 +sS'./pypy-llvm-35923-objspace-opcodes-CALL_LIKELY_BUILTIN-x86_richards' +p320 +I10 +sS'./pypy-llvm-39374-faassen-c-prof_pystone' +p321 +I6 +sS'./pypy-llvm-35923-objspace-opcodes-CALL_LIKELY_BUILTIN-c_richards' +p322 +I10 +sS'./pypy-c-37111-stackless--objspace-std-withstrdict--prof_pystone' +p323 +I10 +sS'./pypy-llvm-38870-faassen-x86_richards' +p324 +I10 +sS'./pypy-llvm-36100-faassen-x86_richards' +p325 +I10 +sS'./pypy-c-35544_richards' +p326 +I10 +sS'./pypy-c-36344_pystone' +p327 +I10 +sS'./pypy-c-36066-gc=framework--objspace-std-withstrdict--prof_richards' +p328 +I10 +sS'./pypy-c-39646-gc=framework--objspace-std-withmultidict--prof_pystone' +p329 +I1 +sS'./pypy-llvm-36082-faassen-c-prof_pystone' +p330 +I10 +sS'./pypy-cli-39302_pystone' +p331 +I9 +sS'./pypy-llvm-36030-faassen-x86_richards' +p332 +I10 +sS'./pypy-llvm-38769-faassen-c_pystone' +p333 +I10 +sS'./pypy-c-35411_richards' +p334 +I10 +sS'./pypy-llvm-35906-objspace-opcodes-CALL_LIKELY_BUILTIN-c-prof_richards' +p335 +I10 +sS'./pypy-c-36539-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p336 +I10 +sS'./pypy-c-36344-stackless--objspace-std-withstrdict--prof_pystone' +p337 +I10 +sS'./pypy-c-35277_richards' +p338 +I10 +sS'./pypy-c-39147-faassen_richards' +p339 +I10 +sS'./pypy-c-35771_richards' +p340 +I10 +sS'./pypy-c-36175-objspace-std-withstrdict--prof_pystone' +p341 +I10 +sS'./pypy-c-34593-prof_pystone' +p342 +I10 +sS'./pypy-llvm-39324-faassen-c-prof_richards' +p343 +I8 +sS'./pypy-c-35982-objspace-std-withstrdict--prof_richards' +p344 +I10 +sS'./pypy-cli-37111_richards' +p345 +I10 +sS'./pypy-c-35065-stackless--objspace-std-withstrdict--prof_richards' +p346 +I10 +sS'./pypy-c-39147-stackless--objspace-std-withmultidict--prof_richards' +p347 +I10 +sS'./pypy-c-39617-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p348 +I2 +sS'./pypy-c-34593-stackless_richards' +p349 +I10 +sS'./pypy-c-36977-objspace-std-withstrdict--prof_richards' +p350 +I10 +sS'./pypy-c-36082-objspace-std-withstrdict--prof_richards' +p351 +I10 +sS'./pypy-c-35010_richards' +p352 +I10 +sS'./pypy-llvm-35923-objspace-opcodes-CALL_LIKELY_BUILTIN-x86_pystone' +p353 +I10 +sS'./pypy-c-36009-stackless--objspace-std-withstrdict--prof_richards' +p354 +I10 +sS'./pypy-c-38994-gc=framework--objspace-std-withmultidict--prof_pystone' +p355 +I10 +sS'./pypy-c-38651-faassen_pystone' +p356 +I10 +sS'./pypy-c-39072-objspace-std-withfastslice_pystone' +p357 +I10 +sS'./pypy-c-35143-objspace-std-withstrdict--prof_pystone' +p358 +I10 +sS'./pypy-llvm-39324-faassen-x86_richards' +p359 +I8 +sS'./pypy-c-35867_pystone' +p360 +I10 +sS'./pypy-c-34927-objspace-std-withstrdict--prof_richards' +p361 +I10 +sS'./pypy-c-34976-stackless--objspace-std-withstrdict--prof_pystone' +p362 +I10 +sS'./pypy-c-39374-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p363 +I6 +sS'./pypy-c-35143-gc=framework--objspace-std-withstrdict--prof_richards' +p364 +I10 +sS'./pypy-cli-36175_richards' +p365 +I10 +sS'./pypy-c-39474-faassen_pystone' +p366 +I4 +sS'./pypy-c-38435_pystone' +p367 +I10 +sS'./pypy-c-37782-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p368 +I10 +sS'./pypy-c-39547_richards' +p369 +I3 +sS'./pypy-llvm-35713-objspace-std-withstrdict-x86_richards' +p370 +I10 +sS'./pypy-llvm-35837-objspace-std-withstrdict-x86_richards' +p371 +I10 +sS'./pypy-c-37415-gc=framework--objspace-std-withstrdict--prof_richards' +p372 +I10 +sS'./pypy-llvm-35923-objspace-std-withstrdict-c-prof_richards' +p373 +I10 +sS'./pypy-c-39617-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p374 +I2 +sS'./pypy-c-35713-gc=framework--objspace-std-withstrdict--prof_richards' +p375 +I10 +sS'./pypy-c-35658-objspace-std-withstrdict--prof_richards' +p376 +I10 +sS'./pypy-llvm-39374-faassen-c_pystone' +p377 +I6 +sS'./pypy-cli-35923_pystone' +p378 +I10 +sS'./pypy-c-36628_richards' +p379 +I10 +sS'./pypy-cli-37367_pystone' +p380 +I10 +sS'./pypy-c-39324-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p381 +I8 +sS'./pypy-c-34593_pystone' +p382 +I10 +sS'./pypy-c-36175-stackless--objspace-std-withstrdict--prof_richards' +p383 +I10 +sS'./pypy-cli-36113_pystone' +p384 +I10 +sS'./pypy-c-35923-gc=framework--objspace-std-withstrdict--prof_pystone' +p385 +I10 +sS'./pypy-c-35824-gc=framework--objspace-std-withstrdict--prof_richards' +p386 +I10 +sS'./pypy-llvm-36113-faassen-x86_richards' +p387 +I10 +sS'./pypy-c-39547-faassen_pystone' +p388 +I3 +sS'./pypy-c-38769-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p389 +I10 +sS'./pypy-c-35557-objspace-std-withstrdict--prof_richards' +p390 +I10 +sS'./pypy-c-36009-objspace-std-withstrdict--prof_richards' +p391 +I10 +sS'./pypy-c-37647-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p392 +I10 +sS'./pypy-c-35183-stackless--objspace-std-withstrdict--prof_richards' +p393 +I10 +sS'./pypy-c-37454-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p394 +I10 +sS'./pypy-c-39188-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p395 +I10 +sS'./pypy-c-35658_richards' +p396 +I10 +sS'./pypy-cli-37647_pystone' +p397 +I10 +sS'./pypy-c-39374-gc=framework--objspace-std-withmultidict--prof_pystone' +p398 +I6 +sS'./pypy-c-36220_richards' +p399 +I10 +sS'./pypy-cli-39324_richards' +p400 +I8 +sS'./pypy-c-39147-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p401 +I10 +sS'./pypy-llvm-36344-faassen-c-prof_pystone' +p402 +I10 +sS'./pypy-c-36628-stackless--objspace-std-withstrdict--prof_richards' +p403 +I10 +sS'./pypy-c-39147-objspace-std-withmultidict--prof_richards' +p404 +I10 +sS'./pypy-llvm-unknown-objspace-std-withstrdict-c_richards' +p405 +I8 +sS'./pypy-cli-35968_pystone' +p406 +I7 +sS'./pypy-cli-35713_pystone' +p407 +I10 +sS'./pypy-c-36100-gc=framework--objspace-std-withstrdict--prof_richards' +p408 +I10 +sS'./pypy-c-37454-stackless--objspace-std-withstrdict--prof_pystone' +p409 +I10 +sS'./pypy-llvm-38994-faassen-x86_pystone' +p410 +I10 +sS'./pypy-c-39324-gc=framework--objspace-std-withmultidict--prof_pystone' +p411 +I8 +sS'./pypy-cli-36082_richards' +p412 +I10 +sS'./pypy-c-36066-objspace-std-withstrdict--prof_richards' +p413 +I10 +sS'./pypy-c-35982-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p414 +I10 +sS'./pypy-llvm-39617-faassen-c_richards' +p415 +I2 +sS'./pypy-c-35411-gc=framework--objspace-std-withstrdict--prof_pystone' +p416 +I10 +sS'./pypy-llvm-38870-faassen-c_pystone' +p417 +I10 +sS'./pypy-c-35277-gc=framework--objspace-std-withstrdict--prof_richards' +p418 +I10 +sS'./pypy-cli-35544~_richards' +p419 +I1 +sS'./pypy-c-37707-faassen_pystone' +p420 +I10 +sS'./pypy-c-36100-objspace-std-withstrdict--prof_pystone' +p421 +I10 +sS'./pypy-c-36052-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p422 +I10 +sS'./pypy-c-36790-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p423 +I10 +sS'./pypy-llvm-39646-faassen-c_richards' +p424 +I1 +sS'./pypy-c-39247-faassen_pystone' +p425 +I10 +sS'./pypy-llvm-39474-faassen-x86_pystone' +p426 +I4 +sS'./pypy-llvm-36344-faassen-c_pystone' +p427 +I10 +sS'./pypy-c-36220-gc=framework--objspace-std-withstrdict--prof_pystone' +p428 +I10 +sS'./pypy-cli-35609_richards' +p429 +I3 +sS'./pypy-c-36030-stackless--objspace-std-withstrdict--prof_richards' +p430 +I10 +sS'./pypy-c-35979-objspace-std-withstrdict--prof_pystone' +p431 +I10 +sS'./pypy-c-36344-objspace-std-withstrdict--prof_pystone' +p432 +I10 +sS'./pypy-c-37782_pystone' +p433 +I10 +sS'./pypy-c-35277-stackless--objspace-std-withstrdict--prof_pystone' +p434 +I10 +sS'./pypy-c-39374-faassen_richards' +p435 +I6 +sS'./pypy-llvm-35988-faassen-x86_pystone' +p436 +I10 +sS'./pypy-c-34593-stackless--objspace-std-withstrdict--prof_pystone' +p437 +I10 +sS'./pypy-c-37310-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p438 +I10 +sS'./pypy-llvm-35183-objspace-std-withstrdict-c_pystone' +p439 +I10 +sS'./pypy-llvm-38769-faassen-x86_richards' +p440 +I10 +sS'./pypy-llvm-39302-faassen-c_richards' +p441 +I9 +sS'./pypy-c-34593-gc=framework--objspace-std-withstrdict--prof_richards' +p442 +I10 +sS'./pypy-llvm-39348-faassen-c_richards' +p443 +I7 +sS'./pypy-c-35944_pystone' +p444 +I10 +sS'./pypy-cli-35988_richards' +p445 +I4 +sS'./pypy-cli-38334_richards' +p446 +I10 +sS'./pypy-c-35350-gc=framework--objspace-std-withstrdict--prof_pystone' +p447 +I10 +sS'./pypy-c-36977-stackless--objspace-std-withstrdict--prof_richards' +p448 +I10 +sS'./pypy-c-35867-stackless--objspace-std-withstrdict--prof_richards' +p449 +I10 +sS'./pypy-c-35923-stackless--prof_richards' +p450 +I10 +sS'./pypy-llvm-36052-faassen-c-prof_pystone' +p451 +I10 +sS'./pypy-llvm-36446-faassen-c_richards' +p452 +I10 +sS'./pypy-llvm-35979-faassen-c_richards' +p453 +I10 +sS'./pypy-c-36158-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p454 +I10 +sS'./pypy-llvm-39646-faassen-c-prof_pystone' +p455 +I1 +sS'./pypy-c-34948-stackless--objspace-std-withstrdict--prof_richards' +p456 +I10 +sS'./pypy-c-34882-stackless--objspace-std-withstrdict--prof_richards' +p457 +I10 +sS'./pypy-c-35963-stackless--objspace-std-withstrdict--prof_pystone' +p458 +I10 +sS'./pypy-c-39646-faassen_pystone' +p459 +I1 +sS'./pypy-c-35963_pystone' +p460 +I10 +sS'./pypy-c-35982_pystone' +p461 +I10 +sS'./pypy-c-39147-faassen_pystone' +p462 +I10 +sS'./pypy-c-37084-gc=framework--objspace-std-withstrdict--prof_pystone' +p463 +I10 +sS'./pypy-c-39072-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p464 +I10 +sS'./pypy-c-35988-objspace-std-withstrdict--prof_richards' +p465 +I10 +sS'./pypy-cli-35658_richards' +p466 +I2 +sS'./pypy-c-35609-gc=framework--objspace-std-withstrdict--prof_richards' +p467 +I10 +sS'./pypy-llvm-35824-objspace-std-withstrdict-c-prof_pystone' +p468 +I10 +sS'./pypy-c-35988-gc=framework--objspace-std-withstrdict--prof_pystone' +p469 +I10 +sS'./pypy-c-36628-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p470 +I10 +sS'./pypy-c-36009-gc=framework--objspace-std-withstrdict--prof_richards' +p471 +I10 +sS'./pypy-c-35944-stackless--objspace-std-withstrdict--prof_richards' +p472 +I10 +sS'./pypy-llvm-39547-faassen-c_pystone' +p473 +I3 +sS'./pypy-c-35217-gc=framework--objspace-std-withstrdict--prof_richards' +p474 +I10 +sS'./pypy-llvm-35867-objspace-std-withstrdict-c-prof_richards' +p475 +I10 +sS'./pypy-c-38529-gc=framework--objspace-std-withstrdict--prof_pystone' +p476 +I10 +sS'./pypy-c-37367_richards' +p477 +I10 +sS'./pypy-cli-39302_richards' +p478 +I9 +sS'./pypy-cli-38651_pystone' +p479 +I10 +sS'./pypy-c-37575-gc=framework--objspace-std-withstrdict--prof_richards' +p480 +I10 +sS'./pypy-c-35867-stackless--objspace-std-withstrdict--prof_pystone' +p481 +I10 +sS'./pypy-c-39374-gc=framework--objspace-std-withmultidict--prof_richards' +p482 +I6 +sS'./pypy-c-35979_pystone' +p483 +I10 +sS'./pypy-c-36136-gc=framework--objspace-std-withstrdict--prof_pystone' +p484 +I10 +sS'./pypy-c-35979_richards' +p485 +I10 +sS'./pypy-c-39247-objspace-std-withmultidict--prof_pystone' +p486 +I10 +sS'./pypy-llvm-35824-objspace-std-withstrdict-c-prof_richards' +p487 +I10 +sS'./pypy-c-36395-stackless--objspace-std-withstrdict--prof_pystone' +p488 +I10 +sS'./pypy-cli-36344_richards' +p489 +I10 +sS'./pypy-c-39072-faassen_richards' +p490 +I10 +sS'./pypy-cli-38529_pystone' +p491 +I3 +sS'./pypy-cli-37084_richards' +p492 +I10 +sS'./pypy-c-39188-stackless--objspace-std-withmultidict--prof_pystone' +p493 +I10 +sS'./pypy-c-39348-stackless--objspace-std-withmultidict--prof_pystone' +p494 +I7 +sS'./pypy-llvm-39147-faassen-x86_pystone' +p495 +I10 +sS'./pypy-c-38651_richards' +p496 +I10 +sS'./pypy-llvm-35771-objspace-std-withstrdict-x86_richards' +p497 +I10 +sS'./pypy-c-35968-objspace-std-withstrdict--prof_pystone' +p498 +I10 +sS'./pypy-c-39547-objspace-std-withmultidict--prof_pystone' +p499 +I3 +sS'./pypy-c-35713-stackless--objspace-std-withstrdict--prof_richards' +p500 +I10 +sS'./pypy-c-35867-objspace-std-withstrdict--prof_richards' +p501 +I10 +sS'./pypy-c-39348-objspace-std-withmultidict--prof_pystone' +p502 +I7 +sS'./pypy-llvm-39188-faassen-c_richards' +p503 +I10 +sS'./pypy-c-37243_pystone' +p504 +I10 +sS'./pypy-c-36893-gc=framework--objspace-std-withstrdict--prof_richards' +p505 +I10 +sS'./pypy-llvm-39072-faassen-x86_richards' +p506 +I10 +sS'./pypy-c-38769-faassen_richards' +p507 +I10 +sS'./pypy-c-36100-stackless--objspace-std-withstrdict--prof_richards' +p508 +I10 +sS'./pypy-llvm-35837-objspace-std-withstrdict-x86_pystone' +p509 +I10 +sS'./pypy-c-35463-objspace-std-withstrdict--prof_richards' +p510 +I10 +sS'./pypy-c-35982_richards' +p511 +I10 +sS'./pypy-c-37111_pystone' +p512 +I10 +sS'./pypy-c-35212_pystone' +p513 +I10 +sS'./pypy-c-38994-faassen_pystone' +p514 +I10 +sS'./pypy-c-35065-gc=framework--objspace-std-withstrdict--prof_pystone' +p515 +I10 +sS'./pypy-llvm-34632-objspace-std-withstrdict-c-prof_richards' +p516 +I10 +sS'./pypy-llvm-39218-faassen-c_richards' +p517 +I10 +sS'./pypy-c-35095-gc=framework--objspace-std-withstrdict--prof_pystone' +p518 +I10 +sS'./pypy-c-36446-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p519 +I10 +sS'./pypy-llvm-34948-objspace-std-withstrdict-c_pystone' +p520 +I10 +sS'./pypy-c-37503-stackless--objspace-std-withstrdict--prof_richards' +p521 +I10 +sS'./pypy-c-35557-gc=framework--objspace-std-withstrdict--prof_pystone' +p522 +I10 +sS'./pypy-c-37243-gc=framework--objspace-std-withstrdict--prof_pystone' +p523 +I10 +sS'./pypy-cli-36100_pystone' +p524 +I10 +sS'./pypy-c-36790-objspace-std-withstrdict--prof_richards' +p525 +I10 +sS'./pypy-c-39646-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p526 +I1 +sS'./pypy-c-37367-stackless--objspace-std-withstrdict--prof_pystone' +p527 +I10 +sS'./pypy-llvm-39188-faassen-c_pystone' +p528 +I10 +sS'./pypy-c-38529-gc=framework--objspace-std-withstrdict--prof_richards' +p529 +I10 +sS'./pypy-llvm-35906-objspace-std-withstrdict-c_richards' +p530 +I10 +sS'./pypy-llvm-35713-objspace-std-withstrdict-c_richards' +p531 +I10 +sS'./pypy-cli-39324_pystone' +p532 +I8 +sS'./pypy-c-35183-gc=framework--objspace-std-withstrdict--prof_richards' +p533 +I10 +sS'./pypy-c-36052-stackless--objspace-std-withstrdict--prof_pystone' +p534 +I10 +sS'./pypy-c-37575-objspace-std-withstrdict--prof_richards' +p535 +I10 +sS'./pypy-c-34882-stackless--objspace-std-withstrdict--prof_pystone' +p536 +I10 +sS'./pypy-c-36893-gc=framework--objspace-std-withstrdict--prof_pystone' +p537 +I10 +sS'./pypy-c-35411_pystone' +p538 +I10 +sS'./pypy-c-37782-objspace-std-withstrdict--prof_pystone' +p539 +I10 +sS'./pypy-cli-39072_pystone' +p540 +I10 +sS'./pypy-c-36052-gc=framework--objspace-std-withstrdict--prof_richards' +p541 +I10 +sS'./pypy-c-37575-objspace-std-withstrdict--prof_pystone' +p542 +I10 +sS'./pypy-cli-35544_pystone' +p543 +I5 +sS'./pypy-c-35906-gc=framework--objspace-std-withstrdict--prof_richards' +p544 +I10 +sS'./pypy-c-38769-objspace-std-withstrdict--prof_richards' +p545 +I10 +sS'./pypy-c-36859-stackless--objspace-std-withstrdict--prof_richards' +p546 +I10 +sS'./pypy-c-37782_richards' +p547 +I10 +sS'./pypy-llvm-39474-faassen-c-prof_pystone' +p548 +I4 +sS'./pypy-cli-36859_richards' +p549 +I10 +sS'./pypy-c-34976-stackless--objspace-std-withstrdict--prof_richards' +p550 +I10 +sS'./pypy-llvm-35988-faassen-c-prof_pystone' +p551 +I10 +sS'./pypy-c-39348-faassen_pystone' +p552 +I7 +sS'./pypy-llvm-39374-faassen-x86_pystone' +p553 +I6 +sS'./pypy-c-39374_richards' +p554 +I6 +sS'./pypy-cli-39474_richards' +p555 +I4 +sS'./pypy-c-37503_pystone' +p556 +I10 +sS'./pypy-c-36082-objspace-std-withstrdict--prof_pystone' +p557 +I10 +sS'./pypy-c-37044-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p558 +I10 +sS'./pypy-llvm-35143-objspace-std-withstrdict-x86_richards' +p559 +I10 +sS'./pypy-cli-35979_richards' +p560 +I6 +sS'./pypy-cli-36009_richards' +p561 +I3 +sS'./pypy-c-36446_richards' +p562 +I10 +sS'./pypy-llvm-36539-faassen-c_pystone' +p563 +I10 +sS'./pypy-c-35350-stackless--objspace-std-withstrdict--prof_richards' +p564 +I10 +sS'./pypy-c-35557-gc=framework--objspace-std-withstrdict--prof_richards' +p565 +I10 +sS'./pypy-c-37243-stackless--objspace-std-withstrdict--prof_pystone' +p566 +I10 +sS'./pypy-llvm-36082-faassen-x86_richards' +p567 +I10 +sS'./pypy-c-35609-objspace-std-withstrdict--prof_pystone' +p568 +I10 +sS'./pypy-c-35544-objspace-std-withstrdict--prof_pystone' +p569 +I10 +sS'./pypy-c-35979-objspace-std-withstrdict--prof_richards' +p570 +I10 +sS'./pypy-c-38529_pystone' +p571 +I3 +sS'./pypy-c-36395_pystone' +p572 +I10 +sS'./pypy-llvm-35988-faassen-x86_richards' +p573 +I10 +sS'./pypy-cli-39374_richards' +p574 +I6 +sS'./pypy-c-37415-faassen_richards' +p575 +I10 +sS'./pypy-c-39188_richards' +p576 +I10 +sS'./pypy-c-39147-objspace-std-withfastslice_richards' +p577 +I10 +sS'./pypy-c-35867-gc=framework--objspace-std-withstrdict--prof_richards' +p578 +I10 +sS'./pypy-c-36066-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p579 +I10 +sS'./pypy-c-36158_richards' +p580 +I10 +sS'./pypy-c-36100_pystone' +p581 +I10 +sS'./pypy-c-36113-gc=framework--objspace-std-withstrdict--prof_richards' +p582 +I10 +sS'./pypy-c-36220-stackless--objspace-std-withstrdict--prof_pystone' +p583 +I10 +sS'./pypy-llvm-39348-faassen-x86_richards' +p584 +I7 +sS'./pypy-c-38140-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p585 +I10 +sS'./pypy-c-39374-objspace-std-withfastslice_richards' +p586 +I6 +sS'./pypy-c-39348-objspace-std-withfastslice_pystone' +p587 +I7 +sS'./pypy-c-39072-gc=framework--objspace-std-withmultidict--prof_richards' +p588 +I10 +sS'./pypy-c-36893-stackless--objspace-std-withstrdict--prof_richards' +p589 +I10 +sS'./pypy-c-38870-objspace-std-withstrdict--prof_pystone' +p590 +I10 +sS'./pypy-cli-36066_richards' +p591 +I10 +sS'./pypy-c-35065-stackless--objspace-std-withstrdict--prof_pystone' +p592 +I10 +sS'./pypy-c-34593-stackless_pystone' +p593 +I10 +sS'./pypy-c-37310-faassen_pystone' +p594 +I10 +sS'./pypy-c-36082-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p595 +I10 +sS'./pypy-c-36539-stackless--objspace-std-withstrdict--prof_pystone' +p596 +I10 +sS'./pypy-c-34882-objspace-std-withstrdict--prof_richards' +p597 +I10 +sS'./pypy-cli-35867_richards' +p598 +I10 +sS'./pypy-llvm-39147-faassen-c-prof_richards' +p599 +I10 +sS'./pypy-c-37415-stackless--objspace-std-withstrdict--prof_richards' +p600 +I10 +sS'./pypy-cli-35982_pystone' +p601 +I5 +sS'./pypy-llvm-34976-objspace-std-withstrdict-c-prof_pystone' +p602 +I10 +sS'./pypy-c-39646-objspace-std-withfastslice_richards' +p603 +I1 +sS'./pypy-cli-37367_richards' +p604 +I10 +sS'./pypy-cli-35963_richards' +p605 +I8 +sS'./pypy-llvm-35713-objspace-std-withstrdict-x86_pystone' +p606 +I10 +sS'./pypy-c-35183-objspace-std-withstrdict--prof_pystone' +p607 +I10 +sS'./pypy-c-39348-gc=framework--objspace-std-withmultidict--prof_richards' +p608 +I7 +sS'./pypy-llvm-35713-objspace-std-withstrdict-c-prof_pystone' +p609 +I10 +sS'./pypy-c-39072-objspace-std-withmultidict--prof_pystone' +p610 +I10 +sS'./pypy-cli-39188_richards' +p611 +I10 +sS'./pypy-cli-35988_pystone' +p612 +I4 +sS'./pypy-c-39188-objspace-std-withfastslice_richards' +p613 +I10 +sS'./pypy-c-35979-gc=framework--objspace-std-withstrdict--prof_richards' +p614 +I10 +sS'./pypy-llvm-35867-objspace-std-withstrdict-c_pystone' +p615 +I10 +sS'./pypy-c-35771-objspace-std-withstrdict--prof_pystone' +p616 +I10 +sS'./pypy-llvm-36539-faassen-x86_pystone' +p617 +I10 +sS'./pypy-llvm-39646-faassen-c_pystone' +p618 +I1 +sS'./pypy-c-35512_richards' +p619 +I10 +sS'./pypy-c-36030-gc=framework--objspace-std-withstrdict--prof_pystone' +p620 +I10 +sS'./pypy-c-35010-objspace-std-withstrdict--prof_richards' +p621 +I10 +sS'./pypy-c-36009-stackless--objspace-std-withstrdict--prof_pystone' +p622 +I10 +sS'./pypy-c-36136_pystone' +p623 +I10 +sS'./pypy-llvm-35982-faassen-c_pystone' +p624 +I10 +sS'./pypy-llvm-39302-faassen-x86_richards' +p625 +I9 +sS'./pypy-c-39247-objspace-std-withfastslice_pystone' +p626 +I10 +sS'./pypy-c-35923-stackless--objspace-std-withstrdict--prof_pystone' +p627 +I10 +sS'./pypy-c-37415-stackless--objspace-std-withstrdict--prof_pystone' +p628 +I10 +sS'./pypy-c-37310-objspace-std-withstrdict--prof_pystone' +p629 +I10 +sS'./pypy-llvm-36539-faassen-c-prof_richards' +p630 +I10 +sS'./pypy-c-39147-gc=framework--objspace-std-withmultidict--prof_pystone' +p631 +I10 +sS'./pypy-c-35837_pystone' +p632 +I10 +sS'./pypy-llvm-35713-objspace-std-withstrdict-c-prof_richards' +p633 +I10 +sS'./pypy-cli-39474_pystone' +p634 +I4 +sS'./pypy-cli-38870_pystone' +p635 +I10 +sS'./pypy-c-35212-objspace-std-withstrdict--prof_pystone' +p636 +I10 +sS'./pypy-c-39324-objspace-std-withfastslice_richards' +p637 +I8 +sS'./pypy-llvm-36030-faassen-x86_pystone' +p638 +I10 +sS'./pypy-llvm-35065-objspace-std-withstrdict-c_pystone' +p639 +I10 +sS'./pypy-c-36113-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p640 +I10 +sS'./pypy-c-39188-faassen_pystone' +p641 +I10 +sS'./pypy-c-36175-stackless--objspace-std-withstrdict--prof_pystone' +p642 +I10 +sS'./pypy-c-35867-objspace-std-withstrdict--prof_pystone' +p643 +I10 +sS'./pypy-c-39302-objspace-std-withmultidict--prof_richards' +p644 +I9 +sS'./pypy-c-37707-objspace-std-withstrdict--prof_pystone' +p645 +I10 +sS'./pypy-c-39247-stackless--objspace-std-withmultidict--prof_richards' +p646 +I10 +sS'./pypy-c-37782-gc=framework--objspace-std-withstrdict--prof_pystone' +p647 +I10 +sS'./pypy-c-36182-objspace-std-withstrdict--prof_richards' +p648 +I10 +sS'./pypy-c-35350-objspace-std-withstrdict--prof_richards' +p649 +I10 +sS'./pypy-c-38334-objspace-std-withfastslice_pystone' +p650 +I10 +sS'./pypy-c-38870-gc=framework--objspace-std-withstrdict--prof_richards' +p651 +I10 +sS'./pypy-c-39188-objspace-std-withfastslice_pystone' +p652 +I10 +sS'./pypy-llvm-35944-faassen-c-prof_richards' +p653 +I10 +sS'./pypy-c-39547-stackless--objspace-std-withmultidict--prof_richards' +p654 +I3 +sS'./pypy-llvm-39348-faassen-c-prof_richards' +p655 +I7 +sS'./pypy-c-36220-gc=framework--objspace-std-withstrdict--prof_richards' +p656 +I10 +sS'./pypy-c-36030-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p657 +I10 +sS'./pypy-c-39218-faassen_pystone' +p658 +I10 +sS'./pypy-c-36158-objspace-std-withstrdict--prof_richards' +p659 +I10 +sS'./pypy-c-39302_richards' +p660 +I9 +sS'./pypy-c-37575-stackless--objspace-std-withstrdict--prof_pystone' +p661 +I10 +sS'./pypy-c-37415_pystone' +p662 +I10 +sS'./pypy-c-35824-gc=framework--objspace-std-withstrdict--prof_pystone' +p663 +I10 +sS'./pypy-c-37454_pystone' +p664 +I10 +sS'./pypy-c-38870-stackless--objspace-std-withstrdict--prof_richards' +p665 +I10 +sS'./pypy-c-38651-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p666 +I10 +sS'./pypy-llvm-36030-faassen-c-prof_pystone' +p667 +I10 +sS'./pypy-cli-36136_pystone' +p668 +I10 +sS'./pypy-c-35824_richards' +p669 +I10 +sS'./pypy-c-39147_richards' +p670 +I10 +sS'./pypy-c-39646-objspace-std-withmultidict--prof_richards' +p671 +I1 +sS'./pypy-c-39188-gc=framework--objspace-std-withmultidict--prof_pystone' +p672 +I10 +sS'./pypy-c-36446_pystone' +p673 +I10 +sS'./pypy-c-36066_pystone' +p674 +I10 +sS'./pypy-c-34948-gc=framework--objspace-std-withstrdict--prof_richards' +p675 +I10 +sS'./pypy-llvm-39188-faassen-c-prof_richards' +p676 +I10 +sS'./pypy-c-35963-objspace-std-withstrdict--prof_richards' +p677 +I10 +sS'./pypy-c-37111_richards' +p678 +I10 +sS'./pypy-c-36158-objspace-std-withstrdict--prof_pystone' +p679 +I10 +sS'./pypy-c-35979-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p680 +I10 +sS'./pypy-c-34976-objspace-std-withstrdict--prof_richards' +p681 +I10 +sS'./pypy-c-39374-objspace-std-withmultidict--prof_richards' +p682 +I6 +sS'./pypy-c-36066-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p683 +I10 +sS'./pypy-cli-35713~_pystone' +p684 +I1 +sS'./pypy-c-35095-objspace-std-withstrdict--prof_pystone' +p685 +I10 +sS'./pypy-c-39072-stackless--objspace-std-withmultidict--prof_richards' +p686 +I10 +sS'./pypy-c-36220-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p687 +I10 +sS'./pypy-llvm-35944-faassen-c-prof_pystone' +p688 +I10 +sS'./pypy-c-37503-stackless--objspace-std-withstrdict--prof_pystone' +p689 +I10 +sS'./pypy-c-35143-stackless--objspace-std-withstrdict--prof_pystone' +p690 +I10 +sS'./pypy-c-36344-stackless--objspace-std-withstrdict--prof_richards' +p691 +I10 +sS'./pypy-llvm-39547-faassen-c-prof_richards' +p692 +I3 +sS'./pypy-llvm-35713-objspace-std-withstrdict-c_pystone' +p693 +I10 +sS'./pypy-c-37647-stackless--objspace-std-withstrdict--prof_richards' +p694 +I10 +sS'./pypy-c-36182-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p695 +I10 +sS'./pypy-c-36030-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p696 +I10 +sS'./pypy-c-39474_pystone' +p697 +I4 +sS'./pypy-c-35771_pystone' +p698 +I10 +sS'./pypy-c-35944-gc=framework--objspace-std-withstrdict--prof_pystone' +p699 +I10 +sS'./pypy-c-36859-stackless--objspace-std-withstrdict--prof_pystone' +p700 +I10 +sS'./pypy-c-34948-gc=framework--objspace-std-withstrdict--prof_pystone' +p701 +I10 +sS'./pypy-c-39072_pystone' +p702 +I10 +sS'./pypy-llvm-36082-faassen-c_pystone' +p703 +I10 +sS'./pypy-c-35065_richards' +p704 +I10 +sS'./pypy-cli-35463_richards' +p705 +I7 +sS'./pypy-c-37782-faassen_richards' +p706 +I10 +sS'./pypy-c-37163-stackless--objspace-std-withstrdict--prof_pystone' +p707 +I10 +sS'./pypy-llvm-35988-faassen-c_richards' +p708 +I10 +sS'./pypy-c-36893-objspace-std-withstrdict--prof_richards' +p709 +I10 +sS'./pypy-llvm-34976-objspace-std-withstrdict-x86_richards' +p710 +I10 +sS'./pypy-c-37044-gc=framework--objspace-std-withstrdict--prof_richards' +p711 +I10 +sS'./pypy-c-39646-faassen_richards' +p712 +I1 +sS'./pypy-c-39617-objspace-std-withmultidict--prof_richards' +p713 +I2 +sS'./pypy-c-35771-gc=framework--objspace-std-withstrdict--prof_richards' +p714 +I10 +sS'2.3.5_pystone' +p715 +I10 +sS'./pypy-c-37707-gc=framework--objspace-std-withstrdict--prof_pystone' +p716 +I10 +sS'./pypy-llvm-36009-faassen-c_richards' +p717 +I10 +sS'./pypy-c-39188-gc=framework--objspace-std-withmultidict--prof_richards' +p718 +I10 +sS'./pypy-c-38529-faassen_richards' +p719 +I10 +sS'./pypy-c-36158-stackless--objspace-std-withstrdict--prof_pystone' +p720 +I10 +sS'./pypy-c-35906_pystone' +p721 +I10 +sS'./pypy-cli-37707_pystone' +p722 +I10 +sS'./pypy-llvm-35982-faassen-c-prof_richards' +p723 +I10 +sS'./pypy-c-36082-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p724 +I10 +sS'./pypy-llvm-34632-objspace-std-withstrdict-c_pystone' +p725 +I10 +sS'./pypy-llvm-35979-faassen-c_pystone' +p726 +I10 +sS'./pypy-llvm-39218-faassen-c-prof_richards' +p727 +I10 +sS'./pypy-llvm-39218-faassen-x86_pystone' +p728 +I10 +sS'./pypy-cli-35658_pystone' +p729 +I2 +sS'./pypy-llvm-35143-objspace-std-withstrdict-c-prof_richards' +p730 +I10 +sS'./pypy-c-36182-gc=framework--objspace-std-withstrdict--prof_richards' +p731 +I10 +sS'./pypy-c-35143-objspace-std-withstrdict--prof_richards' +p732 +I10 +sS'./pypy-llvm-36113-faassen-c-prof_richards' +p733 +I10 +sS'./pypy-c-39547-stackless--objspace-std-withmultidict--prof_pystone' +p734 +I3 +sS'./pypy-c-35557-objspace-std-withstrdict--prof_pystone' +p735 +I10 +sS'./pypy-llvm-38870-faassen-c-prof_richards' +p736 +I10 +sS'./pypy-c-35217_pystone' +p737 +I10 +sS'./pypy-c-35824_pystone' +p738 +I10 +sS'./pypy-cli-37575_richards' +p739 +I10 +sS'./pypy-c-37782-stackless--objspace-std-withstrdict--prof_richards' +p740 +I10 +sS'./pypy-llvm-36175-faassen-c-prof_pystone' +p741 +I10 +sS'./pypy-c-34927-gc=framework--objspace-std-withstrdict--prof_richards' +p742 +I10 +sS'./pypy-c-36977-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p743 +I10 +sS'./pypy-llvm-38769-faassen-c_richards' +p744 +I10 +sS'./pypy-c-35217_richards' +p745 +I10 +sS'./pypy-c-34882-gc=framework--objspace-std-withstrdict--prof_pystone' +p746 +I10 +sS'./pypy-c-34976-objspace-std-withstrdict--prof_pystone' +p747 +I10 +sS'./pypy-llvm-36066-faassen-c-prof_pystone' +p748 +I10 +sS'./pypy-c-37367_pystone' +p749 +I10 +sS'./pypy-c-35217-objspace-std-withstrdict--prof_richards' +p750 +I10 +sS'./pypy-c-34593-thread--objspace-std-withstrdict--prof_pystone' +p751 +I10 +sS'./pypy-c-39348_richards' +p752 +I7 +sS'./pypy-cli-37782_pystone' +p753 +I10 +sS'./pypy-llvm-35143-objspace-std-withstrdict-x86_pystone' +p754 +I10 +sS'./pypy-llvm-38769-faassen-c-prof_pystone' +p755 +I10 +sS'./pypy-c-36182-stackless--objspace-std-withstrdict--prof_richards' +p756 +I10 +sS'./pypy-c-35544-objspace-std-withstrdict--prof_richards' +p757 +I10 +sS'./pypy-llvm-35963-faassen-c-prof_pystone' +p758 +I10 +sS'./pypy-cli-37575_pystone' +p759 +I10 +sS'./pypy-c-36628_pystone' +p760 +I10 +sS'./pypy-llvm-36113-faassen-x86_pystone' +p761 +I10 +sS'./pypy-c-39147-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p762 +I10 +sS'./pypy-cli-36539_richards' +p763 +I10 +sS'./pypy-c-34927-stackless--objspace-std-withstrdict--prof_richards' +p764 +I10 +sS'./pypy-cli-36158_richards' +p765 +I10 +sS'./pypy-llvm-39218-faassen-x86_richards' +p766 +I10 +sS'./pypy-c-37163_pystone' +p767 +I10 +sS'./pypy-c-35982-gc=framework--objspace-std-withstrdict--prof_richards' +p768 +I10 +sS'./pypy-c-39188-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p769 +I10 +sS'./pypy-c-35963-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p770 +I10 +sS'./pypy-c-36175-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p771 +I10 +sS'./pypy-c-38651-gc=framework--objspace-std-withstrdict--prof_pystone' +p772 +I10 +sS'./pypy-cli-39072_richards' +p773 +I10 +sS'./pypy-c-36066-stackless--objspace-std-withstrdict--prof_pystone' +p774 +I10 +sS'./pypy-c-37310_pystone' +p775 +I10 +sS'./pypy-c-unknown_richards' +p776 +I7 +sS'./pypy-llvm-35906-objspace-opcodes-CALL_LIKELY_BUILTIN-c-prof_pystone' +p777 +I10 +sS'./pypy-c-36182-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p778 +I10 +sS'./pypy-c-39302_pystone' +p779 +I9 +sS'./pypy-llvm-36030-faassen-c_richards' +p780 +I10 +sS'./pypy-c-35237_richards' +p781 +I10 +sS'./pypy-c-35350-objspace-std-withstrdict--prof_pystone' +p782 +I10 +sS'./pypy-c-35923-objspace-std-withstrdict--prof_pystone' +p783 +I10 +sS'./pypy-llvm-39348-faassen-c-prof_pystone' +p784 +I7 +sS'./pypy-llvm-34948-objspace-std-withstrdict-c-prof_pystone' +p785 +I10 +sS'./pypy-c-37782-faassen_pystone' +p786 +I10 +sS'./pypy-c-35183_pystone' +p787 +I10 +sS'./pypy-c-39348-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p788 +I7 +sS'./pypy-c-34927-gc=framework--objspace-std-withstrdict--prof_pystone' +p789 +I10 +sS'./pypy-cli-35867_pystone' +p790 +I10 +sS'./pypy-cli-39218_richards' +p791 +I10 +sS'./pypy-llvm-35867-objspace-std-withstrdict-x86_richards' +p792 +I10 +sS'./pypy-c-36539_pystone' +p793 +I10 +sS'./pypy-llvm-35944-faassen-x86_pystone' +p794 +I10 +sS'./pypy-llvm-36052-faassen-x86_pystone' +p795 +I10 +sS'./pypy-c-39324-objspace-std-withmultidict--prof_pystone' +p796 +I8 +sS'./pypy-c-38529_richards' +p797 +I3 +sS'./pypy-c-38334_pystone' +p798 +I10 +sS'./pypy-c-36893_pystone' +p799 +I10 +sS'./pypy-llvm-35095-objspace-std-withstrdict-c_richards' +p800 +I10 +sS'./pypy-c-36790-gc=framework--objspace-std-withstrdict--prof_pystone' +p801 +I10 +sS'./pypy-c-36344-gc=framework--objspace-std-withstrdict--prof_pystone' +p802 +I10 +sS'./pypy-c-38870-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p803 +I10 +sS'./pypy-llvm-39218-faassen-c_pystone' +p804 +I10 +sS'./pypy-c-35979-stackless--objspace-std-withstrdict--prof_pystone' +p805 +I10 +sS'./pypy-llvm-34948-objspace-std-withstrdict-c-prof_richards' +p806 +I10 +sS'./pypy-c-39547-objspace-std-withmultidict--prof_richards' +p807 +I3 +sS'./pypy-c-36052-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p808 +I10 +sS'./pypy-c-35906-stackless--objspace-std-withstrdict--prof_richards' +p809 +I10 +sS'./pypy-c-38222-objspace-std-withfastslice_richards' +p810 +I10 +sS'./pypy-c-39348-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p811 +I7 +sS'./pypy-llvm-35968-faassen-c-prof_richards' +p812 +I10 +sS'./pypy-c-39147-objspace-std-withfastslice_pystone' +p813 +I10 +sS'./pypy-c-39218-objspace-std-withmultidict--prof_richards' +p814 +I10 +sS'./pypy-c-39617-faassen_pystone' +p815 +I2 +sS'./pypy-c-39188-objspace-std-withmultidict--prof_pystone' +p816 +I10 +sS'./pypy-cli-38769_pystone' +p817 +I10 +sS'./pypy-c-37454-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p818 +I10 +sS'./pypy-llvm-36175-faassen-c-prof_richards' +p819 +I10 +sS'./pypy-llvm-39474-faassen-c_pystone' +p820 +I4 +sS'./pypy-c-37111-gc=framework--objspace-std-withstrdict--prof_richards' +p821 +I10 +sS'./pypy-c-38651-gc=framework--objspace-std-withstrdict--prof_richards' +p822 +I10 +sS'./pypy-c-36220-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p823 +I10 +sS'./pypy-cli-36628_pystone' +p824 +I10 +sS'./pypy-llvm-38870-faassen-c_richards' +p825 +I10 +sS'./pypy-c-35867_richards' +p826 +I10 +sS'./pypy-c-37084-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p827 +I10 +sS'./pypy-cli-35837_pystone' +p828 +I10 +sS'./pypy-c-39374-objspace-std-withfastslice_pystone' +p829 +I6 +sS'2.4.4_pystone' +p830 +I10 +sS'./pypy-c-37243-faassen_richards' +p831 +I10 +sS'./pypy-llvm-36182-faassen-x86_pystone' +p832 +I10 +sS'./pypy-c-34927-stackless--objspace-std-withstrdict--prof_pystone' +p833 +I10 +sS'./pypy-c-36859-gc=framework--objspace-std-withstrdict--prof_pystone' +p834 +I10 +sS'./pypy-c-37707_pystone' +p835 +I10 +sS'./pypy-llvm-35968-faassen-x86_richards' +p836 +I10 +sS'./pypy-llvm-36446-faassen-c-prof_richards' +p837 +I10 +sS'./pypy-llvm-35906-objspace-std-withstrdict-x86_richards' +p838 +I10 +sS'./pypy-c-39218-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p839 +I10 +sS'./pypy-llvm-38994-faassen-c-prof_pystone' +p840 +I10 +sS'./pypy-c-35944-gc=framework--objspace-std-withstrdict--prof_richards' +p841 +I10 +sS'./pypy-cli-38994_pystone' +p842 +I10 +sS'./pypy-c-34593-gc=framework--objspace-std-withstrdict--prof_pystone' +p843 +I10 +sS'./pypy-c-36446-stackless--objspace-std-withstrdict--prof_richards' +p844 +I10 +sS'./pypy-llvm-39617-faassen-x86_richards' +p845 +I2 +sS'./pypy-c-35867-gc=framework--objspace-std-withstrdict--prof_pystone' +p846 +I10 +sS'./pypy-llvm-36136-faassen-c-prof_pystone' +p847 +I10 +sS'./pypy-c-38140-stackless--objspace-std-withstrdict--prof_richards' +p848 +I10 +sS'./pypy-llvm-39474-faassen-x86_richards' +p849 +I4 +sS'./pypy-cli-36009_pystone' +p850 +I3 +sS'./pypy-llvm-39617-faassen-x86_pystone' +p851 +I2 +sS'./pypy-c-35095-stackless--objspace-std-withstrdict--prof_pystone' +p852 +I10 +sS'./pypy-llvm-36220-faassen-c_richards' +p853 +I10 +sS'./pypy-c-37367-stackless--objspace-std-withstrdict--prof_richards' +p854 +I10 +sS'./pypy-c-34927-objspace-std-withstrdict--prof_pystone' +p855 +I10 +sS'./pypy-c-38140-gc=framework--objspace-std-withstrdict--prof_richards' +p856 +I10 +sS'./pypy-c-36182_richards' +p857 +I10 +sS'./pypy-llvm-36175-faassen-c_richards' +p858 +I10 +sS'./pypy-c-35095_pystone' +p859 +I10 +sS'./pypy-c-36446-objspace-std-withstrdict--prof_pystone' +p860 +I10 +sS'./pypy-c-35923_pystone' +p861 +I10 +sS'./pypy-c-38994-objspace-std-withfastslice_richards' +p862 +I10 +sS'./pypy-c-37503_richards' +p863 +I10 +sS'./pypy-c-37310-gc=framework--objspace-std-withstrdict--prof_pystone' +p864 +I10 +sS'./pypy-c-39218-stackless--objspace-std-withmultidict--prof_pystone' +p865 +I10 +sS'./pypy-c-34593-objspace-std-withstrdict--prof_pystone' +p866 +I10 +sS'./pypy-c-35212_richards' +p867 +I10 +sS'./pypy-c-35658_pystone' +p868 +I10 +sS'./pypy-c-36113-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p869 +I10 +sS'./pypy-c-34948-objspace-std-withstrdict--prof_richards' +p870 +I10 +sS'./pypy-c-37782-stackless--objspace-std-withstrdict--prof_pystone' +p871 +I10 +sS'./pypy-cli-36066_pystone' +p872 +I10 +sS'./pypy-c-35824-stackless--objspace-std-withstrdict--prof_pystone' +p873 +I10 +sS'./pypy-llvm-34632-objspace-std-withstrdict-c_richards' +p874 +I10 +sS'./pypy-c-35010-gc=framework--objspace-std-withstrdict--prof_richards' +p875 +I10 +sS'./pypy-cli-38435_richards' +p876 +I10 +sS'./pypy-cli-39188_pystone' +p877 +I10 +sS'./pypy-cli-36446_pystone' +p878 +I10 +sS'./pypy-c-36136_richards' +p879 +I10 +sS'./pypy-c-39374-faassen_pystone' +p880 +I6 +sS'2.3.5_richards' +p881 +I10 +sS'./pypy-cli-36136_richards' +p882 +I10 +sS'./pypy-c-36628-gc=framework--objspace-std-withstrdict--prof_pystone' +p883 +I10 +sS'./pypy-c-35963-gc=framework--objspace-std-withstrdict--prof_richards' +p884 +I10 +sS'./pypy-c-39072-objspace-std-withmultidict--prof_richards' +p885 +I10 +sS'./pypy-c-36220-objspace-std-withstrdict--prof_pystone' +p886 +I10 +sS'./pypy-cli-37310_richards' +p887 +I10 +sS'./pypy-cli-37415_richards' +p888 +I10 +sS'./pypy-c-36136-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p889 +I10 +sS'./pypy-c-36790-objspace-std-withstrdict--prof_pystone' +p890 +I10 +sS'./pypy-cli-35775_pystone' +p891 +I10 +sS'./pypy-c-39617-gc=framework--objspace-std-withmultidict--prof_richards' +p892 +I2 +sS'./pypy-c-35837-gc=framework--objspace-std-withstrdict--prof_pystone' +p893 +I10 +sS'./pypy-cli-36158_pystone' +p894 +I10 +sS'./pypy-c-unknown-stackless--objspace-std-withstrdict--prof_richards' +p895 +I2 +sS'./pypy-llvm-35095-objspace-std-withstrdict-c-prof_richards' +p896 +I10 +sS'./pypy-cli-38994_richards' +p897 +I10 +sS'./pypy-cli-35963_pystone' +p898 +I8 +sS'./pypy-cli-36539_pystone' +p899 +I10 +sS'./pypy-c-37454-gc=framework--objspace-std-withstrdict--prof_richards' +p900 +I10 +sS'./pypy-c-38769-gc=framework--objspace-std-withstrdict--prof_richards' +p901 +I10 +sS'./pypy-c-35968-gc=framework--objspace-std-withstrdict--prof_pystone' +p902 +I10 +sS'./pypy-c-36182-gc=framework--objspace-std-withstrdict--prof_pystone' +p903 +I10 +sS'./pypy-c-37310_richards' +p904 +I10 +sS'./pypy-c-39147-stackless--objspace-std-withmultidict--prof_pystone' +p905 +I10 +sS'./pypy-c-38334-objspace-std-withfastslice_richards' +p906 +I10 +sS'./pypy-c-38870-faassen_pystone' +p907 +I10 +sS'./pypy-c-39348-stackless--objspace-std-withmultidict--prof_richards' +p908 +I7 +sS'./pypy-llvm-35824-objspace-std-withstrdict-x86_pystone' +p909 +I10 +sS'./pypy-c-38651-objspace-std-withstrdict--prof_pystone' +p910 +I10 +sS'./pypy-c-34882_pystone' +p911 +I10 +sS'./pypy-c-38994_pystone' +p912 +I10 +sS'./pypy-c-36009_pystone' +p913 +I10 +sS'./pypy-c-36893-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p914 +I10 +sS'./pypy-llvm-36182-faassen-c-prof_richards' +p915 +I10 +sS'./pypy-c-38529-objspace-std-withfastslice_richards' +p916 +I10 +sS'./pypy-c-39374-objspace-std-withmultidict--prof_pystone' +p917 +I6 +sS'./pypy-cli-36182_richards' +p918 +I10 +sS'./pypy-c-36859-objspace-std-withstrdict--prof_richards' +p919 +I10 +sS'./pypy-c-36136-objspace-std-withstrdict--prof_richards' +p920 +I10 +sS'./pypy-c-39547-gc=framework--objspace-std-withmultidict--prof_richards' +p921 +I3 +sS'./pypy-llvm-36158-faassen-c_richards' +p922 +I10 +sS'./pypy-c-35212-gc=framework--objspace-std-withstrdict--prof_pystone' +p923 +I10 +sS'./pypy-c-37415_richards' +p924 +I10 +sS'./pypy-cli-38222_richards' +p925 +I10 +sS'./pypy-c-36082-gc=framework--objspace-std-withstrdict--prof_richards' +p926 +I10 +sS'./pypy-c-unknown-objspace-std-withstrdict--prof_pystone' +p927 +I2 +sS'./pypy-c-34593-gc=framework_pystone' +p928 +I10 +sS'./pypy-llvm-35963-faassen-x86_richards' +p929 +I10 +sS'./pypy-cli-36052_pystone' +p930 +I10 +sS'./pypy-c-35463_richards' +p931 +I10 +sS'./pypy-c-39617-objspace-std-withmultidict--prof_pystone' +p932 +I2 +sS'./pypy-c-35237-objspace-std-withstrdict--prof_pystone' +p933 +I10 +sS'./pypy-c-39348-faassen_richards' +p934 +I7 +sS'./pypy-c-37044-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p935 +I10 +sS'./pypy-c-38994-gc=framework--objspace-std-withmultidict--prof_richards' +p936 +I10 +sS'./pypy-llvm-35988-faassen-c-prof_richards' +p937 +I10 +sS'./pypy-c-36175-gc=framework--objspace-std-withstrdict--prof_richards' +p938 +I10 +sS'./pypy-llvm-36158-faassen-x86_richards' +p939 +I10 +sS'./pypy-c-36859-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p940 +I10 +sS'./pypy-c-37163-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p941 +I10 +sS'./pypy-c-36009-objspace-std-withstrdict--prof_pystone' +p942 +I10 +sS'./pypy-llvm-36446-faassen-x86_richards' +p943 +I10 +sS'./pypy-c-39474-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p944 +I4 +sS'./pypy-llvm-36100-faassen-c_pystone' +p945 +I10 +sS'./pypy-c-35277_pystone' +p946 +I10 +sS'./pypy-c-37044_pystone' +p947 +I10 +sS'./pypy-cli-38222_pystone' +p948 +I10 +sS'./pypy-llvm-36136-faassen-x86_pystone' +p949 +I10 +sS'./pypy-llvm-34976-objspace-std-withstrdict-c-prof_richards' +p950 +I10 +sS'./pypy-c-35095_richards' +p951 +I10 +sS'./pypy-cli-39547_pystone' +p952 +I3 +sS'./pypy-c-36539_richards' +p953 +I10 +sS'./pypy-llvm-35906-objspace-std-withstrdict-x86_pystone' +p954 +I10 +sS'./pypy-c-38994-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p955 +I10 +sS'./pypy-c-35095-stackless--objspace-std-withstrdict--prof_richards' +p956 +I10 +sS'./pypy-c-35010-objspace-std-withstrdict--prof_pystone' +p957 +I10 +sS'./pypy-c-39547_pystone' +p958 +I3 +sS'./pypy-llvm-36100-faassen-c-prof_richards' +p959 +I10 +sS'./pypy-c-36344-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p960 +I10 +sS'./pypy-c-35968-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p961 +I10 +sS'./pypy-cli-35944_pystone' +p962 +I9 +sS'./pypy-llvm-35923-objspace-std-withstrdict-x86_pystone' +p963 +I10 +sS'./pypy-c-37084-objspace-std-withstrdict--prof_pystone' +p964 +I10 +sS'./pypy-c-35411-stackless--objspace-std-withstrdict--prof_richards' +p965 +I10 +sS'./pypy-llvm-39072-faassen-x86_pystone' +p966 +I10 +sS'./pypy-c-36052-objspace-std-withstrdict--prof_pystone' +p967 +I10 +sS'./pypy-llvm-39646-faassen-c-prof_richards' +p968 +I1 +sS'./pypy-c-38994_richards' +p969 +I10 +sS'./pypy-c-35237-objspace-std-withstrdict--prof_richards' +p970 +I10 +sS'./pypy-llvm-38870-faassen-x86_pystone' +p971 +I10 +sS'./pypy-llvm-35923-objspace-std-withstrdict-c_richards' +p972 +I10 +sS'./pypy-c-39247-gc=framework--objspace-std-withmultidict--prof_richards' +p973 +I10 +sS'./pypy-c-35609_richards' +p974 +I10 +sS'./pypy-c-34976-gc=framework--objspace-std-withstrdict--prof_pystone' +p975 +I10 +sS'./pypy-c-35968-objspace-std-withstrdict--prof_richards' +p976 +I10 +sS'./pypy-c-39547-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p977 +I3 +sS'./pypy-c-36136-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p978 +I10 +sS'./pypy-c-37503-faassen_pystone' +p979 +I10 +sS'./pypy-c-35944_richards' +p980 +I10 +sS'./pypy-c-39147_pystone' +p981 +I10 +sS'./pypy-c-36066_richards' +p982 +I10 +sS'./pypy-c-39617-stackless--objspace-std-withmultidict--prof_pystone' +p983 +I2 +sS'./pypy-c-36113-objspace-std-withstrdict--prof_richards' +p984 +I10 +sS'./pypy-llvm-39547-faassen-x86_pystone' +p985 +I3 +sS'./pypy-c-35988_pystone' +p986 +I10 +sS'./pypy-c-39247_pystone' +p987 +I10 +sS'./pypy-c-38769-objspace-std-withfastslice_richards' +p988 +I10 +sS'./pypy-c-37310-objspace-std-withstrdict--prof_richards' +p989 +I10 +sS'./pypy-c-35183-objspace-std-withstrdict--prof_richards' +p990 +I10 +sS'./pypy-c-35837-objspace-std-withstrdict--prof_richards' +p991 +I10 +sS'./pypy-c-37243-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p992 +I10 +sS'./pypy-llvm-35771-objspace-std-withstrdict-c_pystone' +p993 +I10 +sS'./pypy-cli-37647_richards' +p994 +I10 +sS'./pypy-c-35982-gc=framework--objspace-std-withstrdict--prof_pystone' +p995 +I10 +sS'./pypy-c-35713-stackless--objspace-std-withstrdict--prof_pystone' +p996 +I10 +sS'./pypy-c-34948_richards' +p997 +I10 +sS'./pypy-cli-39348_richards' +p998 +I7 +sS'./pypy-cli-35557_pystone' +p999 +I4 +sS'./pypy-c-38769-stackless--objspace-std-withstrdict--prof_pystone' +p1000 +I10 +sS'./pypy-c-35065-objspace-std-withstrdict--prof_pystone' +p1001 +I10 +sS'./pypy-c-34948-stackless--objspace-std-withstrdict--prof_pystone' +p1002 +I10 +sS'./pypy-c-38222-objspace-std-withfastslice_pystone' +p1003 +I10 +sS'./pypy-c-37111-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p1004 +I10 +sS'./pypy-c-35923-gc=framework--objspace-std-withstrdict--prof_richards' +p1005 +I10 +sS'./pypy-cli-37310_pystone' +p1006 +I10 +sS'./pypy-c-35658-gc=framework--objspace-std-withstrdict--prof_richards' +p1007 +I10 +sS'./pypy-c-39474-objspace-std-withmultidict--prof_richards' +p1008 +I4 +sS'./pypy-c-39302-objspace-std-withfastslice_pystone' +p1009 +I9 +sS'./pypy-c-39247-stackless--objspace-std-withmultidict--prof_pystone' +p1010 +I10 +sS'./pypy-llvm-39374-faassen-x86_richards' +p1011 +I6 +sS'./pypy-llvm-35963-faassen-c_pystone' +p1012 +I10 +sS'./pypy-c-37454_richards' +p1013 +I10 +sS'./pypy-llvm-35906-objspace-opcodes-CALL_LIKELY_BUILTIN-x86_pystone' +p1014 +I10 +sS'./pypy-llvm-39617-faassen-c_pystone' +p1015 +I2 +sS'./pypy-cli-39147_pystone' +p1016 +I10 +sS'./pypy-llvm-38994-faassen-x86_richards' +p1017 +I10 +sS'./pypy-c-35906_richards' +p1018 +I10 +sS'./pypy-llvm-36175-faassen-x86_pystone' +p1019 +I10 +sS'./pypy-llvm-36539-faassen-x86_richards' +p1020 +I10 +sS'./pypy-c-37503-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p1021 +I10 +sS'./pypy-c-37111-gc=framework--objspace-std-withstrdict--prof_pystone' +p1022 +I10 +sS'./pypy-llvm-35183-objspace-std-withstrdict-c-prof_pystone' +p1023 +I10 +sS'./pypy-cli-38435_pystone' +p1024 +I10 +sS'./pypy-c-38870-objspace-std-withfastslice_pystone' +p1025 +I10 +sS'./pypy-c-35988-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p1026 +I10 +sS'./pypy-c-35658-stackless--objspace-std-withstrdict--prof_richards' +p1027 +I10 +sS'./pypy-c-35512-objspace-std-withstrdict--prof_pystone' +p1028 +I10 +sS'./pypy-c-39247-objspace-std-withfastslice_richards' +p1029 +I10 +sS'./pypy-c-37415-gc=framework--objspace-std-withstrdict--prof_pystone' +p1030 +I10 +sS'./pypy-c-39474-gc=framework--objspace-std-withmultidict--prof_pystone' +p1031 +I4 +sS'./pypy-llvm-39188-faassen-x86_pystone' +p1032 +I10 +sS'./pypy-c-35944-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p1033 +I10 +sS'./pypy-llvm-36220-faassen-c-prof_pystone' +p1034 +I10 +sS'./pypy-c-35923-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p1035 +I10 +sS'./pypy-c-37111-objspace-std-withstrdict--prof_pystone' +p1036 +I10 +sS'./pypy-c-35212-gc=framework--objspace-std-withstrdict--prof_richards' +p1037 +I10 +sS'./pypy-c-39302-objspace-std-withfastslice_richards' +p1038 +I9 +sS'./pypy-llvm-35010-objspace-std-withstrdict-c_pystone' +p1039 +I10 +sS'./pypy-c-39646-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p1040 +I1 +sS'./pypy-llvm-36082-faassen-c_richards' +p1041 +I10 +sS'./pypy-c-36977-stackless--objspace-std-withstrdict--prof_pystone' +p1042 +I10 +sS'./pypy-c-35512-objspace-std-withstrdict--prof_richards' +p1043 +I10 +sS'./pypy-llvm-35867-objspace-std-withstrdict-c_richards' +p1044 +I10 +sS'./pypy-cli-36446_richards' +p1045 +I10 +sS'./pypy-c-35557_richards' +p1046 +I10 +sS'./pypy-c-36859-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p1047 +I10 +sS'./pypy-c-36859-gc=framework--objspace-std-withstrdict--prof_richards' +p1048 +I10 +sS'./pypy-c-35350-stackless--objspace-std-withstrdict--prof_pystone' +p1049 +I10 +sS'./pypy-c-35143_richards' +p1050 +I10 +sS'./pypy-c-37163-stackless--objspace-std-withstrdict--prof_richards' +p1051 +I10 +sS'./pypy-c-37310-gc=framework--objspace-std-withstrdict--prof_richards' +p1052 +I10 +sS'./pypy-c-37503-gc=framework--objspace-std-withstrdict--prof_pystone' +p1053 +I10 +sS'./pypy-cli-39247_richards' +p1054 +I10 +sS'./pypy-c-39188-objspace-std-withmultidict--prof_richards' +p1055 +I10 +sS'./pypy-c-35963-gc=framework--objspace-std-withstrdict--prof_pystone' +p1056 +I10 +sS'./pypy-c-39302-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p1057 +I9 +sS'./pypy-cli-35463_pystone' +p1058 +I7 +sS'./pypy-llvm-39247-faassen-x86_richards' +p1059 +I10 +sS'./pypy-c-36100_richards' +p1060 +I10 +sS'./pypy-c-39302-objspace-std-withmultidict--prof_pystone' +p1061 +I9 +sS'./pypy-c-37707-objspace-std-withstrdict--prof_richards' +p1062 +I10 +sS'./pypy-c-36175-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p1063 +I10 +sS'./pypy-c-34948_pystone' +p1064 +I10 +sS'./pypy-llvm-39324-faassen-c_richards' +p1065 +I8 +sS'./pypy-cli-38651_richards' +p1066 +I10 +sS'./pypy-c-36893_richards' +p1067 +I10 +sS'./pypy-llvm-36446-faassen-c_pystone' +p1068 +I10 +sS'./pypy-cli-36175_pystone' +p1069 +I10 +sS'./pypy-c-36100-gc=framework--objspace-std-withstrdict--prof_pystone' +p1070 +I10 +sS'./pypy-c-37084-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p1071 +I10 +sS'./pypy-llvm-35982-faassen-x86_pystone' +p1072 +I10 +sS'./pypy-llvm-35183-objspace-std-withstrdict-c-prof_richards' +p1073 +I10 +sS'./pypy-c-36082-stackless--objspace-std-withstrdict--prof_pystone' +p1074 +I10 +sS'./pypy-llvm-35906-objspace-opcodes-CALL_LIKELY_BUILTIN-c_richards' +p1075 +I10 +sS'./pypy-c-38222_pystone' +p1076 +I10 +sS'./pypy-c-35143-gc=framework--objspace-std-withstrdict--prof_pystone' +p1077 +I10 +sS'./pypy-c-39247-gc=framework--objspace-std-withmultidict--prof_pystone' +p1078 +I10 +sS'./pypy-c-37454-objspace-std-withstrdict--prof_pystone' +p1079 +I10 +sS'./pypy-c-35010-gc=framework--objspace-std-withstrdict--prof_pystone' +p1080 +I10 +sS'./pypy-c-35982-objspace-std-withstrdict--prof_pystone' +p1081 +I10 +sS'./pypy-cli-38140_richards' +p1082 +I10 +sS'./pypy-c-35010-stackless--objspace-std-withstrdict--prof_pystone' +p1083 +I10 +sS'./pypy-llvm-39188-faassen-x86_richards' +p1084 +I10 +sS'./pypy-c-38651-objspace-std-withfastslice_pystone' +p1085 +I10 +sS'./pypy-c-39617-objspace-std-withfastslice_pystone' +p1086 +I2 +sS'./pypy-llvm-39324-faassen-x86_pystone' +p1087 +I8 +sS'./pypy-llvm-39147-faassen-c_richards' +p1088 +I10 +sS'./pypy-c-38529-objspace-std-withfastslice_pystone' +p1089 +I10 +sS'./pypy-c-36113-objspace-std-withstrdict--prof_pystone' +p1090 +I10 +sS'./pypy-c-35463-gc=framework--objspace-std-withstrdict--prof_richards' +p1091 +I10 +sS'./pypy-llvm-35771-objspace-std-withstrdict-c_richards' +p1092 +I10 +sS'./pypy-c-36628-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p1093 +I10 +sS'./pypy-c-36790_pystone' +p1094 +I10 +sS'./pypy-c-35277-gc=framework--objspace-std-withstrdict--prof_pystone' +p1095 +I10 +sS'./pypy-c-36009-gc=framework--objspace-std-withstrdict--prof_pystone' +p1096 +I10 +sS'./pypy-cli-35906_pystone' +p1097 +I10 +sS'./pypy-llvm-35771-objspace-std-withstrdict-x86_pystone' +p1098 +I10 +sS'./pypy-c-35658-gc=framework--objspace-std-withstrdict--prof_pystone' +p1099 +I10 +sS'./pypy-c-39348-objspace-std-withmultidict--prof_richards' +p1100 +I7 +sS'./pypy-c-36136-stackless--objspace-std-withstrdict--prof_richards' +p1101 +I10 +sS'./pypy-c-38140-objspace-std-withstrdict--prof_pystone' +p1102 +I10 +sS'./pypy-llvm-36136-faassen-c_richards' +p1103 +I10 +sS'./pypy-c-39474-gc=framework--objspace-std-withmultidict--prof_richards' +p1104 +I4 +sS'./pypy-cli-37163_richards' +p1105 +I10 +sS'./pypy-c-37454-stackless--objspace-std-withstrdict--prof_richards' +p1106 +I10 +sS'./pypy-llvm-35968-faassen-c_richards' +p1107 +I10 +sS'./pypy-c-35609_pystone' +p1108 +I10 +sS'./pypy-llvm-36136-faassen-c-prof_richards' +p1109 +I10 +sS'./pypy-c-34593-gc=framework_richards' +p1110 +I10 +sS'./pypy-llvm-39646-faassen-x86_pystone' +p1111 +I1 +sS'./pypy-cli-38769_richards' +p1112 +I10 +sS'./pypy-c-39218-objspace-std-withmultidict--prof_pystone' +p1113 +I10 +sS'./pypy-c-35988-objspace-std-withstrdict--prof_pystone' +p1114 +I10 +sS'./pypy-llvm-unknown-objspace-std-withstrdict-c_pystone' +p1115 +I7 +sS'./pypy-c-39324-stackless--objspace-std-withmultidict--prof_richards' +p1116 +I8 +sS'./pypy-c-37707-stackless--objspace-std-withstrdict--prof_richards' +p1117 +I10 +sS'./pypy-c-37163-objspace-std-withstrdict--prof_richards' +p1118 +I10 +sS'./pypy-c-39072-faassen_pystone' +p1119 +I10 +sS'./pypy-c-37707_richards' +p1120 +I10 +sS'./pypy-c-39188-faassen_richards' +p1121 +I10 +sS'./pypy-c-37647-objspace-std-withstrdict--prof_pystone' +p1122 +I10 +sS'./pypy-c-36158_pystone' +p1123 +I10 +sS'./pypy-c-38140-faassen_richards' +p1124 +I10 +sS'./pypy-llvm-39147-faassen-c_pystone' +p1125 +I10 +sS'./pypy-c-36859_richards' +p1126 +I10 +sS'./pypy-c-38994-objspace-std-withmultidict--prof_richards' +p1127 +I10 +sS'./pypy-llvm-35065-objspace-std-withstrdict-c-prof_pystone' +p1128 +I10 +sS'./pypy-c-35968-stackless--objspace-std-withstrdict--prof_pystone' +p1129 +I10 +sS'./pypy-c-unknown-gc=framework--objspace-std-withstrdict--prof_richards' +p1130 +I2 +sS'./pypy-c-35463_pystone' +p1131 +I10 +sS'./pypy-c-39218-objspace-std-withfastslice_richards' +p1132 +I10 +sS'./pypy-c-36158-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p1133 +I10 +sS'./pypy-c-38435_richards' +p1134 +I10 +sS'./pypy-cli-35512_richards' +p1135 +I6 +sS'./pypy-c-37367-faassen_richards' +p1136 +I10 +sS'./pypy-c-37243_richards' +p1137 +I10 +sS'./pypy-c-39188_pystone' +p1138 +I10 +sS'./pypy-c-37084-stackless--objspace-std-withstrdict--prof_richards' +p1139 +I10 +sS'./pypy-c-36344-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p1140 +I10 +sS'./pypy-llvm-35143-objspace-std-withstrdict-c-prof_pystone' +p1141 +I10 +sS'./pypy-c-36220_pystone' +p1142 +I10 +sS'./pypy-c-36395-stackless--objspace-std-withstrdict--prof_richards' +p1143 +I10 +sS'./pypy-c-34593-thread--objspace-std-withstrdict--prof_richards' +p1144 +I10 +sS'./pypy-llvm-36539-faassen-c-prof_pystone' +p1145 +I10 +sS'./pypy-cli-37044_pystone' +p1146 +I10 +sS'./pypy-c-35979-gc=framework--objspace-std-withstrdict--prof_pystone' +p1147 +I10 +sS'./pypy-c-39302-gc=framework--objspace-std-withmultidict--prof_pystone' +p1148 +I9 +sS'./pypy-llvm-36113-faassen-c_pystone' +p1149 +I10 +sS'./pypy-cli-37111_pystone' +p1150 +I10 +sS'./pypy-c-36030-objspace-std-withstrdict--prof_richards' +p1151 +I10 +sS'./pypy-c-35713_richards' +p1152 +I10 +sS'./pypy-c-35183-gc=framework--objspace-std-withstrdict--prof_pystone' +p1153 +I10 +sS'./pypy-c-37575-gc=framework--objspace-std-withstrdict--prof_pystone' +p1154 +I10 +sS'./pypy-llvm-35837-objspace-std-withstrdict-c_richards' +p1155 +I10 +sS'./pypy-llvm-36009-faassen-c-prof_richards' +p1156 +I10 +sS'./pypy-llvm-39617-faassen-c-prof_richards' +p1157 +I2 +sS'./pypy-c-35963-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p1158 +I10 +sS'./pypy-c-37503-objspace-std-withstrdict--prof_pystone' +p1159 +I10 +sS'2.4.4_richards' +p1160 +I10 +sS'./pypy-c-38651-objspace-std-withstrdict--prof_richards' +p1161 +I10 +sS'./pypy-llvm-34976-objspace-std-withstrdict-x86_pystone' +p1162 +I10 +sS'./pypy-llvm-36100-faassen-x86_pystone' +p1163 +I10 +sS'./pypy-c-37044-gc=framework--objspace-std-withstrdict--prof_pystone' +p1164 +I10 +sS'./pypy-llvm-39302-faassen-c_pystone' +p1165 +I9 +sS'./pypy-llvm-35771-objspace-std-withstrdict-c-prof_pystone' +p1166 +I10 +sS'./pypy-c-36009-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p1167 +I10 +sS'./pypy-llvm-36158-faassen-x86_pystone' +p1168 +I10 +sS'./pypy-c-35963-stackless--objspace-std-withstrdict--prof_richards' +p1169 +I10 +sS'./pypy-c-37782-gc=framework--objspace-std-withstrdict--prof_richards' +p1170 +I10 +sS'./pypy-c-37647-faassen_pystone' +p1171 +I10 +sS'./pypy-c-35713-gc=framework--objspace-std-withstrdict--prof_pystone' +p1172 +I10 +sS'./pypy-c-36136-gc=framework--objspace-std-withstrdict--prof_richards' +p1173 +I10 +sS'./pypy-c-39617-objspace-std-withfastslice_richards' +p1174 +I2 +sS'./pypy-c-39646-gc=framework--objspace-std-withmultidict--prof_richards' +p1175 +I1 +sS'./pypy-c-36082_richards' +p1176 +I10 +sS'./pypy-c-37243-gc=framework--objspace-std-withstrdict--prof_richards' +p1177 +I10 +sS'./pypy-c-39324_pystone' +p1178 +I8 +sS'./pypy-c-35906-objspace-std-withstrdict--prof_richards' +p1179 +I10 +sS'./pypy-llvm-38870-faassen-c-prof_pystone' +p1180 +I10 +sS'./pypy-c-36539-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p1181 +I10 +sS'./pypy-c-36100-objspace-std-withstrdict--prof_richards' +p1182 +I10 +sS'./pypy-c-35837-objspace-std-withstrdict--prof_pystone' +p1183 +I10 +sS'./pypy-c-39302-gc=framework--objspace-std-withmultidict--prof_richards' +p1184 +I9 +sS'./pypy-llvm-36066-faassen-c_richards' +p1185 +I10 +sS'./pypy-llvm-39547-faassen-c_richards' +p1186 +I3 +sS'./pypy-llvm-35906-objspace-std-withstrdict-c_pystone' +p1187 +I10 +sS'./pypy-llvm-39348-faassen-x86_pystone' +p1188 +I7 +sS'./pypy-c-35963-objspace-std-withstrdict--prof_pystone' +p1189 +I10 +sS'./pypy-c-unknown-gc=framework--objspace-std-withstrdict--prof_pystone' +p1190 +I2 +sS'./pypy-c-36052_pystone' +p1191 +I10 +sS'./pypy-c-39302-stackless--objspace-std-withmultidict--prof_pystone' +p1192 +I9 +sS'./pypy-llvm-38769-faassen-c-prof_richards' +p1193 +I10 +sS'./pypy-cli-38870_richards' +p1194 +I10 +sS'./pypy-llvm-35837-objspace-std-withstrdict-c-prof_richards' +p1195 +I10 +sS'./pypy-llvm-36344-faassen-c-prof_richards' +p1196 +I10 +sS'./pypy-llvm-36030-faassen-c_pystone' +p1197 +I10 +sS'./pypy-c-37647_richards' +p1198 +I10 +sS'./pypy-cli-36220_richards' +p1199 +I10 +sS'./pypy-c-37044-stackless--objspace-std-withstrdict--prof_richards' +p1200 +I10 +sS'./pypy-c-38994-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p1201 +I10 +sS'./pypy-llvm-39324-faassen-c-prof_pystone' +p1202 +I8 +sS'./pypy-c-36066-gc=framework--objspace-std-withstrdict--prof_pystone' +p1203 +I10 +sS'./pypy-c-36446-gc=framework--objspace-std-withstrdict--prof_pystone' +p1204 +I10 +sS'./pypy-c-37243-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p1205 +I10 +sS'./pypy-c-35923-stackless--objspace-std-withstrdict--prof_richards' +p1206 +I10 +sS'./pypy-c-36052-gc=framework--objspace-std-withstrdict--prof_pystone' +p1207 +I10 +sS'./pypy-c-39474-faassen_richards' +p1208 +I4 +sS'./pypy-llvm-36052-faassen-x86_richards' +p1209 +I10 +sS'./pypy-c-38435-objspace-std-withfastslice_richards' +p1210 +I10 +sS'./pypy-c-37415-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p1211 +I10 +sS'./pypy-llvm-35979-faassen-x86_richards' +p1212 +I10 +sS'./pypy-llvm-36175-faassen-c_pystone' +p1213 +I10 +sS'./pypy-c-36446-gc=framework--objspace-std-withstrdict--prof_richards' +p1214 +I10 +sS'./pypy-llvm-35010-objspace-std-withstrdict-c-prof_pystone' +p1215 +I10 +sS'./pypy-c-35771-stackless--objspace-std-withstrdict--prof_richards' +p1216 +I10 +sS'./pypy-c-36009-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p1217 +I10 +sS'./pypy-c-39374_pystone' +p1218 +I6 +sS'./pypy-llvm-35923-objspace-std-withstrdict-c_pystone' +p1219 +I10 +sS'./pypy-c-35212-objspace-std-withstrdict--prof_richards' +p1220 +I10 +sS'./pypy-c-36539-objspace-std-withstrdict--prof_pystone' +p1221 +I10 +sS'./pypy-c-36395-objspace-std-withstrdict--prof_pystone' +p1222 +I10 +sS'./pypy-llvm-39188-faassen-c-prof_pystone' +p1223 +I10 +sS'./pypy-c-37044-stackless--objspace-std-withstrdict--prof_pystone' +p1224 +I10 +sS'./pypy-c-38651-stackless--objspace-std-withstrdict--prof_pystone' +p1225 +I10 +sS'./pypy-c-35212-stackless--objspace-std-withstrdict--prof_richards' +p1226 +I10 +sS'./pypy-llvm-36009-faassen-x86_richards' +p1227 +I10 +sS'./pypy-llvm-35923-objspace-opcodes-CALL_LIKELY_BUILTIN-c_pystone' +p1228 +I10 +sS'./pypy-llvm-35837-objspace-std-withstrdict-c_pystone' +p1229 +I10 +sS'./pypy-llvm-36182-faassen-c_richards' +p1230 +I10 +sS'./pypy-c-36052-objspace-std-withstrdict--prof_richards' +p1231 +I10 +sS'./pypy-c-38870_richards' +p1232 +I10 +sS'./pypy-c-35010-stackless--objspace-std-withstrdict--prof_richards' +p1233 +I10 +sS'./pypy-c-36790_richards' +p1234 +I10 +sS'./pypy-cli-37782_richards' +p1235 +I10 +sS'./pypy-c-35968_pystone' +p1236 +I10 +sS'./pypy-llvm-36182-faassen-c-prof_pystone' +p1237 +I10 +sS'./pypy-c-35463-objspace-std-withstrdict--prof_pystone' +p1238 +I10 +sS'./pypy-cli-37243_richards' +p1239 +I10 +sS'./pypy-c-35237-gc=framework--objspace-std-withstrdict--prof_pystone' +p1240 +I10 +sS'./pypy-llvm-36182-faassen-x86_richards' +p1241 +I10 +sS'./pypy-llvm-35982-faassen-c-prof_pystone' +p1242 +I10 +sS'./pypy-c-34882-gc=framework--objspace-std-withstrdict--prof_richards' +p1243 +I10 +sS'./pypy-c-37367-objspace-std-withstrdict--prof_richards' +p1244 +I10 +sS'./pypy-c-unknown-stackless--objspace-std-withstrdict--prof_pystone' +p1245 +I2 +sS'./pypy-llvm-36158-faassen-c-prof_pystone' +p1246 +I10 +sS'./pypy-c-37367-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p1247 +I10 +sS'./pypy-c-39646-stackless--objspace-std-withmultidict--prof_richards' +p1248 +I1 +sS'./pypy-cli-36977_richards' +p1249 +I10 +sS'./pypy-c-39324-stackless--objspace-std-withmultidict--prof_pystone' +p1250 +I8 +sS'./pypy-c-37647-faassen_richards' +p1251 +I10 +sS'./pypy-c-36136-stackless--objspace-std-withstrdict--prof_pystone' +p1252 +I10 +sS'./pypy-c-35963_richards' +p1253 +I10 +sS'./pypy-llvm-35979-faassen-x86_pystone' +p1254 +I10 +sS'./pypy-c-37707-stackless--objspace-std-withstrdict--prof_pystone' +p1255 +I10 +sS'./pypy-c-38435-objspace-std-withfastslice_pystone' +p1256 +I10 +sS'./pypy-c-38870-faassen_richards' +p1257 +I10 +sS'./pypy-c-35512-gc=framework--objspace-std-withstrdict--prof_richards' +p1258 +I10 +sS'./pypy-c-36344-objspace-std-withstrdict--prof_richards' +p1259 +I10 +sS'./pypy-c-36395_richards' +p1260 +I10 +sS'./pypy-cli-36030_richards' +p1261 +I2 +sS'./pypy-llvm-36539-faassen-c_richards' +p1262 +I10 +sS'./pypy-c-35212-stackless--objspace-std-withstrdict--prof_pystone' +p1263 +I10 +sS'./pypy-c-36220-objspace-std-withstrdict--prof_richards' +p1264 +I10 +sS'./pypy-c-38140-gc=framework--objspace-std-withstrdict--prof_pystone' +p1265 +I10 +sS'./pypy-cli-35544~_pystone' +p1266 +I1 +sS'./pypy-c-35217-objspace-std-withstrdict--prof_pystone' +p1267 +I10 +sS'./pypy-c-37084_richards' +p1268 +I10 +sS'./pypy-c-37707-gc=framework--objspace-std-withstrdict--prof_richards' +p1269 +I10 +sS'./pypy-llvm-39474-faassen-c_richards' +p1270 +I4 +sS'./pypy-c-35217-stackless--objspace-std-withstrdict--prof_richards' +p1271 +I10 +sS'./pypy-c-37084-gc=framework--objspace-std-withstrdict--prof_richards' +p1272 +I10 +sS'./pypy-c-34927_pystone' +p1273 +I10 +sS'./pypy-c-39474-stackless--objspace-std-withmultidict--prof_richards' +p1274 +I4 +sS'./pypy-c-35979-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p1275 +I10 +sS'./pypy-c-39617-stackless--objspace-std-withmultidict--prof_richards' +p1276 +I2 +sS'./pypy-c-35988-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p1277 +I10 +sS'./pypy-c-35512-gc=framework--objspace-std-withstrdict--prof_pystone' +p1278 +I10 +sS'./pypy-llvm-35979-faassen-c-prof_pystone' +p1279 +I10 +sS'./pypy-llvm-36052-faassen-c_richards' +p1280 +I10 +sS'./pypy-c-37575_richards' +p1281 +I10 +sS'./pypy-c-38769-stackless--objspace-std-withstrdict--prof_richards' +p1282 +I10 +sS'./pypy-c-39474-objspace-std-withmultidict--prof_pystone' +p1283 +I4 +sS'./pypy-c-unknown_pystone' +p1284 +I7 +sS'./pypy-llvm-35065-objspace-std-withstrdict-x86_richards' +p1285 +I10 +sS'./pypy-cli-38334_pystone' +p1286 +I10 +sS'./pypy-cli-38140_pystone' +p1287 +I10 +sS'./pypy-llvm-36136-faassen-x86_richards' +p1288 +I10 +sS'./pypy-c-36977-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p1289 +I10 +sS'./pypy-c-35923-stackless--prof_pystone' +p1290 +I10 +sS'./pypy-cli-35557_richards' +p1291 +I4 +sS'./pypy-llvm-36009-faassen-c_pystone' +p1292 +I10 +sS'./pypy-c-36136-objspace-std-withstrdict--prof_pystone' +p1293 +I10 +sS'./pypy-llvm-35095-objspace-std-withstrdict-c-prof_pystone' +p1294 +I10 +sS'./pypy-llvm-34632-objspace-std-withstrdict-c-prof_pystone' +p1295 +I10 +sS'./pypy-c-39302-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p1296 +I9 +sS'./pypy-llvm-39646-faassen-x86_richards' +p1297 +I1 +sS'./pypy-cli-39547_richards' +p1298 +I3 +sS'./pypy-cli-36628_richards' +p1299 +I10 +sS'./pypy-cli-36052_richards' +p1300 +I10 +sS'./pypy-c-36539-gc=framework--objspace-std-withstrdict--prof_pystone' +p1301 +I10 +sS'./pypy-cli-36220_pystone' +p1302 +I10 +sS'./pypy-c-39302-faassen_pystone' +p1303 +I9 +sS'./pypy-llvm-35065-objspace-std-withstrdict-c-prof_richards' +p1304 +I10 +sS'./pypy-c-38769-gc=framework--objspace-std-withstrdict--prof_pystone' +p1305 +I10 +sS'./pypy-c-38769-faassen_pystone' +p1306 +I10 +sS'./pypy-c-36539-stackless--objspace-std-withstrdict--prof_richards' +p1307 +I10 +sS'./pypy-c-35906-stackless--objspace-std-withstrdict--prof_pystone' +p1308 +I10 +sS'./pypy-c-38870-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p1309 +I10 +sS'./pypy-c-37647-objspace-std-withstrdict--prof_richards' +p1310 +I10 +sS'./pypy-c-37415-objspace-std-withstrdict--prof_richards' +p1311 +I10 +sS'./pypy-c-38769-objspace-std-withfastslice_pystone' +p1312 +I10 +sS'./pypy-llvm-38994-faassen-c_richards' +p1313 +I10 +sS'./pypy-llvm-35010-objspace-std-withstrdict-c-prof_richards' +p1314 +I10 +sS'./pypy-c-39474-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p1315 +I4 +sS'./pypy-c-39072-gc=framework--objspace-std-withmultidict--prof_pystone' +p1316 +I10 +sS'./pypy-c-38140_pystone' +p1317 +I10 +sS'./pypy-c-35183_richards' +p1318 +I10 +sS'./pypy-llvm-39072-faassen-c-prof_pystone' +p1319 +I10 +sS'./pypy-c-37503-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p1320 +I10 +sS'./pypy-c-37243-faassen_pystone' +p1321 +I10 +sS'./pypy-c-34927_richards' +p1322 +I10 +sS'./pypy-c-37163_richards' +p1323 +I10 +sS'./pypy-c-35988-stackless--objspace-std-withstrdict--prof_richards' +p1324 +I10 +sS'./pypy-c-37575-stackless--objspace-std-withstrdict--prof_richards' +p1325 +I10 +sS'./pypy-llvm-36446-faassen-c-prof_pystone' +p1326 +I10 +sS'./pypy-cli-36082_pystone' +p1327 +I10 +sS'./pypy-llvm-36052-faassen-c_pystone' +p1328 +I10 +sS'./pypy-cli-35837_richards' +p1329 +I10 +sS'./pypy-c-39646_richards' +p1330 +I1 +sS'./pypy-llvm-35065-objspace-std-withstrdict-x86_pystone' +p1331 +I10 +sS'./pypy-c-37084_pystone' +p1332 +I10 +sS'./pypy-c-34976_pystone' +p1333 +I10 +sS'./pypy-c-37415-faassen_pystone' +p1334 +I10 +sS'./pypy-c-35217-stackless--objspace-std-withstrdict--prof_pystone' +p1335 +I10 +sS'./pypy-c-38994-objspace-std-withmultidict--prof_pystone' +p1336 +I10 +sS'./pypy-c-39348-objspace-std-withfastslice_richards' +p1337 +I7 +sS'./pypy-cli-36182_pystone' +p1338 +I10 +sS'./pypy-llvm-39302-faassen-x86_pystone' +p1339 +I9 +sS'./pypy-c-37454-faassen_pystone' +p1340 +I10 +sS'./pypy-c-35463-stackless--objspace-std-withstrdict--prof_richards' +p1341 +I10 +sS'./pypy-c-36113_pystone' +p1342 +I10 +sS'./pypy-c-37575_pystone' +p1343 +I10 +sS'./pypy-llvm-35923-objspace-opcodes-CALL_LIKELY_BUILTIN-c-prof_pystone' +p1344 +I10 +sS'./pypy-c-38870-stackless--objspace-std-withstrdict--prof_pystone' +p1345 +I10 +sS'./pypy-llvm-35963-faassen-x86_pystone' +p1346 +I10 +sS'./pypy-c-38651-faassen_richards' +p1347 +I10 +sS'./pypy-c-36220-stackless--objspace-std-withstrdict--prof_richards' +p1348 +I10 +sS'./pypy-llvm-36220-faassen-c_pystone' +p1349 +I10 +sS'./pypy-llvm-36175-faassen-x86_richards' +p1350 +I10 +sS'./pypy-c-35095-gc=framework--objspace-std-withstrdict--prof_richards' +p1351 +I10 +sS'./pypy-cli-36344_pystone' +p1352 +I10 +sS'./pypy-c-35824-stackless--objspace-std-withstrdict--prof_richards' +p1353 +I10 +sS'./pypy-c-35944-objspace-std-withstrdict--prof_richards' +p1354 +I10 +sS'./pypy-c-39324-objspace-std-withmultidict--prof_richards' +p1355 +I8 +sS'./pypy-llvm-39218-faassen-c-prof_pystone' +p1356 +I10 +sS'./pypy-c-35968-gc=framework--objspace-std-withstrdict--prof_richards' +p1357 +I10 +sS'./pypy-c-37243-stackless--objspace-std-withstrdict--prof_richards' +p1358 +I10 +sS'./pypy-cli-36893_richards' +p1359 +I10 +sS'./pypy-c-36100-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p1360 +I10 +sS'./pypy-c-38870-gc=framework--objspace-std-withstrdict--prof_pystone' +p1361 +I10 +sS'./pypy-c-39072-stackless--objspace-std-withmultidict--prof_pystone' +p1362 +I10 +sS'./pypy-llvm-35944-faassen-c_richards' +p1363 +I10 +sS'./pypy-c-39247_richards' +p1364 +I10 +sS'./pypy-c-39324-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p1365 +I8 +sS'./pypy-c-37163-gc=framework--objspace-std-withstrdict--prof_pystone' +p1366 +I10 +sS'./pypy-cli-36859_pystone' +p1367 +I10 +sS'./pypy-c-37084-stackless--objspace-std-withstrdict--prof_pystone' +p1368 +I10 +sS'./pypy-cli-36030_pystone' +p1369 +I2 +sS'./pypy-c-37163-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p1370 +I10 +sS'./pypy-c-36100-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p1371 +I10 +sS'./pypy-c-37310-stackless--objspace-std-withstrdict--prof_pystone' +p1372 +I10 +sS'./pypy-llvm-39547-faassen-x86_richards' +p1373 +I3 +sS'./pypy-c-37454-gc=framework--objspace-std-withstrdict--prof_pystone' +p1374 +I10 +sS'./pypy-c-39547-faassen_richards' +p1375 +I3 +sS'./pypy-llvm-36066-faassen-x86_pystone' +p1376 +I10 +sS'./pypy-c-36446-stackless--objspace-std-withstrdict--prof_pystone' +p1377 +I10 +sS'./pypy-c-36175-gc=framework--objspace-std-withstrdict--prof_pystone' +p1378 +I10 +sS'./pypy-c-35982-stackless--objspace-std-withstrdict--prof_pystone' +p1379 +I10 +sS'./pypy-c-38769-objspace-std-withstrdict--prof_pystone' +p1380 +I10 +sS'./pypy-cli-36893_pystone' +p1381 +I10 +sS'./pypy-c-35463-gc=framework--objspace-std-withstrdict--prof_pystone' +p1382 +I10 +sS'./pypy-c-37111-objspace-std-withstrdict--prof_richards' +p1383 +I10 +sS'./pypy-c-34882_richards' +p1384 +I10 +sS'./pypy-c-35065-gc=framework--objspace-std-withstrdict--prof_richards' +p1385 +I10 +sS'./pypy-c-37503-faassen_richards' +p1386 +I10 +sS'./pypy-c-34976-gc=framework--objspace-std-withstrdict--prof_richards' +p1387 +I10 +sS'./pypy-llvm-36066-faassen-c_pystone' +p1388 +I10 +sS'./pypy-llvm-36344-faassen-x86_richards' +p1389 +I10 +sS'./pypy-c-35982-stackless--objspace-std-withstrdict--prof_richards' +p1390 +I10 +sS'./pypy-llvm-36052-faassen-c-prof_richards' +p1391 +I10 +sS'./pypy-c-39646-objspace-std-withfastslice_pystone' +p1392 +I1 +sS'./pypy-c-35923-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p1393 +I10 +sS'./pypy-c-35143-stackless--objspace-std-withstrdict--prof_richards' +p1394 +I10 +sS'./pypy-cli-36100_richards' +p1395 +I10 +sS'./pypy-c-35988_richards' +p1396 +I10 +sS'./pypy-c-37782-objspace-std-withstrdict--prof_richards' +p1397 +I10 +sS'./pypy-c-35411-gc=framework--objspace-std-withstrdict--prof_richards' +p1398 +I10 +sS'./pypy-c-39646-objspace-std-withmultidict--prof_pystone' +p1399 +I1 +sS'./pypy-c-35010_pystone' +p1400 +I10 +sS'./pypy-c-36395-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p1401 +I10 +sS'./pypy-c-37454-faassen_richards' +p1402 +I10 +sS'./pypy-llvm-39247-faassen-c_richards' +p1403 +I10 +sS'./pypy-c-36893-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p1404 +I10 +s.(dp0 +S'./pypy-cli-35609_pystone' +p1 +F480.43788107792199 +sS'./pypy-c-39324-faassen_richards' +p2 +F2163.3800000000001 +sS'./pypy-c-39302-faassen_richards' +p3 +F2204.3400000000001 +sS'./pypy-c-37044_richards' +p4 +F5441.2200000000003 +sS'./pypy-c-36395-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p5 +F10000.0 +sS'./pypy-llvm-35010-objspace-std-withstrdict-x86_pystone' +p6 +F8375.2099999999991 +sS'./pypy-llvm-39247-faassen-c-prof_pystone' +p7 +F18181.799999999999 +sS'./pypy-llvm-35824-objspace-std-withstrdict-x86_richards' +p8 +F2869.4499999999998 +sS'./pypy-c-35463-stackless--objspace-std-withstrdict--prof_pystone' +p9 +F8116.8800000000001 +sS'./pypy-llvm-36066-faassen-x86_richards' +p10 +F3409.7199999999998 +sS'./pypy-llvm-35010-objspace-std-withstrdict-c_richards' +p11 +F3994.3000000000002 +sS'./pypy-c-36446-objspace-std-withstrdict--prof_richards' +p12 +F3312.4299999999998 +sS'./pypy-c-36628-stackless--objspace-std-withstrdict--prof_pystone' +p13 +F9328.3600000000006 +sS'./pypy-c-36344_richards' +p14 +F5303.1499999999996 +sS'./pypy-c-36030_richards' +p15 +F4965.9300000000003 +sS'./pypy-c-37415-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p16 +F3237.46 +sS'./pypy-c-38651-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p17 +F2820.9200000000001 +sS'./pypy-c-35557_pystone' +p18 +F7022.4700000000003 +sS'./pypy-llvm-36009-faassen-c-prof_pystone' +p19 +F15290.5 +sS'./pypy-c-38529-objspace-std-withstrdict--prof_richards' +p20 +F2981.4099999999999 +sS'./pypy-c-36158-stackless--objspace-std-withstrdict--prof_richards' +p21 +F3810.1300000000001 +sS'./pypy-c-35906-gc=framework--objspace-std-withstrdict--prof_pystone' +p22 +F10020.0 +sS'./pypy-llvm-35065-objspace-std-withstrdict-c_richards' +p23 +F99999.0 +sS'./pypy-cli-35544_richards' +p24 +F68798.592090606704 +sS'./pypy-c-35944-objspace-std-withstrdict--prof_pystone' +p25 +F9803.9200000000001 +sS'./pypy-c-39218-objspace-std-withfastslice_pystone' +p26 +F7062.1499999999996 +sS'./pypy-llvm-36066-faassen-c-prof_richards' +p27 +F3215.8600000000001 +sS'./pypy-llvm-39348-faassen-c_pystone' +p28 +F15974.4 +sS'./pypy-c-36859_pystone' +p29 +F6944.4399999999996 +sS'./pypy-llvm-36082-faassen-c-prof_richards' +p30 +F2153.46 +sS'./pypy-c-35609-objspace-std-withstrdict--prof_richards' +p31 +F3082.2199999999998 +sS'./pypy-c-35923_richards' +p32 +F5417.9300000000003 +sS'./pypy-llvm-35867-objspace-std-withstrdict-c-prof_pystone' +p33 +F13054.799999999999 +sS'./pypy-c-39374-stackless--objspace-std-withmultidict--prof_richards' +p34 +F3256.9099999999999 +sS'./pypy-c-39474-objspace-std-withfastslice_pystone' +p35 +F6561.6800000000003 +sS'./pypy-c-37310-stackless--objspace-std-withstrdict--prof_richards' +p36 +F3830.0999999999999 +sS'./pypy-llvm-34976-objspace-std-withstrdict-c_pystone' +p37 +F8264.4599999999991 +sS'./pypy-llvm-35771-objspace-std-withstrdict-c-prof_richards' +p38 +F2448.5500000000002 +sS'./pypy-c-38994-faassen_richards' +p39 +F2125.4400000000001 +sS'./pypy-cli-37163_pystone' +p40 +F697.26277088013705 +sS'./pypy-llvm-35944-faassen-c_pystone' +p41 +F14164.299999999999 +sS'./pypy-llvm-35837-objspace-std-withstrdict-c-prof_pystone' +p42 +F12562.799999999999 +sS'./pypy-c-35824-objspace-std-withstrdict--prof_richards' +p43 +F3239.0700000000002 +sS'./pypy-llvm-38994-faassen-c_pystone' +p44 +F15060.200000000001 +sS'./pypy-llvm-unknown-objspace-std-withstrdict-c-prof_richards' +p45 +F3701.4299999999998 +sS'./pypy-llvm-36446-faassen-x86_pystone' +p46 +F13262.6 +sS'./pypy-c-35837-stackless--objspace-std-withstrdict--prof_pystone' +p47 +F9041.5900000000001 +sS'./pypy-c-37084-objspace-std-withstrdict--prof_richards' +p48 +F3245.5599999999999 +sS'./pypy-llvm-35923-objspace-std-withstrdict-x86_richards' +p49 +F3085.0500000000002 +sS'./pypy-c-39247-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p50 +F2864.3400000000001 +sS'./pypy-c-39072_richards' +p51 +F4720.96 +sS'./pypy-llvm-36158-faassen-c-prof_richards' +p52 +F2190.3800000000001 +sS'./pypy-c-35944-stackless--objspace-std-withstrdict--prof_pystone' +p53 +F8849.5599999999995 +sS'./pypy-c-36182-objspace-std-withstrdict--prof_pystone' +p54 +F10266.9 +sS'./pypy-c-36113-stackless--objspace-std-withstrdict--prof_pystone' +p55 +F9191.1800000000003 +sS'./pypy-llvm-35906-objspace-opcodes-CALL_LIKELY_BUILTIN-c_pystone' +p56 +F11600.9 +sS'./pypy-c-38140-objspace-std-withstrdict--prof_richards' +p57 +F3208.6399999999999 +sS'./pypy-c-35512-stackless--objspace-std-withstrdict--prof_richards' +p58 +F3937.4000000000001 +sS'./pypy-c-36113_richards' +p59 +F5345.4399999999996 +sS'./pypy-c-38870_pystone' +p60 +F7142.8599999999997 +sS'./pypy-c-35988-gc=framework--objspace-std-withstrdict--prof_richards' +p61 +F3156.02 +sS'./pypy-llvm-36182-faassen-c_pystone' +p62 +F13698.6 +sS'./pypy-c-34593-stackless--objspace-std-withstrdict--prof_richards' +p63 +F3940.23 +sS'./pypy-c-39188-stackless--objspace-std-withmultidict--prof_richards' +p64 +F3475.0 +sS'./pypy-c-35350_pystone' +p65 +F6426.7399999999998 +sS'./pypy-c-35277-stackless--objspace-std-withstrdict--prof_richards' +p66 +F3993.1900000000001 +sS'./pypy-c-35237-gc=framework--objspace-std-withstrdict--prof_richards' +p67 +F3633.6700000000001 +sS'./pypy-llvm-39247-faassen-c-prof_richards' +p68 +F1601.24 +sS'./pypy-c-35771-stackless--objspace-std-withstrdict--prof_pystone' +p69 +F8880.9899999999998 +sS'./pypy-c-37111-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p70 +F3211.1399999999999 +sS'./pypy-c-36977-objspace-std-withstrdict--prof_pystone' +p71 +F9560.2299999999996 +sS'./pypy-llvm-39324-faassen-c_pystone' +p72 +F15723.299999999999 +sS'./pypy-c-38140-stackless--objspace-std-withstrdict--prof_pystone' +p73 +F9025.2700000000004 +sS'./pypy-c-36395-gc=framework--objspace-std-withstrdict--prof_richards' +p74 +F3309.6900000000001 +sS'./pypy-llvm-35944-faassen-x86_richards' +p75 +F2511.1599999999999 +sS'./pypy-c-38529-faassen_pystone' +p76 +F11820.299999999999 +sS'./pypy-llvm-39374-faassen-c-prof_richards' +p77 +F1620.52 +sS'./pypy-c-35237-stackless--objspace-std-withstrdict--prof_pystone' +p78 +F8169.9300000000003 +sS'./pypy-llvm-39302-faassen-c-prof_pystone' +p79 +F17421.599999999999 +sS'./pypy-c-39374-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p80 +F2875.52 +sS'./pypy-c-36082-stackless--objspace-std-withstrdict--prof_richards' +p81 +F3272.2399999999998 +sS'./pypy-c-36052_richards' +p82 +F8364.6499999999996 +sS'./pypy-c-38870-objspace-std-withstrdict--prof_richards' +p83 +F2885.9200000000001 +sS'./pypy-c-35544-gc=framework--objspace-std-withstrdict--prof_richards' +p84 +F3371.5100000000002 +sS'./pypy-c-35988-stackless--objspace-std-withstrdict--prof_pystone' +p85 +F8865.25 +sS'./pypy-c-37111-stackless--objspace-std-withstrdict--prof_richards' +p86 +F3527.7199999999998 +sS'./pypy-llvm-36220-faassen-c-prof_richards' +p87 +F2144.21 +sS'./pypy-c-36893-objspace-std-withstrdict--prof_pystone' +p88 +F9708.7399999999998 +sS'./pypy-llvm-39247-faassen-c_pystone' +p89 +F15576.299999999999 +sS'./pypy-c-34882-objspace-std-withstrdict--prof_pystone' +p90 +F8960.5699999999997 +sS'./pypy-c-37310-faassen_richards' +p91 +F2971.3299999999999 +sS'./pypy-c-35713-objspace-std-withstrdict--prof_richards' +p92 +F3497.77 +sS'./pypy-c-39474-stackless--objspace-std-withmultidict--prof_pystone' +p93 +F8771.9300000000003 +sS'./pypy-c-36395-gc=framework--objspace-std-withstrdict--prof_pystone' +p94 +F9980.0400000000009 +sS'./pypy-cli-35713_richards' +p95 +F69800.940036773696 +sS'./pypy-c-39474_richards' +p96 +F4750.5100000000002 +sS'./pypy-llvm-39247-faassen-x86_pystone' +p97 +F14662.799999999999 +sS'./pypy-c-35944-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p98 +F3333.3899999999999 +sS'./pypy-llvm-36082-faassen-x86_pystone' +p99 +F12165.5 +sS'./pypy-llvm-35982-faassen-x86_richards' +p100 +F2548.54 +sS'./pypy-c-39547-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p101 +F10706.6 +sS'./pypy-c-35837-stackless--objspace-std-withstrdict--prof_richards' +p102 +F3603.8800000000001 +sS'./pypy-c-36977_pystone' +p103 +F6915.6300000000001 +sS'./pypy-c-39218_richards' +p104 +F4822.8800000000001 +sS'./pypy-c-35923-objspace-std-withstrdict--prof_richards' +p105 +F3363.23 +sS'./pypy-cli-38529_richards' +p106 +F99999.0 +sS'./pypy-c-39324_richards' +p107 +F4939.8299999999999 +sS'./pypy-c-37454-objspace-std-withstrdict--prof_richards' +p108 +F3224.0100000000002 +sS'./pypy-c-39374-stackless--objspace-std-withmultidict--prof_pystone' +p109 +F9107.4699999999993 +sS'./pypy-c-38870-objspace-std-withfastslice_richards' +p110 +F4625.29 +sS'./pypy-c-34593-objspace-std-withstrdict--prof_richards' +p111 +F3363.75 +sS'./pypy-llvm-36344-faassen-x86_pystone' +p112 +F13587.0 +sS'./pypy-c-39218_pystone' +p113 +F7122.5100000000002 +sS'./pypy-llvm-35963-faassen-c_richards' +p114 +F2352.6999999999998 +sS'./pypy-c-39547-objspace-std-withfastslice_pystone' +p115 +F6839.9499999999998 +sS'./pypy-c-36113-gc=framework--objspace-std-withstrdict--prof_pystone' +p116 +F10121.5 +sS'./pypy-c-34593_richards' +p117 +F5630.2700000000004 +sS'./pypy-c-36182-stackless--objspace-std-withstrdict--prof_pystone' +p118 +F8488.9599999999991 +sS'./pypy-c-35350-gc=framework--objspace-std-withstrdict--prof_richards' +p119 +F3581.5100000000002 +sS'./pypy-llvm-35979-faassen-c-prof_richards' +p120 +F2288.0300000000002 +sS'./pypy-c-36113-stackless--objspace-std-withstrdict--prof_richards' +p121 +F3333.0100000000002 +sS'./pypy-c-35824-objspace-std-withstrdict--prof_pystone' +p122 +F10020.0 +sS'./pypy-c-36175-objspace-std-withstrdict--prof_richards' +p123 +F3000.1100000000001 +sS'./pypy-c-36158-gc=framework--objspace-std-withstrdict--prof_pystone' +p124 +F10020.0 +sS'./pypy-llvm-39617-faassen-c-prof_pystone' +p125 +F16778.5 +sS'./pypy-c-37310-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p126 +F2949.46 +sS'./pypy-llvm-35095-objspace-std-withstrdict-x86_richards' +p127 +F99999.0 +sS'./pypy-c-39247-faassen_richards' +p128 +F2163.8000000000002 +sS'./pypy-llvm-35923-objspace-opcodes-CALL_LIKELY_BUILTIN-c-prof_richards' +p129 +F2266.0900000000001 +sS'./pypy-c-38529-objspace-std-withstrdict--prof_pystone' +p130 +F9940.3600000000006 +sS'./pypy-cli-36977_pystone' +p131 +F702.08866885617203 +sS'./pypy-c-38769-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p132 +F2909.8099999999999 +sS'./pypy-c-37367-objspace-std-withstrdict--prof_pystone' +p133 +F9523.8099999999995 +sS'./pypy-c-36030_pystone' +p134 +F7062.1499999999996 +sS'./pypy-c-39218-stackless--objspace-std-withmultidict--prof_richards' +p135 +F3287.2600000000002 +sS'./pypy-c-37415-objspace-std-withstrdict--prof_pystone' +p136 +F9451.7999999999993 +sS'./pypy-c-36066-objspace-std-withstrdict--prof_pystone' +p137 +F6702.4099999999999 +sS'./pypy-c-36790-stackless--objspace-std-withstrdict--prof_richards' +p138 +F3658.52 +sS'./pypy-c-35982-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p139 +F3270.3200000000002 +sS'./pypy-llvm-36220-faassen-x86_pystone' +p140 +F12690.4 +sS'./pypy-c-36628-gc=framework--objspace-std-withstrdict--prof_richards' +p141 +F3584.2399999999998 +sS'./pypy-cli-39374_pystone' +p142 +F639.99766528851706 +sS'./pypy-c-35658-stackless--objspace-std-withstrdict--prof_pystone' +p143 +F9074.4099999999999 +sS'./pypy-llvm-35867-objspace-std-withstrdict-x86_pystone' +p144 +F11933.200000000001 +sS'./pypy-cli-37415_pystone' +p145 +F687.26849274913195 +sS'./pypy-c-35837_richards' +p146 +F5359.3599999999997 +sS'./pypy-cli-37084_pystone' +p147 +F681.52587537023601 +sS'./pypy-cli-35923_richards' +p148 +F50604.163169860803 +sS'./pypy-c-39646_pystone' +p149 +F7288.6300000000001 +sS'./pypy-llvm-36100-faassen-c-prof_pystone' +p150 +F15625.0 +sS'./pypy-llvm-35095-objspace-std-withstrdict-c_pystone' +p151 +F99999.0 +sS'./pypy-llvm-35906-objspace-std-withstrdict-c-prof_richards' +p152 +F2547.4499999999998 +sS'./pypy-llvm-35143-objspace-std-withstrdict-c_richards' +p153 +F99999.0 +sS'./pypy-c-37243-objspace-std-withstrdict--prof_pystone' +p154 +F9784.7399999999998 +sS'./pypy-c-35065-objspace-std-withstrdict--prof_richards' +p155 +F3559.6799999999998 +sS'./pypy-c-35143_pystone' +p156 +F6265.6599999999999 +sS'./pypy-c-38222_richards' +p157 +F5579.1000000000004 +sS'./pypy-c-39547-gc=framework--objspace-std-withmultidict--prof_pystone' +p158 +F10288.1 +sS'./pypy-c-36009_richards' +p159 +F5301.1000000000004 +sS'./pypy-llvm-35183-objspace-std-withstrdict-c_richards' +p160 +F99999.0 +sS'./pypy-c-35512-stackless--objspace-std-withstrdict--prof_pystone' +p161 +F7949.1300000000001 +sS'./pypy-c-35277-objspace-std-withstrdict--prof_richards' +p162 +F3571.1599999999999 +sS'./pypy-llvm-36220-faassen-x86_richards' +p163 +F2647.5700000000002 +sS'./pypy-c-37647-stackless--objspace-std-withstrdict--prof_pystone' +p164 +F9057.9699999999993 +sS'./pypy-c-36030-objspace-std-withstrdict--prof_pystone' +p165 +F9861.9300000000003 +sS'./pypy-c-38651-stackless--objspace-std-withstrdict--prof_richards' +p166 +F3255.5599999999999 +sS'./pypy-c-39072-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p167 +F10661.0 +sS'./pypy-c-36395-objspace-std-withstrdict--prof_richards' +p168 +F3343.9400000000001 +sS'./pypy-c-39072-objspace-std-withfastslice_richards' +p169 +F4483.6199999999999 +sS'./pypy-c-39324-objspace-std-withfastslice_pystone' +p170 +F6666.6700000000001 +sS'./pypy-cli-36113_richards' +p171 +F64548.238992690996 +sS'./pypy-c-35217-gc=framework--objspace-std-withstrdict--prof_pystone' +p172 +F9451.7999999999993 +sS'./pypy-c-35968-stackless--objspace-std-withstrdict--prof_richards' +p173 +F3639.0 +sS'./pypy-c-36977_richards' +p174 +F5172.9399999999996 +sS'./pypy-c-36182_pystone' +p175 +F6868.1300000000001 +sS'./pypy-c-39302-stackless--objspace-std-withmultidict--prof_richards' +p176 +F3011.5100000000002 +sS'./pypy-llvm-36030-faassen-c-prof_richards' +p177 +F2239.5799999999999 +sS'./pypy-c-35771-objspace-std-withstrdict--prof_richards' +p178 +F3306.9099999999999 +sS'./pypy-c-34593-prof_richards' +p179 +F5565.46 +sS'./pypy-cli-35968_richards' +p180 +F50464.357137680097 +sS'./pypy-cli-37044_richards' +p181 +F47606.956005096399 +sS'./pypy-llvm-35982-faassen-c_richards' +p182 +F2333.4699999999998 +sS'./pypy-c-36100-stackless--objspace-std-withstrdict--prof_pystone' +p183 +F9310.9899999999998 +sS'./pypy-cli-35906_richards' +p184 +F62764.541864395098 +sS'./pypy-c-39147-gc=framework--objspace-std-withmultidict--prof_richards' +p185 +F3072.96 +sS'./pypy-c-39348-gc=framework--objspace-std-withmultidict--prof_pystone' +p186 +F10526.299999999999 +sS'./pypy-llvm-unknown-objspace-std-withstrdict-c-prof_pystone' +p187 +F9057.9699999999993 +sS'./pypy-c-35350_richards' +p188 +F5494.7700000000004 +sS'./pypy-c-34948-objspace-std-withstrdict--prof_pystone' +p189 +F7352.9399999999996 +sS'./pypy-c-38334_richards' +p190 +F5427.0100000000002 +sS'./pypy-c-36030-gc=framework--objspace-std-withstrdict--prof_richards' +p191 +F3533.0500000000002 +sS'./pypy-c-39324-gc=framework--objspace-std-withmultidict--prof_richards' +p192 +F3131.52 +sS'./pypy-c-35411-objspace-std-withstrdict--prof_pystone' +p193 +F8802.8199999999997 +sS'./pypy-llvm-38769-faassen-x86_pystone' +p194 +F14749.299999999999 +sS'./pypy-llvm-34948-objspace-std-withstrdict-c_richards' +p195 +F3585.23 +sS'./pypy-cli-36790_pystone' +p196 +F696.40308780115004 +sS'./pypy-llvm-39147-faassen-c-prof_pystone' +p197 +F17857.099999999999 +sS'./pypy-llvm-36158-faassen-c_pystone' +p198 +F13661.200000000001 +sS'./pypy-c-37647_pystone' +p199 +F6934.8100000000004 +sS'./pypy-c-35906-objspace-std-withstrdict--prof_pystone' +p200 +F9746.5900000000001 +sS'./pypy-llvm-36009-faassen-x86_pystone' +p201 +F13192.6 +sS'./pypy-c-38140-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p202 +F3124.3099999999999 +sS'./pypy-c-35512_pystone' +p203 +F6666.6700000000001 +sS'./pypy-c-35713-objspace-std-withstrdict--prof_pystone' +p204 +F9523.8099999999995 +sS'./pypy-llvm-39147-faassen-x86_richards' +p205 +F1857.74 +sS'./pypy-cli-35775_richards' +p206 +F71631.805896759004 +sS'./pypy-c-36628-objspace-std-withstrdict--prof_richards' +p207 +F3305.1199999999999 +sS'./pypy-c-37647-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p208 +F10183.299999999999 +sS'./pypy-c-35183-stackless--objspace-std-withstrdict--prof_pystone' +p209 +F8116.8800000000001 +sS'./pypy-c-37367-gc=framework--objspace-std-withstrdict--prof_pystone' +p210 +F10121.5 +sS'./pypy-cli-35944_richards' +p211 +F50181.558132171602 +sS'./pypy-llvm-34976-objspace-std-withstrdict-c_richards' +p212 +F4084.9899999999998 +sS'./pypy-llvm-39072-faassen-c_richards' +p213 +F1866.73 +sS'./pypy-llvm-35095-objspace-std-withstrdict-x86_pystone' +p214 +F99999.0 +sS'./pypy-c-36344-gc=framework--objspace-std-withstrdict--prof_richards' +p215 +F3670.3699999999999 +sS'./pypy-c-37647-gc=framework--objspace-std-withstrdict--prof_pystone' +p216 +F10352.0 +sS'./pypy-c-36446-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p217 +F10352.0 +sS'./pypy-llvm-35183-objspace-std-withstrdict-x86_richards' +p218 +F99999.0 +sS'./pypy-c-36175_richards' +p219 +F5323.5799999999999 +sS'./pypy-c-37503-gc=framework--objspace-std-withstrdict--prof_richards' +p220 +F3592.4099999999999 +sS'./pypy-cli-36790_richards' +p221 +F47052.5670051575 +sS'./pypy-cli-37243_pystone' +p222 +F682.15102190588902 +sS'./pypy-c-39218-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p223 +F10416.700000000001 +sS'./pypy-c-38140_richards' +p224 +F5294.0900000000001 +sS'./pypy-llvm-35183-objspace-std-withstrdict-x86_pystone' +p225 +F99999.0 +sS'./pypy-c-35968-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p226 +F10224.9 +sS'./pypy-c-35609-gc=framework--objspace-std-withstrdict--prof_pystone' +p227 +F9920.6299999999992 +sS'./pypy-c-36859-objspace-std-withstrdict--prof_pystone' +p228 +F9940.3600000000006 +sS'./pypy-c-35658-objspace-std-withstrdict--prof_pystone' +p229 +F9980.0400000000009 +sS'./pypy-c-35544-gc=framework--objspace-std-withstrdict--prof_pystone' +p230 +F10204.1 +sS'./pypy-llvm-35923-objspace-std-withstrdict-c-prof_pystone' +p231 +F13020.799999999999 +sS'./pypy-c-36030-stackless--objspace-std-withstrdict--prof_pystone' +p232 +F8880.9899999999998 +sS'./pypy-c-35237_pystone' +p233 +F6273.5299999999997 +sS'./pypy-cli-37707_richards' +p234 +F47950.798034667998 +sS'./pypy-c-37163-gc=framework--objspace-std-withstrdict--prof_richards' +p235 +F3431.75 +sS'./pypy-c-39247-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p236 +F10706.6 +sS'./pypy-c-39147-objspace-std-withmultidict--prof_pystone' +p237 +F10330.6 +sS'./pypy-c-35906-stackless--prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p238 +F3447.9499999999998 +sS'./pypy-c-36539-objspace-std-withstrdict--prof_richards' +p239 +F3344.1999999999998 +sS'./pypy-c-37782-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p240 +F10729.6 +sS'./pypy-c-35906-stackless--prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p241 +F9107.4699999999993 +sS'./pypy-llvm-39374-faassen-c_richards' +p242 +F1850.1900000000001 +sS'./pypy-llvm-35988-faassen-c_pystone' +p243 +F14164.299999999999 +sS'./pypy-c-39218-faassen_richards' +p244 +F2169.6799999999998 +sS'./pypy-cli-35713~_richards' +p245 +F99999.0 +sS'./pypy-cli-39247_pystone' +p246 +F663.07800011961899 +sS'./pypy-c-36790-stackless--objspace-std-withstrdict--prof_pystone' +p247 +F8756.5699999999997 +sS'./pypy-c-39247-objspace-std-withmultidict--prof_richards' +p248 +F2989.1999999999998 +sS'./pypy-llvm-35143-objspace-std-withstrdict-c_pystone' +p249 +F99999.0 +sS'./pypy-c-35237-stackless--objspace-std-withstrdict--prof_richards' +p250 +F4002.3600000000001 +sS'./pypy-c-39474-objspace-std-withfastslice_richards' +p251 +F4874.8699999999999 +sS'./pypy-c-37163-objspace-std-withstrdict--prof_pystone' +p252 +F9652.5100000000002 +sS'./pypy-cli-39348_pystone' +p253 +F648.77586763456804 +sS'./pypy-llvm-39474-faassen-c-prof_richards' +p254 +F1677.78 +sS'./pypy-c-36052-stackless--objspace-std-withstrdict--prof_richards' +p255 +F5159.8000000000002 +sS'./pypy-c-37367-gc=framework--objspace-std-withstrdict--prof_richards' +p256 +F3315.9699999999998 +sS'./pypy-c-35713_pystone' +p257 +F6811.9899999999998 +sS'./pypy-c-36893-stackless--objspace-std-withstrdict--prof_pystone' +p258 +F8605.8500000000004 +sS'./pypy-c-37503-objspace-std-withstrdict--prof_richards' +p259 +F3039.1900000000001 +sS'./pypy-c-35411-objspace-std-withstrdict--prof_richards' +p260 +F3424.8499999999999 +sS'./pypy-c-36539-gc=framework--objspace-std-withstrdict--prof_richards' +p261 +F3487.7399999999998 +sS'./pypy-llvm-35968-faassen-c-prof_pystone' +p262 +F15432.1 +sS'./pypy-c-35771-gc=framework--objspace-std-withstrdict--prof_pystone' +p263 +F9980.0400000000009 +sS'./pypy-c-35095-objspace-std-withstrdict--prof_richards' +p264 +F3414.73 +sS'./pypy-c-39348_pystone' +p265 +F7002.8000000000002 +sS'./pypy-c-35411-stackless--objspace-std-withstrdict--prof_pystone' +p266 +F8025.6800000000003 +sS'./pypy-c-35277-objspace-std-withstrdict--prof_pystone' +p267 +F8818.3400000000001 +sS'./pypy-c-35837-gc=framework--objspace-std-withstrdict--prof_richards' +p268 +F3466.5799999999999 +sS'./pypy-llvm-39302-faassen-c-prof_richards' +p269 +F1632.26 +sS'./pypy-c-37367-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p270 +F3091.3200000000002 +sS'./pypy-llvm-35906-objspace-std-withstrdict-c-prof_pystone' +p271 +F13297.9 +sS'./pypy-llvm-36113-faassen-c-prof_pystone' +p272 +F15015.0 +sS'./pypy-llvm-35010-objspace-std-withstrdict-x86_richards' +p273 +F3921.4899999999998 +sS'./pypy-llvm-36136-faassen-c_pystone' +p274 +F14367.799999999999 +sS'./pypy-c-36790-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p275 +F3002.54 +sS'./pypy-c-37647-gc=framework--objspace-std-withstrdict--prof_richards' +p276 +F3406.8200000000002 +sS'./pypy-llvm-35906-objspace-opcodes-CALL_LIKELY_BUILTIN-x86_richards' +p277 +F3060.73 +sS'./pypy-llvm-39072-faassen-c-prof_richards' +p278 +F1688.78 +sS'./pypy-c-38651_pystone' +p279 +F6849.3199999999997 +sS'./pypy-llvm-35968-faassen-c_pystone' +p280 +F14245.0 +sS'./pypy-c-35065_pystone' +p281 +F6605.0200000000004 +sS'./pypy-cli-35512_pystone' +p282 +F475.95074659871102 +sS'./pypy-llvm-38994-faassen-c-prof_richards' +p283 +F1692.5599999999999 +sS'./pypy-llvm-39547-faassen-c-prof_pystone' +p284 +F17543.900000000001 +sS'./pypy-c-39324-faassen_pystone' +p285 +F12953.4 +sS'./pypy-c-unknown-objspace-std-withstrdict--prof_richards' +p286 +F4425.1999999999998 +sS'./pypy-c-36082-gc=framework--objspace-std-withstrdict--prof_pystone' +p287 +F9980.0400000000009 +sS'./pypy-cli-39147_richards' +p288 +F45330.018997192397 +sS'./pypy-llvm-36113-faassen-c_richards' +p289 +F2387.9099999999999 +sS'./pypy-c-39646-stackless--objspace-std-withmultidict--prof_pystone' +p290 +F8976.6599999999999 +sS'./pypy-c-39547-objspace-std-withfastslice_richards' +p291 +F4737.5 +sS'./pypy-cli-35979_pystone' +p292 +F666.64617840744995 +sS'./pypy-cli-35982_richards' +p293 +F50194.116830825798 +sS'./pypy-llvm-36100-faassen-c_richards' +p294 +F2332.8099999999999 +sS'./pypy-c-34976_richards' +p295 +F6251.3900000000003 +sS'./pypy-llvm-36344-faassen-c_richards' +p296 +F2353.79 +sS'./pypy-c-36158-gc=framework--objspace-std-withstrdict--prof_richards' +p297 +F3487.6199999999999 +sS'./pypy-c-39617-faassen_richards' +p298 +F2148.9899999999998 +sS'./pypy-c-36628-objspace-std-withstrdict--prof_pystone' +p299 +F9727.6299999999992 +sS'./pypy-c-36790-gc=framework--objspace-std-withstrdict--prof_richards' +p300 +F3650.3699999999999 +sS'./pypy-c-37707-faassen_richards' +p301 +F2788.5999999999999 +sS'./pypy-c-37367-faassen_pystone' +p302 +F10989.0 +sS'./pypy-c-35979-stackless--objspace-std-withstrdict--prof_richards' +p303 +F3284.21 +sS'./pypy-c-36082_pystone' +p304 +F6747.6400000000003 +sS'./pypy-c-35968_richards' +p305 +F5445.1199999999999 +sS'./pypy-llvm-39072-faassen-c_pystone' +p306 +F15772.9 +sS'./pypy-c-35544_pystone' +p307 +F6830.6000000000004 +sS'./pypy-c-38140-faassen_pystone' +p308 +F11494.299999999999 +sS'./pypy-cli-39218_pystone' +p309 +F657.44864063815203 +sS'./pypy-llvm-35963-faassen-c-prof_richards' +p310 +F2349.0999999999999 +sS'./pypy-c-37243-objspace-std-withstrdict--prof_richards' +p311 +F3243.9099999999999 +sS'./pypy-c-38994-objspace-std-withfastslice_pystone' +p312 +F7541.4799999999996 +sS'./pypy-c-39617-gc=framework--objspace-std-withmultidict--prof_pystone' +p313 +F9633.9099999999999 +sS'./pypy-llvm-35824-objspace-std-withstrdict-c_pystone' +p314 +F11961.700000000001 +sS'./pypy-c-38651-objspace-std-withfastslice_richards' +p315 +F4457.3000000000002 +sS'./pypy-c-36175_pystone' +p316 +F6622.5200000000004 +sS'./pypy-llvm-35824-objspace-std-withstrdict-c_richards' +p317 +F2897.25 +sS'./pypy-c-36066-stackless--objspace-std-withstrdict--prof_richards' +p318 +F5412.5799999999999 +sS'./pypy-llvm-35968-faassen-x86_pystone' +p319 +F13812.200000000001 +sS'./pypy-llvm-35923-objspace-opcodes-CALL_LIKELY_BUILTIN-x86_richards' +p320 +F2874.4099999999999 +sS'./pypy-llvm-39374-faassen-c-prof_pystone' +p321 +F18382.400000000001 +sS'./pypy-llvm-35923-objspace-opcodes-CALL_LIKELY_BUILTIN-c_richards' +p322 +F2575.5100000000002 +sS'./pypy-c-37111-stackless--objspace-std-withstrdict--prof_pystone' +p323 +F8665.5100000000002 +sS'./pypy-llvm-38870-faassen-x86_richards' +p324 +F1931.53 +sS'./pypy-llvm-36100-faassen-x86_richards' +p325 +F2427.0100000000002 +sS'./pypy-c-35544_richards' +p326 +F5301.6300000000001 +sS'./pypy-c-36344_pystone' +p327 +F6587.6199999999999 +sS'./pypy-c-36066-gc=framework--objspace-std-withstrdict--prof_richards' +p328 +F4784.4899999999998 +sS'./pypy-c-39646-gc=framework--objspace-std-withmultidict--prof_pystone' +p329 +F10330.6 +sS'./pypy-llvm-36082-faassen-c-prof_pystone' +p330 +F15384.6 +sS'./pypy-cli-39302_pystone' +p331 +F641.46991651063797 +sS'./pypy-llvm-36030-faassen-x86_richards' +p332 +F2687.0700000000002 +sS'./pypy-llvm-38769-faassen-c_pystone' +p333 +F15822.799999999999 +sS'./pypy-c-35411_richards' +p334 +F5426.3599999999997 +sS'./pypy-llvm-35906-objspace-opcodes-CALL_LIKELY_BUILTIN-c-prof_richards' +p335 +F2577.6599999999999 +sS'./pypy-c-36539-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p336 +F3197.9400000000001 +sS'./pypy-c-36344-stackless--objspace-std-withstrdict--prof_pystone' +p337 +F8771.9300000000003 +sS'./pypy-c-35277_richards' +p338 +F5188.75 +sS'./pypy-c-39147-faassen_richards' +p339 +F2154.3200000000002 +sS'./pypy-c-35771_richards' +p340 +F5289.7200000000003 +sS'./pypy-c-36175-objspace-std-withstrdict--prof_pystone' +p341 +F10288.1 +sS'./pypy-c-34593-prof_pystone' +p342 +F6426.7399999999998 +sS'./pypy-llvm-39324-faassen-c-prof_richards' +p343 +F1656.8399999999999 +sS'./pypy-c-35982-objspace-std-withstrdict--prof_richards' +p344 +F3274.3699999999999 +sS'./pypy-cli-37111_richards' +p345 +F47068.382024765 +sS'./pypy-c-35065-stackless--objspace-std-withstrdict--prof_richards' +p346 +F3958.4699999999998 +sS'./pypy-c-39147-stackless--objspace-std-withmultidict--prof_richards' +p347 +F3161.4899999999998 +sS'./pypy-c-39617-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p348 +F9861.9300000000003 +sS'./pypy-c-34593-stackless_richards' +p349 +F6129.8500000000004 +sS'./pypy-c-36977-objspace-std-withstrdict--prof_richards' +p350 +F3268.1100000000001 +sS'./pypy-c-36082-objspace-std-withstrdict--prof_richards' +p351 +F3246.6599999999999 +sS'./pypy-c-35010_richards' +p352 +F6540.8900000000003 +sS'./pypy-llvm-35923-objspace-opcodes-CALL_LIKELY_BUILTIN-x86_pystone' +p353 +F11061.9 +sS'./pypy-c-36009-stackless--objspace-std-withstrdict--prof_richards' +p354 +F3704.48 +sS'./pypy-c-38994-gc=framework--objspace-std-withmultidict--prof_pystone' +p355 +F10548.5 +sS'./pypy-c-38651-faassen_pystone' +p356 +F12019.200000000001 +sS'./pypy-c-39072-objspace-std-withfastslice_pystone' +p357 +F7235.8900000000003 +sS'./pypy-c-35143-objspace-std-withstrdict--prof_pystone' +p358 +F9009.0100000000002 +sS'./pypy-llvm-39324-faassen-x86_richards' +p359 +F1854.3800000000001 +sS'./pypy-c-35867_pystone' +p360 +F6369.4300000000003 +sS'./pypy-c-34927-objspace-std-withstrdict--prof_richards' +p361 +F4373.1300000000001 +sS'./pypy-c-34976-stackless--objspace-std-withstrdict--prof_pystone' +p362 +F6443.3000000000002 +sS'./pypy-c-39374-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p363 +F10683.799999999999 +sS'./pypy-c-35143-gc=framework--objspace-std-withstrdict--prof_richards' +p364 +F3606.5100000000002 +sS'./pypy-cli-36175_richards' +p365 +F62573.691129684397 +sS'./pypy-c-39474-faassen_pystone' +p366 +F13587.0 +sS'./pypy-c-38435_pystone' +p367 +F6297.2299999999996 +sS'./pypy-c-37782-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p368 +F2911.5500000000002 +sS'./pypy-c-39547_richards' +p369 +F5191.0600000000004 +sS'./pypy-llvm-35713-objspace-std-withstrdict-x86_richards' +p370 +F2898.52 +sS'./pypy-llvm-35837-objspace-std-withstrdict-x86_richards' +p371 +F2941.1900000000001 +sS'./pypy-c-37415-gc=framework--objspace-std-withstrdict--prof_richards' +p372 +F3569.8600000000001 +sS'./pypy-llvm-35923-objspace-std-withstrdict-c-prof_richards' +p373 +F2451.1199999999999 +sS'./pypy-c-39617-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p374 +F2972.23 +sS'./pypy-c-35713-gc=framework--objspace-std-withstrdict--prof_richards' +p375 +F3132.02 +sS'./pypy-c-35658-objspace-std-withstrdict--prof_richards' +p376 +F3095.02 +sS'./pypy-llvm-39374-faassen-c_pystone' +p377 +F15772.9 +sS'./pypy-cli-35923_pystone' +p378 +F666.70796700286303 +sS'./pypy-c-36628_richards' +p379 +F5305.3400000000001 +sS'./pypy-cli-37367_pystone' +p380 +F690.97227039834399 +sS'./pypy-c-39324-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p381 +F2775.9099999999999 +sS'./pypy-c-34593_pystone' +p382 +F6393.8599999999997 +sS'./pypy-c-36175-stackless--objspace-std-withstrdict--prof_richards' +p383 +F3836.8099999999999 +sS'./pypy-cli-36113_pystone' +p384 +F544.21402047914398 +sS'./pypy-c-35923-gc=framework--objspace-std-withstrdict--prof_pystone' +p385 +F10266.9 +sS'./pypy-c-35824-gc=framework--objspace-std-withstrdict--prof_richards' +p386 +F3436.1500000000001 +sS'./pypy-llvm-36113-faassen-x86_richards' +p387 +F2556.0100000000002 +sS'./pypy-c-39547-faassen_pystone' +p388 +F13192.6 +sS'./pypy-c-38769-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p389 +F10183.299999999999 +sS'./pypy-c-35557-objspace-std-withstrdict--prof_richards' +p390 +F2958.96 +sS'./pypy-c-36009-objspace-std-withstrdict--prof_richards' +p391 +F3260.0599999999999 +sS'./pypy-c-37647-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p392 +F3095.21 +sS'./pypy-c-35183-stackless--objspace-std-withstrdict--prof_richards' +p393 +F4043.8200000000002 +sS'./pypy-c-37454-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p394 +F3264.0900000000001 +sS'./pypy-c-39188-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p395 +F10183.299999999999 +sS'./pypy-c-35658_richards' +p396 +F5354.2299999999996 +sS'./pypy-cli-37647_pystone' +p397 +F703.90901936505804 +sS'./pypy-c-39374-gc=framework--objspace-std-withmultidict--prof_pystone' +p398 +F10504.200000000001 +sS'./pypy-c-36220_richards' +p399 +F5279.2700000000004 +sS'./pypy-cli-39324_richards' +p400 +F47383.9371204376 +sS'./pypy-c-39147-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p401 +F10706.6 +sS'./pypy-llvm-36344-faassen-c-prof_pystone' +p402 +F15822.799999999999 +sS'./pypy-c-36628-stackless--objspace-std-withstrdict--prof_richards' +p403 +F3321.23 +sS'./pypy-c-39147-objspace-std-withmultidict--prof_richards' +p404 +F3038.21 +sS'./pypy-llvm-unknown-objspace-std-withstrdict-c_richards' +p405 +F4184.46 +sS'./pypy-cli-35968_pystone' +p406 +F658.81729777520695 +sS'./pypy-cli-35713_pystone' +p407 +F482.26100781728701 +sS'./pypy-c-36100-gc=framework--objspace-std-withstrdict--prof_richards' +p408 +F3497.3400000000001 +sS'./pypy-c-37454-stackless--objspace-std-withstrdict--prof_pystone' +p409 +F8576.3299999999999 +sS'./pypy-llvm-38994-faassen-x86_pystone' +p410 +F14084.5 +sS'./pypy-c-39324-gc=framework--objspace-std-withmultidict--prof_pystone' +p411 +F10615.700000000001 +sS'./pypy-cli-36082_richards' +p412 +F62594.981908798203 +sS'./pypy-c-36066-objspace-std-withstrdict--prof_richards' +p413 +F5167.9899999999998 +sS'./pypy-c-35982-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p414 +F9960.1599999999999 +sS'./pypy-llvm-39617-faassen-c_richards' +p415 +F1632.1099999999999 +sS'./pypy-c-35411-gc=framework--objspace-std-withstrdict--prof_pystone' +p416 +F9363.2999999999993 +sS'./pypy-llvm-38870-faassen-c_pystone' +p417 +F15528.0 +sS'./pypy-c-35277-gc=framework--objspace-std-withstrdict--prof_richards' +p418 +F3360.8600000000001 +sS'./pypy-cli-35544~_richards' +p419 +F96284.034013748198 +sS'./pypy-c-37707-faassen_pystone' +p420 +F11520.700000000001 +sS'./pypy-c-36100-objspace-std-withstrdict--prof_pystone' +p421 +F9920.6299999999992 +sS'./pypy-c-36052-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p422 +F6587.6199999999999 +sS'./pypy-c-36790-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p423 +F10204.1 +sS'./pypy-llvm-39646-faassen-c_richards' +p424 +F1576.0899999999999 +sS'./pypy-c-39247-faassen_pystone' +p425 +F13192.6 +sS'./pypy-llvm-39474-faassen-x86_pystone' +p426 +F14836.799999999999 +sS'./pypy-llvm-36344-faassen-c_pystone' +p427 +F14084.5 +sS'./pypy-c-36220-gc=framework--objspace-std-withstrdict--prof_pystone' +p428 +F9980.0400000000009 +sS'./pypy-cli-35609_richards' +p429 +F68936.759948730498 +sS'./pypy-c-36030-stackless--objspace-std-withstrdict--prof_richards' +p430 +F3665.6199999999999 +sS'./pypy-c-35979-objspace-std-withstrdict--prof_pystone' +p431 +F9823.1800000000003 +sS'./pypy-c-36344-objspace-std-withstrdict--prof_pystone' +p432 +F9784.7399999999998 +sS'./pypy-c-37782_pystone' +p433 +F6459.9499999999998 +sS'./pypy-c-35277-stackless--objspace-std-withstrdict--prof_pystone' +p434 +F7861.6400000000003 +sS'./pypy-c-39374-faassen_richards' +p435 +F2164.6900000000001 +sS'./pypy-llvm-35988-faassen-x86_pystone' +p436 +F13369.0 +sS'./pypy-c-34593-stackless--objspace-std-withstrdict--prof_pystone' +p437 +F8375.2099999999991 +sS'./pypy-c-37310-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p438 +F10183.299999999999 +sS'./pypy-llvm-35183-objspace-std-withstrdict-c_pystone' +p439 +F99999.0 +sS'./pypy-llvm-38769-faassen-x86_richards' +p440 +F1950.9000000000001 +sS'./pypy-llvm-39302-faassen-c_richards' +p441 +F1822.6600000000001 +sS'./pypy-c-34593-gc=framework--objspace-std-withstrdict--prof_richards' +p442 +F3684.3600000000001 +sS'./pypy-llvm-39348-faassen-c_richards' +p443 +F1757.49 +sS'./pypy-c-35944_pystone' +p444 +F6578.9499999999998 +sS'./pypy-cli-35988_richards' +p445 +F50151.942968368501 +sS'./pypy-cli-38334_richards' +p446 +F47268.691062927202 +sS'./pypy-c-35350-gc=framework--objspace-std-withstrdict--prof_pystone' +p447 +F9433.9599999999991 +sS'./pypy-c-36977-stackless--objspace-std-withstrdict--prof_richards' +p448 +F3585.1199999999999 +sS'./pypy-c-35867-stackless--objspace-std-withstrdict--prof_richards' +p449 +F3697.3400000000001 +sS'./pypy-c-35923-stackless--prof_richards' +p450 +F6350.9099999999999 +sS'./pypy-llvm-36052-faassen-c-prof_pystone' +p451 +F11160.700000000001 +sS'./pypy-llvm-36446-faassen-c_richards' +p452 +F2267.9899999999998 +sS'./pypy-llvm-35979-faassen-c_richards' +p453 +F2354.21 +sS'./pypy-c-36158-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p454 +F3123.0 +sS'./pypy-llvm-39646-faassen-c-prof_pystone' +p455 +F17421.599999999999 +sS'./pypy-c-34948-stackless--objspace-std-withstrdict--prof_richards' +p456 +F5050.5 +sS'./pypy-c-34882-stackless--objspace-std-withstrdict--prof_richards' +p457 +F4210.7299999999996 +sS'./pypy-c-35963-stackless--objspace-std-withstrdict--prof_pystone' +p458 +F9380.8600000000006 +sS'./pypy-c-39646-faassen_pystone' +p459 +F13297.9 +sS'./pypy-c-35963_pystone' +p460 +F6915.6300000000001 +sS'./pypy-c-35982_pystone' +p461 +F6934.8100000000004 +sS'./pypy-c-39147-faassen_pystone' +p462 +F12820.5 +sS'./pypy-c-37084-gc=framework--objspace-std-withstrdict--prof_pystone' +p463 +F9803.9200000000001 +sS'./pypy-c-39072-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p464 +F2866.73 +sS'./pypy-c-35988-objspace-std-withstrdict--prof_richards' +p465 +F3379.0100000000002 +sS'./pypy-cli-35658_richards' +p466 +F68534.044027328506 +sS'./pypy-c-35609-gc=framework--objspace-std-withstrdict--prof_richards' +p467 +F3474.1700000000001 +sS'./pypy-llvm-35824-objspace-std-withstrdict-c-prof_pystone' +p468 +F12820.5 +sS'./pypy-c-35988-gc=framework--objspace-std-withstrdict--prof_pystone' +p469 +F10352.0 +sS'./pypy-c-36628-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p470 +F9363.2999999999993 +sS'./pypy-c-36009-gc=framework--objspace-std-withstrdict--prof_richards' +p471 +F3588.3899999999999 +sS'./pypy-c-35944-stackless--objspace-std-withstrdict--prof_richards' +p472 +F3611.3099999999999 +sS'./pypy-llvm-39547-faassen-c_pystone' +p473 +F15290.5 +sS'./pypy-c-35217-gc=framework--objspace-std-withstrdict--prof_richards' +p474 +F3458.1900000000001 +sS'./pypy-llvm-35867-objspace-std-withstrdict-c-prof_richards' +p475 +F2536.02 +sS'./pypy-c-38529-gc=framework--objspace-std-withstrdict--prof_pystone' +p476 +F10373.4 +sS'./pypy-c-37367_richards' +p477 +F5231.1899999999996 +sS'./pypy-cli-39302_richards' +p478 +F47496.8359470367 +sS'./pypy-cli-38651_pystone' +p479 +F646.41409923268304 +sS'./pypy-c-37575-gc=framework--objspace-std-withstrdict--prof_richards' +p480 +F3133.7399999999998 +sS'./pypy-c-35867-stackless--objspace-std-withstrdict--prof_pystone' +p481 +F8865.25 +sS'./pypy-c-39374-gc=framework--objspace-std-withmultidict--prof_richards' +p482 +F3100.0500000000002 +sS'./pypy-c-35979_pystone' +p483 +F6329.1099999999997 +sS'./pypy-c-36136-gc=framework--objspace-std-withstrdict--prof_pystone' +p484 +F10080.6 +sS'./pypy-c-35979_richards' +p485 +F5697.5299999999997 +sS'./pypy-c-39247-objspace-std-withmultidict--prof_pystone' +p486 +F10121.5 +sS'./pypy-llvm-35824-objspace-std-withstrdict-c-prof_richards' +p487 +F2576.2399999999998 +sS'./pypy-c-36395-stackless--objspace-std-withstrdict--prof_pystone' +p488 +F7923.9300000000003 +sS'./pypy-cli-36344_richards' +p489 +F47873.358011245698 +sS'./pypy-c-39072-faassen_richards' +p490 +F2202.7800000000002 +sS'./pypy-cli-38529_pystone' +p491 +F99999.0 +sS'./pypy-cli-37084_richards' +p492 +F48448.585033416697 +sS'./pypy-c-39188-stackless--objspace-std-withmultidict--prof_pystone' +p493 +F8771.9300000000003 +sS'./pypy-c-39348-stackless--objspace-std-withmultidict--prof_pystone' +p494 +F9276.4400000000005 +sS'./pypy-llvm-39147-faassen-x86_pystone' +p495 +F15015.0 +sS'./pypy-c-38651_richards' +p496 +F4816.8599999999997 +sS'./pypy-llvm-35771-objspace-std-withstrdict-x86_richards' +p497 +F2855.1399999999999 +sS'./pypy-c-35968-objspace-std-withstrdict--prof_pystone' +p498 +F9746.5900000000001 +sS'./pypy-c-39547-objspace-std-withmultidict--prof_pystone' +p499 +F10142.0 +sS'./pypy-c-35713-stackless--objspace-std-withstrdict--prof_richards' +p500 +F3397.3600000000001 +sS'./pypy-c-35867-objspace-std-withstrdict--prof_richards' +p501 +F3313.5799999999999 +sS'./pypy-c-39348-objspace-std-withmultidict--prof_pystone' +p502 +F10080.6 +sS'./pypy-llvm-39188-faassen-c_richards' +p503 +F1915.1700000000001 +sS'./pypy-c-37243_pystone' +p504 +F6666.6700000000001 +sS'./pypy-c-36893-gc=framework--objspace-std-withstrdict--prof_richards' +p505 +F3436.6799999999998 +sS'./pypy-llvm-39072-faassen-x86_richards' +p506 +F1853.1199999999999 +sS'./pypy-c-38769-faassen_richards' +p507 +F2202.1500000000001 +sS'./pypy-c-36100-stackless--objspace-std-withstrdict--prof_richards' +p508 +F3277.9099999999999 +sS'./pypy-llvm-35837-objspace-std-withstrdict-x86_pystone' +p509 +F10869.6 +sS'./pypy-c-35463-objspace-std-withstrdict--prof_richards' +p510 +F3555.54 +sS'./pypy-c-35982_richards' +p511 +F5224.9799999999996 +sS'./pypy-c-37111_pystone' +p512 +F6553.0799999999999 +sS'./pypy-c-35212_pystone' +p513 +F6468.3100000000004 +sS'./pypy-c-38994-faassen_pystone' +p514 +F13262.6 +sS'./pypy-c-35065-gc=framework--objspace-std-withstrdict--prof_pystone' +p515 +F9074.4099999999999 +sS'./pypy-llvm-34632-objspace-std-withstrdict-c-prof_richards' +p516 +F3454.2800000000002 +sS'./pypy-llvm-39218-faassen-c_richards' +p517 +F1839.23 +sS'./pypy-c-35095-gc=framework--objspace-std-withstrdict--prof_pystone' +p518 +F9157.5100000000002 +sS'./pypy-c-36446-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p519 +F3171.1100000000001 +sS'./pypy-llvm-34948-objspace-std-withstrdict-c_pystone' +p520 +F9107.4699999999993 +sS'./pypy-c-37503-stackless--objspace-std-withstrdict--prof_richards' +p521 +F4067.5100000000002 +sS'./pypy-c-35557-gc=framework--objspace-std-withstrdict--prof_pystone' +p522 +F10040.200000000001 +sS'./pypy-c-37243-gc=framework--objspace-std-withstrdict--prof_pystone' +p523 +F9784.7399999999998 +sS'./pypy-cli-36100_pystone' +p524 +F553.47692377038697 +sS'./pypy-c-36790-objspace-std-withstrdict--prof_richards' +p525 +F3281.5599999999999 +sS'./pypy-c-39646-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p526 +F10162.6 +sS'./pypy-c-37367-stackless--objspace-std-withstrdict--prof_pystone' +p527 +F8460.2399999999998 +sS'./pypy-llvm-39188-faassen-c_pystone' +p528 +F15197.6 +sS'./pypy-c-38529-gc=framework--objspace-std-withstrdict--prof_richards' +p529 +F3022.0100000000002 +sS'./pypy-llvm-35906-objspace-std-withstrdict-c_richards' +p530 +F2767.25 +sS'./pypy-llvm-35713-objspace-std-withstrdict-c_richards' +p531 +F2876.7399999999998 +sS'./pypy-cli-39324_pystone' +p532 +F638.15736095179705 +sS'./pypy-c-35183-gc=framework--objspace-std-withstrdict--prof_richards' +p533 +F3775.6999999999998 +sS'./pypy-c-36052-stackless--objspace-std-withstrdict--prof_pystone' +p534 +F6009.6199999999999 +sS'./pypy-c-37575-objspace-std-withstrdict--prof_richards' +p535 +F2979.5999999999999 +sS'./pypy-c-34882-stackless--objspace-std-withstrdict--prof_pystone' +p536 +F7267.4399999999996 +sS'./pypy-c-36893-gc=framework--objspace-std-withstrdict--prof_pystone' +p537 +F9842.5200000000004 +sS'./pypy-c-35411_pystone' +p538 +F6476.6800000000003 +sS'./pypy-c-37782-objspace-std-withstrdict--prof_pystone' +p539 +F10162.6 +sS'./pypy-cli-39072_pystone' +p540 +F653.285225060941 +sS'./pypy-c-36052-gc=framework--objspace-std-withstrdict--prof_richards' +p541 +F4939.9499999999998 +sS'./pypy-c-37575-objspace-std-withstrdict--prof_pystone' +p542 +F10204.1 +sS'./pypy-cli-35544_pystone' +p543 +F479.25493723883397 +sS'./pypy-c-35906-gc=framework--objspace-std-withstrdict--prof_richards' +p544 +F3480.73 +sS'./pypy-c-38769-objspace-std-withstrdict--prof_richards' +p545 +F2900.6900000000001 +sS'./pypy-c-36859-stackless--objspace-std-withstrdict--prof_richards' +p546 +F3815.6100000000001 +sS'./pypy-c-37782_richards' +p547 +F5572.71 +sS'./pypy-llvm-39474-faassen-c-prof_pystone' +p548 +F17482.5 +sS'./pypy-cli-36859_richards' +p549 +F48998.996973037698 +sS'./pypy-c-34976-stackless--objspace-std-withstrdict--prof_richards' +p550 +F4870.0699999999997 +sS'./pypy-llvm-35988-faassen-c-prof_pystone' +p551 +F15528.0 +sS'./pypy-c-39348-faassen_pystone' +p552 +F12853.5 +sS'./pypy-llvm-39374-faassen-x86_pystone' +p553 +F14705.9 +sS'./pypy-c-39374_richards' +p554 +F5105.4799999999996 +sS'./pypy-cli-39474_richards' +p555 +F45988.880872726397 +sS'./pypy-c-37503_pystone' +p556 +F7002.8000000000002 +sS'./pypy-c-36082-objspace-std-withstrdict--prof_pystone' +p557 +F9940.3600000000006 +sS'./pypy-c-37044-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p558 +F10204.1 +sS'./pypy-llvm-35143-objspace-std-withstrdict-x86_richards' +p559 +F99999.0 +sS'./pypy-cli-35979_richards' +p560 +F49869.193077087402 +sS'./pypy-cli-36009_richards' +p561 +F50453.392982482903 +sS'./pypy-c-36446_richards' +p562 +F5466.5299999999997 +sS'./pypy-llvm-36539-faassen-c_pystone' +p563 +F14450.9 +sS'./pypy-c-35350-stackless--objspace-std-withstrdict--prof_richards' +p564 +F3879.1100000000001 +sS'./pypy-c-35557-gc=framework--objspace-std-withstrdict--prof_richards' +p565 +F3436.79 +sS'./pypy-c-37243-stackless--objspace-std-withstrdict--prof_pystone' +p566 +F8726.0 +sS'./pypy-llvm-36082-faassen-x86_richards' +p567 +F2725.0100000000002 +sS'./pypy-c-35609-objspace-std-withstrdict--prof_pystone' +p568 +F10460.299999999999 +sS'./pypy-c-35544-objspace-std-withstrdict--prof_pystone' +p569 +F10142.0 +sS'./pypy-c-35979-objspace-std-withstrdict--prof_richards' +p570 +F3270.6399999999999 +sS'./pypy-c-38529_pystone' +p571 +F99999.0 +sS'./pypy-c-36395_pystone' +p572 +F6493.5100000000002 +sS'./pypy-llvm-35988-faassen-x86_richards' +p573 +F2575.4299999999998 +sS'./pypy-cli-39374_richards' +p574 +F46781.165838241599 +sS'./pypy-c-37415-faassen_richards' +p575 +F2910.1599999999999 +sS'./pypy-c-39188_richards' +p576 +F4330.8000000000002 +sS'./pypy-c-39147-objspace-std-withfastslice_richards' +p577 +F4222.4300000000003 +sS'./pypy-c-35867-gc=framework--objspace-std-withstrdict--prof_richards' +p578 +F3266.4899999999998 +sS'./pypy-c-36066-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p579 +F4867.96 +sS'./pypy-c-36158_richards' +p580 +F5231.54 +sS'./pypy-c-36100_pystone' +p581 +F6775.0699999999997 +sS'./pypy-c-36113-gc=framework--objspace-std-withstrdict--prof_richards' +p582 +F3212.4499999999998 +sS'./pypy-c-36220-stackless--objspace-std-withstrdict--prof_pystone' +p583 +F9009.0100000000002 +sS'./pypy-llvm-39348-faassen-x86_richards' +p584 +F2045.3699999999999 +sS'./pypy-c-38140-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p585 +F10330.6 +sS'./pypy-c-39374-objspace-std-withfastslice_richards' +p586 +F5060.9899999999998 +sS'./pypy-c-39348-objspace-std-withfastslice_pystone' +p587 +F6640.1099999999997 +sS'./pypy-c-39072-gc=framework--objspace-std-withmultidict--prof_richards' +p588 +F3109.8400000000001 +sS'./pypy-c-36893-stackless--objspace-std-withstrdict--prof_richards' +p589 +F3829.6999999999998 +sS'./pypy-c-38870-objspace-std-withstrdict--prof_pystone' +p590 +F10395.0 +sS'./pypy-cli-36066_richards' +p591 +F50349.507093429602 +sS'./pypy-c-35065-stackless--objspace-std-withstrdict--prof_pystone' +p592 +F7974.4799999999996 +sS'./pypy-c-34593-stackless_pystone' +p593 +F5500.5500000000002 +sS'./pypy-c-37310-faassen_pystone' +p594 +F10893.200000000001 +sS'./pypy-c-36082-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p595 +F9881.4200000000001 +sS'./pypy-c-36539-stackless--objspace-std-withstrdict--prof_pystone' +p596 +F8865.25 +sS'./pypy-c-34882-objspace-std-withstrdict--prof_richards' +p597 +F3543.1799999999998 +sS'./pypy-cli-35867_richards' +p598 +F63281.657934188799 +sS'./pypy-llvm-39147-faassen-c-prof_richards' +p599 +F1625.46 +sS'./pypy-c-37415-stackless--objspace-std-withstrdict--prof_richards' +p600 +F3720.52 +sS'./pypy-cli-35982_pystone' +p601 +F656.03663392536498 +sS'./pypy-llvm-34976-objspace-std-withstrdict-c-prof_pystone' +p602 +F9140.7700000000004 +sS'./pypy-c-39646-objspace-std-withfastslice_richards' +p603 +F4266.9200000000001 +sS'./pypy-cli-37367_richards' +p604 +F48221.861124038704 +sS'./pypy-cli-35963_richards' +p605 +F50861.653089523301 +sS'./pypy-llvm-35713-objspace-std-withstrdict-x86_pystone' +p606 +F11363.6 +sS'./pypy-c-35183-objspace-std-withstrdict--prof_pystone' +p607 +F9124.0900000000001 +sS'./pypy-c-39348-gc=framework--objspace-std-withmultidict--prof_richards' +p608 +F3162.8000000000002 +sS'./pypy-llvm-35713-objspace-std-withstrdict-c-prof_pystone' +p609 +F12953.4 +sS'./pypy-c-39072-objspace-std-withmultidict--prof_pystone' +p610 +F9980.0400000000009 +sS'./pypy-cli-39188_richards' +p611 +F46943.6841011047 +sS'./pypy-cli-35988_pystone' +p612 +F668.81363870454504 +sS'./pypy-c-39188-objspace-std-withfastslice_richards' +p613 +F4453.8500000000004 +sS'./pypy-c-35979-gc=framework--objspace-std-withstrdict--prof_richards' +p614 +F3487.8699999999999 +sS'./pypy-llvm-35867-objspace-std-withstrdict-c_pystone' +p615 +F12106.5 +sS'./pypy-c-35771-objspace-std-withstrdict--prof_pystone' +p616 +F9708.7399999999998 +sS'./pypy-llvm-36539-faassen-x86_pystone' +p617 +F13020.799999999999 +sS'./pypy-llvm-39646-faassen-c_pystone' +p618 +F15974.4 +sS'./pypy-c-35512_richards' +p619 +F5288.9799999999996 +sS'./pypy-c-36030-gc=framework--objspace-std-withstrdict--prof_pystone' +p620 +F10080.6 +sS'./pypy-c-35010-objspace-std-withstrdict--prof_richards' +p621 +F4502.8599999999997 +sS'./pypy-c-36009-stackless--objspace-std-withstrdict--prof_pystone' +p622 +F8944.5400000000009 +sS'./pypy-c-36136_pystone' +p623 +F6675.5699999999997 +sS'./pypy-llvm-35982-faassen-c_pystone' +p624 +F13888.9 +sS'./pypy-llvm-39302-faassen-x86_richards' +p625 +F1805.3599999999999 +sS'./pypy-c-39247-objspace-std-withfastslice_pystone' +p626 +F6729.4799999999996 +sS'./pypy-c-35923-stackless--objspace-std-withstrdict--prof_pystone' +p627 +F8196.7199999999993 +sS'./pypy-c-37415-stackless--objspace-std-withstrdict--prof_pystone' +p628 +F8818.3400000000001 +sS'./pypy-c-37310-objspace-std-withstrdict--prof_pystone' +p629 +F9823.1800000000003 +sS'./pypy-llvm-36539-faassen-c-prof_richards' +p630 +F2043.9300000000001 +sS'./pypy-c-39147-gc=framework--objspace-std-withmultidict--prof_pystone' +p631 +F10615.700000000001 +sS'./pypy-c-35837_pystone' +p632 +F6811.9899999999998 +sS'./pypy-llvm-35713-objspace-std-withstrdict-c-prof_richards' +p633 +F2577.8699999999999 +sS'./pypy-cli-39474_pystone' +p634 +F656.21334556304998 +sS'./pypy-cli-38870_pystone' +p635 +F651.79444681820701 +sS'./pypy-c-35212-objspace-std-withstrdict--prof_pystone' +p636 +F9242.1399999999994 +sS'./pypy-c-39324-objspace-std-withfastslice_richards' +p637 +F4767.7600000000002 +sS'./pypy-llvm-36030-faassen-x86_pystone' +p638 +F12658.200000000001 +sS'./pypy-llvm-35065-objspace-std-withstrdict-c_pystone' +p639 +F99999.0 +sS'./pypy-c-36113-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p640 +F3253.3499999999999 +sS'./pypy-c-39188-faassen_pystone' +p641 +F12886.6 +sS'./pypy-c-36175-stackless--objspace-std-withstrdict--prof_pystone' +p642 +F8403.3600000000006 +sS'./pypy-c-35867-objspace-std-withstrdict--prof_pystone' +p643 +F9823.1800000000003 +sS'./pypy-c-39302-objspace-std-withmultidict--prof_richards' +p644 +F2994.6999999999998 +sS'./pypy-c-37707-objspace-std-withstrdict--prof_pystone' +p645 +F10060.4 +sS'./pypy-c-39247-stackless--objspace-std-withmultidict--prof_richards' +p646 +F3167.5500000000002 +sS'./pypy-c-37782-gc=framework--objspace-std-withstrdict--prof_pystone' +p647 +F10309.299999999999 +sS'./pypy-c-36182-objspace-std-withstrdict--prof_richards' +p648 +F2983.71 +sS'./pypy-c-35350-objspace-std-withstrdict--prof_richards' +p649 +F3575.9099999999999 +sS'./pypy-c-38334-objspace-std-withfastslice_pystone' +p650 +F6622.5200000000004 +sS'./pypy-c-38870-gc=framework--objspace-std-withstrdict--prof_richards' +p651 +F2979.1900000000001 +sS'./pypy-c-39188-objspace-std-withfastslice_pystone' +p652 +F7215.0100000000002 +sS'./pypy-llvm-35944-faassen-c-prof_richards' +p653 +F2158.1500000000001 +sS'./pypy-c-39547-stackless--objspace-std-withmultidict--prof_richards' +p654 +F3307.5999999999999 +sS'./pypy-llvm-39348-faassen-c-prof_richards' +p655 +F1625.45 +sS'./pypy-c-36220-gc=framework--objspace-std-withstrdict--prof_richards' +p656 +F3424.8600000000001 +sS'./pypy-c-36030-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p657 +F3399.9499999999998 +sS'./pypy-c-39218-faassen_pystone' +p658 +F12787.700000000001 +sS'./pypy-c-36158-objspace-std-withstrdict--prof_richards' +p659 +F3205.75 +sS'./pypy-c-39302_richards' +p660 +F4666.1000000000004 +sS'./pypy-c-37575-stackless--objspace-std-withstrdict--prof_pystone' +p661 +F8912.6599999999999 +sS'./pypy-c-37415_pystone' +p662 +F6535.9499999999998 +sS'./pypy-c-35824-gc=framework--objspace-std-withstrdict--prof_pystone' +p663 +F10162.6 +sS'./pypy-c-37454_pystone' +p664 +F7112.3800000000001 +sS'./pypy-c-38870-stackless--objspace-std-withstrdict--prof_richards' +p665 +F3208.2199999999998 +sS'./pypy-c-38651-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p666 +F10683.799999999999 +sS'./pypy-llvm-36030-faassen-c-prof_pystone' +p667 +F14881.0 +sS'./pypy-cli-36136_pystone' +p668 +F558.04538665720395 +sS'./pypy-c-35824_richards' +p669 +F5440.1099999999997 +sS'./pypy-c-39147_richards' +p670 +F4713.0799999999999 +sS'./pypy-c-39646-objspace-std-withmultidict--prof_richards' +p671 +F2855.9099999999999 +sS'./pypy-c-39188-gc=framework--objspace-std-withmultidict--prof_pystone' +p672 +F10729.6 +sS'./pypy-c-36446_pystone' +p673 +F6561.6800000000003 +sS'./pypy-c-36066_pystone' +p674 +F4537.21 +sS'./pypy-c-34948-gc=framework--objspace-std-withstrdict--prof_richards' +p675 +F4322.0 +sS'./pypy-llvm-39188-faassen-c-prof_richards' +p676 +F1689.3900000000001 +sS'./pypy-c-35963-objspace-std-withstrdict--prof_richards' +p677 +F3334.3299999999999 +sS'./pypy-c-37111_richards' +p678 +F5532.1300000000001 +sS'./pypy-c-36158-objspace-std-withstrdict--prof_pystone' +p679 +F10000.0 +sS'./pypy-c-35979-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p680 +F3195.5 +sS'./pypy-c-34976-objspace-std-withstrdict--prof_richards' +p681 +F4405.3699999999999 +sS'./pypy-c-39374-objspace-std-withmultidict--prof_richards' +p682 +F2967.73 +sS'./pypy-c-36066-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p683 +F6983.2399999999998 +sS'./pypy-cli-35713~_pystone' +p684 +F99999.0 +sS'./pypy-c-35095-objspace-std-withstrdict--prof_pystone' +p685 +F9124.0900000000001 +sS'./pypy-c-39072-stackless--objspace-std-withmultidict--prof_richards' +p686 +F2948.3600000000001 +sS'./pypy-c-36220-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p687 +F10288.1 +sS'./pypy-llvm-35944-faassen-c-prof_pystone' +p688 +F15576.299999999999 +sS'./pypy-c-37503-stackless--objspace-std-withstrdict--prof_pystone' +p689 +F8183.3100000000004 +sS'./pypy-c-35143-stackless--objspace-std-withstrdict--prof_pystone' +p690 +F8130.0799999999999 +sS'./pypy-c-36344-stackless--objspace-std-withstrdict--prof_richards' +p691 +F3682.96 +sS'./pypy-llvm-39547-faassen-c-prof_richards' +p692 +F1458.8599999999999 +sS'./pypy-llvm-35713-objspace-std-withstrdict-c_pystone' +p693 +F11547.299999999999 +sS'./pypy-c-37647-stackless--objspace-std-withstrdict--prof_richards' +p694 +F3425.5100000000002 +sS'./pypy-c-36182-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p695 +F3129.29 +sS'./pypy-c-36030-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p696 +F9328.3600000000006 +sS'./pypy-c-39474_pystone' +p697 +F7278.0200000000004 +sS'./pypy-c-35771_pystone' +p698 +F6784.2600000000002 +sS'./pypy-c-35944-gc=framework--objspace-std-withstrdict--prof_pystone' +p699 +F10373.4 +sS'./pypy-c-36859-stackless--objspace-std-withstrdict--prof_pystone' +p700 +F8710.7999999999993 +sS'./pypy-c-34948-gc=framework--objspace-std-withstrdict--prof_pystone' +p701 +F7462.6899999999996 +sS'./pypy-c-39072_pystone' +p702 +F7352.9399999999996 +sS'./pypy-llvm-36082-faassen-c_pystone' +p703 +F13812.200000000001 +sS'./pypy-c-35065_richards' +p704 +F5242.0900000000001 +sS'./pypy-cli-35463_richards' +p705 +F69375.231981277495 +sS'./pypy-c-37782-faassen_richards' +p706 +F2790.71 +sS'./pypy-c-37163-stackless--objspace-std-withstrdict--prof_pystone' +p707 +F8680.5599999999995 +sS'./pypy-llvm-35988-faassen-c_richards' +p708 +F2308.7199999999998 +sS'./pypy-c-36893-objspace-std-withstrdict--prof_richards' +p709 +F3275.6700000000001 +sS'./pypy-llvm-34976-objspace-std-withstrdict-x86_richards' +p710 +F3691.8699999999999 +sS'./pypy-c-37044-gc=framework--objspace-std-withstrdict--prof_richards' +p711 +F3627.0799999999999 +sS'./pypy-c-39646-faassen_richards' +p712 +F2050.4499999999998 +sS'./pypy-c-39617-objspace-std-withmultidict--prof_richards' +p713 +F3019.8499999999999 +sS'./pypy-c-35771-gc=framework--objspace-std-withstrdict--prof_richards' +p714 +F3458.5 +sS'2.3.5_pystone' +p715 +F36231.900000000001 +sS'./pypy-c-37707-gc=framework--objspace-std-withstrdict--prof_pystone' +p716 +F10288.1 +sS'./pypy-llvm-36009-faassen-c_richards' +p717 +F2368.0599999999999 +sS'./pypy-c-39188-gc=framework--objspace-std-withmultidict--prof_richards' +p718 +F3060.2800000000002 +sS'./pypy-c-38529-faassen_richards' +p719 +F2689.9400000000001 +sS'./pypy-c-36158-stackless--objspace-std-withstrdict--prof_pystone' +p720 +F8503.3999999999996 +sS'./pypy-c-35906_pystone' +p721 +F6510.4200000000001 +sS'./pypy-cli-37707_pystone' +p722 +F694.96980300608402 +sS'./pypy-llvm-35982-faassen-c-prof_richards' +p723 +F2304.1900000000001 +sS'./pypy-c-36082-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p724 +F3108.6799999999998 +sS'./pypy-llvm-34632-objspace-std-withstrdict-c_pystone' +p725 +F9652.5100000000002 +sS'./pypy-llvm-35979-faassen-c_pystone' +p726 +F13513.5 +sS'./pypy-llvm-39218-faassen-c-prof_richards' +p727 +F1640.5 +sS'./pypy-llvm-39218-faassen-x86_pystone' +p728 +F15432.1 +sS'./pypy-cli-35658_pystone' +p729 +F482.51465795090797 +sS'./pypy-llvm-35143-objspace-std-withstrdict-c-prof_richards' +p730 +F99999.0 +sS'./pypy-c-36182-gc=framework--objspace-std-withstrdict--prof_richards' +p731 +F3535.5799999999999 +sS'./pypy-c-35143-objspace-std-withstrdict--prof_richards' +p732 +F3493.1900000000001 +sS'./pypy-llvm-36113-faassen-c-prof_richards' +p733 +F2193.0999999999999 +sS'./pypy-c-39547-stackless--objspace-std-withmultidict--prof_pystone' +p734 +F9174.3099999999995 +sS'./pypy-c-35557-objspace-std-withstrdict--prof_pystone' +p735 +F10482.200000000001 +sS'./pypy-llvm-38870-faassen-c-prof_richards' +p736 +F1727.5999999999999 +sS'./pypy-c-35217_pystone' +p737 +F6518.8999999999996 +sS'./pypy-c-35824_pystone' +p738 +F6596.3100000000004 +sS'./pypy-cli-37575_richards' +p739 +F47255.622148513801 +sS'./pypy-c-37782-stackless--objspace-std-withstrdict--prof_richards' +p740 +F3593.3099999999999 +sS'./pypy-llvm-36175-faassen-c-prof_pystone' +p741 +F15674.0 +sS'./pypy-c-34927-gc=framework--objspace-std-withstrdict--prof_richards' +p742 +F4362.1000000000004 +sS'./pypy-c-36977-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p743 +F3050.6799999999998 +sS'./pypy-llvm-38769-faassen-c_richards' +p744 +F1816.1400000000001 +sS'./pypy-c-35217_richards' +p745 +F5250.5100000000002 +sS'./pypy-c-34882-gc=framework--objspace-std-withstrdict--prof_pystone' +p746 +F9025.2700000000004 +sS'./pypy-c-34976-objspace-std-withstrdict--prof_pystone' +p747 +F7299.2700000000004 +sS'./pypy-llvm-36066-faassen-c-prof_pystone' +p748 +F10504.200000000001 +sS'./pypy-c-37367_pystone' +p749 +F6631.3000000000002 +sS'./pypy-c-35217-objspace-std-withstrdict--prof_richards' +p750 +F3476.5 +sS'./pypy-c-34593-thread--objspace-std-withstrdict--prof_pystone' +p751 +F8319.4699999999993 +sS'./pypy-c-39348_richards' +p752 +F4958.6000000000004 +sS'./pypy-cli-37782_pystone' +p753 +F701.57543253458402 +sS'./pypy-llvm-35143-objspace-std-withstrdict-x86_pystone' +p754 +F99999.0 +sS'./pypy-llvm-38769-faassen-c-prof_pystone' +p755 +F17006.799999999999 +sS'./pypy-c-36182-stackless--objspace-std-withstrdict--prof_richards' +p756 +F3610.8499999999999 +sS'./pypy-c-35544-objspace-std-withstrdict--prof_richards' +p757 +F3097.4099999999999 +sS'./pypy-llvm-35963-faassen-c-prof_pystone' +p758 +F14326.6 +sS'./pypy-cli-37575_pystone' +p759 +F699.513018622799 +sS'./pypy-c-36628_pystone' +p760 +F6613.7600000000002 +sS'./pypy-llvm-36113-faassen-x86_pystone' +p761 +F13123.4 +sS'./pypy-c-39147-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p762 +F2681.6599999999999 +sS'./pypy-cli-36539_richards' +p763 +F54847.146987915003 +sS'./pypy-c-34927-stackless--objspace-std-withstrdict--prof_richards' +p764 +F5014.8000000000002 +sS'./pypy-cli-36158_richards' +p765 +F62707.854032516501 +sS'./pypy-llvm-39218-faassen-x86_richards' +p766 +F1848.98 +sS'./pypy-c-37163_pystone' +p767 +F6915.6300000000001 +sS'./pypy-c-35982-gc=framework--objspace-std-withstrdict--prof_richards' +p768 +F3483.2600000000002 +sS'./pypy-c-39188-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p769 +F2938.8899999999999 +sS'./pypy-c-35963-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p770 +F2929.3499999999999 +sS'./pypy-c-36175-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p771 +F2909.9499999999998 +sS'./pypy-c-38651-gc=framework--objspace-std-withstrdict--prof_pystone' +p772 +F10706.6 +sS'./pypy-cli-39072_richards' +p773 +F47044.425010681203 +sS'./pypy-c-36066-stackless--objspace-std-withstrdict--prof_pystone' +p774 +F5931.1999999999998 +sS'./pypy-c-37310_pystone' +p775 +F6993.0100000000002 +sS'./pypy-c-unknown_richards' +p776 +F6920.8699999999999 +sS'./pypy-llvm-35906-objspace-opcodes-CALL_LIKELY_BUILTIN-c-prof_pystone' +p777 +F12376.200000000001 +sS'./pypy-c-36182-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p778 +F10245.9 +sS'./pypy-c-39302_pystone' +p779 +F7012.6199999999999 +sS'./pypy-llvm-36030-faassen-c_richards' +p780 +F2345.2199999999998 +sS'./pypy-c-35237_richards' +p781 +F5593.79 +sS'./pypy-c-35350-objspace-std-withstrdict--prof_pystone' +p782 +F8912.6599999999999 +sS'./pypy-c-35923-objspace-std-withstrdict--prof_pystone' +p783 +F9784.7399999999998 +sS'./pypy-llvm-39348-faassen-c-prof_pystone' +p784 +F18181.799999999999 +sS'./pypy-llvm-34948-objspace-std-withstrdict-c-prof_pystone' +p785 +F9765.6200000000008 +sS'./pypy-c-37782-faassen_pystone' +p786 +F11627.9 +sS'./pypy-c-35183_pystone' +p787 +F6361.3199999999997 +sS'./pypy-c-39348-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p788 +F10752.700000000001 +sS'./pypy-c-34927-gc=framework--objspace-std-withstrdict--prof_pystone' +p789 +F7633.5900000000001 +sS'./pypy-cli-35867_pystone' +p790 +F554.44990851133002 +sS'./pypy-cli-39218_richards' +p791 +F46355.895042419397 +sS'./pypy-llvm-35867-objspace-std-withstrdict-x86_richards' +p792 +F2854.5900000000001 +sS'./pypy-c-36539_pystone' +p793 +F6765.8999999999996 +sS'./pypy-llvm-35944-faassen-x86_pystone' +p794 +F13812.200000000001 +sS'./pypy-llvm-36052-faassen-x86_pystone' +p795 +F9578.5400000000009 +sS'./pypy-c-39324-objspace-std-withmultidict--prof_pystone' +p796 +F9920.6299999999992 +sS'./pypy-c-38529_richards' +p797 +F99999.0 +sS'./pypy-c-38334_pystone' +p798 +F6468.3100000000004 +sS'./pypy-c-36893_pystone' +p799 +F6963.79 +sS'./pypy-llvm-35095-objspace-std-withstrdict-c_richards' +p800 +F99999.0 +sS'./pypy-c-36790-gc=framework--objspace-std-withstrdict--prof_pystone' +p801 +F9487.6700000000001 +sS'./pypy-c-36344-gc=framework--objspace-std-withstrdict--prof_pystone' +p802 +F10060.4 +sS'./pypy-c-38870-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p803 +F2899.79 +sS'./pypy-llvm-39218-faassen-c_pystone' +p804 +F15822.799999999999 +sS'./pypy-c-35979-stackless--objspace-std-withstrdict--prof_pystone' +p805 +F9363.2999999999993 +sS'./pypy-llvm-34948-objspace-std-withstrdict-c-prof_richards' +p806 +F3353.9000000000001 +sS'./pypy-c-39547-objspace-std-withmultidict--prof_richards' +p807 +F3006.9699999999998 +sS'./pypy-c-36052-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p808 +F5048.7399999999998 +sS'./pypy-c-35906-stackless--objspace-std-withstrdict--prof_richards' +p809 +F3671.5 +sS'./pypy-c-38222-objspace-std-withfastslice_richards' +p810 +F5061.9300000000003 +sS'./pypy-c-39348-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p811 +F2823.4200000000001 +sS'./pypy-llvm-35968-faassen-c-prof_richards' +p812 +F2190.1900000000001 +sS'./pypy-c-39147-objspace-std-withfastslice_pystone' +p813 +F7396.4499999999998 +sS'./pypy-c-39218-objspace-std-withmultidict--prof_richards' +p814 +F2716.04 +sS'./pypy-c-39617-faassen_pystone' +p815 +F12048.200000000001 +sS'./pypy-c-39188-objspace-std-withmultidict--prof_pystone' +p816 +F10593.200000000001 +sS'./pypy-cli-38769_pystone' +p817 +F653.89305759517504 +sS'./pypy-c-37454-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p818 +F10142.0 +sS'./pypy-llvm-36175-faassen-c-prof_richards' +p819 +F2055.5100000000002 +sS'./pypy-llvm-39474-faassen-c_pystone' +p820 +F15060.200000000001 +sS'./pypy-c-37111-gc=framework--objspace-std-withstrdict--prof_richards' +p821 +F3153.7199999999998 +sS'./pypy-c-38651-gc=framework--objspace-std-withstrdict--prof_richards' +p822 +F3102.4099999999999 +sS'./pypy-c-36220-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p823 +F2995.5500000000002 +sS'./pypy-cli-36628_pystone' +p824 +F723.09658418429296 +sS'./pypy-llvm-38870-faassen-c_richards' +p825 +F1928.4400000000001 +sS'./pypy-c-35867_richards' +p826 +F5666.79 +sS'./pypy-c-37084-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p827 +F3176.0999999999999 +sS'./pypy-cli-35837_pystone' +p828 +F557.84531844103503 +sS'./pypy-c-39374-objspace-std-withfastslice_pystone' +p829 +F6265.6599999999999 +sS'2.4.4_pystone' +p830 +F44642.900000000001 +sS'./pypy-c-37243-faassen_richards' +p831 +F2822.25 +sS'./pypy-llvm-36182-faassen-x86_pystone' +p832 +F12722.6 +sS'./pypy-c-34927-stackless--objspace-std-withstrdict--prof_pystone' +p833 +F6410.2600000000002 +sS'./pypy-c-36859-gc=framework--objspace-std-withstrdict--prof_pystone' +p834 +F9765.6200000000008 +sS'./pypy-c-37707_pystone' +p835 +F6821.2799999999997 +sS'./pypy-llvm-35968-faassen-x86_richards' +p836 +F2533.1300000000001 +sS'./pypy-llvm-36446-faassen-c-prof_richards' +p837 +F2039.52 +sS'./pypy-llvm-35906-objspace-std-withstrdict-x86_richards' +p838 +F2974.9200000000001 +sS'./pypy-c-39218-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p839 +F2861.8000000000002 +sS'./pypy-llvm-38994-faassen-c-prof_pystone' +p840 +F17301.0 +sS'./pypy-c-35944-gc=framework--objspace-std-withstrdict--prof_richards' +p841 +F3164.7800000000002 +sS'./pypy-cli-38994_pystone' +p842 +F659.83510351255597 +sS'./pypy-c-34593-gc=framework--objspace-std-withstrdict--prof_pystone' +p843 +F9025.2700000000004 +sS'./pypy-c-36446-stackless--objspace-std-withstrdict--prof_richards' +p844 +F3770.46 +sS'./pypy-llvm-39617-faassen-x86_richards' +p845 +F1707.9100000000001 +sS'./pypy-c-35867-gc=framework--objspace-std-withstrdict--prof_pystone' +p846 +F10373.4 +sS'./pypy-llvm-36136-faassen-c-prof_pystone' +p847 +F15432.1 +sS'./pypy-c-38140-stackless--objspace-std-withstrdict--prof_richards' +p848 +F3375.25 +sS'./pypy-llvm-39474-faassen-x86_richards' +p849 +F1819.21 +sS'./pypy-cli-36009_pystone' +p850 +F666.51266669331801 +sS'./pypy-llvm-39617-faassen-x86_pystone' +p851 +F14881.0 +sS'./pypy-c-35095-stackless--objspace-std-withstrdict--prof_pystone' +p852 +F7716.0500000000002 +sS'./pypy-llvm-36220-faassen-c_richards' +p853 +F2348.9699999999998 +sS'./pypy-c-37367-stackless--objspace-std-withstrdict--prof_richards' +p854 +F3832.8400000000001 +sS'./pypy-c-34927-objspace-std-withstrdict--prof_pystone' +p855 +F7451.5600000000004 +sS'./pypy-c-38140-gc=framework--objspace-std-withstrdict--prof_richards' +p856 +F3314.8499999999999 +sS'./pypy-c-36182_richards' +p857 +F5161.0699999999997 +sS'./pypy-llvm-36175-faassen-c_richards' +p858 +F2227.9000000000001 +sS'./pypy-c-35095_pystone' +p859 +F6297.2299999999996 +sS'./pypy-c-36446-objspace-std-withstrdict--prof_pystone' +p860 +F9652.5100000000002 +sS'./pypy-c-35923_pystone' +p861 +F6468.3100000000004 +sS'./pypy-c-38994-objspace-std-withfastslice_richards' +p862 +F4294.7600000000002 +sS'./pypy-c-37503_richards' +p863 +F5047.9200000000001 +sS'./pypy-c-37310-gc=framework--objspace-std-withstrdict--prof_pystone' +p864 +F10080.6 +sS'./pypy-c-39218-stackless--objspace-std-withmultidict--prof_pystone' +p865 +F9293.6800000000003 +sS'./pypy-c-34593-objspace-std-withstrdict--prof_pystone' +p866 +F9380.8600000000006 +sS'./pypy-c-35212_richards' +p867 +F5357.6300000000001 +sS'./pypy-c-35658_pystone' +p868 +F6675.5699999999997 +sS'./pypy-c-36113-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p869 +F9578.5400000000009 +sS'./pypy-c-34948-objspace-std-withstrdict--prof_richards' +p870 +F4400.3599999999997 +sS'./pypy-c-37782-stackless--objspace-std-withstrdict--prof_pystone' +p871 +F8944.5400000000009 +sS'./pypy-cli-36066_pystone' +p872 +F669.040672748764 +sS'./pypy-c-35824-stackless--objspace-std-withstrdict--prof_pystone' +p873 +F8944.5400000000009 +sS'./pypy-llvm-34632-objspace-std-withstrdict-c_richards' +p874 +F3531.6900000000001 +sS'./pypy-c-35010-gc=framework--objspace-std-withstrdict--prof_richards' +p875 +F4655.5600000000004 +sS'./pypy-cli-38435_richards' +p876 +F50884.289026260398 +sS'./pypy-cli-39188_pystone' +p877 +F635.41038100185006 +sS'./pypy-cli-36446_pystone' +p878 +F676.036249658619 +sS'./pypy-c-36136_richards' +p879 +F5282.4899999999998 +sS'./pypy-c-39374-faassen_pystone' +p880 +F13054.799999999999 +sS'2.3.5_richards' +p881 +F973.13999999999999 +sS'./pypy-cli-36136_richards' +p882 +F63001.344919204697 +sS'./pypy-c-36628-gc=framework--objspace-std-withstrdict--prof_pystone' +p883 +F10060.4 +sS'./pypy-c-35963-gc=framework--objspace-std-withstrdict--prof_richards' +p884 +F3482.4299999999998 +sS'./pypy-c-39072-objspace-std-withmultidict--prof_richards' +p885 +F3039.5999999999999 +sS'./pypy-c-36220-objspace-std-withstrdict--prof_pystone' +p886 +F9980.0400000000009 +sS'./pypy-cli-37310_richards' +p887 +F48405.558109283404 +sS'./pypy-cli-37415_richards' +p888 +F48393.4779167175 +sS'./pypy-c-36136-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p889 +F9784.7399999999998 +sS'./pypy-c-36790-objspace-std-withstrdict--prof_pystone' +p890 +F9560.2299999999996 +sS'./pypy-cli-35775_pystone' +p891 +F480.36249768093001 +sS'./pypy-c-39617-gc=framework--objspace-std-withmultidict--prof_richards' +p892 +F3256.6500000000001 +sS'./pypy-c-35837-gc=framework--objspace-std-withstrdict--prof_pystone' +p893 +F10309.299999999999 +sS'./pypy-cli-36158_pystone' +p894 +F561.74309962359996 +sS'./pypy-c-unknown-stackless--objspace-std-withstrdict--prof_richards' +p895 +F5133.5200000000004 +sS'./pypy-llvm-35095-objspace-std-withstrdict-c-prof_richards' +p896 +F99999.0 +sS'./pypy-cli-38994_richards' +p897 +F46162.909030914299 +sS'./pypy-cli-35963_pystone' +p898 +F670.59309654181402 +sS'./pypy-cli-36539_pystone' +p899 +F615.53012291779498 +sS'./pypy-c-37454-gc=framework--objspace-std-withstrdict--prof_richards' +p900 +F3229.8099999999999 +sS'./pypy-c-38769-gc=framework--objspace-std-withstrdict--prof_richards' +p901 +F3058.1399999999999 +sS'./pypy-c-35968-gc=framework--objspace-std-withstrdict--prof_pystone' +p902 +F10142.0 +sS'./pypy-c-36182-gc=framework--objspace-std-withstrdict--prof_pystone' +p903 +F9861.9300000000003 +sS'./pypy-c-37310_richards' +p904 +F5191.1000000000004 +sS'./pypy-c-39147-stackless--objspace-std-withmultidict--prof_pystone' +p905 +F9487.6700000000001 +sS'./pypy-c-38334-objspace-std-withfastslice_richards' +p906 +F5204.3100000000004 +sS'./pypy-c-38870-faassen_pystone' +p907 +F12853.5 +sS'./pypy-c-39348-stackless--objspace-std-withmultidict--prof_richards' +p908 +F3207.6900000000001 +sS'./pypy-llvm-35824-objspace-std-withstrdict-x86_pystone' +p909 +F11494.299999999999 +sS'./pypy-c-38651-objspace-std-withstrdict--prof_pystone' +p910 +F11013.200000000001 +sS'./pypy-c-34882_pystone' +p911 +F6402.0500000000002 +sS'./pypy-c-38994_pystone' +p912 +F7299.2700000000004 +sS'./pypy-c-36009_pystone' +p913 +F6775.0699999999997 +sS'./pypy-c-36893-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p914 +F10121.5 +sS'./pypy-llvm-36182-faassen-c-prof_richards' +p915 +F2098.6999999999998 +sS'./pypy-c-38529-objspace-std-withfastslice_richards' +p916 +F4681.4499999999998 +sS'./pypy-c-39374-objspace-std-withmultidict--prof_pystone' +p917 +F10309.299999999999 +sS'./pypy-cli-36182_richards' +p918 +F62752.619981765703 +sS'./pypy-c-36859-objspace-std-withstrdict--prof_richards' +p919 +F3023.9899999999998 +sS'./pypy-c-36136-objspace-std-withstrdict--prof_richards' +p920 +F3248.25 +sS'./pypy-c-39547-gc=framework--objspace-std-withmultidict--prof_richards' +p921 +F3188.8400000000001 +sS'./pypy-llvm-36158-faassen-c_richards' +p922 +F2328.73 +sS'./pypy-c-35212-gc=framework--objspace-std-withstrdict--prof_pystone' +p923 +F9433.9599999999991 +sS'./pypy-c-37415_richards' +p924 +F5504.1300000000001 +sS'./pypy-cli-38222_richards' +p925 +F48951.274156570398 +sS'./pypy-c-36082-gc=framework--objspace-std-withstrdict--prof_richards' +p926 +F3530.3600000000001 +sS'./pypy-c-unknown-objspace-std-withstrdict--prof_pystone' +p927 +F7122.5100000000002 +sS'./pypy-c-34593-gc=framework_pystone' +p928 +F6195.79 +sS'./pypy-llvm-35963-faassen-x86_richards' +p929 +F2470.1900000000001 +sS'./pypy-cli-36052_pystone' +p930 +F99999.0 +sS'./pypy-c-35463_richards' +p931 +F5439.8299999999999 +sS'./pypy-c-39617-objspace-std-withmultidict--prof_pystone' +p932 +F10183.299999999999 +sS'./pypy-c-35237-objspace-std-withstrdict--prof_pystone' +p933 +F8802.8199999999997 +sS'./pypy-c-39348-faassen_richards' +p934 +F2237.5799999999999 +sS'./pypy-c-37044-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p935 +F3069.52 +sS'./pypy-c-38994-gc=framework--objspace-std-withmultidict--prof_richards' +p936 +F3169.6999999999998 +sS'./pypy-llvm-35988-faassen-c-prof_richards' +p937 +F2177.7199999999998 +sS'./pypy-c-36175-gc=framework--objspace-std-withstrdict--prof_richards' +p938 +F3539.3299999999999 +sS'./pypy-llvm-36158-faassen-x86_richards' +p939 +F2622.8000000000002 +sS'./pypy-c-36859-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p940 +F2948.8400000000001 +sS'./pypy-c-37163-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p941 +F3214.3000000000002 +sS'./pypy-c-36009-objspace-std-withstrdict--prof_pystone' +p942 +F9842.5200000000004 +sS'./pypy-llvm-36446-faassen-x86_richards' +p943 +F2516.48 +sS'./pypy-c-39474-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p944 +F2882.02 +sS'./pypy-llvm-36100-faassen-c_pystone' +p945 +F13774.1 +sS'./pypy-c-35277_pystone' +p946 +F6596.3100000000004 +sS'./pypy-c-37044_pystone' +p947 +F6596.3100000000004 +sS'./pypy-cli-38222_pystone' +p948 +F688.80053720931505 +sS'./pypy-llvm-36136-faassen-x86_pystone' +p949 +F13850.4 +sS'./pypy-llvm-34976-objspace-std-withstrdict-c-prof_richards' +p950 +F3683.3499999999999 +sS'./pypy-c-35095_richards' +p951 +F5528.5100000000002 +sS'./pypy-cli-39547_pystone' +p952 +F668.15960248245301 +sS'./pypy-c-36539_richards' +p953 +F5283.3999999999996 +sS'./pypy-llvm-35906-objspace-std-withstrdict-x86_pystone' +p954 +F11600.9 +sS'./pypy-c-38994-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p955 +F10288.1 +sS'./pypy-c-35095-stackless--objspace-std-withstrdict--prof_richards' +p956 +F4135.6999999999998 +sS'./pypy-c-35010-objspace-std-withstrdict--prof_pystone' +p957 +F7215.0100000000002 +sS'./pypy-c-39547_pystone' +p958 +F6944.4399999999996 +sS'./pypy-llvm-36100-faassen-c-prof_richards' +p959 +F2208.9400000000001 +sS'./pypy-c-36344-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p960 +F9900.9899999999998 +sS'./pypy-c-35968-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p961 +F3179.0 +sS'./pypy-cli-35944_pystone' +p962 +F650.47989935150497 +sS'./pypy-llvm-35923-objspace-std-withstrdict-x86_pystone' +p963 +F10775.9 +sS'./pypy-c-37084-objspace-std-withstrdict--prof_pystone' +p964 +F9861.9300000000003 +sS'./pypy-c-35411-stackless--objspace-std-withstrdict--prof_richards' +p965 +F3984.8499999999999 +sS'./pypy-llvm-39072-faassen-x86_pystone' +p966 +F15432.1 +sS'./pypy-c-36052-objspace-std-withstrdict--prof_pystone' +p967 +F6830.6000000000004 +sS'./pypy-llvm-39646-faassen-c-prof_richards' +p968 +F1472.21 +sS'./pypy-c-38994_richards' +p969 +F4539.2600000000002 +sS'./pypy-c-35237-objspace-std-withstrdict--prof_richards' +p970 +F3674.0900000000001 +sS'./pypy-llvm-38870-faassen-x86_pystone' +p971 +F14836.799999999999 +sS'./pypy-llvm-35923-objspace-std-withstrdict-c_richards' +p972 +F2581.3800000000001 +sS'./pypy-c-39247-gc=framework--objspace-std-withmultidict--prof_richards' +p973 +F3168.6199999999999 +sS'./pypy-c-35609_richards' +p974 +F5428.1199999999999 +sS'./pypy-c-34976-gc=framework--objspace-std-withstrdict--prof_pystone' +p975 +F7716.0500000000002 +sS'./pypy-c-35968-objspace-std-withstrdict--prof_richards' +p976 +F3279.73 +sS'./pypy-c-39547-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p977 +F2841.9699999999998 +sS'./pypy-c-36136-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p978 +F3240.3600000000001 +sS'./pypy-c-37503-faassen_pystone' +p979 +F11236.0 +sS'./pypy-c-35944_richards' +p980 +F5473.1899999999996 +sS'./pypy-c-39147_pystone' +p981 +F7352.9399999999996 +sS'./pypy-c-36066_richards' +p982 +F8355.2199999999993 +sS'./pypy-c-39617-stackless--objspace-std-withmultidict--prof_pystone' +p983 +F8896.7999999999993 +sS'./pypy-c-36113-objspace-std-withstrdict--prof_richards' +p984 +F3249.0300000000002 +sS'./pypy-llvm-39547-faassen-x86_pystone' +p985 +F15151.5 +sS'./pypy-c-35988_pystone' +p986 +F6830.6000000000004 +sS'./pypy-c-39247_pystone' +p987 +F6858.71 +sS'./pypy-c-38769-objspace-std-withfastslice_richards' +p988 +F4608.0299999999997 +sS'./pypy-c-37310-objspace-std-withstrdict--prof_richards' +p989 +F3026.2600000000002 +sS'./pypy-c-35183-objspace-std-withstrdict--prof_richards' +p990 +F3455.3499999999999 +sS'./pypy-c-35837-objspace-std-withstrdict--prof_richards' +p991 +F3350.3499999999999 +sS'./pypy-c-37243-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p992 +F3151.3000000000002 +sS'./pypy-llvm-35771-objspace-std-withstrdict-c_pystone' +p993 +F12437.799999999999 +sS'./pypy-cli-37647_richards' +p994 +F47033.993959426902 +sS'./pypy-c-35982-gc=framework--objspace-std-withstrdict--prof_pystone' +p995 +F10080.6 +sS'./pypy-c-35713-stackless--objspace-std-withstrdict--prof_pystone' +p996 +F9074.4099999999999 +sS'./pypy-c-34948_richards' +p997 +F6717.1499999999996 +sS'./pypy-cli-39348_richards' +p998 +F46597.933053970301 +sS'./pypy-cli-35557_pystone' +p999 +F479.65731132814 +sS'./pypy-c-38769-stackless--objspace-std-withstrdict--prof_pystone' +p1000 +F9276.4400000000005 +sS'./pypy-c-35065-objspace-std-withstrdict--prof_pystone' +p1001 +F9009.0100000000002 +sS'./pypy-c-34948-stackless--objspace-std-withstrdict--prof_pystone' +p1002 +F6377.5500000000002 +sS'./pypy-c-38222-objspace-std-withfastslice_pystone' +p1003 +F6738.54 +sS'./pypy-c-37111-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p1004 +F9823.1800000000003 +sS'./pypy-c-35923-gc=framework--objspace-std-withstrdict--prof_richards' +p1005 +F3322.9400000000001 +sS'./pypy-cli-37310_pystone' +p1006 +F689.84143911740898 +sS'./pypy-c-35658-gc=framework--objspace-std-withstrdict--prof_richards' +p1007 +F3365.1500000000001 +sS'./pypy-c-39474-objspace-std-withmultidict--prof_richards' +p1008 +F3015.77 +sS'./pypy-c-39302-objspace-std-withfastslice_pystone' +p1009 +F6711.4099999999999 +sS'./pypy-c-39247-stackless--objspace-std-withmultidict--prof_pystone' +p1010 +F9293.6800000000003 +sS'./pypy-llvm-39374-faassen-x86_richards' +p1011 +F1901.3 +sS'./pypy-llvm-35963-faassen-c_pystone' +p1012 +F13850.4 +sS'./pypy-c-37454_richards' +p1013 +F5119.8699999999999 +sS'./pypy-llvm-35906-objspace-opcodes-CALL_LIKELY_BUILTIN-x86_pystone' +p1014 +F10504.200000000001 +sS'./pypy-llvm-39617-faassen-c_pystone' +p1015 +F16611.299999999999 +sS'./pypy-cli-39147_pystone' +p1016 +F660.96968085805997 +sS'./pypy-llvm-38994-faassen-x86_richards' +p1017 +F2106.6399999999999 +sS'./pypy-c-35906_richards' +p1018 +F5447.8199999999997 +sS'./pypy-llvm-36175-faassen-x86_pystone' +p1019 +F12853.5 +sS'./pypy-llvm-36539-faassen-x86_richards' +p1020 +F2497.4499999999998 +sS'./pypy-c-37503-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p1021 +F3271.5999999999999 +sS'./pypy-c-37111-gc=framework--objspace-std-withstrdict--prof_pystone' +p1022 +F10309.299999999999 +sS'./pypy-llvm-35183-objspace-std-withstrdict-c-prof_pystone' +p1023 +F99999.0 +sS'./pypy-cli-38435_pystone' +p1024 +F643.511550897201 +sS'./pypy-c-38870-objspace-std-withfastslice_pystone' +p1025 +F7012.6199999999999 +sS'./pypy-c-35988-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p1026 +F10438.4 +sS'./pypy-c-35658-stackless--objspace-std-withstrdict--prof_richards' +p1027 +F3561.1199999999999 +sS'./pypy-c-35512-objspace-std-withstrdict--prof_pystone' +p1028 +F9259.2600000000002 +sS'./pypy-c-39247-objspace-std-withfastslice_richards' +p1029 +F4797.4300000000003 +sS'./pypy-c-37415-gc=framework--objspace-std-withstrdict--prof_pystone' +p1030 +F9920.6299999999992 +sS'./pypy-c-39474-gc=framework--objspace-std-withmultidict--prof_pystone' +p1031 +F10460.299999999999 +sS'./pypy-llvm-39188-faassen-x86_pystone' +p1032 +F14749.299999999999 +sS'./pypy-c-35944-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p1033 +F9746.5900000000001 +sS'./pypy-llvm-36220-faassen-c-prof_pystone' +p1034 +F15337.4 +sS'./pypy-c-35923-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p1035 +F10183.299999999999 +sS'./pypy-c-37111-objspace-std-withstrdict--prof_pystone' +p1036 +F9560.2299999999996 +sS'./pypy-c-35212-gc=framework--objspace-std-withstrdict--prof_richards' +p1037 +F3486.0900000000001 +sS'./pypy-c-39302-objspace-std-withfastslice_richards' +p1038 +F4839.2399999999998 +sS'./pypy-llvm-35010-objspace-std-withstrdict-c_pystone' +p1039 +F8741.2600000000002 +sS'./pypy-c-39646-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p1040 +F2925.0300000000002 +sS'./pypy-llvm-36082-faassen-c_richards' +p1041 +F2404.46 +sS'./pypy-c-36977-stackless--objspace-std-withstrdict--prof_pystone' +p1042 +F9074.4099999999999 +sS'./pypy-c-35512-objspace-std-withstrdict--prof_richards' +p1043 +F3395.9099999999999 +sS'./pypy-llvm-35867-objspace-std-withstrdict-c_richards' +p1044 +F2769.4000000000001 +sS'./pypy-cli-36446_richards' +p1045 +F49426.156044006297 +sS'./pypy-c-35557_richards' +p1046 +F5194.6999999999998 +sS'./pypy-c-36859-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p1047 +F10162.6 +sS'./pypy-c-36859-gc=framework--objspace-std-withstrdict--prof_richards' +p1048 +F3698.9400000000001 +sS'./pypy-c-35350-stackless--objspace-std-withstrdict--prof_pystone' +p1049 +F8143.3199999999997 +sS'./pypy-c-35143_richards' +p1050 +F5419.3299999999999 +sS'./pypy-c-37163-stackless--objspace-std-withstrdict--prof_richards' +p1051 +F3803.96 +sS'./pypy-c-37310-gc=framework--objspace-std-withstrdict--prof_richards' +p1052 +F3465.73 +sS'./pypy-c-37503-gc=framework--objspace-std-withstrdict--prof_pystone' +p1053 +F9900.9899999999998 +sS'./pypy-cli-39247_richards' +p1054 +F46365.128993988001 +sS'./pypy-c-39188-objspace-std-withmultidict--prof_richards' +p1055 +F3040.0799999999999 +sS'./pypy-c-35963-gc=framework--objspace-std-withstrdict--prof_pystone' +p1056 +F9960.1599999999999 +sS'./pypy-c-39302-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p1057 +F10752.700000000001 +sS'./pypy-cli-35463_pystone' +p1058 +F99999.0 +sS'./pypy-llvm-39247-faassen-x86_richards' +p1059 +F1920.6300000000001 +sS'./pypy-c-36100_richards' +p1060 +F5166.8599999999997 +sS'./pypy-c-39302-objspace-std-withmultidict--prof_pystone' +p1061 +F10142.0 +sS'./pypy-c-37707-objspace-std-withstrdict--prof_richards' +p1062 +F3237.46 +sS'./pypy-c-36175-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p1063 +F10416.700000000001 +sS'./pypy-c-34948_pystone' +p1064 +F5117.71 +sS'./pypy-llvm-39324-faassen-c_richards' +p1065 +F1826.02 +sS'./pypy-cli-38651_richards' +p1066 +F46635.348081588701 +sS'./pypy-c-36893_richards' +p1067 +F5125.1499999999996 +sS'./pypy-llvm-36446-faassen-c_pystone' +p1068 +F14367.799999999999 +sS'./pypy-cli-36175_pystone' +p1069 +F560.984338125097 +sS'./pypy-c-36100-gc=framework--objspace-std-withstrdict--prof_pystone' +p1070 +F10101.0 +sS'./pypy-c-37084-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p1071 +F10142.0 +sS'./pypy-llvm-35982-faassen-x86_pystone' +p1072 +F13054.799999999999 +sS'./pypy-llvm-35183-objspace-std-withstrdict-c-prof_richards' +p1073 +F99999.0 +sS'./pypy-c-36082-stackless--objspace-std-withstrdict--prof_pystone' +p1074 +F9276.4400000000005 +sS'./pypy-llvm-35906-objspace-opcodes-CALL_LIKELY_BUILTIN-c_richards' +p1075 +F2749.6399999999999 +sS'./pypy-c-38222_pystone' +p1076 +F6527.4200000000001 +sS'./pypy-c-35143-gc=framework--objspace-std-withstrdict--prof_pystone' +p1077 +F9380.8600000000006 +sS'./pypy-c-39247-gc=framework--objspace-std-withmultidict--prof_pystone' +p1078 +F10638.299999999999 +sS'./pypy-c-37454-objspace-std-withstrdict--prof_pystone' +p1079 +F9560.2299999999996 +sS'./pypy-c-35010-gc=framework--objspace-std-withstrdict--prof_pystone' +p1080 +F7374.6300000000001 +sS'./pypy-c-35982-objspace-std-withstrdict--prof_pystone' +p1081 +F9727.6299999999992 +sS'./pypy-cli-38140_richards' +p1082 +F48225.253105163603 +sS'./pypy-c-35010-stackless--objspace-std-withstrdict--prof_pystone' +p1083 +F6329.1099999999997 +sS'./pypy-llvm-39188-faassen-x86_richards' +p1084 +F1893.74 +sS'./pypy-c-38651-objspace-std-withfastslice_pystone' +p1085 +F7163.3199999999997 +sS'./pypy-c-39617-objspace-std-withfastslice_pystone' +p1086 +F6906.0799999999999 +sS'./pypy-llvm-39324-faassen-x86_pystone' +p1087 +F14662.799999999999 +sS'./pypy-llvm-39147-faassen-c_richards' +p1088 +F1846.5999999999999 +sS'./pypy-c-38529-objspace-std-withfastslice_pystone' +p1089 +F7153.0799999999999 +sS'./pypy-c-36113-objspace-std-withstrdict--prof_pystone' +p1090 +F9727.6299999999992 +sS'./pypy-c-35463-gc=framework--objspace-std-withstrdict--prof_richards' +p1091 +F3680.8499999999999 +sS'./pypy-llvm-35771-objspace-std-withstrdict-c_richards' +p1092 +F2654.6700000000001 +sS'./pypy-c-36628-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p1093 +F3376.9099999999999 +sS'./pypy-c-36790_pystone' +p1094 +F6973.5 +sS'./pypy-c-35277-gc=framework--objspace-std-withstrdict--prof_pystone' +p1095 +F9596.9300000000003 +sS'./pypy-c-36009-gc=framework--objspace-std-withstrdict--prof_pystone' +p1096 +F9960.1599999999999 +sS'./pypy-cli-35906_pystone' +p1097 +F555.39603964190303 +sS'./pypy-llvm-35771-objspace-std-withstrdict-x86_pystone' +p1098 +F11467.9 +sS'./pypy-c-35658-gc=framework--objspace-std-withstrdict--prof_pystone' +p1099 +F10245.9 +sS'./pypy-c-39348-objspace-std-withmultidict--prof_richards' +p1100 +F3085.79 +sS'./pypy-c-36136-stackless--objspace-std-withstrdict--prof_richards' +p1101 +F3656.4400000000001 +sS'./pypy-c-38140-objspace-std-withstrdict--prof_pystone' +p1102 +F10183.299999999999 +sS'./pypy-llvm-36136-faassen-c_richards' +p1103 +F2288.9099999999999 +sS'./pypy-c-39474-gc=framework--objspace-std-withmultidict--prof_richards' +p1104 +F3134.0100000000002 +sS'./pypy-cli-37163_richards' +p1105 +F47607.441902160601 +sS'./pypy-c-37454-stackless--objspace-std-withstrdict--prof_richards' +p1106 +F3766.29 +sS'./pypy-llvm-35968-faassen-c_richards' +p1107 +F2327.3600000000001 +sS'./pypy-c-35609_pystone' +p1108 +F6648.9399999999996 +sS'./pypy-llvm-36136-faassen-c-prof_richards' +p1109 +F2163.2600000000002 +sS'./pypy-c-34593-gc=framework_richards' +p1110 +F6086.0200000000004 +sS'./pypy-llvm-39646-faassen-x86_pystone' +p1111 +F15290.5 +sS'./pypy-cli-38769_richards' +p1112 +F45344.499111175501 +sS'./pypy-c-39218-objspace-std-withmultidict--prof_pystone' +p1113 +F10846.0 +sS'./pypy-c-35988-objspace-std-withstrdict--prof_pystone' +p1114 +F9689.9200000000001 +sS'./pypy-llvm-unknown-objspace-std-withstrdict-c_pystone' +p1115 +F7861.6400000000003 +sS'./pypy-c-39324-stackless--objspace-std-withmultidict--prof_richards' +p1116 +F3175.4299999999998 +sS'./pypy-c-37707-stackless--objspace-std-withstrdict--prof_richards' +p1117 +F3772.0700000000002 +sS'./pypy-c-37163-objspace-std-withstrdict--prof_richards' +p1118 +F3284.6700000000001 +sS'./pypy-c-39072-faassen_pystone' +p1119 +F12690.4 +sS'./pypy-c-37707_richards' +p1120 +F5281.6700000000001 +sS'./pypy-c-39188-faassen_richards' +p1121 +F2143.8299999999999 +sS'./pypy-c-37647-objspace-std-withstrdict--prof_pystone' +p1122 +F9980.0400000000009 +sS'./pypy-c-36158_pystone' +p1123 +F6821.2799999999997 +sS'./pypy-c-38140-faassen_richards' +p1124 +F2784.0900000000001 +sS'./pypy-llvm-39147-faassen-c_pystone' +p1125 +F15528.0 +sS'./pypy-c-36859_richards' +p1126 +F5122.2799999999997 +sS'./pypy-c-38994-objspace-std-withmultidict--prof_richards' +p1127 +F2694.3699999999999 +sS'./pypy-llvm-35065-objspace-std-withstrdict-c-prof_pystone' +p1128 +F99999.0 +sS'./pypy-c-35968-stackless--objspace-std-withstrdict--prof_pystone' +p1129 +F8818.3400000000001 +sS'./pypy-c-unknown-gc=framework--objspace-std-withstrdict--prof_richards' +p1130 +F4653.9200000000001 +sS'./pypy-c-35463_pystone' +p1131 +F6561.6800000000003 +sS'./pypy-c-39218-objspace-std-withfastslice_richards' +p1132 +F4632.7799999999997 +sS'./pypy-c-36158-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p1133 +F10224.9 +sS'./pypy-c-38435_richards' +p1134 +F5532.6000000000004 +sS'./pypy-cli-35512_richards' +p1135 +F68813.671112060503 +sS'./pypy-c-37367-faassen_richards' +p1136 +F2928.9200000000001 +sS'./pypy-c-37243_richards' +p1137 +F5348.9899999999998 +sS'./pypy-c-39188_pystone' +p1138 +F7680.4899999999998 +sS'./pypy-c-37084-stackless--objspace-std-withstrdict--prof_richards' +p1139 +F3467.3200000000002 +sS'./pypy-c-36344-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p1140 +F3103.1900000000001 +sS'./pypy-llvm-35143-objspace-std-withstrdict-c-prof_pystone' +p1141 +F99999.0 +sS'./pypy-c-36220_pystone' +p1142 +F6666.6700000000001 +sS'./pypy-c-36395-stackless--objspace-std-withstrdict--prof_richards' +p1143 +F4021.48 +sS'./pypy-c-34593-thread--objspace-std-withstrdict--prof_richards' +p1144 +F3527.8499999999999 +sS'./pypy-llvm-36539-faassen-c-prof_pystone' +p1145 +F16025.6 +sS'./pypy-cli-37044_pystone' +p1146 +F695.76830792890701 +sS'./pypy-c-35979-gc=framework--objspace-std-withstrdict--prof_pystone' +p1147 +F9823.1800000000003 +sS'./pypy-c-39302-gc=framework--objspace-std-withmultidict--prof_pystone' +p1148 +F10460.299999999999 +sS'./pypy-llvm-36113-faassen-c_pystone' +p1149 +F13736.299999999999 +sS'./pypy-cli-37111_pystone' +p1150 +F696.47288302331197 +sS'./pypy-c-36030-objspace-std-withstrdict--prof_richards' +p1151 +F3261.0300000000002 +sS'./pypy-c-35713_richards' +p1152 +F5200.5500000000002 +sS'./pypy-c-35183-gc=framework--objspace-std-withstrdict--prof_pystone' +p1153 +F9041.5900000000001 +sS'./pypy-c-37575-gc=framework--objspace-std-withstrdict--prof_pystone' +p1154 +F10917.0 +sS'./pypy-llvm-35837-objspace-std-withstrdict-c_richards' +p1155 +F2704.5700000000002 +sS'./pypy-llvm-36009-faassen-c-prof_richards' +p1156 +F2250.2199999999998 +sS'./pypy-llvm-39617-faassen-c-prof_richards' +p1157 +F1541.29 +sS'./pypy-c-35963-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p1158 +F10416.700000000001 +sS'./pypy-c-37503-objspace-std-withstrdict--prof_pystone' +p1159 +F9823.1800000000003 +sS'2.4.4_richards' +p1160 +F827.38999999999999 +sS'./pypy-c-38651-objspace-std-withstrdict--prof_richards' +p1161 +F2609.71 +sS'./pypy-llvm-34976-objspace-std-withstrdict-x86_pystone' +p1162 +F8726.0 +sS'./pypy-llvm-36100-faassen-x86_pystone' +p1163 +F13736.299999999999 +sS'./pypy-c-37044-gc=framework--objspace-std-withstrdict--prof_pystone' +p1164 +F9578.5400000000009 +sS'./pypy-llvm-39302-faassen-c_pystone' +p1165 +F15479.9 +sS'./pypy-llvm-35771-objspace-std-withstrdict-c-prof_pystone' +p1166 +F13369.0 +sS'./pypy-c-36009-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p1167 +F3125.1100000000001 +sS'./pypy-llvm-36158-faassen-x86_pystone' +p1168 +F13054.799999999999 +sS'./pypy-c-35963-stackless--objspace-std-withstrdict--prof_richards' +p1169 +F3382.6100000000001 +sS'./pypy-c-37782-gc=framework--objspace-std-withstrdict--prof_richards' +p1170 +F3367.0500000000002 +sS'./pypy-c-37647-faassen_pystone' +p1171 +F12195.1 +sS'./pypy-c-35713-gc=framework--objspace-std-withstrdict--prof_pystone' +p1172 +F10593.200000000001 +sS'./pypy-c-36136-gc=framework--objspace-std-withstrdict--prof_richards' +p1173 +F3440.6399999999999 +sS'./pypy-c-39617-objspace-std-withfastslice_richards' +p1174 +F4699.3900000000003 +sS'./pypy-c-39646-gc=framework--objspace-std-withmultidict--prof_richards' +p1175 +F3216.3800000000001 +sS'./pypy-c-36082_richards' +p1176 +F5220.9200000000001 +sS'./pypy-c-37243-gc=framework--objspace-std-withstrdict--prof_richards' +p1177 +F3474.6799999999998 +sS'./pypy-c-39324_pystone' +p1178 +F7022.4700000000003 +sS'./pypy-c-35906-objspace-std-withstrdict--prof_richards' +p1179 +F3412.77 +sS'./pypy-llvm-38870-faassen-c-prof_pystone' +p1180 +F16891.900000000001 +sS'./pypy-c-36539-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p1181 +F9861.9300000000003 +sS'./pypy-c-36100-objspace-std-withstrdict--prof_richards' +p1182 +F3240.1799999999998 +sS'./pypy-c-35837-objspace-std-withstrdict--prof_pystone' +p1183 +F9633.9099999999999 +sS'./pypy-c-39302-gc=framework--objspace-std-withmultidict--prof_richards' +p1184 +F3160.4499999999998 +sS'./pypy-llvm-36066-faassen-c_richards' +p1185 +F3328.1599999999999 +sS'./pypy-llvm-39547-faassen-c_richards' +p1186 +F1588.8299999999999 +sS'./pypy-llvm-35906-objspace-std-withstrdict-c_pystone' +p1187 +F11820.299999999999 +sS'./pypy-llvm-39348-faassen-x86_pystone' +p1188 +F14044.9 +sS'./pypy-c-35963-objspace-std-withstrdict--prof_pystone' +p1189 +F9727.6299999999992 +sS'./pypy-c-unknown-gc=framework--objspace-std-withstrdict--prof_pystone' +p1190 +F7342.1400000000003 +sS'./pypy-c-36052_pystone' +p1191 +F4549.5900000000001 +sS'./pypy-c-39302-stackless--objspace-std-withmultidict--prof_pystone' +p1192 +F9416.2000000000007 +sS'./pypy-llvm-38769-faassen-c-prof_richards' +p1193 +F1609.03 +sS'./pypy-cli-38870_richards' +p1194 +F46157.076835632302 +sS'./pypy-llvm-35837-objspace-std-withstrdict-c-prof_richards' +p1195 +F2606.21 +sS'./pypy-llvm-36344-faassen-c-prof_richards' +p1196 +F2108.6500000000001 +sS'./pypy-llvm-36030-faassen-c_pystone' +p1197 +F13927.6 +sS'./pypy-c-37647_richards' +p1198 +F5243.1999999999998 +sS'./pypy-cli-36220_richards' +p1199 +F63048.5520362854 +sS'./pypy-c-37044-stackless--objspace-std-withstrdict--prof_richards' +p1200 +F3930.1500000000001 +sS'./pypy-c-38994-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p1201 +F2766.21 +sS'./pypy-llvm-39324-faassen-c-prof_pystone' +p1202 +F17730.5 +sS'./pypy-c-36066-gc=framework--objspace-std-withstrdict--prof_pystone' +p1203 +F7451.5600000000004 +sS'./pypy-c-36446-gc=framework--objspace-std-withstrdict--prof_pystone' +p1204 +F9842.5200000000004 +sS'./pypy-c-37243-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p1205 +F10040.200000000001 +sS'./pypy-c-35923-stackless--objspace-std-withstrdict--prof_richards' +p1206 +F3955.9499999999998 +sS'./pypy-c-36052-gc=framework--objspace-std-withstrdict--prof_pystone' +p1207 +F7194.2399999999998 +sS'./pypy-c-39474-faassen_richards' +p1208 +F2177.8699999999999 +sS'./pypy-llvm-36052-faassen-x86_richards' +p1209 +F3583.8000000000002 +sS'./pypy-c-38435-objspace-std-withfastslice_richards' +p1210 +F5380.0799999999999 +sS'./pypy-c-37415-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p1211 +F9746.5900000000001 +sS'./pypy-llvm-35979-faassen-x86_richards' +p1212 +F2649.0100000000002 +sS'./pypy-llvm-36175-faassen-c_pystone' +p1213 +F14534.9 +sS'./pypy-c-36446-gc=framework--objspace-std-withstrdict--prof_richards' +p1214 +F3502.7399999999998 +sS'./pypy-llvm-35010-objspace-std-withstrdict-c-prof_pystone' +p1215 +F8849.5599999999995 +sS'./pypy-c-35771-stackless--objspace-std-withstrdict--prof_richards' +p1216 +F3516.0500000000002 +sS'./pypy-c-36009-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p1217 +F9578.5400000000009 +sS'./pypy-c-39374_pystone' +p1218 +F6849.3199999999997 +sS'./pypy-llvm-35923-objspace-std-withstrdict-c_pystone' +p1219 +F12376.200000000001 +sS'./pypy-c-35212-objspace-std-withstrdict--prof_richards' +p1220 +F3435.1799999999998 +sS'./pypy-c-36539-objspace-std-withstrdict--prof_pystone' +p1221 +F9652.5100000000002 +sS'./pypy-c-36395-objspace-std-withstrdict--prof_pystone' +p1222 +F9328.3600000000006 +sS'./pypy-llvm-39188-faassen-c-prof_pystone' +p1223 +F17241.400000000001 +sS'./pypy-c-37044-stackless--objspace-std-withstrdict--prof_pystone' +p1224 +F8156.6099999999997 +sS'./pypy-c-38651-stackless--objspace-std-withstrdict--prof_pystone' +p1225 +F9025.2700000000004 +sS'./pypy-c-35212-stackless--objspace-std-withstrdict--prof_richards' +p1226 +F3661.6300000000001 +sS'./pypy-llvm-36009-faassen-x86_richards' +p1227 +F2614.77 +sS'./pypy-llvm-35923-objspace-opcodes-CALL_LIKELY_BUILTIN-c_pystone' +p1228 +F11655.0 +sS'./pypy-llvm-35837-objspace-std-withstrdict-c_pystone' +p1229 +F11933.200000000001 +sS'./pypy-llvm-36182-faassen-c_richards' +p1230 +F2319.0300000000002 +sS'./pypy-c-36052-objspace-std-withstrdict--prof_richards' +p1231 +F4955.96 +sS'./pypy-c-38870_richards' +p1232 +F4675.4200000000001 +sS'./pypy-c-35010-stackless--objspace-std-withstrdict--prof_richards' +p1233 +F4828.79 +sS'./pypy-c-36790_richards' +p1234 +F5237.54 +sS'./pypy-cli-37782_richards' +p1235 +F47472.757101059004 +sS'./pypy-c-35968_pystone' +p1236 +F6587.6199999999999 +sS'./pypy-llvm-36182-faassen-c-prof_pystone' +p1237 +F15432.1 +sS'./pypy-c-35463-objspace-std-withstrdict--prof_pystone' +p1238 +F8896.7999999999993 +sS'./pypy-cli-37243_richards' +p1239 +F48961.3389968872 +sS'./pypy-c-35237-gc=framework--objspace-std-withstrdict--prof_pystone' +p1240 +F9276.4400000000005 +sS'./pypy-llvm-36182-faassen-x86_richards' +p1241 +F2615.73 +sS'./pypy-llvm-35982-faassen-c-prof_pystone' +p1242 +F15015.0 +sS'./pypy-c-34882-gc=framework--objspace-std-withstrdict--prof_richards' +p1243 +F3567.0799999999999 +sS'./pypy-c-37367-objspace-std-withstrdict--prof_richards' +p1244 +F3274.21 +sS'./pypy-c-unknown-stackless--objspace-std-withstrdict--prof_pystone' +p1245 +F6410.2600000000002 +sS'./pypy-llvm-36158-faassen-c-prof_pystone' +p1246 +F14970.1 +sS'./pypy-c-37367-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p1247 +F10080.6 +sS'./pypy-c-39646-stackless--objspace-std-withmultidict--prof_richards' +p1248 +F3448.4099999999999 +sS'./pypy-cli-36977_richards' +p1249 +F46406.007051467903 +sS'./pypy-c-39324-stackless--objspace-std-withmultidict--prof_pystone' +p1250 +F9505.7000000000007 +sS'./pypy-c-37647-faassen_richards' +p1251 +F2628.4499999999998 +sS'./pypy-c-36136-stackless--objspace-std-withstrdict--prof_pystone' +p1252 +F8680.5599999999995 +sS'./pypy-c-35963_richards' +p1253 +F5102.8800000000001 +sS'./pypy-llvm-35979-faassen-x86_pystone' +p1254 +F12500.0 +sS'./pypy-c-37707-stackless--objspace-std-withstrdict--prof_pystone' +p1255 +F8710.7999999999993 +sS'./pypy-c-38435-objspace-std-withfastslice_pystone' +p1256 +F6570.3000000000002 +sS'./pypy-c-38870-faassen_richards' +p1257 +F2233.5500000000002 +sS'./pypy-c-35512-gc=framework--objspace-std-withstrdict--prof_richards' +p1258 +F3598.6199999999999 +sS'./pypy-c-36344-objspace-std-withstrdict--prof_richards' +p1259 +F3324.7800000000002 +sS'./pypy-c-36395_richards' +p1260 +F5536.9499999999998 +sS'./pypy-cli-36030_richards' +p1261 +F51116.893053054802 +sS'./pypy-llvm-36539-faassen-c_richards' +p1262 +F2207.1900000000001 +sS'./pypy-c-35212-stackless--objspace-std-withstrdict--prof_pystone' +p1263 +F8250.8299999999999 +sS'./pypy-c-36220-objspace-std-withstrdict--prof_richards' +p1264 +F3165.1300000000001 +sS'./pypy-c-38140-gc=framework--objspace-std-withstrdict--prof_pystone' +p1265 +F10416.700000000001 +sS'./pypy-cli-35544~_pystone' +p1266 +F359.68572215440503 +sS'./pypy-c-35217-objspace-std-withstrdict--prof_pystone' +p1267 +F9157.5100000000002 +sS'./pypy-c-37084_richards' +p1268 +F5364.8400000000001 +sS'./pypy-c-37707-gc=framework--objspace-std-withstrdict--prof_richards' +p1269 +F3246.2199999999998 +sS'./pypy-llvm-39474-faassen-c_richards' +p1270 +F1849.0599999999999 +sS'./pypy-c-35217-stackless--objspace-std-withstrdict--prof_richards' +p1271 +F3569.1399999999999 +sS'./pypy-c-37084-gc=framework--objspace-std-withstrdict--prof_richards' +p1272 +F3595.0900000000001 +sS'./pypy-c-34927_pystone' +p1273 +F5382.1300000000001 +sS'./pypy-c-39474-stackless--objspace-std-withmultidict--prof_richards' +p1274 +F3353.96 +sS'./pypy-c-35979-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p1275 +F10101.0 +sS'./pypy-c-39617-stackless--objspace-std-withmultidict--prof_richards' +p1276 +F3497.6500000000001 +sS'./pypy-c-35988-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p1277 +F2916.8400000000001 +sS'./pypy-c-35512-gc=framework--objspace-std-withstrdict--prof_pystone' +p1278 +F9487.6700000000001 +sS'./pypy-llvm-35979-faassen-c-prof_pystone' +p1279 +F15290.5 +sS'./pypy-llvm-36052-faassen-c_richards' +p1280 +F3234.1500000000001 +sS'./pypy-c-37575_richards' +p1281 +F5280.8199999999997 +sS'./pypy-c-38769-stackless--objspace-std-withstrdict--prof_richards' +p1282 +F3226.9000000000001 +sS'./pypy-c-39474-objspace-std-withmultidict--prof_pystone' +p1283 +F10142.0 +sS'./pypy-c-unknown_pystone' +p1284 +F5107.25 +sS'./pypy-llvm-35065-objspace-std-withstrdict-x86_richards' +p1285 +F99999.0 +sS'./pypy-cli-38334_pystone' +p1286 +F705.05345228788406 +sS'./pypy-cli-38140_pystone' +p1287 +F690.24997748059502 +sS'./pypy-llvm-36136-faassen-x86_richards' +p1288 +F2364.9899999999998 +sS'./pypy-c-36977-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p1289 +F10330.6 +sS'./pypy-c-35923-stackless--prof_pystone' +p1290 +F5488.4700000000003 +sS'./pypy-cli-35557_richards' +p1291 +F69753.593921661406 +sS'./pypy-llvm-36009-faassen-c_pystone' +p1292 +F13966.5 +sS'./pypy-c-36136-objspace-std-withstrdict--prof_pystone' +p1293 +F9746.5900000000001 +sS'./pypy-llvm-35095-objspace-std-withstrdict-c-prof_pystone' +p1294 +F99999.0 +sS'./pypy-llvm-34632-objspace-std-withstrdict-c-prof_pystone' +p1295 +F9727.6299999999992 +sS'./pypy-c-39302-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p1296 +F2797.0799999999999 +sS'./pypy-llvm-39646-faassen-x86_richards' +p1297 +F1693.5799999999999 +sS'./pypy-cli-39547_richards' +p1298 +F46401.371955871597 +sS'./pypy-cli-36628_richards' +p1299 +F46990.438938140898 +sS'./pypy-cli-36052_richards' +p1300 +F50074.877977371201 +sS'./pypy-c-36539-gc=framework--objspace-std-withstrdict--prof_pystone' +p1301 +F9861.9300000000003 +sS'./pypy-cli-36220_pystone' +p1302 +F568.02782454761098 +sS'./pypy-c-39302-faassen_pystone' +p1303 +F13404.799999999999 +sS'./pypy-llvm-35065-objspace-std-withstrdict-c-prof_richards' +p1304 +F99999.0 +sS'./pypy-c-38769-gc=framework--objspace-std-withstrdict--prof_pystone' +p1305 +F10706.6 +sS'./pypy-c-38769-faassen_pystone' +p1306 +F13020.799999999999 +sS'./pypy-c-36539-stackless--objspace-std-withstrdict--prof_richards' +p1307 +F3703.25 +sS'./pypy-c-35906-stackless--objspace-std-withstrdict--prof_pystone' +p1308 +F8912.6599999999999 +sS'./pypy-c-38870-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p1309 +F10080.6 +sS'./pypy-c-37647-objspace-std-withstrdict--prof_richards' +p1310 +F3194.1500000000001 +sS'./pypy-c-37415-objspace-std-withstrdict--prof_richards' +p1311 +F3333.1799999999998 +sS'./pypy-c-38769-objspace-std-withfastslice_pystone' +p1312 +F7225.4300000000003 +sS'./pypy-llvm-38994-faassen-c_richards' +p1313 +F1995.52 +sS'./pypy-llvm-35010-objspace-std-withstrdict-c-prof_richards' +p1314 +F3694.4899999999998 +sS'./pypy-c-39474-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p1315 +F10548.5 +sS'./pypy-c-39072-gc=framework--objspace-std-withmultidict--prof_pystone' +p1316 +F10638.299999999999 +sS'./pypy-c-38140_pystone' +p1317 +F6756.7600000000002 +sS'./pypy-c-35183_richards' +p1318 +F5474.7200000000003 +sS'./pypy-llvm-39072-faassen-c-prof_pystone' +p1319 +F17182.099999999999 +sS'./pypy-c-37503-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p1320 +F9708.7399999999998 +sS'./pypy-c-37243-faassen_pystone' +p1321 +F11286.700000000001 +sS'./pypy-c-34927_richards' +p1322 +F6220.5799999999999 +sS'./pypy-c-37163_richards' +p1323 +F5178.71 +sS'./pypy-c-35988-stackless--objspace-std-withstrdict--prof_richards' +p1324 +F3631.2800000000002 +sS'./pypy-c-37575-stackless--objspace-std-withstrdict--prof_richards' +p1325 +F3572.48 +sS'./pypy-llvm-36446-faassen-c-prof_pystone' +p1326 +F15384.6 +sS'./pypy-cli-36082_pystone' +p1327 +F559.66122407692603 +sS'./pypy-llvm-36052-faassen-c_pystone' +p1328 +F10020.0 +sS'./pypy-cli-35837_richards' +p1329 +F63587.2900485992 +sS'./pypy-c-39646_richards' +p1330 +F4784.2799999999997 +sS'./pypy-llvm-35065-objspace-std-withstrdict-x86_pystone' +p1331 +F99999.0 +sS'./pypy-c-37084_pystone' +p1332 +F6684.4899999999998 +sS'./pypy-c-34976_pystone' +p1333 +F5341.8800000000001 +sS'./pypy-c-37415-faassen_pystone' +p1334 +F11160.700000000001 +sS'./pypy-c-35217-stackless--objspace-std-withstrdict--prof_pystone' +p1335 +F8431.7000000000007 +sS'./pypy-c-38994-objspace-std-withmultidict--prof_pystone' +p1336 +F11013.200000000001 +sS'./pypy-c-39348-objspace-std-withfastslice_richards' +p1337 +F4794.7799999999997 +sS'./pypy-cli-36182_pystone' +p1338 +F564.35634791688506 +sS'./pypy-llvm-39302-faassen-x86_pystone' +p1339 +F15105.700000000001 +sS'./pypy-c-37454-faassen_pystone' +p1340 +F10964.9 +sS'./pypy-c-35463-stackless--objspace-std-withstrdict--prof_richards' +p1341 +F3909.1999999999998 +sS'./pypy-c-36113_pystone' +p1342 +F6561.6800000000003 +sS'./pypy-c-37575_pystone' +p1343 +F6811.9899999999998 +sS'./pypy-llvm-35923-objspace-opcodes-CALL_LIKELY_BUILTIN-c-prof_pystone' +p1344 +F12953.4 +sS'./pypy-c-38870-stackless--objspace-std-withstrdict--prof_pystone' +p1345 +F9469.7000000000007 +sS'./pypy-llvm-35963-faassen-x86_pystone' +p1346 +F13550.1 +sS'./pypy-c-38651-faassen_richards' +p1347 +F2558.71 +sS'./pypy-c-36220-stackless--objspace-std-withstrdict--prof_richards' +p1348 +F3684.4899999999998 +sS'./pypy-llvm-36220-faassen-c_pystone' +p1349 +F13513.5 +sS'./pypy-llvm-36175-faassen-x86_richards' +p1350 +F2650.6199999999999 +sS'./pypy-c-35095-gc=framework--objspace-std-withstrdict--prof_richards' +p1351 +F3664.8499999999999 +sS'./pypy-cli-36344_pystone' +p1352 +F700.04986035125398 +sS'./pypy-c-35824-stackless--objspace-std-withstrdict--prof_richards' +p1353 +F3721.0 +sS'./pypy-c-35944-objspace-std-withstrdict--prof_richards' +p1354 +F3346.5700000000002 +sS'./pypy-c-39324-objspace-std-withmultidict--prof_richards' +p1355 +F3051.3699999999999 +sS'./pypy-llvm-39218-faassen-c-prof_pystone' +p1356 +F17482.5 +sS'./pypy-c-35968-gc=framework--objspace-std-withstrdict--prof_richards' +p1357 +F3237.96 +sS'./pypy-c-37243-stackless--objspace-std-withstrdict--prof_richards' +p1358 +F3860.48 +sS'./pypy-cli-36893_richards' +p1359 +F47774.488925933802 +sS'./pypy-c-36100-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p1360 +F3104.6599999999999 +sS'./pypy-c-38870-gc=framework--objspace-std-withstrdict--prof_pystone' +p1361 +F10893.200000000001 +sS'./pypy-c-39072-stackless--objspace-std-withmultidict--prof_pystone' +p1362 +F9451.7999999999993 +sS'./pypy-llvm-35944-faassen-c_richards' +p1363 +F2296.7800000000002 +sS'./pypy-c-39247_richards' +p1364 +F5249.0699999999997 +sS'./pypy-c-39324-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p1365 +F10706.6 +sS'./pypy-c-37163-gc=framework--objspace-std-withstrdict--prof_pystone' +p1366 +F10080.6 +sS'./pypy-cli-36859_pystone' +p1367 +F684.05926569083499 +sS'./pypy-c-37084-stackless--objspace-std-withstrdict--prof_pystone' +p1368 +F8896.7999999999993 +sS'./pypy-cli-36030_pystone' +p1369 +F663.80092302314904 +sS'./pypy-c-37163-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p1370 +F9940.3600000000006 +sS'./pypy-c-36100-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_pystone' +p1371 +F9881.4200000000001 +sS'./pypy-c-37310-stackless--objspace-std-withstrdict--prof_pystone' +p1372 +F8787.3500000000004 +sS'./pypy-llvm-39547-faassen-x86_richards' +p1373 +F1673.3599999999999 +sS'./pypy-c-37454-gc=framework--objspace-std-withstrdict--prof_pystone' +p1374 +F10352.0 +sS'./pypy-c-39547-faassen_richards' +p1375 +F2071.8400000000001 +sS'./pypy-llvm-36066-faassen-x86_pystone' +p1376 +F9803.9200000000001 +sS'./pypy-c-36446-stackless--objspace-std-withstrdict--prof_pystone' +p1377 +F8517.8899999999994 +sS'./pypy-c-36175-gc=framework--objspace-std-withstrdict--prof_pystone' +p1378 +F9900.9899999999998 +sS'./pypy-c-35982-stackless--objspace-std-withstrdict--prof_pystone' +p1379 +F8818.3400000000001 +sS'./pypy-c-38769-objspace-std-withstrdict--prof_pystone' +p1380 +F10661.0 +sS'./pypy-cli-36893_pystone' +p1381 +F697.65262912835101 +sS'./pypy-c-35463-gc=framework--objspace-std-withstrdict--prof_pystone' +p1382 +F9174.3099999999995 +sS'./pypy-c-37111-objspace-std-withstrdict--prof_richards' +p1383 +F3254.29 +sS'./pypy-c-34882_richards' +p1384 +F5477.2700000000004 +sS'./pypy-c-35065-gc=framework--objspace-std-withstrdict--prof_richards' +p1385 +F3811.1399999999999 +sS'./pypy-c-37503-faassen_richards' +p1386 +F2882.5300000000002 +sS'./pypy-c-34976-gc=framework--objspace-std-withstrdict--prof_richards' +p1387 +F4066.96 +sS'./pypy-llvm-36066-faassen-c_pystone' +p1388 +F10000.0 +sS'./pypy-llvm-36344-faassen-x86_richards' +p1389 +F2462.7600000000002 +sS'./pypy-c-35982-stackless--objspace-std-withstrdict--prof_richards' +p1390 +F3610.6500000000001 +sS'./pypy-llvm-36052-faassen-c-prof_richards' +p1391 +F3088.0500000000002 +sS'./pypy-c-39646-objspace-std-withfastslice_pystone' +p1392 +F7331.3800000000001 +sS'./pypy-c-35923-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p1393 +F3141.4299999999998 +sS'./pypy-c-35143-stackless--objspace-std-withstrdict--prof_richards' +p1394 +F3903.3800000000001 +sS'./pypy-cli-36100_richards' +p1395 +F62768.2371139526 +sS'./pypy-c-35988_richards' +p1396 +F5141.29 +sS'./pypy-c-37782-objspace-std-withstrdict--prof_richards' +p1397 +F3027.9400000000001 +sS'./pypy-c-35411-gc=framework--objspace-std-withstrdict--prof_richards' +p1398 +F3620.1700000000001 +sS'./pypy-c-39646-objspace-std-withmultidict--prof_pystone' +p1399 +F10661.0 +sS'./pypy-c-35010_pystone' +p1400 +F5296.6099999999997 +sS'./pypy-c-36395-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p1401 +F3052.6900000000001 +sS'./pypy-c-37454-faassen_richards' +p1402 +F2934.5300000000002 +sS'./pypy-llvm-39247-faassen-c_richards' +p1403 +F1795.95 +sS'./pypy-c-36893-prof--objspace-opcodes-CALL_LIKELY_BUILTIN_richards' +p1404 +F2947.9499999999998 +s. \ No newline at end of file From xoraxax at codespeak.net Sun Mar 4 10:56:06 2007 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sun, 4 Mar 2007 10:56:06 +0100 (CET) Subject: [pypy-svn] r39849 - pypy/dist/pypy/module/thread Message-ID: <20070304095606.5CCC11006F@code0.codespeak.net> Author: xoraxax Date: Sun Mar 4 10:56:02 2007 New Revision: 39849 Modified: pypy/dist/pypy/module/thread/threadlocals.py Log: Added getGIL to OSThreadLocals to conform to the interface of thread locals that is implemented by the other two implementations. Modified: pypy/dist/pypy/module/thread/threadlocals.py ============================================================================== --- pypy/dist/pypy/module/thread/threadlocals.py (original) +++ pypy/dist/pypy/module/thread/threadlocals.py Sun Mar 4 10:56:02 2007 @@ -56,3 +56,7 @@ def atthreadexit(self, space, exit_func, w_obj): ec = space.getexecutioncontext() ec.thread_exit_funcs.append((exit_func, w_obj)) + + def getGIL(self): + return None + From xoraxax at codespeak.net Sun Mar 4 10:59:17 2007 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sun, 4 Mar 2007 10:59:17 +0100 (CET) Subject: [pypy-svn] r39850 - pypy/dist/pypy/translator/c Message-ID: <20070304095917.D51741006F@code0.codespeak.net> Author: xoraxax Date: Sun Mar 4 10:59:16 2007 New Revision: 39850 Modified: pypy/dist/pypy/translator/c/node.py pypy/dist/pypy/translator/c/support.py Log: Add the possiblity of having __thread globals in genc. Note that the code doesnt actually use the result of the __thread check that is done before code generation. Modified: pypy/dist/pypy/translator/c/node.py ============================================================================== --- pypy/dist/pypy/translator/c/node.py (original) +++ pypy/dist/pypy/translator/c/node.py Sun Mar 4 10:59:16 2007 @@ -406,15 +406,18 @@ self.ptrname = '((%s)(void*)%s)' % (cdecl(ptrtypename, ''), self.ptrname) + def is_thread_local(self): + return hasattr(self.T, "_hints") and self.T._hints.get('thread_local') + def forward_declaration(self): yield '%s;' % ( forward_cdecl(self.implementationtypename, - self.name, self.db.standalone)) + self.name, self.db.standalone, self.is_thread_local())) def implementation(self): lines = list(self.initializationexpr()) lines[0] = '%s = %s' % ( - cdecl(self.implementationtypename, self.name), + cdecl(self.implementationtypename, self.name, self.is_thread_local()), lines[0]) lines[-1] += ';' return lines Modified: pypy/dist/pypy/translator/c/support.py ============================================================================== --- pypy/dist/pypy/translator/c/support.py (original) +++ pypy/dist/pypy/translator/c/support.py Sun Mar 4 10:59:16 2007 @@ -18,7 +18,7 @@ # # helpers # -def cdecl(ctype, cname): +def cdecl(ctype, cname, is_thread_local=False): """ Produce a C declaration from a 'type template' and an identifier. The type template must contain a '@' sign at the place where the @@ -26,10 +26,17 @@ """ # the (@) case is for functions, where if there is a plain (@) around # the function name, we don't need the very confusing parenthesis - return ctype.replace('(@)', '@').replace('@', cname).strip() + __thread = "" + if is_thread_local: + __thread = "__thread " + return __thread + ctype.replace('(@)', '@').replace('@', cname).strip() + +def forward_cdecl(ctype, cname, standalone, is_thread_local=False): + __thread = "" + if is_thread_local: + __thread = "__thread " -def forward_cdecl(ctype, cname, standalone): - cdecl_str = cdecl(ctype, cname) + cdecl_str = __thread + cdecl(ctype, cname) if standalone: return 'extern ' + cdecl_str else: From arigo at codespeak.net Sun Mar 4 11:20:26 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 4 Mar 2007 11:20:26 +0100 (CET) Subject: [pypy-svn] r39851 - pypy/dist/pypy/config Message-ID: <20070304102026.1809110060@code0.codespeak.net> Author: arigo Date: Sun Mar 4 11:20:25 2007 New Revision: 39851 Modified: pypy/dist/pypy/config/config.py Log: Printing config objects: hide subgroups with all-default values, sort the rest alphabetically. Modified: pypy/dist/pypy/config/config.py ============================================================================== --- pypy/dist/pypy/config/config.py (original) +++ pypy/dist/pypy/config/config.py Sun Mar 4 11:20:25 2007 @@ -137,19 +137,25 @@ if isinstance(child, Option): yield child._name, getattr(self, child._name) - def __str__(self): - result = "[%s]\n" % (self._cfgimpl_descr._name, ) - for child in self._cfgimpl_descr._children: - if isinstance(child, Option): - if self._cfgimpl_value_owners[child._name] == 'default': - continue - result += " %s = %s\n" % ( - child._name, getattr(self, child._name)) + def __str__(self, indent=""): + lines = [] + children = [(child._name, child) + for child in self._cfgimpl_descr._children] + children.sort() + for name, child in children: + if self._cfgimpl_value_owners.get(name, None) == 'default': + continue + value = getattr(self, name) + if isinstance(value, Config): + substr = value.__str__(indent + " ") else: - substr = str(getattr(self, child._name)) - substr = " " + substr[:-1].replace("\n", "\n ") + "\n" - result += substr - return result + substr = "%s %s = %s" % (indent, name, value) + if substr: + lines.append(substr) + if indent and not lines: + return '' # hide subgroups with all default values + lines.insert(0, "%s[%s]" % (indent, self._cfgimpl_descr._name,)) + return '\n'.join(lines) def getpaths(self, include_groups=False): """returns a list of all paths in self, recursively From cfbolz at codespeak.net Sun Mar 4 11:24:11 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sun, 4 Mar 2007 11:24:11 +0100 (CET) Subject: [pypy-svn] r39852 - pypy/extradoc/sprintinfo/trillke-2007 Message-ID: <20070304102411.4224B10050@code0.codespeak.net> Author: cfbolz Date: Sun Mar 4 11:24:09 2007 New Revision: 39852 Modified: pypy/extradoc/sprintinfo/trillke-2007/planning.txt Log: (all): planning for today Modified: pypy/extradoc/sprintinfo/trillke-2007/planning.txt ============================================================================== --- pypy/extradoc/sprintinfo/trillke-2007/planning.txt (original) +++ pypy/extradoc/sprintinfo/trillke-2007/planning.txt Sun Mar 4 11:24:09 2007 @@ -5,29 +5,41 @@ People present: Michael, Arre, Stephan, Anto, Guido, Armin, Maciek, Bea, Samuele, Georg, Alexander, Holger, Carl Friedrich, Anders +post-eu funding planning at 16.30, Sunday + Tutorial: Georg, Anders DONE + * prepare the post-eu funding planning meeting + (Carl Friedrich, Holger, Samuele) + * think a bit about what needs to be done for 1.0 - * move some of the external functions to the new interface (Samuele, Anto) + * move some of the external functions to the new interface + IN-PROGRESS, but as good as it's going to get during the sprint + + * fixing translation of the taint space IN-PROGRESS * Fix the rdict bug DONE + + * fix the new rdict bug * run application on top of PyPy and turn them into benchmarks: Guido, Christian - templess is now a pypy benchmark (5-6x) - docutils is now a pypy benchmark (5-6x) - gadfly is working with old-style classes + - some progress on making it work with new-style classes * object optimizations: ropes, list optimizations, cuckoo hashing, tree-based dicts: after the tutorial, Holger, Armin, Carl Friedrich, Georg - - ropes DONE (but slow) - - chunked list DONE - - multilist broken?! (Alexander, Carl Friedrich) + - ropes BUGGY (but not so slow any more) + - chunked list DONE (but slower) + - multilist not broken any more DONE - O(sqrt(n)) DONE but is slow and uses too much memory - - move string interpolation to rpython (Holger, Stephan) - - chained hash table (Armin), NEARLY DONE - - discuss global dict lookup ideas (Armin, Georg) + - move string interpolation to rpython IN-PROGRESS (Holger, Stephan) + - chained hash table, DONE (two times slower on micro-benchmarks) + - discuss global dict lookup ideas PFFFF + - improve getattr chains DISCUSSED (Anto, Holger to write it down) * improve the error messages of the rtyper @@ -37,6 +49,7 @@ (Michael, Holger) * hunt the strange speed bottleneck of gencli: DONE + - wrote RPython microbenchmarks in the process * fix application-level stackless code: DONE @@ -48,17 +61,38 @@ * fix the javascript backend work in internet explorer: IN-PROGRESS (Guido, Maciek) - * make the usage of the js backend nicer (Guido, Maciek) + * make the usage of the js backend nicer SOME PROGRESS (Guido, Maciek) + + * discuss code sharing between the js backend and gencli: DONE - * discuss code sharing between the js backend and gencli: MOSTLY DONE + * make genllvm less of a FrankenBackend (Richard, half of Michael) + LOTS OF PROGRESS + - ripped out old code + - worked in the direction of supporting rctypes - * make genllvm less of a FrankenBackend (Richard, half of Michael), IN-PROGRESS + * moved remaining useful stuff from translator/asm to jit/codegen/ppc + DONE * use "const" for immutable structures * have a pypy with a gil and threading that works - * object-level locking for a gil-less pypy + * object-level locking for a gil-less pypy: boehm seems to be a problem * use no locking, multiple interpreters and shared memory instead of object-level locks + + * solved some of the issues in the tracker: -m working, -C works + better, preventing changes to builtin types DONE + + * start supporting __index__ IN-PROGRESS + (Georg, Alexander, Anders, help from Armin) + + * re-think the interface of composable coroutines + (Armin, Christian, Stephan) + + * incorporate Richard's rsocket changes (Arre, Richard) + + * kill strdict, move normal dicts to the attic, keep only multidict + (Carl Friedrich, ...) + From ac at codespeak.net Sun Mar 4 11:24:53 2007 From: ac at codespeak.net (ac at codespeak.net) Date: Sun, 4 Mar 2007 11:24:53 +0100 (CET) Subject: [pypy-svn] r39853 - in pypy/dist/pypy: module/_stackless objspace/std objspace/std/test Message-ID: <20070304102453.8A3A710060@code0.codespeak.net> Author: ac Date: Sun Mar 4 11:24:50 2007 New Revision: 39853 Modified: pypy/dist/pypy/module/_stackless/coroutine.py pypy/dist/pypy/module/_stackless/interp_greenlet.py pypy/dist/pypy/objspace/std/objspace.py pypy/dist/pypy/objspace/std/test/test_typeobject.py pypy/dist/pypy/objspace/std/typeobject.py Log: issue285 resolved (asigfrid, arre) Prevent changes to builtin types. Add hacks where we change builtin types as part of setting them up. Modified: pypy/dist/pypy/module/_stackless/coroutine.py ============================================================================== --- pypy/dist/pypy/module/_stackless/coroutine.py (original) +++ pypy/dist/pypy/module/_stackless/coroutine.py Sun Mar 4 11:24:50 2007 @@ -263,12 +263,20 @@ def makeStaticMethod(module, classname, funcname): space = module.space - space.appexec(map(space.wrap, (module, classname, funcname)), """ - (module, klassname, funcname): - klass = getattr(module, klassname) + w_klass = space.getattr(space.wrap(module), space.wrap(classname)) + # HACK HACK HACK + # make the typeobject mutable for a while + from pypy.objspace.std.typeobject import _HEAPTYPE, W_TypeObject + assert isinstance(w_klass, W_TypeObject) + old_flags = w_klass.__flags__ + w_klass.__flags__ |= _HEAPTYPE + + space.appexec([w_klass, space.wrap(funcname)], """ + (klass, funcname): func = getattr(klass, funcname) setattr(klass, funcname, staticmethod(func.im_func)) """) + w_klass.__flags__ = old_flags def post_install(module): makeStaticMethod(module, 'coroutine', 'getcurrent') 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 Sun Mar 4 11:24:50 2007 @@ -206,14 +206,21 @@ space = module.space state = AppGreenlet._get_state(space) state.post_install() - w_module = space.getbuiltinmodule('_stackless') - space.appexec([w_module, + w_greenlet = get(space, 'greenlet') + # HACK HACK HACK + # make the typeobject mutable for a while + from pypy.objspace.std.typeobject import _HEAPTYPE, W_TypeObject + assert isinstance(w_greenlet, W_TypeObject) + old_flags = w_greenlet.__flags__ + w_greenlet.__flags__ |= _HEAPTYPE + space.appexec([w_greenlet, state.w_GreenletExit, state.w_GreenletError], """ - (mod, exit, error): - mod.greenlet.GreenletExit = exit - mod.greenlet.error = error + (greenlet, exit, error): + greenlet.GreenletExit = exit + greenlet.error = error """) + w_greenlet.__flags__ = old_flags AppGreenlet.typedef = TypeDef("greenlet", __new__ = interp2app(AppGreenlet.descr_method__new__.im_func, Modified: pypy/dist/pypy/objspace/std/objspace.py ============================================================================== --- pypy/dist/pypy/objspace/std/objspace.py (original) +++ pypy/dist/pypy/objspace/std/objspace.py Sun Mar 4 11:24:50 2007 @@ -186,6 +186,10 @@ # fix up a problem where multimethods apparently don't # like to define this at interp-level + # HACK HACK HACK + from pypy.objspace.std.typeobject import _HEAPTYPE + old_flags = self.w_dict.__flags__ + self.w_dict.__flags__ |= _HEAPTYPE self.appexec([self.w_dict], """ (dict): def fromkeys(cls, seq, value=None): @@ -195,6 +199,7 @@ return r dict.fromkeys = classmethod(fromkeys) """) + self.w_dict.__flags__ = old_flags if self.config.objspace.std.oldstyle: self.enable_old_style_classes_as_default_metaclass() Modified: pypy/dist/pypy/objspace/std/test/test_typeobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/test/test_typeobject.py (original) +++ pypy/dist/pypy/objspace/std/test/test_typeobject.py Sun Mar 4 11:24:50 2007 @@ -716,3 +716,9 @@ exec """class A(object):\n pass\n""" in d A = d['A'] assert A.__module__ == 'yay' + + def test_immutable_builtin(self): + raises(TypeError, setattr, list, 'append', 42) + raises(TypeError, setattr, list, 'foobar', 42) + raises(TypeError, delattr, dict, 'keys') + Modified: pypy/dist/pypy/objspace/std/typeobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/typeobject.py (original) +++ pypy/dist/pypy/objspace/std/typeobject.py Sun Mar 4 11:24:50 2007 @@ -508,6 +508,10 @@ if space.is_data_descr(w_descr): space.set(w_descr, w_type, w_value) return + + if not w_type.is_heaptype(): + msg = "can't set attributes on type object '%s'" %(w_type.name,) + raise OperationError(space.w_TypeError, space.wrap(msg)) w_type.dict_w[name] = w_value def delattr__Type_ANY(space, w_type, w_name): @@ -521,6 +525,9 @@ if space.is_data_descr(w_descr): space.delete(w_descr, w_type) return + if not w_type.is_heaptype(): + msg = "can't delete attributes on type object '%s'" %(w_type.name,) + raise OperationError(space.w_TypeError, space.wrap(msg)) try: del w_type.dict_w[name] return From fijal at codespeak.net Sun Mar 4 11:34:35 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 4 Mar 2007 11:34:35 +0100 (CET) Subject: [pypy-svn] r39854 - in pypy/dist/pypy/translator/js/examples/console: . data Message-ID: <20070304103435.0F42410060@code0.codespeak.net> Author: fijal Date: Sun Mar 4 11:34:33 2007 New Revision: 39854 Modified: pypy/dist/pypy/translator/js/examples/console/console.py pypy/dist/pypy/translator/js/examples/console/data/console.html Log: Fine tuning 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 Sun Mar 4 11:34:33 2007 @@ -36,12 +36,19 @@ return "\n".join(to_ret) +STATIC_DIR = py.path.local(__file__) +for x in range(6): + STATIC_DIR = STATIC_DIR.dirpath() +STATIC_DIR = STATIC_DIR.join("compiled") + class Sessions(object): def __init__(self): self.sessions = {} self.updating = {} def new_session(self, python="python"): + if not py.path.local().sysfind(python): + python = str(STATIC_DIR.join(python)) ip = Interpreter(python) self.sessions[ip.pid] = ip self.updating[ip.pid] = False @@ -81,7 +88,7 @@ #print "Refresh %s %d" % (to_write, int(pid)) try: return ["refresh", sessions.update_session(int(pid), to_write)] - except KeyError: + except (KeyError, IOError): return ["disconnected"] except Ignore: return ["ignore"] @@ -91,7 +98,7 @@ #print "Empty refresh %d" % int(pid) try: return ["refresh", sessions.update_session(int(pid), None)] - except KeyError: + except (KeyError, IOError): return ["disconnected"] except Ignore: return ["ignore"] Modified: pypy/dist/pypy/translator/js/examples/console/data/console.html ============================================================================== --- pypy/dist/pypy/translator/js/examples/console/data/console.html (original) +++ pypy/dist/pypy/translator/js/examples/console/data/console.html Sun Mar 4 11:34:33 2007 @@ -1,7 +1,7 @@ - + Console From guido at codespeak.net Sun Mar 4 12:05:17 2007 From: guido at codespeak.net (guido at codespeak.net) Date: Sun, 4 Mar 2007 12:05:17 +0100 (CET) Subject: [pypy-svn] r39855 - pypy/dist/pypy/translator/js/modules Message-ID: <20070304110517.BC4F310060@code0.codespeak.net> Author: guido Date: Sun Mar 4 12:05:15 2007 New Revision: 39855 Modified: pypy/dist/pypy/translator/js/modules/dom.py pypy/dist/pypy/translator/js/modules/mochikit.py Log: Moved some stuff from KeyEvent to Event to allow more generic event registration, extended the MochiKit event interface a tiny bit. 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 Sun Mar 4 12:05:15 2007 @@ -429,6 +429,8 @@ # XXX: From HTMLInputElement to make pythonconsole work. 'value': str, 'checked': bool, + # IMG specific + 'src': str, }) Element._methods = Node._methods.copy() @@ -696,6 +698,13 @@ 'relatedTarget': Element, 'target': Element, 'type': str, + 'returnValue': bool, + 'which': int, + 'keyCode' : int, + 'charCode': int, + 'altKey' : bool, + 'ctrlKey' : bool, + 'shiftKey': bool, } Event._methods = { @@ -707,13 +716,6 @@ KeyEvent._methods = Event._methods.copy() KeyEvent._fields = Event._fields.copy() -KeyEvent._fields.update({ - 'keyCode' : int, - 'charCode': int, - 'altKey' : bool, - 'ctrlKey' : bool, - 'shiftKey': bool, -}) class _FunctionWrapper(object): """makes sure function return values are wrapped if appropriate""" 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 Sun Mar 4 12:05:15 2007 @@ -52,7 +52,11 @@ pass Event._fields = { - '_event': dom.KeyEvent, + '_event': dom.Event, +} + +Event._methods = { + 'preventDefault': MethodDesc([]), } From cfbolz at codespeak.net Sun Mar 4 12:09:11 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sun, 4 Mar 2007 12:09:11 +0100 (CET) Subject: [pypy-svn] r39857 - pypy/dist/pypy/doc/config Message-ID: <20070304110911.10ED310060@code0.codespeak.net> Author: cfbolz Date: Sun Mar 4 12:09:09 2007 New Revision: 39857 Added: pypy/dist/pypy/doc/config/translation.llvm.debug.txt pypy/dist/pypy/doc/config/translation.llvm.isolate.txt pypy/dist/pypy/doc/config/translation.llvm.logging.txt pypy/dist/pypy/doc/config/translation.llvm.txt Log: add text files for new options Added: pypy/dist/pypy/doc/config/translation.llvm.debug.txt ============================================================================== Added: pypy/dist/pypy/doc/config/translation.llvm.isolate.txt ============================================================================== Added: pypy/dist/pypy/doc/config/translation.llvm.logging.txt ============================================================================== Added: pypy/dist/pypy/doc/config/translation.llvm.txt ============================================================================== From fijal at codespeak.net Sun Mar 4 12:10:44 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 4 Mar 2007 12:10:44 +0100 (CET) Subject: [pypy-svn] r39858 - pypy/dist/pypy/translator/js/examples/console Message-ID: <20070304111044.94C5310060@code0.codespeak.net> Author: fijal Date: Sun Mar 4 12:10:42 2007 New Revision: 39858 Added: pypy/dist/pypy/translator/js/examples/console/ideas.txt Log: (arigo, fijal, pedronis) Ideas for demos Added: pypy/dist/pypy/translator/js/examples/console/ideas.txt ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/js/examples/console/ideas.txt Sun Mar 4 12:10:42 2007 @@ -0,0 +1,11 @@ +* Thunk objspace - lazy evaluation in demo/fibonacci2 or sth + +* Taint objspace - examples in the documentation + +* Transparent proxy + +* Stackless - examples in a docs of stackless/WP7 + +* pypymagic.pypy_repr - --faassen, ropes + +* changing grammar at the runtime From gbrandl at codespeak.net Sun Mar 4 12:17:26 2007 From: gbrandl at codespeak.net (gbrandl at codespeak.net) Date: Sun, 4 Mar 2007 12:17:26 +0100 (CET) Subject: [pypy-svn] r39859 - pypy/branch/pypy-2.5 Message-ID: <20070304111726.9453710050@code0.codespeak.net> Author: gbrandl Date: Sun Mar 4 12:17:24 2007 New Revision: 39859 Added: pypy/branch/pypy-2.5/ - copied from r39858, pypy/dist/ Log: Add branch for 2.5 features. From gbrandl at codespeak.net Sun Mar 4 12:19:31 2007 From: gbrandl at codespeak.net (gbrandl at codespeak.net) Date: Sun, 4 Mar 2007 12:19:31 +0100 (CET) Subject: [pypy-svn] r39860 - in pypy/branch/pypy-2.5/pypy: interpreter interpreter/test lib module/operator objspace objspace/flow objspace/std Message-ID: <20070304111931.4867010060@code0.codespeak.net> Author: gbrandl Date: Sun Mar 4 12:19:28 2007 New Revision: 39860 Added: pypy/branch/pypy-2.5/pypy/module/operator/ pypy/branch/pypy-2.5/pypy/module/operator/__init__.py pypy/branch/pypy-2.5/pypy/module/operator/app_operator.py - copied, changed from r39846, pypy/dist/pypy/lib/operator.py pypy/branch/pypy-2.5/pypy/module/operator/interp_operator.py Removed: pypy/branch/pypy-2.5/pypy/lib/operator.py Modified: pypy/branch/pypy-2.5/pypy/interpreter/baseobjspace.py pypy/branch/pypy-2.5/pypy/interpreter/test/test_objspace.py pypy/branch/pypy-2.5/pypy/lib/_classobj.py pypy/branch/pypy-2.5/pypy/objspace/descroperation.py pypy/branch/pypy-2.5/pypy/objspace/flow/operation.py pypy/branch/pypy-2.5/pypy/objspace/std/intobject.py pypy/branch/pypy-2.5/pypy/objspace/std/longobject.py pypy/branch/pypy-2.5/pypy/objspace/std/stringobject.py Log: Add space.index, space.getindex_w, start moving operator module to interplevel. Modified: pypy/branch/pypy-2.5/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/branch/pypy-2.5/pypy/interpreter/baseobjspace.py (original) +++ pypy/branch/pypy-2.5/pypy/interpreter/baseobjspace.py Sun Mar 4 12:19:28 2007 @@ -5,7 +5,7 @@ from pypy.interpreter.miscutils import ThreadLocals from pypy.tool.cache import Cache from pypy.tool.uid import HUGEVAL_BYTES -import os +import os, sys __all__ = ['ObjSpace', 'OperationError', 'Wrappable', 'W_Root'] @@ -785,6 +785,28 @@ step = 0 return start, stop, step + def getindex_w(self, w_obj, exception=None): + w_index = self.index(w_obj) + try: + index = self.int_w(w_index) + except OperationError, err: + if not err.match(self, self.w_OverflowError): + raise + if not exception: + # w_index is a long object + if w_index.get_sign() < 0: + return -sys.maxint-1 + else: + return sys.maxint + else: + raise OperationError( + exception, self.wrap( + "cannot fit '%s' into an index-sized " + "integer" % self.type(w_obj).getname(self, '?'))) + else: + return index + + class AppExecCache(SpaceCache): def build(cache, source): """ NOT_RPYTHON """ @@ -841,6 +863,7 @@ ('or_', '|', 2, ['__or__', '__ror__']), ('xor', '^', 2, ['__xor__', '__rxor__']), ('int', 'int', 1, ['__int__']), + ('index', 'index', 1, ['__index__']), ('float', 'float', 1, ['__float__']), ('long', 'long', 1, ['__long__']), ('inplace_add', '+=', 2, ['__iadd__']), Modified: pypy/branch/pypy-2.5/pypy/interpreter/test/test_objspace.py ============================================================================== --- pypy/branch/pypy-2.5/pypy/interpreter/test/test_objspace.py (original) +++ pypy/branch/pypy-2.5/pypy/interpreter/test/test_objspace.py Sun Mar 4 12:19:28 2007 @@ -1,6 +1,7 @@ from py.test import raises from pypy.interpreter.function import Function from pypy.interpreter.pycode import PyCode +import sys # this test isn't so much to test that the objspace interface *works* # -- it's more to test that it's *there* @@ -139,6 +140,23 @@ res = self.space.interp_w(Function, w(None), can_be_None=True) assert res is None + def test_getindex_w(self): + w_instance1 = self.space.appexec([], """(): + class X(object): + def __index__(self): return 42 + return X()""") + w_instance2 = self.space.appexec([], """(): + class Y(object): + def __index__(self): return 2**70 + return Y()""") + first = self.space.getindex_w(w_instance1) + assert first == 42 + second = self.space.getindex_w(w_instance2) + assert second == sys.maxint + self.space.raises_w(self.space.w_IndexError, + self.space.getindex_w, w_instance2, self.space.w_IndexError) + + class TestModuleMinimal: def test_sys_exists(self): assert self.space.sys Modified: pypy/branch/pypy-2.5/pypy/lib/_classobj.py ============================================================================== --- pypy/branch/pypy-2.5/pypy/lib/_classobj.py (original) +++ pypy/branch/pypy-2.5/pypy/lib/_classobj.py Sun Mar 4 12:19:28 2007 @@ -399,6 +399,14 @@ """, {"op": op}) del op + def __index__(self): + func = instance_getattr1(self, '__index__', False) + if func: + return func() + else: + raise AttributeError('object cannot be interpreted as an index') + + # coerce def __coerce__(self, other): func = instance_getattr1(self, '__coerce__', False) Added: pypy/branch/pypy-2.5/pypy/module/operator/__init__.py ============================================================================== --- (empty file) +++ pypy/branch/pypy-2.5/pypy/module/operator/__init__.py Sun Mar 4 12:19:28 2007 @@ -0,0 +1,32 @@ +from pypy.interpreter.mixedmodule import MixedModule +from pypy.interpreter.error import OperationError + +class Module(MixedModule): + """Operator Builtin Module. """ + + appleveldefs = {} + + names = ['__abs__', '__add__', '__and__', + '__concat__', '__contains__', '__delitem__', '__delslice__', + '__div__', '__doc__', '__eq__', '__floordiv__', + '__ge__', '__getitem__', '__getslice__', '__gt__', '__inv__', + '__invert__', '__le__', '__lshift__', '__lt__', '__mod__', + '__mul__', '__name__', '__ne__', '__neg__', '__not__', '__or__', + '__pos__', '__pow__', '__repeat__', '__rshift__', '__setitem__', + '__setslice__', '__sub__', '__truediv__', '__xor__', 'abs', 'add', + 'and_', 'attrgetter', 'concat', 'contains', 'countOf', 'delitem', + 'delslice', 'div', 'division', 'eq', 'floordiv', 'ge', 'getitem', + 'getslice', 'gt', 'indexOf', 'inv', 'invert', 'isCallable', + 'isMappingType', 'isNumberType', 'isSequenceType', 'is_', + 'is_not', 'itemgetter', 'le', 'lshift', 'lt', 'mod', 'mul', + 'ne', 'neg', 'not_', 'or_', 'pos', 'pow', 'repeat', 'rshift', + 'sequenceIncludes', 'setitem', 'setslice', 'sub', 'truediv', + 'truth', 'xor'] + + for name in names: + appleveldefs[name] = 'app_operator.%s' % name + + + interpleveldefs = { + 'index': 'interp_operator.index' + } Added: pypy/branch/pypy-2.5/pypy/module/operator/interp_operator.py ============================================================================== --- (empty file) +++ pypy/branch/pypy-2.5/pypy/module/operator/interp_operator.py Sun Mar 4 12:19:28 2007 @@ -0,0 +1,9 @@ + +def index(space, w_a): + return space.index(w_a) + +def abs(space, w_obj): + 'abs(a) -- Same as abs(a).' + return space.abs(w_obj) + +__abs__ = abs Modified: pypy/branch/pypy-2.5/pypy/objspace/descroperation.py ============================================================================== --- pypy/branch/pypy-2.5/pypy/objspace/descroperation.py (original) +++ pypy/branch/pypy-2.5/pypy/objspace/descroperation.py Sun Mar 4 12:19:28 2007 @@ -514,6 +514,7 @@ for targetname, specialname, checkerspec in [ ('int', '__int__', ("space.w_int", "space.w_long")), + ('index', '__index__', ("space.w_int", "space.w_long")), ('long', '__long__', ("space.w_int", "space.w_long")), ('float', '__float__', ("space.w_float",))]: @@ -537,7 +538,7 @@ assert not hasattr(DescrOperation, %(targetname)r) DescrOperation.%(targetname)s = %(targetname)s del %(targetname)s - \n""" % locals() + \n""" % locals() exec compile2(source) for targetname, specialname in [ Modified: pypy/branch/pypy-2.5/pypy/objspace/flow/operation.py ============================================================================== --- pypy/branch/pypy-2.5/pypy/objspace/flow/operation.py (original) +++ pypy/branch/pypy-2.5/pypy/objspace/flow/operation.py Sun Mar 4 12:19:28 2007 @@ -23,6 +23,9 @@ def do_int(x): return x.__int__() +def do_index(x): + return x.__index__() + def do_float(x): return x.__float__() @@ -162,6 +165,7 @@ ('divmod', divmod), ('pow', pow), ('int', do_int), + ('index', do_index), ('float', do_float), ('long', do_long), ('inplace_add', inplace_add), Modified: pypy/branch/pypy-2.5/pypy/objspace/std/intobject.py ============================================================================== --- pypy/branch/pypy-2.5/pypy/objspace/std/intobject.py (original) +++ pypy/branch/pypy-2.5/pypy/objspace/std/intobject.py Sun Mar 4 12:19:28 2007 @@ -326,6 +326,9 @@ a = w_int1.intval return wrapint(space, a) +def index__Int(space, w_int1): + return int__Int(space, w_int1) + def float__Int(space, w_int1): a = w_int1.intval x = float(a) Modified: pypy/branch/pypy-2.5/pypy/objspace/std/longobject.py ============================================================================== --- pypy/branch/pypy-2.5/pypy/objspace/std/longobject.py (original) +++ pypy/branch/pypy-2.5/pypy/objspace/std/longobject.py Sun Mar 4 12:19:28 2007 @@ -50,6 +50,9 @@ def is_odd(self): return self.num.is_odd() + def get_sign(self): + return self.num.sign + registerimplementation(W_LongObject) # bool-to-long @@ -79,6 +82,9 @@ except OverflowError: return long__Long(space, w_value) +def index__Long(space, w_value): + return long__Long(space, w_value) + def float__Long(space, w_longobj): try: return space.newfloat(w_longobj.num.tofloat()) Modified: pypy/branch/pypy-2.5/pypy/objspace/std/stringobject.py ============================================================================== --- pypy/branch/pypy-2.5/pypy/objspace/std/stringobject.py (original) +++ pypy/branch/pypy-2.5/pypy/objspace/std/stringobject.py Sun Mar 4 12:19:28 2007 @@ -810,6 +810,9 @@ def getnewargs__String(space, w_str): return space.newtuple([wrapstr(space, w_str._value)]) +def index__String(space, w_str): + return space.wrap(42) + def repr__String(space, w_str): s = w_str._value From rxe at codespeak.net Sun Mar 4 12:20:05 2007 From: rxe at codespeak.net (rxe at codespeak.net) Date: Sun, 4 Mar 2007 12:20:05 +0100 (CET) Subject: [pypy-svn] r39861 - pypy/dist/pypy/translator/llvm/test Message-ID: <20070304112005.38B6110060@code0.codespeak.net> Author: rxe Date: Sun Mar 4 12:20:02 2007 New Revision: 39861 Modified: pypy/dist/pypy/translator/llvm/test/runtest.py Log: (mwh, rxe) typos 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 Sun Mar 4 12:20:02 2007 @@ -79,13 +79,13 @@ driver.setup(function, annotation) driver.annotate() if conftest.option.view: - translator.view() + driver.translator.view() driver.rtype() if conftest.option.view: - translator.view() + driver.translator.view() driver.compile() if conftest.option.view: - translator.view() + driver.translator.view() return driver.c_module, driver.c_entryp def compile_test(function, annotation, isolate=True, **kwds): From rxe at codespeak.net Sun Mar 4 12:23:22 2007 From: rxe at codespeak.net (rxe at codespeak.net) Date: Sun, 4 Mar 2007 12:23:22 +0100 (CET) Subject: [pypy-svn] r39863 - in pypy/dist/pypy/translator/llvm: . test Message-ID: <20070304112322.D4D4610061@code0.codespeak.net> Author: rxe Date: Sun Mar 4 12:23:21 2007 New Revision: 39863 Modified: pypy/dist/pypy/translator/llvm/opwriter.py pypy/dist/pypy/translator/llvm/structnode.py pypy/dist/pypy/translator/llvm/test/test_lltype.py Log: (mwh, rxe) implement direct_xxx. all tests in test_lltype pass now Modified: pypy/dist/pypy/translator/llvm/opwriter.py ============================================================================== --- pypy/dist/pypy/translator/llvm/opwriter.py (original) +++ pypy/dist/pypy/translator/llvm/opwriter.py Sun Mar 4 12:23:21 2007 @@ -39,16 +39,6 @@ else: self.functionref = '%pypyop_' + op.opname -def arrayindices(arg): - ARRAYTYPE = arg.concretetype.TO - if isinstance(ARRAYTYPE, lltype.Array): - # skip the length field - indices = [("uint", 1)] - else: - assert isinstance(ARRAYTYPE, lltype.FixedSizeArray) - indices = [] - return indices - class OpWriter(object): binary_operations = { @@ -102,6 +92,16 @@ else: return [self.db.repr_tmpvar() for ii in range(count)] + def _arrayindices(self, arg): + ARRAYTYPE = arg.concretetype.TO + if isinstance(ARRAYTYPE, lltype.Array): + # skip the length field + indices = [(self.uword, 1)] + else: + assert isinstance(ARRAYTYPE, lltype.FixedSizeArray) + indices = [] + return indices + def write_operation(self, op): #log(op) @@ -350,17 +350,17 @@ assert index != -1 tmpvar = self._tmp() self.codewriter.getelementptr(tmpvar, opr.argtypes[0], - opr.argrefs[0], [("uint", index)]) + opr.argrefs[0], [(self.uword, index)]) # get element ptr gets a pointer to the right type, except the generated code really expected # an array of size 1... so we just cast it - element_type = self.db.repr_type(op.result.concretetype.TO.OF)+'*' + element_type = self.db.repr_type(op.result.concretetype.TO.OF) + '*' self.codewriter.cast(opr.retref, element_type, tmpvar, opr.rettype) def getsubstruct(self, opr): index = getindexhelper(opr.op.args[1].value, opr.op.args[0].concretetype.TO) assert opr.rettype != "void" - indices = [("uint", index)] + indices = [(self.uword, index)] self.codewriter.getelementptr(opr.retref, opr.argtypes[0], opr.argrefs[0], indices) @@ -371,7 +371,7 @@ index = getindexhelper(op.args[1].value, op.args[0].concretetype.TO) self.codewriter.getelementptr(tmpvar, opr.argtypes[0], - opr.argrefs[0], [("uint", index)]) + opr.argrefs[0], [(self.uword, index)]) self.codewriter.store(opr.argtypes[2], opr.argrefs[2], tmpvar) else: self._skipped(opr) @@ -387,21 +387,41 @@ arraytype, indextype = opr.argtypes tmpvar = self._tmp() - indices = arrayindices(opr.op.args[0]) + [(indextype, index)] + indices = self._arrayindices(opr.op.args[0]) + [(self.word, index)] self.codewriter.getelementptr(tmpvar, arraytype, array, indices) 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, indices) + assert opr.rettype != "void" + + array = opr.argrefs[0] + arraytype = opr.argtypes[0] + indices = self._arrayindices(opr.op.args[0]) + [(self.word, 0)] + tmpvar = self._tmp() + self.codewriter.getelementptr(tmpvar, arraytype, array, indices) + # get element ptr gets a pointer to the right type, except the generated code really expected + # an array of size 1... so we just cast it + element_type = self.db.repr_type(opr.op.result.concretetype.TO.OF) + '*' + self.codewriter.cast(opr.retref, element_type, tmpvar, opr.rettype) + + def direct_ptradd(self, opr): + array, incr = opr.argrefs + arraytype, _ = opr.argtypes + + tmpvar = self._tmp() + self.codewriter.getelementptr(tmpvar, arraytype, array, [(self.word, incr)]) + + # get element ptr gets a pointer to the right type, except the generated code really expected + # an array of size 1... so we just cast it + element_type = self.db.repr_type(opr.op.result.concretetype.TO.OF) + '*' + self.codewriter.cast(opr.retref, element_type, tmpvar, opr.rettype) + def getarraysubstruct(self, opr): array, index = opr.argrefs arraytype, indextype = opr.argtypes - indices = arrayindices(opr.op.args[0]) + [(indextype, index)] + indices = self._arrayindices(opr.op.args[0]) + [(self.word, index)] self.codewriter.getelementptr(opr.retref, arraytype, array, indices) def setarrayitem(self, opr): @@ -413,7 +433,7 @@ self._skipped(opr) return - indices = arrayindices(opr.op.args[0]) + [(indextype, index)] + indices = self._arrayindices(opr.op.args[0]) + [(self.word, index)] self.codewriter.getelementptr(tmpvar, arraytype, array, indices) self.codewriter.store(valuetype, valuevar, tmpvar) bare_setarrayitem = setarrayitem @@ -423,7 +443,7 @@ assert isinstance(ARRAYTYPE, lltype.Array) tmpvar = self._tmp() self.codewriter.getelementptr(tmpvar, opr.argtypes[0], - opr.argrefs[0], [("uint", 0)]) + opr.argrefs[0], [(self.uword, 0)]) self.codewriter.load(opr.retref, opr.rettype, tmpvar) def adr_delta(self, opr): Modified: pypy/dist/pypy/translator/llvm/structnode.py ============================================================================== --- pypy/dist/pypy/translator/llvm/structnode.py (original) +++ pypy/dist/pypy/translator/llvm/structnode.py Sun Mar 4 12:23:21 2007 @@ -157,14 +157,16 @@ def get_ref(self): """ Returns a reference as used for operations in blocks. """ - if self._get_ref_cache: - return self._get_ref_cache + # XXX cache here is **dangerous** considering it can return different values :-( + # XXX should write a test to prove this + #if self._get_ref_cache: + # return self._get_ref_cache p, c = lltype.parentlink(self.value) if p is None: ref = self.ref else: ref = self.db.get_childref(p, c) - self._get_ref_cache = ref + #XXXself._get_ref_cache = ref return ref def get_pbcref(self, toptr): @@ -181,6 +183,11 @@ class FixedSizeArrayNode(StructNode): prefix = '%fixarrayinstance_' + def __init__(self, db, struct): + super(FixedSizeArrayNode, self).__init__(db, struct) + self.array = struct + self.arraytype = self.structtype.OF + def __str__(self): return "" % (self.ref,) @@ -190,14 +197,25 @@ all_values = ",\n ".join(values) return "%s [\n %s\n ]\n" % (self.get_typerepr(), all_values) + def get_ref(self): + p, c = lltype.parentlink(self.value) + if p is None: + ref = self.ref + else: + assert isinstance(self.value, lltype._subarray) + ref = self.db.get_childref(p, c) + + # ptr -> array of len 1 + ref = "cast(%s* %s to %s*)" % (self.db.repr_type(self.arraytype), + ref, + self.db.repr_type(lltype.typeOf(self.value))) + return ref + def get_childref(self, index): - ptr_type = self.db.repr_type(self.structtype.OF) + '*' - to_one_type = self.db.repr_type(lltype.FixedSizeArray(self.structtype.OF, 1)) + '*' - ptr = "getelementptr(%s* %s, int 0, int %s)" % ( + return "getelementptr(%s* %s, int 0, int %s)" % ( self.get_typerepr(), self.get_ref(), index) - return "cast(%s %s to %s)" % (ptr_type, ptr, to_one_type) def setup(self): if isinstance(self.value, lltype._subarray): Modified: pypy/dist/pypy/translator/llvm/test/test_lltype.py ============================================================================== --- pypy/dist/pypy/translator/llvm/test/test_lltype.py (original) +++ pypy/dist/pypy/translator/llvm/test/test_lltype.py Sun Mar 4 12:23:21 2007 @@ -352,7 +352,6 @@ assert res == -1 def test_direct_arrayitems(): - py.test.skip("wip") for a in [malloc(GcArray(Signed), 5), malloc(FixedSizeArray(Signed, 5), immortal=True)]: a[0] = 0 @@ -411,7 +410,6 @@ assert res == 142 def test_prebuilt_subarrays(): - py.test.skip("wip") a1 = malloc(GcArray(Signed), 5, zero=True) a2 = malloc(FixedSizeArray(Signed, 5), immortal=True) s = malloc(GcStruct('S', ('x', Signed), ('y', Signed))) From ac at codespeak.net Sun Mar 4 12:25:20 2007 From: ac at codespeak.net (ac at codespeak.net) Date: Sun, 4 Mar 2007 12:25:20 +0100 (CET) Subject: [pypy-svn] r39864 - in pypy/dist/pypy/module/rsocket: . test Message-ID: <20070304112520.51B9210061@code0.codespeak.net> Author: ac Date: Sun Mar 4 12:25:17 2007 New Revision: 39864 Modified: pypy/dist/pypy/module/rsocket/interp_socket.py pypy/dist/pypy/module/rsocket/test/test_sock_app.py Log: issue251 resolved issue256 in-progress Make _socket.socket.{send,sendall,sendto} accept a buffer object as data. Modified: pypy/dist/pypy/module/rsocket/interp_socket.py ============================================================================== --- pypy/dist/pypy/module/rsocket/interp_socket.py (original) +++ pypy/dist/pypy/module/rsocket/interp_socket.py Sun Mar 4 12:25:17 2007 @@ -7,6 +7,19 @@ from pypy.interpreter.error import OperationError from pypy.interpreter import gateway +class State(object): + "Cache the lookup of the buffer type" + def __init__(self, space): + w__builtin__ = space.getbuiltinmodule('__builtin__') + self.w_buffer = space.getattr(w__builtin__, space.wrap('buffer')) + +def coerce_to_str_w(space, w_obj): + "Accept an applevel string or buffer and return a string." + w_buffer = space.fromcache(State).w_buffer + if space.is_true(space.isinstance(w_obj, w_buffer)): + w_obj = space.str(w_obj) + return space.str_w(w_obj) + class W_RSocket(Wrappable, RSocket): def accept_w(self, space): """accept() -> (socket object, address info) @@ -251,13 +264,14 @@ raise converted_error(space, e) recvfrom_w.unwrap_spec = ['self', ObjSpace, int, int] - def send_w(self, space, data, flags=0): + def send_w(self, space, w_data, flags=0): """send(data[, flags]) -> count Send a data string to the socket. For the optional flags argument, see the Unix manual. Return the number of bytes sent; this may be less than len(data) if the network is busy. """ + data = coerce_to_str_w(space, w_data) try: GIL = space.threadlocals.getGIL() if GIL is not None: GIL.release() @@ -268,9 +282,9 @@ except SocketError, e: raise converted_error(space, e) return space.wrap(count) - send_w.unwrap_spec = ['self', ObjSpace, str, int] + send_w.unwrap_spec = ['self', ObjSpace, W_Root, int] - def sendall_w(self, space, data, flags=0): + def sendall_w(self, space, w_data, flags=0): """sendall(data[, flags]) Send a data string to the socket. For the optional flags @@ -278,6 +292,7 @@ until all data is sent. If an error occurs, it's impossible to tell how much data has been sent. """ + data = coerce_to_str_w(space, w_data) try: GIL = space.threadlocals.getGIL() if GIL is not None: GIL.release() @@ -287,14 +302,15 @@ if GIL is not None: GIL.acquire(True) except SocketError, e: raise converted_error(space, e) - sendall_w.unwrap_spec = ['self', ObjSpace, str, int] + sendall_w.unwrap_spec = ['self', ObjSpace, W_Root, int] - def sendto_w(self, space, data, w_param2, w_param3=NoneNotWrapped): + def sendto_w(self, space, w_data, w_param2, w_param3=NoneNotWrapped): """sendto(data[, flags], address) -> count Like send(data, flags) but allows specifying the destination address. For IP sockets, the address is a pair (hostaddr, port). """ + data = coerce_to_str_w(space, w_data) if w_param3 is None: # 2 args version flags = 0 @@ -314,7 +330,7 @@ except SocketError, e: raise converted_error(space, e) return space.wrap(count) - sendto_w.unwrap_spec = ['self', ObjSpace, str, W_Root, W_Root] + sendto_w.unwrap_spec = ['self', ObjSpace, W_Root, W_Root, W_Root] def setblocking_w(self, space, flag): """setblocking(flag) 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 Sun Mar 4 12:25:17 2007 @@ -385,6 +385,22 @@ assert s.getsockname() == s2.getsockname() + def test_buffer(self): + # Test that send/sendall/sendto accept a buffer as argument + import _socket, os + s = _socket.socket(_socket.AF_INET, _socket.SOCK_STREAM, 0) + # XXX temporarily we use codespeak to test, will have more robust tests in + # the absence of a network connection later when mroe parts of the socket + # API are implemented. + s.connect(("codespeak.net", 80)) + s.send(buffer('')) + s.sendall(buffer('')) + s.close() + s = _socket.socket(_socket.AF_INET, _socket.SOCK_DGRAM, 0) + s.sendto(buffer(''), ('localhost', 9)) # Send to discard port. + s.close() + + class AppTestSocketTCP: def setup_class(cls): cls.space = space From hpk at codespeak.net Sun Mar 4 12:29:57 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sun, 4 Mar 2007 12:29:57 +0100 (CET) Subject: [pypy-svn] r39865 - pypy/dist/pypy/doc/discussion Message-ID: <20070304112957.8706310060@code0.codespeak.net> Author: hpk Date: Sun Mar 4 12:29:55 2007 New Revision: 39865 Added: pypy/dist/pypy/doc/discussion/chained_getattr.txt (contents, props changed) Log: first draft of chained getattr/globals optimization Added: pypy/dist/pypy/doc/discussion/chained_getattr.txt ============================================================================== --- (empty file) +++ pypy/dist/pypy/doc/discussion/chained_getattr.txt Sun Mar 4 12:29:55 2007 @@ -0,0 +1,56 @@ + + +"chained getattr/module global lookup" optimization +(discussion during trillke-sprint 2007, anto/holger, +a bit of samuele and cf earlier on) + +random example: + + code: + import os.path + normed = [os.path.normpath(p) for p in somelist] + bytecode: + [...] + LOAD_GLOBAL (os) + LOAD_ATTR (path) + LOAD_ATTR (normpath) + LOAD_FAST (p) + CALL_FUNCTION 1 + + would be turned by pypy-compiler into: + + LOAD_CHAINED_GLOBAL (os,path,normpath) + LOAD_FAST (p) + CALL_FUNCTION 1 + + now for the LOAD_CHAINED_GLOBAL bytecode implementation: + + Module dicts have a special implemnetation, providing: + - an extra "fastlookup" rpython-list serving as a cache for + LOAD_CHAINED_GLOBAL places within the modules + - LOAD_CHAINED_GLOBAL has an index pointing into the + rpython-list + - the fastlookup list contains e.g. tuple entries: + ([obj1, obj2, obj3], [verglobals, ver1, ver2]) + "verglobals" refers to the version of the module globals + at which the initial 'os' global lookup was done. + "ver1" refer to the version of the globals of "os" + "ver2" refer to the version of the globals of "os.path" + "obj3" is the resulting "normpath" function + + - after the fastlookup entry is filled for a given + LOAD_CHAINED_GLOBAL index, the following checks need + to be performed in the bytecode implementation: + + objects, versions = f_globals.fastlookup[chained_global_index] + if getver(f_globals) != versions[0]: + return do_full_lookup() + i = 0 + while i < len(objects) - 1: + curobj = objects[i] + lastversion = versions[i+1] + currentversion = getver(curobj) + if currentversion != lastversion: + return do_full_lookup() # can be more clever + i += 1 + return objects[i] From fijal at codespeak.net Sun Mar 4 12:39:25 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 4 Mar 2007 12:39:25 +0100 (CET) Subject: [pypy-svn] r39866 - in pypy/dist/pypy/tool/build: . test Message-ID: <20070304113925.8762110060@code0.codespeak.net> Author: fijal Date: Sun Mar 4 12:39:23 2007 New Revision: 39866 Modified: pypy/dist/pypy/tool/build/test/__init__.py (props changed) pypy/dist/pypy/tool/build/test/test_webserver.py (props changed) pypy/dist/pypy/tool/build/webapp.py (props changed) pypy/dist/pypy/tool/build/webserver.py (props changed) Log: fixeol From fijal at codespeak.net Sun Mar 4 12:39:47 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 4 Mar 2007 12:39:47 +0100 (CET) Subject: [pypy-svn] r39867 - pypy/dist/pypy/tool/bench Message-ID: <20070304113947.59BAC10063@code0.codespeak.net> Author: fijal Date: Sun Mar 4 12:39:43 2007 New Revision: 39867 Modified: pypy/dist/pypy/tool/bench/ (props changed) Log: fixeol From fijal at codespeak.net Sun Mar 4 12:40:19 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 4 Mar 2007 12:40:19 +0100 (CET) Subject: [pypy-svn] r39868 - in pypy/dist/pypy: rpython/ootypesystem tool tool/test Message-ID: <20070304114019.DD12410060@code0.codespeak.net> Author: fijal Date: Sun Mar 4 12:40:18 2007 New Revision: 39868 Modified: pypy/dist/pypy/rpython/ootypesystem/bltregistry.py pypy/dist/pypy/tool/error.py pypy/dist/pypy/tool/test/test_error.py Log: Improve error reporting of BasicExternal Modified: pypy/dist/pypy/rpython/ootypesystem/bltregistry.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/bltregistry.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/bltregistry.py Sun Mar 4 12:40:18 2007 @@ -166,7 +166,12 @@ def get_field(self, attr): self.check_update() - return self._fields[attr] + try: + return self._fields[attr] + except KeyError: + from pypy.tool.error import NoSuchAttrError + raise NoSuchAttrError("Basic external %s has no attribute %s" % + (self._class_, attr)) def find_method(self, meth): raise NotImplementedError() Modified: pypy/dist/pypy/tool/error.py ============================================================================== --- pypy/dist/pypy/tool/error.py (original) +++ pypy/dist/pypy/tool/error.py Sun Mar 4 12:40:18 2007 @@ -67,6 +67,9 @@ class AnnotatorError(Exception): pass +class NoSuchAttrError(Exception): + pass + def gather_error(annotator, block, graph): msg = [""] msg.append('-+' * 30) Modified: pypy/dist/pypy/tool/test/test_error.py ============================================================================== --- pypy/dist/pypy/tool/test/test_error.py (original) +++ pypy/dist/pypy/tool/test/test_error.py Sun Mar 4 12:40:18 2007 @@ -3,7 +3,7 @@ """ from pypy.translator.translator import TranslationContext -from pypy.tool.error import FlowingError, AnnotatorError +from pypy.tool.error import FlowingError, AnnotatorError, NoSuchAttrError from pypy.annotation.policy import BasicAnnotatorPolicy import py @@ -68,3 +68,19 @@ exec("def f(n):\n if n == 2:\n return 'a'\n else:\n return 3") py.test.raises(AnnotatorError, compile_function, f, [int]) + +def test_basicexternal_attribute(): + from pypy.rpython.ootypesystem.bltregistry import BasicExternal + + class A(BasicExternal): + pass + + def f(): + return A().f + + py.test.raises(NoSuchAttrError, compile_function, f, []) + + def g(): + return A().g() + + py.test.raises(NoSuchAttrError, compile_function, g, []) From cfbolz at codespeak.net Sun Mar 4 12:45:22 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sun, 4 Mar 2007 12:45:22 +0100 (CET) Subject: [pypy-svn] r39869 - in pypy/dist/pypy: config doc doc/config objspace/std objspace/std/test Message-ID: <20070304114522.8D43210060@code0.codespeak.net> Author: cfbolz Date: Sun Mar 4 12:45:20 2007 New Revision: 39869 Removed: pypy/dist/pypy/doc/config/objspace.std.withstrdict.txt pypy/dist/pypy/objspace/std/dictstrobject.py pypy/dist/pypy/objspace/std/test/test_dictstrobject.py Modified: pypy/dist/pypy/config/pypyoption.py pypy/dist/pypy/doc/object-optimizations.txt pypy/dist/pypy/objspace/std/dicttype.py pypy/dist/pypy/objspace/std/marshal_impl.py pypy/dist/pypy/objspace/std/model.py pypy/dist/pypy/objspace/std/objspace.py pypy/dist/pypy/objspace/std/test/test_dictobject.py pypy/dist/pypy/objspace/std/test/test_proxy.py Log: trying to beat michael in the "removing code" metric: kill the now obsolete string dicts Modified: pypy/dist/pypy/config/pypyoption.py ============================================================================== --- pypy/dist/pypy/config/pypyoption.py (original) +++ pypy/dist/pypy/config/pypyoption.py Sun Mar 4 12:45:20 2007 @@ -136,14 +136,9 @@ "(the empty string and potentially single-char strings)", default=False), - BoolOption("withstrdict", - "use dictionaries optimized for string keys", - default=False), - BoolOption("withmultidict", "use dictionaries optimized for flexibility", - default=False, - requires=[("objspace.std.withstrdict", False)]), + default=False), BoolOption("withsharingdict", "use dictionaries that share the keys part", Modified: pypy/dist/pypy/doc/object-optimizations.txt ============================================================================== --- pypy/dist/pypy/doc/object-optimizations.txt (original) +++ pypy/dist/pypy/doc/object-optimizations.txt Sun Mar 4 12:45:20 2007 @@ -77,28 +77,14 @@ Dictionary optimizations ======================== -string-keyed dictionaries -------------------------- - -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 -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 ----------- -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: they provide generic support for such -switching of representations for dicts. +Multi-dicts are a special implementation of dictionaries. It became clear that +it is very useful to *change* the internal representation of an object during +its lifetime. Multi-Dicts are a general way to do that for dictionaries: they +provide generic support for the switching of internal 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 Modified: pypy/dist/pypy/objspace/std/dicttype.py ============================================================================== --- pypy/dist/pypy/objspace/std/dicttype.py (original) +++ pypy/dist/pypy/objspace/std/dicttype.py Sun Mar 4 12:45:20 2007 @@ -183,11 +183,6 @@ raise OperationError( space.w_RuntimeError, space.wrap("cannot pickle dictiters with multidicts")) - if space.config.objspace.std.withstrdict: - from pypy.objspace.std.dictstrobject import \ - W_DictStrIter_Keys as W_DictIter_Keys, \ - W_DictStrIter_Values as W_DictIter_Values, \ - W_DictStrIter_Items as W_DictIter_Items else: from pypy.objspace.std.dictobject import \ W_DictIter_Keys, W_DictIter_Values, W_DictIter_Items @@ -204,8 +199,6 @@ raise OperationError(space.w_TypeError, space.wrap(msg)) w_clone.space = space w_clone.content = w_self.content - if space.config.objspace.std.withstrdict: - w_clone.content_str = w_self.content_str w_clone.len = w_self.len w_clone.pos = 0 w_clone.setup_iterator() 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 Sun Mar 4 12:45:20 2007 @@ -26,7 +26,6 @@ from pypy.objspace.std.listobject import W_ListObject from pypy.objspace.std.dictobject import W_DictObject 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 @@ -360,18 +359,6 @@ 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: - for w_key, w_value in w_dict.content.iteritems(): - m.put_w_obj(w_key) - m.put_w_obj(w_value) - else: - for key, w_value in w_dict.content_str.iteritems(): - m.put_w_obj(space.wrap(key)) - m.put_w_obj(w_value) - m.atom(TYPE_NULL) - def unmarshal_Dict(space, u, tc): # since primitive lists are not optimized and we don't know # the dict size in advance, use the dict's setitem instead Modified: pypy/dist/pypy/objspace/std/model.py ============================================================================== --- pypy/dist/pypy/objspace/std/model.py (original) +++ pypy/dist/pypy/objspace/std/model.py Sun Mar 4 12:45:20 2007 @@ -12,8 +12,6 @@ "withsmallint" : ["smallintobject.W_SmallIntObject"], "withstrslice" : ["strsliceobject.W_StringSliceObject"], "withstrjoin" : ["strjoinobject.W_StringJoinObject"], - "withstrdict" : ["dictstrobject.W_DictStrObject", - "dictstrobject.W_DictStrIterObject"], "withmultidict" : ["dictmultiobject.W_DictMultiObject", "dictmultiobject.W_DictMultiIterObject"], "withmultilist" : ["listmultiobject.W_ListMultiObject"], @@ -64,7 +62,6 @@ from pypy.objspace.std import tupleobject from pypy.objspace.std import listobject 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 @@ -125,8 +122,7 @@ else: imported_but_not_registered[implcls] = True - if (config.objspace.std.withstrdict or - config.objspace.std.withmultidict): + if config.objspace.std.withmultidict: del self.typeorder[dictobject.W_DictObject] del self.typeorder[dictobject.W_DictIterObject] Modified: pypy/dist/pypy/objspace/std/objspace.py ============================================================================== --- pypy/dist/pypy/objspace/std/objspace.py (original) +++ pypy/dist/pypy/objspace/std/objspace.py Sun Mar 4 12:45:20 2007 @@ -120,10 +120,7 @@ self.FrameClass = StdObjSpaceFrame # XXX store the dict class on the space to access it in various places - if self.config.objspace.std.withstrdict: - from pypy.objspace.std import dictstrobject - self.DictObjectCls = dictstrobject.W_DictStrObject - elif self.config.objspace.std.withmultidict: + if self.config.objspace.std.withmultidict: from pypy.objspace.std import dictmultiobject self.DictObjectCls = dictmultiobject.W_DictMultiObject self.emptydictimpl = dictmultiobject.EmptyDictImplementation(self) Modified: pypy/dist/pypy/objspace/std/test/test_dictobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/test/test_dictobject.py (original) +++ pypy/dist/pypy/objspace/std/test/test_dictobject.py Sun Mar 4 12:45:20 2007 @@ -4,7 +4,7 @@ class TestW_DictObject: def setup_class(cls): - cls.space = gettestobjspace(**{"objspace.std.withstrdict": False}) + cls.space = gettestobjspace() def test_empty(self): space = self.space Modified: pypy/dist/pypy/objspace/std/test/test_proxy.py ============================================================================== --- pypy/dist/pypy/objspace/std/test/test_proxy.py (original) +++ pypy/dist/pypy/objspace/std/test/test_proxy.py Sun Mar 4 12:45:20 2007 @@ -120,5 +120,5 @@ class AppTestDictStrProxy(AppTestDictProxy): def setup_class(cls): - cls.space = gettestobjspace(**{"objspace.std.withstrdict": True, + cls.space = gettestobjspace(**{"objspace.std.withmultidict": True, "objspace.std.withtproxy": True}) From hpk at codespeak.net Sun Mar 4 12:52:06 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sun, 4 Mar 2007 12:52:06 +0100 (CET) Subject: [pypy-svn] r39870 - pypy/dist/pypy/doc/discussion Message-ID: <20070304115206.CBA6C10060@code0.codespeak.net> Author: hpk Date: Sun Mar 4 12:52:03 2007 New Revision: 39870 Modified: pypy/dist/pypy/doc/discussion/chained_getattr.txt Log: (Anto, hpk) updates, rather use a dict at module global level, and tweak the current code consideations a bit Modified: pypy/dist/pypy/doc/discussion/chained_getattr.txt ============================================================================== --- pypy/dist/pypy/doc/discussion/chained_getattr.txt (original) +++ pypy/dist/pypy/doc/discussion/chained_getattr.txt Sun Mar 4 12:52:03 2007 @@ -26,31 +26,41 @@ now for the LOAD_CHAINED_GLOBAL bytecode implementation: Module dicts have a special implemnetation, providing: - - an extra "fastlookup" rpython-list serving as a cache for - LOAD_CHAINED_GLOBAL places within the modules - - LOAD_CHAINED_GLOBAL has an index pointing into the - rpython-list - - the fastlookup list contains e.g. tuple entries: - ([obj1, obj2, obj3], [verglobals, ver1, ver2]) - "verglobals" refers to the version of the module globals - at which the initial 'os' global lookup was done. + - an extra "fastlookup" rpython-dict serving as a cache for + LOAD_CHAINED_GLOBAL places within the modules: + - keys are e.g. ('os', 'path', 'normpath') + - values are tuples of the form: + ([obj1, obj2, obj3], [ver1, ver2]) "ver1" refer to the version of the globals of "os" "ver2" refer to the version of the globals of "os.path" "obj3" is the resulting "normpath" function + - upon changes to the global dict, "fastlookup.clear()" is called + - after the fastlookup entry is filled for a given LOAD_CHAINED_GLOBAL index, the following checks need to be performed in the bytecode implementation: - objects, versions = f_globals.fastlookup[chained_global_index] - if getver(f_globals) != versions[0]: - return do_full_lookup() - i = 0 - while i < len(objects) - 1: - curobj = objects[i] - lastversion = versions[i+1] - currentversion = getver(curobj) - if currentversion != lastversion: - return do_full_lookup() # can be more clever - i += 1 + value = f_globals.fastlookup.get(key, None) + if value is None: + # fill entry + else: + # check that our cached lookups are still valid + assert isinstance(value, tuple) + objects, versions = value + i = 0 + while i < len(versions): + lastversion = versions[i] + ver = getver_for_obj(objects[i]) + if ver == -1 or ver != lastversion: + name = key[i] + objects[i] = space.getattr(curobj, name) + versions[i] = ver + curobj = objects[i] + i += 1 return objects[i] + + def getver_for_obj(obj): + if "obj is not Module": + return -1 + return obj.w_dict.version From cfbolz at codespeak.net Sun Mar 4 12:53:26 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sun, 4 Mar 2007 12:53:26 +0100 (CET) Subject: [pypy-svn] r39871 - in pypy/dist/pypy: config config/test doc doc/config doc/js doc/statistic lang/js lang/js/test/ecma lib/cslib lib/distributed lib/distributed/demo lib/distributed/test module/_cslib module/cclp module/cclp/constraint module/cclp/constraint/test objspace/std objspace/std/test rlib/cslib rlib/cslib/test rpython/microbench translator/js/examples/console translator/js/examples/console/test translator/js/lib/test translator/js/modules/test translator/jvm translator/microbench Message-ID: <20070304115326.C706E10060@code0.codespeak.net> Author: cfbolz Date: Sun Mar 4 12:53:24 2007 New Revision: 39871 Modified: pypy/dist/pypy/config/makerestdoc.py (props changed) pypy/dist/pypy/config/test/test_makerestdoc.py (props changed) pypy/dist/pypy/doc/cleanup-todo.txt (props changed) pypy/dist/pypy/doc/config/commandline.txt (props changed) pypy/dist/pypy/doc/config/makemodules.py (props changed) pypy/dist/pypy/doc/config/objspace.honor__builtins__.txt (props changed) pypy/dist/pypy/doc/config/objspace.std.withfastslice.txt (props changed) pypy/dist/pypy/doc/config/objspace.std.withmultilist.txt (props changed) pypy/dist/pypy/doc/config/objspace.std.withsmartresizablelist.txt (props changed) pypy/dist/pypy/doc/config/translation.backendopt.none.txt (props changed) pypy/dist/pypy/doc/config/translation.llvm.debug.txt (props changed) pypy/dist/pypy/doc/config/translation.llvm.isolate.txt (props changed) pypy/dist/pypy/doc/config/translation.llvm.logging.txt (props changed) pypy/dist/pypy/doc/config/translation.llvm.txt (props changed) pypy/dist/pypy/doc/js/testing.txt (props changed) pypy/dist/pypy/doc/object-optimizations.txt (props changed) pypy/dist/pypy/doc/statistic/python-list.txt (props changed) pypy/dist/pypy/doc/windows.txt (props changed) pypy/dist/pypy/lang/js/conftest.py (props changed) pypy/dist/pypy/lang/js/driver.py (props changed) pypy/dist/pypy/lang/js/operations.py (props changed) pypy/dist/pypy/lang/js/test/ecma/ (props changed) pypy/dist/pypy/lang/js/test/ecma/conftest.py (props changed) pypy/dist/pypy/lib/cslib/ (props changed) pypy/dist/pypy/lib/distributed/demo/ (props changed) pypy/dist/pypy/lib/distributed/demo/gsock.py (props changed) pypy/dist/pypy/lib/distributed/socklayer.py (props changed) pypy/dist/pypy/lib/distributed/test/__init__.py (props changed) pypy/dist/pypy/module/_cslib/ (props changed) pypy/dist/pypy/module/cclp/ (props changed) pypy/dist/pypy/module/cclp/constraint/ (props changed) pypy/dist/pypy/module/cclp/constraint/test/ (props changed) pypy/dist/pypy/objspace/std/listmultiobject.py (props changed) pypy/dist/pypy/objspace/std/smartresizablelist.py (props changed) pypy/dist/pypy/objspace/std/test/test_listmultiobject.py (props changed) pypy/dist/pypy/objspace/std/test/test_resizable.py (props changed) pypy/dist/pypy/rlib/cslib/ (props changed) pypy/dist/pypy/rlib/cslib/test/ (props changed) pypy/dist/pypy/rpython/microbench/ (props changed) pypy/dist/pypy/translator/js/examples/console/ideas.txt (props changed) pypy/dist/pypy/translator/js/examples/console/session.py (props changed) pypy/dist/pypy/translator/js/examples/console/test/test_session.py (props changed) pypy/dist/pypy/translator/js/lib/test/test_server_g.py (props changed) pypy/dist/pypy/translator/js/modules/test/test_mochikit.py (props changed) pypy/dist/pypy/translator/jvm/prebuiltnodes.py (props changed) pypy/dist/pypy/translator/microbench/test_formatting.py (props changed) pypy/dist/pypy/translator/microbench/test_list.py (props changed) Log: FIXEOL From xoraxax at codespeak.net Sun Mar 4 13:24:48 2007 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sun, 4 Mar 2007 13:24:48 +0100 (CET) Subject: [pypy-svn] r39872 - in pypy/branch/pypy-2.5/pypy: interpreter interpreter/test rlib Message-ID: <20070304122448.59C0110060@code0.codespeak.net> Author: xoraxax Date: Sun Mar 4 13:24:41 2007 New Revision: 39872 Modified: pypy/branch/pypy-2.5/pypy/interpreter/gateway.py pypy/branch/pypy-2.5/pypy/interpreter/test/test_gateway.py pypy/branch/pypy-2.5/pypy/rlib/streamio.py Log: (xorAxAx, gbrandl, samuele in the kitchen) Added gateway support for the index protocol. Modified: pypy/branch/pypy-2.5/pypy/interpreter/gateway.py ============================================================================== --- pypy/branch/pypy-2.5/pypy/interpreter/gateway.py (original) +++ pypy/branch/pypy-2.5/pypy/interpreter/gateway.py Sun Mar 4 13:24:41 2007 @@ -106,7 +106,17 @@ def visit_self(self, cls, app_sig): self.visit__Wrappable(cls, app_sig) - + + def checked_space_method(self, typ, app_sig): + argname = self.orig_arg() + assert not argname.startswith('w_'), ( + "unwrapped %s argument %s of built-in function %r should " + "not start with 'w_'" % (typ.__name__, argname, self.func)) + app_sig.append(argname) + + def visit_index(self, index, app_sig): + self.checked_space_method(index, app_sig) + def visit__Wrappable(self, el, app_sig): name = el.__name__ argname = self.orig_arg() @@ -154,11 +164,7 @@ def visit__object(self, typ, app_sig): if typ not in (int, str, float): assert False, "unsupported basic type in unwrap_spec" - argname = self.orig_arg() - assert not argname.startswith('w_'), ( - "unwrapped %s argument %s of built-in function %r should " - "not start with 'w_'" % (typ.__name__, argname, self.func)) - app_sig.append(argname) + self.checked_space_method(typ, app_sig) class UnwrapSpec_EmitRun(UnwrapSpecEmit): @@ -207,6 +213,9 @@ self.run_args.append("space.%s_w(%s)" % (typ.__name__, self.scopenext())) + def visit_index(self, typ): + self.run_args.append("space.getindex_w(%s)" % (self.scopenext(), )) + def _make_unwrap_activation_class(self, unwrap_spec, cache={}): try: key = tuple(unwrap_spec) @@ -316,6 +325,9 @@ self.unwrap.append("space.%s_w(%s)" % (typ.__name__, self.nextarg())) + def visit_index(self, typ): + self.unwrap.append("space.getindex_w(%s)" % (self.nextarg()), ) + def make_fastfunc(unwrap_spec, func): unwrap_info = UnwrapSpec_FastFunc_Unwrap() unwrap_info.apply_over(unwrap_spec) Modified: pypy/branch/pypy-2.5/pypy/interpreter/test/test_gateway.py ============================================================================== --- pypy/branch/pypy-2.5/pypy/interpreter/test/test_gateway.py (original) +++ pypy/branch/pypy-2.5/pypy/interpreter/test/test_gateway.py Sun Mar 4 13:24:41 2007 @@ -33,6 +33,12 @@ gateway.Arguments]) assert code.signature() == (['x', 'y'], 'args', 'keywords') + def f(space, index): + pass + code = gateway.BuiltinCode(f, unwrap_spec=[gateway.ObjSpace, "index"]) + assert code.signature() == (["index"], None, None) + + def test_call(self): def c(space, w_x, w_y, hello_w): u = space.unwrap @@ -50,6 +56,15 @@ w_result = code.funcrun(FakeFunc(self.space, "c"), args) assert self.space.eq_w(w_result, w(102)) + def test_call_index(self): + def c(space, index): + assert type(index) is int + code = gateway.BuiltinCode(c, unwrap_spec=[gateway.ObjSpace, + "index"]) + w = self.space.wrap + args = argument.Arguments(self.space, [w(123)]) + code.funcrun(FakeFunc(self.space, "c"), args) + def test_call_args(self): def c(space, w_x, w_y, __args__): args_w, kwds_w = __args__.unpack() Modified: pypy/branch/pypy-2.5/pypy/rlib/streamio.py ============================================================================== --- pypy/branch/pypy-2.5/pypy/rlib/streamio.py (original) +++ pypy/branch/pypy-2.5/pypy/rlib/streamio.py Sun Mar 4 13:24:41 2007 @@ -356,7 +356,7 @@ ("read", [int]), ("write", [str]), ("tell", []), - ("seek", [int, int]), + ("seek", ["index", int]), ("readall", []), ("readline", []), ("truncate", [int]), From rxe at codespeak.net Sun Mar 4 13:46:40 2007 From: rxe at codespeak.net (rxe at codespeak.net) Date: Sun, 4 Mar 2007 13:46:40 +0100 (CET) Subject: [pypy-svn] r39873 - in pypy/dist/pypy/translator/llvm: . test Message-ID: <20070304124640.21ACF10063@code0.codespeak.net> Author: rxe Date: Sun Mar 4 13:46:36 2007 New Revision: 39873 Modified: pypy/dist/pypy/translator/llvm/structnode.py pypy/dist/pypy/translator/llvm/test/test_lltype.py Log: (mwh, rxe) fix case when we get childref inside another pbc (see tests) Modified: pypy/dist/pypy/translator/llvm/structnode.py ============================================================================== --- pypy/dist/pypy/translator/llvm/structnode.py (original) +++ pypy/dist/pypy/translator/llvm/structnode.py Sun Mar 4 13:46:36 2007 @@ -202,13 +202,12 @@ if p is None: ref = self.ref else: - assert isinstance(self.value, lltype._subarray) ref = self.db.get_childref(p, c) - - # ptr -> array of len 1 - ref = "cast(%s* %s to %s*)" % (self.db.repr_type(self.arraytype), - ref, - self.db.repr_type(lltype.typeOf(self.value))) + if isinstance(self.value, lltype._subarray): + # ptr -> array of len 1 + ref = "cast(%s* %s to %s*)" % (self.db.repr_type(self.arraytype), + ref, + self.db.repr_type(lltype.typeOf(self.value))) return ref def get_childref(self, index): Modified: pypy/dist/pypy/translator/llvm/test/test_lltype.py ============================================================================== --- pypy/dist/pypy/translator/llvm/test/test_lltype.py (original) +++ pypy/dist/pypy/translator/llvm/test/test_lltype.py Sun Mar 4 13:46:36 2007 @@ -432,3 +432,56 @@ res = fn() assert res == 8765 +def test_pointer2fixedsizearray(): + A = FixedSizeArray(Signed, 1) + EmbedS = GcStruct('S', ('data', A)) + S = GcStruct('S', ('c_data', Ptr(A))) + + e = malloc(EmbedS, zero=True) + s = malloc(S, zero=True) + c_data = s.c_data = e.data + c_data[0] = 42 + + def llf(): + return s.c_data[0] + + fn = compile_function(llf, []) + res = fn() + assert res == 42 + +def test_rctypes_array_access(): + from ctypes import ARRAY, c_int + c_int_1 = ARRAY(c_int, 1) + + my_array = c_int_1() + + def llf(): + my_array[0] = 42 + return my_array[0] + + fn = compile_function(llf, []) + res = fn() + assert res == 42 + +def test_rctypes_char_array_value(): + from ctypes import c_char + A = c_char * 3 + + def llf(n): + a = A() + a[n+0] = 'x' + a[n+1] = 'y' + return a.value == 'xy' + + fn = compile_function(llf, [int]) + res = fn(0) + assert res + +def test_rctypes_variants(): + py.test.skip("wip") + from pypy.rpython.rctypes.test import test_rarray + llf, expected = test_rarray.maketest() + + fn = compile_function(llf, []) + res = fn() + assert res == expected From gbrandl at codespeak.net Sun Mar 4 13:53:08 2007 From: gbrandl at codespeak.net (gbrandl at codespeak.net) Date: Sun, 4 Mar 2007 13:53:08 +0100 (CET) Subject: [pypy-svn] r39875 - in pypy/branch/pypy-2.5/pypy: module/mmap objspace objspace/std Message-ID: <20070304125308.1D58B10075@code0.codespeak.net> Author: gbrandl Date: Sun Mar 4 13:53:05 2007 New Revision: 39875 Modified: pypy/branch/pypy-2.5/pypy/module/mmap/interp_mmap.py pypy/branch/pypy-2.5/pypy/objspace/descroperation.py pypy/branch/pypy-2.5/pypy/objspace/std/listmultiobject.py pypy/branch/pypy-2.5/pypy/objspace/std/listobject.py pypy/branch/pypy-2.5/pypy/objspace/std/rangeobject.py pypy/branch/pypy-2.5/pypy/objspace/std/sliceobject.py pypy/branch/pypy-2.5/pypy/objspace/std/stringobject.py pypy/branch/pypy-2.5/pypy/objspace/std/strsliceobject.py pypy/branch/pypy-2.5/pypy/objspace/std/tupleobject.py pypy/branch/pypy-2.5/pypy/objspace/std/unicodeobject.py Log: (gbrandl, xoraxax) use space.getindex_w for sequence indices, more to follow. Modified: pypy/branch/pypy-2.5/pypy/module/mmap/interp_mmap.py ============================================================================== --- pypy/branch/pypy-2.5/pypy/module/mmap/interp_mmap.py (original) +++ pypy/branch/pypy-2.5/pypy/module/mmap/interp_mmap.py Sun Mar 4 13:53:05 2007 @@ -350,7 +350,7 @@ self.space.wrap("seek out of range")) self.pos = where - seek.unwrap_spec = ['self', int, int] + seek.unwrap_spec = ['self', 'index', int] def tell(self): self.check_valid() @@ -679,7 +679,7 @@ m.setdata(res, map_size) return space.wrap(m) - mmap.unwrap_spec = [ObjSpace, int, int, int, int, int] + mmap.unwrap_spec = [ObjSpace, int, 'index', int, int, int] elif _MS_WINDOWS: def mmap(space, fileno, length, tagname="", access=_ACCESS_DEFAULT): # check size boundaries @@ -771,4 +771,4 @@ raise OperationError(space.w_EnvironmentError, space.wrap(os.strerror(dwErr))) - mmap.unwrap_spec = [ObjSpace, int, int, str, int] + mmap.unwrap_spec = [ObjSpace, int, 'index', str, int] Modified: pypy/branch/pypy-2.5/pypy/objspace/descroperation.py ============================================================================== --- pypy/branch/pypy-2.5/pypy/objspace/descroperation.py (original) +++ pypy/branch/pypy-2.5/pypy/objspace/descroperation.py Sun Mar 4 13:53:05 2007 @@ -580,7 +580,7 @@ for _name, _symbol, _arity, _specialnames in ObjSpace.MethodTable: if not hasattr(DescrOperation, _name): _impl_maker = None - if _arity ==2 and _name in ['lt', 'le', 'gt', 'ge', 'ne', 'eq']: + if _arity == 2 and _name in ['lt', 'le', 'gt', 'ge', 'ne', 'eq']: #print "comparison", _specialnames _impl_maker = _make_comparison_impl elif _arity == 2 and _name.startswith('inplace_'): Modified: pypy/branch/pypy-2.5/pypy/objspace/std/listmultiobject.py ============================================================================== --- pypy/branch/pypy-2.5/pypy/objspace/std/listmultiobject.py (original) +++ pypy/branch/pypy-2.5/pypy/objspace/std/listmultiobject.py Sun Mar 4 13:53:05 2007 @@ -940,7 +940,7 @@ def mul_list_times(space, w_list, w_times): try: - times = space.int_w(w_times) + times = space.getindex_w(w_times, space.w_OverflowError) except OperationError, e: if e.match(space, space.w_TypeError): raise FailedToImplement @@ -957,7 +957,7 @@ def inplace_mul__ListMulti_ANY(space, w_list, w_times): try: - times = space.int_w(w_times) + times = space.getindex_w(w_times, space.w_OverflowError) except OperationError, e: if e.match(space, space.w_TypeError): raise FailedToImplement Modified: pypy/branch/pypy-2.5/pypy/objspace/std/listobject.py ============================================================================== --- pypy/branch/pypy-2.5/pypy/objspace/std/listobject.py (original) +++ pypy/branch/pypy-2.5/pypy/objspace/std/listobject.py Sun Mar 4 13:53:05 2007 @@ -26,6 +26,15 @@ registerimplementation(W_ListObject) +def get_list_index(space, w_index): + if not space.lookup(w_index, '__index__'): + raise OperationError( + space.w_TypeError, + space.wrap("list indices must be integers, not %s" % + space.type(w_index).getname(space, '?'))) + return space.getindex_w(w_index, space.w_IndexError) + + EMPTY_LIST = W_ListObject([]) def init__List(space, w_list, __args__): @@ -42,9 +51,8 @@ return wrapint(space, result) def getitem__List_ANY(space, w_list, w_index): - idx = space.int_w(w_index) try: - return w_list.wrappeditems[idx] + return w_list.wrappeditems[get_list_index(space, w_index)] except IndexError: raise OperationError(space.w_IndexError, space.wrap("list index out of range")) @@ -92,7 +100,7 @@ def mul_list_times(space, w_list, w_times): try: - times = space.int_w(w_times) + times = space.getindex_w(w_times, space.w_OverflowError) except OperationError, e: if e.match(space, space.w_TypeError): raise FailedToImplement @@ -107,7 +115,7 @@ def inplace_mul__List_ANY(space, w_list, w_times): try: - times = space.int_w(w_times) + times = space.getindex_w(w_times, space.w_OverflowError) except OperationError, e: if e.match(space, space.w_TypeError): raise FailedToImplement @@ -171,7 +179,7 @@ w_list2.wrappeditems) def delitem__List_ANY(space, w_list, w_idx): - idx = space.int_w(w_idx) + idx = get_list_index(space, w_list) try: del w_list.wrappeditems[idx] except IndexError: @@ -227,7 +235,7 @@ return space.w_None def setitem__List_ANY_ANY(space, w_list, w_index, w_any): - idx = space.int_w(w_index) + idx = get_list_index(space, w_index) try: w_list.wrappeditems[idx] = w_any except IndexError: Modified: pypy/branch/pypy-2.5/pypy/objspace/std/rangeobject.py ============================================================================== --- pypy/branch/pypy-2.5/pypy/objspace/std/rangeobject.py (original) +++ pypy/branch/pypy-2.5/pypy/objspace/std/rangeobject.py Sun Mar 4 13:53:05 2007 @@ -78,7 +78,7 @@ def getitem__RangeList_ANY(space, w_rangelist, w_index): if w_rangelist.w_list is not None: return space.getitem(w_rangelist.w_list, w_index) - idx = space.int_w(w_index) + idx = space.getindex_w(w_index, space.w_IndexError) try: return wrapint(space, w_rangelist.getitem(idx)) except IndexError: Modified: pypy/branch/pypy-2.5/pypy/objspace/std/sliceobject.py ============================================================================== --- pypy/branch/pypy-2.5/pypy/objspace/std/sliceobject.py (original) +++ pypy/branch/pypy-2.5/pypy/objspace/std/sliceobject.py Sun Mar 4 13:53:05 2007 @@ -111,7 +111,7 @@ # indices impl def slice_indices__Slice_ANY(space, w_slice, w_length): - length = space.int_w(w_length) + length = space.getindex_w(w_length, space.w_OverflowError) start, stop, step = w_slice.indices3(space, length) return space.newtuple([space.wrap(start), space.wrap(stop), space.wrap(step)]) Modified: pypy/branch/pypy-2.5/pypy/objspace/std/stringobject.py ============================================================================== --- pypy/branch/pypy-2.5/pypy/objspace/std/stringobject.py (original) +++ pypy/branch/pypy-2.5/pypy/objspace/std/stringobject.py Sun Mar 4 13:53:05 2007 @@ -1,4 +1,4 @@ -# -*- Coding: Latin-1 -*- +# -*- coding: latin-1 -*- from pypy.objspace.std.objspace import * from pypy.interpreter import gateway @@ -730,7 +730,12 @@ return space.w_False def getitem__String_ANY(space, w_str, w_index): - ival = space.int_w(w_index) + if not space.lookup(w_index, '__index__'): + raise OperationError( + space.w_TypeError, + space.wrap("string indices must be integers, not %s" % + space.type(w_index).getname(space, '?'))) + ival = space.getindex_w(w_index, space.w_IndexError) str = w_str._value slen = len(str) if ival < 0: @@ -757,7 +762,7 @@ def mul_string_times(space, w_str, w_times): try: - mul = space.int_w(w_times) + mul = space.getindex_w(w_times, space.w_OverflowError) except OperationError, e: if e.match(space, space.w_TypeError): raise FailedToImplement @@ -810,9 +815,6 @@ def getnewargs__String(space, w_str): return space.newtuple([wrapstr(space, w_str._value)]) -def index__String(space, w_str): - return space.wrap(42) - def repr__String(space, w_str): s = w_str._value Modified: pypy/branch/pypy-2.5/pypy/objspace/std/strsliceobject.py ============================================================================== --- pypy/branch/pypy-2.5/pypy/objspace/std/strsliceobject.py (original) +++ pypy/branch/pypy-2.5/pypy/objspace/std/strsliceobject.py Sun Mar 4 13:53:05 2007 @@ -112,7 +112,12 @@ def getitem__StringSlice_ANY(space, w_str, w_index): - ival = space.int_w(w_index) + if not space.lookup(w_index, '__index__'): + raise OperationError( + space.w_TypeError, + space.wrap("string indices must be integers, not %s" % + space.type(w_index).getname(space, '?'))) + ival = space.getindex_w(w_index, space.w_IndexError) slen = w_str.stop - w_str.start if ival < 0: ival += slen Modified: pypy/branch/pypy-2.5/pypy/objspace/std/tupleobject.py ============================================================================== --- pypy/branch/pypy-2.5/pypy/objspace/std/tupleobject.py (original) +++ pypy/branch/pypy-2.5/pypy/objspace/std/tupleobject.py Sun Mar 4 13:53:05 2007 @@ -28,13 +28,18 @@ return wrapint(space, result) def getitem__Tuple_ANY(space, w_tuple, w_index): - items = w_tuple.wrappeditems + if not space.lookup(w_index, '__index__'): + raise OperationError( + space.w_TypeError, + space.wrap("tuple indices must be integers, not %s" % + space.type(w_index).getname(space, '?'))) try: - w_item = items[space.int_w(w_index)] + # XXX: getindex_w should get a second argument space.w_IndexError, + # but that doesn't exist the first time this is called. + return w_tuple.wrappeditems[space.getindex_w(w_index)] except IndexError: raise OperationError(space.w_IndexError, space.wrap("tuple index out of range")) - return w_item def getitem__Tuple_Slice(space, w_tuple, w_slice): items = w_tuple.wrappeditems @@ -64,7 +69,7 @@ def mul_tuple_times(space, w_tuple, w_times): try: - times = space.int_w(w_times) + times = space.getindex_w(w_times, space.w_OverflowError) except OperationError, e: if e.match(space, space.w_TypeError): raise FailedToImplement Modified: pypy/branch/pypy-2.5/pypy/objspace/std/unicodeobject.py ============================================================================== --- pypy/branch/pypy-2.5/pypy/objspace/std/unicodeobject.py (original) +++ pypy/branch/pypy-2.5/pypy/objspace/std/unicodeobject.py Sun Mar 4 13:53:05 2007 @@ -203,7 +203,12 @@ return space.wrap(len(w_uni._value)) def getitem__Unicode_ANY(space, w_uni, w_index): - ival = space.int_w(w_index) + if not space.lookup(w_index, '__index__'): + raise OperationError( + space.w_TypeError, + space.wrap("string indices must be integers, not %s" % + space.type(w_index).getname(space, '?'))) + ival = space.getindex_w(w_index, space.w_IndexError) uni = w_uni._value ulen = len(uni) if ival < 0: @@ -230,7 +235,7 @@ def mul__Unicode_ANY(space, w_uni, w_times): chars = w_uni._value charlen = len(chars) - times = space.int_w(w_times) + times = space.getindex_w(w_times, space.w_OverflowError) if times <= 0 or charlen == 0: return W_UnicodeObject([]) if times == 1: From xoraxax at codespeak.net Sun Mar 4 13:53:29 2007 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sun, 4 Mar 2007 13:53:29 +0100 (CET) Subject: [pypy-svn] r39877 - pypy/branch/pypy-2.5/pypy/objspace/cpy Message-ID: <20070304125329.67D7E10078@code0.codespeak.net> Author: xoraxax Date: Sun Mar 4 13:53:26 2007 New Revision: 39877 Modified: pypy/branch/pypy-2.5/pypy/objspace/cpy/function.py pypy/branch/pypy-2.5/pypy/objspace/cpy/objspace.py Log: Some basic __index__ support for the CPyObjSpace (well, it is equivalent to calling int() currently). Modified: pypy/branch/pypy-2.5/pypy/objspace/cpy/function.py ============================================================================== --- pypy/branch/pypy-2.5/pypy/objspace/cpy/function.py (original) +++ pypy/branch/pypy-2.5/pypy/objspace/cpy/function.py Sun Mar 4 13:53:26 2007 @@ -52,7 +52,9 @@ def visit__object(self, el): convertermap = {int: 'int_w', str: 'str_w', - float: 'float_w'} + float: 'float_w', + "index": 'getindex_w' + } argname = self.orig_arg() assert not argname.startswith('w_') self.inputargs.append(argname) @@ -62,6 +64,9 @@ argname)) self.passedargs.append(argname) + def visit_index(self, el): + self.visit__object("index") + def visit_args_w(self, el): argname = self.orig_arg() assert argname.endswith('_w') Modified: pypy/branch/pypy-2.5/pypy/objspace/cpy/objspace.py ============================================================================== --- pypy/branch/pypy-2.5/pypy/objspace/cpy/objspace.py (original) +++ pypy/branch/pypy-2.5/pypy/objspace/cpy/objspace.py Sun Mar 4 13:53:26 2007 @@ -148,6 +148,11 @@ repr = staticmethod(PyObject_Repr) id = staticmethod(PyLong_FromVoidPtr_PYOBJ) + def index(self, w_obj): + # XXX we do not support 2.5 yet, so we just do some + # hack here to have index working + return self.wrap(self.int_w(w_obj)) + def bigint_w(self, w_obj): if self.is_true(self.isinstance(w_obj, self.w_long)): sign = _PyLong_Sign(w_obj) From cfbolz at codespeak.net Sun Mar 4 14:07:18 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sun, 4 Mar 2007 14:07:18 +0100 (CET) Subject: [pypy-svn] r39878 - in pypy/branch/rope-branch/pypy/objspace/std: . test Message-ID: <20070304130718.A24891006E@code0.codespeak.net> Author: cfbolz Date: Sun Mar 4 14:07:14 2007 New Revision: 39878 Modified: pypy/branch/rope-branch/pypy/objspace/std/ropeobject.py pypy/branch/rope-branch/pypy/objspace/std/test/test_ropeobject.py Log: check for hash differences first before doing a real rope comparison. hm, storing the hash as a wrapped object is not such a good idea: I really want to use it easily for the equality comparisons. Modified: pypy/branch/rope-branch/pypy/objspace/std/ropeobject.py ============================================================================== --- pypy/branch/rope-branch/pypy/objspace/std/ropeobject.py (original) +++ pypy/branch/rope-branch/pypy/objspace/std/ropeobject.py Sun Mar 4 14:07:14 2007 @@ -16,7 +16,7 @@ def __init__(w_self, node): w_self._node = node - w_self._w_hash = None + w_self._hash = 0 def __repr__(w_self): """ representation for debugging purposes """ @@ -788,12 +788,11 @@ return w_str._node.flatten() def hash__Rope(space, w_str): - w_hash = w_str._w_hash - if w_hash is None: + hash = w_str._hash + if hash == 0: node = w_str._node - x = rope.hash_rope(node) - w_hash = w_str._w_hash = wrapint(space, x) - return w_hash + hash = w_str._hash = rope.hash_rope(node) + return wrapint(space, hash) def lt__Rope_Rope(space, w_str1, w_str2): n1 = w_str1._node @@ -806,11 +805,19 @@ return space.newbool(rope.compare(n1, n2) <= 0) def eq__Rope_Rope(space, w_str1, w_str2): + h1 = w_str1._hash + h2 = w_str2._hash + if h1 and h2 and h1 != h2: + return space.w_False n1 = w_str1._node n2 = w_str2._node return space.newbool(rope.eq(n1, n2)) def ne__Rope_Rope(space, w_str1, w_str2): + h1 = w_str1._hash + h2 = w_str2._hash + if h1 and h2 and h1 != h2: + return space.w_True n1 = w_str1._node n2 = w_str2._node return space.newbool(not rope.eq(n1, n2)) Modified: pypy/branch/rope-branch/pypy/objspace/std/test/test_ropeobject.py ============================================================================== --- pypy/branch/rope-branch/pypy/objspace/std/test/test_ropeobject.py (original) +++ pypy/branch/rope-branch/pypy/objspace/std/test/test_ropeobject.py Sun Mar 4 14:07:14 2007 @@ -33,14 +33,31 @@ # check twice to catch hash cache problems` s1 = 'hello' s2 = 'hello world!' - assert hash(s1) is hash(s1) # does the caching actually work? assert hash(s1) & 0x7fffffff == 0x347697fd assert hash(s1) & 0x7fffffff == 0x347697fd - assert hash(s2) is hash(s2) # does the caching actually work? assert hash(s2) & 0x7fffffff == 0x2f0bb411 assert hash(s2) & 0x7fffffff == 0x2f0bb411 - + def test_rope_equality(self): + # make sure that they are not just literal nodes + s1 = 'hello' * 1000 + s2 = ('he' + 'llo') * 1000 + s3 = 'HELLO' * 1000 + s4 = 'World!' * 1000 + # fill hash caches one by one: + for s in [None, s1, s2, s3, s4]: + hash(s) + assert s1 == s1 + assert s1 == s2 + assert s1 != s3 + assert s1 != s4 + assert s2 == s2 + assert s2 != s3 + assert s2 != s4 + assert s3 == s3 + assert s3 != s4 + assert s4 == s4 + class AppTestRopeUnicode(object): def setup_class(cls): From pedronis at codespeak.net Sun Mar 4 14:16:07 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sun, 4 Mar 2007 14:16:07 +0100 (CET) Subject: [pypy-svn] r39879 - in pypy/dist/pypy: interpreter objspace objspace/std Message-ID: <20070304131607.BD87B1007C@code0.codespeak.net> Author: pedronis Date: Sun Mar 4 14:16:05 2007 New Revision: 39879 Modified: pypy/dist/pypy/interpreter/typedef.py pypy/dist/pypy/objspace/descroperation.py pypy/dist/pypy/objspace/std/stdtypedef.py pypy/dist/pypy/objspace/std/stringobject.py pypy/dist/pypy/objspace/std/typeobject.py pypy/dist/pypy/objspace/std/typetype.py Log: use getname more consistently, helps making the taint space translatable. py.test -A tests pass. There are still problems and open issues (also design-wise), some usages can produce fatal internal assertion errors :( Modified: pypy/dist/pypy/interpreter/typedef.py ============================================================================== --- pypy/dist/pypy/interpreter/typedef.py (original) +++ pypy/dist/pypy/interpreter/typedef.py Sun Mar 4 14:16:05 2007 @@ -420,8 +420,11 @@ def typecheck(self, space, w_obj): if not space.is_true(space.isinstance(w_obj, self.w_cls)): raise OperationError(space.w_TypeError, - space.wrap("descriptor '%s' for '%s' objects doesn't apply to '%s' object" % - (self.name, self.w_cls.name, space.type(w_obj).name))) + space.wrap("descriptor '%s' for '%s'" + " objects doesn't apply to '%s' object" % + (self.name, + self.w_cls.name, + space.type(w_obj).getname(space, '?')))) def descr_member_get(space, member, w_obj, w_w_cls=None): """member.__get__(obj[, type]) -> value Modified: pypy/dist/pypy/objspace/descroperation.py ============================================================================== --- pypy/dist/pypy/objspace/descroperation.py (original) +++ pypy/dist/pypy/objspace/descroperation.py Sun Mar 4 14:16:05 2007 @@ -8,10 +8,11 @@ def raiseattrerror(space, w_obj, name, w_descr=None): w_type = space.type(w_obj) + typename = w_type.getname(space, '?') if w_descr is None: - msg = "'%s' object has no attribute '%s'" %(w_type.name, name) + msg = "'%s' object has no attribute '%s'" % (typename, name) else: - msg = "'%s' object attribute '%s' is read-only" %(w_type.name, name) + msg = "'%s' object attribute '%s' is read-only" % (typename, name) raise OperationError(space.w_AttributeError, space.wrap(msg)) class Object: Modified: pypy/dist/pypy/objspace/std/stdtypedef.py ============================================================================== --- pypy/dist/pypy/objspace/std/stdtypedef.py (original) +++ pypy/dist/pypy/objspace/std/stdtypedef.py Sun Mar 4 14:16:05 2007 @@ -173,7 +173,7 @@ return prefix, list_of_typeorders def typeerrormsg(space, operatorsymbol, args_w): - type_names = [ space.type(w_arg).name for w_arg in args_w ] + type_names = [ space.type(w_arg).getname(space, '?') for w_arg in args_w ] if len(args_w) > 1: plural = 's' else: Modified: pypy/dist/pypy/objspace/std/stringobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/stringobject.py (original) +++ pypy/dist/pypy/objspace/std/stringobject.py Sun Mar 4 14:16:05 2007 @@ -335,7 +335,8 @@ raise OperationError( space.w_TypeError, space.wrap("sequence item %d: expected string, %s " - "found" % (i, space.type(w_s).name))) + "found" % (i, + space.type(w_s).getname(space, '?')))) l.append(space.str_w(w_s)) return space.wrap(self.join(l)) else: Modified: pypy/dist/pypy/objspace/std/typeobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/typeobject.py (original) +++ pypy/dist/pypy/objspace/std/typeobject.py Sun Mar 4 14:16:05 2007 @@ -347,7 +347,7 @@ if not isinstance(w_subtype, W_TypeObject): raise OperationError(space.w_TypeError, space.wrap("X is not a type object (%s)" % ( - space.type(w_subtype).name))) + space.type(w_subtype).getname(space, '?')))) if not space.is_true(space.issubtype(w_subtype, w_self)): raise OperationError(space.w_TypeError, space.wrap("%s.__new__(%s): %s is not a subtype of %s" % ( Modified: pypy/dist/pypy/objspace/std/typetype.py ============================================================================== --- pypy/dist/pypy/objspace/std/typetype.py (original) +++ pypy/dist/pypy/objspace/std/typetype.py Sun Mar 4 14:16:05 2007 @@ -52,7 +52,8 @@ from pypy.objspace.std.typeobject import W_TypeObject if not isinstance(w_type, W_TypeObject): raise OperationError(space.w_TypeError, - space.wrap("X is not a type object (%s)" % (space.type(w_type).name))) + space.wrap("X is not a type object (%s)" % + (space.type(w_type).getname(space, '?')))) return w_type def _check(space, w_type, msg=None): @@ -144,8 +145,10 @@ w_type.name)) if not space.is_true(space.isinstance(w_value, space.w_tuple)): raise OperationError(space.w_TypeError, - space.wrap("can only assign tuple to %s.__bases__, not %s"% - (w_type.name, space.type(w_value).name))) + space.wrap("can only assign tuple" + " to %s.__bases__, not %s"% + (w_type.name, + space.type(w_value).getname(space, '?')))) if space.int_w(space.len(w_value)) == 0: raise OperationError(space.w_TypeError, space.wrap("can only assign non-empty tuple to %s.__bases__, not ()"% @@ -156,8 +159,11 @@ w_typ = space.type(w_base) if not space.is_w(w_typ, space.w_classobj): raise OperationError(space.w_TypeError, - space.wrap("%s.__bases__ must be tuple of old- or new-style classes, not '%s'"% - (w_type.name, w_typ.name))) + space.wrap("%s.__bases__ must be tuple " + "of old- or new-style classes" + ", not '%s'"% + (w_type.name, + w_typ.getname(space, '?')))) else: new_newstyle_bases.append(w_base) if space.is_true(space.issubtype(w_base, w_type)): From cfbolz at codespeak.net Sun Mar 4 14:19:22 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sun, 4 Mar 2007 14:19:22 +0100 (CET) Subject: [pypy-svn] r39880 - pypy/branch/rope-branch/pypy/objspace/std Message-ID: <20070304131922.003EB1007E@code0.codespeak.net> Author: cfbolz Date: Sun Mar 4 14:19:20 2007 New Revision: 39880 Modified: pypy/branch/rope-branch/pypy/objspace/std/ropeobject.py Log: be advanced: when two strings turn out to be equal and one has a cached hash, store it into the hash cache of the other one. Modified: pypy/branch/rope-branch/pypy/objspace/std/ropeobject.py ============================================================================== --- pypy/branch/rope-branch/pypy/objspace/std/ropeobject.py (original) +++ pypy/branch/rope-branch/pypy/objspace/std/ropeobject.py Sun Mar 4 14:19:20 2007 @@ -804,23 +804,29 @@ n2 = w_str2._node return space.newbool(rope.compare(n1, n2) <= 0) -def eq__Rope_Rope(space, w_str1, w_str2): +def _eq(w_str1, w_str2): h1 = w_str1._hash h2 = w_str2._hash if h1 and h2 and h1 != h2: - return space.w_False + return False n1 = w_str1._node n2 = w_str2._node - return space.newbool(rope.eq(n1, n2)) + result = rope.eq(n1, n2) + if result: + if h1: + if not h2: + w_str2._hash = h1 + else: + if h2: + w_str1._hash = h2 + return result + + +def eq__Rope_Rope(space, w_str1, w_str2): + return space.newbool(_eq(w_str1, w_str2)) def ne__Rope_Rope(space, w_str1, w_str2): - h1 = w_str1._hash - h2 = w_str2._hash - if h1 and h2 and h1 != h2: - return space.w_True - n1 = w_str1._node - n2 = w_str2._node - return space.newbool(not rope.eq(n1, n2)) + return space.newbool(not _eq(w_str1, w_str2)) def gt__Rope_Rope(space, w_str1, w_str2): n1 = w_str1._node From gbrandl at codespeak.net Sun Mar 4 14:30:57 2007 From: gbrandl at codespeak.net (gbrandl at codespeak.net) Date: Sun, 4 Mar 2007 14:30:57 +0100 (CET) Subject: [pypy-svn] r39881 - pypy/branch/pypy-2.5/pypy/objspace/std Message-ID: <20070304133057.4984210080@code0.codespeak.net> Author: gbrandl Date: Sun Mar 4 14:30:48 2007 New Revision: 39881 Modified: pypy/branch/pypy-2.5/pypy/objspace/std/listmultiobject.py pypy/branch/pypy-2.5/pypy/objspace/std/listobject.py pypy/branch/pypy-2.5/pypy/objspace/std/listtype.py pypy/branch/pypy-2.5/pypy/objspace/std/slicetype.py Log: A few more int_w -> getindex_w changes. Modified: pypy/branch/pypy-2.5/pypy/objspace/std/listmultiobject.py ============================================================================== --- pypy/branch/pypy-2.5/pypy/objspace/std/listmultiobject.py (original) +++ pypy/branch/pypy-2.5/pypy/objspace/std/listmultiobject.py Sun Mar 4 14:30:48 2007 @@ -892,7 +892,7 @@ return wrapint(space, result) def getitem__ListMulti_ANY(space, w_list, w_index): - idx = space.int_w(w_index) + idx = get_list_index(space, w_index) idx = _adjust_index(space, idx, w_list.implementation.length(), "list index out of range") return w_list.implementation.getitem(idx) @@ -1025,7 +1025,7 @@ w_list2.implementation) def delitem__ListMulti_ANY(space, w_list, w_idx): - idx = space.int_w(w_idx) + idx = get_list_index(space, w_idx) length = w_list.implementation.length() idx = _adjust_index(space, idx, length, "list deletion index out of range") if length == 1: @@ -1059,7 +1059,7 @@ return space.w_None def setitem__ListMulti_ANY_ANY(space, w_list, w_index, w_any): - idx = space.int_w(w_index) + idx = get_list_index(space, 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) Modified: pypy/branch/pypy-2.5/pypy/objspace/std/listobject.py ============================================================================== --- pypy/branch/pypy-2.5/pypy/objspace/std/listobject.py (original) +++ pypy/branch/pypy-2.5/pypy/objspace/std/listobject.py Sun Mar 4 14:30:48 2007 @@ -1,5 +1,6 @@ from pypy.objspace.std.objspace import * from pypy.objspace.std.inttype import wrapint +from pypy.objspace.std.listtype import get_list_index from pypy.objspace.std.sliceobject import W_SliceObject from pypy.objspace.std.tupleobject import W_TupleObject @@ -26,15 +27,6 @@ registerimplementation(W_ListObject) -def get_list_index(space, w_index): - if not space.lookup(w_index, '__index__'): - raise OperationError( - space.w_TypeError, - space.wrap("list indices must be integers, not %s" % - space.type(w_index).getname(space, '?'))) - return space.getindex_w(w_index, space.w_IndexError) - - EMPTY_LIST = W_ListObject([]) def init__List(space, w_list, __args__): @@ -179,7 +171,7 @@ w_list2.wrappeditems) def delitem__List_ANY(space, w_list, w_idx): - idx = get_list_index(space, w_list) + idx = get_list_index(space, w_idx) try: del w_list.wrappeditems[idx] except IndexError: Modified: pypy/branch/pypy-2.5/pypy/objspace/std/listtype.py ============================================================================== --- pypy/branch/pypy-2.5/pypy/objspace/std/listtype.py (original) +++ pypy/branch/pypy-2.5/pypy/objspace/std/listtype.py Sun Mar 4 14:30:48 2007 @@ -61,3 +61,13 @@ __hash__ = no_hash_descr, ) list_typedef.registermethods(globals()) + +# ____________________________________________________________ + +def get_list_index(space, w_index): + if not space.lookup(w_index, '__index__'): + raise OperationError( + space.w_TypeError, + space.wrap("list indices must be integers, not %s" % + space.type(w_index).getname(space, '?'))) + return space.getindex_w(w_index, space.w_IndexError) Modified: pypy/branch/pypy-2.5/pypy/objspace/std/slicetype.py ============================================================================== --- pypy/branch/pypy-2.5/pypy/objspace/std/slicetype.py (original) +++ pypy/branch/pypy-2.5/pypy/objspace/std/slicetype.py Sun Mar 4 14:30:48 2007 @@ -16,7 +16,7 @@ # utility functions def _Eval_SliceIndex(space, w_int): try: - x = space.int_w(w_int) + x = space.getindex_w(w_int) # clamp if long integer is too large except OperationError, e: if not e.match(space, space.w_OverflowError): raise From gbrandl at codespeak.net Sun Mar 4 14:57:59 2007 From: gbrandl at codespeak.net (gbrandl at codespeak.net) Date: Sun, 4 Mar 2007 14:57:59 +0100 (CET) Subject: [pypy-svn] r39884 - pypy/branch/pypy-2.5/pypy/objspace/std Message-ID: <20070304135759.AE45110098@code0.codespeak.net> Author: gbrandl Date: Sun Mar 4 14:57:57 2007 New Revision: 39884 Modified: pypy/branch/pypy-2.5/pypy/objspace/std/listmultiobject.py pypy/branch/pypy-2.5/pypy/objspace/std/listtype.py Log: Missing imports. Modified: pypy/branch/pypy-2.5/pypy/objspace/std/listmultiobject.py ============================================================================== --- pypy/branch/pypy-2.5/pypy/objspace/std/listmultiobject.py (original) +++ pypy/branch/pypy-2.5/pypy/objspace/std/listmultiobject.py Sun Mar 4 14:57:57 2007 @@ -1,5 +1,6 @@ from pypy.objspace.std.objspace import * from pypy.objspace.std.inttype import wrapint +from pypy.objspace.std.listtype import get_list_index from pypy.objspace.std.sliceobject import W_SliceObject from pypy.objspace.std import slicetype Modified: pypy/branch/pypy-2.5/pypy/objspace/std/listtype.py ============================================================================== --- pypy/branch/pypy-2.5/pypy/objspace/std/listtype.py (original) +++ pypy/branch/pypy-2.5/pypy/objspace/std/listtype.py Sun Mar 4 14:57:57 2007 @@ -1,5 +1,6 @@ from __future__ import generators from pypy.interpreter import gateway +from pypy.interpreter.error import OperationError from pypy.objspace.std.stdtypedef import * from pypy.objspace.std.register_all import register_all from sys import maxint From gbrandl at codespeak.net Sun Mar 4 15:11:31 2007 From: gbrandl at codespeak.net (gbrandl at codespeak.net) Date: Sun, 4 Mar 2007 15:11:31 +0100 (CET) Subject: [pypy-svn] r39885 - pypy/branch/pypy-2.5/pypy/config Message-ID: <20070304141131.C552F1009D@code0.codespeak.net> Author: gbrandl Date: Sun Mar 4 15:11:29 2007 New Revision: 39885 Modified: pypy/branch/pypy-2.5/pypy/config/pypyoption.py Log: operator must be in the default modules. Modified: pypy/branch/pypy-2.5/pypy/config/pypyoption.py ============================================================================== --- pypy/branch/pypy-2.5/pypy/config/pypyoption.py (original) +++ pypy/branch/pypy-2.5/pypy/config/pypyoption.py Sun Mar 4 15:11:29 2007 @@ -17,7 +17,7 @@ default_modules = essential_modules.copy() default_modules.update(dict.fromkeys( ["_codecs", "gc", "_weakref", "array", "marshal", "errno", - "math", "_sre", "_pickle_support", + "math", "_sre", "_pickle_support", "operator", "recparser", "symbol", "_random", "pypymagic"])) From ac at codespeak.net Sun Mar 4 15:18:44 2007 From: ac at codespeak.net (ac at codespeak.net) Date: Sun, 4 Mar 2007 15:18:44 +0100 (CET) Subject: [pypy-svn] r39886 - pypy/dist/pypy/rlib Message-ID: <20070304141844.F1BA81009F@code0.codespeak.net> Author: ac Date: Sun Mar 4 15:18:42 2007 New Revision: 39886 Modified: pypy/dist/pypy/rlib/rsocket.py Log: (rxe, arre) Add explicit keepalives to work around rctypes not doing The Right Thing. Modified: pypy/dist/pypy/rlib/rsocket.py ============================================================================== --- pypy/dist/pypy/rlib/rsocket.py (original) +++ pypy/dist/pypy/rlib/rsocket.py Sun Mar 4 15:18:42 2007 @@ -329,6 +329,7 @@ sun.sun_path[len(path)] = 0 for i in range(len(path)): sun.sun_path[i] = ord(path[i]) + self.sun = sun self.addr = cast(pointer(sun), _c.sockaddr_ptr).contents self.addrlen = offsetof(_c.sockaddr_un, 'sun_path') + len(path) @@ -375,6 +376,7 @@ addr = _c.sockaddr_nl(nl_family = AF_NETLINK) addr.nl_pid = pid addr.nl_groups = groups + self._addr_keepalive_netlink = addr self.addr = cast(pointer(addr), _c.sockaddr_ptr).contents self.addrlen = sizeof(addr) @@ -416,7 +418,7 @@ result = instantiate(familyclass(family)) elif result.family != family: raise RSocketError("address family mismatched") - paddr = copy_buffer(cast(addrptr, POINTER(c_char)), addrlen) + paddr = result._addr_keepalive0 = copy_buffer(cast(addrptr, POINTER(c_char)), addrlen) result.addr = cast(paddr, _c.sockaddr_ptr).contents result.addrlen = addrlen return result @@ -429,6 +431,7 @@ sin = _c.sockaddr_in(sin_family = AF_INET) # PLAT sin_len sin.sin_addr.s_addr = s_addr paddr = cast(pointer(sin), _c.sockaddr_ptr) + result._addr_keepalive1 = sin result.addr = paddr.contents result.addrlen = sizeof(_c.sockaddr_in) return result @@ -437,6 +440,7 @@ klass = familyclass(family) buf = create_string_buffer(klass.maxlen) result = instantiate(klass) + result._addr_keepalive2 = buf result.addr = cast(buf, _c.sockaddr_ptr).contents result.addrlen = 0 return result, len(buf) From guido at codespeak.net Sun Mar 4 15:26:14 2007 From: guido at codespeak.net (guido at codespeak.net) Date: Sun, 4 Mar 2007 15:26:14 +0100 (CET) Subject: [pypy-svn] r39887 - in pypy/dist/pypy/translator/js/modules: . test Message-ID: <20070304142614.44231100A3@code0.codespeak.net> Author: guido Date: Sun Mar 4 15:26:11 2007 New Revision: 39887 Modified: pypy/dist/pypy/translator/js/modules/dom.py pypy/dist/pypy/translator/js/modules/mochikit.py pypy/dist/pypy/translator/js/modules/test/test_dom.py Log: Added window.navigator (for navigator.appName) in dom and Signal.disconnectAll in mochikit. 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 Sun Mar 4 15:26:11 2007 @@ -280,6 +280,10 @@ 'toString' : MethodDesc([], str), } +class Navigator(BasicExternal): + def __init__(self): + self.appName = 'Netscape' + class Window(EventTarget): def __init__(self, html=('Untitled document' ''), parent=None): @@ -304,6 +308,8 @@ self._original = self # for EventTarget interface (XXX a bit nasty) + self.navigator = Navigator() + def __getattr__(self, name): return globals()[name] @@ -538,6 +544,7 @@ 'status' : str, 'top' : Window, 'window' : Window, + 'navigator': Navigator, }) Window._methods = Node._methods.copy() @@ -717,6 +724,12 @@ KeyEvent._fields = Event._fields.copy() +Navigator._methods = { +} +Navigator._fields = { + 'appName': str, +} + class _FunctionWrapper(object): """makes sure function return values are wrapped if appropriate""" def __init__(self, callable): 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 Sun Mar 4 15:26:11 2007 @@ -61,7 +61,7 @@ def connect(src, signal, dest): - print 'connecting event %s' % (event,) + print 'connecting signal %s' % (signal,) register_external(connect, args=[dom.EventTarget, str, _callable([Event])], result=int) @@ -69,3 +69,7 @@ pass register_external(disconnect, args=[int]) +def disconnectAll(src, signal): + print 'disconnecting all handlers for signal: %s' % (signal,) +register_external(disconnectAll, args=[dom.EventTarget, str]) + 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 Sun Mar 4 15:26:11 2007 @@ -379,3 +379,7 @@ assert rpython2javascript(sys.modules[__name__], [var], use_pdb=True) TRANSLATING = False + +def test_navigator(): + window = get_window() + assert window.navigator.appName == 'Netscape' From asigfrid at codespeak.net Sun Mar 4 15:38:22 2007 From: asigfrid at codespeak.net (asigfrid at codespeak.net) Date: Sun, 4 Mar 2007 15:38:22 +0100 (CET) Subject: [pypy-svn] r39888 - pypy/branch/pypy-2.5/pypy/module/operator Message-ID: <20070304143822.C634810036@code0.codespeak.net> Author: asigfrid Date: Sun Mar 4 15:38:20 2007 New Revision: 39888 Modified: pypy/branch/pypy-2.5/pypy/module/operator/__init__.py pypy/branch/pypy-2.5/pypy/module/operator/app_operator.py pypy/branch/pypy-2.5/pypy/module/operator/interp_operator.py Log: Moved the directly translatable functions in operator from app to interpreter level. Modified: pypy/branch/pypy-2.5/pypy/module/operator/__init__.py ============================================================================== --- pypy/branch/pypy-2.5/pypy/module/operator/__init__.py (original) +++ pypy/branch/pypy-2.5/pypy/module/operator/__init__.py Sun Mar 4 15:38:20 2007 @@ -6,27 +6,33 @@ appleveldefs = {} - names = ['__abs__', '__add__', '__and__', - '__concat__', '__contains__', '__delitem__', '__delslice__', - '__div__', '__doc__', '__eq__', '__floordiv__', - '__ge__', '__getitem__', '__getslice__', '__gt__', '__inv__', - '__invert__', '__le__', '__lshift__', '__lt__', '__mod__', - '__mul__', '__name__', '__ne__', '__neg__', '__not__', '__or__', - '__pos__', '__pow__', '__repeat__', '__rshift__', '__setitem__', - '__setslice__', '__sub__', '__truediv__', '__xor__', 'abs', 'add', - 'and_', 'attrgetter', 'concat', 'contains', 'countOf', 'delitem', - 'delslice', 'div', 'division', 'eq', 'floordiv', 'ge', 'getitem', - 'getslice', 'gt', 'indexOf', 'inv', 'invert', 'isCallable', - 'isMappingType', 'isNumberType', 'isSequenceType', 'is_', - 'is_not', 'itemgetter', 'le', 'lshift', 'lt', 'mod', 'mul', - 'ne', 'neg', 'not_', 'or_', 'pos', 'pow', 'repeat', 'rshift', - 'sequenceIncludes', 'setitem', 'setslice', 'sub', 'truediv', - 'truth', 'xor'] + app_names = ['__delslice__', '__doc__','__getslice__', '__name__', + '__repeat__', '__setslice__', '__truediv__','attrgetter', + 'concat', 'contains', 'countOf', 'delitem', + 'delslice', 'division', 'getslice', 'indexOf', + 'isCallable','isMappingType', 'isNumberType', 'isSequenceType', + 'itemgetter','repeat', 'sequenceIncludes', 'setslice', + 'truediv'] - for name in names: + for name in app_names: appleveldefs[name] = 'app_operator.%s' % name - - - interpleveldefs = { - 'index': 'interp_operator.index' - } + + interp_names = ['index', '__abs__', '__add__', '__and__', + '__concat__', '__contains__', '__delitem__','__div__', + '__eq__', '__floordiv__', '__ge__', '__getitem__', + '__gt__', '__inv__', '__invert__', '__le__', + '__lshift__', '__lt__', '__mod__', '__mul__', + '__ne__', '__neg__', '__not__', '__or__', + '__pos__', '__pow__', '__rshift__', '__setitem__', + '__sub__', '__xor__', 'abs', 'add', + 'and_', 'div', 'eq', 'floordiv', + 'ge', 'getitem', 'gt', 'inv', + 'invert', 'is_', 'is_not', 'le', + 'lshift', 'lt', 'mod', 'mul', + 'ne', 'neg', 'not_', 'or_', + 'pos', 'pow', 'rshift', 'setitem', + 'sub', 'truth', 'xor'] + interpleveldefs = {} + + for name in interp_names: + interpleveldefs[name] = 'interp_operator.%s' % name Modified: pypy/branch/pypy-2.5/pypy/module/operator/app_operator.py ============================================================================== --- pypy/branch/pypy-2.5/pypy/module/operator/app_operator.py (original) +++ pypy/branch/pypy-2.5/pypy/module/operator/app_operator.py Sun Mar 4 15:38:20 2007 @@ -5,32 +5,11 @@ ''' import __builtin__ -def abs(obj,): - 'abs(a) -- Same as abs(a).' - return __builtin__.abs(obj) -__abs__ = abs -def add(obj1, obj2): - 'add(a, b) -- Same as a + b.' - return obj1 + obj2 -__add__ = add -def and_(obj1,obj2): - 'and_(a, b) -- Same as a & b.' - return obj1 & obj2 -__and__ = and_ def attrgetter(attr): def f(obj): return getattr(obj, attr) return f -def concat(obj1, obj2): - 'concat(a, b) -- Same as a + b, for a and b sequences.' - return obj1 + obj2 # XXX cPython only works on types with sequence api - # we support any with __add__ -__concat__ = concat - -def contains(obj1,obj2): - 'contains(a, b) -- Same as b in a (note reversed operands).' - return obj2 in obj1 -__contains__ = contains + def countOf(a,b): 'countOf(a, b) -- Return the number of times b occurs in a.' count = 0 @@ -38,46 +17,21 @@ if x == b: count += 1 return count -def delitem(obj, key): - 'delitem(a, b) -- Same as del a[b].' - del obj[key] -__delitem__ = delitem + def delslice(obj, start, end): 'delslice(a, b, c) -- Same as del a[b:c].' if not isinstance(start, int) or not isinstance(end, int): raise TypeError("an integer is expected") del obj[start:end] __delslice__ = delslice -def div(a,b): - 'div(a, b) -- Same as a / b when __future__.division is not in effect.' - return a / b -__div__ = div -def eq(a, b): - 'eq(a, b) -- Same as a==b.' - return a == b -__eq__ = eq -def floordiv(a, b): - 'floordiv(a, b) -- Same as a // b.' - return a // b -__floordiv__ = floordiv -def ge(a, b): - 'ge(a, b) -- Same as a>=b.' - return a >= b -__ge__ = ge -def getitem(a, b): - 'getitem(a, b) -- Same as a[b].' - return a[b] -__getitem__ = getitem + def getslice(a, start, end): 'getslice(a, b, c) -- Same as a[b:c].' if not isinstance(start, int) or not isinstance(end, int): raise TypeError("an integer is expected") return a[start:end] __getslice__ = getslice -def gt(a,b): - 'gt(a, b) -- Same as a>b.' - return a > b -__gt__ = gt + def indexOf(a, b): 'indexOf(a, b) -- Return the first index of b in a.' index = 0 @@ -86,14 +40,7 @@ return index index += 1 raise ValueError, 'sequence.index(x): x not in sequence' -def inv(obj,): - 'inv(a) -- Same as ~a.' - return ~obj -__inv__ = inv -def invert(obj,): - 'invert(a) -- Same as ~a.' - return ~obj -__invert__ = invert + def isCallable(obj,): 'isCallable(a) -- Same as callable(a).' return callable(obj) @@ -103,68 +50,20 @@ 'isMappingType(a) -- Return True if a has a mapping type, False otherwise.' # XXX this is fragile and approximative anyway return hasattr(obj, '__getitem__') and hasattr(obj, 'keys') + def isNumberType(obj,): 'isNumberType(a) -- Return True if a has a numeric type, False otherwise.' - return hasattr(obj, '__int__') or hasattr(obj, '__float__') + return hasattr(obj, '__int__') or hasattr(obj, '__float__') + def isSequenceType(obj,): 'isSequenceType(a) -- Return True if a has a sequence type, False otherwise.' return hasattr(obj, '__getitem__') -def is_(a, b): - 'is_(a, b) -- Same as a is b.' - return a is b -def is_not(a, b): - 'is_not(a, b) -- Same as a is not b.' - return a is not b def itemgetter(idx): def f(obj): return obj[idx] return f -def le(a, b): - 'le(a, b) -- Same as a<=b.' - return a <= b -__le__ = le -def lshift(a, b): - 'lshift(a, b) -- Same as a << b.' - return a << b -__lshift__ = lshift -def lt(a, b): - 'lt(a, b) -- Same as a> b.' - return a >> b -__rshift__ = rshift def sequenceIncludes(a, b): 'sequenceIncludes(a, b) -- Same as b in a (note reversed operands; deprecated).' for x in a: if x == b: return True return False -def setitem(obj, key, value): - 'setitem(a, b, c) -- Same as a[b] = c.' - obj[key] = value -__setitem__ = setitem + def setslice(a, b, c, d): 'setslice(a, b, c, d) -- Same as a[b:c] = d.' a[b:c] = d __setslice__ = setslice -def sub(a, b): - 'sub(a, b) -- Same as a - b.' - return a - b -__sub__ = sub exec """from __future__ import division def truediv(a, b): @@ -202,10 +90,3 @@ return a / b """ __truediv__ = truediv -def truth(a,): - 'truth(a) -- Return True if a is true, False otherwise.' - return not not a -def xor(a, b): - 'xor(a, b) -- Same as a ^ b.' - return a ^ b -__xor__ = xor Modified: pypy/branch/pypy-2.5/pypy/module/operator/interp_operator.py ============================================================================== --- pypy/branch/pypy-2.5/pypy/module/operator/interp_operator.py (original) +++ pypy/branch/pypy-2.5/pypy/module/operator/interp_operator.py Sun Mar 4 15:38:20 2007 @@ -1,4 +1,3 @@ - def index(space, w_a): return space.index(w_a) @@ -7,3 +6,183 @@ return space.abs(w_obj) __abs__ = abs + +def add(space, w_obj1, w_obj2): + 'add(a, b) -- Same as a a + b' + return space.add(w_obj1, w_obj2) +__add__ = add + +def and_(space, w_obj1, w_obj2): + 'and_(a, b) -- Same as a a & b' + return space.and_(w_obj1, w_obj2) +__and__ = and_ + +# attrgetter + +def concat(space, w_obj1, w_obj2): + 'concat(a, b) -- Same as a a + b, for a and b sequences.' + return space.add(w_obj1, w_obj2) # XXX cPython only works on types with sequence api + # we support any with __add__ +__concat__ = concat + +def contains(space, w_obj1, w_obj2): + 'contains(a, b) -- Same as b in a (note reversed operands).' + return space.contains(w_obj1, w_obj2) +__contains__ = contains + +# countOf + +def delitem(space, w_obj, w_key): + 'delitem(a,b) -- Same as del a[b]' + space.delete(w_obj, w_key) + +__delitem__ = delitem + +# delslice + +def div(space, w_a, w_b): + 'div(a, b) -- Same as a / b when __future__.division is no in effect' + return space.div(w_a, w_b) +__div__ = div + +def eq(space, w_a, w_b): + 'eq(a, b) -- Same as a==b' + return space.eq(w_a, w_b) +__eq__ = eq + +def floordiv(space, w_a, w_b): + 'floordiv(a, b) -- Same as a // b.' + return space.floordiv(w_a, w_b) +__floordiv__ = floordiv + +def ge(space, w_a, w_b): + 'ge(a, b) -- Same as a>=b.' + return space.ge(w_a, w_b) +__ge__ = ge + +def getitem(space, w_a, w_b): + 'getitem(a, b) -- Same as a[b].' + return space.getitem(w_a, w_b) +__getitem__ = getitem + +# getslice + +def gt(space, w_a, w_b): + 'gt(a, b) -- Same as a>b.' + return space.gt(w_a, w_b) +__gt__ = gt + +# indexOf + +def inv(space, w_obj,): + 'inv(a) -- Same as ~a.' + return space.invert(w_obj) +__inv__ = inv + +def invert(space, w_obj,): + 'invert(a) -- Same as ~a.' + return space.invert(w_obj) +__invert__ = invert + +# isCallable + +# isMappingType + +# isNumberType + +# isSequenceType + +def _is(space, w_a, w_b): + 'is_(a,b) -- Same as a is b' + return space.is_(w_a, w_b) + +def is_not(space, w_a, w_b): + 'is_not(a, b) -- Same as a is not b' + return space.not_(space.is_(w_a, w_b)) + +# itemgetter + +def le(space, w_a, w_b): + 'le(a, b) -- Same as a<=b.' + return space.le(w_a, w_b) +__le__ = le + +def lshift(space, w_a, w_b): + 'lshift(a, b) -- Same as a << b.' + return space.lshift(w_a, w_b) +__lshift__ = lshift + +def lt(space, w_a, w_b): + 'lt(a, b) -- Same as a> b.' + return space.rshift(w_a, w_b) +__rshift__ = rshift + +# sequenceIncludes + +def setitem(space, w_obj, w_key, w_value): + 'setitem(a, b, c) -- Same as a[b] = c.' + space.setitem(w_obj, w_key, w_value) +__setitem__ = setitem + +# setslice + +def sub(space, w_a, w_b): + 'sub(a, b) -- Same as a - b.' + return space.sub(w_a, w_b) +__sub__ = sub + +def truth(space, w_a,): + 'truth(a) -- Return True if a is true, False otherwise.' + return space.is_true(w_a) + +def xor(space, w_a, w_b): + 'xor(a, b) -- Same as a ^ b.' + return space.xor(w_a, w_b) +__xor__ = xor From fijal at codespeak.net Sun Mar 4 15:42:58 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 4 Mar 2007 15:42:58 +0100 (CET) Subject: [pypy-svn] r39889 - pypy/dist/pypy/rpython Message-ID: <20070304144258.14FEC10081@code0.codespeak.net> Author: fijal Date: Sun Mar 4 15:42:55 2007 New Revision: 39889 Modified: pypy/dist/pypy/rpython/extfuncregistry.py Log: (fijal, pedronis) Import module/ll_os early enough Modified: pypy/dist/pypy/rpython/extfuncregistry.py ============================================================================== --- pypy/dist/pypy/rpython/extfuncregistry.py (original) +++ pypy/dist/pypy/rpython/extfuncregistry.py Sun Mar 4 15:42:55 2007 @@ -9,6 +9,7 @@ from pypy.rpython.lltypesystem.module import ll_math from pypy.rpython.ootypesystem.module import ll_math as oo_math +from pypy.rpython.module import ll_os # the following functions all take one float, return one float # and are part of math.h From arigo at codespeak.net Sun Mar 4 15:43:08 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 4 Mar 2007 15:43:08 +0100 (CET) Subject: [pypy-svn] r39890 - in pypy/dist/pypy/translator/c: . test Message-ID: <20070304144308.3A36F10084@code0.codespeak.net> Author: arigo Date: Sun Mar 4 15:43:06 2007 New Revision: 39890 Modified: pypy/dist/pypy/translator/c/genc.py pypy/dist/pypy/translator/c/test/test_genc.py Log: * compile with -g in "make profile": necessary to have the results properly reported! * honor --view in the compile() genc tests in general. Modified: pypy/dist/pypy/translator/c/genc.py ============================================================================== --- pypy/dist/pypy/translator/c/genc.py (original) +++ pypy/dist/pypy/translator/c/genc.py Sun Mar 4 15:43:06 2007 @@ -871,7 +871,7 @@ \tmake CFLAGS="-g -DRPY_ASSERT -DNO_OBMALLOC" profile: -\tmake CFLAGS="-pg $(CFLAGS)" LDFLAGS="-pg $(LDFLAGS)" +\tmake CFLAGS="-g -pg $(CFLAGS)" LDFLAGS="-pg $(LDFLAGS)" profopt: \tmake CFLAGS="-fprofile-generate $(CFLAGS)" LDFLAGS="-fprofile-generate $(LDFLAGS)" Modified: pypy/dist/pypy/translator/c/test/test_genc.py ============================================================================== --- pypy/dist/pypy/translator/c/test/test_genc.py (original) +++ pypy/dist/pypy/translator/c/test/test_genc.py Sun Mar 4 15:43:06 2007 @@ -40,6 +40,8 @@ # XXX fish t.driver.config.translation.countmallocs = True compiled_fn = t.compile_c() + if conftest.option.view: + t.view() # XXX fish fish fish some more module = t.driver.cbuilder.c_ext_module def checking_fn(*args, **kwds): From xoraxax at codespeak.net Sun Mar 4 15:43:46 2007 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sun, 4 Mar 2007 15:43:46 +0100 (CET) Subject: [pypy-svn] r39891 - pypy/branch/pypy-2.5/pypy/lib Message-ID: <20070304144346.D33CB1006E@code0.codespeak.net> Author: xoraxax Date: Sun Mar 4 15:43:45 2007 New Revision: 39891 Added: pypy/branch/pypy-2.5/pypy/lib/_functools.py Log: Add a basic partial class in lib/_functools. The standard lib of Python 2.5 is needed to make it usable. Added: pypy/branch/pypy-2.5/pypy/lib/_functools.py ============================================================================== --- (empty file) +++ pypy/branch/pypy-2.5/pypy/lib/_functools.py Sun Mar 4 15:43:45 2007 @@ -0,0 +1,171 @@ +""" Supplies the internal functions for functools.py in the standard library """ + +class partial: + def __init__(self, func, *args, **keywords): + self.func = func + self.args = args + self.keywords = keywords + + def __call__(self, *fargs, **fkeywords): + newkeywords = self.keywords.copy() + newkeywords.update(fkeywords) + return self.func(*(self.args + fargs), **newkeywords) + +# XXX ------------- cut here + +import unittest +from test import test_support +from weakref import proxy + +def capture(*args, **kw): + """capture all positional and keyword arguments""" + return args, kw + +class TestPartial(unittest.TestCase): + + thetype = partial + + def test_basic_examples(self): + p = self.thetype(capture, 1, 2, a=10, b=20) + self.assertEqual(p(3, 4, b=30, c=40), + ((1, 2, 3, 4), dict(a=10, b=30, c=40))) + p = self.thetype(map, lambda x: x*10) + self.assertEqual(p([1,2,3,4]), [10, 20, 30, 40]) + + def test_attributes(self): + p = self.thetype(capture, 1, 2, a=10, b=20) + # attributes should be readable + self.assertEqual(p.func, capture) + self.assertEqual(p.args, (1, 2)) + self.assertEqual(p.keywords, dict(a=10, b=20)) + # attributes should not be writable + if not isinstance(self.thetype, type): + return + self.assertRaises(TypeError, setattr, p, 'func', map) + self.assertRaises(TypeError, setattr, p, 'args', (1, 2)) + self.assertRaises(TypeError, setattr, p, 'keywords', dict(a=1, b=2)) + + def test_argument_checking(self): + self.assertRaises(TypeError, self.thetype) # need at least a func arg + try: + self.thetype(2)() + except TypeError: + pass + else: + self.fail('First arg not checked for callability') + + def test_protection_of_callers_dict_argument(self): + # a caller's dictionary should not be altered by partial + def func(a=10, b=20): + return a + d = {'a':3} + p = self.thetype(func, a=5) + self.assertEqual(p(**d), 3) + self.assertEqual(d, {'a':3}) + p(b=7) + self.assertEqual(d, {'a':3}) + + def test_arg_combinations(self): + # exercise special code paths for zero args in either partial + # object or the caller + p = self.thetype(capture) + self.assertEqual(p(), ((), {})) + self.assertEqual(p(1,2), ((1,2), {})) + p = self.thetype(capture, 1, 2) + self.assertEqual(p(), ((1,2), {})) + self.assertEqual(p(3,4), ((1,2,3,4), {})) + + def test_kw_combinations(self): + # exercise special code paths for no keyword args in + # either the partial object or the caller + p = self.thetype(capture) + self.assertEqual(p(), ((), {})) + self.assertEqual(p(a=1), ((), {'a':1})) + p = self.thetype(capture, a=1) + self.assertEqual(p(), ((), {'a':1})) + self.assertEqual(p(b=2), ((), {'a':1, 'b':2})) + # keyword args in the call override those in the partial object + self.assertEqual(p(a=3, b=2), ((), {'a':3, 'b':2})) + + def test_positional(self): + # make sure positional arguments are captured correctly + for args in [(), (0,), (0,1), (0,1,2), (0,1,2,3)]: + p = self.thetype(capture, *args) + expected = args + ('x',) + got, empty = p('x') + self.failUnless(expected == got and empty == {}) + + def test_keyword(self): + # make sure keyword arguments are captured correctly + for a in ['a', 0, None, 3.5]: + p = self.thetype(capture, a=a) + expected = {'a':a,'x':None} + empty, got = p(x=None) + self.failUnless(expected == got and empty == ()) + + def test_no_side_effects(self): + # make sure there are no side effects that affect subsequent calls + p = self.thetype(capture, 0, a=1) + args1, kw1 = p(1, b=2) + self.failUnless(args1 == (0,1) and kw1 == {'a':1,'b':2}) + args2, kw2 = p() + self.failUnless(args2 == (0,) and kw2 == {'a':1}) + + def test_error_propagation(self): + def f(x, y): + x / y + self.assertRaises(ZeroDivisionError, self.thetype(f, 1, 0)) + self.assertRaises(ZeroDivisionError, self.thetype(f, 1), 0) + self.assertRaises(ZeroDivisionError, self.thetype(f), 1, 0) + self.assertRaises(ZeroDivisionError, self.thetype(f, y=0), 1) + + def test_attributes(self): + p = self.thetype(hex) + try: + del p.__dict__ + except TypeError: + pass + else: + self.fail('partial object allowed __dict__ to be deleted') + + def test_weakref(self): + f = self.thetype(int, base=16) + p = proxy(f) + self.assertEqual(f.func, p.func) + f = None + self.assertRaises(ReferenceError, getattr, p, 'func') + + def test_with_bound_and_unbound_methods(self): + data = map(str, range(10)) + join = self.thetype(str.join, '') + self.assertEqual(join(data), '0123456789') + join = self.thetype(''.join) + self.assertEqual(join(data), '0123456789') + +class PartialSubclass(partial): + pass + +class TestPartialSubclass(TestPartial): + thetype = PartialSubclass + + +def test_main(verbose=None): + import sys + test_classes = ( + TestPartial, + TestPartialSubclass, + ) + test_support.run_unittest(*test_classes) + + # verify reference counting + if verbose and hasattr(sys, "gettotalrefcount"): + import gc + counts = [None] * 5 + for i in xrange(len(counts)): + test_support.run_unittest(*test_classes) + gc.collect() + counts[i] = sys.gettotalrefcount() + print counts + +if __name__ == '__main__': + test_main(verbose=True) From hpk at codespeak.net Sun Mar 4 15:54:55 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sun, 4 Mar 2007 15:54:55 +0100 (CET) Subject: [pypy-svn] r39893 - in pypy/dist/pypy/tool/bench: . test Message-ID: <20070304145455.856B610034@code0.codespeak.net> Author: hpk Date: Sun Mar 4 15:54:53 2007 New Revision: 39893 Added: pypy/dist/pypy/tool/bench/test/ pypy/dist/pypy/tool/bench/test/__init__.py (contents, props changed) pypy/dist/pypy/tool/bench/test/test_benchmark_report.py - copied, changed from r39879, pypy/dist/pypy/tool/bench/test_benchmark_report.py Removed: pypy/dist/pypy/tool/bench/test_benchmark_report.py Log: shift test to its own directory Added: pypy/dist/pypy/tool/bench/test/__init__.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/tool/bench/test/__init__.py Sun Mar 4 15:54:53 2007 @@ -0,0 +1 @@ +# From gbrandl at codespeak.net Sun Mar 4 16:06:28 2007 From: gbrandl at codespeak.net (gbrandl at codespeak.net) Date: Sun, 4 Mar 2007 16:06:28 +0100 (CET) Subject: [pypy-svn] r39894 - pypy/branch/pypy-2.5/pypy/module/operator Message-ID: <20070304150628.BF72610060@code0.codespeak.net> Author: gbrandl Date: Sun Mar 4 16:06:27 2007 New Revision: 39894 Modified: pypy/branch/pypy-2.5/pypy/module/operator/__init__.py pypy/branch/pypy-2.5/pypy/module/operator/app_operator.py pypy/branch/pypy-2.5/pypy/module/operator/interp_operator.py Log: (gbrandl, asigfrid) Some more moves to interp_operator. Modified: pypy/branch/pypy-2.5/pypy/module/operator/__init__.py ============================================================================== --- pypy/branch/pypy-2.5/pypy/module/operator/__init__.py (original) +++ pypy/branch/pypy-2.5/pypy/module/operator/__init__.py Sun Mar 4 16:06:27 2007 @@ -6,13 +6,11 @@ appleveldefs = {} - app_names = ['__delslice__', '__doc__','__getslice__', '__name__', - '__repeat__', '__setslice__', '__truediv__','attrgetter', - 'concat', 'contains', 'countOf', 'delitem', - 'delslice', 'division', 'getslice', 'indexOf', - 'isCallable','isMappingType', 'isNumberType', 'isSequenceType', - 'itemgetter','repeat', 'sequenceIncludes', 'setslice', - 'truediv'] + app_names = ['__delslice__', '__getslice__', '__repeat__', '__setslice__', + 'attrgetter', 'countOf', 'delslice', 'getslice', 'indexOf', + 'isMappingType', 'isNumberType', 'isSequenceType', + 'itemgetter','repeat', 'setslice', + ] for name in app_names: appleveldefs[name] = 'app_operator.%s' % name @@ -24,14 +22,14 @@ '__lshift__', '__lt__', '__mod__', '__mul__', '__ne__', '__neg__', '__not__', '__or__', '__pos__', '__pow__', '__rshift__', '__setitem__', - '__sub__', '__xor__', 'abs', 'add', - 'and_', 'div', 'eq', 'floordiv', + '__sub__', '__truediv__', '__xor__', 'abs', 'add', + 'and_', 'concat', 'contains', 'delitem', 'div', 'eq', 'floordiv', 'ge', 'getitem', 'gt', 'inv', - 'invert', 'is_', 'is_not', 'le', + 'invert', 'is_', 'is_not', 'isCallable', 'le', 'lshift', 'lt', 'mod', 'mul', 'ne', 'neg', 'not_', 'or_', - 'pos', 'pow', 'rshift', 'setitem', - 'sub', 'truth', 'xor'] + 'pos', 'pow', 'rshift', 'setitem', 'sequenceIncludes', + 'sub', 'truediv', 'truth', 'xor'] interpleveldefs = {} for name in interp_names: Modified: pypy/branch/pypy-2.5/pypy/module/operator/app_operator.py ============================================================================== --- pypy/branch/pypy-2.5/pypy/module/operator/app_operator.py (original) +++ pypy/branch/pypy-2.5/pypy/module/operator/app_operator.py Sun Mar 4 16:06:27 2007 @@ -1,9 +1,8 @@ -'''NOT_RPYTHON: Operator interface. +'''Operator interface. This module exports a set of operators as functions. E.g. operator.add(x,y) is equivalent to x+y. ''' -import __builtin__ def attrgetter(attr): def f(obj): @@ -41,10 +40,6 @@ index += 1 raise ValueError, 'sequence.index(x): x not in sequence' -def isCallable(obj,): - 'isCallable(a) -- Same as callable(a).' - return callable(obj) - # XXX the following is approximative def isMappingType(obj,): 'isMappingType(a) -- Return True if a has a mapping type, False otherwise.' @@ -72,21 +67,8 @@ # protocol. We support any with a __mul__ __repeat__ = repeat -def sequenceIncludes(a, b): - 'sequenceIncludes(a, b) -- Same as b in a (note reversed operands; deprecated).' - for x in a: - if x == b: - return True - return False - def setslice(a, b, c, d): 'setslice(a, b, c, d) -- Same as a[b:c] = d.' a[b:c] = d __setslice__ = setslice -exec """from __future__ import division -def truediv(a, b): - 'truediv(a, b) -- Same as a / b when __future__.division is in effect.' - return a / b -""" -__truediv__ = truediv Modified: pypy/branch/pypy-2.5/pypy/module/operator/interp_operator.py ============================================================================== --- pypy/branch/pypy-2.5/pypy/module/operator/interp_operator.py (original) +++ pypy/branch/pypy-2.5/pypy/module/operator/interp_operator.py Sun Mar 4 16:06:27 2007 @@ -29,12 +29,13 @@ 'contains(a, b) -- Same as b in a (note reversed operands).' return space.contains(w_obj1, w_obj2) __contains__ = contains +sequenceIncludes = contains # countOf def delitem(space, w_obj, w_key): 'delitem(a,b) -- Same as del a[b]' - space.delete(w_obj, w_key) + space.delitem(w_obj, w_key) __delitem__ = delitem @@ -84,7 +85,9 @@ return space.invert(w_obj) __invert__ = invert -# isCallable +def isCallable(space, w_obj): + 'isCallable(a) -- Same as callable(a).' + return space.callable(w_obj) # isMappingType @@ -92,7 +95,7 @@ # isSequenceType -def _is(space, w_a, w_b): +def is_(space, w_a, w_b): 'is_(a,b) -- Same as a is b' return space.is_(w_a, w_b) @@ -154,7 +157,7 @@ def pow(space, w_a, w_b): 'pow(a, b) -- Same as a**b.' - return space.pow(w_a, w_b) + return space.pow(w_a, w_b, space.w_None) __pow__ = pow # reapeat @@ -178,9 +181,14 @@ return space.sub(w_a, w_b) __sub__ = sub +def truediv(space, w_a, w_b): + 'truediv(a, b) -- Same as a / b when __future__.division is in effect.' + return space.truediv(w_a, w_b) +__truediv__ = truediv + def truth(space, w_a,): 'truth(a) -- Return True if a is true, False otherwise.' - return space.is_true(w_a) + return space.nonzero(w_a) def xor(space, w_a, w_b): 'xor(a, b) -- Same as a ^ b.' From hpk at codespeak.net Sun Mar 4 16:13:27 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sun, 4 Mar 2007 16:13:27 +0100 (CET) Subject: [pypy-svn] r39895 - in pypy/dist/pypy/tool/bench: . test Message-ID: <20070304151327.3193610060@code0.codespeak.net> Author: hpk Date: Sun Mar 4 16:13:25 2007 New Revision: 39895 Added: pypy/dist/pypy/tool/bench/pypyresult.py (contents, props changed) pypy/dist/pypy/tool/bench/test/test_pypyresult.py (contents, props changed) Log: added the start of pypy benchmark result parsing and tests Added: pypy/dist/pypy/tool/bench/pypyresult.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/tool/bench/pypyresult.py Sun Mar 4 16:13:25 2007 @@ -0,0 +1,37 @@ +import py + +class ResultDB(object): + def __init__(self): + self.benchmarks = [] + + def parsepickle(self, path): + f = path.open("rb") + id2numrun = py.std.pickle.load(f) + id2bestspeed = py.std.pickle.load(f) + f.close() + for id in id2numrun: + besttime = id2bestspeed[id] + numruns = id2numrun[id] + bench = BenchResult(id, besttime, numruns) + self.benchmarks.append(bench) + + def getbenchmarks(self, name=None): + l = [] + for bench in self.benchmarks: + if name is not None and name != bench.name: + continue + l.append(bench) + return l + +class BenchResult(object): + def __init__(self, id, besttime, numruns): + self._id = id + if id.startswith("./"): + id = id[2:] + parts = id.split("-") + self.name = parts.pop(-1) + self.backend = parts[1] + self.revision = int(parts[2]) + self.executable = "-".join(parts) + self.besttime = besttime + self.numruns = numruns Added: pypy/dist/pypy/tool/bench/test/test_pypyresult.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/tool/bench/test/test_pypyresult.py Sun Mar 4 16:13:25 2007 @@ -0,0 +1,34 @@ + +import py + +from pypy.tool.bench.pypyresult import ResultDB +import pickle + +def setup_module(mod): + mod.tmpdir = py.test.ensuretemp(__name__) + +def gettestpickle(cache=[]): + if cache: + return cache[0] + pp = tmpdir.join("testpickle") + f = pp.open("wb") + pickle.dump({'./pypy-llvm-39474-faassen-c_richards': 5}, f) + pickle.dump({'./pypy-llvm-39474-faassen-c_richards': 42.0}, f) + f.close() + cache.append(pp) + return pp + +def test_unpickle(): + pp = gettestpickle() + db = ResultDB() + db.parsepickle(pp) + assert len(db.benchmarks) == 1 + l = db.getbenchmarks(name="c_richards") + assert len(l) == 1 + bench = l[0] + assert bench.executable == "pypy-llvm-39474-faassen" + assert bench.name == "c_richards" + assert bench.revision == 39474 + assert bench.numruns == 5 + assert bench.besttime == 42.0 + From mwh at codespeak.net Sun Mar 4 16:15:01 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Sun, 4 Mar 2007 16:15:01 +0100 (CET) Subject: [pypy-svn] r39896 - pypy/dist/pypy/translator/c Message-ID: <20070304151501.ACEF010061@code0.codespeak.net> Author: mwh Date: Sun Mar 4 16:14:59 2007 New Revision: 39896 Modified: pypy/dist/pypy/translator/c/gc.py Log: make the decisions about which #defines to give to the boehm gc a bit saner. in particular, use GC_REDIRECT_TO_LOCAL all the time, which makes pypy-c about 5-10% faster on OS X (well, tuatara, at least...). someone should do a windows build, i guess... Modified: pypy/dist/pypy/translator/c/gc.py ============================================================================== --- pypy/dist/pypy/translator/c/gc.py (original) +++ pypy/dist/pypy/translator/c/gc.py Sun Mar 4 16:14:59 2007 @@ -216,21 +216,12 @@ def pre_pre_gc_code(self): if sys.platform == "linux2": - if self.thread_enabled or True: - yield "#define _REENTRANT 1" - yield "#define GC_LINUX_THREADS 1" - yield "#define GC_REDIRECT_TO_LOCAL 1" - yield "#define GC_I_HIDE_POINTERS 1" - yield '#include ' - yield '#define USING_BOEHM_GC' - else: - yield "#define GC_I_HIDE_POINTERS 1" - yield '#include ' - yield '#define USING_BOEHM_GC' - else: - yield "#define GC_I_HIDE_POINTERS 1" - yield '#include ' - yield '#define USING_BOEHM_GC' + yield "#define _REENTRANT 1" + yield "#define GC_LINUX_THREADS 1" + yield "#define GC_I_HIDE_POINTERS 1" + yield "#define GC_REDIRECT_TO_LOCAL 1" + yield '#include ' + yield '#define USING_BOEHM_GC' def pre_gc_code(self): return [] From xoraxax at codespeak.net Sun Mar 4 16:24:59 2007 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sun, 4 Mar 2007 16:24:59 +0100 (CET) Subject: [pypy-svn] r39899 - pypy/branch/pypy-2.5/pypy/module/operator Message-ID: <20070304152459.CB9A810061@code0.codespeak.net> Author: xoraxax Date: Sun Mar 4 16:24:57 2007 New Revision: 39899 Modified: pypy/branch/pypy-2.5/pypy/module/operator/app_operator.py Log: Document issue with geninterp. Modified: pypy/branch/pypy-2.5/pypy/module/operator/app_operator.py ============================================================================== --- pypy/branch/pypy-2.5/pypy/module/operator/app_operator.py (original) +++ pypy/branch/pypy-2.5/pypy/module/operator/app_operator.py Sun Mar 4 16:24:57 2007 @@ -1,4 +1,5 @@ -'''Operator interface. +'''NOT_RPYTHON: because of attrgetter and itemgetter +Operator interface. This module exports a set of operators as functions. E.g. operator.add(x,y) is equivalent to x+y. From gbrandl at codespeak.net Sun Mar 4 16:26:34 2007 From: gbrandl at codespeak.net (gbrandl at codespeak.net) Date: Sun, 4 Mar 2007 16:26:34 +0100 (CET) Subject: [pypy-svn] r39900 - pypy/branch/pypy-2.5/pypy/lib Message-ID: <20070304152634.54BC110061@code0.codespeak.net> Author: gbrandl Date: Sun Mar 4 16:26:31 2007 New Revision: 39900 Modified: pypy/branch/pypy-2.5/pypy/lib/_functools.py Log: Remove tests from _functools. Will be tested again when syncing the lib with 2.5. Modified: pypy/branch/pypy-2.5/pypy/lib/_functools.py ============================================================================== --- pypy/branch/pypy-2.5/pypy/lib/_functools.py (original) +++ pypy/branch/pypy-2.5/pypy/lib/_functools.py Sun Mar 4 16:26:31 2007 @@ -1,7 +1,15 @@ """ Supplies the internal functions for functools.py in the standard library """ class partial: + """ + partial(func, *args, **keywords) - new function with partial application + of the given arguments and keywords. + """ + __slots__ = ['func', 'args', 'keywords'] + def __init__(self, func, *args, **keywords): + if not callable(func): + raise TypeError("the first argument must be callable") self.func = func self.args = args self.keywords = keywords @@ -11,161 +19,3 @@ newkeywords.update(fkeywords) return self.func(*(self.args + fargs), **newkeywords) -# XXX ------------- cut here - -import unittest -from test import test_support -from weakref import proxy - -def capture(*args, **kw): - """capture all positional and keyword arguments""" - return args, kw - -class TestPartial(unittest.TestCase): - - thetype = partial - - def test_basic_examples(self): - p = self.thetype(capture, 1, 2, a=10, b=20) - self.assertEqual(p(3, 4, b=30, c=40), - ((1, 2, 3, 4), dict(a=10, b=30, c=40))) - p = self.thetype(map, lambda x: x*10) - self.assertEqual(p([1,2,3,4]), [10, 20, 30, 40]) - - def test_attributes(self): - p = self.thetype(capture, 1, 2, a=10, b=20) - # attributes should be readable - self.assertEqual(p.func, capture) - self.assertEqual(p.args, (1, 2)) - self.assertEqual(p.keywords, dict(a=10, b=20)) - # attributes should not be writable - if not isinstance(self.thetype, type): - return - self.assertRaises(TypeError, setattr, p, 'func', map) - self.assertRaises(TypeError, setattr, p, 'args', (1, 2)) - self.assertRaises(TypeError, setattr, p, 'keywords', dict(a=1, b=2)) - - def test_argument_checking(self): - self.assertRaises(TypeError, self.thetype) # need at least a func arg - try: - self.thetype(2)() - except TypeError: - pass - else: - self.fail('First arg not checked for callability') - - def test_protection_of_callers_dict_argument(self): - # a caller's dictionary should not be altered by partial - def func(a=10, b=20): - return a - d = {'a':3} - p = self.thetype(func, a=5) - self.assertEqual(p(**d), 3) - self.assertEqual(d, {'a':3}) - p(b=7) - self.assertEqual(d, {'a':3}) - - def test_arg_combinations(self): - # exercise special code paths for zero args in either partial - # object or the caller - p = self.thetype(capture) - self.assertEqual(p(), ((), {})) - self.assertEqual(p(1,2), ((1,2), {})) - p = self.thetype(capture, 1, 2) - self.assertEqual(p(), ((1,2), {})) - self.assertEqual(p(3,4), ((1,2,3,4), {})) - - def test_kw_combinations(self): - # exercise special code paths for no keyword args in - # either the partial object or the caller - p = self.thetype(capture) - self.assertEqual(p(), ((), {})) - self.assertEqual(p(a=1), ((), {'a':1})) - p = self.thetype(capture, a=1) - self.assertEqual(p(), ((), {'a':1})) - self.assertEqual(p(b=2), ((), {'a':1, 'b':2})) - # keyword args in the call override those in the partial object - self.assertEqual(p(a=3, b=2), ((), {'a':3, 'b':2})) - - def test_positional(self): - # make sure positional arguments are captured correctly - for args in [(), (0,), (0,1), (0,1,2), (0,1,2,3)]: - p = self.thetype(capture, *args) - expected = args + ('x',) - got, empty = p('x') - self.failUnless(expected == got and empty == {}) - - def test_keyword(self): - # make sure keyword arguments are captured correctly - for a in ['a', 0, None, 3.5]: - p = self.thetype(capture, a=a) - expected = {'a':a,'x':None} - empty, got = p(x=None) - self.failUnless(expected == got and empty == ()) - - def test_no_side_effects(self): - # make sure there are no side effects that affect subsequent calls - p = self.thetype(capture, 0, a=1) - args1, kw1 = p(1, b=2) - self.failUnless(args1 == (0,1) and kw1 == {'a':1,'b':2}) - args2, kw2 = p() - self.failUnless(args2 == (0,) and kw2 == {'a':1}) - - def test_error_propagation(self): - def f(x, y): - x / y - self.assertRaises(ZeroDivisionError, self.thetype(f, 1, 0)) - self.assertRaises(ZeroDivisionError, self.thetype(f, 1), 0) - self.assertRaises(ZeroDivisionError, self.thetype(f), 1, 0) - self.assertRaises(ZeroDivisionError, self.thetype(f, y=0), 1) - - def test_attributes(self): - p = self.thetype(hex) - try: - del p.__dict__ - except TypeError: - pass - else: - self.fail('partial object allowed __dict__ to be deleted') - - def test_weakref(self): - f = self.thetype(int, base=16) - p = proxy(f) - self.assertEqual(f.func, p.func) - f = None - self.assertRaises(ReferenceError, getattr, p, 'func') - - def test_with_bound_and_unbound_methods(self): - data = map(str, range(10)) - join = self.thetype(str.join, '') - self.assertEqual(join(data), '0123456789') - join = self.thetype(''.join) - self.assertEqual(join(data), '0123456789') - -class PartialSubclass(partial): - pass - -class TestPartialSubclass(TestPartial): - thetype = PartialSubclass - - -def test_main(verbose=None): - import sys - test_classes = ( - TestPartial, - TestPartialSubclass, - ) - test_support.run_unittest(*test_classes) - - # verify reference counting - if verbose and hasattr(sys, "gettotalrefcount"): - import gc - counts = [None] * 5 - for i in xrange(len(counts)): - test_support.run_unittest(*test_classes) - gc.collect() - counts[i] = sys.gettotalrefcount() - print counts - -if __name__ == '__main__': - test_main(verbose=True) From mwh at codespeak.net Sun Mar 4 17:45:46 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Sun, 4 Mar 2007 17:45:46 +0100 (CET) Subject: [pypy-svn] r39905 - pypy/dist/pypy/translator/c Message-ID: <20070304164546.393851006F@code0.codespeak.net> Author: mwh Date: Sun Mar 4 17:45:44 2007 New Revision: 39905 Modified: pypy/dist/pypy/translator/c/genc.py Log: very much a plaform hack, but good for 10-15% performance on OS X/PPC: compile standalone builds with -mdynamic-no-pic on OS X Modified: pypy/dist/pypy/translator/c/genc.py ============================================================================== --- pypy/dist/pypy/translator/c/genc.py (original) +++ pypy/dist/pypy/translator/c/genc.py Sun Mar 4 17:45:44 2007 @@ -1,5 +1,6 @@ import autopath import py +import sys from pypy.translator.c.node import PyObjectNode, PyObjHeadNode, FuncNode from pypy.translator.c.database import LowLevelDatabase from pypy.translator.c.extfunc import pre_include_code_lines @@ -241,6 +242,8 @@ assert self.c_source_filename assert not self._compiled compiler = self.getccompiler(extra_includes=[str(self.targetdir)]) + if sys.platform == 'darwin': + compiler.compile_extra.append('-mdynamic-no-pic') if self.config.translation.compilerflags: compiler.compile_extra.append(self.config.translation.compilerflags) if self.config.translation.linkerflags: @@ -265,6 +268,8 @@ prefix = ' ' * len(prefix) compiler = self.getccompiler(extra_includes=['.']) + if sys.platform == 'darwin': + compiler.compile_extra.append('-mdynamic-no-pic') if self.config.translation.compilerflags: compiler.compile_extra.append(self.config.translation.compilerflags) if self.config.translation.linkerflags: From antocuni at codespeak.net Sun Mar 4 18:25:03 2007 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Sun, 4 Mar 2007 18:25:03 +0100 (CET) Subject: [pypy-svn] r39906 - in pypy/dist/pypy: rpython/ootypesystem rpython/ootypesystem/test translator/cli/src Message-ID: <20070304172503.3051310060@code0.codespeak.net> Author: antocuni Date: Sun Mar 4 18:25:01 2007 New Revision: 39906 Modified: pypy/dist/pypy/rpython/ootypesystem/ootype.py pypy/dist/pypy/rpython/ootypesystem/rdict.py pypy/dist/pypy/rpython/ootypesystem/test/test_oodict.py pypy/dist/pypy/translator/cli/src/pypylib.cs Log: so far each RPython-dictionary lookup resulted in two CLI-dictionary-lookups: fix this. Other backends should be also fixed (it's not trivial for java, though). Modified: pypy/dist/pypy/rpython/ootypesystem/ootype.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/ootype.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/ootype.py Sun Mar 4 18:25:01 2007 @@ -499,6 +499,9 @@ self.VALUETYPE_T: self._VALUETYPE }) + # ll_get() is always used just after a call to ll_contains(), + # always with the same key, so backends can optimize/cache the + # result self._GENERIC_METHODS = frozendict({ "ll_length": Meth([], Signed), "ll_get": Meth([self.KEYTYPE_T], self.VALUETYPE_T), @@ -1188,15 +1191,17 @@ self._TYPE = DICT self._dict = {} self._stamp = 0 + self._last_key = object() # placeholder != to everything else def ll_length(self): # NOT_RPYTHON return len(self._dict) def ll_get(self, key): - # NOT_RPYTHON + # NOT_RPYTHON assert typeOf(key) == self._TYPE._KEYTYPE assert key in self._dict + assert key == self._last_key return self._dict[key] def ll_set(self, key, value): @@ -1219,6 +1224,7 @@ def ll_contains(self, key): # NOT_RPYTHON assert typeOf(key) == self._TYPE._KEYTYPE + self._last_key = key return key in self._dict def ll_clear(self): Modified: pypy/dist/pypy/rpython/ootypesystem/rdict.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/rdict.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/rdict.py Sun Mar 4 18:25:01 2007 @@ -299,7 +299,6 @@ def ll_dict_getitem(d, key): - # TODO: this is inefficient because it does two lookups if d.ll_contains(key): return d.ll_get(key) else: @@ -310,7 +309,6 @@ raise KeyError def ll_dict_get(d, key, default): - # TODO: this is inefficient because it does two lookups if d.ll_contains(key): return d.ll_get(key) else: @@ -339,7 +337,7 @@ r.item1 = it.ll_current_value() result.ll_setitem_fast(i, r) i += 1 - #assert i == length + assert i == length return result Modified: pypy/dist/pypy/rpython/ootypesystem/test/test_oodict.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/test/test_oodict.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/test/test_oodict.py Sun Mar 4 18:25:01 2007 @@ -17,6 +17,7 @@ DT = Dict(Signed, Float) d = new(DT) d.ll_set(42, 123.45) + assert d.ll_contains(42) assert d.ll_get(42) == 123.45 def test_iteritems(): @@ -49,3 +50,10 @@ assert isinstance(str(DT), str) assert isinstance(hash(DT), int) +def test_invalid_cache(): + DT = Dict(Signed, Signed) + d = new(DT) + py.test.raises(AssertionError, d.ll_get, 0) + d.ll_set(42, 1) + d.ll_contains(43) + py.test.raises(AssertionError, d.ll_get, 42) Modified: pypy/dist/pypy/translator/cli/src/pypylib.cs ============================================================================== --- pypy/dist/pypy/translator/cli/src/pypylib.cs (original) +++ pypy/dist/pypy/translator/cli/src/pypylib.cs Sun Mar 4 18:25:01 2007 @@ -440,6 +440,8 @@ public class Dict: System.Collections.Generic.Dictionary { IEqualityComparer comparer = null; + TValue cache; + public Dict() {} public Dict(IEqualityComparer comparer): base(comparer) { @@ -447,10 +449,10 @@ } public int ll_length() { return this.Count; } - public TValue ll_get(TKey key) { return this[key]; } + public TValue ll_get(TKey key) { return cache; } public void ll_set(TKey key, TValue value) { this[key] = value; } public bool ll_remove(TKey key) { return this.Remove(key); } - public bool ll_contains(TKey key) { return this.ContainsKey(key); } + public bool ll_contains(TKey key) { return this.TryGetValue(key, out cache); } public void ll_clear() { this.Clear(); } public DictItemsIterator ll_get_items_iterator() @@ -484,6 +486,7 @@ public void ll_set(TKey key) { this[key] = default(TValue); } public bool ll_remove(TKey key) { return this.Remove(key); } public bool ll_contains(TKey key) { return this.ContainsKey(key); } + public void ll_contains_get() { } public void ll_clear() { this.Clear(); } public DictItemsIterator ll_get_items_iterator() @@ -502,16 +505,26 @@ public class DictVoidVoid { - public int ll_length() { return 0; } + private int length = 0; + + public int ll_length() { return length; } public void ll_get() { } - public void ll_set() { } - public bool ll_remove() { return false; } // should it be true? - public bool ll_contains() { return false; } - public void ll_clear() { } + public void ll_set() { length = 1; } + public bool ll_remove() { + if (length == 0) + return false; + length = 0; + return true; + } + public bool ll_contains() { return length != 0; } + public void ll_contains_get() { } + public void ll_clear() { length = 0; } public DictItemsIterator ll_get_items_iterator() { List> foo = new List>(); + if (length == 1) + foo.Add(new KeyValuePair(0, 0)); return new DictItemsIterator(foo.GetEnumerator()); } } From gbrandl at codespeak.net Sun Mar 4 18:27:24 2007 From: gbrandl at codespeak.net (gbrandl at codespeak.net) Date: Sun, 4 Mar 2007 18:27:24 +0100 (CET) Subject: [pypy-svn] r39907 - in pypy/branch/pypy-2.5/pypy/objspace/std: . test Message-ID: <20070304172724.01F5310060@code0.codespeak.net> Author: gbrandl Date: Sun Mar 4 18:27:22 2007 New Revision: 39907 Modified: pypy/branch/pypy-2.5/pypy/objspace/std/stringobject.py pypy/branch/pypy-2.5/pypy/objspace/std/stringtype.py pypy/branch/pypy-2.5/pypy/objspace/std/strsliceobject.py pypy/branch/pypy-2.5/pypy/objspace/std/test/test_stringobject.py Log: Add str.partition and str.rpartition. Modified: pypy/branch/pypy-2.5/pypy/objspace/std/stringobject.py ============================================================================== --- pypy/branch/pypy-2.5/pypy/objspace/std/stringobject.py (original) +++ pypy/branch/pypy-2.5/pypy/objspace/std/stringobject.py Sun Mar 4 18:27:22 2007 @@ -393,19 +393,45 @@ return space.newbool(self.find(sub) >= 0) def str_find__String_String_ANY_ANY(space, w_self, w_sub, w_start, w_end): - (self, sub, start, end) = _convert_idx_params(space, w_self, w_sub, w_start, w_end) res = self.find(sub, start, end) return space.wrap(res) def str_rfind__String_String_ANY_ANY(space, w_self, w_sub, w_start, w_end): - (self, sub, start, end) = _convert_idx_params(space, w_self, w_sub, w_start, w_end) res = self.rfind(sub, start, end) return space.wrap(res) -def str_index__String_String_ANY_ANY(space, w_self, w_sub, w_start, w_end): +def str_partition__String_String(space, w_self, w_sub): + self = w_self._value + sub = w_sub._value + if not sub: + raise OperationError(space.w_ValueError, + space.wrap("empty separator")) + pos = self.find(sub) + if pos == -1: + return space.newtuple([w_self, space.wrap(''), space.wrap('')]) + else: + return space.newtuple([sliced(space, self, 0, pos), + w_sub, + sliced(space, self, pos+len(sub), len(self))]) + +def str_rpartition__String_String(space, w_self, w_sub): + self = w_self._value + sub = w_sub._value + if not sub: + raise OperationError(space.w_ValueError, + space.wrap("empty separator")) + pos = self.rfind(sub) + if pos == -1: + return space.newtuple([space.wrap(''), space.wrap(''), w_self]) + else: + return space.newtuple([sliced(space, self, 0, pos), + w_sub, + sliced(space, self, pos+len(sub), len(self))]) + +def str_index__String_String_ANY_ANY(space, w_self, w_sub, w_start, w_end): (self, sub, start, end) = _convert_idx_params(space, w_self, w_sub, w_start, w_end) res = self.find(sub, start, end) if res < 0: @@ -416,7 +442,6 @@ def str_rindex__String_String_ANY_ANY(space, w_self, w_sub, w_start, w_end): - (self, sub, start, end) = _convert_idx_params(space, w_self, w_sub, w_start, w_end) res = self.rfind(sub, start, end) if res < 0: @@ -427,7 +452,6 @@ def str_replace__String_String_String_ANY(space, w_self, w_sub, w_by, w_maxsplit=-1): - input = w_self._value sub = w_sub._value by = w_by._value Modified: pypy/branch/pypy-2.5/pypy/objspace/std/stringtype.py ============================================================================== --- pypy/branch/pypy-2.5/pypy/objspace/std/stringtype.py (original) +++ pypy/branch/pypy-2.5/pypy/objspace/std/stringtype.py Sun Mar 4 18:27:22 2007 @@ -133,6 +133,18 @@ ' s[start,end]. Optional\narguments start and end' ' are interpreted as in slice notation.\n\nReturn -1' ' on failure.') +str_partition = SMM('partition', 2, + doc='S.partition(sep) -> (head, sep, tail)\n\nSearches' + ' for the separator sep in S, and returns the part before' + ' it,\nthe separator itself, and the part after it. If' + ' the separator is not\nfound, returns S and two empty' + ' strings.') +str_rpartition = SMM('rpartition', 2, + doc='S.rpartition(sep) -> (tail, sep, head)\n\nSearches' + ' for the separator sep in S, starting at the end of S,' + ' and returns\nthe part before it, the separator itself,' + ' and the part after it. If the\nseparator is not found,' + ' returns two empty strings and S.') str_index = SMM('index', 4, defaults=(0, maxint), doc='S.index(sub [,start [,end]]) -> int\n\nLike S.find()' ' but raise ValueError when the substring is not' Modified: pypy/branch/pypy-2.5/pypy/objspace/std/strsliceobject.py ============================================================================== --- pypy/branch/pypy-2.5/pypy/objspace/std/strsliceobject.py (original) +++ pypy/branch/pypy-2.5/pypy/objspace/std/strsliceobject.py Sun Mar 4 18:27:22 2007 @@ -5,7 +5,7 @@ from pypy.objspace.std import slicetype from pypy.objspace.std.inttype import wrapint -from pypy.objspace.std.stringtype import wrapstr, wrapchar +from pypy.objspace.std.stringtype import wrapstr, wrapchar, sliced class W_StringSliceObject(W_Object): @@ -63,7 +63,6 @@ def str_find__StringSlice_String_ANY_ANY(space, w_self, w_sub, w_start, w_end): - (self, sub, start, end) = _convert_idx_params(space, w_self, w_sub, w_start, w_end) res = self.find(sub, start, end) if res >= 0: @@ -71,13 +70,41 @@ else: return space.wrap(res) +def str_partition__StringSlice_String(space, w_self, w_sub): + self = w_self.str + sub = w_sub._value + if not sub: + raise OperationError(space.w_ValueError, + space.wrap("empty separator")) + pos = self.find(sub, w_self.start, w_self.stop) + if pos == -1: + return space.newtuple([w_self, space.wrap(''), space.wrap('')]) + else: + return space.newtuple([sliced(space, self, w_self.start, pos), + w_sub, + sliced(space, self, pos+len(sub), w_self.stop)]) + +def str_rpartition__StringSlice_String(space, w_self, w_sub): + self = w_self.str + sub = w_sub._value + if not sub: + raise OperationError(space.w_ValueError, + space.wrap("empty separator")) + pos = self.rfind(sub, w_self.start, w_self.stop) + if pos == -1: + return space.newtuple([space.wrap(''), space.wrap(''), w_self]) + else: + return space.newtuple([sliced(space, self, w_self.start, pos), + w_sub, + sliced(space, self, pos+len(sub), w_self.stop)]) + + def str_count__StringSlice_String_ANY_ANY(space, w_self, w_arg, w_start, w_end): (s, arg, start, end) = _convert_idx_params( space, w_self, w_arg, w_start, w_end) return wrapint(space, s.count(arg, start, end)) def str_rfind__StringSlice_String_ANY_ANY(space, w_self, w_sub, w_start, w_end): - (self, sub, start, end) = _convert_idx_params(space, w_self, w_sub, w_start, w_end) res = self.rfind(sub, start, end) if res >= 0: @@ -86,7 +113,6 @@ return space.wrap(res) def str_index__StringSlice_String_ANY_ANY(space, w_self, w_sub, w_start, w_end): - (self, sub, start, end) = _convert_idx_params(space, w_self, w_sub, w_start, w_end) res = self.find(sub, start, end) if res < 0: @@ -97,7 +123,6 @@ def str_rindex__StringSlice_String_ANY_ANY(space, w_self, w_sub, w_start, w_end): - (self, sub, start, end) = _convert_idx_params(space, w_self, w_sub, w_start, w_end) res = self.rfind(sub, start, end) if res < 0: Modified: pypy/branch/pypy-2.5/pypy/objspace/std/test/test_stringobject.py ============================================================================== --- pypy/branch/pypy-2.5/pypy/objspace/std/test/test_stringobject.py (original) +++ pypy/branch/pypy-2.5/pypy/objspace/std/test/test_stringobject.py Sun Mar 4 18:27:22 2007 @@ -5,7 +5,7 @@ class TestW_StringObject: - def teardown_method(self,method): + def teardown_method(self, method): pass ## def test_order_rich(self): @@ -436,6 +436,36 @@ raises(TypeError, 'abcdefghijklmn'.rindex, 'abc', -10.0, 30) + def test_partition(self): + + assert ('this is the par', 'ti', 'tion method') == \ + 'this is the partition method'.partition('ti') + + # from raymond's original specification + S = 'http://www.python.org' + assert ('http', '://', 'www.python.org') == S.partition('://') + assert ('http://www.python.org', '', '') == S.partition('?') + assert ('', 'http://', 'www.python.org') == S.partition('http://') + assert ('http://www.python.', 'org', '') == S.partition('org') + + raises(ValueError, S.partition, '') + raises(TypeError, S.partition, None) + + def test_rpartition(self): + + assert ('this is the rparti', 'ti', 'on method') == \ + 'this is the rpartition method'.rpartition('ti') + + # from raymond's original specification + S = 'http://www.python.org' + assert ('http', '://', 'www.python.org') == S.rpartition('://') + assert ('', '', 'http://www.python.org') == S.rpartition('?') + assert ('', 'http://', 'www.python.org') == S.rpartition('http://') + assert ('http://www.python.', 'org', '') == S.rpartition('org') + + raises(ValueError, S.rpartition, '') + raises(TypeError, S.rpartition, None) + def test_split_maxsplit(self): assert "/a/b/c".split('/', 2) == ['','a','b/c'] assert "a/b/c".split("/") == ['a', 'b', 'c'] From cfbolz at codespeak.net Sun Mar 4 18:28:08 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sun, 4 Mar 2007 18:28:08 +0100 (CET) Subject: [pypy-svn] r39908 - in pypy/branch/rope-branch/pypy/objspace/std: . test Message-ID: <20070304172808.D93AF10068@code0.codespeak.net> Author: cfbolz Date: Sun Mar 4 18:28:06 2007 New Revision: 39908 Modified: pypy/branch/rope-branch/pypy/objspace/std/rope.py pypy/branch/rope-branch/pypy/objspace/std/test/test_rope.py Log: intermediate checkin: steps in the direction of "composable hashes", that compose the hash of a binary concatenation node out of the hashes of the two subtrees. Modified: pypy/branch/rope-branch/pypy/objspace/std/rope.py ============================================================================== --- pypy/branch/rope-branch/pypy/objspace/std/rope.py (original) +++ pypy/branch/rope-branch/pypy/objspace/std/rope.py Sun Mar 4 18:28:06 2007 @@ -1,6 +1,13 @@ import py import sys +from pypy.rlib.rarithmetic import intmask, _hash_string +from pypy.rlib.objectmodel import we_are_translated +import math +LOG2 = math.log(2) +NBITS = int(math.log(sys.maxint) / LOG2) + 2 + +# XXX should optimize the numbers NEW_NODE_WHEN_LENGTH = 16 MAX_DEPTH = 32 # maybe should be smaller MIN_SLICE_LENGTH = 64 @@ -27,6 +34,9 @@ def rebalance(self): return self + def hash_part(self): + raise NotImplementedError("base class") + def flatten(self): return '' @@ -69,6 +79,12 @@ def flatten(self): return self.s + def hash_part(self): + x = 0 + for c in self.s: + x = (1000003*x) + ord(c) + return intmask(x) + def getitem(self, index): return self.s[index] @@ -129,6 +145,11 @@ f = fringe(self) return "".join([node.flatten() for node in f]) + def hash_part(self): + h1 = self.left.hash_part() + h2 = self.right.hash_part() + return intmask(h1 + h2 * (1000003 ** self.left.length())) + def rebalance(self): return rebalance([self], self.len) @@ -168,6 +189,12 @@ def flatten(self): return self.node.flatten()[self.start: self.stop] + def hash_part(self): + x = 0 + for i in range(self.start, self.stop): + x = (1000003*x) + ord(self.node.getitem(i)) + return intmask(x) + def dot(self, seen, toplevel=False): if self in seen: return @@ -784,8 +811,6 @@ def hash_rope(rope): - from pypy.rlib.rarithmetic import intmask, _hash_string - from pypy.rlib.objectmodel import we_are_translated length = rope.length() if length == 0: x = -1 @@ -802,11 +827,10 @@ iter = CharIterator(rope) while 1: try: - x = (1000003*x) ^ ord(iter.next()) + x = (1000003*x) + ord(iter.next()) except StopIteration: break x ^= length if x == 0: x = -1 - return intmask(x) - + return intmask(x) Modified: pypy/branch/rope-branch/pypy/objspace/std/test/test_rope.py ============================================================================== --- pypy/branch/rope-branch/pypy/objspace/std/test/test_rope.py (original) +++ pypy/branch/rope-branch/pypy/objspace/std/test/test_rope.py Sun Mar 4 18:28:06 2007 @@ -310,6 +310,18 @@ rope = LiteralStringNode(st) assert hash_rope(rope) == _hash_string(st) +def test_hash_part(): + a = "".join([chr(random.randrange(256)) * random.randrange(500)]) + h = None + for split in range(1, 499): + s1 = LiteralStringNode(a[:split]) + s2 = LiteralStringNode(a[split:]) + s = BinaryConcatNode(s1, s2) + if h is None: + h = s.hash_part() + else: + assert s.hash_part() == h + def test_equality(): l = [make_random_string() for i in range(3)] l.append((LiteralStringNode(""), "")) From cfbolz at codespeak.net Sun Mar 4 18:42:27 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sun, 4 Mar 2007 18:42:27 +0100 (CET) Subject: [pypy-svn] r39909 - in pypy/branch/rope-branch/pypy/objspace/std: . test Message-ID: <20070304174227.219D510060@code0.codespeak.net> Author: cfbolz Date: Sun Mar 4 18:42:24 2007 New Revision: 39909 Modified: pypy/branch/rope-branch/pypy/objspace/std/rope.py pypy/branch/rope-branch/pypy/objspace/std/test/test_rope.py Log: cache hashes, always making sure that the highest bit is set (so that 0 is recognized as "not computed yet"). Modified: pypy/branch/rope-branch/pypy/objspace/std/rope.py ============================================================================== --- pypy/branch/rope-branch/pypy/objspace/std/rope.py (original) +++ pypy/branch/rope-branch/pypy/objspace/std/rope.py Sun Mar 4 18:42:24 2007 @@ -25,6 +25,7 @@ i += 1 class StringNode(object): + hash_cache = 0 def length(self): return 0 @@ -80,10 +81,15 @@ return self.s def hash_part(self): - x = 0 - for c in self.s: - x = (1000003*x) + ord(c) - return intmask(x) + h = self.hash_cache + if not h: + x = 0 + for c in self.s: + x = (1000003*x) + ord(c) + x = intmask(x) + x |= intmask(1L << (NBITS - 1)) + h = self.hash_cache = x + return h def getitem(self, index): return self.s[index] @@ -146,9 +152,14 @@ return "".join([node.flatten() for node in f]) def hash_part(self): - h1 = self.left.hash_part() - h2 = self.right.hash_part() - return intmask(h1 + h2 * (1000003 ** self.left.length())) + h = self.hash_cache + if not h: + h1 = self.left.hash_part() + h2 = self.right.hash_part() + x = intmask(h1 + h2 * (1000003 ** self.left.length())) + x |= intmask(1L << (NBITS - 1)) + h = self.hash_cache = x + return h def rebalance(self): return rebalance([self], self.len) @@ -190,10 +201,15 @@ return self.node.flatten()[self.start: self.stop] def hash_part(self): - x = 0 - for i in range(self.start, self.stop): - x = (1000003*x) + ord(self.node.getitem(i)) - return intmask(x) + h = self.hash_cache + if not h: + x = 0 + for i in range(self.start, self.stop): + x = (1000003*x) + ord(self.node.getitem(i)) + x = intmask(x) + x |= intmask(1L << (NBITS - 1)) + h = self.hash_cache = x + return h def dot(self, seen, toplevel=False): if self in seen: Modified: pypy/branch/rope-branch/pypy/objspace/std/test/test_rope.py ============================================================================== --- pypy/branch/rope-branch/pypy/objspace/std/test/test_rope.py (original) +++ pypy/branch/rope-branch/pypy/objspace/std/test/test_rope.py Sun Mar 4 18:42:24 2007 @@ -320,6 +320,8 @@ if h is None: h = s.hash_part() else: + # try twice due to caching reasons + assert s.hash_part() == h assert s.hash_part() == h def test_equality(): From hpk at codespeak.net Sun Mar 4 18:44:54 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sun, 4 Mar 2007 18:44:54 +0100 (CET) Subject: [pypy-svn] r39910 - in pypy/dist/pypy/tool/bench: . test Message-ID: <20070304174454.A58C310060@code0.codespeak.net> Author: hpk Date: Sun Mar 4 18:44:52 2007 New Revision: 39910 Modified: pypy/dist/pypy/tool/bench/pypyresult.py pypy/dist/pypy/tool/bench/test/test_pypyresult.py Log: can now parse complete pypy benchmark results Modified: pypy/dist/pypy/tool/bench/pypyresult.py ============================================================================== --- pypy/dist/pypy/tool/bench/pypyresult.py (original) +++ pypy/dist/pypy/tool/bench/pypyresult.py Sun Mar 4 18:44:52 2007 @@ -12,6 +12,7 @@ for id in id2numrun: besttime = id2bestspeed[id] numruns = id2numrun[id] + print id bench = BenchResult(id, besttime, numruns) self.benchmarks.append(bench) @@ -28,10 +29,30 @@ self._id = id if id.startswith("./"): id = id[2:] - parts = id.split("-") - self.name = parts.pop(-1) - self.backend = parts[1] - self.revision = int(parts[2]) - self.executable = "-".join(parts) + if id.startswith("pypy"): + parts = id.rsplit("_", 1) + self.executable = parts[0] + self.name = parts[1] + parts = self.executable.split("-") + self.backend = parts[1] + try: + self.revision = int(parts[2]) + except ValueError: + self.revision = None + else: # presumably cpython + version, name = id.split("_", 1) + self.name = name + self.backend = None + self.revision = version + self.executable = "cpython" self.besttime = besttime self.numruns = numruns + def __repr__(self): + return "" %(self._id, ) + + +if __name__ == "__main__": + x = py.magic.autopath().dirpath("bench-unix.benchmark_result") + db = ResultDB() + db.parsepickle(x) + Modified: pypy/dist/pypy/tool/bench/test/test_pypyresult.py ============================================================================== --- pypy/dist/pypy/tool/bench/test/test_pypyresult.py (original) +++ pypy/dist/pypy/tool/bench/test/test_pypyresult.py Sun Mar 4 18:44:52 2007 @@ -1,7 +1,7 @@ import py -from pypy.tool.bench.pypyresult import ResultDB +from pypy.tool.bench.pypyresult import ResultDB, BenchResult import pickle def setup_module(mod): @@ -23,12 +23,25 @@ db = ResultDB() db.parsepickle(pp) assert len(db.benchmarks) == 1 - l = db.getbenchmarks(name="c_richards") + l = db.getbenchmarks(name="richards") assert len(l) == 1 bench = l[0] - assert bench.executable == "pypy-llvm-39474-faassen" - assert bench.name == "c_richards" - assert bench.revision == 39474 - assert bench.numruns == 5 - assert bench.besttime == 42.0 - + l = db.getbenchmarks(name="xyz") + assert not l + +def test_BenchResult_cpython(): + res = BenchResult("2.3.5_pystone", besttime=2.0, numruns=3) + assert res.executable == "cpython" + assert res.revision == "2.3.5" + assert res.name == "pystone" + assert res.numruns == 3 + assert res.besttime == 2.0 + +def test_BenchResult_pypy(): + res = BenchResult("pypy-llvm-39474-faassen-c_richards", + besttime=2.0, numruns=3) + assert res.executable == "pypy-llvm-39474-faassen-c" + assert res.revision == 39474 + assert res.name == "richards" + assert res.numruns == 3 + assert res.besttime == 2.0 From xoraxax at codespeak.net Sun Mar 4 18:46:40 2007 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sun, 4 Mar 2007 18:46:40 +0100 (CET) Subject: [pypy-svn] r39911 - pypy/branch/pypy-2.5/pypy/objspace/std Message-ID: <20070304174640.D172C10060@code0.codespeak.net> Author: xoraxax Date: Sun Mar 4 18:46:38 2007 New Revision: 39911 Modified: pypy/branch/pypy-2.5/pypy/objspace/std/dictmultiobject.py pypy/branch/pypy-2.5/pypy/objspace/std/dictobject.py Log: Implement the __missing__ method of Python 2.5. Modified: pypy/branch/pypy-2.5/pypy/objspace/std/dictmultiobject.py ============================================================================== --- pypy/branch/pypy-2.5/pypy/objspace/std/dictmultiobject.py (original) +++ pypy/branch/pypy-2.5/pypy/objspace/std/dictmultiobject.py Sun Mar 4 18:46:38 2007 @@ -138,6 +138,7 @@ def get(self, w_lookup): return None + def setitem(self, w_key, w_value): if _is_str(self.space, w_key): return StrDictImplementation(self.space).setitem_str(w_key, w_value) @@ -1010,6 +1011,15 @@ result[key] = val return result + def missing_method(w_dict, space, w_key): + if not space.is_w(space.type(w_dict), space.w_dict): + w_missing = space.lookup(w_dict, "__missing__") + if w_missing is None: + return None + return space.call_function(w_missing, w_dict, w_key) + else: + return None + def len(w_self): return w_self.implementation.length() @@ -1054,6 +1064,11 @@ w_value = w_dict.implementation.get(w_lookup) if w_value is not None: return w_value + + w_missing_item = w_dict.missing_method(space, w_lookup) + if w_missing_item is not None: + return w_missing_item + raise OperationError(space.w_KeyError, w_lookup) def setitem__DictMulti_ANY_ANY(space, w_dict, w_newkey, w_newvalue): Modified: pypy/branch/pypy-2.5/pypy/objspace/std/dictobject.py ============================================================================== --- pypy/branch/pypy-2.5/pypy/objspace/std/dictobject.py (original) +++ pypy/branch/pypy-2.5/pypy/objspace/std/dictobject.py Sun Mar 4 18:46:38 2007 @@ -41,6 +41,15 @@ def get(w_dict, w_lookup, w_default): return w_dict.content.get(w_lookup, w_default) + def missing_method(w_dict, space, w_key): + if not space.is_w(space.type(w_dict), space.w_dict): + w_missing = space.lookup(w_dict, "__missing__") + if w_missing is None: + return None + return space.call_function(w_missing, w_dict, w_key) + else: + return None + def set_str_keyed_item(w_dict, w_key, w_value, shadows_type=True): w_dict.content[w_key] = w_value @@ -73,7 +82,11 @@ try: return w_dict.content[w_lookup] except KeyError: - raise OperationError(space.w_KeyError, w_lookup) + w_missing_item = w_dict.missing_method(space, w_lookup) + if w_missing_item is None: + raise OperationError(space.w_KeyError, w_lookup) + else: + return w_missing_item def setitem__Dict_ANY_ANY(space, w_dict, w_newkey, w_newvalue): w_dict.content[w_newkey] = w_newvalue From cfbolz at codespeak.net Sun Mar 4 19:22:09 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sun, 4 Mar 2007 19:22:09 +0100 (CET) Subject: [pypy-svn] r39912 - pypy/extradoc/minute Message-ID: <20070304182209.2B98210061@code0.codespeak.net> Author: cfbolz Date: Sun Mar 4 19:22:07 2007 New Revision: 39912 Added: pypy/extradoc/minute/post-eu-structure.txt Log: (all): some preliminary ideas about how to go about things after the funding ends. Added: pypy/extradoc/minute/post-eu-structure.txt ============================================================================== --- (empty file) +++ pypy/extradoc/minute/post-eu-structure.txt Sun Mar 4 19:22:07 2007 @@ -0,0 +1,85 @@ +=========== +DISCLAIMER: +=========== + +These are ideas that were discussed and agreed by the people present on the +sprint, nothing final. + + +post-EU PyPy organisation suggestion +---------------------------------------- + +- PyPy's future as an open-source project should be shaped + by the community and the people contributing and involved with it + +- development and communication continues as before: + - pypy-dev + - IRC + - sprints (fewer, though, likely) + - #pypy-sync (maybe on a fixed date like 1st thursday each month) + - meetings of interested people involved with a particular topic + - in case of unresolved conflicts: caretakers + +- make http://pypy.org the new main entry point to + pypy, and make the website a bit more independent of + {dist,trunk,release}/pypy/doc structure. That might + also make sense for the 1.0 release already. + +- have a "caretakers" group of people for the next year of + PyPy development (so until 1st april 2008 - 1st april + is a good day for project news, anyway), + +- the name is open for discussion + + "care for the next year of PyPy development" means: + - keeping conceptual integrity of the code base and project + - settling roadmaps / dev targets / new releases + - organising communication within the community + (including regulating commit rights/structure) + - talking to / negotiating with external parties + (including the EU partner organisations) + + Regarding the caretaker people/group: + - group may get extended by the group if everybody agrees + - agree to working with each other + - everbody is free to leave + - members should employ an overall project perspective + - confirmation from community (sprint, pypy-sync) + - may include non-technical persons on a regular basis + - consensus decisions, or majority decisions after a break + - non-attending people may re-raise a topic/decision + if they disagree with the decision of the attending people + + infrastructure: + - mailing list + - protected subversion area for mail drafts, internal issues + + suggested candidates: + samuele, cf, armin, hpk, michael + (bea, lene integrated and others + consulting/joining on case-by-case basis) + +- make statements to the community about future plans soon, + particulary noticing that the development pace will slowdown. + +- start determining how to go about external funding opportunities + + + +Background notes +---------------------- + +- full-time codespeak.net maintenance is going to end 1st April, + Martin (merlinux) may care a bit after that but he will + also be looking for other work opportunities. + There will be some (shared?) physical hosting costs and hopefully multiple + volunteers helping out with sys maintenance/care. Martin would + probably also be happy to continue somewhat professionally + for a fee to maintain the server. + background: merlinux as a company will do some sort of break/sabbatical + starting around april-june, lasting until end of the year, + but nevertheless considers future project opportunities. + +- major focus of march-may will still be EU related goals and deadlines +- next sprint likely not before EuroPython + From xoraxax at codespeak.net Sun Mar 4 19:29:58 2007 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sun, 4 Mar 2007 19:29:58 +0100 (CET) Subject: [pypy-svn] r39913 - pypy/branch/pypy-2.5/pypy/module/__builtin__ Message-ID: <20070304182958.2864C10061@code0.codespeak.net> Author: xoraxax Date: Sun Mar 4 19:29:55 2007 New Revision: 39913 Modified: pypy/branch/pypy-2.5/pypy/module/__builtin__/app_functional.py Log: Streamline min()/max() and implement Python 2.5s key= feature. Modified: pypy/branch/pypy-2.5/pypy/module/__builtin__/app_functional.py ============================================================================== --- pypy/branch/pypy-2.5/pypy/module/__builtin__/app_functional.py (original) +++ pypy/branch/pypy-2.5/pypy/module/__builtin__/app_functional.py Sun Mar 4 19:29:55 2007 @@ -4,6 +4,10 @@ """ from __future__ import generators + +from operator import lt, gt + + def sum(sequence, total=0): """sum(sequence, start=0) -> value @@ -203,47 +207,48 @@ # min and max could be one function if we had operator.__gt__ and # operator.__lt__ Perhaps later when we have operator. -def min(*arr): + +def _identity(arg): + return arg + + +def min(*arr, **kwargs): """return the smallest number in a list, or its smallest argument if more than one is given.""" + return min_max(gt, "min", *arr, **kwargs) + +def min_max(comp, funcname, *arr, **kwargs): + key = kwargs.pop("key", _identity) + if len(kwargs): + raise TypeError, '%s() got an unexpected keyword argument' % funcname + if not arr: - raise TypeError, 'min() takes at least one argument' + raise TypeError, '%s() takes at least one argument' % funcname if len(arr) == 1: arr = arr[0] iterator = iter(arr) try: - min = iterator.next() + min_max_val = iterator.next() except StopIteration: - raise ValueError, 'min() arg is an empty sequence' + raise ValueError, '%s() arg is an empty sequence' % funcname + + keyed_min_max_val = key(min_max_val) for i in iterator: - if min > i: - min = i - return min + keyed = key(i) + if comp(keyed_min_max_val, keyed): + min_max_val = i + keyed_min_max_val = keyed + return min_max_val -def max(*arr): +def max(*arr, **kwargs): """return the largest number in a list, or its largest argument if more than one is given.""" - if not arr: - raise TypeError, 'max() takes at least one argument' - - if len(arr) == 1: - arr = arr[0] - - iterator = iter(arr) - try: - max = iterator.next() - except StopIteration: - raise ValueError, 'max() arg is an empty sequence' - - for i in iterator: - if max < i: - max = i - return max + return min_max(lt, "max", *arr, **kwargs) class enumerate(object): """enumerate(iterable) -> iterator for (index, value) of iterable. From gbrandl at codespeak.net Sun Mar 4 19:35:41 2007 From: gbrandl at codespeak.net (gbrandl at codespeak.net) Date: Sun, 4 Mar 2007 19:35:41 +0100 (CET) Subject: [pypy-svn] r39914 - in pypy/branch/pypy-2.5/pypy/objspace/std: . test Message-ID: <20070304183541.08DB210061@code0.codespeak.net> Author: gbrandl Date: Sun Mar 4 19:35:40 2007 New Revision: 39914 Modified: pypy/branch/pypy-2.5/pypy/objspace/std/stringobject.py pypy/branch/pypy-2.5/pypy/objspace/std/stringtype.py pypy/branch/pypy-2.5/pypy/objspace/std/strsliceobject.py pypy/branch/pypy-2.5/pypy/objspace/std/test/test_stringobject.py pypy/branch/pypy-2.5/pypy/objspace/std/unicodeobject.py pypy/branch/pypy-2.5/pypy/objspace/std/unicodetype.py Log: Add str.startswith and str.endswith with tuple objects. Modified: pypy/branch/pypy-2.5/pypy/objspace/std/stringobject.py ============================================================================== --- pypy/branch/pypy-2.5/pypy/objspace/std/stringobject.py (original) +++ pypy/branch/pypy-2.5/pypy/objspace/std/stringobject.py Sun Mar 4 19:35:40 2007 @@ -11,7 +11,8 @@ from pypy.objspace.std.noneobject import W_NoneObject from pypy.objspace.std.tupleobject import W_TupleObject -from pypy.objspace.std.stringtype import sliced, joined, wrapstr, wrapchar +from pypy.objspace.std.stringtype import sliced, joined, wrapstr, wrapchar, \ + stringendswith, stringstartswith class W_StringObject(W_Object): @@ -342,7 +343,6 @@ return W_StringObject.EMPTY def str_rjust__String_ANY_ANY(space, w_self, w_arg, w_fillchar): - u_arg = space.int_w(w_arg) u_self = w_self._value fillchar = space.str_w(w_fillchar) @@ -359,7 +359,6 @@ def str_ljust__String_ANY_ANY(space, w_self, w_arg, w_fillchar): - u_self = w_self._value u_arg = space.int_w(w_arg) fillchar = space.str_w(w_fillchar) @@ -576,26 +575,30 @@ def str_endswith__String_String_ANY_ANY(space, w_self, w_suffix, w_start, w_end): (u_self, suffix, start, end) = _convert_idx_params(space, w_self, w_suffix, w_start, w_end) - begin = end - len(suffix) - if begin < start: - return space.w_False - for i in range(len(suffix)): - if u_self[begin+i] != suffix[i]: - return space.w_False - return space.w_True - - + return space.newbool(stringendswith(u_self, suffix, start, end)) + +def str_endswith__String_Tuple_ANY_ANY(space, w_self, w_suffixes, w_start, w_end): + (u_self, _, start, end) = _convert_idx_params(space, w_self, + space.wrap(''), w_start, w_end) + for w_suffix in space.unpacktuple(w_suffixes): + suffix = space.str_w(w_suffix) + if stringendswith(u_self, suffix, start, end): + return space.w_True + return space.w_False + def str_startswith__String_String_ANY_ANY(space, w_self, w_prefix, w_start, w_end): (u_self, prefix, start, end) = _convert_idx_params(space, w_self, w_prefix, w_start, w_end) - stop = start + len(prefix) - if stop > end: - return space.w_False - for i in range(len(prefix)): - if u_self[start+i] != prefix[i]: - return space.w_False - return space.w_True - + return space.newbool(stringstartswith(u_self, prefix, start, end)) + +def str_startswith__String_Tuple_ANY_ANY(space, w_self, w_prefixes, w_start, w_end): + (u_self, _, start, end) = _convert_idx_params(space, w_self, space.wrap(''), + w_start, w_end) + for w_prefix in space.unpacktuple(w_prefixes): + prefix = space.str_w(w_prefix) + if stringstartswith(u_self, prefix, start, end): + return space.w_True + return space.w_False def _tabindent(u_token, u_tabsize): "calculates distance behind the token to the next tabstop" Modified: pypy/branch/pypy-2.5/pypy/objspace/std/stringtype.py ============================================================================== --- pypy/branch/pypy-2.5/pypy/objspace/std/stringtype.py (original) +++ pypy/branch/pypy-2.5/pypy/objspace/std/stringtype.py Sun Mar 4 19:35:40 2007 @@ -28,6 +28,8 @@ return W_StringObject(c) def sliced(space, s, start, stop): + assert start >= 0 + assert stop >= 0 if space.config.objspace.std.withstrslice: from pypy.objspace.std.strsliceobject import W_StringSliceObject # XXX heuristic, should be improved! @@ -268,3 +270,26 @@ str_typedef.custom_hash = True str_typedef.registermethods(globals()) + +# ____________________________________________________________ + +# Helpers for several string implementations + +def stringendswith(u_self, suffix, start, end): + begin = end - len(suffix) + if begin < start: + return False + for i in range(len(suffix)): + if u_self[begin+i] != suffix[i]: + return False + return True + +def stringstartswith(u_self, prefix, start, end): + stop = start + len(prefix) + if stop > end: + return False + for i in range(len(prefix)): + if u_self[start+i] != prefix[i]: + return False + return True + Modified: pypy/branch/pypy-2.5/pypy/objspace/std/strsliceobject.py ============================================================================== --- pypy/branch/pypy-2.5/pypy/objspace/std/strsliceobject.py (original) +++ pypy/branch/pypy-2.5/pypy/objspace/std/strsliceobject.py Sun Mar 4 19:35:40 2007 @@ -5,13 +5,16 @@ from pypy.objspace.std import slicetype from pypy.objspace.std.inttype import wrapint -from pypy.objspace.std.stringtype import wrapstr, wrapchar, sliced +from pypy.objspace.std.stringtype import wrapstr, wrapchar, sliced, \ + stringendswith, stringstartswith class W_StringSliceObject(W_Object): from pypy.objspace.std.stringtype import str_typedef as typedef def __init__(w_self, str, start, stop): + assert start >= 0 + assert stop >= 0 w_self.str = str w_self.start = start w_self.stop = stop @@ -131,6 +134,34 @@ return space.wrap(res - w_self.start) +def str_endswith__StringSlice_String_ANY_ANY(space, w_self, w_suffix, w_start, w_end): + (u_self, suffix, start, end) = _convert_idx_params(space, w_self, + w_suffix, w_start, w_end) + return space.newbool(stringendswith(u_self, suffix, start, end)) + +#def str_endswith__StringSlice_Tuple_ANY_ANY(space, w_self, w_suffixes, w_start, w_end): +# (u_self, _, start, end) = _convert_idx_params(space, w_self, +# space.wrap(''), w_start, w_end) +# for w_suffix in space.unpacktuple(w_suffixes): +# suffix = space.str_w(w_suffix) +# if stringendswith(u_self, suffix, start, end): +# return space.w_True +# return space.w_False + +def str_startswith__StringSlice_String_ANY_ANY(space, w_self, w_prefix, w_start, w_end): + (u_self, prefix, start, end) = _convert_idx_params(space, w_self, + w_prefix, w_start, w_end) + return space.newbool(stringstartswith(u_self, prefix, start, end)) + +#def str_startswith__StringSlice_Tuple_ANY_ANY(space, w_self, w_prefixes, w_start, w_end): +# (u_self, _, start, end) = _convert_idx_params(space, w_self, space.wrap(''), +# w_start, w_end) +# for w_prefix in space.unpacktuple(w_prefixes): +# prefix = space.str_w(w_prefix) +# if stringstartswith(u_self, prefix, start, end): +# return space.w_True +# return space.w_False + def str_w__StringSlice(space, w_str): return w_str.force() @@ -178,5 +209,6 @@ return w_str return W_StringSliceObject(w_str.str, w_str.start, w_str.stop) + from pypy.objspace.std import stringtype register_all(vars(), stringtype) Modified: pypy/branch/pypy-2.5/pypy/objspace/std/test/test_stringobject.py ============================================================================== --- pypy/branch/pypy-2.5/pypy/objspace/std/test/test_stringobject.py (original) +++ pypy/branch/pypy-2.5/pypy/objspace/std/test/test_stringobject.py Sun Mar 4 19:35:40 2007 @@ -334,6 +334,18 @@ assert 'abc'.startswith('bc', 1, 2) is False assert 'abc'.startswith('c', -1, 4) is True + def test_startswith_tuples(self): + assert 'hello'.startswith(('he', 'ha')) + assert not 'hello'.startswith(('lo', 'llo')) + assert 'hello'.startswith(('hellox', 'hello')) + assert not 'hello'.startswith(()) + assert 'helloworld'.startswith(('hellowo', 'rld', 'lowo'), 3) + assert not 'helloworld'.startswith(('hellowo', 'ello', 'rld'), 3) + assert 'hello'.startswith(('lo', 'he'), 0, -1) + assert not 'hello'.startswith(('he', 'hel'), 0, 1) + assert 'hello'.startswith(('he', 'hel'), 0, 2) + raises(TypeError, 'hello'.startswith, (42,)) + def test_endswith(self): assert 'ab'.endswith('ab') is True assert 'ab'.endswith('b') is True @@ -350,7 +362,19 @@ assert 'abc'.endswith('bc', 1) is True assert 'abc'.endswith('bc', 2) is False assert 'abc'.endswith('b', -3, -1) is True - + + def test_endswith_tuple(self): + assert not 'hello'.endswith(('he', 'ha')) + assert 'hello'.endswith(('lo', 'llo')) + assert 'hello'.endswith(('hellox', 'hello')) + assert not 'hello'.endswith(()) + assert 'helloworld'.endswith(('hellowo', 'rld', 'lowo'), 3) + assert not 'helloworld'.endswith(('hellowo', 'ello', 'rld'), 3, -1) + assert 'hello'.endswith(('hell', 'ell'), 0, -1) + assert not 'hello'.endswith(('he', 'hel'), 0, 1) + assert 'hello'.endswith(('he', 'hell'), 0, 4) + raises(TypeError, 'hello'.endswith, (42,)) + def test_expandtabs(self): assert 'abc\rab\tdef\ng\thi'.expandtabs() == 'abc\rab def\ng hi' assert 'abc\rab\tdef\ng\thi'.expandtabs(8) == 'abc\rab def\ng hi' Modified: pypy/branch/pypy-2.5/pypy/objspace/std/unicodeobject.py ============================================================================== --- pypy/branch/pypy-2.5/pypy/objspace/std/unicodeobject.py (original) +++ pypy/branch/pypy-2.5/pypy/objspace/std/unicodeobject.py Sun Mar 4 19:35:40 2007 @@ -865,15 +865,32 @@ type(retval).__name__) return retval -def repr__Unicode(unistr): - import _codecs - return ''.join(_codecs.unicodeescape_string(unistr,len(unistr),True)) +# XXX: These should probably be written on interplevel + +def unicode_partition__Unicode_Unicode(unistr, unisub): + pos = unistr.find(unisub) + if pos == -1: + return (unistr, u'', u'') + else: + return (unistr[:pos], unisub, unistr[pos+len(unisub):]) + +def unicode_rpartition__Unicode_Unicode(unistr, unisub): + pos = unistr.rfind(unisub) + if pos == -1: + return (u'', u'', unistr) + else: + return (unistr[:pos], unisub, unistr[pos+len(unisub):]) + +#def unicode_startswith_ ''') + +mod__Unicode_ANY = app.interphook('mod__Unicode_ANY') unicode_expandtabs__Unicode_ANY = app.interphook('unicode_expandtabs__Unicode_ANY') unicode_translate__Unicode_ANY = app.interphook('unicode_translate__Unicode_ANY') -mod__Unicode_ANY = app.interphook('mod__Unicode_ANY') unicode_encode__Unicode_ANY_ANY = app.interphook('unicode_encode__Unicode_ANY_ANY') +unicode_partition__Unicode_Unicode = app.interphook('unicode_partition__Unicode_Unicode') +unicode_rpartition__Unicode_Unicode = app.interphook('unicode_rpartition__Unicode_Unicode') # Move this into the _codecs module as 'unicodeescape_string (Remember to cater for quotes)' def repr__Unicode(space, w_unicode): Modified: pypy/branch/pypy-2.5/pypy/objspace/std/unicodetype.py ============================================================================== --- pypy/branch/pypy-2.5/pypy/objspace/std/unicodetype.py (original) +++ pypy/branch/pypy-2.5/pypy/objspace/std/unicodetype.py Sun Mar 4 19:35:40 2007 @@ -207,6 +207,19 @@ ' string x with zeros on the left, to fill a' ' field\nof the specified width. The string x is' ' never truncated.') +unicode_partition = SMM('partition', 2, + doc='S.partition(sep) -> (head, sep, tail)\n\nSearches' + ' for the separator sep in S, and returns the part before' + ' it,\nthe separator itself, and the part after it. If' + ' the separator is not\nfound, returns S and two empty' + ' strings.') +unicode_rpartition = SMM('rpartition', 2, + doc='S.rpartition(sep) -> (tail, sep, head)\n\nSearches' + ' for the separator sep in S, starting at the end of S,' + ' and returns\nthe part before it, the separator itself,' + ' and the part after it. If the\nseparator is not found,' + ' returns two empty strings and S.') + # ____________________________________________________________ From xoraxax at codespeak.net Sun Mar 4 19:39:04 2007 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sun, 4 Mar 2007 19:39:04 +0100 (CET) Subject: [pypy-svn] r39915 - pypy/branch/pypy-2.5/pypy/objspace/std Message-ID: <20070304183904.2427310061@code0.codespeak.net> Author: xoraxax Date: Sun Mar 4 19:39:02 2007 New Revision: 39915 Modified: pypy/branch/pypy-2.5/pypy/objspace/std/strsliceobject.py Log: (xorAxAx, good hint by samuele) Enable the startswith/endswith method for string slice objects and tuples. Modified: pypy/branch/pypy-2.5/pypy/objspace/std/strsliceobject.py ============================================================================== --- pypy/branch/pypy-2.5/pypy/objspace/std/strsliceobject.py (original) +++ pypy/branch/pypy-2.5/pypy/objspace/std/strsliceobject.py Sun Mar 4 19:39:02 2007 @@ -2,6 +2,7 @@ from pypy.objspace.std.stringobject import W_StringObject from pypy.objspace.std.unicodeobject import delegate_String2Unicode from pypy.objspace.std.sliceobject import W_SliceObject +from pypy.objspace.std.tupleobject import W_TupleObject from pypy.objspace.std import slicetype from pypy.objspace.std.inttype import wrapint @@ -139,28 +140,28 @@ w_suffix, w_start, w_end) return space.newbool(stringendswith(u_self, suffix, start, end)) -#def str_endswith__StringSlice_Tuple_ANY_ANY(space, w_self, w_suffixes, w_start, w_end): -# (u_self, _, start, end) = _convert_idx_params(space, w_self, -# space.wrap(''), w_start, w_end) -# for w_suffix in space.unpacktuple(w_suffixes): -# suffix = space.str_w(w_suffix) -# if stringendswith(u_self, suffix, start, end): -# return space.w_True -# return space.w_False +def str_endswith__StringSlice_Tuple_ANY_ANY(space, w_self, w_suffixes, w_start, w_end): + (u_self, _, start, end) = _convert_idx_params(space, w_self, + space.wrap(''), w_start, w_end) + for w_suffix in space.unpacktuple(w_suffixes): + suffix = space.str_w(w_suffix) + if stringendswith(u_self, suffix, start, end): + return space.w_True + return space.w_False def str_startswith__StringSlice_String_ANY_ANY(space, w_self, w_prefix, w_start, w_end): (u_self, prefix, start, end) = _convert_idx_params(space, w_self, w_prefix, w_start, w_end) return space.newbool(stringstartswith(u_self, prefix, start, end)) -#def str_startswith__StringSlice_Tuple_ANY_ANY(space, w_self, w_prefixes, w_start, w_end): -# (u_self, _, start, end) = _convert_idx_params(space, w_self, space.wrap(''), -# w_start, w_end) -# for w_prefix in space.unpacktuple(w_prefixes): -# prefix = space.str_w(w_prefix) -# if stringstartswith(u_self, prefix, start, end): -# return space.w_True -# return space.w_False +def str_startswith__StringSlice_Tuple_ANY_ANY(space, w_self, w_prefixes, w_start, w_end): + (u_self, _, start, end) = _convert_idx_params(space, w_self, space.wrap(''), + w_start, w_end) + for w_prefix in space.unpacktuple(w_prefixes): + prefix = space.str_w(w_prefix) + if stringstartswith(u_self, prefix, start, end): + return space.w_True + return space.w_False def str_w__StringSlice(space, w_str): From gbrandl at codespeak.net Sun Mar 4 19:39:12 2007 From: gbrandl at codespeak.net (gbrandl at codespeak.net) Date: Sun, 4 Mar 2007 19:39:12 +0100 (CET) Subject: [pypy-svn] r39916 - pypy/branch/pypy-2.5/pypy/objspace/std Message-ID: <20070304183912.78AF010070@code0.codespeak.net> Author: gbrandl Date: Sun Mar 4 19:39:09 2007 New Revision: 39916 Modified: pypy/branch/pypy-2.5/pypy/objspace/std/unicodeobject.py Log: str.startswith and endswith with tuple argument for unicode too. Modified: pypy/branch/pypy-2.5/pypy/objspace/std/unicodeobject.py ============================================================================== --- pypy/branch/pypy-2.5/pypy/objspace/std/unicodeobject.py (original) +++ pypy/branch/pypy-2.5/pypy/objspace/std/unicodeobject.py Sun Mar 4 19:39:09 2007 @@ -3,6 +3,7 @@ from pypy.objspace.std.stringobject import W_StringObject from pypy.objspace.std.noneobject import W_NoneObject from pypy.objspace.std.sliceobject import W_SliceObject +from pypy.objspace.std.tupleobject import W_TupleObject from pypy.rlib.rarithmetic import intmask, ovfcheck from pypy.module.unicodedata import unicodedb_3_2_0 as unicodedb @@ -881,7 +882,17 @@ else: return (unistr[:pos], unisub, unistr[pos+len(unisub):]) -#def unicode_startswith_ +def unicode_startswith__Unicode_Tuple_ANY_ANY(unistr, prefixes, start, end): + for prefix in prefixes: + if unistr.startswith(prefix): + return True + return False + +def unicode_endswith__Unicode_Tuple_ANY_ANY(unistr, suffixes, start, end): + for suffix in suffixes: + if unistr.endswith(suffix): + return True + return False ''') @@ -891,6 +902,8 @@ unicode_encode__Unicode_ANY_ANY = app.interphook('unicode_encode__Unicode_ANY_ANY') unicode_partition__Unicode_Unicode = app.interphook('unicode_partition__Unicode_Unicode') unicode_rpartition__Unicode_Unicode = app.interphook('unicode_rpartition__Unicode_Unicode') +unicode_startswith__Unicode_Tuple_ANY_ANY = app.interphook('unicode_startswith__Unicode_Tuple_ANY_ANY') +unicode_endswith__Unicode_Tuple_ANY_ANY = app.interphook('unicode_endswith__Unicode_Tuple_ANY_ANY') # Move this into the _codecs module as 'unicodeescape_string (Remember to cater for quotes)' def repr__Unicode(space, w_unicode): From antocuni at codespeak.net Sun Mar 4 20:08:04 2007 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Sun, 4 Mar 2007 20:08:04 +0100 (CET) Subject: [pypy-svn] r39918 - pypy/dist/pypy/rpython/microbench Message-ID: <20070304190804.66AA310060@code0.codespeak.net> Author: antocuni Date: Sun Mar 4 20:08:02 2007 New Revision: 39918 Modified: pypy/dist/pypy/rpython/microbench/list.py pypy/dist/pypy/rpython/microbench/microbench.py Log: I finally found a sensible benchmark that is considerably slower on gencli that on genc. Modified: pypy/dist/pypy/rpython/microbench/list.py ============================================================================== --- pypy/dist/pypy/rpython/microbench/list.py (original) +++ pypy/dist/pypy/rpython/microbench/list.py Sun Mar 4 20:08:02 2007 @@ -49,3 +49,17 @@ args = ['obj', 'i'] def loop(obj, i): obj[i%1000] = i + +class list__iteration: + __metaclass__ = MetaBench + LOOPS = 100000 + def init(): + obj = [0]*1000 + obj[0] = 42 + return obj + args = ['obj'] + def loop(obj): + tot = 0 + for item in obj: + tot += item + return tot Modified: pypy/dist/pypy/rpython/microbench/microbench.py ============================================================================== --- pypy/dist/pypy/rpython/microbench/microbench.py (original) +++ pypy/dist/pypy/rpython/microbench/microbench.py Sun Mar 4 20:08:02 2007 @@ -1,3 +1,5 @@ +#!/usr/bin/env python + import sys import autopath from time import clock From gbrandl at codespeak.net Sun Mar 4 20:11:59 2007 From: gbrandl at codespeak.net (gbrandl at codespeak.net) Date: Sun, 4 Mar 2007 20:11:59 +0100 (CET) Subject: [pypy-svn] r39919 - in pypy/branch/pypy-2.5/pypy: module/__builtin__ objspace/std/test Message-ID: <20070304191159.99FA710069@code0.codespeak.net> Author: gbrandl Date: Sun Mar 4 20:11:57 2007 New Revision: 39919 Added: pypy/branch/pypy-2.5/pypy/objspace/std/test/test_index.py Modified: pypy/branch/pypy-2.5/pypy/module/__builtin__/app_functional.py Log: Add a test for __index__ builtin. Fix xrange() to use operator.index. Modified: pypy/branch/pypy-2.5/pypy/module/__builtin__/app_functional.py ============================================================================== --- pypy/branch/pypy-2.5/pypy/module/__builtin__/app_functional.py (original) +++ pypy/branch/pypy-2.5/pypy/module/__builtin__/app_functional.py Sun Mar 4 20:11:57 2007 @@ -5,7 +5,7 @@ from __future__ import generators -from operator import lt, gt +from operator import lt, gt, index def sum(sequence, total=0): @@ -347,15 +347,14 @@ def __len__(self): return self.len - def __getitem__(self, index): + def __getitem__(self, i): # xrange does NOT support slicing - if not isinstance(index, int): - raise TypeError, "sequence index must be integer" + i = index(i) len = self.len - if index < 0: - index += len - if 0 <= index < len: - return self.start + index * self.step + if i < 0: + i += len + if 0 <= i < len: + return self.start + i * self.step raise IndexError, "xrange object index out of range" def __iter__(self): Added: pypy/branch/pypy-2.5/pypy/objspace/std/test/test_index.py ============================================================================== --- (empty file) +++ pypy/branch/pypy-2.5/pypy/objspace/std/test/test_index.py Sun Mar 4 20:11:57 2007 @@ -0,0 +1,268 @@ +from py.test import raises + +class AppTest_IndexProtocol: + def setup_class(self): + w_oldstyle = self.space.appexec([], """(): + class oldstyle: + def __index__(self): + return self.ind + return oldstyle""") + + w_newstyle = self.space.appexec([], """(): + class newstyle(object): + def __index__(self): + return self.ind + return newstyle""") + + w_TrapInt = self.space.appexec([], """(): + class TrapInt(int): + def __index__(self): + return self + return TrapInt""") + + w_TrapLong = self.space.appexec([], """(): + class TrapLong(long): + def __index__(self): + return self + return TrapLong""") + + self.w_oldstyle = w_oldstyle + self.w_o = self.space.call_function(w_oldstyle) + self.w_newstyle = w_newstyle + self.w_n = self.space.call_function(w_newstyle) + + self.w_TrapInt = w_TrapInt + self.w_TrapLong = w_TrapLong + + def test_basic(self): + self.o.ind = -2 + self.n.ind = 2 + import operator + assert operator.index(self.o) == -2 + assert operator.index(self.n) == 2 + + def test_slice(self): + self.o.ind = 1 + self.n.ind = 2 + slc = slice(self.o, self.o, self.o) + check_slc = slice(1, 1, 1) + assert slc.indices(self.o) == check_slc.indices(1) + slc = slice(self.n, self.n, self.n) + check_slc = slice(2, 2, 2) + assert slc.indices(self.n) == check_slc.indices(2) + + def test_wrappers(self): + self.o.ind = 4 + self.n.ind = 5 + assert 6 .__index__() == 6 + assert -7L.__index__() == -7 + assert self.o.__index__() == 4 + assert self.n.__index__() == 5 + + def test_subclasses(self): + r = range(10) + assert r[self.TrapInt(5):self.TrapInt(10)] == r[5:10] + assert r[self.TrapLong(5):self.TrapLong(10)] == r[5:10] + assert slice(self.TrapInt()).indices(0) == (0,0,1) + assert slice(self.TrapLong(0)).indices(0) == (0,0,1) + + def test_error(self): + self.o.ind = 'dumb' + self.n.ind = 'bad' + import operator + raises(TypeError, operator.index, self.o) + raises(TypeError, operator.index, self.n) + raises(TypeError, slice(self.o).indices, 0) + raises(TypeError, slice(self.n).indices, 0) + + +class SeqTestCase: + # This test case isn't run directly. It just defines common tests + # to the different sequence types below + def setup_method(self, method): + w_oldstyle = self.space.appexec([], """(): + class oldstyle: + def __index__(self): + return self.ind + return oldstyle""") + + w_newstyle = self.space.appexec([], """(): + class newstyle(object): + def __index__(self): + return self.ind + return newstyle""") + + w_TrapInt = self.space.appexec([], """(): + class TrapInt(int): + def __index__(self): + return self + return TrapInt""") + + w_TrapLong = self.space.appexec([], """(): + class TrapLong(long): + def __index__(self): + return self + return TrapLong""") + + self.w_o = self.space.call_function(w_oldstyle) + self.w_n = self.space.call_function(w_newstyle) + self.w_o2 = self.space.call_function(w_oldstyle) + self.w_n2 = self.space.call_function(w_newstyle) + + self.w_TrapInt = w_TrapInt + self.w_TrapLong = w_TrapLong + + def test_index(self): + self.o.ind = -2 + self.n.ind = 2 + assert self.seq[self.n] == self.seq[2] + assert self.seq[self.o] == self.seq[-2] + + def test_slice(self): + self.o.ind = 1 + self.o2.ind = 3 + self.n.ind = 2 + self.n2.ind = 4 + assert self.seq[self.o:self.o2] == self.seq[1:3] + assert self.seq[self.n:self.n2] == self.seq[2:4] + + def test_repeat(self): + self.o.ind = 3 + self.n.ind = 2 + assert self.seq * self.o == self.seq * 3 + assert self.seq * self.n == self.seq * 2 + assert self.o * self.seq == self.seq * 3 + assert self.n * self.seq == self.seq * 2 + + def test_wrappers(self): + self.o.ind = 4 + self.n.ind = 5 + assert self.seq.__getitem__(self.o) == self.seq[4] + assert self.seq.__mul__(self.o) == self.seq * 4 + assert self.seq.__rmul__(self.o) == self.seq * 4 + assert self.seq.__getitem__(self.n) == self.seq[5] + assert self.seq.__mul__(self.n) == self.seq * 5 + assert self.seq.__rmul__(self.n) == self.seq * 5 + + def test_subclasses(self): + assert self.seq[self.TrapInt()] == self.seq[0] + assert self.seq[self.TrapLong()] == self.seq[0] + + def test_error(self): + self.o.ind = 'dumb' + self.n.ind = 'bad' + indexobj = lambda x, obj: obj.seq[x] + raises(TypeError, indexobj, self.o, self) + raises(TypeError, indexobj, self.n, self) + sliceobj = lambda x, obj: obj.seq[x:] + raises(TypeError, sliceobj, self.o, self) + raises(TypeError, sliceobj, self.n, self) + + +class AppTest_ListTestCase(SeqTestCase): + def setup_method(self, method): + SeqTestCase.setup_method(self, method) + self.w_seq = self.space.newlist([self.space.wrap(x) for x in (0,10,20,30,40,50)]) + + def test_setdelitem(self): + self.o.ind = -2 + self.n.ind = 2 + lst = list('ab!cdefghi!j') + del lst[self.o] + del lst[self.n] + lst[self.o] = 'X' + lst[self.n] = 'Y' + assert lst == list('abYdefghXj') + + lst = [5, 6, 7, 8, 9, 10, 11] + lst.__setitem__(self.n, "here") + assert lst == [5, 6, "here", 8, 9, 10, 11] + lst.__delitem__(self.n) + assert lst == [5, 6, 8, 9, 10, 11] + + def test_inplace_repeat(self): + self.o.ind = 2 + self.n.ind = 3 + lst = [6, 4] + lst *= self.o + assert lst == [6, 4, 6, 4] + lst *= self.n + assert lst == [6, 4, 6, 4] * 3 + + lst = [5, 6, 7, 8, 9, 11] + l2 = lst.__imul__(self.n) + assert l2 is lst + assert lst == [5, 6, 7, 8, 9, 11] * 3 + + +class AppTest_TupleTestCase(SeqTestCase): + def setup_method(self, method): + SeqTestCase.setup_method(self, method) + self.w_seq = self.space.newtuple([self.space.wrap(x) for x in (0,10,20,30,40,50)]) + +class AppTest_StringTestCase(SeqTestCase): + def setup_method(self, method): + SeqTestCase.setup_method(self, method) + self.w_seq = self.space.wrap("this is a test") + +class AppTest_UnicodeTestCase(SeqTestCase): + def setup_method(self, method): + SeqTestCase.setup_method(self, method) + self.w_seq = self.space.wrap(u"this is a test") + + +class AppTest_XRangeTestCase: + + def test_xrange(self): + class newstyle(object): + def __index__(self): + return self.ind + n = newstyle() + n.ind = 5 + assert xrange(1, 20)[n] == 6 + assert xrange(1, 20).__getitem__(n) == 6 + +class AppTest_OverflowTestCase: + + def setup_class(self): + self.w_pos = self.space.wrap(2**100) + self.w_neg = self.space.wrap(-2**100) + + def test_large_longs(self): + assert self.pos.__index__() == self.pos + assert self.neg.__index__() == self.neg + + def test_getitem(self): + from sys import maxint + class GetItem(object): + def __len__(self): + return maxint + def __getitem__(self, key): + return key + def __getslice__(self, i, j): + return i, j + x = GetItem() + assert x[self.pos] == self.pos + assert x[self.neg] == self.neg + assert x[self.neg:self.pos] == (-1, maxint) + assert x[self.neg:self.pos:1].indices(maxint) == (0, maxint, 1) + + def test_getitem_classic(self): + from sys import maxint + class Empty: pass + class GetItem(Empty): + def __len__(self): + return maxint + def __getitem__(self, key): + return key + def __getslice__(self, i, j): + return i, j + x = GetItem() + assert x[self.pos] == self.pos + assert x[self.neg] == self.neg + assert x[self.neg:self.pos] == (-1, maxint) + assert x[self.neg:self.pos:1].indices(maxint) == (0, maxint, 1) + + def test_sequence_repeat(self): + raises(OverflowError, lambda: "a" * self.pos) + raises(OverflowError, lambda: "a" * self.neg) From tismer at codespeak.net Sun Mar 4 21:23:56 2007 From: tismer at codespeak.net (tismer at codespeak.net) Date: Sun, 4 Mar 2007 21:23:56 +0100 (CET) Subject: [pypy-svn] r39923 - pypy/dist/pypy/translator/benchmark Message-ID: <20070304202356.C29C910069@code0.codespeak.net> Author: tismer Date: Sun Mar 4 21:23:53 2007 New Revision: 39923 Added: pypy/dist/pypy/translator/benchmark/gadtest.py Log: checking in as far as I got. There is some bug that shows up only after running all the tests. I want to track this down before continuing integrating a gadfly test. Please feel free to jump in if you like, but leave that bug to me - chris Added: pypy/dist/pypy/translator/benchmark/gadtest.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/benchmark/gadtest.py Sun Mar 4 21:23:53 2007 @@ -0,0 +1,53 @@ +""" +This file contains some monkeypatching for Gadfly, depending on +the options for pypy-c things are patched or not. + +There is some bug related to files and marshal that prevented me +to finish this stuff. + +TODO: + Make paths independent from an actual install of Gadfly + integrate benchmark into benchmarks.py + maybe extract a few parts from Gadfly's test to make it take + less time + + If instead anybody likes to continue from here, please feel free. + I was too much occupated by everything else. + cheers - chris +""" + +import site + +""" +Monkey-patching +gadfly asks for InstanceType. We need to cheat for new style classes. +Also time.gmtime does not always exist in PyPy. We simply patch it in. +""" + +# depending on the buils, we may or may not have gmtime. Just make it work. +import time +try: + time.gmtime +except AttributeError: + time.gmtime = time.time + +# do we have oldstyle classes? If not, just cheat. +import types +class _X: pass +if type(_X) is not types.ClassType: + print 'emulating old-style classes by monkeypatching' + _isinstance = isinstance + def isinstance(ob, klass): + if klass is types.InstanceType: + return ob.__class__.__module__ != '__builtin__' + return _isinstance(ob, klass) + import __builtin__ + __builtin__.isinstance = isinstance + _type = type + def type(ob): + tp = _type(ob) + if ob.__class__.__module__ != '__builtin__': + return types.InstanceType +else: + print 'using real old-style classes (slow ATM)' +execfile('Desktop/gadflyZip/test/test_gadfly.py') \ No newline at end of file From gbrandl at codespeak.net Sun Mar 4 21:41:03 2007 From: gbrandl at codespeak.net (gbrandl at codespeak.net) Date: Sun, 4 Mar 2007 21:41:03 +0100 (CET) Subject: [pypy-svn] r39926 - pypy/branch/pypy-2.5/pypy/module/__builtin__ Message-ID: <20070304204103.3CD5C10061@code0.codespeak.net> Author: gbrandl Date: Sun Mar 4 21:41:00 2007 New Revision: 39926 Modified: pypy/branch/pypy-2.5/pypy/module/__builtin__/app_functional.py Log: Fix xrange on py.py. Modified: pypy/branch/pypy-2.5/pypy/module/__builtin__/app_functional.py ============================================================================== --- pypy/branch/pypy-2.5/pypy/module/__builtin__/app_functional.py (original) +++ pypy/branch/pypy-2.5/pypy/module/__builtin__/app_functional.py Sun Mar 4 21:41:00 2007 @@ -4,8 +4,7 @@ """ from __future__ import generators - -from operator import lt, gt, index +from operator import lt, gt def sum(sequence, total=0): @@ -349,7 +348,8 @@ def __getitem__(self, i): # xrange does NOT support slicing - i = index(i) + import operator + i = operator.index(i) len = self.len if i < 0: i += len From fijal at codespeak.net Mon Mar 5 10:06:55 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 5 Mar 2007 10:06:55 +0100 (CET) Subject: [pypy-svn] r39932 - pypy/dist/pypy/translator/js Message-ID: <20070305090655.32DD410063@code0.codespeak.net> Author: fijal Date: Mon Mar 5 10:06:52 2007 New Revision: 39932 Modified: pypy/dist/pypy/translator/js/jsbuiltin.py Log: fix name Modified: pypy/dist/pypy/translator/js/jsbuiltin.py ============================================================================== --- pypy/dist/pypy/translator/js/jsbuiltin.py (original) +++ pypy/dist/pypy/translator/js/jsbuiltin.py Mon Mar 5 10:06:52 2007 @@ -23,7 +23,7 @@ #'alert' : CallBuiltin('alert'), 'seval' : CallBuiltin('seval'), 'date': NewBuiltin('Date'), - 'll_math_fmod' : InstructionList([PushAllArgs, '%']), + 'll_math.ll_math_fmod' : InstructionList([PushAllArgs, '%']), 'll_time_time' : CallBuiltin('time'), 'll_time_clock' : CallBuiltin('clock'), 'll_os_write' : CallBuiltin('print'), From fijal at codespeak.net Mon Mar 5 10:09:49 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 5 Mar 2007 10:09:49 +0100 (CET) Subject: [pypy-svn] r39934 - in pypy/dist/pypy/translator/js/examples: console/test test Message-ID: <20070305090949.2381410063@code0.codespeak.net> Author: fijal Date: Mon Mar 5 10:09:47 2007 New Revision: 39934 Modified: pypy/dist/pypy/translator/js/examples/console/test/test_console.py pypy/dist/pypy/translator/js/examples/test/test_examples.py Log: Make tests aware of import problems with greensock2 Modified: pypy/dist/pypy/translator/js/examples/console/test/test_console.py ============================================================================== --- pypy/dist/pypy/translator/js/examples/console/test/test_console.py (original) +++ pypy/dist/pypy/translator/js/examples/console/test/test_console.py Mon Mar 5 10:09:47 2007 @@ -1,6 +1,10 @@ def test_line_skip(): - from pypy.translator.js.examples.console.console import line_split + try: + from pypy.translator.js.examples.console.console import line_split + except ImportError: + import py + py.test.skip("cannot import greensock") assert line_split("asdf", 80) == "asdf" assert line_split("a b c d", 3) == "a b\n c d" 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 Mon Mar 5 10:09:47 2007 @@ -16,7 +16,12 @@ assert rpython2javascript(start_bnb, ['bnb'], use_pdb=False) def test_overmind_build(): - from pypy.translator.js.examples import overmind, over_client + try: + from pypy.translator.js.examples import overmind, over_client + except ImportError: + import py + py.test.skip("greensock wasn't found") + assert rpython2javascript(over_client, overmind.FUNCTION_LIST, use_pdb=False) @@ -30,6 +35,7 @@ try: from pypy.translator.js.examples.console import console, client except ImportError: + import py py.test.skip("greensock wasn't found") assert rpython2javascript(client, console.FUNCTION_LIST, From fijal at codespeak.net Mon Mar 5 10:16:03 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 5 Mar 2007 10:16:03 +0100 (CET) Subject: [pypy-svn] r39935 - pypy/dist/pypy/translator/js/test Message-ID: <20070305091603.D14701006E@code0.codespeak.net> Author: fijal Date: Mon Mar 5 10:16:01 2007 New Revision: 39935 Added: pypy/dist/pypy/translator/js/test/test_rfloat.py Log: Added float tests (stolen from rpython dir) Added: pypy/dist/pypy/translator/js/test/test_rfloat.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/js/test/test_rfloat.py Mon Mar 5 10:16:01 2007 @@ -0,0 +1,8 @@ + +import py +from pypy.translator.js.test.runtest import JsTest +from pypy.rpython.test.test_rfloat import BaseTestRfloat + +class TestJsFloat(JsTest, BaseTestRfloat): + def test_from_r_uint(self): + py.test.skip("Not implemented") From antocuni at codespeak.net Mon Mar 5 10:29:08 2007 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Mon, 5 Mar 2007 10:29:08 +0100 (CET) Subject: [pypy-svn] r39938 - pypy/dist/pypy/translator/cli Message-ID: <20070305092908.3D15E1006E@code0.codespeak.net> Author: antocuni Date: Mon Mar 5 10:29:05 2007 New Revision: 39938 Modified: pypy/dist/pypy/translator/cli/opcodes.py Log: this bug has been around for about 1 year and has been discovered just today... Modified: pypy/dist/pypy/translator/cli/opcodes.py ============================================================================== --- pypy/dist/pypy/translator/cli/opcodes.py (original) +++ pypy/dist/pypy/translator/cli/opcodes.py Mon Mar 5 10:29:05 2007 @@ -223,7 +223,7 @@ 'cast_uint_to_int': DoNothing, 'cast_uint_to_float': [PushAllArgs, 'conv.u8', 'conv.r8'], 'cast_float_to_int': 'conv.i4', - 'cast_float_to_uint': 'conv.i4', + 'cast_float_to_uint': 'conv.u4', 'truncate_longlong_to_int': 'conv.i4', } From antocuni at codespeak.net Mon Mar 5 10:34:15 2007 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Mon, 5 Mar 2007 10:34:15 +0100 (CET) Subject: [pypy-svn] r39939 - pypy/dist/pypy/rpython/module/test Message-ID: <20070305093415.5916810068@code0.codespeak.net> Author: antocuni Date: Mon Mar 5 10:34:13 2007 New Revision: 39939 Modified: pypy/dist/pypy/rpython/module/test/test_ll_os.py Log: we no longer need to get im_func Modified: pypy/dist/pypy/rpython/module/test/test_ll_os.py ============================================================================== --- pypy/dist/pypy/rpython/module/test/test_ll_os.py (original) +++ pypy/dist/pypy/rpython/module/test/test_ll_os.py Mon Mar 5 10:34:13 2007 @@ -118,7 +118,7 @@ if hasattr(os, 'execv'): from pypy.rpython.extregistry import lookup - os_execv = lookup(os.execv).lltypeimpl.im_func + os_execv = lookup(os.execv).lltypeimpl def test_execv(): filename = str(udir.join('test_execv_ctypes.txt')) @@ -137,7 +137,7 @@ def test_dup(): from pypy.rpython.extregistry import lookup - os_dup = lookup(os.dup).lltypeimpl.im_func + os_dup = lookup(os.dup).lltypeimpl testf = udir.join('test.txt') testf.write("foo") path = testf.strpath From gbrandl at codespeak.net Mon Mar 5 10:35:10 2007 From: gbrandl at codespeak.net (gbrandl at codespeak.net) Date: Mon, 5 Mar 2007 10:35:10 +0100 (CET) Subject: [pypy-svn] r39940 - pypy/branch/pypy-2.5/pypy/objspace/std Message-ID: <20070305093510.079DA10068@code0.codespeak.net> Author: gbrandl Date: Mon Mar 5 10:35:08 2007 New Revision: 39940 Modified: pypy/branch/pypy-2.5/pypy/objspace/std/slicetype.py Log: Remove redundant code in _Eval_SliceIndex. Modified: pypy/branch/pypy-2.5/pypy/objspace/std/slicetype.py ============================================================================== --- pypy/branch/pypy-2.5/pypy/objspace/std/slicetype.py (original) +++ pypy/branch/pypy-2.5/pypy/objspace/std/slicetype.py Mon Mar 5 10:35:08 2007 @@ -15,17 +15,19 @@ # utility functions def _Eval_SliceIndex(space, w_int): - try: - x = space.getindex_w(w_int) # clamp if long integer is too large - except OperationError, e: - if not e.match(space, space.w_OverflowError): - raise - cmp = space.is_true(space.ge(w_int, space.wrap(0))) - if cmp: - x = sys.maxint - else: - x = -sys.maxint - return x + return space.getindex_w(w_int) # clamp if long integer is too large + # This is done by getindex_w already. + #try: + # x = space.getindex_w(w_int) + #except OperationError, e: + # if not e.match(space, space.w_OverflowError): + # raise + # cmp = space.is_true(space.ge(w_int, space.wrap(0))) + # if cmp: + # x = sys.maxint + # else: + # x = -sys.maxint + #return x def adapt_bound(space, w_index, w_size): if not (space.is_true(space.isinstance(w_index, space.w_int)) or From xoraxax at codespeak.net Mon Mar 5 10:36:53 2007 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Mon, 5 Mar 2007 10:36:53 +0100 (CET) Subject: [pypy-svn] r39941 - pypy/branch/pypy-2.5/pypy/objspace/std Message-ID: <20070305093653.0151510069@code0.codespeak.net> Author: xoraxax Date: Mon Mar 5 10:36:51 2007 New Revision: 39941 Modified: pypy/branch/pypy-2.5/pypy/objspace/std/objspace.py Log: Fix old slice cases and make the index test work. Modified: pypy/branch/pypy-2.5/pypy/objspace/std/objspace.py ============================================================================== --- pypy/branch/pypy-2.5/pypy/objspace/std/objspace.py (original) +++ pypy/branch/pypy-2.5/pypy/objspace/std/objspace.py Mon Mar 5 10:36:51 2007 @@ -627,13 +627,17 @@ """Only for backward compatibility for __getslice__()&co methods.""" if space.is_w(w_start, space.w_None): w_start = space.wrap(0) - elif space.is_true(space.lt(w_start, space.wrap(0))): - w_start = space.add(w_start, space.len(w_obj)) - # NB. the language ref is inconsistent with the new-style class - # behavior when w_obj doesn't implement __len__(), so we just - # ignore this case. + else: + w_start = space.wrap(space.getindex_w(w_start)) + if space.is_true(space.lt(w_start, space.wrap(0))): + w_start = space.add(w_start, space.len(w_obj)) + # NB. the language ref is inconsistent with the new-style class + # behavior when w_obj doesn't implement __len__(), so we just + # ignore this case. if space.is_w(w_stop, space.w_None): w_stop = space.wrap(slice_max) - elif space.is_true(space.lt(w_stop, space.wrap(0))): - w_stop = space.add(w_stop, space.len(w_obj)) + else: + w_stop = space.wrap(space.getindex_w(w_stop)) + if space.is_true(space.lt(w_stop, space.wrap(0))): + w_stop = space.add(w_stop, space.len(w_obj)) return w_start, w_stop From gbrandl at codespeak.net Mon Mar 5 10:42:45 2007 From: gbrandl at codespeak.net (gbrandl at codespeak.net) Date: Mon, 5 Mar 2007 10:42:45 +0100 (CET) Subject: [pypy-svn] r39942 - pypy/dist/pypy Message-ID: <20070305094245.47B6810068@code0.codespeak.net> Author: gbrandl Date: Mon Mar 5 10:42:42 2007 New Revision: 39942 Modified: pypy/dist/pypy/conftest.py Log: (xoraxax, gbrandl) Add a few methods to TinyObjSpace. Modified: pypy/dist/pypy/conftest.py ============================================================================== --- pypy/dist/pypy/conftest.py (original) +++ pypy/dist/pypy/conftest.py Mon Mar 5 10:42:42 2007 @@ -105,6 +105,15 @@ def newdict(self): return {} + def newtuple(self, iterable): + return tuple(iterable) + + def newlist(self, iterable): + return list(iterable) + + def call_function(self, func, *args, **kwds): + return func(*args, **kwds) + def translation_test_so_skip_if_appdirect(): if option.runappdirect: py.test.skip("translation test, skipped for appdirect") From antocuni at codespeak.net Mon Mar 5 10:42:58 2007 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Mon, 5 Mar 2007 10:42:58 +0100 (CET) Subject: [pypy-svn] r39943 - pypy/dist/pypy/rpython/test Message-ID: <20070305094258.0A8591006F@code0.codespeak.net> Author: antocuni Date: Mon Mar 5 10:42:53 2007 New Revision: 39943 Modified: pypy/dist/pypy/rpython/test/test_extfunc.py Log: this fix the test, though I'm not completely sure it's The Right Way (TM). 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 Mar 5 10:42:53 2007 @@ -43,6 +43,7 @@ def lltypeimpl(y, x): return y + x + lltypeimpl = staticmethod(lltypeimpl) def test_interp_c(): def f(): From xoraxax at codespeak.net Mon Mar 5 10:50:07 2007 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Mon, 5 Mar 2007 10:50:07 +0100 (CET) Subject: [pypy-svn] r39945 - in pypy/dist/pypy: config interpreter interpreter/test lib module/__builtin__ module/mmap module/operator objspace objspace/cpy objspace/flow objspace/std objspace/std/test rlib Message-ID: <20070305095007.CCEFA10069@code0.codespeak.net> Author: xoraxax Date: Mon Mar 5 10:50:02 2007 New Revision: 39945 Added: pypy/dist/pypy/lib/_functools.py - copied unchanged from r39940, pypy/branch/pypy-2.5/pypy/lib/_functools.py pypy/dist/pypy/module/operator/ - copied from r39940, pypy/branch/pypy-2.5/pypy/module/operator/ pypy/dist/pypy/objspace/std/test/test_index.py - copied unchanged from r39940, pypy/branch/pypy-2.5/pypy/objspace/std/test/test_index.py Removed: pypy/dist/pypy/lib/operator.py Modified: pypy/dist/pypy/config/pypyoption.py pypy/dist/pypy/interpreter/baseobjspace.py pypy/dist/pypy/interpreter/gateway.py pypy/dist/pypy/interpreter/test/test_gateway.py pypy/dist/pypy/interpreter/test/test_objspace.py pypy/dist/pypy/lib/_classobj.py pypy/dist/pypy/module/__builtin__/app_functional.py pypy/dist/pypy/module/mmap/interp_mmap.py pypy/dist/pypy/objspace/cpy/function.py pypy/dist/pypy/objspace/cpy/objspace.py pypy/dist/pypy/objspace/descroperation.py pypy/dist/pypy/objspace/flow/operation.py pypy/dist/pypy/objspace/std/dictmultiobject.py pypy/dist/pypy/objspace/std/dictobject.py pypy/dist/pypy/objspace/std/intobject.py pypy/dist/pypy/objspace/std/listmultiobject.py pypy/dist/pypy/objspace/std/listobject.py pypy/dist/pypy/objspace/std/listtype.py pypy/dist/pypy/objspace/std/longobject.py pypy/dist/pypy/objspace/std/rangeobject.py pypy/dist/pypy/objspace/std/sliceobject.py pypy/dist/pypy/objspace/std/slicetype.py pypy/dist/pypy/objspace/std/stringobject.py pypy/dist/pypy/objspace/std/stringtype.py pypy/dist/pypy/objspace/std/strsliceobject.py pypy/dist/pypy/objspace/std/test/test_stringobject.py pypy/dist/pypy/objspace/std/tupleobject.py pypy/dist/pypy/objspace/std/unicodeobject.py pypy/dist/pypy/objspace/std/unicodetype.py pypy/dist/pypy/rlib/streamio.py Log: (xorAxAx, gbrandl, armin with useful svn hints) Merged pypy-2.5 branch into dist. Modified: pypy/dist/pypy/config/pypyoption.py ============================================================================== --- pypy/dist/pypy/config/pypyoption.py (original) +++ pypy/dist/pypy/config/pypyoption.py Mon Mar 5 10:50:02 2007 @@ -17,7 +17,7 @@ default_modules = essential_modules.copy() default_modules.update(dict.fromkeys( ["_codecs", "gc", "_weakref", "array", "marshal", "errno", - "math", "_sre", "_pickle_support", + "math", "_sre", "_pickle_support", "operator", "recparser", "symbol", "_random", "pypymagic"])) Modified: pypy/dist/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/dist/pypy/interpreter/baseobjspace.py (original) +++ pypy/dist/pypy/interpreter/baseobjspace.py Mon Mar 5 10:50:02 2007 @@ -5,7 +5,7 @@ from pypy.interpreter.miscutils import ThreadLocals from pypy.tool.cache import Cache from pypy.tool.uid import HUGEVAL_BYTES -import os +import os, sys __all__ = ['ObjSpace', 'OperationError', 'Wrappable', 'W_Root'] @@ -785,6 +785,28 @@ step = 0 return start, stop, step + def getindex_w(self, w_obj, exception=None): + w_index = self.index(w_obj) + try: + index = self.int_w(w_index) + except OperationError, err: + if not err.match(self, self.w_OverflowError): + raise + if not exception: + # w_index is a long object + if w_index.get_sign() < 0: + return -sys.maxint-1 + else: + return sys.maxint + else: + raise OperationError( + exception, self.wrap( + "cannot fit '%s' into an index-sized " + "integer" % self.type(w_obj).getname(self, '?'))) + else: + return index + + class AppExecCache(SpaceCache): def build(cache, source): """ NOT_RPYTHON """ @@ -841,6 +863,7 @@ ('or_', '|', 2, ['__or__', '__ror__']), ('xor', '^', 2, ['__xor__', '__rxor__']), ('int', 'int', 1, ['__int__']), + ('index', 'index', 1, ['__index__']), ('float', 'float', 1, ['__float__']), ('long', 'long', 1, ['__long__']), ('inplace_add', '+=', 2, ['__iadd__']), Modified: pypy/dist/pypy/interpreter/gateway.py ============================================================================== --- pypy/dist/pypy/interpreter/gateway.py (original) +++ pypy/dist/pypy/interpreter/gateway.py Mon Mar 5 10:50:02 2007 @@ -106,7 +106,17 @@ def visit_self(self, cls, app_sig): self.visit__Wrappable(cls, app_sig) - + + def checked_space_method(self, typ, app_sig): + argname = self.orig_arg() + assert not argname.startswith('w_'), ( + "unwrapped %s argument %s of built-in function %r should " + "not start with 'w_'" % (typ.__name__, argname, self.func)) + app_sig.append(argname) + + def visit_index(self, index, app_sig): + self.checked_space_method(index, app_sig) + def visit__Wrappable(self, el, app_sig): name = el.__name__ argname = self.orig_arg() @@ -154,11 +164,7 @@ def visit__object(self, typ, app_sig): if typ not in (int, str, float): assert False, "unsupported basic type in unwrap_spec" - argname = self.orig_arg() - assert not argname.startswith('w_'), ( - "unwrapped %s argument %s of built-in function %r should " - "not start with 'w_'" % (typ.__name__, argname, self.func)) - app_sig.append(argname) + self.checked_space_method(typ, app_sig) class UnwrapSpec_EmitRun(UnwrapSpecEmit): @@ -207,6 +213,9 @@ self.run_args.append("space.%s_w(%s)" % (typ.__name__, self.scopenext())) + def visit_index(self, typ): + self.run_args.append("space.getindex_w(%s)" % (self.scopenext(), )) + def _make_unwrap_activation_class(self, unwrap_spec, cache={}): try: key = tuple(unwrap_spec) @@ -316,6 +325,9 @@ self.unwrap.append("space.%s_w(%s)" % (typ.__name__, self.nextarg())) + def visit_index(self, typ): + self.unwrap.append("space.getindex_w(%s)" % (self.nextarg()), ) + def make_fastfunc(unwrap_spec, func): unwrap_info = UnwrapSpec_FastFunc_Unwrap() unwrap_info.apply_over(unwrap_spec) Modified: pypy/dist/pypy/interpreter/test/test_gateway.py ============================================================================== --- pypy/dist/pypy/interpreter/test/test_gateway.py (original) +++ pypy/dist/pypy/interpreter/test/test_gateway.py Mon Mar 5 10:50:02 2007 @@ -33,6 +33,12 @@ gateway.Arguments]) assert code.signature() == (['x', 'y'], 'args', 'keywords') + def f(space, index): + pass + code = gateway.BuiltinCode(f, unwrap_spec=[gateway.ObjSpace, "index"]) + assert code.signature() == (["index"], None, None) + + def test_call(self): def c(space, w_x, w_y, hello_w): u = space.unwrap @@ -50,6 +56,15 @@ w_result = code.funcrun(FakeFunc(self.space, "c"), args) assert self.space.eq_w(w_result, w(102)) + def test_call_index(self): + def c(space, index): + assert type(index) is int + code = gateway.BuiltinCode(c, unwrap_spec=[gateway.ObjSpace, + "index"]) + w = self.space.wrap + args = argument.Arguments(self.space, [w(123)]) + code.funcrun(FakeFunc(self.space, "c"), args) + def test_call_args(self): def c(space, w_x, w_y, __args__): args_w, kwds_w = __args__.unpack() Modified: pypy/dist/pypy/interpreter/test/test_objspace.py ============================================================================== --- pypy/dist/pypy/interpreter/test/test_objspace.py (original) +++ pypy/dist/pypy/interpreter/test/test_objspace.py Mon Mar 5 10:50:02 2007 @@ -1,6 +1,7 @@ from py.test import raises from pypy.interpreter.function import Function from pypy.interpreter.pycode import PyCode +import sys # this test isn't so much to test that the objspace interface *works* # -- it's more to test that it's *there* @@ -139,6 +140,23 @@ res = self.space.interp_w(Function, w(None), can_be_None=True) assert res is None + def test_getindex_w(self): + w_instance1 = self.space.appexec([], """(): + class X(object): + def __index__(self): return 42 + return X()""") + w_instance2 = self.space.appexec([], """(): + class Y(object): + def __index__(self): return 2**70 + return Y()""") + first = self.space.getindex_w(w_instance1) + assert first == 42 + second = self.space.getindex_w(w_instance2) + assert second == sys.maxint + self.space.raises_w(self.space.w_IndexError, + self.space.getindex_w, w_instance2, self.space.w_IndexError) + + class TestModuleMinimal: def test_sys_exists(self): assert self.space.sys Modified: pypy/dist/pypy/lib/_classobj.py ============================================================================== --- pypy/dist/pypy/lib/_classobj.py (original) +++ pypy/dist/pypy/lib/_classobj.py Mon Mar 5 10:50:02 2007 @@ -399,6 +399,14 @@ """, {"op": op}) del op + def __index__(self): + func = instance_getattr1(self, '__index__', False) + if func: + return func() + else: + raise AttributeError('object cannot be interpreted as an index') + + # coerce def __coerce__(self, other): func = instance_getattr1(self, '__coerce__', False) Modified: pypy/dist/pypy/module/__builtin__/app_functional.py ============================================================================== --- pypy/dist/pypy/module/__builtin__/app_functional.py (original) +++ pypy/dist/pypy/module/__builtin__/app_functional.py Mon Mar 5 10:50:02 2007 @@ -4,6 +4,9 @@ """ from __future__ import generators +from operator import lt, gt + + def sum(sequence, total=0): """sum(sequence, start=0) -> value @@ -203,47 +206,48 @@ # min and max could be one function if we had operator.__gt__ and # operator.__lt__ Perhaps later when we have operator. -def min(*arr): + +def _identity(arg): + return arg + + +def min(*arr, **kwargs): """return the smallest number in a list, or its smallest argument if more than one is given.""" + return min_max(gt, "min", *arr, **kwargs) + +def min_max(comp, funcname, *arr, **kwargs): + key = kwargs.pop("key", _identity) + if len(kwargs): + raise TypeError, '%s() got an unexpected keyword argument' % funcname + if not arr: - raise TypeError, 'min() takes at least one argument' + raise TypeError, '%s() takes at least one argument' % funcname if len(arr) == 1: arr = arr[0] iterator = iter(arr) try: - min = iterator.next() + min_max_val = iterator.next() except StopIteration: - raise ValueError, 'min() arg is an empty sequence' + raise ValueError, '%s() arg is an empty sequence' % funcname + + keyed_min_max_val = key(min_max_val) for i in iterator: - if min > i: - min = i - return min + keyed = key(i) + if comp(keyed_min_max_val, keyed): + min_max_val = i + keyed_min_max_val = keyed + return min_max_val -def max(*arr): +def max(*arr, **kwargs): """return the largest number in a list, or its largest argument if more than one is given.""" - if not arr: - raise TypeError, 'max() takes at least one argument' - - if len(arr) == 1: - arr = arr[0] - - iterator = iter(arr) - try: - max = iterator.next() - except StopIteration: - raise ValueError, 'max() arg is an empty sequence' - - for i in iterator: - if max < i: - max = i - return max + return min_max(lt, "max", *arr, **kwargs) class enumerate(object): """enumerate(iterable) -> iterator for (index, value) of iterable. @@ -342,15 +346,15 @@ def __len__(self): return self.len - def __getitem__(self, index): + def __getitem__(self, i): # xrange does NOT support slicing - if not isinstance(index, int): - raise TypeError, "sequence index must be integer" + import operator + i = operator.index(i) len = self.len - if index < 0: - index += len - if 0 <= index < len: - return self.start + index * self.step + if i < 0: + i += len + if 0 <= i < len: + return self.start + i * self.step raise IndexError, "xrange object index out of range" def __iter__(self): 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 Mar 5 10:50:02 2007 @@ -350,7 +350,7 @@ self.space.wrap("seek out of range")) self.pos = where - seek.unwrap_spec = ['self', int, int] + seek.unwrap_spec = ['self', 'index', int] def tell(self): self.check_valid() @@ -679,7 +679,7 @@ m.setdata(res, map_size) return space.wrap(m) - mmap.unwrap_spec = [ObjSpace, int, int, int, int, int] + mmap.unwrap_spec = [ObjSpace, int, 'index', int, int, int] elif _MS_WINDOWS: def mmap(space, fileno, length, tagname="", access=_ACCESS_DEFAULT): # check size boundaries @@ -771,4 +771,4 @@ raise OperationError(space.w_EnvironmentError, space.wrap(os.strerror(dwErr))) - mmap.unwrap_spec = [ObjSpace, int, int, str, int] + mmap.unwrap_spec = [ObjSpace, int, 'index', str, int] Modified: pypy/dist/pypy/objspace/cpy/function.py ============================================================================== --- pypy/dist/pypy/objspace/cpy/function.py (original) +++ pypy/dist/pypy/objspace/cpy/function.py Mon Mar 5 10:50:02 2007 @@ -52,7 +52,9 @@ def visit__object(self, el): convertermap = {int: 'int_w', str: 'str_w', - float: 'float_w'} + float: 'float_w', + "index": 'getindex_w' + } argname = self.orig_arg() assert not argname.startswith('w_') self.inputargs.append(argname) @@ -62,6 +64,9 @@ argname)) self.passedargs.append(argname) + def visit_index(self, el): + self.visit__object("index") + def visit_args_w(self, el): argname = self.orig_arg() assert argname.endswith('_w') Modified: pypy/dist/pypy/objspace/cpy/objspace.py ============================================================================== --- pypy/dist/pypy/objspace/cpy/objspace.py (original) +++ pypy/dist/pypy/objspace/cpy/objspace.py Mon Mar 5 10:50:02 2007 @@ -148,6 +148,11 @@ repr = staticmethod(PyObject_Repr) id = staticmethod(PyLong_FromVoidPtr_PYOBJ) + def index(self, w_obj): + # XXX we do not support 2.5 yet, so we just do some + # hack here to have index working + return self.wrap(self.int_w(w_obj)) + def bigint_w(self, w_obj): if self.is_true(self.isinstance(w_obj, self.w_long)): sign = _PyLong_Sign(w_obj) Modified: pypy/dist/pypy/objspace/descroperation.py ============================================================================== --- pypy/dist/pypy/objspace/descroperation.py (original) +++ pypy/dist/pypy/objspace/descroperation.py Mon Mar 5 10:50:02 2007 @@ -515,6 +515,7 @@ for targetname, specialname, checkerspec in [ ('int', '__int__', ("space.w_int", "space.w_long")), + ('index', '__index__', ("space.w_int", "space.w_long")), ('long', '__long__', ("space.w_int", "space.w_long")), ('float', '__float__', ("space.w_float",))]: @@ -538,7 +539,7 @@ assert not hasattr(DescrOperation, %(targetname)r) DescrOperation.%(targetname)s = %(targetname)s del %(targetname)s - \n""" % locals() + \n""" % locals() exec compile2(source) for targetname, specialname in [ @@ -580,7 +581,7 @@ for _name, _symbol, _arity, _specialnames in ObjSpace.MethodTable: if not hasattr(DescrOperation, _name): _impl_maker = None - if _arity ==2 and _name in ['lt', 'le', 'gt', 'ge', 'ne', 'eq']: + if _arity == 2 and _name in ['lt', 'le', 'gt', 'ge', 'ne', 'eq']: #print "comparison", _specialnames _impl_maker = _make_comparison_impl elif _arity == 2 and _name.startswith('inplace_'): Modified: pypy/dist/pypy/objspace/flow/operation.py ============================================================================== --- pypy/dist/pypy/objspace/flow/operation.py (original) +++ pypy/dist/pypy/objspace/flow/operation.py Mon Mar 5 10:50:02 2007 @@ -23,6 +23,9 @@ def do_int(x): return x.__int__() +def do_index(x): + return x.__index__() + def do_float(x): return x.__float__() @@ -162,6 +165,7 @@ ('divmod', divmod), ('pow', pow), ('int', do_int), + ('index', do_index), ('float', do_float), ('long', do_long), ('inplace_add', inplace_add), Modified: pypy/dist/pypy/objspace/std/dictmultiobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/dictmultiobject.py (original) +++ pypy/dist/pypy/objspace/std/dictmultiobject.py Mon Mar 5 10:50:02 2007 @@ -138,6 +138,7 @@ def get(self, w_lookup): return None + def setitem(self, w_key, w_value): if _is_str(self.space, w_key): return StrDictImplementation(self.space).setitem_str(w_key, w_value) @@ -1010,6 +1011,15 @@ result[key] = val return result + def missing_method(w_dict, space, w_key): + if not space.is_w(space.type(w_dict), space.w_dict): + w_missing = space.lookup(w_dict, "__missing__") + if w_missing is None: + return None + return space.call_function(w_missing, w_dict, w_key) + else: + return None + def len(w_self): return w_self.implementation.length() @@ -1054,6 +1064,11 @@ w_value = w_dict.implementation.get(w_lookup) if w_value is not None: return w_value + + w_missing_item = w_dict.missing_method(space, w_lookup) + if w_missing_item is not None: + return w_missing_item + raise OperationError(space.w_KeyError, w_lookup) def setitem__DictMulti_ANY_ANY(space, w_dict, w_newkey, w_newvalue): Modified: pypy/dist/pypy/objspace/std/dictobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/dictobject.py (original) +++ pypy/dist/pypy/objspace/std/dictobject.py Mon Mar 5 10:50:02 2007 @@ -41,6 +41,15 @@ def get(w_dict, w_lookup, w_default): return w_dict.content.get(w_lookup, w_default) + def missing_method(w_dict, space, w_key): + if not space.is_w(space.type(w_dict), space.w_dict): + w_missing = space.lookup(w_dict, "__missing__") + if w_missing is None: + return None + return space.call_function(w_missing, w_dict, w_key) + else: + return None + def set_str_keyed_item(w_dict, w_key, w_value, shadows_type=True): w_dict.content[w_key] = w_value @@ -73,7 +82,11 @@ try: return w_dict.content[w_lookup] except KeyError: - raise OperationError(space.w_KeyError, w_lookup) + w_missing_item = w_dict.missing_method(space, w_lookup) + if w_missing_item is None: + raise OperationError(space.w_KeyError, w_lookup) + else: + return w_missing_item def setitem__Dict_ANY_ANY(space, w_dict, w_newkey, w_newvalue): w_dict.content[w_newkey] = w_newvalue Modified: pypy/dist/pypy/objspace/std/intobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/intobject.py (original) +++ pypy/dist/pypy/objspace/std/intobject.py Mon Mar 5 10:50:02 2007 @@ -326,6 +326,9 @@ a = w_int1.intval return wrapint(space, a) +def index__Int(space, w_int1): + return int__Int(space, w_int1) + def float__Int(space, w_int1): a = w_int1.intval x = float(a) Modified: pypy/dist/pypy/objspace/std/listmultiobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/listmultiobject.py (original) +++ pypy/dist/pypy/objspace/std/listmultiobject.py Mon Mar 5 10:50:02 2007 @@ -1,5 +1,6 @@ from pypy.objspace.std.objspace import * from pypy.objspace.std.inttype import wrapint +from pypy.objspace.std.listtype import get_list_index from pypy.objspace.std.sliceobject import W_SliceObject from pypy.objspace.std import slicetype @@ -892,7 +893,7 @@ return wrapint(space, result) def getitem__ListMulti_ANY(space, w_list, w_index): - idx = space.int_w(w_index) + idx = get_list_index(space, w_index) idx = _adjust_index(space, idx, w_list.implementation.length(), "list index out of range") return w_list.implementation.getitem(idx) @@ -940,7 +941,7 @@ def mul_list_times(space, w_list, w_times): try: - times = space.int_w(w_times) + times = space.getindex_w(w_times, space.w_OverflowError) except OperationError, e: if e.match(space, space.w_TypeError): raise FailedToImplement @@ -957,7 +958,7 @@ def inplace_mul__ListMulti_ANY(space, w_list, w_times): try: - times = space.int_w(w_times) + times = space.getindex_w(w_times, space.w_OverflowError) except OperationError, e: if e.match(space, space.w_TypeError): raise FailedToImplement @@ -1025,7 +1026,7 @@ w_list2.implementation) def delitem__ListMulti_ANY(space, w_list, w_idx): - idx = space.int_w(w_idx) + idx = get_list_index(space, w_idx) length = w_list.implementation.length() idx = _adjust_index(space, idx, length, "list deletion index out of range") if length == 1: @@ -1059,7 +1060,7 @@ return space.w_None def setitem__ListMulti_ANY_ANY(space, w_list, w_index, w_any): - idx = space.int_w(w_index) + idx = get_list_index(space, 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) Modified: pypy/dist/pypy/objspace/std/listobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/listobject.py (original) +++ pypy/dist/pypy/objspace/std/listobject.py Mon Mar 5 10:50:02 2007 @@ -1,5 +1,6 @@ from pypy.objspace.std.objspace import * from pypy.objspace.std.inttype import wrapint +from pypy.objspace.std.listtype import get_list_index from pypy.objspace.std.sliceobject import W_SliceObject from pypy.objspace.std.tupleobject import W_TupleObject @@ -42,9 +43,8 @@ return wrapint(space, result) def getitem__List_ANY(space, w_list, w_index): - idx = space.int_w(w_index) try: - return w_list.wrappeditems[idx] + return w_list.wrappeditems[get_list_index(space, w_index)] except IndexError: raise OperationError(space.w_IndexError, space.wrap("list index out of range")) @@ -92,7 +92,7 @@ def mul_list_times(space, w_list, w_times): try: - times = space.int_w(w_times) + times = space.getindex_w(w_times, space.w_OverflowError) except OperationError, e: if e.match(space, space.w_TypeError): raise FailedToImplement @@ -107,7 +107,7 @@ def inplace_mul__List_ANY(space, w_list, w_times): try: - times = space.int_w(w_times) + times = space.getindex_w(w_times, space.w_OverflowError) except OperationError, e: if e.match(space, space.w_TypeError): raise FailedToImplement @@ -171,7 +171,7 @@ w_list2.wrappeditems) def delitem__List_ANY(space, w_list, w_idx): - idx = space.int_w(w_idx) + idx = get_list_index(space, w_idx) try: del w_list.wrappeditems[idx] except IndexError: @@ -227,7 +227,7 @@ return space.w_None def setitem__List_ANY_ANY(space, w_list, w_index, w_any): - idx = space.int_w(w_index) + idx = get_list_index(space, w_index) try: w_list.wrappeditems[idx] = w_any except IndexError: Modified: pypy/dist/pypy/objspace/std/listtype.py ============================================================================== --- pypy/dist/pypy/objspace/std/listtype.py (original) +++ pypy/dist/pypy/objspace/std/listtype.py Mon Mar 5 10:50:02 2007 @@ -1,5 +1,6 @@ from __future__ import generators from pypy.interpreter import gateway +from pypy.interpreter.error import OperationError from pypy.objspace.std.stdtypedef import * from pypy.objspace.std.register_all import register_all from sys import maxint @@ -61,3 +62,13 @@ __hash__ = no_hash_descr, ) list_typedef.registermethods(globals()) + +# ____________________________________________________________ + +def get_list_index(space, w_index): + if not space.lookup(w_index, '__index__'): + raise OperationError( + space.w_TypeError, + space.wrap("list indices must be integers, not %s" % + space.type(w_index).getname(space, '?'))) + return space.getindex_w(w_index, space.w_IndexError) Modified: pypy/dist/pypy/objspace/std/longobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/longobject.py (original) +++ pypy/dist/pypy/objspace/std/longobject.py Mon Mar 5 10:50:02 2007 @@ -50,6 +50,9 @@ def is_odd(self): return self.num.is_odd() + def get_sign(self): + return self.num.sign + registerimplementation(W_LongObject) # bool-to-long @@ -79,6 +82,9 @@ except OverflowError: return long__Long(space, w_value) +def index__Long(space, w_value): + return long__Long(space, w_value) + def float__Long(space, w_longobj): try: return space.newfloat(w_longobj.num.tofloat()) Modified: pypy/dist/pypy/objspace/std/rangeobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/rangeobject.py (original) +++ pypy/dist/pypy/objspace/std/rangeobject.py Mon Mar 5 10:50:02 2007 @@ -78,7 +78,7 @@ def getitem__RangeList_ANY(space, w_rangelist, w_index): if w_rangelist.w_list is not None: return space.getitem(w_rangelist.w_list, w_index) - idx = space.int_w(w_index) + idx = space.getindex_w(w_index, space.w_IndexError) try: return wrapint(space, w_rangelist.getitem(idx)) except IndexError: Modified: pypy/dist/pypy/objspace/std/sliceobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/sliceobject.py (original) +++ pypy/dist/pypy/objspace/std/sliceobject.py Mon Mar 5 10:50:02 2007 @@ -111,7 +111,7 @@ # indices impl def slice_indices__Slice_ANY(space, w_slice, w_length): - length = space.int_w(w_length) + length = space.getindex_w(w_length, space.w_OverflowError) start, stop, step = w_slice.indices3(space, length) return space.newtuple([space.wrap(start), space.wrap(stop), space.wrap(step)]) Modified: pypy/dist/pypy/objspace/std/slicetype.py ============================================================================== --- pypy/dist/pypy/objspace/std/slicetype.py (original) +++ pypy/dist/pypy/objspace/std/slicetype.py Mon Mar 5 10:50:02 2007 @@ -15,17 +15,19 @@ # utility functions def _Eval_SliceIndex(space, w_int): - try: - x = space.int_w(w_int) - except OperationError, e: - if not e.match(space, space.w_OverflowError): - raise - cmp = space.is_true(space.ge(w_int, space.wrap(0))) - if cmp: - x = sys.maxint - else: - x = -sys.maxint - return x + return space.getindex_w(w_int) # clamp if long integer is too large + # This is done by getindex_w already. + #try: + # x = space.getindex_w(w_int) + #except OperationError, e: + # if not e.match(space, space.w_OverflowError): + # raise + # cmp = space.is_true(space.ge(w_int, space.wrap(0))) + # if cmp: + # x = sys.maxint + # else: + # x = -sys.maxint + #return x def adapt_bound(space, w_index, w_size): if not (space.is_true(space.isinstance(w_index, space.w_int)) or Modified: pypy/dist/pypy/objspace/std/stringobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/stringobject.py (original) +++ pypy/dist/pypy/objspace/std/stringobject.py Mon Mar 5 10:50:02 2007 @@ -1,4 +1,4 @@ -# -*- Coding: Latin-1 -*- +# -*- coding: latin-1 -*- from pypy.objspace.std.objspace import * from pypy.interpreter import gateway @@ -11,7 +11,8 @@ from pypy.objspace.std.noneobject import W_NoneObject from pypy.objspace.std.tupleobject import W_TupleObject -from pypy.objspace.std.stringtype import sliced, joined, wrapstr, wrapchar +from pypy.objspace.std.stringtype import sliced, joined, wrapstr, wrapchar, \ + stringendswith, stringstartswith class W_StringObject(W_Object): @@ -343,7 +344,6 @@ return W_StringObject.EMPTY def str_rjust__String_ANY_ANY(space, w_self, w_arg, w_fillchar): - u_arg = space.int_w(w_arg) u_self = w_self._value fillchar = space.str_w(w_fillchar) @@ -360,7 +360,6 @@ def str_ljust__String_ANY_ANY(space, w_self, w_arg, w_fillchar): - u_self = w_self._value u_arg = space.int_w(w_arg) fillchar = space.str_w(w_fillchar) @@ -394,19 +393,45 @@ return space.newbool(self.find(sub) >= 0) def str_find__String_String_ANY_ANY(space, w_self, w_sub, w_start, w_end): - (self, sub, start, end) = _convert_idx_params(space, w_self, w_sub, w_start, w_end) res = self.find(sub, start, end) return space.wrap(res) def str_rfind__String_String_ANY_ANY(space, w_self, w_sub, w_start, w_end): - (self, sub, start, end) = _convert_idx_params(space, w_self, w_sub, w_start, w_end) res = self.rfind(sub, start, end) return space.wrap(res) -def str_index__String_String_ANY_ANY(space, w_self, w_sub, w_start, w_end): +def str_partition__String_String(space, w_self, w_sub): + self = w_self._value + sub = w_sub._value + if not sub: + raise OperationError(space.w_ValueError, + space.wrap("empty separator")) + pos = self.find(sub) + if pos == -1: + return space.newtuple([w_self, space.wrap(''), space.wrap('')]) + else: + return space.newtuple([sliced(space, self, 0, pos), + w_sub, + sliced(space, self, pos+len(sub), len(self))]) + +def str_rpartition__String_String(space, w_self, w_sub): + self = w_self._value + sub = w_sub._value + if not sub: + raise OperationError(space.w_ValueError, + space.wrap("empty separator")) + pos = self.rfind(sub) + if pos == -1: + return space.newtuple([space.wrap(''), space.wrap(''), w_self]) + else: + return space.newtuple([sliced(space, self, 0, pos), + w_sub, + sliced(space, self, pos+len(sub), len(self))]) + +def str_index__String_String_ANY_ANY(space, w_self, w_sub, w_start, w_end): (self, sub, start, end) = _convert_idx_params(space, w_self, w_sub, w_start, w_end) res = self.find(sub, start, end) if res < 0: @@ -417,7 +442,6 @@ def str_rindex__String_String_ANY_ANY(space, w_self, w_sub, w_start, w_end): - (self, sub, start, end) = _convert_idx_params(space, w_self, w_sub, w_start, w_end) res = self.rfind(sub, start, end) if res < 0: @@ -428,7 +452,6 @@ def str_replace__String_String_String_ANY(space, w_self, w_sub, w_by, w_maxsplit=-1): - input = w_self._value sub = w_sub._value by = w_by._value @@ -553,26 +576,30 @@ def str_endswith__String_String_ANY_ANY(space, w_self, w_suffix, w_start, w_end): (u_self, suffix, start, end) = _convert_idx_params(space, w_self, w_suffix, w_start, w_end) - begin = end - len(suffix) - if begin < start: - return space.w_False - for i in range(len(suffix)): - if u_self[begin+i] != suffix[i]: - return space.w_False - return space.w_True - - + return space.newbool(stringendswith(u_self, suffix, start, end)) + +def str_endswith__String_Tuple_ANY_ANY(space, w_self, w_suffixes, w_start, w_end): + (u_self, _, start, end) = _convert_idx_params(space, w_self, + space.wrap(''), w_start, w_end) + for w_suffix in space.unpacktuple(w_suffixes): + suffix = space.str_w(w_suffix) + if stringendswith(u_self, suffix, start, end): + return space.w_True + return space.w_False + def str_startswith__String_String_ANY_ANY(space, w_self, w_prefix, w_start, w_end): (u_self, prefix, start, end) = _convert_idx_params(space, w_self, w_prefix, w_start, w_end) - stop = start + len(prefix) - if stop > end: - return space.w_False - for i in range(len(prefix)): - if u_self[start+i] != prefix[i]: - return space.w_False - return space.w_True - + return space.newbool(stringstartswith(u_self, prefix, start, end)) + +def str_startswith__String_Tuple_ANY_ANY(space, w_self, w_prefixes, w_start, w_end): + (u_self, _, start, end) = _convert_idx_params(space, w_self, space.wrap(''), + w_start, w_end) + for w_prefix in space.unpacktuple(w_prefixes): + prefix = space.str_w(w_prefix) + if stringstartswith(u_self, prefix, start, end): + return space.w_True + return space.w_False def _tabindent(u_token, u_tabsize): "calculates distance behind the token to the next tabstop" @@ -731,7 +758,12 @@ return space.w_False def getitem__String_ANY(space, w_str, w_index): - ival = space.int_w(w_index) + if not space.lookup(w_index, '__index__'): + raise OperationError( + space.w_TypeError, + space.wrap("string indices must be integers, not %s" % + space.type(w_index).getname(space, '?'))) + ival = space.getindex_w(w_index, space.w_IndexError) str = w_str._value slen = len(str) if ival < 0: @@ -758,7 +790,7 @@ def mul_string_times(space, w_str, w_times): try: - mul = space.int_w(w_times) + mul = space.getindex_w(w_times, space.w_OverflowError) except OperationError, e: if e.match(space, space.w_TypeError): raise FailedToImplement Modified: pypy/dist/pypy/objspace/std/stringtype.py ============================================================================== --- pypy/dist/pypy/objspace/std/stringtype.py (original) +++ pypy/dist/pypy/objspace/std/stringtype.py Mon Mar 5 10:50:02 2007 @@ -28,6 +28,8 @@ return W_StringObject(c) def sliced(space, s, start, stop): + assert start >= 0 + assert stop >= 0 if space.config.objspace.std.withstrslice: from pypy.objspace.std.strsliceobject import W_StringSliceObject # XXX heuristic, should be improved! @@ -133,6 +135,18 @@ ' s[start,end]. Optional\narguments start and end' ' are interpreted as in slice notation.\n\nReturn -1' ' on failure.') +str_partition = SMM('partition', 2, + doc='S.partition(sep) -> (head, sep, tail)\n\nSearches' + ' for the separator sep in S, and returns the part before' + ' it,\nthe separator itself, and the part after it. If' + ' the separator is not\nfound, returns S and two empty' + ' strings.') +str_rpartition = SMM('rpartition', 2, + doc='S.rpartition(sep) -> (tail, sep, head)\n\nSearches' + ' for the separator sep in S, starting at the end of S,' + ' and returns\nthe part before it, the separator itself,' + ' and the part after it. If the\nseparator is not found,' + ' returns two empty strings and S.') str_index = SMM('index', 4, defaults=(0, maxint), doc='S.index(sub [,start [,end]]) -> int\n\nLike S.find()' ' but raise ValueError when the substring is not' @@ -256,3 +270,26 @@ str_typedef.custom_hash = True str_typedef.registermethods(globals()) + +# ____________________________________________________________ + +# Helpers for several string implementations + +def stringendswith(u_self, suffix, start, end): + begin = end - len(suffix) + if begin < start: + return False + for i in range(len(suffix)): + if u_self[begin+i] != suffix[i]: + return False + return True + +def stringstartswith(u_self, prefix, start, end): + stop = start + len(prefix) + if stop > end: + return False + for i in range(len(prefix)): + if u_self[start+i] != prefix[i]: + return False + return True + Modified: pypy/dist/pypy/objspace/std/strsliceobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/strsliceobject.py (original) +++ pypy/dist/pypy/objspace/std/strsliceobject.py Mon Mar 5 10:50:02 2007 @@ -2,16 +2,20 @@ from pypy.objspace.std.stringobject import W_StringObject from pypy.objspace.std.unicodeobject import delegate_String2Unicode from pypy.objspace.std.sliceobject import W_SliceObject +from pypy.objspace.std.tupleobject import W_TupleObject from pypy.objspace.std import slicetype from pypy.objspace.std.inttype import wrapint -from pypy.objspace.std.stringtype import wrapstr, wrapchar +from pypy.objspace.std.stringtype import wrapstr, wrapchar, sliced, \ + stringendswith, stringstartswith class W_StringSliceObject(W_Object): from pypy.objspace.std.stringtype import str_typedef as typedef def __init__(w_self, str, start, stop): + assert start >= 0 + assert stop >= 0 w_self.str = str w_self.start = start w_self.stop = stop @@ -63,7 +67,6 @@ def str_find__StringSlice_String_ANY_ANY(space, w_self, w_sub, w_start, w_end): - (self, sub, start, end) = _convert_idx_params(space, w_self, w_sub, w_start, w_end) res = self.find(sub, start, end) if res >= 0: @@ -71,13 +74,41 @@ else: return space.wrap(res) +def str_partition__StringSlice_String(space, w_self, w_sub): + self = w_self.str + sub = w_sub._value + if not sub: + raise OperationError(space.w_ValueError, + space.wrap("empty separator")) + pos = self.find(sub, w_self.start, w_self.stop) + if pos == -1: + return space.newtuple([w_self, space.wrap(''), space.wrap('')]) + else: + return space.newtuple([sliced(space, self, w_self.start, pos), + w_sub, + sliced(space, self, pos+len(sub), w_self.stop)]) + +def str_rpartition__StringSlice_String(space, w_self, w_sub): + self = w_self.str + sub = w_sub._value + if not sub: + raise OperationError(space.w_ValueError, + space.wrap("empty separator")) + pos = self.rfind(sub, w_self.start, w_self.stop) + if pos == -1: + return space.newtuple([space.wrap(''), space.wrap(''), w_self]) + else: + return space.newtuple([sliced(space, self, w_self.start, pos), + w_sub, + sliced(space, self, pos+len(sub), w_self.stop)]) + + def str_count__StringSlice_String_ANY_ANY(space, w_self, w_arg, w_start, w_end): (s, arg, start, end) = _convert_idx_params( space, w_self, w_arg, w_start, w_end) return wrapint(space, s.count(arg, start, end)) def str_rfind__StringSlice_String_ANY_ANY(space, w_self, w_sub, w_start, w_end): - (self, sub, start, end) = _convert_idx_params(space, w_self, w_sub, w_start, w_end) res = self.rfind(sub, start, end) if res >= 0: @@ -86,7 +117,6 @@ return space.wrap(res) def str_index__StringSlice_String_ANY_ANY(space, w_self, w_sub, w_start, w_end): - (self, sub, start, end) = _convert_idx_params(space, w_self, w_sub, w_start, w_end) res = self.find(sub, start, end) if res < 0: @@ -97,7 +127,6 @@ def str_rindex__StringSlice_String_ANY_ANY(space, w_self, w_sub, w_start, w_end): - (self, sub, start, end) = _convert_idx_params(space, w_self, w_sub, w_start, w_end) res = self.rfind(sub, start, end) if res < 0: @@ -106,13 +135,46 @@ return space.wrap(res - w_self.start) +def str_endswith__StringSlice_String_ANY_ANY(space, w_self, w_suffix, w_start, w_end): + (u_self, suffix, start, end) = _convert_idx_params(space, w_self, + w_suffix, w_start, w_end) + return space.newbool(stringendswith(u_self, suffix, start, end)) + +def str_endswith__StringSlice_Tuple_ANY_ANY(space, w_self, w_suffixes, w_start, w_end): + (u_self, _, start, end) = _convert_idx_params(space, w_self, + space.wrap(''), w_start, w_end) + for w_suffix in space.unpacktuple(w_suffixes): + suffix = space.str_w(w_suffix) + if stringendswith(u_self, suffix, start, end): + return space.w_True + return space.w_False + +def str_startswith__StringSlice_String_ANY_ANY(space, w_self, w_prefix, w_start, w_end): + (u_self, prefix, start, end) = _convert_idx_params(space, w_self, + w_prefix, w_start, w_end) + return space.newbool(stringstartswith(u_self, prefix, start, end)) + +def str_startswith__StringSlice_Tuple_ANY_ANY(space, w_self, w_prefixes, w_start, w_end): + (u_self, _, start, end) = _convert_idx_params(space, w_self, space.wrap(''), + w_start, w_end) + for w_prefix in space.unpacktuple(w_prefixes): + prefix = space.str_w(w_prefix) + if stringstartswith(u_self, prefix, start, end): + return space.w_True + return space.w_False + def str_w__StringSlice(space, w_str): return w_str.force() def getitem__StringSlice_ANY(space, w_str, w_index): - ival = space.int_w(w_index) + if not space.lookup(w_index, '__index__'): + raise OperationError( + space.w_TypeError, + space.wrap("string indices must be integers, not %s" % + space.type(w_index).getname(space, '?'))) + ival = space.getindex_w(w_index, space.w_IndexError) slen = w_str.stop - w_str.start if ival < 0: ival += slen @@ -148,5 +210,6 @@ return w_str return W_StringSliceObject(w_str.str, w_str.start, w_str.stop) + from pypy.objspace.std import stringtype register_all(vars(), stringtype) Modified: pypy/dist/pypy/objspace/std/test/test_stringobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/test/test_stringobject.py (original) +++ pypy/dist/pypy/objspace/std/test/test_stringobject.py Mon Mar 5 10:50:02 2007 @@ -5,7 +5,7 @@ class TestW_StringObject: - def teardown_method(self,method): + def teardown_method(self, method): pass ## def test_order_rich(self): @@ -334,6 +334,18 @@ assert 'abc'.startswith('bc', 1, 2) is False assert 'abc'.startswith('c', -1, 4) is True + def test_startswith_tuples(self): + assert 'hello'.startswith(('he', 'ha')) + assert not 'hello'.startswith(('lo', 'llo')) + assert 'hello'.startswith(('hellox', 'hello')) + assert not 'hello'.startswith(()) + assert 'helloworld'.startswith(('hellowo', 'rld', 'lowo'), 3) + assert not 'helloworld'.startswith(('hellowo', 'ello', 'rld'), 3) + assert 'hello'.startswith(('lo', 'he'), 0, -1) + assert not 'hello'.startswith(('he', 'hel'), 0, 1) + assert 'hello'.startswith(('he', 'hel'), 0, 2) + raises(TypeError, 'hello'.startswith, (42,)) + def test_endswith(self): assert 'ab'.endswith('ab') is True assert 'ab'.endswith('b') is True @@ -350,7 +362,19 @@ assert 'abc'.endswith('bc', 1) is True assert 'abc'.endswith('bc', 2) is False assert 'abc'.endswith('b', -3, -1) is True - + + def test_endswith_tuple(self): + assert not 'hello'.endswith(('he', 'ha')) + assert 'hello'.endswith(('lo', 'llo')) + assert 'hello'.endswith(('hellox', 'hello')) + assert not 'hello'.endswith(()) + assert 'helloworld'.endswith(('hellowo', 'rld', 'lowo'), 3) + assert not 'helloworld'.endswith(('hellowo', 'ello', 'rld'), 3, -1) + assert 'hello'.endswith(('hell', 'ell'), 0, -1) + assert not 'hello'.endswith(('he', 'hel'), 0, 1) + assert 'hello'.endswith(('he', 'hell'), 0, 4) + raises(TypeError, 'hello'.endswith, (42,)) + def test_expandtabs(self): assert 'abc\rab\tdef\ng\thi'.expandtabs() == 'abc\rab def\ng hi' assert 'abc\rab\tdef\ng\thi'.expandtabs(8) == 'abc\rab def\ng hi' @@ -436,6 +460,36 @@ raises(TypeError, 'abcdefghijklmn'.rindex, 'abc', -10.0, 30) + def test_partition(self): + + assert ('this is the par', 'ti', 'tion method') == \ + 'this is the partition method'.partition('ti') + + # from raymond's original specification + S = 'http://www.python.org' + assert ('http', '://', 'www.python.org') == S.partition('://') + assert ('http://www.python.org', '', '') == S.partition('?') + assert ('', 'http://', 'www.python.org') == S.partition('http://') + assert ('http://www.python.', 'org', '') == S.partition('org') + + raises(ValueError, S.partition, '') + raises(TypeError, S.partition, None) + + def test_rpartition(self): + + assert ('this is the rparti', 'ti', 'on method') == \ + 'this is the rpartition method'.rpartition('ti') + + # from raymond's original specification + S = 'http://www.python.org' + assert ('http', '://', 'www.python.org') == S.rpartition('://') + assert ('', '', 'http://www.python.org') == S.rpartition('?') + assert ('', 'http://', 'www.python.org') == S.rpartition('http://') + assert ('http://www.python.', 'org', '') == S.rpartition('org') + + raises(ValueError, S.rpartition, '') + raises(TypeError, S.rpartition, None) + def test_split_maxsplit(self): assert "/a/b/c".split('/', 2) == ['','a','b/c'] assert "a/b/c".split("/") == ['a', 'b', 'c'] Modified: pypy/dist/pypy/objspace/std/tupleobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/tupleobject.py (original) +++ pypy/dist/pypy/objspace/std/tupleobject.py Mon Mar 5 10:50:02 2007 @@ -28,13 +28,18 @@ return wrapint(space, result) def getitem__Tuple_ANY(space, w_tuple, w_index): - items = w_tuple.wrappeditems + if not space.lookup(w_index, '__index__'): + raise OperationError( + space.w_TypeError, + space.wrap("tuple indices must be integers, not %s" % + space.type(w_index).getname(space, '?'))) try: - w_item = items[space.int_w(w_index)] + # XXX: getindex_w should get a second argument space.w_IndexError, + # but that doesn't exist the first time this is called. + return w_tuple.wrappeditems[space.getindex_w(w_index)] except IndexError: raise OperationError(space.w_IndexError, space.wrap("tuple index out of range")) - return w_item def getitem__Tuple_Slice(space, w_tuple, w_slice): items = w_tuple.wrappeditems @@ -64,7 +69,7 @@ def mul_tuple_times(space, w_tuple, w_times): try: - times = space.int_w(w_times) + times = space.getindex_w(w_times, space.w_OverflowError) except OperationError, e: if e.match(space, space.w_TypeError): raise FailedToImplement Modified: pypy/dist/pypy/objspace/std/unicodeobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/unicodeobject.py (original) +++ pypy/dist/pypy/objspace/std/unicodeobject.py Mon Mar 5 10:50:02 2007 @@ -3,6 +3,7 @@ from pypy.objspace.std.stringobject import W_StringObject from pypy.objspace.std.noneobject import W_NoneObject from pypy.objspace.std.sliceobject import W_SliceObject +from pypy.objspace.std.tupleobject import W_TupleObject from pypy.rlib.rarithmetic import intmask, ovfcheck from pypy.module.unicodedata import unicodedb_3_2_0 as unicodedb @@ -203,7 +204,12 @@ return space.wrap(len(w_uni._value)) def getitem__Unicode_ANY(space, w_uni, w_index): - ival = space.int_w(w_index) + if not space.lookup(w_index, '__index__'): + raise OperationError( + space.w_TypeError, + space.wrap("string indices must be integers, not %s" % + space.type(w_index).getname(space, '?'))) + ival = space.getindex_w(w_index, space.w_IndexError) uni = w_uni._value ulen = len(uni) if ival < 0: @@ -230,7 +236,7 @@ def mul__Unicode_ANY(space, w_uni, w_times): chars = w_uni._value charlen = len(chars) - times = space.int_w(w_times) + times = space.getindex_w(w_times, space.w_OverflowError) if times <= 0 or charlen == 0: return W_UnicodeObject([]) if times == 1: @@ -860,15 +866,44 @@ type(retval).__name__) return retval -def repr__Unicode(unistr): - import _codecs - return ''.join(_codecs.unicodeescape_string(unistr,len(unistr),True)) +# XXX: These should probably be written on interplevel + +def unicode_partition__Unicode_Unicode(unistr, unisub): + pos = unistr.find(unisub) + if pos == -1: + return (unistr, u'', u'') + else: + return (unistr[:pos], unisub, unistr[pos+len(unisub):]) + +def unicode_rpartition__Unicode_Unicode(unistr, unisub): + pos = unistr.rfind(unisub) + if pos == -1: + return (u'', u'', unistr) + else: + return (unistr[:pos], unisub, unistr[pos+len(unisub):]) + +def unicode_startswith__Unicode_Tuple_ANY_ANY(unistr, prefixes, start, end): + for prefix in prefixes: + if unistr.startswith(prefix): + return True + return False + +def unicode_endswith__Unicode_Tuple_ANY_ANY(unistr, suffixes, start, end): + for suffix in suffixes: + if unistr.endswith(suffix): + return True + return False ''') + +mod__Unicode_ANY = app.interphook('mod__Unicode_ANY') unicode_expandtabs__Unicode_ANY = app.interphook('unicode_expandtabs__Unicode_ANY') unicode_translate__Unicode_ANY = app.interphook('unicode_translate__Unicode_ANY') -mod__Unicode_ANY = app.interphook('mod__Unicode_ANY') unicode_encode__Unicode_ANY_ANY = app.interphook('unicode_encode__Unicode_ANY_ANY') +unicode_partition__Unicode_Unicode = app.interphook('unicode_partition__Unicode_Unicode') +unicode_rpartition__Unicode_Unicode = app.interphook('unicode_rpartition__Unicode_Unicode') +unicode_startswith__Unicode_Tuple_ANY_ANY = app.interphook('unicode_startswith__Unicode_Tuple_ANY_ANY') +unicode_endswith__Unicode_Tuple_ANY_ANY = app.interphook('unicode_endswith__Unicode_Tuple_ANY_ANY') # Move this into the _codecs module as 'unicodeescape_string (Remember to cater for quotes)' def repr__Unicode(space, w_unicode): Modified: pypy/dist/pypy/objspace/std/unicodetype.py ============================================================================== --- pypy/dist/pypy/objspace/std/unicodetype.py (original) +++ pypy/dist/pypy/objspace/std/unicodetype.py Mon Mar 5 10:50:02 2007 @@ -207,6 +207,19 @@ ' string x with zeros on the left, to fill a' ' field\nof the specified width. The string x is' ' never truncated.') +unicode_partition = SMM('partition', 2, + doc='S.partition(sep) -> (head, sep, tail)\n\nSearches' + ' for the separator sep in S, and returns the part before' + ' it,\nthe separator itself, and the part after it. If' + ' the separator is not\nfound, returns S and two empty' + ' strings.') +unicode_rpartition = SMM('rpartition', 2, + doc='S.rpartition(sep) -> (tail, sep, head)\n\nSearches' + ' for the separator sep in S, starting at the end of S,' + ' and returns\nthe part before it, the separator itself,' + ' and the part after it. If the\nseparator is not found,' + ' returns two empty strings and S.') + # ____________________________________________________________ Modified: pypy/dist/pypy/rlib/streamio.py ============================================================================== --- pypy/dist/pypy/rlib/streamio.py (original) +++ pypy/dist/pypy/rlib/streamio.py Mon Mar 5 10:50:02 2007 @@ -356,7 +356,7 @@ ("read", [int]), ("write", [str]), ("tell", []), - ("seek", [int, int]), + ("seek", ["index", int]), ("readall", []), ("readline", []), ("truncate", [int]), From xoraxax at codespeak.net Mon Mar 5 10:51:51 2007 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Mon, 5 Mar 2007 10:51:51 +0100 (CET) Subject: [pypy-svn] r39946 - pypy/branch/pypy-2.5 Message-ID: <20070305095151.A92B610071@code0.codespeak.net> Author: xoraxax Date: Mon Mar 5 10:51:49 2007 New Revision: 39946 Removed: pypy/branch/pypy-2.5/ Log: Kill the pypy-2.5 branch, it was merged in rev 39945 to dist. From ac at codespeak.net Mon Mar 5 11:10:06 2007 From: ac at codespeak.net (ac at codespeak.net) Date: Mon, 5 Mar 2007 11:10:06 +0100 (CET) Subject: [pypy-svn] r39947 - in pypy/dist/pypy: bin translator/goal Message-ID: <20070305101006.895D810070@code0.codespeak.net> Author: ac Date: Mon Mar 5 11:10:05 2007 New Revision: 39947 Modified: pypy/dist/pypy/bin/py.py pypy/dist/pypy/translator/goal/app_main.py Log: Add support for PYTHONSTARTUP environment variable. Modified: pypy/dist/pypy/bin/py.py ============================================================================== --- pypy/dist/pypy/bin/py.py (original) +++ pypy/dist/pypy/bin/py.py Mon Mar 5 11:10:05 2007 @@ -46,9 +46,19 @@ import site except: import sys - print >> sys.stderr, "import site' failed" + print >> sys.stderr, "import site\' failed" ''').interphook('pypy_init') +def getenv_w(space, name): + w_os = space.getbuiltinmodule('os') + w_environ = space.getattr(w_os, space.wrap('environ')) + w_v = space.call_method(w_environ, 'get', space.wrap(name)) + try: + return space.str_w(w_v) + except: + return None + + def main_(argv=None): starttime = time.time() config, parser = option.get_standard_options() @@ -111,7 +121,14 @@ exit_status = 1 # start the interactive console - if go_interactive: + if go_interactive or getenv_w(space, 'PYTHONINSPECT'): + python_startup = getenv_w(space, 'PYTHONSTARTUP') + if python_startup: + try: + main.run_file(python_startup, space=space) + except: + pass + con = interactive.PyPyConsole( space, verbose=interactiveconfig.verbose, completer=interactiveconfig.completer) 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 Mon Mar 5 11:10:05 2007 @@ -267,7 +267,14 @@ else: sys.argv.append('') go_interactive = True + if go_interactive or os.environ.get('PYTHONINSPECT'): + python_startup = os.environ.get('PYTHONSTARTUP') + if python_startup: + try: + execfile(python_startup, mainmodule.__dict__) + except: + pass print >> sys.stderr, "debug: importing code" import code print >> sys.stderr, "debug: calling code.interact()" From mwh at codespeak.net Mon Mar 5 11:33:42 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Mon, 5 Mar 2007 11:33:42 +0100 (CET) Subject: [pypy-svn] r39949 - pypy/extradoc/sprintinfo/trillke-2007 Message-ID: <20070305103342.71B6010075@code0.codespeak.net> Author: mwh Date: Mon Mar 5 11:33:40 2007 New Revision: 39949 Added: pypy/extradoc/sprintinfo/trillke-2007/sprint-report.txt (contents, props changed) Log: half a sprint report Added: pypy/extradoc/sprintinfo/trillke-2007/sprint-report.txt ============================================================================== --- (empty file) +++ pypy/extradoc/sprintinfo/trillke-2007/sprint-report.txt Mon Mar 5 11:33:40 2007 @@ -0,0 +1,113 @@ +Hello pypy-dev! + +25th sprint, 18th and final EU funded + +tutorial + +As has become ususal, the sprint began with a tutorial for those +participants who are less familiar with PyPy code base. This time +Carl Friedrich was talking to Georg Brandl, an interested CPython +developer, and Anders (only the third Anders to be involved in the +project!) Sigfridsson, a PhD student at the Interaction Design Centre +at the University of Limerick. Anders originally became involved in +the project as an observer of the sprint process for his group's +research when we sprinted at the University of Limerick, and that was +partly why he was here this time, but it seems he found PyPy +interesting enough to learn Python in the mean time and participate on +the coding less at this sprint (or maybe he thought the view from the +sprint trenches would be more revealing!). + +This sprint has seen many, many small tasks completed. On the first +morning, Holger and Armin improved the readline module to the point of +being useful -- supporting line editing and history, but not +completion -- and hooked it into the interpreter sufficiently that the +interactive interpreter and pdb both use it when available. At the +same time Richard and Michael were hunting a bug Richard had +discovered translating his own code, which was generally referred to +as "the rdict bug" but turned out to be a bug in the garbage +collector. + +Carl Friedrich and his band of helpers (mostly Anders, Georg, +Alexander) worked on experimental reimplementations of Python lists, +one using a theoretically optimal overallocation strategy and another +using chunked storage to reduce the cost of list resizing. Sadly both +resulted in a measurable slow down. This can be seen as yet more +evidence that theory is different from practice... + +CF's other target for reimplementation at this sprint was strings. +With help and moral support from Armin, he reimplemented strings +according to the design from the "ropes paper" of Boehm, Atkinson & +Plass: + +http://www.cs.ubc.ca/local/reading/proceedings/spe91-95/spe/vol25/issue12/spe986.pdf + +The predictable effect was that "typical Python code", written in the +knowledge of how strings are implemented in Python today, takes a +small (at most 10%) performance hit, but an arguably more natural and +naive style of string handling becomes efficient. And some completely +crazy code (like hash('a'*sys.maxint)) becomes very fast too... + +Continuing the theme of making things slower by object +reimplementation, Armin supplied an implementation of general +dictionaries as a hash table whose collision resolution is via chained +lists instead of open addressing. Next! + +As opposed to the above, Armin and CF implemented caching of app-level +character (i.e. strings of length 1) objects, which was a clear win, +improving the pystone benchmark by around 10%. + +There have been many discussions recently about optimizing the lookup +of global variables, and during one that took place here about various +corner cases, Armin and Carl Friedrich and Samuele removed from PyPy +some of the strange things CPython does to determine what the +__builtins__ are for the executiong of a given frame -- of course, +depending on the value of PyPy's five millionth configuration option. + +Holger and Antonio came up with yet another optimization idea along +these lines, which can be found in doc/discussion/chained_getattr.txt. + +Georg and Alexander implemented some of Python 2.5's features in the +interpeter, in particular support for __index__ and some extensions to +string and dict methods. + +Anders and Anders worked very productively on fixing some of the bugs +in PyPy's issue tracker, implementing the -m command line option in +pypy-c, much improved handling of EINTR results from syscalls (which +makes most difference when pressing ^C on the command line), allowing +buffer objects to be passed to socket.send and preventing modifications +to builtin types. + +Holger and Stephan worked in the direction of moving the currently +app-level and extremely slow string interpolation code into RPython by +separating out the code that analyzes the format string from the code +that access the values to be interpolated. + +Maciej and Guido worked a little on the javascript backend, both +generally tidying and improving compatibility with Internet Explorer. +Guido should not be allowed to forget saying "I am happy to work with +Internet Explorer" during one of the daily status meetings :-) + +Stephan and Arre worked on fixing the last remaining bugs in the +rewrite of the application-level stackless code that Stephan had been +working on for some time. + +Later Stephan joined Armin and Christian in a discussion about the +best API to provide for the new "composable coroutine" concept. They +feel that the concept is powerful to encompass threads, greenlets, coroutines XXX + +view/pivot/world/composable discussion (/user/stephan) + +benchmarking & graphing +lib/distributed demo +pypy-cli speed/rpython microbenches +genllvm butchery +external functions/translation breaking session +small cli improvements +taint translation +gil-less hacking +os x specific genc hacks +post-funding + + +Cordiali Saluti, +mwh & Carl Friedrich From cfbolz at codespeak.net Mon Mar 5 14:57:20 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 5 Mar 2007 14:57:20 +0100 (CET) Subject: [pypy-svn] r39955 - in pypy/branch/rope-branch/pypy/objspace/std: . test Message-ID: <20070305135720.0798A1006E@code0.codespeak.net> Author: cfbolz Date: Mon Mar 5 14:57:19 2007 New Revision: 39955 Modified: pypy/branch/rope-branch/pypy/objspace/std/rope.py pypy/branch/rope-branch/pypy/objspace/std/ropeobject.py pypy/branch/rope-branch/pypy/objspace/std/test/test_rope.py pypy/branch/rope-branch/pypy/objspace/std/test/test_ropeobject.py pypy/branch/rope-branch/pypy/objspace/std/unicodeobject.py Log: - make ropes use the "composable hash" - change unicode objects to use the same hash if ropes are used - make ropes detect an overflow if their length does not fit into a c long Modified: pypy/branch/rope-branch/pypy/objspace/std/rope.py ============================================================================== --- pypy/branch/rope-branch/pypy/objspace/std/rope.py (original) +++ pypy/branch/rope-branch/pypy/objspace/std/rope.py Mon Mar 5 14:57:19 2007 @@ -1,6 +1,6 @@ import py import sys -from pypy.rlib.rarithmetic import intmask, _hash_string +from pypy.rlib.rarithmetic import intmask, _hash_string, ovfcheck from pypy.rlib.objectmodel import we_are_translated import math @@ -24,6 +24,32 @@ a, b = b, a + b i += 1 +def masked_power(a, b): + if b == 0: + return 1 + if b == 1: + return a + if a == 0: + return 0 + if a == 1: + return 1 + num_bits = 2 + mask = b >> 2 + while mask: + num_bits += 1 + mask >>= 1 + result = a + mask = 1 << (num_bits - 2) + #import pdb; pdb.set_trace() + for i in range(num_bits - 1): + if mask & b: + result = intmask(result * result * a) + else: + result = intmask(result * result) + mask >>= 1 + return result + + class StringNode(object): hash_cache = 0 def length(self): @@ -114,7 +140,10 @@ def __init__(self, left, right): self.left = left self.right = right - self.len = left.length() + right.length() + try: + self.len = ovfcheck(left.length() + right.length()) + except OverflowError: + raise self._depth = max(left.depth(), right.depth()) + 1 self.balanced = False @@ -156,7 +185,7 @@ if not h: h1 = self.left.hash_part() h2 = self.right.hash_part() - x = intmask(h1 + h2 * (1000003 ** self.left.length())) + x = intmask(h2 + h1 * (masked_power(1000003, self.right.length()))) x |= intmask(1L << (NBITS - 1)) h = self.hash_cache = x return h @@ -784,11 +813,13 @@ def eq(node1, node2): if node1 is node2: return True - # could be cleverer and detect partial equalities if node1.length() != node2.length(): return False + if hash_rope(node1) != hash_rope(node2): + return False iter1 = CharIterator(node1) iter2 = CharIterator(node2) + # XXX could be cleverer and detect partial equalities while 1: try: c = iter1.next() @@ -825,28 +856,12 @@ # __________________________________________________________________________ # misc - def hash_rope(rope): length = rope.length() if length == 0: - x = -1 - elif isinstance(rope, LiteralStringNode): - if we_are_translated(): - return hash(rope.s) # to use the hash cache in rpython strings - else: - # to make sure we get the same hash as rpython (otherwise - # translation will freeze W_DictObjects where we can't find the - # keys any more!) - return _hash_string(rope.s) - else: - x = ord(rope.getitem(0)) << 7 - iter = CharIterator(rope) - while 1: - try: - x = (1000003*x) + ord(iter.next()) - except StopIteration: - break - x ^= length - if x == 0: - x = -1 - return intmask(x) + return -1 + x = rope.hash_part() + x <<= 1 # get rid of the bit that is always set + x ^= ord(rope.getitem(0)) + x ^= rope.length() + return intmask(x) Modified: pypy/branch/rope-branch/pypy/objspace/std/ropeobject.py ============================================================================== --- pypy/branch/rope-branch/pypy/objspace/std/ropeobject.py (original) +++ pypy/branch/rope-branch/pypy/objspace/std/ropeobject.py Mon Mar 5 14:57:19 2007 @@ -16,7 +16,6 @@ def __init__(w_self, node): w_self._node = node - w_self._hash = 0 def __repr__(w_self): """ representation for debugging purposes """ @@ -351,8 +350,6 @@ str_w = space.str_w if list_w: self = w_self._node - listlen = 0 - reslen = 0 l = [] for i in range(len(list_w)): w_s = list_w[i] @@ -365,8 +362,16 @@ space.wrap("sequence item %d: expected string, %s " "found" % (i, space.type(w_s).name))) assert isinstance(w_s, W_RopeObject) - l.append(w_s._node) - return W_RopeObject(rope.join(w_self._node, l)) + node = w_s._node + l.append(node) + selfnode = w_self._node + length = selfnode.length() + listlen_minus_one = len(list_w) - 1 + try: + return W_RopeObject(rope.join(selfnode, l)) + except OverflowError: + raise OperationError(space.w_OverflowError, + space.wrap("string too long")) else: return W_RopeObject.empty @@ -483,7 +488,11 @@ substrings.append(rope.LiteralStringNode(iter.next())) substrings.append(by) substrings.append(rope.getslice_one(node, upper, length)) - return W_RopeObject(rope.rebalance(substrings)) + try: + return W_RopeObject(rope.rebalance(substrings)) + except OverflowError: + raise OperationError(space.w_OverflowError, + space.wrap("string too long")) startidx = 0 substrings = [] iter = rope.FindIterator(node, sub) @@ -500,7 +509,11 @@ break maxsplit = maxsplit - 1 substrings.append(rope.getslice_one(node, startidx, length)) - return W_RopeObject(rope.join(by, substrings)) + try: + return W_RopeObject(rope.join(by, substrings)) + except OverflowError: + raise OperationError(space.w_OverflowError, + space.wrap("string too long")) def _strip(space, w_self, w_chars, left, right): "internal function called by str_xstrip methods" @@ -788,11 +801,7 @@ return w_str._node.flatten() def hash__Rope(space, w_str): - hash = w_str._hash - if hash == 0: - node = w_str._node - hash = w_str._hash = rope.hash_rope(node) - return wrapint(space, hash) + return wrapint(space, rope.hash_rope(w_str._node)) def lt__Rope_Rope(space, w_str1, w_str2): n1 = w_str1._node @@ -805,23 +814,9 @@ return space.newbool(rope.compare(n1, n2) <= 0) def _eq(w_str1, w_str2): - h1 = w_str1._hash - h2 = w_str2._hash - if h1 and h2 and h1 != h2: - return False - n1 = w_str1._node - n2 = w_str2._node - result = rope.eq(n1, n2) - if result: - if h1: - if not h2: - w_str2._hash = h1 - else: - if h2: - w_str1._hash = h2 + result = rope.eq(w_str1._node, w_str2._node) return result - def eq__Rope_Rope(space, w_str1, w_str2): return space.newbool(_eq(w_str1, w_str2)) @@ -869,13 +864,17 @@ return W_RopeObject.empty node = w_str._node length = node.length() +# try: +# buflen = ovfcheck(mul * length) +# except OverflowError: +# raise OperationError( +# space.w_OverflowError, +# space.wrap("repeated string is too long: %d %d" % (length, mul))) try: - buflen = ovfcheck(mul * length) + return W_RopeObject(rope.multiply(node, mul)) except OverflowError: - raise OperationError( - space.w_OverflowError, - space.wrap("repeated string is too long: %d %d" % (length, mul))) - return W_RopeObject(rope.multiply(node, mul)) + raise OperationError(space.w_OverflowError, + space.wrap("string too long")) def mul__Rope_ANY(space, w_str, w_times): return mul_string_times(space, w_str, w_times) @@ -886,7 +885,11 @@ def add__Rope_Rope(space, w_left, w_right): right = w_right._node left = w_left._node - return W_RopeObject(rope.concatenate(left, right)) + try: + return W_RopeObject(rope.concatenate(left, right)) + except OverflowError: + raise OperationError(space.w_OverflowError, + space.wrap("string too long")) def len__Rope(space, w_str): return space.wrap(w_str._node.length()) Modified: pypy/branch/rope-branch/pypy/objspace/std/test/test_rope.py ============================================================================== --- pypy/branch/rope-branch/pypy/objspace/std/test/test_rope.py (original) +++ pypy/branch/rope-branch/pypy/objspace/std/test/test_rope.py Mon Mar 5 14:57:19 2007 @@ -1,9 +1,10 @@ import random from pypy.objspace.std.rope import * -def make_random_string(operations=10, slicing=True): +def make_random_string(operations=10, slicing=True, print_seed=True): seed = random.randrange(10000) - print seed + if print_seed: + print seed random.seed(seed) st = "abc" curr = LiteralStringNode(st) @@ -299,21 +300,104 @@ start = r2 + max(len(searchstring), 1) def test_hash(): - from pypy.rlib.rarithmetic import _hash_string + from pypy.rlib.rarithmetic import _hash_string, intmask for i in range(10): - rope, st = make_random_string() - assert hash_rope(rope) == _hash_string(st) - rope = LiteralStringNode(st) - assert hash_rope(rope) == _hash_string(st) - charlist = [chr(random.randrange(0, 256)) for i in range(10)] - st = "".join(charlist) - rope = LiteralStringNode(st) - assert hash_rope(rope) == _hash_string(st) + rope, _ = make_random_string() + if rope.length() == 0: + assert hash_rope(rope) == -1 + continue + h = hash_rope(rope) + x = LiteralStringNode(rope.flatten()).hash_part() + assert x == rope.hash_part() + x <<= 1 + x ^= ord(rope.getitem(0)) + x ^= rope.length() + assert intmask(x) == h + # hash again to check for cache effects + h1 = hash_rope(rope) + assert h1 == h + +def test_hash_collisions_identifiers(): + hashes1 = {} + hashes2 = {} + cs = [""] + [chr(i) for i in range(256)] + cs = "_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" + for i in range(50000): + s = "".join([random.choice(cs) + for i in range(random.randrange(1, 15))]) + rope = LiteralStringNode(s) + h1 = hash_rope(rope) + hashes1[h1] = hashes1.get(h1, -1) + 1 + h2 = hash(s) + hashes2[h2] = hashes2.get(h2, -1) + 1 + # hope that there are only ten percent more collisions + # than with CPython's hash: + assert sum(hashes1.values()) < sum(hashes2.values()) * 1.10 + +def test_hash_distribution_tiny_strings(): + hashes = [0 for i in range(256)] + cs = [""] + [chr(i) for i in range(256)] + for c1 in cs: + for c2 in cs: + rope = LiteralStringNode(c1 + c2) + h = hash_rope(rope) + hashes[h & 0xff] += 1 + hashes[(h & 0xff00) >> 8] += 1 + hashes[(h & 0xff0000) >> 16] += 1 + for h in hashes: + assert h > 300 + print hashes + +def test_hash_distribution_small_strings(): + random.seed(42) # prevent randomly failing test + hashes = [0 for i in range(256)] + for i in range(20000): + s = "".join([chr(random.randrange(256)) + for i in range(random.randrange(1, 15))]) + rope = LiteralStringNode(s) + h = hash_rope(rope) + hashes[h & 0xff] += 1 + hashes[(h & 0xff00) >> 8] += 1 + hashes[(h & 0xff0000) >> 16] += 1 + for h in hashes: + assert h > 180 + print hashes + +def test_hash_distribution_big_strings(): + random.seed(42) # prevent randomly failing test + hashes = [0 for i in range(256)] + for i in range(4000): + s = "".join([chr(random.randrange(256)) + for i in range(random.randrange(20, 500))]) + rope = LiteralStringNode(s) + h = hash_rope(rope) + hashes[h & 0xff] += 1 + hashes[(h & 0xff00) >> 8] += 1 + hashes[(h & 0xff0000) >> 16] += 1 + for h in hashes: + assert h > 29 + +def test_hash_distribution_identifiers(): + random.seed(42) # prevent randomly failing test + hashes = [0 for i in range(256)] + cs = "_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" + for i in range(50000): + s = "".join([random.choice(cs) + for i in range(random.randrange(1, 15))]) + rope = LiteralStringNode(s) + h = hash_rope(rope) + hashes[h & 0xff] += 1 + hashes[(h & 0xff00) >> 8] += 1 + hashes[(h & 0xff0000) >> 16] += 1 + for h in hashes: + assert h > 450 + print hashes + def test_hash_part(): a = "".join([chr(random.randrange(256)) * random.randrange(500)]) h = None - for split in range(1, 499): + for split in range(1, len(a) - 1): s1 = LiteralStringNode(a[:split]) s2 = LiteralStringNode(a[split:]) s = BinaryConcatNode(s1, s2) @@ -324,6 +408,13 @@ assert s.hash_part() == h assert s.hash_part() == h +def test_hash_part_more(): + for i in range(100): + rope, st = make_random_string() + h = rope.hash_part() + assert LiteralStringNode(st).hash_part() == h + + def test_equality(): l = [make_random_string() for i in range(3)] l.append((LiteralStringNode(""), "")) @@ -341,3 +432,8 @@ c = c // abs(c) assert c == cmp(st1, st2) +def test_power(): + for i in range(0, 60, 13): + print i + for j in range(1, 10000, 7): + assert intmask(i ** j) == masked_power(i, j) Modified: pypy/branch/rope-branch/pypy/objspace/std/test/test_ropeobject.py ============================================================================== --- pypy/branch/rope-branch/pypy/objspace/std/test/test_ropeobject.py (original) +++ pypy/branch/rope-branch/pypy/objspace/std/test/test_ropeobject.py Mon Mar 5 14:57:19 2007 @@ -27,17 +27,6 @@ s += '3' raises(TypeError, ord, s) - def test_hash_cache(self): - # check that we have the same hash as CPython for at least 31 bits - # (but don't go checking CPython's special case -1) - # check twice to catch hash cache problems` - s1 = 'hello' - s2 = 'hello world!' - assert hash(s1) & 0x7fffffff == 0x347697fd - assert hash(s1) & 0x7fffffff == 0x347697fd - assert hash(s2) & 0x7fffffff == 0x2f0bb411 - assert hash(s2) & 0x7fffffff == 0x2f0bb411 - def test_rope_equality(self): # make sure that they are not just literal nodes s1 = 'hello' * 1000 @@ -57,6 +46,10 @@ assert s3 == s3 assert s3 != s4 assert s4 == s4 + + def test_hash(self): + # does not make sense, since our hash is different than CPython's + pass class AppTestRopeUnicode(object): @@ -66,6 +59,10 @@ def test_startswith(self): assert "abc".startswith("a", 0, 2147483647) + def test_hash_equality(self): + d = {u'abcdefg': 2} + assert d['abcdefg'] == 2 + class AppTestUnicodeRopeStdOnly(test_unicodeobject.AppTestUnicodeStringStdOnly): def setup_class(cls): Modified: pypy/branch/rope-branch/pypy/objspace/std/unicodeobject.py ============================================================================== --- pypy/branch/rope-branch/pypy/objspace/std/unicodeobject.py (original) +++ pypy/branch/rope-branch/pypy/objspace/std/unicodeobject.py Mon Mar 5 14:57:19 2007 @@ -194,15 +194,25 @@ def hash__Unicode(space, w_uni): if w_uni.w_hash is None: + # hrmpf chars = w_uni._value if len(chars) == 0: return space.wrap(0) - x = ord(chars[0]) << 7 - for c in chars: - x = intmask((1000003 * x) ^ ord(c)) - h = intmask(x ^ len(chars)) - if h == -1: - h = -2 + if space.config.objspace.std.withrope: + x = 0 + for c in chars: + x = intmask((1000003 * x) + ord(c)) + x <<= 1 + x ^= len(chars) + x ^= ord(chars[0]) + h = intmask(x) + else: + x = ord(chars[0]) << 7 + for c in chars: + x = intmask((1000003 * x) ^ ord(c)) + h = intmask(x ^ len(chars)) + if h == -1: + h = -2 w_uni.w_hash = space.wrap(h) return w_uni.w_hash From cfbolz at codespeak.net Mon Mar 5 15:08:38 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 5 Mar 2007 15:08:38 +0100 (CET) Subject: [pypy-svn] r39957 - pypy/branch/rope-branch/pypy/objspace/std Message-ID: <20070305140838.0E19F1006E@code0.codespeak.net> Author: cfbolz Date: Mon Mar 5 15:08:36 2007 New Revision: 39957 Modified: pypy/branch/rope-branch/pypy/objspace/std/rope.py Log: hopefully fix an annotation problem Modified: pypy/branch/rope-branch/pypy/objspace/std/rope.py ============================================================================== --- pypy/branch/rope-branch/pypy/objspace/std/rope.py (original) +++ pypy/branch/rope-branch/pypy/objspace/std/rope.py Mon Mar 5 15:08:36 2007 @@ -12,6 +12,7 @@ MAX_DEPTH = 32 # maybe should be smaller MIN_SLICE_LENGTH = 64 CONCATENATE_WHEN_MULTIPLYING = 128 +HIGHEST_BIT_SET = intmask(1L << (NBITS - 1)) def find_fib_index(l): if l == 0: @@ -113,7 +114,7 @@ for c in self.s: x = (1000003*x) + ord(c) x = intmask(x) - x |= intmask(1L << (NBITS - 1)) + x |= HIGHEST_BIT_SET h = self.hash_cache = x return h @@ -186,7 +187,7 @@ h1 = self.left.hash_part() h2 = self.right.hash_part() x = intmask(h2 + h1 * (masked_power(1000003, self.right.length()))) - x |= intmask(1L << (NBITS - 1)) + x |= HIGHEST_BIT_SET h = self.hash_cache = x return h @@ -236,7 +237,7 @@ for i in range(self.start, self.stop): x = (1000003*x) + ord(self.node.getitem(i)) x = intmask(x) - x |= intmask(1L << (NBITS - 1)) + x |= HIGHEST_BIT_SET h = self.hash_cache = x return h From afayolle at codespeak.net Mon Mar 5 17:16:15 2007 From: afayolle at codespeak.net (afayolle at codespeak.net) Date: Mon, 5 Mar 2007 17:16:15 +0100 (CET) Subject: [pypy-svn] r39962 - in pypy/dist/pypy/lib: . app_test Message-ID: <20070305161615.E19F11006F@code0.codespeak.net> Author: afayolle Date: Mon Mar 5 17:16:13 2007 New Revision: 39962 Added: pypy/dist/pypy/lib/aop.py (contents, props changed) pypy/dist/pypy/lib/app_test/sample_aop_code.py (contents, props changed) pypy/dist/pypy/lib/app_test/test_aop.py (contents, props changed) Log: AOP in Python: first useful test passing Added: pypy/dist/pypy/lib/aop.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/lib/aop.py Mon Mar 5 17:16:13 2007 @@ -0,0 +1,314 @@ +"""tentative API for AOP in python. + +heavily influenced by Aspect++""" + + +########################### +# API +########################### +import parser + +# advices +# ------- + + +class Debug(parser.ASTVisitor): + def __init__(self): + self.offset = 0 + def default(self, node): + print ' '*self.offset+str(node) + self.offset += 2 + for child in node.getChildNodes(): + child.accept(self) + self.offset -= 2 + return node + +DEBUGGER= Debug() + +class Advice(parser.ASTVisitor): + requires_dynamic_pointcut=True + def __init__(self, pointcut): + if self.requires_dynamic_pointcut != pointcut.isdynamic: + raise TypeError('Expecting a static pointcut') + self.pointcut = pointcut + + def __call__(self, function): + print 'wrapping advice %s on %s' % (self.pointcut, function.__name__) + self.function = function + return self + +## def decorated(self,*args, **kwargs): +## print 'calling aspectized function %s (with %s)' % (self.function.__name__, self.pointcut) +## return self.function(*args, **kwargs) + + def weave(self, ast, enc): + return ast.accept(self) + + def visitFunction(self, node): + if self.pointcut.match(node): + self.weave_at_pointcut(node, + self.pointcut.joinpoint(node)) + return node + + def vistClass(self, node): + if self.pointcut.match(node): + print "found match", node.name + return node + + +def make_aop_call(id): + """return an AST for a call to a woven function + id is the integer returned when the advice was stored in the registry""" + p = parser + return p.ASTDiscard(p.ASTCallFunc(p.ASTName('__aop__'), + [p.ASTConst(id),], # arguments + None, # *args + None # *kwargs + ) + ) + + +def is_aop_call(node): + p = parser + return node.__class__ == p.ASTDiscard and \ + node.expr.__class__ == p.ASTCallFunc and \ + node.expr.node.varname == '__aop__' + +class around(Advice): + """specify code to be run instead of the pointcut""" + def weave_at_pointcut(self, node, tjp): + print "WEAVE around!!!" + pass # XXX WRITEME + +class before(Advice): + """specify code to be run before the pointcut""" + def weave_at_pointcut(self, node, tjp): + print "WEAVE before!!!" + id = __aop__.register_joinpoint(self.function, tjp) + statement_list = node.code.nodes + for idx, stmt in enumerate(statement_list): + if is_aop_call(stmt): + continue + else: + break + statement_list.insert(idx, make_aop_call(id)) + node.code.nodes = statement_list + + + +class after(Advice): + """specify code to be run after the pointcut""" + def weave_at_pointcut(self, node, tjp): + print "WEAVE after!!!" + pass # XXX WRITEME + +class introduce(Advice): + """insert new code in the pointcut + this is the only advice available on static point cuts""" + requires_dynamic_pointcut=False + def weave_at_pointcut(self, node, tjp): + print "WEAVE introduce!!!" + pass # XXX WRITEME + + + +# TODO: add new base classes to a pointcut. Maybe with introduce ? + +# JoinPoint +# -------- + +class JoinPoint: + # API for use within advices + def signature(self): + """return: string representation of the signature of the joint + point""" + return self.signature + + def that(self): + """return: a reference on the object initiating the call, or + None if it is a static method or a global function""" + return self.that + + def target(self): + """return: reference the object that is the target of a call + or None if it is a static method or a global function""" + return self.target + + def result(self): + """return: reference on result value or None""" + return self.result + + def arguments(self): + """return: the (args, kwargs) of the join point""" + return self.arguments + + def proceed(self, *args, **kwargs): + """execute the original code in an around advice""" + self.result = self.func(*args, **kwargs) + + def action(self): + """return: the runtime action object containing the execution + environment to execute XXX""" + pass + + def __init__(self, signature=None, that=None, target=None, result=None, arguments=None, func=None): + self.signature = signature + self.that = that + self.target = target + self.result = result + self.arguments = arguments + self.func = func + + +# PointCut +# -------- + +class PointCut: + """a collection of Join Points.""" + # maybe not managed as a real collection. + + # API for use in declarative code + def __init__(self, pointcut): + """if pointcut is a string: + * matches a substring without . or , + ** matches any substring + pointcut looks like object_name_or_pattern[([argname_or_pattern[, ...]])] + the pointcut is static + else, pointcut must be a pointcut instance""" + if type(pointcut) == str: + self.pointcutdef = pointcut + elif isinstance(pointcut, PointCut): + self.pointcutdef = pointcut.pointcutdef # XXX FIXME + else: + raise TypeError(type(pointcut)) + self.isdynamic = False + + def __and__(self, other): + """return: new pointcut, intersection of the join points in the self and other""" + pass + def __or__(self, other): + """return: new pointcut, union of the join points in the self and other""" + pass + def __not__(self): + """return: new pointcut, exclusion of the join points in self""" + pass + + def call(self): + """return a dynamic pointcut representing places where the pointcut is called""" + # XXX may be difficult to implement ? + self.isdynamic = True + #raise NotImplementedError('call') + return self + + def execution(self): + """return a dynamic pointcut representing places where the pointcut is executed""" + self.isdynamic = True + return self + + def initialization(self): + """return a dynamic pointcut representing places where the pointcut is instantiated""" + self.isdynamic = True + #raise NotImplementedError('initialization') + return self + + def destruction(self): + """return a dynamic pointcut representing places where the pointcut is destroyed""" + self.isdynamic = True + #raise NotImplementedError('destruction') + + return self + + def match(self, astnode): + # FIXME !!! :-) + try: + return astnode.name == self.pointcutdef + except AttributeError: + return False + + def joinpoint(self, node): + """returns a join point instance for the node""" + assert self.match(node) + return JoinPoint() + +### make these class methods of PointCut ? +def within(pointcutstring): + """return point cut filtering joinpoints on lexical scope""" + pass + +def base(pointcutstring): + """return class pointcuts based on the class hierarchy""" + pass +def derived(pointcutstring): + """return class pointcuts based on the class hierarchy""" + pass + +def that(typepattern): + pass +def target(typepattern): + pass +def result(typepattern): + pass +def args(typepattern): + pass + + +class Weaver: + """The weaver is responsible for weaving the Aspects in the code + using the compiler_hook. The woven modules will generally use the + __aop__ builtin instance of this class to run the advices""" + def __init__(self): + self.advices = [] + self.joinpoints = {} + self._id = 1 + parser.install_compiler_hook(self.weave) + + def register_advice(self, aspect, advice): + self.advices.append((aspect, advice)) + + def weave(self, ast, enc): + for aspect, advice in self.advices: + self._curr_aspect = aspect + ast = advice.weave(ast, enc) + self._curr_aspect = None + return ast + + def _next_id(self): + try: + return self._id + finally: + self._id += 1 + + def register_joinpoint(self, callable, *args): + assert self._curr_aspect is not None + id = self._next_id() + args = (self._curr_aspect,) + args + self.joinpoints[id] = callable, args + return id + + def __call__(self, id): + callable, args = self.joinpoints[id] + callable(*args) + +import __builtin__ +__builtin__.__aop__ = Weaver() +del __builtin__ + + + +# Aspect metaclass +# ---------------- + +class Aspect(type): +## def __init__(cls, name, bases, dct): +## super(Aspect, cls).__init__(name, bases, dct) + + def __call__(cls, *args, **kwargs): + instance = super(Aspect, cls).__call__(*args, **kwargs) + for name, advice in cls.__dict__.iteritems(): + if isinstance(advice, Advice): + print "registering advice %s.%s" % (instance.__class__.__name__, name) + __aop__.register_advice(instance, advice) + + return instance + + Added: pypy/dist/pypy/lib/app_test/sample_aop_code.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/lib/app_test/sample_aop_code.py Mon Mar 5 17:16:13 2007 @@ -0,0 +1,8 @@ +def foo(b,c): + a = 2 + d = bar() + return b+a+c+d + + +def bar(): + return 42 Added: pypy/dist/pypy/lib/app_test/test_aop.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/lib/app_test/test_aop.py Mon Mar 5 17:16:13 2007 @@ -0,0 +1,63 @@ +from pypy.conftest import gettestobjspace + +class AppTestAop(object): + def setup_class(cls): + cls.space = gettestobjspace(**{'objspace.usepycfiles':False}) + + def test_init(self): + import aop + + def test_static_dynamic_advice_and_pointcut(self): + from aop import PointCut, introduce, before, around, after + + dyn_pc = PointCut('foo').call() + assert dyn_pc.isdynamic + + stat_pc = PointCut('bar') + assert not stat_pc.isdynamic + + assert not introduce.requires_dynamic_pointcut + raises(TypeError, introduce, dyn_pc) + adv = introduce(stat_pc) + assert adv is not None + + for advice in before, around, after: + assert advice.requires_dynamic_pointcut + raises(TypeError, advice, stat_pc) + adv = advice(dyn_pc) + assert adv is not None + + def test_is_aop(self): + from aop import is_aop_call + import parser + func = """ +def f(): + __aop__(1) + g(12) + __aop__(12) +""" + funcast = parser.source2ast(func).node.nodes[0] + result = [is_aop_call(n) for n in funcast.code.nodes] + assert result == [True, False, True] + + def test_simple_aspect(self): + from aop import PointCut, Aspect, before + + class AspectTest: + __metaclass__ = Aspect + def __init__(self): + self.executed = False + @before(PointCut('foo').execution()) + def advice_before_excecution(self, tjp): + self.executed = True + + assert __aop__.advices == [] + aspect = AspectTest() + assert __aop__.advices == [(aspect, AspectTest.advice_before_excecution)] + assert not aspect.executed + + from app_test import sample_aop_code + assert not aspect.executed + sample_aop_code.foo(1,2) + assert aspect.executed + From hpk at codespeak.net Mon Mar 5 17:29:49 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Mon, 5 Mar 2007 17:29:49 +0100 (CET) Subject: [pypy-svn] r39963 - pypy/extradoc/minute Message-ID: <20070305162949.C833F1006F@code0.codespeak.net> Author: hpk Date: Mon Mar 5 17:29:48 2007 New Revision: 39963 Modified: pypy/extradoc/minute/post-eu-structure.txt Log: added the attendants of the discussion and clarified the disclaimer, small streamlining. Modified: pypy/extradoc/minute/post-eu-structure.txt ============================================================================== --- pypy/extradoc/minute/post-eu-structure.txt (original) +++ pypy/extradoc/minute/post-eu-structure.txt Mon Mar 5 17:29:48 2007 @@ -1,13 +1,18 @@ -=========== -DISCLAIMER: -=========== +post-EU PyPy organisation discussion +---------------------------------------- -These are ideas that were discussed and agreed by the people present on the -sprint, nothing final. +Attendants: +Samuele Pedroni, Anders Chrigstr?m, Christian Tismer, Anders +Sigfridsson, Michael Hudson, Antonio Cuni, Richard Emslie, +Stephan Diel, Alexander Schremmer, Georg Brandl, +Maciej Fijalkowski, Guido Wesdorp, Carl Friedrich Bolz, +Armin Rigo, Holger Krekel, Lene Wagner + +*disclaimer*: Below are keypoint results of the sprint discussion +about the organisation of the open-source PyPy project after +the EU funding period. -post-EU PyPy organisation suggestion ----------------------------------------- - PyPy's future as an open-source project should be shaped by the community and the people contributing and involved with it @@ -70,8 +75,7 @@ ---------------------- - full-time codespeak.net maintenance is going to end 1st April, - Martin (merlinux) may care a bit after that but he will - also be looking for other work opportunities. + Martin (merlinux) may care a bit after that. There will be some (shared?) physical hosting costs and hopefully multiple volunteers helping out with sys maintenance/care. Martin would probably also be happy to continue somewhat professionally @@ -81,5 +85,6 @@ but nevertheless considers future project opportunities. - major focus of march-may will still be EU related goals and deadlines + - next sprint likely not before EuroPython From cfbolz at codespeak.net Mon Mar 5 17:45:50 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 5 Mar 2007 17:45:50 +0100 (CET) Subject: [pypy-svn] r39964 - pypy/branch/rope-branch/pypy/objspace/std Message-ID: <20070305164550.7A97810075@code0.codespeak.net> Author: cfbolz Date: Mon Mar 5 17:45:49 2007 New Revision: 39964 Modified: pypy/branch/rope-branch/pypy/objspace/std/rope.py Log: optimization for rope equality in the very common case Modified: pypy/branch/rope-branch/pypy/objspace/std/rope.py ============================================================================== --- pypy/branch/rope-branch/pypy/objspace/std/rope.py (original) +++ pypy/branch/rope-branch/pypy/objspace/std/rope.py Mon Mar 5 17:45:49 2007 @@ -818,6 +818,9 @@ return False if hash_rope(node1) != hash_rope(node2): return False + if (isinstance(node1, LiteralStringNode) and + isinstance(node2, LiteralStringNode)): + return node1.s == node2.s iter1 = CharIterator(node1) iter2 = CharIterator(node2) # XXX could be cleverer and detect partial equalities From hpk at codespeak.net Mon Mar 5 19:27:47 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Mon, 5 Mar 2007 19:27:47 +0100 (CET) Subject: [pypy-svn] r39969 - pypy/extradoc/olpc Message-ID: <20070305182747.CE38210087@code0.codespeak.net> Author: hpk Date: Mon Mar 5 19:27:46 2007 New Revision: 39969 Added: pypy/extradoc/olpc/ Log: adding an olpc directory for gathering OLPC related information, in preparation for the 15th March olpc-workshop meeting From gbrandl at codespeak.net Mon Mar 5 21:28:51 2007 From: gbrandl at codespeak.net (gbrandl at codespeak.net) Date: Mon, 5 Mar 2007 21:28:51 +0100 (CET) Subject: [pypy-svn] r39970 - in pypy/dist/pypy: doc interpreter Message-ID: <20070305202851.58DFE10071@code0.codespeak.net> Author: gbrandl Date: Mon Mar 5 21:28:49 2007 New Revision: 39970 Modified: pypy/dist/pypy/doc/objspace.txt pypy/dist/pypy/interpreter/baseobjspace.py Log: (xoraxax, gbrandl) Document the new index() and getindex_w() object space methods and rename an argument of the latter one. Modified: pypy/dist/pypy/doc/objspace.txt ============================================================================== --- pypy/dist/pypy/doc/objspace.txt (original) +++ pypy/dist/pypy/doc/objspace.txt Mon Mar 5 21:28:49 2007 @@ -110,6 +110,11 @@ ``call(w_callable, w_args, w_kwds):`` Call a function with the given args and keywords. +``index(w_obj):`` + Implements the index lookup (new in CPython 2.5) on 'w_obj'. Will return a + wrapped integer or long, or raise a TypeError if the object doesn't have an + ``__index__`` special method. + ``is_(w_x, w_y):`` Implements 'w_x is w_y'. (Returns a wrapped result too!) @@ -214,16 +219,28 @@ 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. + 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):`` - If w_x is an application-level integer or long, return an interpreter-level rbigint. Otherwise raise TypeError. + If w_x is an application-level integer or long, return an interpreter-level rbigint. + Otherwise raise TypeError. ``str_w(w_x):`` - If w_x is an application-level string, return an interpreter-level string. Otherwise raise TypeError. + If w_x is an application-level string, return an interpreter-level string. + Otherwise raise TypeError. ``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. + 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. + +``getindex_w(w_obj, w_exception=None):`` + Call `index(w_obj)`. If the resulting integer or long object can be converted + to an interpreter-level int, return that. If not, return a clamped result if + `w_exception` is None, otherwise raise that exception on application-level. + (If w_obj can't be converted to an index, `index()` will raise an + application-level TypeError.) ``interp_w(RequiredClass, w_x, can_be_None=False):`` If w_x is a wrapped instance of the given bytecode interpreter class, Modified: pypy/dist/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/dist/pypy/interpreter/baseobjspace.py (original) +++ pypy/dist/pypy/interpreter/baseobjspace.py Mon Mar 5 21:28:49 2007 @@ -785,14 +785,14 @@ step = 0 return start, stop, step - def getindex_w(self, w_obj, exception=None): + def getindex_w(self, w_obj, w_exception=None): w_index = self.index(w_obj) try: index = self.int_w(w_index) except OperationError, err: if not err.match(self, self.w_OverflowError): raise - if not exception: + if not w_exception: # w_index is a long object if w_index.get_sign() < 0: return -sys.maxint-1 @@ -800,7 +800,7 @@ return sys.maxint else: raise OperationError( - exception, self.wrap( + w_exception, self.wrap( "cannot fit '%s' into an index-sized " "integer" % self.type(w_obj).getname(self, '?'))) else: From gbrandl at codespeak.net Tue Mar 6 00:21:16 2007 From: gbrandl at codespeak.net (gbrandl at codespeak.net) Date: Tue, 6 Mar 2007 00:21:16 +0100 (CET) Subject: [pypy-svn] r39971 - in pypy/dist/pypy: interpreter objspace/std objspace/std/test Message-ID: <20070305232116.D82A010063@code0.codespeak.net> Author: gbrandl Date: Tue Mar 6 00:21:14 2007 New Revision: 39971 Modified: pypy/dist/pypy/interpreter/baseobjspace.py pypy/dist/pypy/objspace/std/listmultiobject.py pypy/dist/pypy/objspace/std/listobject.py pypy/dist/pypy/objspace/std/objspace.py pypy/dist/pypy/objspace/std/slicetype.py pypy/dist/pypy/objspace/std/stringobject.py pypy/dist/pypy/objspace/std/strsliceobject.py pypy/dist/pypy/objspace/std/test/test_index.py Log: Some string/list methods use __index__ for their "slice" arguments too. Also, make _Eval_SliceIndex act more like its CPython counterpart. Modified: pypy/dist/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/dist/pypy/interpreter/baseobjspace.py (original) +++ pypy/dist/pypy/interpreter/baseobjspace.py Tue Mar 6 00:21:14 2007 @@ -786,6 +786,10 @@ return start, stop, step def getindex_w(self, w_obj, w_exception=None): + # shortcut for int objects + if self.is_w(self.type(w_obj), self.w_int): + return self.int_w(w_obj) + w_index = self.index(w_obj) try: index = self.int_w(w_index) Modified: pypy/dist/pypy/objspace/std/listmultiobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/listmultiobject.py (original) +++ pypy/dist/pypy/objspace/std/listmultiobject.py Tue Mar 6 00:21:14 2007 @@ -1218,10 +1218,8 @@ 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) + i = slicetype.adapt_bound(space, length, w_start) + stop = slicetype.adapt_bound(space, length, 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) Modified: pypy/dist/pypy/objspace/std/listobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/listobject.py (original) +++ pypy/dist/pypy/objspace/std/listobject.py Tue Mar 6 00:21:14 2007 @@ -390,10 +390,8 @@ # needs to be safe against eq_w() mutating the w_list behind our back items = w_list.wrappeditems size = len(items) - w_start = slicetype.adapt_bound(space, w_start, space.wrap(size)) - w_stop = slicetype.adapt_bound(space, w_stop, space.wrap(size)) - i = space.int_w(w_start) - stop = space.int_w(w_stop) + i = slicetype.adapt_bound(space, size, w_start) + stop = slicetype.adapt_bound(space, size, w_stop) while i < stop and i < len(items): if space.eq_w(items[i], w_any): return space.wrap(i) Modified: pypy/dist/pypy/objspace/std/objspace.py ============================================================================== --- pypy/dist/pypy/objspace/std/objspace.py (original) +++ pypy/dist/pypy/objspace/std/objspace.py Tue Mar 6 00:21:14 2007 @@ -624,13 +624,17 @@ """Only for backward compatibility for __getslice__()&co methods.""" if space.is_w(w_start, space.w_None): w_start = space.wrap(0) - elif space.is_true(space.lt(w_start, space.wrap(0))): - w_start = space.add(w_start, space.len(w_obj)) - # NB. the language ref is inconsistent with the new-style class - # behavior when w_obj doesn't implement __len__(), so we just - # ignore this case. + else: + w_start = space.wrap(space.getindex_w(w_start)) + if space.is_true(space.lt(w_start, space.wrap(0))): + w_start = space.add(w_start, space.len(w_obj)) + # NB. the language ref is inconsistent with the new-style class + # behavior when w_obj doesn't implement __len__(), so we just + # ignore this case. if space.is_w(w_stop, space.w_None): w_stop = space.wrap(slice_max) - elif space.is_true(space.lt(w_stop, space.wrap(0))): - w_stop = space.add(w_stop, space.len(w_obj)) + else: + w_stop = space.wrap(space.getindex_w(w_stop)) + if space.is_true(space.lt(w_stop, space.wrap(0))): + w_stop = space.add(w_stop, space.len(w_obj)) return w_start, w_stop Modified: pypy/dist/pypy/objspace/std/slicetype.py ============================================================================== --- pypy/dist/pypy/objspace/std/slicetype.py (original) +++ pypy/dist/pypy/objspace/std/slicetype.py Tue Mar 6 00:21:14 2007 @@ -15,32 +15,24 @@ # utility functions def _Eval_SliceIndex(space, w_int): - return space.getindex_w(w_int) # clamp if long integer is too large - # This is done by getindex_w already. - #try: - # x = space.getindex_w(w_int) - #except OperationError, e: - # if not e.match(space, space.w_OverflowError): - # raise - # cmp = space.is_true(space.ge(w_int, space.wrap(0))) - # if cmp: - # x = sys.maxint - # else: - # x = -sys.maxint - #return x - -def adapt_bound(space, w_index, w_size): - if not (space.is_true(space.isinstance(w_index, space.w_int)) or - space.is_true(space.isinstance(w_index, space.w_long))): + try: + return space.getindex_w(w_int) # clamp if long integer is too large + except OperationError, err: + if not err.match(space, space.w_TypeError): + raise raise OperationError(space.w_TypeError, - space.wrap("slice indices must be integers")) - if space.is_true(space.lt(w_index, space.wrap(0))): - w_index = space.add(w_index, w_size) - if space.is_true(space.lt(w_index, space.wrap(0))): - w_index = space.wrap(0) - if space.is_true(space.gt(w_index, w_size)): - w_index = w_size - return w_index + space.wrap("slice indices must be integers or " + "None or have an __index__ method")) + +def adapt_bound(space, size, w_index): + index = _Eval_SliceIndex(space, w_index) + if index < 0: + index = index + size + if index < 0: + index = 0 + if index > size: + index = size + return index register_all(vars(), globals()) Modified: pypy/dist/pypy/objspace/std/stringobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/stringobject.py (original) +++ pypy/dist/pypy/objspace/std/stringobject.py Tue Mar 6 00:21:14 2007 @@ -377,11 +377,9 @@ def _convert_idx_params(space, w_self, w_sub, w_start, w_end): self = w_self._value sub = w_sub._value - w_start = slicetype.adapt_bound(space, w_start, space.wrap(len(self))) - w_end = slicetype.adapt_bound(space, w_end, space.wrap(len(self))) + start = slicetype.adapt_bound(space, len(self), w_start) + end = slicetype.adapt_bound(space, len(self), w_end) - start = space.int_w(w_start) - end = space.int_w(w_end) assert start >= 0 assert end >= 0 @@ -562,15 +560,8 @@ return wrapstr(space, u_centered) def str_count__String_String_ANY_ANY(space, w_self, w_arg, w_start, w_end): - u_self = w_self._value - u_arg = w_arg._value - - w_start = slicetype.adapt_bound(space, w_start, space.wrap(len(u_self))) - w_end = slicetype.adapt_bound(space, w_end, space.wrap(len(u_self))) - u_start = space.int_w(w_start) - u_end = space.int_w(w_end) - assert u_start >= 0 - assert u_end >= 0 + u_self, u_arg, u_start, u_end = _convert_idx_params(space, w_self, w_arg, + w_start, w_end) return wrapint(space, u_self.count(u_arg, u_start, u_end)) def str_endswith__String_String_ANY_ANY(space, w_self, w_suffix, w_start, w_end): Modified: pypy/dist/pypy/objspace/std/strsliceobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/strsliceobject.py (original) +++ pypy/dist/pypy/objspace/std/strsliceobject.py Tue Mar 6 00:21:14 2007 @@ -55,11 +55,9 @@ def _convert_idx_params(space, w_self, w_sub, w_start, w_end): length = w_self.stop - w_self.start sub = w_sub._value - w_start = slicetype.adapt_bound(space, w_start, space.wrap(length)) - w_end = slicetype.adapt_bound(space, w_end, space.wrap(length)) + start = slicetype.adapt_bound(space, length, w_start) + end = slicetype.adapt_bound(space, length, w_end) - start = space.int_w(w_start) - end = space.int_w(w_end) assert start >= 0 assert end >= 0 @@ -67,7 +65,7 @@ def str_find__StringSlice_String_ANY_ANY(space, w_self, w_sub, w_start, w_end): - (self, sub, start, end) = _convert_idx_params(space, w_self, w_sub, w_start, w_end) + (self, sub, start, end) = _convert_idx_params(space, w_self, w_sub, w_start, w_end) res = self.find(sub, start, end) if res >= 0: return space.wrap(res - w_self.start) Modified: pypy/dist/pypy/objspace/std/test/test_index.py ============================================================================== --- pypy/dist/pypy/objspace/std/test/test_index.py (original) +++ pypy/dist/pypy/objspace/std/test/test_index.py Tue Mar 6 00:21:14 2007 @@ -51,6 +51,13 @@ check_slc = slice(2, 2, 2) assert slc.indices(self.n) == check_slc.indices(2) + def test_in_methods(self): + self.o.ind = 5 + self.n.ind = 10 + s = "abcdefghijklmno" + assert s.find("a", self.o, self.n) == -1 + assert s.find("f", self.o, self.n) == 5 + def test_wrappers(self): self.o.ind = 4 self.n.ind = 5 From fijal at codespeak.net Tue Mar 6 10:51:56 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 6 Mar 2007 10:51:56 +0100 (CET) Subject: [pypy-svn] r39976 - in pypy/dist/pypy/translator/js/examples: console console/data console/test test Message-ID: <20070306095156.2E66010074@code0.codespeak.net> Author: fijal Date: Tue Mar 6 10:51:54 2007 New Revision: 39976 Modified: pypy/dist/pypy/translator/js/examples/console/console.py pypy/dist/pypy/translator/js/examples/console/data/console.html pypy/dist/pypy/translator/js/examples/console/session.py pypy/dist/pypy/translator/js/examples/console/test/test_console.py pypy/dist/pypy/translator/js/examples/console/test/test_session.py pypy/dist/pypy/translator/js/examples/test/test_examples.py Log: Move interface to use pylib's net stack instead of pypeers 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 Tue Mar 6 10:51:54 2007 @@ -10,7 +10,7 @@ from pypy.translator.js.lib.support import callback from pypy.translator.js import commproxy from pypy.translator.js.examples.console.session import Interpreter -from pypeers.httpserver import GreenHTTPServer +from py.__.net.server.httpserver import GreenHTTPServer commproxy.USE_MOCHIKIT = True Modified: pypy/dist/pypy/translator/js/examples/console/data/console.html ============================================================================== --- pypy/dist/pypy/translator/js/examples/console/data/console.html (original) +++ pypy/dist/pypy/translator/js/examples/console/data/console.html Tue Mar 6 10:51:54 2007 @@ -20,5 +20,8 @@ >>>

+
+ Random help here +
- \ No newline at end of file + Modified: pypy/dist/pypy/translator/js/examples/console/session.py ============================================================================== --- pypy/dist/pypy/translator/js/examples/console/session.py (original) +++ pypy/dist/pypy/translator/js/examples/console/session.py Tue Mar 6 10:51:54 2007 @@ -13,9 +13,9 @@ import py import subprocess from Queue import Queue -from pypeers.greensock2 import autogreenlet, Timer, wait, meetingpoint,\ +from py.__.net.greensock2 import autogreenlet, Timer, wait, meetingpoint,\ Interrupted -from pypeers.pipe.fd import FDInput +from py.__.net.pipe.fd import FDInput class Interpreter(object): def __init__(self, python, timeout=TIMEOUT): Modified: pypy/dist/pypy/translator/js/examples/console/test/test_console.py ============================================================================== --- pypy/dist/pypy/translator/js/examples/console/test/test_console.py (original) +++ pypy/dist/pypy/translator/js/examples/console/test/test_console.py Tue Mar 6 10:51:54 2007 @@ -1,11 +1,6 @@ def test_line_skip(): - try: - from pypy.translator.js.examples.console.console import line_split - except ImportError: - import py - py.test.skip("cannot import greensock") - + from pypy.translator.js.examples.console.console import line_split assert line_split("asdf", 80) == "asdf" assert line_split("a b c d", 3) == "a b\n c d" assert line_split("a b c d e f g h i j", 3) == "a b\n c \nd e\n f \ng h\n i j" Modified: pypy/dist/pypy/translator/js/examples/console/test/test_session.py ============================================================================== --- pypy/dist/pypy/translator/js/examples/console/test/test_session.py (original) +++ pypy/dist/pypy/translator/js/examples/console/test/test_session.py Tue Mar 6 10:51:54 2007 @@ -4,11 +4,8 @@ import py -try: - from pypeers.greensock2 import autogreenlet, wait, sleep, ConnexionClosed - from pypeers.pipe.fd import FDInput -except ImportError: - py.test.skip("greensock wasn't found") +from py.__.net.greensock2 import autogreenlet, wait, sleep, ConnexionClosed +from py.__.net.pipe.fd import FDInput from pypy.translator.js.examples.console.session import Interpreter def test_greensock_reader_timeouter(): @@ -34,6 +31,7 @@ g_f = autogreenlet(f) g_g = autogreenlet(g) - wait() + wait(g_g) + wait(g_f) assert len(l) == 2 assert l[1].startswith(">>") 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 Tue Mar 6 10:51:54 2007 @@ -16,12 +16,7 @@ assert rpython2javascript(start_bnb, ['bnb'], use_pdb=False) def test_overmind_build(): - try: - from pypy.translator.js.examples import overmind, over_client - except ImportError: - import py - py.test.skip("greensock wasn't found") - + from pypy.translator.js.examples import overmind, over_client assert rpython2javascript(over_client, overmind.FUNCTION_LIST, use_pdb=False) @@ -32,11 +27,6 @@ def test_console_2_build(): - try: - from pypy.translator.js.examples.console import console, client - except ImportError: - import py - py.test.skip("greensock wasn't found") - + from pypy.translator.js.examples.console import console, client assert rpython2javascript(client, console.FUNCTION_LIST, use_pdb=False) From fijal at codespeak.net Tue Mar 6 10:52:29 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 6 Mar 2007 10:52:29 +0100 (CET) Subject: [pypy-svn] r39977 - pypy/dist/pypy/lib/distributed Message-ID: <20070306095229.A8BE010078@code0.codespeak.net> Author: fijal Date: Tue Mar 6 10:52:27 2007 New Revision: 39977 Modified: pypy/dist/pypy/lib/distributed/objkeeper.py Log: remove debug prints Modified: pypy/dist/pypy/lib/distributed/objkeeper.py ============================================================================== --- pypy/dist/pypy/lib/distributed/objkeeper.py (original) +++ pypy/dist/pypy/lib/distributed/objkeeper.py Tue Mar 6 10:52:27 2007 @@ -43,7 +43,7 @@ try: return self.exported_types[tp] except KeyError: - print "Registering type %s as %s" % (tp, self.exported_types_id) + #print "Registering type %s as %s" % (tp, self.exported_types_id) self.exported_types[tp] = self.exported_types_id self.exported_types_reverse[self.exported_types_id] = tp tp_id = self.exported_types_id @@ -58,7 +58,7 @@ return tp_id def fake_remote_type(self, protocol, type_id, _name, _dict): - print "Faking type %s as %s" % (_name, type_id) + #print "Faking type %s as %s" % (_name, type_id) # create and register new type d = dict([(key, None) for key in _dict]) # some stuff needs to go first... From fijal at codespeak.net Tue Mar 6 10:53:02 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 6 Mar 2007 10:53:02 +0100 (CET) Subject: [pypy-svn] r39978 - pypy/dist/pypy/lib/distributed Message-ID: <20070306095302.CBEEE10076@code0.codespeak.net> Author: fijal Date: Tue Mar 6 10:52:59 2007 New Revision: 39978 Modified: pypy/dist/pypy/lib/distributed/socklayer.py Log: Move interface to standard socket - works as well Modified: pypy/dist/pypy/lib/distributed/socklayer.py ============================================================================== --- pypy/dist/pypy/lib/distributed/socklayer.py (original) +++ pypy/dist/pypy/lib/distributed/socklayer.py Tue Mar 6 10:52:59 2007 @@ -1,6 +1,7 @@ -from pypeers.pipe.gsocket import GreenSocket -from pypeers.msgstruct import decodemessage, message +#from pypeers.pipe.gsocket import GreenSocket +from socket import socket +from py.__.net.msgstruct import decodemessage, message from socket import socket, AF_INET, SOCK_STREAM import marshal import sys @@ -30,7 +31,7 @@ trace("done") def socket_listener(address=('', 12122)): - s = GreenSocket(AF_INET, SOCK_STREAM) + s = socket(AF_INET, SOCK_STREAM) s.bind(address) s.listen(1) print "Waiting for connection" @@ -40,7 +41,7 @@ return sw.send, sw.receive def socket_connecter(address): - s = GreenSocket(AF_INET, SOCK_STREAM) + s = socket(AF_INET, SOCK_STREAM) print "Connecting %s" % (address,) s.connect(address) From fijal at codespeak.net Tue Mar 6 12:34:12 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 6 Mar 2007 12:34:12 +0100 (CET) Subject: [pypy-svn] r39980 - pypy/dist/pypy/doc Message-ID: <20070306113412.7432A10078@code0.codespeak.net> Author: fijal Date: Tue Mar 6 12:34:11 2007 New Revision: 39980 Modified: pypy/dist/pypy/doc/objspace-proxies.txt Log: Improve transparent proxy documentation a bit Modified: pypy/dist/pypy/doc/objspace-proxies.txt ============================================================================== --- pypy/dist/pypy/doc/objspace-proxies.txt (original) +++ pypy/dist/pypy/doc/objspace-proxies.txt Tue Mar 6 12:34:11 2007 @@ -457,59 +457,73 @@ 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. - -To enable them, use the :config:`objspace.std.withtproxy` option. +Transparent proxies are implementation of types which sends every performed +operation on an object to a provided callable. From an application level +it looks like an instance of arbitrary type, but all operations are directly +calling a provided callable with an apropriate arguments. + +Suppose we have a need of having a list instance which added to anything +will provide 42. Than we create transparent proxy for int:: + + $ py.py --with-transparent-proxy + >>>> from pypymagic import transparent_proxy + >>>> def f(operation, *args, **kwargs): + >>>> if operation == '__add__': + >>>> return 42 + >>>> raise AttributeError + >>>> + >>>> i = transparent_proxy(list, f) + +And now:: + + >>> type(i) + list + >>> i + 3 + 42 .. _`alternative object implementations`: object-optimizations.html -Example: ---------- +More sophisticated example: +--------------------------- Suppose we want to have list which stores all operations performed on 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 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. - -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 the history of operations on the list in ``c.history``. -Example:: - - >>>> lst - [] - >>>> type(lst) - + >>>> 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) + +Now we can perform:: + >>>> lst.append(3) - >>>> lst + >>>> len(lst) + 1 + >>>> l [3] - >>>> lst[-1] - 3 >>>> c.history - ['__repr__', '__getattribute__', '__repr__', '__getitem__'] + [__getattribute__, __len__] + >>>> type(lst) is type(l) + True + +So what happened: + +* We've create transparent proxy of type list with controller c.perform + +* When performing lst.append, it calls lst.__getattribute__ which returns + bound method append of l (so append did not show up) + +* we call len + +* we call type, which does not show up at all (indeed the type is the only + aspect of the instance that the controller cannot change). 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 From fijal at codespeak.net Tue Mar 6 14:57:54 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 6 Mar 2007 14:57:54 +0100 (CET) Subject: [pypy-svn] r39984 - pypy/dist/pypy/lib/distributed/demo Message-ID: <20070306135754.0756910079@code0.codespeak.net> Author: fijal Date: Tue Mar 6 14:57:53 2007 New Revision: 39984 Added: pypy/dist/pypy/lib/distributed/demo/sockdemo.py - copied unchanged from r39978, pypy/dist/pypy/lib/distributed/demo/gsock.py Removed: pypy/dist/pypy/lib/distributed/demo/gsock.py Log: Rename demo (it does not use greensock any more) From fijal at codespeak.net Tue Mar 6 15:03:44 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 6 Mar 2007 15:03:44 +0100 (CET) Subject: [pypy-svn] r39986 - in pypy/dist/pypy/translator/js/examples/console: . test Message-ID: <20070306140344.A50651007E@code0.codespeak.net> Author: fijal Date: Tue Mar 6 15:03:43 2007 New Revision: 39986 Modified: pypy/dist/pypy/translator/js/examples/console/session.py pypy/dist/pypy/translator/js/examples/console/test/test_session.py Log: (fijal, arigo) - New strange py.__.net interface for those. Less code :) Modified: pypy/dist/pypy/translator/js/examples/console/session.py ============================================================================== --- pypy/dist/pypy/translator/js/examples/console/session.py (original) +++ pypy/dist/pypy/translator/js/examples/console/session.py Tue Mar 6 15:03:43 2007 @@ -13,8 +13,7 @@ import py import subprocess from Queue import Queue -from py.__.net.greensock2 import autogreenlet, Timer, wait, meetingpoint,\ - Interrupted +from py.__.net.greensock2 import autogreenlet, Timer, Interrupted from py.__.net.pipe.fd import FDInput class Interpreter(object): @@ -23,7 +22,7 @@ stdin=subprocess.PIPE, stderr=subprocess.STDOUT, close_fds=True, bufsize=0) self.pipe = pipe - self.read_fd = FDInput(self.pipe.stdout.fileno()) + self.read_fd = FDInput(self.pipe.stdout.fileno(), close=False) self.pid = pipe.pid self.timeout = timeout Modified: pypy/dist/pypy/translator/js/examples/console/test/test_session.py ============================================================================== --- pypy/dist/pypy/translator/js/examples/console/test/test_session.py (original) +++ pypy/dist/pypy/translator/js/examples/console/test/test_session.py Tue Mar 6 15:03:43 2007 @@ -4,7 +4,7 @@ import py -from py.__.net.greensock2 import autogreenlet, wait, sleep, ConnexionClosed +from py.__.net.greensock2 import allof from py.__.net.pipe.fd import FDInput from pypy.translator.js.examples.console.session import Interpreter @@ -22,16 +22,12 @@ pass while not i2.interact().endswith(">>> "): pass - l = [] def f(): - l.append(i.interact("import time;time.sleep(1)\n")) + return i.interact("import time;time.sleep(1)\n") def g(): - l.append(i2.interact("a\n")) + return i2.interact("a\n") - g_f = autogreenlet(f) - g_g = autogreenlet(g) - wait(g_g) - wait(g_f) - assert len(l) == 2 - assert l[1].startswith(">>") + one, two = allof(g, f) + assert two.startswith(">>") + assert one.startswith("Traceback") From arigo at codespeak.net Tue Mar 6 16:46:47 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 6 Mar 2007 16:46:47 +0100 (CET) Subject: [pypy-svn] r39987 - pypy/dist/pypy/module/_file Message-ID: <20070306154647.C659610071@code0.codespeak.net> Author: arigo Date: Tue Mar 6 16:46:46 2007 New Revision: 39987 Modified: pypy/dist/pypy/module/_file/app_file.py Log: Fix the last "XXX slow" of app_file. 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 Mar 6 16:46:46 2007 @@ -115,14 +115,23 @@ if size < 0: return self.stream.readline() else: - # XXX slow - chars = [] - for i in xrange(size): - char = self.stream.read(1) - chars.append(char) - if char == '' or char == '\n': + # very inefficient unless there is a peek() + result = [] + while size > 0: + # "peeks" on the underlying stream to see how many characters + # we can safely read without reading past an end-of-line + peeked = self.stream.peek() + pn = peeked.find("\n", 0, size) + if pn < 0: + pn = min(size-1, len(peeked)) + c = self.stream.read(pn + 1) + if not c: + break + result.append(c) + if c.endswith('\n'): break - return ''.join(chars) + size -= len(c) + return ''.join(result) def readlines(self, size=-1): """readlines([size]) -> list of strings, each a line from the file. From fijal at codespeak.net Tue Mar 6 16:52:12 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 6 Mar 2007 16:52:12 +0100 (CET) Subject: [pypy-svn] r39988 - pypy/dist/pypy/doc Message-ID: <20070306155212.CA0041007A@code0.codespeak.net> Author: fijal Date: Tue Mar 6 16:52:11 2007 New Revision: 39988 Added: pypy/dist/pypy/doc/distribution.txt Log: Some kind of draft how lib/distributed is implemented Added: pypy/dist/pypy/doc/distribution.txt ============================================================================== --- (empty file) +++ pypy/dist/pypy/doc/distribution.txt Tue Mar 6 16:52:11 2007 @@ -0,0 +1,66 @@ + +======================== +lib/distributed features +======================== + +Stuff & things. mostly + +Distributed library is an attempt to build a transparent, lazy +access to remote objects. This is accomplished using +the `transparent proxy`_ approach and build on application +level (pure python module). + +The main idea is to provide kind-of-RPC protocol, which +accesses only necessary parts of objects (not whole objects) +and also not to rely on objects being picklable nor having +the same source code on both sides. + +In order to provide this, only necessary parts of remote objects +are retrieved for every call, keeping remote references to objects +which are not needed yet. + +Imagine remote object, which is locally available under name `x`. +Let's call:: + + >>>> x.foo(1, [1,2,3], y) + +Where y is some instance of local, user-created class. So, what +is really called, is a call to x.__getattribute__ with argument ('foo') +which is copied, so remote side replies with a bound method. Locally +this bound method appears as a remote reference which is again called +with a remote reference to x as self, 1 (which is copied as a primitive type), +reference to a list and refence to y. Remote side receives call to bound +method x.foo, with x being resolved as local object, 1 as a immutable +primitive, [1,2,3] as a reference to mutable primitive and y as a reference +to remote object. If type of y is not known on remote side, the type of +y is faked, given enough shape to be able to perform operations. The contents +of a list are not retrieved as long as thei're not needed. + +This approach transfers minimal data over network, but tends to send +tones of small packages to remote side. This might be improved at some +point in future. Also this approach allows to have remote references to +internal interpreter types, like frames, code objects and tracebacks. In +a demo directory there is an example of using this to attach pdb.post\_mortem() +to a remote traceback. + +Distributed lib is build with an abstract network layer, which means you +can provide it any possible communication channel which can +send/receive marshallable objects (no pickle needed!) via +two functions - send and receive. + +Exact rules of copying +---------------------- + +- Immutable primitives are always transfered + +- Mutable primitives are transfered as reference, but several operations + (like iter()) force them to appear + +- Builtin exceptions are transfered by name + +- User objects are always faked on the other side, with enough shape + transfered + +XXX finish, basic interface, example, build some stuff on top of greenlets + +.. _`transparent proxy`: objspace-proxies.html#tproxy From santagada at codespeak.net Tue Mar 6 16:56:41 2007 From: santagada at codespeak.net (santagada at codespeak.net) Date: Tue, 6 Mar 2007 16:56:41 +0100 (CET) Subject: [pypy-svn] r39989 - pypy/dist/pypy/lang/js Message-ID: <20070306155641.0F2271007A@code0.codespeak.net> Author: santagada Date: Tue Mar 6 16:56:41 2007 New Revision: 39989 Modified: pypy/dist/pypy/lang/js/jsparser.py pypy/dist/pypy/lang/js/operations.py Log: some rpython fixes Modified: pypy/dist/pypy/lang/js/jsparser.py ============================================================================== --- pypy/dist/pypy/lang/js/jsparser.py (original) +++ pypy/dist/pypy/lang/js/jsparser.py Tue Mar 6 16:56:41 2007 @@ -5,10 +5,11 @@ # TODO Should be replaced by a real parser import os -import py +import os.path as path import re from pypy.rlib.parsing.ebnfparse import parse_ebnf, make_parse_function from pypy.rlib.parsing.ebnfparse import Symbol +from pypy.rlib.streamio import open_file_as_stream DEBUG = False @@ -35,12 +36,18 @@ print code_string print "------ put:" print stripped_code - jsdir = py.path.local(__file__).dirpath().join("js") - jsdefs = jsdir.join("jsdefs.js").read() - jsparse = jsdir.join("jsparse.js").read() - f = py.test.ensuretemp("jsinterp").join("tobeparsed.js") + jsdir = path.join(path.dirname(__file__),"js") + f_jsdefs = open_file_as_stream(path.join(jsdir, "jsdefs.js")) + jsdefs = f_jsdefs.readall() + f_jsdefs.close() + f_jsparse = open_file_as_stream(path.join(jsdir, "jsparse.js")) + jsparse = f_jsparse.readall() + f_jsparse.close() + fname = path.join(path.dirname(__file__) ,"tobeparsed.js") + f = open_file_as_stream(fname, 'w') f.write(jsdefs+jsparse+"print(parse('%s'));\n" % stripped_code) - pipe = os.popen("js -f "+str(f), 'r') + f.close() + pipe = os.popen("js -f "+fname, 'r') retval = pipe.read() if not retval.startswith("{"): raise JsSyntaxError(retval) Modified: pypy/dist/pypy/lang/js/operations.py ============================================================================== --- pypy/dist/pypy/lang/js/operations.py (original) +++ pypy/dist/pypy/lang/js/operations.py Tue Mar 6 16:56:41 2007 @@ -42,7 +42,7 @@ self.end = 0 self.from_tree(t) - def from_tree(t): + def from_tree(self, t): """ Initializes the content from the AST specific for each node type """ @@ -444,7 +444,7 @@ else: return W_Boolean(s5) -def AEC(x, y): +def AEC(ctx, x, y): """ Implements the Abstract Equality Comparison x == y trying to be fully to the spec @@ -474,19 +474,19 @@ (type1 == "null" and type2 == "undefined"): return True if type1 == "number" and type2 == "string": - return AEC(x, W_Number(y.ToNumber())) + return AEC(ctx, x, W_Number(y.ToNumber())) if type1 == "string" and type2 == "number": - return AEC(W_Number(x.ToNumber()), y) + return AEC(ctx, W_Number(x.ToNumber()), y) if type1 == "boolean": - return AEC(W_Number(x.ToNumber()), y) + return AEC(ctx, W_Number(x.ToNumber()), y) if type2 == "boolean": - return AEC(x, W_Number(y.ToNumber())) + return AEC(ctx, x, W_Number(y.ToNumber())) if (type1 == "string" or type1 == "number") and \ type2 == "object": - return AEC(x, y.ToPrimitive()) + return AEC(ctx, x, y.ToPrimitive(ctx)) if (type2 == "string" or type2 == "number") and \ type1 == "object": - return AEC(x.ToPrimitive(), y) + return AEC(ctx, x.ToPrimitive(ctx), y) return False @@ -505,13 +505,13 @@ opcode = 'EQ' def decision(self, ctx, op1, op2): - return W_Boolean(AEC(op1, op2)) + return W_Boolean(AEC(ctx, op1, op2)) class Ne(BinaryComparisonOp): opcode = 'NE' def decision(self, ctx, op1, op2): - return W_Boolean(not AEC(op1, op2)) + return W_Boolean(not AEC(ctx, op1, op2)) def SEC(x,y): """ @@ -773,7 +773,7 @@ if isinstance(e, ExecutionReturned) and e.type == 'return': return e.value else: - print "exeception in line: %s, on: %s"%(node.lineno, node.value) + print "exception in line: %s, on: %s"%(node.lineno, node.value) raise class Semicolon(Statement): From mwh at codespeak.net Tue Mar 6 18:11:35 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Tue, 6 Mar 2007 18:11:35 +0100 (CET) Subject: [pypy-svn] r39990 - pypy/extradoc/sprintinfo/trillke-2007 Message-ID: <20070306171135.0EF3E1005A@code0.codespeak.net> Author: mwh Date: Tue Mar 6 18:11:33 2007 New Revision: 39990 Modified: pypy/extradoc/sprintinfo/trillke-2007/sprint-report.txt Log: most of the rest of a sprint report. Modified: pypy/extradoc/sprintinfo/trillke-2007/sprint-report.txt ============================================================================== --- pypy/extradoc/sprintinfo/trillke-2007/sprint-report.txt (original) +++ pypy/extradoc/sprintinfo/trillke-2007/sprint-report.txt Tue Mar 6 18:11:33 2007 @@ -2,8 +2,6 @@ 25th sprint, 18th and final EU funded -tutorial - As has become ususal, the sprint began with a tutorial for those participants who are less familiar with PyPy code base. This time Carl Friedrich was talking to Georg Brandl, an interested CPython @@ -66,6 +64,29 @@ Holger and Antonio came up with yet another optimization idea along these lines, which can be found in doc/discussion/chained_getattr.txt. +Going back to the first day, Anto and Samuele worked on analyzing why +pypy-cli was being reported as 50+ times slower than CPython on the +benchmark page: + + http://tuatara.cs.uni-duesseldorf.de/benchmark.html + +To do this they wrote some small benchmarks in RPython and stared at +some code, but the main problem seems to be that Mono on PowerPC just +isn't that good: running pypy-cli using Microsoft's runtime shows +performance just 5 time slower than CPython. + +After this, they worked on streamlining PyPy's much complained about +external function interface (and also broke translation a few times in +the process). The last sprint saw the introduction of a more general +registry-based interface for external functions, and Samuele and Anto +began by moving the math module over to using this interface. This +was harder than what had gone before because these functions depend on +header files, so some modifications to the C and LLVM backends were +necessary. + +On the last day, Anto made some small improvements to pypy-cli's +performance and Samuele made the taint object space translatable. + Georg and Alexander implemented some of Python 2.5's features in the interpeter, in particular support for __index__ and some extensions to string and dict methods. @@ -93,21 +114,54 @@ Later Stephan joined Armin and Christian in a discussion about the best API to provide for the new "composable coroutine" concept. They -feel that the concept is powerful to encompass threads, greenlets, coroutines XXX - -view/pivot/world/composable discussion (/user/stephan) +feel that the concept is powerful to encompass threads, greenlets, +coroutines, threads, syslets and the best way to barbecue ribs. You +can read about the basic idea in the "Composability" section of PyPy's +stackless documentation: + + http://codespeak.net/pypy/dist/pypy/doc/stackless.html + +and further insight is unlikely to be provided by this diagram: + + http://python.net/crew/mwh/stackless.jpg + +The basic conclusion was that this is a very nice and natural model +for a lot of things, at least once you've whacked your head into the +right shape. + +A task that occupied various people at various times of the sprint was +that of benchmarking, the goal being to determine how much effect the +object and other optimizations have. Michael had over the previous +month or so some written some scaffolding code to allow various +benchmarks to be run and the results recorded. At the sprint he added +a benchmark using docutils to process 'translation.txt' from pypy's +own documentation and Guido added another using his own 'templess' +templating system. + +Holger worked on getting some code written for bzr that makes nice +graphs out of benchmark to parse the benchmark data produced by PyPy's +benchmark runs. + +Maciej worked on the lib/distributed code that demonstrates the PyPy's +transparent proxies. After a bit of effort, he was able to write a +demo that implemented a remote version of pdb by simply by creating a +traceback object that proxied all operations to a remote process. + +Michael and Richard spent a day or so on the LLVM backend, which of +late hasn't been so much "maintained" as "held together by +increasingly large amounts of sticky tape". After some refactoring of +the way the backend handled options, they removed a layer of hacks +around the issue of FixedSizedArrays and implemented them properly, +and also added support for the direct_* pointer operations produced by +rctypes. -benchmarking & graphing -lib/distributed demo -pypy-cli speed/rpython microbenches -genllvm butchery -external functions/translation breaking session -small cli improvements -taint translation gil-less hacking -os x specific genc hacks -post-funding +Michael spent some time using Shark, an OS X profiling application, +and found some OS specific flags and tweaks that improved the +performance of pypy-c on OS X/PPC by around 20%. + +post-funding Cordiali Saluti, mwh & Carl Friedrich From afayolle at codespeak.net Tue Mar 6 18:18:52 2007 From: afayolle at codespeak.net (afayolle at codespeak.net) Date: Tue, 6 Mar 2007 18:18:52 +0100 (CET) Subject: [pypy-svn] r39991 - pypy/dist/pypy/interpreter/astcompiler Message-ID: <20070306171852.C82D710069@code0.codespeak.net> Author: afayolle Date: Tue Mar 6 18:18:46 2007 New Revision: 39991 Modified: pypy/dist/pypy/interpreter/astcompiler/ast.py pypy/dist/pypy/interpreter/astcompiler/ast.txt pypy/dist/pypy/interpreter/astcompiler/astgen.py Log: (adim, ludal, cfbolz, alf) - fix ast.txt and astgen.py : * removed some duplicated code * properly initialize Function objects from app level code - regenerate ast.py Modified: pypy/dist/pypy/interpreter/astcompiler/ast.py ============================================================================== --- pypy/dist/pypy/interpreter/astcompiler/ast.py (original) +++ pypy/dist/pypy/interpreter/astcompiler/ast.py Tue Mar 6 18:18:46 2007 @@ -1709,7 +1709,6 @@ - Compare.typedef = TypeDef('Compare', Node.typedef, __new__ = interp2app(descr_Compare_new, unwrap_spec=[ObjSpace, W_Root, W_Root, W_Root, int]), accept=interp2app(descr_Compare_accept, unwrap_spec=[ObjSpace, W_Root, W_Root] ), @@ -2653,7 +2652,7 @@ def fset_code( space, self, w_arg): self.code = space.interp_w(Node, w_arg, can_be_None=False) -def descr_Function_new(space, w_subtype, w_decorators, w_name, w_argnames, w_defaults, w_flags, w_w_doc, w_code, lineno=-1): +def descr_Function_new(space, w_subtype, w_decorators, w_name, w_argnames, w_defaults, w_flags, w_doc, w_code, lineno=-1): self = space.allocate_instance(Function, w_subtype) decorators = space.interp_w(Node, w_decorators, can_be_None=True) self.decorators = decorators @@ -2664,15 +2663,22 @@ defaults = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_defaults)] self.defaults = defaults flags = space.int_w(w_flags) - self.flags = flags - # This dummy assingment is auto-generated, astgen.py should be fixed to avoid that - w_doc = w_w_doc + self.flags = flags self.w_doc = w_doc code = space.interp_w(Node, w_code, can_be_None=False) self.code = code self.lineno = lineno + + self.varargs = 0 + self.kwargs = 0 + if flags & CO_VARARGS: + self.varargs = 1 + if flags & CO_VARKEYWORDS: + self.kwargs = 1 return space.wrap(self) + + def descr_Function_accept( space, w_self, w_visitor): return space.call_method(w_visitor, 'visitFunction', w_self) Modified: pypy/dist/pypy/interpreter/astcompiler/ast.txt ============================================================================== --- pypy/dist/pypy/interpreter/astcompiler/ast.txt (original) +++ pypy/dist/pypy/interpreter/astcompiler/ast.txt Tue Mar 6 18:18:46 2007 @@ -289,6 +289,31 @@ self.lineno = lineno return space.wrap(self) +def descr_Function_new(space, w_subtype, w_decorators, w_name, w_argnames, w_defaults, w_flags, w_doc, w_code, lineno=-1): + self = space.allocate_instance(Function, w_subtype) + decorators = space.interp_w(Node, w_decorators, can_be_None=True) + self.decorators = decorators + name = space.str_w(w_name) + self.name = name + argnames = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_argnames)] + self.argnames = argnames + defaults = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_defaults)] + self.defaults = defaults + flags = space.int_w(w_flags) + self.flags = flags + self.w_doc = w_doc + code = space.interp_w(Node, w_code, can_be_None=False) + self.code = code + self.lineno = lineno + + self.varargs = 0 + self.kwargs = 0 + if flags & CO_VARARGS: + self.varargs = 1 + if flags & CO_VARKEYWORDS: + self.kwargs = 1 + return space.wrap(self) + def descr_Import_new(space, w_subtype, w_names, lineno=-1): self = space.allocate_instance(Import, w_subtype) names = [] @@ -336,32 +361,6 @@ space.setattr(w_self, space.wrap("ops"), w_newlist) 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 Tue Mar 6 18:18:46 2007 @@ -297,27 +297,6 @@ print >> buf, " def accept(self, visitor):" print >> buf, " return visitor.visit%s(self)" % self.name - 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_insertnodes_func(self, buf): print >> buf, " def descr_insert_after(space, self, node, w_added_nodes):" From auc at codespeak.net Tue Mar 6 19:33:50 2007 From: auc at codespeak.net (auc at codespeak.net) Date: Tue, 6 Mar 2007 19:33:50 +0100 (CET) Subject: [pypy-svn] r39997 - pypy/dist/pypy/module/cclp/constraint/test Message-ID: <20070306183350.99CC110063@code0.codespeak.net> Author: auc Date: Tue Mar 6 19:33:48 2007 New Revision: 39997 Removed: pypy/dist/pypy/module/cclp/constraint/test/ Log: silence these obsolete tests From antocuni at codespeak.net Tue Mar 6 20:07:38 2007 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Tue, 6 Mar 2007 20:07:38 +0100 (CET) Subject: [pypy-svn] r39998 - pypy/extradoc/sprintinfo/trillke-2007 Message-ID: <20070306190738.3080A10069@code0.codespeak.net> Author: antocuni Date: Tue Mar 6 20:07:35 2007 New Revision: 39998 Modified: pypy/extradoc/sprintinfo/trillke-2007/sprint-report.txt Log: unfortunately pypy-cli is not so fast :-( Modified: pypy/extradoc/sprintinfo/trillke-2007/sprint-report.txt ============================================================================== --- pypy/extradoc/sprintinfo/trillke-2007/sprint-report.txt (original) +++ pypy/extradoc/sprintinfo/trillke-2007/sprint-report.txt Tue Mar 6 20:07:35 2007 @@ -73,7 +73,7 @@ To do this they wrote some small benchmarks in RPython and stared at some code, but the main problem seems to be that Mono on PowerPC just isn't that good: running pypy-cli using Microsoft's runtime shows -performance just 5 time slower than CPython. +performance just 3-4 time slower than pypy-c. After this, they worked on streamlining PyPy's much complained about external function interface (and also broke translation a few times in From afayolle at codespeak.net Tue Mar 6 20:48:55 2007 From: afayolle at codespeak.net (afayolle at codespeak.net) Date: Tue, 6 Mar 2007 20:48:55 +0100 (CET) Subject: [pypy-svn] r39999 - in pypy/dist/pypy/lib: . app_test Message-ID: <20070306194855.BBFF310069@code0.codespeak.net> Author: afayolle Date: Tue Mar 6 20:48:54 2007 New Revision: 39999 Modified: pypy/dist/pypy/lib/aop.py pypy/dist/pypy/lib/app_test/sample_aop_code.py pypy/dist/pypy/lib/app_test/test_aop.py Log: before and after advices supported on execution pointcuts Modified: pypy/dist/pypy/lib/aop.py ============================================================================== --- pypy/dist/pypy/lib/aop.py (original) +++ pypy/dist/pypy/lib/aop.py Tue Mar 6 20:48:54 2007 @@ -17,12 +17,25 @@ self.offset = 0 def default(self, node): print ' '*self.offset+str(node) - self.offset += 2 + self.offset += 4 for child in node.getChildNodes(): child.accept(self) - self.offset -= 2 + self.offset -= 4 return node + def visitFunction(self, func): + print " "*self.offset+'def %s:' % (func.name) + self.offset += 4 + for node in func.code.nodes: + node.accept(self) + self.offset -= 4 + def visitReturn(self, ret): + print ' '*self.offset+'return ', + for child in ret.getChildNodes(): + child.accept(self) + + + DEBUGGER= Debug() class Advice(parser.ASTVisitor): @@ -46,8 +59,8 @@ def visitFunction(self, node): if self.pointcut.match(node): - self.weave_at_pointcut(node, - self.pointcut.joinpoint(node)) + node = self.weave_at_pointcut(node, + self.pointcut.joinpoint(node)) return node def vistClass(self, node): @@ -56,17 +69,23 @@ return node -def make_aop_call(id): +def make_aop_call(id, targetname=None, discard=True): """return an AST for a call to a woven function id is the integer returned when the advice was stored in the registry""" p = parser - return p.ASTDiscard(p.ASTCallFunc(p.ASTName('__aop__'), - [p.ASTConst(id),], # arguments + arguments = [p.ASTConst(id),] + if targetname is not None: + arguments.append(p.ASTName(targetname)) + if discard: + returnclass = p.ASTDiscard + else: + returnclass = p.ASTReturn + return returnclass(p.ASTCallFunc(p.ASTName('__aop__'), + arguments, None, # *args None # *kwargs ) ) - def is_aop_call(node): p = parser @@ -78,21 +97,39 @@ """specify code to be run instead of the pointcut""" def weave_at_pointcut(self, node, tjp): print "WEAVE around!!!" - pass # XXX WRITEME - + p = parser + print 'original func:' + node.accept(DEBUGGER) + print '+++', self.function + id = __aop__.register_joinpoint(self.function, tjp) + statement = node.code + newname = '__aoptarget_%s_%s__' % (node.name, id) + newcode = p.ASTStmt([p.ASTFunction(node.decorators, + newname, + node.argnames, + node.defaults, + node.flags, + node.w_doc, + node.code, + node.lineno), + make_aop_call(id, targetname=newname, discard=False), + ]) + + node.decorators = None + node.code = newcode + print 'weaving produced:' + node.accept(DEBUGGER) + return node + class before(Advice): """specify code to be run before the pointcut""" def weave_at_pointcut(self, node, tjp): print "WEAVE before!!!" id = __aop__.register_joinpoint(self.function, tjp) statement_list = node.code.nodes - for idx, stmt in enumerate(statement_list): - if is_aop_call(stmt): - continue - else: - break - statement_list.insert(idx, make_aop_call(id)) + statement_list.insert(0, make_aop_call(id)) node.code.nodes = statement_list + return node @@ -100,7 +137,11 @@ """specify code to be run after the pointcut""" def weave_at_pointcut(self, node, tjp): print "WEAVE after!!!" - pass # XXX WRITEME + id = __aop__.register_joinpoint(self.function, tjp) + statement = node.code + tryfinally = parser.ASTTryFinally(statement, make_aop_call(id)) + node.code = tryfinally + return node class introduce(Advice): """insert new code in the pointcut @@ -109,6 +150,7 @@ def weave_at_pointcut(self, node, tjp): print "WEAVE introduce!!!" pass # XXX WRITEME + return node @@ -197,38 +239,46 @@ """return a dynamic pointcut representing places where the pointcut is called""" # XXX may be difficult to implement ? self.isdynamic = True + self.mode = 'call' #raise NotImplementedError('call') return self def execution(self): """return a dynamic pointcut representing places where the pointcut is executed""" self.isdynamic = True + self.mode = 'execution' return self def initialization(self): """return a dynamic pointcut representing places where the pointcut is instantiated""" self.isdynamic = True + self.mode = 'initializartion' #raise NotImplementedError('initialization') return self def destruction(self): """return a dynamic pointcut representing places where the pointcut is destroyed""" self.isdynamic = True + self.mode = 'destruction' #raise NotImplementedError('destruction') return self def match(self, astnode): # FIXME !!! :-) - try: - return astnode.name == self.pointcutdef - except AttributeError: - return False + if self.mode == 'execution': + try: + return astnode.name == self.pointcutdef + except AttributeError: + return False def joinpoint(self, node): """returns a join point instance for the node""" assert self.match(node) - return JoinPoint() + if self.mode == 'execution': +## stnode = parser.STType(node) +## target = getattr(stnode.compile(), node.name) + return JoinPoint() ### make these class methods of PointCut ? def within(pointcutstring): @@ -272,6 +322,10 @@ self._curr_aspect = None return ast + def _clear_all(self): + self.advices = [] + self.joinpoints = {} + def _next_id(self): try: return self._id @@ -281,12 +335,15 @@ def register_joinpoint(self, callable, *args): assert self._curr_aspect is not None id = self._next_id() + print "register joinpoint with id %d" % id args = (self._curr_aspect,) + args self.joinpoints[id] = callable, args return id - def __call__(self, id): + def __call__(self, id, target=None): callable, args = self.joinpoints[id] + print args + args[-1].target = target callable(*args) import __builtin__ Modified: pypy/dist/pypy/lib/app_test/sample_aop_code.py ============================================================================== --- pypy/dist/pypy/lib/app_test/sample_aop_code.py (original) +++ pypy/dist/pypy/lib/app_test/sample_aop_code.py Tue Mar 6 20:48:54 2007 @@ -1,8 +1,33 @@ +code = """ def foo(b,c): + print 'foo' a = 2 d = bar() return b+a+c+d def bar(): + print 'bar' return 42 + +def baz(b,c): + try: + return foo(b,c) + finally: + bar() +""" +import os +import os.path as osp + +def _make_filename(name): + if not name.endswith('.py'): + name += ".py" + return osp.join(osp.dirname(__file__), name) + +def write_module(name): + f = open(_make_filename(name), 'w') + f.write(code) + f.close() + +def clean_module(name): + os.unlink(_make_filename(name)) Modified: pypy/dist/pypy/lib/app_test/test_aop.py ============================================================================== --- pypy/dist/pypy/lib/app_test/test_aop.py (original) +++ pypy/dist/pypy/lib/app_test/test_aop.py Tue Mar 6 20:48:54 2007 @@ -1,13 +1,14 @@ from pypy.conftest import gettestobjspace + class AppTestAop(object): def setup_class(cls): cls.space = gettestobjspace(**{'objspace.usepycfiles':False}) - def test_init(self): + def _test_init(self): import aop - def test_static_dynamic_advice_and_pointcut(self): + def _test_static_dynamic_advice_and_pointcut(self): from aop import PointCut, introduce, before, around, after dyn_pc = PointCut('foo').call() @@ -27,7 +28,7 @@ adv = advice(dyn_pc) assert adv is not None - def test_is_aop(self): + def _test_is_aop(self): from aop import is_aop_call import parser func = """ @@ -40,24 +41,80 @@ result = [is_aop_call(n) for n in funcast.code.nodes] assert result == [True, False, True] - def test_simple_aspect(self): + def _test_simple_aspect_before_execution(self): from aop import PointCut, Aspect, before + from app_test import sample_aop_code + __aop__._clear_all() + sample_aop_code.write_module('aop_before_execution') class AspectTest: __metaclass__ = Aspect def __init__(self): self.executed = False @before(PointCut('foo').execution()) - def advice_before_excecution(self, tjp): + def advice_before_execution(self, tjp): self.executed = True assert __aop__.advices == [] aspect = AspectTest() - assert __aop__.advices == [(aspect, AspectTest.advice_before_excecution)] + assert __aop__.advices == [(aspect, AspectTest.advice_before_execution)] assert not aspect.executed + from app_test import aop_before_execution + assert aspect.executed == 0 + aop_before_execution.foo(1,2) + assert aspect.executed == 1 + sample_aop_code.clean_module('aop_before_execution') + + def _test_simple_aspect_after_execution(self): + from aop import PointCut, Aspect, after from app_test import sample_aop_code + __aop__._clear_all() + sample_aop_code.write_module('aop_after_execution') + class AspectTest: + __metaclass__ = Aspect + def __init__(self): + self.executed = 0 + @after(PointCut('foo').execution()) + def advice_after_execution(self, tjp): + self.executed += 1 + + assert __aop__.advices == [] + aspect = AspectTest() + assert __aop__.advices == [(aspect, AspectTest.advice_after_execution)] assert not aspect.executed - sample_aop_code.foo(1,2) - assert aspect.executed + from app_test import aop_after_execution + assert aspect.executed == 0 + aop_after_execution.foo(1,2) + assert aspect.executed == 1 + sample_aop_code.clean_module('aop_after_execution') + def test_simple_aspect_around_execution(self): + from aop import PointCut, Aspect, around + from app_test import sample_aop_code + __aop__._clear_all() + sample_aop_code.write_module('aop_around_execution') + class AspectTest: + __metaclass__ = Aspect + def __init__(self): + self.executed_before = 0 + self.executed_after = 0 + @around(PointCut('foo').execution()) + def advice_around_execution(self, tjp): + print '>>>in' + self.executed_before += 1 + tjp.proceed() + self.executed_after += 1 + self.result = tjp.result() + print '<< Author: santagada Date: Wed Mar 7 00:05:10 2007 New Revision: 40004 Modified: pypy/dist/pypy/lang/js/jsparser.py Log: rpython modifications Modified: pypy/dist/pypy/lang/js/jsparser.py ============================================================================== --- pypy/dist/pypy/lang/js/jsparser.py (original) +++ pypy/dist/pypy/lang/js/jsparser.py Wed Mar 7 00:05:10 2007 @@ -47,8 +47,20 @@ f = open_file_as_stream(fname, 'w') f.write(jsdefs+jsparse+"print(parse('%s'));\n" % stripped_code) f.close() - pipe = os.popen("js -f "+fname, 'r') - retval = pipe.read() + c2pread, c2pwrite = os.pipe() + if os.fork() == 0: + #child + os.dup2(c2pwrite, 1) + for i in range(3, 256): + try: + os.close(i) + except OSError: + pass + cmd = ['/bin/sh', '-c', 'js -f '+fname] + os.execvp(cmd[0], cmd) + os.close(c2pwrite) + retval = os.read(c2pread, -1) + os.close(c2pread) if not retval.startswith("{"): raise JsSyntaxError(retval) if DEBUG: From cfbolz at codespeak.net Wed Mar 7 00:08:33 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 7 Mar 2007 00:08:33 +0100 (CET) Subject: [pypy-svn] r40005 - in pypy/branch/rope-branch/pypy/objspace/std: . test Message-ID: <20070306230833.600E010068@code0.codespeak.net> Author: cfbolz Date: Wed Mar 7 00:08:29 2007 New Revision: 40005 Modified: pypy/branch/rope-branch/pypy/objspace/std/rope.py pypy/branch/rope-branch/pypy/objspace/std/test/test_rope.py Log: - improve finding of single characters - fix a bug in seekable iterator - prepare a wrapper around binary concat nodes that makes getitem access efficient if the consecutive indexes are somewhat close to each other Modified: pypy/branch/rope-branch/pypy/objspace/std/rope.py ============================================================================== --- pypy/branch/rope-branch/pypy/objspace/std/rope.py (original) +++ pypy/branch/rope-branch/pypy/objspace/std/rope.py Wed Mar 7 00:08:29 2007 @@ -75,7 +75,7 @@ if isinstance(index, slice): start, stop, step = index.indices(self.length()) # XXX sucks - slicelength = len(range(start, stop, step)) + slicelength = len(xrange(start, stop, step)) return getslice(self, start, stop, step, slicelength) return self.getitem(index) @@ -251,6 +251,49 @@ for line in self.node.dot(seen): yield line +class EfficientGetitemWraper(StringNode): + def __init__(self, node): + assert isinstance(node, BinaryConcatNode) + self.node = node + self.iter = SeekableCharIterator(node) + self.nextpos = 0 + self.accesses = 0 + self.seeks = 0 + + def length(self): + return self.node.length() + + def depth(self): + return self.node.depth() + + def rebalance(self): + return EfficientGetitemWraper(self.node.rebalance()) + + def hash_part(self): + return self.node.hash_part() + + def flatten(self): + return self.node.flatten() + + def getitem(self, index): + self.accesses += 1 + nextpos = self.nextpos + self.nextpos = index + 1 + if index < nextpos: + self.iter.seekback(nextpos - index) + self.seeks += nextpos - index + elif index > nextpos: + self.iter.seekforward(index - nextpos) + self.seeks += index - nextpos + return self.iter.next() + + def view(self): + return self.node.view() + + def check_balanced(self): + return self.node.check_balanced() + + def concatenate(node1, node2): if node1.length() == 0: return node2 @@ -487,19 +530,32 @@ elif isinstance(node, SliceNode): return find_char(node.node, c, node.start + start, node.start + stop) - node.start + offset - iter = CharIterator(node) + iter = FringeIterator(node) + #import pdb; pdb.set_trace() i = 0 while i < stop: try: - c2 = iter.next() - if i < start: - i += 1 - continue - if c == c2: - return i + offset - i += 1 + fringenode = iter.next() except StopIteration: return -1 + nodelength = fringenode.length() + if i + nodelength <= start: + i += nodelength + continue + searchstart = max(0, start - i) + searchstop = min(stop - i, nodelength) + if isinstance(fringenode, LiteralStringNode): + st = fringenode.s + elif isinstance(fringenode, SliceNode): + n = fringenode.node + assert isinstance(n, LiteralStringNode) + st = n.s + searchstart += fringenode.start + searchstop += fringenode.stop + pos = fringenode.s.find(c, searchstart, searchstop) + if pos != -1: + return pos + i + offset + i += nodelength return -1 def find(node, subnode, start=0, stop=-1): @@ -507,7 +563,7 @@ len1 = node.length() if stop > len1 or stop == -1: stop = len1 - substring = subnode.flatten() # stressful to do it as a node + substring = subnode.flatten() # XXX stressful to do it as a node len2 = len(substring) if len2 == 1: return find_char(node, substring[0], start, stop) @@ -653,6 +709,7 @@ return result class SeekableFringeIterator(object): + # XXX allow to seek in bigger character steps def __init__(self, node): self.stack = [node] self.fringestack = [] @@ -750,6 +807,9 @@ def seekback(self, numchars): if numchars <= self.index: self.index -= numchars + if self.node is None: + self.iter.seekback() + self.node = self.iter.next() return numchars -= self.index self.iter.seekback() # for first item @@ -768,7 +828,7 @@ def __init__(self, node, sub, start=0, stop=-1): self.node = node len1 = self.length = node.length() - substring = self.substring = sub.flatten() # for now + substring = self.substring = sub.flatten() # XXX for now len2 = len(substring) self.search_length = len2 if len2 == 0: Modified: pypy/branch/rope-branch/pypy/objspace/std/test/test_rope.py ============================================================================== --- pypy/branch/rope-branch/pypy/objspace/std/test/test_rope.py (original) +++ pypy/branch/rope-branch/pypy/objspace/std/test/test_rope.py Wed Mar 7 00:08:29 2007 @@ -437,3 +437,25 @@ print i for j in range(1, 10000, 7): assert intmask(i ** j) == masked_power(i, j) + +def test_EfficientGetitemWraper(): + node1, _ = make_random_string(slicing=False) + node2 = EfficientGetitemWraper(node1) + for i in range(node2.length()): + assert node1.getitem(i) == node2.getitem(i) + for j in range(1000): + i = random.randrange(node1.length()) + assert node1.getitem(i) == node2.getitem(i) + +def test_seekable_bug(): + node = BinaryConcatNode(LiteralStringNode("abc"), LiteralStringNode("def")) + iter = SeekableCharIterator(node) + c = iter.next(); assert c == "a" + c = iter.next(); assert c == "b" + c = iter.next(); assert c == "c" + iter.seekback(1) + c = iter.next(); assert c == "c" + c = iter.next(); assert c == "d" + c = iter.next(); assert c == "e" + c = iter.next(); assert c == "f" + py.test.raises(StopIteration, iter.next) From santagada at codespeak.net Wed Mar 7 01:01:40 2007 From: santagada at codespeak.net (santagada at codespeak.net) Date: Wed, 7 Mar 2007 01:01:40 +0100 (CET) Subject: [pypy-svn] r40006 - in pypy/dist/pypy/lang/js: . test Message-ID: <20070307000140.9745510063@code0.codespeak.net> Author: santagada Date: Wed Mar 7 01:01:36 2007 New Revision: 40006 Modified: pypy/dist/pypy/lang/js/interpreter.py pypy/dist/pypy/lang/js/jsparser.py pypy/dist/pypy/lang/js/operations.py pypy/dist/pypy/lang/js/test/test_interp.py Log: more rpython corrections, and a new test Modified: pypy/dist/pypy/lang/js/interpreter.py ============================================================================== --- pypy/dist/pypy/lang/js/interpreter.py (original) +++ pypy/dist/pypy/lang/js/interpreter.py Wed Mar 7 01:01:36 2007 @@ -22,10 +22,11 @@ return load_source(code.ToString()).execute(ctx) def functionjs(ctx, args, this): - if len(args) >= 1: - fbody = args[-1].GetValue().ToString() + tam = len(args) + if tam >= 1: + fbody = args[tam-1].GetValue().ToString() argslist = [] - for i in range(len(args)-1): + for i in range(tam-1): argslist.append(args[i].GetValue().ToString()) fargs = ','.join(argslist) functioncode = "__anon__ = function (%s) {%s}"%(fargs, fbody) Modified: pypy/dist/pypy/lang/js/jsparser.py ============================================================================== --- pypy/dist/pypy/lang/js/jsparser.py (original) +++ pypy/dist/pypy/lang/js/jsparser.py Wed Mar 7 01:01:36 2007 @@ -9,7 +9,7 @@ import re from pypy.rlib.parsing.ebnfparse import parse_ebnf, make_parse_function from pypy.rlib.parsing.ebnfparse import Symbol -from pypy.rlib.streamio import open_file_as_stream +from pypy.rlib.streamio import open_file_as_stream, fdopen_as_stream DEBUG = False @@ -57,10 +57,11 @@ except OSError: pass cmd = ['/bin/sh', '-c', 'js -f '+fname] - os.execvp(cmd[0], cmd) + os.execv(cmd[0], cmd) os.close(c2pwrite) - retval = os.read(c2pread, -1) - os.close(c2pread) + f = fdopen_as_stream(c2pread, 'r', 0) + retval = f.readall() + f.close() if not retval.startswith("{"): raise JsSyntaxError(retval) if DEBUG: @@ -71,7 +72,10 @@ def unquote(t): if isinstance(t, Symbol): if t.symbol == "QUOTED_STRING": - t.additional_info = t.additional_info[1:-1].replace("\\'", "'").replace("\\\\", "\\") + stop = len(t.additional_info)-1 + if stop < 0: + stop = 0 + t.additional_info = t.additional_info[1:].replace("\\'", "'").replace("\\\\", "\\") else: for i in t.children: unquote(i) Modified: pypy/dist/pypy/lang/js/operations.py ============================================================================== --- pypy/dist/pypy/lang/js/operations.py (original) +++ pypy/dist/pypy/lang/js/operations.py Wed Mar 7 01:01:36 2007 @@ -14,7 +14,7 @@ is used to match the AST operation to the efective execution node. """ opcode = None - def __init__(self, t=None, type='', value='', lineno=0, start=0, end=0): + def __init__(self, t=None, type_='', value='', lineno=0, start=0, end=0): """ Not to be overriden by subclasses, this method thakes the basic node information from the AST needed for tracing and debuging. if you want @@ -22,7 +22,7 @@ call. """ if t is None: - self.type = type + self.type = type_ self.value = value self.lineno = lineno self.start = start @@ -152,11 +152,11 @@ elif op == "%": val = Mod().mathop(ctx, v1.GetValue(), v3) elif op == "&": - val = BitwiseAnd().mathop(ctx, v1.GetValue(), v3) + val = BitwiseAnd().decision(ctx, v1.GetValue().ToInt32(), v3.ToInt32()) elif op == "|": - val = BitwiseOR().mathop(ctx, v1.GetValue(), v3) + val = BitwiseOR().decision(ctx, v1.GetValue().ToInt32(), v3.ToInt32()) elif op == "^": - val = BitwiseXOR().mathop(ctx, v1.GetValue(), v3) + val = BitwiseXOR().decision(ctx, v1.GetValue().ToInt32(), v3.ToInt32()) else: print op raise NotImplementedError() @@ -709,8 +709,8 @@ opcode = 'MOD' def mathop(self, ctx, nleft, nright): - fleft = nleft.ToNumber() - fright = nright.ToNumber() + fleft = nleft.ToInt32() + fright = nright.ToInt32() return W_Number(fleft % fright) @@ -718,8 +718,8 @@ opcode = 'DIV' def mathop(self, ctx, nleft, nright): - fleft = nleft.ToNumber() - fright = nright.ToNumber() + fleft = nleft.ToInt32() + fright = nright.ToInt32() return W_Number(fleft / fright) class Minus(BinaryNumberOp): 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 Wed Mar 7 01:01:36 2007 @@ -496,3 +496,10 @@ } print(x) """, ['4', '2', '3', '4']) + + def test_bitops(self): + self.assert_prints(""" + print(2 ^ 2) + print(2 & 3) + print(2 | 3) + """, ['0', '2', '3']) From santagada at codespeak.net Wed Mar 7 03:16:47 2007 From: santagada at codespeak.net (santagada at codespeak.net) Date: Wed, 7 Mar 2007 03:16:47 +0100 (CET) Subject: [pypy-svn] r40007 - pypy/dist/pypy/lang/js Message-ID: <20070307021647.0D0D610068@code0.codespeak.net> Author: santagada Date: Wed Mar 7 03:16:46 2007 New Revision: 40007 Modified: pypy/dist/pypy/lang/js/jsobj.py pypy/dist/pypy/lang/js/jsparser.py pypy/dist/pypy/lang/js/operations.py Log: fully rpython, some bugs corrected and started doing a little documentation Modified: pypy/dist/pypy/lang/js/jsobj.py ============================================================================== --- pypy/dist/pypy/lang/js/jsobj.py (original) +++ pypy/dist/pypy/lang/js/jsobj.py Wed Mar 7 03:16:46 2007 @@ -1,5 +1,5 @@ # encoding: utf-8 -from pypy.rlib.rarithmetic import r_uint +from pypy.rlib.rarithmetic import r_uint, intmask DEBUG = False @@ -75,7 +75,8 @@ raise NotImplementedError def PutValue(self, w, ctx): - print self, w.ToString(), w.__class__, ctx + if DEBUG: + print self, w.ToString(), w.__class__, ctx raise NotImplementedError def Call(self, ctx, args=[], this=None): @@ -321,7 +322,7 @@ return W_PrimitiveObject.Get(self, P) def ToString(self): - return ','.join(self.array) + return ','.join([item.ToString() for item in self.array]) def array_str_builtin(ctx, args, this): return W_String(this.ToString()) Modified: pypy/dist/pypy/lang/js/jsparser.py ============================================================================== --- pypy/dist/pypy/lang/js/jsparser.py (original) +++ pypy/dist/pypy/lang/js/jsparser.py Wed Mar 7 03:16:46 2007 @@ -17,6 +17,11 @@ pass SLASH = "\\" +jsdir = path.join(path.dirname(__file__),"js") +jsdefspath = path.join(jsdir, "jsdefs.js") +jsparsepath = path.join(jsdir, "jsparse.js") +fname = path.join(path.dirname(__file__) ,"tobeparsed.js") + def read_js_output(code_string): tmp = [] last = "" @@ -36,14 +41,12 @@ print code_string print "------ put:" print stripped_code - jsdir = path.join(path.dirname(__file__),"js") - f_jsdefs = open_file_as_stream(path.join(jsdir, "jsdefs.js")) + f_jsdefs = open_file_as_stream(jsdefspath) jsdefs = f_jsdefs.readall() f_jsdefs.close() - f_jsparse = open_file_as_stream(path.join(jsdir, "jsparse.js")) + f_jsparse = open_file_as_stream(jsparsepath) jsparse = f_jsparse.readall() f_jsparse.close() - fname = path.join(path.dirname(__file__) ,"tobeparsed.js") f = open_file_as_stream(fname, 'w') f.write(jsdefs+jsparse+"print(parse('%s'));\n" % stripped_code) f.close() @@ -75,7 +78,17 @@ stop = len(t.additional_info)-1 if stop < 0: stop = 0 - t.additional_info = t.additional_info[1:].replace("\\'", "'").replace("\\\\", "\\") + t.additional_info = t.additional_info[1:stop] + temp = [] + last = "" + for char in t.additional_info: + if last == SLASH: + if char == SLASH: + temp.append(SLASH) + if char != SLASH: + temp.append(char) + last = char + t.additional_info = ''.join(temp) else: for i in t.children: unquote(i) Modified: pypy/dist/pypy/lang/js/operations.py ============================================================================== --- pypy/dist/pypy/lang/js/operations.py (original) +++ pypy/dist/pypy/lang/js/operations.py Wed Mar 7 03:16:46 2007 @@ -6,7 +6,7 @@ from pypy.lang.js.jsobj import * from pypy.rlib.parsing.ebnfparse import Symbol, Nonterminal - +from pypy.rlib.rarithmetic import r_uint, intmask class Node(object): """ @@ -336,6 +336,12 @@ def eval(self, ctx): return self.expr.eval(ctx) +############################################################################## +# +# Binary logic comparison ops and suporting abstract operation +# +############################################################################## + def ARC(ctx, x, y): """ Implements the Abstract Relational Comparison x < y @@ -376,30 +382,6 @@ s4 = self.right.eval(ctx).GetValue() return s4 -class Ursh(BinaryComparisonOp): - opcode = 'URSH' - - def decision(self, ctx, op1, op2): - a = op1.ToUInt32() - b = op2.ToUInt32() - return W_Number(a >> (b & 0x1F)) - -class Rsh(BinaryComparisonOp): - opcode = 'RSH' - - def decision(self, ctx, op1, op2): - a = op1.ToInt32() - b = op2.ToUInt32() - return W_Number(a >> int(b & 0x1F)) - -class Lsh(BinaryComparisonOp): - opcode = 'LSH' - - def decision(self, ctx, op1, op2): - a = op1.ToInt32() - b = op2.ToUInt32() - return W_Number(a << int(b & 0x1F)) - class Ge(BinaryComparisonOp): opcode = 'GE' @@ -444,6 +426,44 @@ else: return W_Boolean(s5) + +############################################################################## +# +# Bitwise shifts +# +############################################################################## + +class Ursh(BinaryComparisonOp): + opcode = 'URSH' + + def decision(self, ctx, op1, op2): + a = op1.ToUInt32() + b = op2.ToUInt32() + return W_Number(a >> (b & 0x1F)) + +class Rsh(BinaryComparisonOp): + opcode = 'RSH' + + def decision(self, ctx, op1, op2): + a = op1.ToInt32() + b = op2.ToUInt32() + return W_Number(a >> intmask(b & 0x1F)) + +class Lsh(BinaryComparisonOp): + opcode = 'LSH' + + def decision(self, ctx, op1, op2): + a = op1.ToInt32() + b = op2.ToUInt32() + return W_Number(a << intmask(b & 0x1F)) + +############################################################################## +# +# Equality and unequality (== and !=) +# +############################################################################## + + def AEC(ctx, x, y): """ Implements the Abstract Equality Comparison x == y @@ -513,6 +533,14 @@ def decision(self, ctx, op1, op2): return W_Boolean(not AEC(ctx, op1, op2)) + +############################################################################## +# +# Strict Equality and unequality, usually means same place in memory +# or equality for primitive values +# +############################################################################## + def SEC(x,y): """ Implements the Strict Equality Comparison x === y @@ -553,6 +581,9 @@ class In(BinaryComparisonOp): + """ + The in operator, eg: "property in object" + """ opcode = 'IN' def decision(self, ctx, op1, op2): @@ -562,6 +593,9 @@ return W_Boolean(op2.HasProperty(name)) class Delete(UnaryOp): + """ + the delete op, erases properties from objects + """ opcode = 'DELETE' def eval(self, ctx): @@ -573,6 +607,9 @@ return W_Boolean(r3.Delete(r4)) class Increment(UnaryOp): + """ + ++value (prefix) and value++ (postfix) + """ opcode = 'INCREMENT' def eval(self, ctx): @@ -588,6 +625,9 @@ class Decrement(UnaryOp): + """ + same as increment --value and value -- + """ opcode = 'DECREMENT' def eval(self, ctx): @@ -616,64 +656,12 @@ def eval(self, ctx): return W_List([node.eval(ctx).GetValue() for node in self.list]) -class Minus(BinaryComparisonOp): - opcode = 'MINUS' - - def decision(self, ctx, op1, op2): - x = op1.ToNumber() - y = op2.ToNumber() - return W_Number(x - y) -class New(UnaryOp): - opcode = 'NEW' - - def eval(self, ctx): - x = self.expr.eval(ctx).GetValue() - if not isinstance(x, W_PrimitiveObject): - raise TypeError() - - return x.Construct(ctx=ctx) - -class NewWithArgs(BinaryOp): - opcode = 'NEW_WITH_ARGS' - - def eval(self, ctx): - x = self.left.eval(ctx).GetValue() - if not isinstance(x, W_PrimitiveObject): - raise TypeError() - args = self.right.eval(ctx).get_args() - return x.Construct(ctx=ctx, args=args) - -class Null(Expression): - opcode = 'NULL' - - def from_tree(self, t): - pass - - def eval(self, ctx): - return w_Null - -class Number(Expression): - opcode = 'NUMBER' - - def from_tree(self, t): - self.num = float(get_string(t, 'value')) - - def eval(self, ctx): - return W_Number(self.num) - -class ObjectInit(ListOp): - opcode = 'OBJECT_INIT' - - def eval(self, ctx): - w_obj = W_Object() - for prop in self.list: - if DEBUG: - print prop.left - name = prop.left.value - w_expr = prop.right.eval(ctx).GetValue() - w_obj.Put(name, w_expr) - return w_obj +############################################################################## +# +# Math Ops +# +############################################################################## class BinaryNumberOp(BinaryOp): def eval(self, ctx): @@ -683,7 +671,7 @@ if DEBUG: print self.left, nleft, self.opcode, self.right, nright, '=', result return result - + class Plus(BinaryNumberOp): opcode = 'PLUS' @@ -713,7 +701,6 @@ fright = nright.ToInt32() return W_Number(fleft % fright) - class Div(BinaryNumberOp): opcode = 'DIV' @@ -731,7 +718,87 @@ return W_Number(fleft - fright) + +class Null(Expression): + opcode = 'NULL' + + def from_tree(self, t): + pass + + def eval(self, ctx): + return w_Null + + +############################################################################## +# +# Value and object creation +# +############################################################################## + +class New(UnaryOp): + opcode = 'NEW' + + def eval(self, ctx): + x = self.expr.eval(ctx).GetValue() + if not isinstance(x, W_PrimitiveObject): + raise TypeError() + + return x.Construct(ctx=ctx) + +class NewWithArgs(BinaryOp): + opcode = 'NEW_WITH_ARGS' + + def eval(self, ctx): + x = self.left.eval(ctx).GetValue() + if not isinstance(x, W_PrimitiveObject): + raise TypeError() + args = self.right.eval(ctx).get_args() + return x.Construct(ctx=ctx, args=args) + +class Number(Expression): + opcode = 'NUMBER' + + def from_tree(self, t): + self.num = float(get_string(t, 'value')) + + def eval(self, ctx): + return W_Number(self.num) + +class String(Expression): + opcode = 'STRING' + + def from_tree(self, t): + self.strval = get_string(t, 'value') + + def eval(self, ctx): + return W_String(self.strval) + + def get_literal(self): + return W_String(self.strval).ToString() + +class ObjectInit(ListOp): + opcode = 'OBJECT_INIT' + + def eval(self, ctx): + w_obj = W_Object() + for prop in self.list: + if DEBUG: + print prop.left + name = prop.left.value + w_expr = prop.right.eval(ctx).GetValue() + w_obj.Put(name, w_expr) + return w_obj + +############################################################################## +# +# Script and semicolon, the most important part of the interpreter probably +# +############################################################################## + class Script(Statement): + """ + Script nodes are found on each function declaration and in global code + """ opcode = 'SCRIPT' def from_tree(self, t): @@ -773,6 +840,7 @@ if isinstance(e, ExecutionReturned) and e.type == 'return': return e.value else: + # TODO: proper exception handling print "exception in line: %s, on: %s"%(node.lineno, node.value) raise @@ -787,18 +855,6 @@ return w_Undefined return self.expr.execute(ctx) -class String(Expression): - opcode = 'STRING' - - def from_tree(self, t): - self.strval = get_string(t, 'value') - - def eval(self, ctx): - return W_String(self.strval) - - def get_literal(self): - return W_String(self.strval).ToString() - class Return(Statement): opcode = 'RETURN' From santagada at codespeak.net Wed Mar 7 04:33:20 2007 From: santagada at codespeak.net (santagada at codespeak.net) Date: Wed, 7 Mar 2007 04:33:20 +0100 (CET) Subject: [pypy-svn] r40008 - pypy/dist/pypy/translator/goal Message-ID: <20070307033320.0067010068@code0.codespeak.net> Author: santagada Date: Wed Mar 7 04:33:18 2007 New Revision: 40008 Modified: pypy/dist/pypy/translator/goal/targetjsstandalone.py Log: now it can load a normal js file :) Modified: pypy/dist/pypy/translator/goal/targetjsstandalone.py ============================================================================== --- pypy/dist/pypy/translator/goal/targetjsstandalone.py (original) +++ pypy/dist/pypy/translator/goal/targetjsstandalone.py Wed Mar 7 04:33:18 2007 @@ -14,12 +14,12 @@ def entry_point(argv): if len(argv) == 2: f = open_file_as_stream(argv[1]) - interp.run(load_bytecode(f.readall())) + interp.run(load_source(f.readall())) return 0 elif argv[0] == 'foo': raise ExecutionReturned(None) else: - print "Usage: %s bytecodefile" % argv[0] + print "Usage: %s jsourcefile" % argv[0] return 1 # _____ Define and setup target ___ From briandorsey at codespeak.net Wed Mar 7 09:52:27 2007 From: briandorsey at codespeak.net (briandorsey at codespeak.net) Date: Wed, 7 Mar 2007 09:52:27 +0100 (CET) Subject: [pypy-svn] r40011 - pypy/dist/pypy/doc Message-ID: <20070307085227.5380810063@code0.codespeak.net> Author: briandorsey Date: Wed Mar 7 09:52:25 2007 New Revision: 40011 Modified: pypy/dist/pypy/doc/index-report.txt Log: Reworded one sentence. Modified: pypy/dist/pypy/doc/index-report.txt ============================================================================== --- pypy/dist/pypy/doc/index-report.txt (original) +++ pypy/dist/pypy/doc/index-report.txt Wed Mar 7 09:52:25 2007 @@ -5,9 +5,9 @@ We have written several reports for the EU of which some are also quite useful as documentation. The ones not so useful as documentation mostly contain text -that can also be found in the regular documentation section. All these -documents are not approved by the European Union and therefore only -preliminary. +that can also be found in the regular documentation section. All of these +documents are preliminary versions, none of them have been approved by the +European Union. Reports of 2007 =============== From antocuni at codespeak.net Wed Mar 7 10:55:09 2007 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Wed, 7 Mar 2007 10:55:09 +0100 (CET) Subject: [pypy-svn] r40013 - pypy/dist/pypy/doc/discussion Message-ID: <20070307095509.D4C0F1006E@code0.codespeak.net> Author: antocuni Date: Wed Mar 7 10:55:09 2007 New Revision: 40013 Modified: pypy/dist/pypy/doc/discussion/chained_getattr.txt Log: fixrest Modified: pypy/dist/pypy/doc/discussion/chained_getattr.txt ============================================================================== --- pypy/dist/pypy/doc/discussion/chained_getattr.txt (original) +++ pypy/dist/pypy/doc/discussion/chained_getattr.txt Wed Mar 7 10:55:09 2007 @@ -26,41 +26,45 @@ now for the LOAD_CHAINED_GLOBAL bytecode implementation: Module dicts have a special implemnetation, providing: + - an extra "fastlookup" rpython-dict serving as a cache for LOAD_CHAINED_GLOBAL places within the modules: - - keys are e.g. ('os', 'path', 'normpath') - - values are tuples of the form: + + * keys are e.g. ('os', 'path', 'normpath') + + * values are tuples of the form: ([obj1, obj2, obj3], [ver1, ver2]) - "ver1" refer to the version of the globals of "os" - "ver2" refer to the version of the globals of "os.path" - "obj3" is the resulting "normpath" function + + "ver1" refer to the version of the globals of "os" + "ver2" refer to the version of the globals of "os.path" + "obj3" is the resulting "normpath" function - upon changes to the global dict, "fastlookup.clear()" is called - after the fastlookup entry is filled for a given LOAD_CHAINED_GLOBAL index, the following checks need - to be performed in the bytecode implementation: + to be performed in the bytecode implementation:: - value = f_globals.fastlookup.get(key, None) - if value is None: - # fill entry - else: - # check that our cached lookups are still valid - assert isinstance(value, tuple) - objects, versions = value - i = 0 - while i < len(versions): - lastversion = versions[i] - ver = getver_for_obj(objects[i]) - if ver == -1 or ver != lastversion: - name = key[i] - objects[i] = space.getattr(curobj, name) - versions[i] = ver - curobj = objects[i] - i += 1 - return objects[i] - - def getver_for_obj(obj): - if "obj is not Module": - return -1 - return obj.w_dict.version + value = f_globals.fastlookup.get(key, None) + if value is None: + # fill entry + else: + # check that our cached lookups are still valid + assert isinstance(value, tuple) + objects, versions = value + i = 0 + while i < len(versions): + lastversion = versions[i] + ver = getver_for_obj(objects[i]) + if ver == -1 or ver != lastversion: + name = key[i] + objects[i] = space.getattr(curobj, name) + versions[i] = ver + curobj = objects[i] + i += 1 + return objects[i] + + def getver_for_obj(obj): + if "obj is not Module": + return -1 + return obj.w_dict.version From antocuni at codespeak.net Wed Mar 7 11:44:31 2007 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Wed, 7 Mar 2007 11:44:31 +0100 (CET) Subject: [pypy-svn] r40014 - pypy/dist/pypy/translator/backendopt/test Message-ID: <20070307104431.EA1B71005A@code0.codespeak.net> Author: antocuni Date: Wed Mar 7 11:44:30 2007 New Revision: 40014 Modified: pypy/dist/pypy/translator/backendopt/test/test_inline.py Log: A failing test for ootype Modified: pypy/dist/pypy/translator/backendopt/test/test_inline.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/test/test_inline.py (original) +++ pypy/dist/pypy/translator/backendopt/test/test_inline.py Wed Mar 7 11:44:30 2007 @@ -512,6 +512,20 @@ assert x4() == 1 py.test.raises(CannotInline, self.check_inline, x3, x4, []) + def test_list_iteration(self): + def f(): + tot = 0 + for item in [1,2,3]: + tot += item + return tot + + eval_func, t = self.check_auto_inlining(f, []) + f_graph = graphof(t, f) + assert len(collect_called_graphs(f_graph, t)) == 0 + + result = eval_func([]) + assert result == 6 + class TestInlineLLType(LLRtypeMixin, BaseTestInline): @@ -636,3 +650,5 @@ res = eval_func([]) assert res == 42 + def test_list_iteration(self): + py.test.skip('fixme!') From ac at codespeak.net Wed Mar 7 12:05:51 2007 From: ac at codespeak.net (ac at codespeak.net) Date: Wed, 7 Mar 2007 12:05:51 +0100 (CET) Subject: [pypy-svn] r40016 - pypy/dist/pypy/bin Message-ID: <20070307110551.8B89C1006E@code0.codespeak.net> Author: ac Date: Wed Mar 7 12:05:49 2007 New Revision: 40016 Modified: pypy/dist/pypy/bin/py.py Log: Remove support for PYTHONSTARTUP from untranslated py.py as it is likely to confuse (and significantly increase startuptime) rather than help. Modified: pypy/dist/pypy/bin/py.py ============================================================================== --- pypy/dist/pypy/bin/py.py (original) +++ pypy/dist/pypy/bin/py.py Wed Mar 7 12:05:49 2007 @@ -122,13 +122,6 @@ # start the interactive console if go_interactive or getenv_w(space, 'PYTHONINSPECT'): - python_startup = getenv_w(space, 'PYTHONSTARTUP') - if python_startup: - try: - main.run_file(python_startup, space=space) - except: - pass - con = interactive.PyPyConsole( space, verbose=interactiveconfig.verbose, completer=interactiveconfig.completer) From gbrandl at codespeak.net Wed Mar 7 12:08:10 2007 From: gbrandl at codespeak.net (gbrandl at codespeak.net) Date: Wed, 7 Mar 2007 12:08:10 +0100 (CET) Subject: [pypy-svn] r40017 - pypy/dist/pypy/interpreter Message-ID: <20070307110810.C30F91006E@code0.codespeak.net> Author: gbrandl Date: Wed Mar 7 12:08:09 2007 New Revision: 40017 Modified: pypy/dist/pypy/interpreter/baseobjspace.py Log: (arigo, xoraxax, gbrandl): fix wrong assumption in getindex_w. Modified: pypy/dist/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/dist/pypy/interpreter/baseobjspace.py (original) +++ pypy/dist/pypy/interpreter/baseobjspace.py Wed Mar 7 12:08:09 2007 @@ -797,8 +797,8 @@ if not err.match(self, self.w_OverflowError): raise if not w_exception: - # w_index is a long object - if w_index.get_sign() < 0: + # w_index should be a long object, but can't be sure of that + if self.is_true(self.lt(w_index, self.wrap(0))): return -sys.maxint-1 else: return sys.maxint From ac at codespeak.net Wed Mar 7 12:13:36 2007 From: ac at codespeak.net (ac at codespeak.net) Date: Wed, 7 Mar 2007 12:13:36 +0100 (CET) Subject: [pypy-svn] r40018 - pypy/dist/pypy/translator/goal Message-ID: <20070307111336.762A61006E@code0.codespeak.net> Author: ac Date: Wed Mar 7 12:13:34 2007 New Revision: 40018 Modified: pypy/dist/pypy/translator/goal/app_main.py Log: Print traceback if we get an exception when running $PYTHONSTARTUP. Use os.getenv since os.environ currently is buggy :( Modified: pypy/dist/pypy/translator/goal/app_main.py ============================================================================== --- pypy/dist/pypy/translator/goal/app_main.py (original) +++ pypy/dist/pypy/translator/goal/app_main.py Wed Mar 7 12:13:34 2007 @@ -268,13 +268,17 @@ sys.argv.append('') go_interactive = True - if go_interactive or os.environ.get('PYTHONINSPECT'): - python_startup = os.environ.get('PYTHONSTARTUP') + if go_interactive or os.getenv('PYTHONINSPECT'): + python_startup = os.getenv('PYTHONSTARTUP') if python_startup: try: - execfile(python_startup, mainmodule.__dict__) - except: + startup = open(python_startup).read() + except IOError: pass + else: + def run_it(): + exec startup in mainmodule.__dict__ + run_toplevel(run_it) print >> sys.stderr, "debug: importing code" import code print >> sys.stderr, "debug: calling code.interact()" From arigo at codespeak.net Wed Mar 7 12:22:44 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 7 Mar 2007 12:22:44 +0100 (CET) Subject: [pypy-svn] r40019 - pypy/dist/pypy/lib Message-ID: <20070307112244.BEB8210069@code0.codespeak.net> Author: arigo Date: Wed Mar 7 12:22:43 2007 New Revision: 40019 Modified: pypy/dist/pypy/lib/_functools.py Log: Remove tab. Modified: pypy/dist/pypy/lib/_functools.py ============================================================================== --- pypy/dist/pypy/lib/_functools.py (original) +++ pypy/dist/pypy/lib/_functools.py Wed Mar 7 12:22:43 2007 @@ -3,7 +3,7 @@ class partial: """ partial(func, *args, **keywords) - new function with partial application - of the given arguments and keywords. + of the given arguments and keywords. """ __slots__ = ['func', 'args', 'keywords'] From bea at codespeak.net Wed Mar 7 13:25:09 2007 From: bea at codespeak.net (bea at codespeak.net) Date: Wed, 7 Mar 2007 13:25:09 +0100 (CET) Subject: [pypy-svn] r40021 - pypy/extradoc/sprintinfo/trillke-2007 Message-ID: <20070307122509.A7F5610069@code0.codespeak.net> Author: bea Date: Wed Mar 7 13:25:08 2007 New Revision: 40021 Modified: pypy/extradoc/sprintinfo/trillke-2007/sprint-report.txt Log: fixed typos - there seem to be two missing pieces before we can send this out - mwh/cf - today? Modified: pypy/extradoc/sprintinfo/trillke-2007/sprint-report.txt ============================================================================== --- pypy/extradoc/sprintinfo/trillke-2007/sprint-report.txt (original) +++ pypy/extradoc/sprintinfo/trillke-2007/sprint-report.txt Wed Mar 7 13:25:08 2007 @@ -2,7 +2,7 @@ 25th sprint, 18th and final EU funded -As has become ususal, the sprint began with a tutorial for those +As has become usual, the sprint began with a tutorial for those participants who are less familiar with PyPy code base. This time Carl Friedrich was talking to Georg Brandl, an interested CPython developer, and Anders (only the third Anders to be involved in the @@ -58,7 +58,7 @@ of global variables, and during one that took place here about various corner cases, Armin and Carl Friedrich and Samuele removed from PyPy some of the strange things CPython does to determine what the -__builtins__ are for the executiong of a given frame -- of course, +__builtins__ are for the execution of a given frame -- of course, depending on the value of PyPy's five millionth configuration option. Holger and Antonio came up with yet another optimization idea along @@ -73,7 +73,7 @@ To do this they wrote some small benchmarks in RPython and stared at some code, but the main problem seems to be that Mono on PowerPC just isn't that good: running pypy-cli using Microsoft's runtime shows -performance just 3-4 time slower than pypy-c. +performance just 3-4 times slower than pypy-c. After this, they worked on streamlining PyPy's much complained about external function interface (and also broke translation a few times in @@ -88,7 +88,7 @@ performance and Samuele made the taint object space translatable. Georg and Alexander implemented some of Python 2.5's features in the -interpeter, in particular support for __index__ and some extensions to +interpreter, in particular support for __index__ and some extensions to string and dict methods. Anders and Anders worked very productively on fixing some of the bugs @@ -144,7 +144,7 @@ Maciej worked on the lib/distributed code that demonstrates the PyPy's transparent proxies. After a bit of effort, he was able to write a -demo that implemented a remote version of pdb by simply by creating a +demo that implemented a remote version of pdb by simply creating a traceback object that proxied all operations to a remote process. Michael and Richard spent a day or so on the LLVM backend, which of From pedronis at codespeak.net Wed Mar 7 13:52:33 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Wed, 7 Mar 2007 13:52:33 +0100 (CET) Subject: [pypy-svn] r40022 - pypy/dist/pypy/translator/backendopt Message-ID: <20070307125233.4A5A410063@code0.codespeak.net> Author: pedronis Date: Wed Mar 7 13:52:31 2007 New Revision: 40022 Modified: pypy/dist/pypy/translator/backendopt/all.py Log: make base inlining and malloc removal orthogonal options again Modified: pypy/dist/pypy/translator/backendopt/all.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/all.py (original) +++ pypy/dist/pypy/translator/backendopt/all.py Wed Mar 7 13:52:31 2007 @@ -64,10 +64,14 @@ print "after no-op removal:" print_statistics(translator.graphs[0], translator) - if config.inline and config.inline_threshold != 0: + if config.inline or config.mallocs: heuristic = get_function(config.inline_heuristic) + if config.inline: + threshold = config.inline_threshold + else: + threshold = 0 inline_malloc_removal_phase(config, translator, graphs, - config.inline_threshold, + threshold, inline_heuristic=heuristic) if config.clever_malloc_removal: @@ -131,12 +135,12 @@ call_count_pred=None): type_system = translator.rtyper.type_system.name - log.inlining("phase with threshold factor: %s" % inline_threshold) - log.inlining("heuristic: %s.%s" % (inline_heuristic.__module__, - inline_heuristic.__name__)) - # inline functions in each other if inline_threshold: + log.inlining("phase with threshold factor: %s" % inline_threshold) + log.inlining("heuristic: %s.%s" % (inline_heuristic.__module__, + inline_heuristic.__name__)) + inline.auto_inline_graphs(translator, graphs, inline_threshold, heuristic=inline_heuristic, call_count_pred=call_count_pred) From mwh at codespeak.net Wed Mar 7 14:18:04 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Wed, 7 Mar 2007 14:18:04 +0100 (CET) Subject: [pypy-svn] r40024 - pypy/extradoc/sprintinfo/trillke-2007 Message-ID: <20070307131804.567271006E@code0.codespeak.net> Author: mwh Date: Wed Mar 7 14:18:03 2007 New Revision: 40024 Modified: pypy/extradoc/sprintinfo/trillke-2007/sprint-report.txt Log: finish the sprint report -- review anyone? Modified: pypy/extradoc/sprintinfo/trillke-2007/sprint-report.txt ============================================================================== --- pypy/extradoc/sprintinfo/trillke-2007/sprint-report.txt (original) +++ pypy/extradoc/sprintinfo/trillke-2007/sprint-report.txt Wed Mar 7 14:18:03 2007 @@ -87,9 +87,22 @@ On the last day, Anto made some small improvements to pypy-cli's performance and Samuele made the taint object space translatable. -Georg and Alexander implemented some of Python 2.5's features in the -interpreter, in particular support for __index__ and some extensions to -string and dict methods. +On the first day Georg and Alexander tried to see how fast a PyPy +could get if there was no Global Interpreter Lock (GIL). By disabling +the GIL and making the exception state thread-local on the genc-level, +they could easily get a binary that at least didn't crash if multiple +threads were not modifying internal stuff concurrently. Running 4 +Pystone instances (from 4 different modules) on this pypy-c let the +process use 381% of cpu time, but the resulting figures were +disappointing: running the 4 Pystone instances in parallel was less +than 25% faster than running them in series, as opposed to being 300% +faster in the best case. Both concluded that the garbage collector +used (Boehm) is not very well suited for the heavy-duty memory +allocation pattern of PyPy in case of multiple threads. + +After this, they implemented some of Python 2.5's features in the +interpreter, in particular support for __index__ and some extensions +to string and dict methods. Anders and Anders worked very productively on fixing some of the bugs in PyPy's issue tracker, implementing the -m command line option in @@ -155,13 +168,16 @@ and also added support for the direct_* pointer operations produced by rctypes. -gil-less hacking - Michael spent some time using Shark, an OS X profiling application, and found some OS specific flags and tweaks that improved the performance of pypy-c on OS X/PPC by around 20%. -post-funding +As readers of pypy-dev will know by now, there were discussions about +how PyPy is going to continue after then end of the EU funding period. +However, I don't have to summarize them here because I can just link +to Armin's mail: + + http://codespeak.net/pipermail/pypy-dev/2007q1/003577.html Cordiali Saluti, mwh & Carl Friedrich From lene at codespeak.net Wed Mar 7 14:21:24 2007 From: lene at codespeak.net (lene at codespeak.net) Date: Wed, 7 Mar 2007 14:21:24 +0100 (CET) Subject: [pypy-svn] r40025 - pypy/extradoc/sprintinfo/trillke-2007 Message-ID: <20070307132124.498E110076@code0.codespeak.net> Author: lene Date: Wed Mar 7 14:21:23 2007 New Revision: 40025 Added: pypy/extradoc/sprintinfo/trillke-2007/eu-report-sprint-report.txt Log: the eu-report sprint report as sent to pypy-dev Added: pypy/extradoc/sprintinfo/trillke-2007/eu-report-sprint-report.txt ============================================================================== --- (empty file) +++ pypy/extradoc/sprintinfo/trillke-2007/eu-report-sprint-report.txt Wed Mar 7 14:21:23 2007 @@ -0,0 +1,76 @@ +Hi pypy-dev! + +Welcome to a slightly unconventional sprint report +(only fair for this slightly unconventional sprint): +The first three days of the Trillke-sprint were fully +dedicated to EU-reporting, considering +that it may be slightly more fun to write them +knowing that everybody else is doing the same, +and that's what this report is about. + +The coding sprint report will follow, once the writers +will have managed to travel home and recover a bit. + +Each of the 14 work packages that PyPy promised +to do to the EU will conclude with at least +one report due in the next month, and the target +of the report sprint was to wrap up most of them +and even deliver some to the EU already, also +to have some spare time for coding works in March. + +In addition, there were the so-called 'review +recommendations' - some first project period +feedback by the Commission, requesting that the +reports should meet scientific standards, include +references and in general be useful for other than +filling the EU's archives purposes. + +So, everybody was busy collecting papers, writing +footnotes and consider overall sense-making strategies +of the EU-reports, many of the results can be found here: + +http://codespeak.net/pypy/dist/pypy/doc/index-report.html + +A big effort went into the D12 report (prototypes, +backends) taken care of by Samuele, Arre, Anto, Guido, +Armin and overall coordinated by Holger, who also got +Niko on the boat for remotely writing a section +on the JVM backend. + +And then there were D02.1, D14.2, D01.2-4, D13.1, D03.1, +D09.1 not to speak of the periodic/final EU management related +reports and (sigh) the D06.1 report, being worked on by +Holger, Anto, Arre, Stephan, Samuele, Lene, Carl Friedrich, +Bea, Armin, Niko, Guido, and even the jet-lagged Michael and +Richard helped with reviews and consultancy. + +Carl Friedrich, the very patient report release manager, +took care for overall finalization and pdf-ing of reports +apart from driving and starting the D06.1 report. + +Bea, Holger and Lene sat together dicussing ideas for +overall activity reporting. On Wednesday, we finally managed +to send out a pile of reports to the EU project officer, +also presenting a commonly discussed table of planned +report deliveries. + +And then the OLPC laptop came - introduced by Christian +bringing it directly from Pycon to the +PyPy group - which more or less stopped all report writing +in exchange for people gathering around the machine +and starting hacking. But luckily it was only +Wednesday afternoon when it arrived and the belly- +dancers were about to conquer the sprint room anyway :) + +(Actually, Armin continued working with the OLPC on the +breakday and managed to port the Bub-n-Bros client to it, +getting one step closer to the PyPy3000 goal of running +Bub-n-Bros on every imaginable platform.) + +Cheers, + +Lene + + + + From pedronis at codespeak.net Wed Mar 7 14:21:50 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Wed, 7 Mar 2007 14:21:50 +0100 (CET) Subject: [pypy-svn] r40026 - pypy/extradoc/sprintinfo/trillke-2007 Message-ID: <20070307132150.0271D10079@code0.codespeak.net> Author: pedronis Date: Wed Mar 7 14:21:50 2007 New Revision: 40026 Modified: pypy/extradoc/sprintinfo/trillke-2007/sprint-report.txt Log: typo Modified: pypy/extradoc/sprintinfo/trillke-2007/sprint-report.txt ============================================================================== --- pypy/extradoc/sprintinfo/trillke-2007/sprint-report.txt (original) +++ pypy/extradoc/sprintinfo/trillke-2007/sprint-report.txt Wed Mar 7 14:21:50 2007 @@ -173,7 +173,7 @@ performance of pypy-c on OS X/PPC by around 20%. As readers of pypy-dev will know by now, there were discussions about -how PyPy is going to continue after then end of the EU funding period. +how PyPy is going to continue after the end of the EU funding period. However, I don't have to summarize them here because I can just link to Armin's mail: From lene at codespeak.net Wed Mar 7 14:24:07 2007 From: lene at codespeak.net (lene at codespeak.net) Date: Wed, 7 Mar 2007 14:24:07 +0100 (CET) Subject: [pypy-svn] r40027 - pypy/extradoc/sprintinfo/trillke-2007 Message-ID: <20070307132407.7668010070@code0.codespeak.net> Author: lene Date: Wed Mar 7 14:24:05 2007 New Revision: 40027 Modified: pypy/extradoc/sprintinfo/trillke-2007/sprint-report.txt Log: turn the I into a we Modified: pypy/extradoc/sprintinfo/trillke-2007/sprint-report.txt ============================================================================== --- pypy/extradoc/sprintinfo/trillke-2007/sprint-report.txt (original) +++ pypy/extradoc/sprintinfo/trillke-2007/sprint-report.txt Wed Mar 7 14:24:05 2007 @@ -174,7 +174,7 @@ As readers of pypy-dev will know by now, there were discussions about how PyPy is going to continue after the end of the EU funding period. -However, I don't have to summarize them here because I can just link +However, we don't have to summarize them here because we can just link to Armin's mail: http://codespeak.net/pipermail/pypy-dev/2007q1/003577.html From antocuni at codespeak.net Wed Mar 7 14:34:13 2007 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Wed, 7 Mar 2007 14:34:13 +0100 (CET) Subject: [pypy-svn] r40028 - in pypy/dist/pypy: rpython/ootypesystem rpython/ootypesystem/test translator/backendopt translator/backendopt/test Message-ID: <20070307133413.1FC081007C@code0.codespeak.net> Author: antocuni Date: Wed Mar 7 14:34:11 2007 New Revision: 40028 Modified: pypy/dist/pypy/rpython/ootypesystem/ootype.py pypy/dist/pypy/rpython/ootypesystem/test/test_ootype.py pypy/dist/pypy/translator/backendopt/inline.py pypy/dist/pypy/translator/backendopt/test/test_inline.py Log: make inline_once aware that most of methods of BuiltinTypes don't raise exceptions. This allow much more inlining and make test_list_iteration passing. Modified: pypy/dist/pypy/rpython/ootypesystem/ootype.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/ootype.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/ootype.py Wed Mar 7 14:34:11 2007 @@ -292,20 +292,23 @@ class BuiltinADTType(BuiltinType): - def _setup_methods(self, generic_types): + def _setup_methods(self, generic_types, can_raise=[]): methods = {} for name, meth in self._GENERIC_METHODS.iteritems(): args = [self._specialize_type(arg, generic_types) for arg in meth.ARGS] result = self._specialize_type(meth.RESULT, generic_types) methods[name] = Meth(args, result) self._METHODS = frozendict(methods) + self._can_raise = tuple(can_raise) def _lookup(self, meth_name): METH = self._METHODS.get(meth_name) meth = None if METH is not None: cls = self._get_interp_class() - meth = _meth(METH, _name=meth_name, _callable=getattr(cls, meth_name)) + can_raise = meth_name in self._can_raise + meth = _meth(METH, _name=meth_name, _callable=getattr(cls, meth_name), _can_raise=can_raise) + meth._virtual = False return self, meth @@ -600,8 +603,7 @@ "ll_current_key": Meth([], self.KEYTYPE_T), "ll_current_value": Meth([], self.VALUETYPE_T), }) - - self._setup_methods(generic_types) + self._setup_methods(generic_types, can_raise=['ll_go_next']) def __str__(self): return '%s%s' % (self.__class__.__name__, Modified: pypy/dist/pypy/rpython/ootypesystem/test/test_ootype.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/test/test_ootype.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/test/test_ootype.py Wed Mar 7 14:34:11 2007 @@ -443,3 +443,11 @@ assert not B._subclasses assert C in A._subclasses assert D in C._subclasses + +def test_canraise(): + LT = List(Signed) + _, meth = LT._lookup('ll_length') + assert meth._can_raise == False + DT = DictItemsIterator(String, Signed) + _, meth = DT._lookup('ll_go_next') + assert meth._can_raise == True Modified: pypy/dist/pypy/translator/backendopt/inline.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/inline.py (original) +++ pypy/dist/pypy/translator/backendopt/inline.py Wed Mar 7 14:34:11 2007 @@ -30,7 +30,11 @@ else: return meth -def collect_called_graphs(graph, translator): +class CanRaise: + def __init__(self, can_raise): + self.can_raise = can_raise + +def collect_called_graphs(graph, translator, include_oosend=True): graphs_or_something = {} for block in graph.iterblocks(): for op in block.operations: @@ -47,9 +51,14 @@ else: for graph in graphs: graphs_or_something[graph] = True - if op.opname == 'oosend': + if op.opname == 'oosend' and include_oosend: meth = get_meth_from_oosend(op) - key = getattr(meth, 'graph', op.args[0]) + if hasattr(meth, 'graph'): + key = meth.graph + elif hasattr(meth, '_can_raise'): + key = CanRaise(meth._can_raise) + else: + key = op.args[0] graphs_or_something[key] = True return graphs_or_something @@ -144,11 +153,15 @@ return False def any_call_to_raising_graphs(from_graph, translator, raise_analyzer): - for graph in collect_called_graphs(from_graph, translator): - if not isinstance(graph, FunctionGraph): - return True # conservatively - if does_raise_directly(graph, raise_analyzer): - return True + for graph_or_something in collect_called_graphs(from_graph, translator): + if isinstance(graph_or_something, FunctionGraph): + if does_raise_directly(graph_or_something, raise_analyzer): + return True + elif isinstance(graph_or_something, CanRaise): + if graph_or_something.can_raise: + return True + else: + return True # conservatively return False class BaseInliner(object): @@ -435,7 +448,7 @@ assert afterblock.operations[n].opname == self.op.opname self.op = afterblock.operations.pop(n) #vars that need to be passed through the blocks of the inlined function - linktoinlined = splitlink + linktoinlined = splitlink copiedstartblock = self.copy_block(self.graph_to_inline.startblock) copiedstartblock.isstartblock = False #find args passed to startblock of inlined function Modified: pypy/dist/pypy/translator/backendopt/test/test_inline.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/test/test_inline.py (original) +++ pypy/dist/pypy/translator/backendopt/test/test_inline.py Wed Mar 7 14:34:11 2007 @@ -519,9 +519,10 @@ tot += item return tot - eval_func, t = self.check_auto_inlining(f, []) + eval_func, t = self.check_auto_inlining(f, [], checkvirtual=True) f_graph = graphof(t, f) - assert len(collect_called_graphs(f_graph, t)) == 0 + called_graphs = collect_called_graphs(f_graph, t, include_oosend=False) + assert len(called_graphs) == 0 result = eval_func([]) assert result == 6 @@ -649,6 +650,3 @@ eval_func, t = self.check_auto_inlining(fn5, [], checkvirtual=True) res = eval_func([]) assert res == 42 - - def test_list_iteration(self): - py.test.skip('fixme!') From antocuni at codespeak.net Wed Mar 7 14:48:28 2007 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Wed, 7 Mar 2007 14:48:28 +0100 (CET) Subject: [pypy-svn] r40029 - pypy/dist/pypy/rpython/microbench Message-ID: <20070307134828.952C810063@code0.codespeak.net> Author: antocuni Date: Wed Mar 7 14:48:27 2007 New Revision: 40029 Modified: pypy/dist/pypy/rpython/microbench/list.py Log: a new microbenchmark showing that boxing *is* an issue Modified: pypy/dist/pypy/rpython/microbench/list.py ============================================================================== --- pypy/dist/pypy/rpython/microbench/list.py (original) +++ pypy/dist/pypy/rpython/microbench/list.py Wed Mar 7 14:48:27 2007 @@ -50,7 +50,7 @@ def loop(obj, i): obj[i%1000] = i -class list__iteration: +class list__iteration__int: __metaclass__ = MetaBench LOOPS = 100000 def init(): @@ -63,3 +63,17 @@ for item in obj: tot += item return tot + +class list__iteration__string: + __metaclass__ = MetaBench + LOOPS = 100000 + def init(): + obj = ['foo']*1000 + obj[0] = 'bar' + return obj + args = ['obj'] + def loop(obj): + tot = 0 + for item in obj: + tot += len(item) + return tot From mwh at codespeak.net Wed Mar 7 15:04:11 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Wed, 7 Mar 2007 15:04:11 +0100 (CET) Subject: [pypy-svn] r40030 - pypy/extradoc/sprintinfo/trillke-2007 Message-ID: <20070307140411.3B96610068@code0.codespeak.net> Author: mwh Date: Wed Mar 7 15:04:09 2007 New Revision: 40030 Modified: pypy/extradoc/sprintinfo/trillke-2007/sprint-report.txt Log: some kind of introduction Modified: pypy/extradoc/sprintinfo/trillke-2007/sprint-report.txt ============================================================================== --- pypy/extradoc/sprintinfo/trillke-2007/sprint-report.txt (original) +++ pypy/extradoc/sprintinfo/trillke-2007/sprint-report.txt Wed Mar 7 15:04:09 2007 @@ -1,19 +1,21 @@ Hello pypy-dev! -25th sprint, 18th and final EU funded +This is the report for the second, coding, half of PyPy's **25th** +sprint, and the 18th and final sprint of the EU funded period. -As has become usual, the sprint began with a tutorial for those -participants who are less familiar with PyPy code base. This time -Carl Friedrich was talking to Georg Brandl, an interested CPython -developer, and Anders (only the third Anders to be involved in the -project!) Sigfridsson, a PhD student at the Interaction Design Centre -at the University of Limerick. Anders originally became involved in -the project as an observer of the sprint process for his group's -research when we sprinted at the University of Limerick, and that was -partly why he was here this time, but it seems he found PyPy -interesting enough to learn Python in the mean time and participate on -the coding less at this sprint (or maybe he thought the view from the -sprint trenches would be more revealing!). +We are so completely tired that we don't have the energy to write a +witty entry, so we'll skip that bit and start with the now usual +tutorial for those participants who are less familiar with PyPy code +base. This time Carl Friedrich was talking to Georg Brandl, an +interested CPython developer, and Anders (only the third Anders to be +involved in the project!) Sigfridsson, a PhD student at the +Interaction Design Centre at the University of Limerick. Anders +originally became involved in the project as an observer of the sprint +process for his group's research when we sprinted at the University of +Limerick, and that was partly why he was here this time, but it seems +he found PyPy interesting enough to learn Python in the mean time and +participate on the coding less at this sprint (or maybe he thought the +view from the sprint trenches would be more revealing!). This sprint has seen many, many small tasks completed. On the first morning, Holger and Armin improved the readline module to the point of From mwh at codespeak.net Wed Mar 7 15:04:32 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Wed, 7 Mar 2007 15:04:32 +0100 (CET) Subject: [pypy-svn] r40031 - pypy/extradoc/sprintinfo/trillke-2007 Message-ID: <20070307140432.DB86510076@code0.codespeak.net> Author: mwh Date: Wed Mar 7 15:04:32 2007 New Revision: 40031 Modified: pypy/extradoc/sprintinfo/trillke-2007/sprint-report.txt Log: argh Modified: pypy/extradoc/sprintinfo/trillke-2007/sprint-report.txt ============================================================================== --- pypy/extradoc/sprintinfo/trillke-2007/sprint-report.txt (original) +++ pypy/extradoc/sprintinfo/trillke-2007/sprint-report.txt Wed Mar 7 15:04:32 2007 @@ -4,9 +4,9 @@ sprint, and the 18th and final sprint of the EU funded period. We are so completely tired that we don't have the energy to write a -witty entry, so we'll skip that bit and start with the now usual -tutorial for those participants who are less familiar with PyPy code -base. This time Carl Friedrich was talking to Georg Brandl, an +witty entry, so we'll skip that bit and start with describing the now +usual tutorial for those participants who are less familiar with PyPy +code base. This time Carl Friedrich was talking to Georg Brandl, an interested CPython developer, and Anders (only the third Anders to be involved in the project!) Sigfridsson, a PhD student at the Interaction Design Centre at the University of Limerick. Anders From ac at codespeak.net Wed Mar 7 16:32:26 2007 From: ac at codespeak.net (ac at codespeak.net) Date: Wed, 7 Mar 2007 16:32:26 +0100 (CET) Subject: [pypy-svn] r40032 - in pypy/dist/pypy: interpreter module/posix Message-ID: <20070307153226.C895A10063@code0.codespeak.net> Author: ac Date: Wed Mar 7 16:32:25 2007 New Revision: 40032 Modified: pypy/dist/pypy/interpreter/baseobjspace.py pypy/dist/pypy/interpreter/module.py pypy/dist/pypy/module/posix/__init__.py pypy/dist/pypy/module/posix/interp_posix.py Log: Add a startup method to Module to allow modules to do runtime initialization. Make posix module use the startup method to initialize the environ dict. Modified: pypy/dist/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/dist/pypy/interpreter/baseobjspace.py (original) +++ pypy/dist/pypy/interpreter/baseobjspace.py Wed Mar 7 16:32:25 2007 @@ -197,7 +197,17 @@ def startup(self): # To be called before using the space - pass + + # Initialize all builtin modules + from pypy.interpreter.module import Module + for modname in self._builtinmodule_list: + try: + mod = self.getbuiltinmodule(modname) + except OperationError: + # Not found, ignore it. + continue + if isinstance(mod, Module): + mod.startup(self) def finish(self): w_exitfunc = self.sys.getdictvalue_w(self, 'exitfunc') Modified: pypy/dist/pypy/interpreter/module.py ============================================================================== --- pypy/dist/pypy/interpreter/module.py (original) +++ pypy/dist/pypy/interpreter/module.py Wed Mar 7 16:32:25 2007 @@ -20,6 +20,11 @@ """NOT_RPYTHON: to allow built-in modules to do some more setup after the space is fully initialized.""" + def startup(self, space): + """This is called at runtime before the space gets uses to allow + the module to do initialization at runtime. + """ + def getdict(self): return self.w_dict Modified: pypy/dist/pypy/module/posix/__init__.py ============================================================================== --- pypy/dist/pypy/module/posix/__init__.py (original) +++ pypy/dist/pypy/module/posix/__init__.py Wed Mar 7 16:32:25 2007 @@ -90,6 +90,10 @@ if config.translating and config.translation.backend == "llvm": space.delattr(self, space.wrap("execv")) + def startup(self, space): + from pypy.module.posix import interp_posix + interp_posix.get(space).startup(space) + for constant in dir(os): value = getattr(os, constant) if constant.isupper() and type(value) is int: 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 Wed Mar 7 16:32:25 2007 @@ -259,7 +259,9 @@ def __init__(self, space): self.posix_putenv_garbage = {} self.w_environ = space.newdict() + def startup(self, space): _convertenviron(space, self.w_environ) + def get(space): return space.fromcache(State) From pedronis at codespeak.net Wed Mar 7 17:15:23 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Wed, 7 Mar 2007 17:15:23 +0100 (CET) Subject: [pypy-svn] r40033 - pypy/dist/pypy/interpreter Message-ID: <20070307161523.4BF271006E@code0.codespeak.net> Author: pedronis Date: Wed Mar 7 17:15:21 2007 New Revision: 40033 Modified: pypy/dist/pypy/interpreter/baseobjspace.py Log: use a logic more similar to setup_after_initialization, no need for exception handling this way Modified: pypy/dist/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/dist/pypy/interpreter/baseobjspace.py (original) +++ pypy/dist/pypy/interpreter/baseobjspace.py Wed Mar 7 17:15:21 2007 @@ -200,12 +200,10 @@ # Initialize all builtin modules from pypy.interpreter.module import Module - for modname in self._builtinmodule_list: - try: - mod = self.getbuiltinmodule(modname) - except OperationError: - # Not found, ignore it. - continue + for w_modname in self.unpackiterable( + self.sys.get('builtin_module_names')): + modname = self.str_w(w_modname) + mod = self.getbuiltinmodule(modname) if isinstance(mod, Module): mod.startup(self) From pedronis at codespeak.net Wed Mar 7 17:16:02 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Wed, 7 Mar 2007 17:16:02 +0100 (CET) Subject: [pypy-svn] r40034 - pypy/dist/pypy/module/operator Message-ID: <20070307161602.419E210071@code0.codespeak.net> Author: pedronis Date: Wed Mar 7 17:16:00 2007 New Revision: 40034 Modified: pypy/dist/pypy/module/operator/ (props changed) pypy/dist/pypy/module/operator/__init__.py (props changed) pypy/dist/pypy/module/operator/interp_operator.py (props changed) Log: fixeol (ignore .pyc files) From hpk at codespeak.net Wed Mar 7 17:34:55 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Wed, 7 Mar 2007 17:34:55 +0100 (CET) Subject: [pypy-svn] r40035 - in pypy/dist/pypy/lib: . test2 Message-ID: <20070307163455.BA1F210063@code0.codespeak.net> Author: hpk Date: Wed Mar 7 17:34:54 2007 New Revision: 40035 Added: pypy/dist/pypy/lib/test2/test_formatting.py (contents, props changed) Modified: pypy/dist/pypy/lib/_formatting.py Log: Issue296 resolved added the beginnings of a direct test file for string interpolation, first testing/fixing the regression introduced by the string interp refactorings during the sprint. (Note: you need to remove _cache, at least i had to do that to have the fix effectively) Modified: pypy/dist/pypy/lib/_formatting.py ============================================================================== --- pypy/dist/pypy/lib/_formatting.py (original) +++ pypy/dist/pypy/lib/_formatting.py Wed Mar 7 17:34:54 2007 @@ -304,7 +304,6 @@ v = self.valuebox.str() if len(v) != 1: raise TypeError, "%c requires int or char" - elif self.valuebox.isunicode(): raise NeedUnicodeFormattingError else: @@ -507,6 +506,8 @@ def isint(self): return isinstance(self._value, int) + def isstr(self): + return isinstance(self._value, str) def isunicode(self): return isinstance(self._value, unicode) Added: pypy/dist/pypy/lib/test2/test_formatting.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/lib/test2/test_formatting.py Wed Mar 7 17:34:54 2007 @@ -0,0 +1,15 @@ + +import py + +from pypy.lib._formatting import format, NeedUnicodeFormattingError + +def test_charformatter(): + res = format("%c", ("a",)) + assert res == "a" + res = format("%c", (ord("b"),)) + assert res == "b" + py.test.raises(TypeError, + "format('%c', ('qw',))") + #py.test.raises(NeedUnicodeFormattingError, + # "format(u'%c', (u'b',))") + From santagada at codespeak.net Wed Mar 7 17:59:13 2007 From: santagada at codespeak.net (santagada at codespeak.net) Date: Wed, 7 Mar 2007 17:59:13 +0100 (CET) Subject: [pypy-svn] r40037 - pypy/dist/pypy/lang/js Message-ID: <20070307165913.10C431006E@code0.codespeak.net> Author: santagada Date: Wed Mar 7 17:59:12 2007 New Revision: 40037 Added: pypy/dist/pypy/lang/js/commit (contents, props changed) Log: simple shell script to run tests before commiting Added: pypy/dist/pypy/lang/js/commit ============================================================================== --- (empty file) +++ pypy/dist/pypy/lang/js/commit Wed Mar 7 17:59:12 2007 @@ -0,0 +1 @@ +py.test -x --tb=no|grep -q "1 failed" || svn commit From afayolle at codespeak.net Wed Mar 7 18:05:29 2007 From: afayolle at codespeak.net (afayolle at codespeak.net) Date: Wed, 7 Mar 2007 18:05:29 +0100 (CET) Subject: [pypy-svn] r40038 - in pypy/dist/pypy/lib: . app_test Message-ID: <20070307170529.7A7DF1006E@code0.codespeak.net> Author: afayolle Date: Wed Mar 7 18:05:27 2007 New Revision: 40038 Modified: pypy/dist/pypy/lib/aop.py pypy/dist/pypy/lib/app_test/test_aop.py Log: around execution advice is working Modified: pypy/dist/pypy/lib/aop.py ============================================================================== --- pypy/dist/pypy/lib/aop.py (original) +++ pypy/dist/pypy/lib/aop.py Wed Mar 7 18:05:27 2007 @@ -10,34 +10,6 @@ # advices # ------- - - -class Debug(parser.ASTVisitor): - def __init__(self): - self.offset = 0 - def default(self, node): - print ' '*self.offset+str(node) - self.offset += 4 - for child in node.getChildNodes(): - child.accept(self) - self.offset -= 4 - return node - - def visitFunction(self, func): - print " "*self.offset+'def %s:' % (func.name) - self.offset += 4 - for node in func.code.nodes: - node.accept(self) - self.offset -= 4 - def visitReturn(self, ret): - print ' '*self.offset+'return ', - for child in ret.getChildNodes(): - child.accept(self) - - - -DEBUGGER= Debug() - class Advice(parser.ASTVisitor): requires_dynamic_pointcut=True def __init__(self, pointcut): @@ -47,13 +19,9 @@ def __call__(self, function): print 'wrapping advice %s on %s' % (self.pointcut, function.__name__) - self.function = function + self.woven_code = function return self -## def decorated(self,*args, **kwargs): -## print 'calling aspectized function %s (with %s)' % (self.function.__name__, self.pointcut) -## return self.function(*args, **kwargs) - def weave(self, ast, enc): return ast.accept(self) @@ -76,6 +44,12 @@ arguments = [p.ASTConst(id),] if targetname is not None: arguments.append(p.ASTName(targetname)) + else: + arguments.append(p.ASTConst(None)) + arguments.append(p.ASTCallFunc(p.ASTName('locals'), + [], None, None) + ) + if discard: returnclass = p.ASTDiscard else: @@ -98,10 +72,7 @@ def weave_at_pointcut(self, node, tjp): print "WEAVE around!!!" p = parser - print 'original func:' - node.accept(DEBUGGER) - print '+++', self.function - id = __aop__.register_joinpoint(self.function, tjp) + id = __aop__.register_joinpoint(self.woven_code, tjp) statement = node.code newname = '__aoptarget_%s_%s__' % (node.name, id) newcode = p.ASTStmt([p.ASTFunction(node.decorators, @@ -112,20 +83,19 @@ node.w_doc, node.code, node.lineno), - make_aop_call(id, targetname=newname, discard=False), + make_aop_call(id, targetname=newname, + discard=False), ]) node.decorators = None node.code = newcode - print 'weaving produced:' - node.accept(DEBUGGER) return node class before(Advice): """specify code to be run before the pointcut""" def weave_at_pointcut(self, node, tjp): print "WEAVE before!!!" - id = __aop__.register_joinpoint(self.function, tjp) + id = __aop__.register_joinpoint(self.woven_code, tjp) statement_list = node.code.nodes statement_list.insert(0, make_aop_call(id)) node.code.nodes = statement_list @@ -137,7 +107,7 @@ """specify code to be run after the pointcut""" def weave_at_pointcut(self, node, tjp): print "WEAVE after!!!" - id = __aop__.register_joinpoint(self.function, tjp) + id = __aop__.register_joinpoint(self.woven_code, tjp) statement = node.code tryfinally = parser.ASTTryFinally(statement, make_aop_call(id)) node.code = tryfinally @@ -164,29 +134,29 @@ def signature(self): """return: string representation of the signature of the joint point""" - return self.signature + return self._signature def that(self): """return: a reference on the object initiating the call, or None if it is a static method or a global function""" - return self.that + return self._that def target(self): """return: reference the object that is the target of a call or None if it is a static method or a global function""" - return self.target + return self._target def result(self): """return: reference on result value or None""" - return self.result + return self._result def arguments(self): """return: the (args, kwargs) of the join point""" - return self.arguments + return self._arguments def proceed(self, *args, **kwargs): """execute the original code in an around advice""" - self.result = self.func(*args, **kwargs) + self._result = self.func(*args, **kwargs) def action(self): """return: the runtime action object containing the execution @@ -194,11 +164,13 @@ pass def __init__(self, signature=None, that=None, target=None, result=None, arguments=None, func=None): - self.signature = signature - self.that = that - self.target = target - self.result = result - self.arguments = arguments + self._signature = signature + self._that = that + self._target = target + self._result = result + if arguments is None: + arguments = (), {} + self._arguments = arguments self.func = func @@ -237,48 +209,60 @@ def call(self): """return a dynamic pointcut representing places where the pointcut is called""" - # XXX may be difficult to implement ? - self.isdynamic = True - self.mode = 'call' - #raise NotImplementedError('call') - return self - + return CallPointCut(self) def execution(self): """return a dynamic pointcut representing places where the pointcut is executed""" - self.isdynamic = True - self.mode = 'execution' - return self + return ExecutionPointCut(self) def initialization(self): """return a dynamic pointcut representing places where the pointcut is instantiated""" - self.isdynamic = True - self.mode = 'initializartion' - #raise NotImplementedError('initialization') - return self + return InitializationPointCut(self) def destruction(self): """return a dynamic pointcut representing places where the pointcut is destroyed""" - self.isdynamic = True - self.mode = 'destruction' - #raise NotImplementedError('destruction') + return DestructionPointCut(self) + + def match(self, astnode): + raise NotImplementedError + + def joinpoint(self, node): + """returns a join point instance for the node""" + assert self.match(node) + return JoinPoint() - return self +class AbstractDynamicPointCut(PointCut): + def __init__(self, pointcut): + PointCut.__init__(self, pointcut) + self.isdynamic = True + + +class ExecutionPointCut(AbstractDynamicPointCut): def match(self, astnode): - # FIXME !!! :-) - if self.mode == 'execution': - try: - return astnode.name == self.pointcutdef - except AttributeError: - return False + try: + return astnode.name == self.pointcutdef + except AttributeError: + return False def joinpoint(self, node): """returns a join point instance for the node""" assert self.match(node) - if self.mode == 'execution': -## stnode = parser.STType(node) -## target = getattr(stnode.compile(), node.name) - return JoinPoint() + jp = JoinPoint() + jp._flags = node.flags + jp._argnames = [a.name for a in node.argnames] + jp._defaultargvalues = [d.value for d in node.defaults] + + return jp + +class CallPointCut(AbstractDynamicPointCut): + pass + +class DestructionPointCut(AbstractDynamicPointCut): + pass + +class InitializationPointCut(AbstractDynamicPointCut): + pass + ### make these class methods of PointCut ? def within(pointcutstring): @@ -332,19 +316,21 @@ finally: self._id += 1 - def register_joinpoint(self, callable, *args): + def register_joinpoint(self, woven_code, joinpoint, *args): assert self._curr_aspect is not None id = self._next_id() print "register joinpoint with id %d" % id - args = (self._curr_aspect,) + args - self.joinpoints[id] = callable, args + arguments = self._curr_aspect, joinpoint, args + self.joinpoints[id] = woven_code, arguments return id - def __call__(self, id, target=None): - callable, args = self.joinpoints[id] - print args - args[-1].target = target - callable(*args) + def __call__(self, id, target=None, target_locals = None): + woven_code, (aspect, joinpoint, arguments) = self.joinpoints[id] + joinpoint.func = target + if target_locals is not None: + joinpoint._arguments = (), dict([(n, target_locals[n]) for n in joinpoint._argnames]) + args = (aspect, joinpoint,) + arguments + return woven_code(*args) import __builtin__ __builtin__.__aop__ = Weaver() @@ -369,3 +355,18 @@ return instance +# debugging visitor +class Debug(parser.ASTVisitor): + def __init__(self): + self.offset = 0 + def default(self, node): + print ' '*self.offset+str(node) + self.offset += 4 + for child in node.getChildNodes(): + child.accept(self) + self.offset -= 4 + return node + + + +DEBUGGER= Debug() Modified: pypy/dist/pypy/lib/app_test/test_aop.py ============================================================================== --- pypy/dist/pypy/lib/app_test/test_aop.py (original) +++ pypy/dist/pypy/lib/app_test/test_aop.py Wed Mar 7 18:05:27 2007 @@ -5,10 +5,10 @@ def setup_class(cls): cls.space = gettestobjspace(**{'objspace.usepycfiles':False}) - def _test_init(self): + def test_init(self): import aop - def _test_static_dynamic_advice_and_pointcut(self): + def test_static_dynamic_advice_and_pointcut(self): from aop import PointCut, introduce, before, around, after dyn_pc = PointCut('foo').call() @@ -28,7 +28,7 @@ adv = advice(dyn_pc) assert adv is not None - def _test_is_aop(self): + def test_is_aop(self): from aop import is_aop_call import parser func = """ @@ -41,7 +41,7 @@ result = [is_aop_call(n) for n in funcast.code.nodes] assert result == [True, False, True] - def _test_simple_aspect_before_execution(self): + def test_simple_aspect_before_execution(self): from aop import PointCut, Aspect, before from app_test import sample_aop_code __aop__._clear_all() @@ -54,6 +54,8 @@ @before(PointCut('foo').execution()) def advice_before_execution(self, tjp): self.executed = True + self.argnames = tjp._argnames + self.flags = tjp._flags assert __aop__.advices == [] aspect = AspectTest() @@ -62,11 +64,14 @@ from app_test import aop_before_execution assert aspect.executed == 0 - aop_before_execution.foo(1,2) + answ = aop_before_execution.foo(1,2) assert aspect.executed == 1 + assert aspect.argnames == ['b', 'c'] + assert aspect.flags == 0 + assert answ == 47 sample_aop_code.clean_module('aop_before_execution') - def _test_simple_aspect_after_execution(self): + def test_simple_aspect_after_execution(self): from aop import PointCut, Aspect, after from app_test import sample_aop_code __aop__._clear_all() @@ -85,8 +90,9 @@ assert not aspect.executed from app_test import aop_after_execution assert aspect.executed == 0 - aop_after_execution.foo(1,2) + answ = aop_after_execution.foo(1,2) assert aspect.executed == 1 + assert answ == 47 sample_aop_code.clean_module('aop_after_execution') def test_simple_aspect_around_execution(self): @@ -101,20 +107,23 @@ self.executed_after = 0 @around(PointCut('foo').execution()) def advice_around_execution(self, tjp): - print '>>>in' + print '>>>in', tjp.arguments() self.executed_before += 1 - tjp.proceed() + args, kwargs = tjp.arguments() + tjp.proceed(*args, **kwargs) self.executed_after += 1 self.result = tjp.result() print '<< Author: fijal Date: Wed Mar 7 18:32:20 2007 New Revision: 40040 Added: pypy/dist/pypy/lib/distributed/test/test_greensock.py Modified: pypy/dist/pypy/lib/distributed/socklayer.py Log: Add a fancy test and a simple helper Modified: pypy/dist/pypy/lib/distributed/socklayer.py ============================================================================== --- pypy/dist/pypy/lib/distributed/socklayer.py (original) +++ pypy/dist/pypy/lib/distributed/socklayer.py Wed Mar 7 18:32:20 2007 @@ -1,5 +1,5 @@ -#from pypeers.pipe.gsocket import GreenSocket +import py from socket import socket from py.__.net.msgstruct import decodemessage, message from socket import socket, AF_INET, SOCK_STREAM @@ -30,7 +30,7 @@ self.conn.sendall(message('c', marshal.dumps(data))) trace("done") -def socket_listener(address=('', 12122)): +def socket_listener(address=('', 12122), socket=socket): s = socket(AF_INET, SOCK_STREAM) s.bind(address) s.listen(1) @@ -40,10 +40,22 @@ sw = SocketWrapper(conn) return sw.send, sw.receive -def socket_connecter(address): +def socket_connecter(address, socket=socket): s = socket(AF_INET, SOCK_STREAM) print "Connecting %s" % (address,) s.connect(address) sw = SocketWrapper(s) return sw.send, sw.receive + +def spawn_remote_side(code, gw): + """ A very simple wrapper around greenexecnet to allow + spawning a remote side of lib/distributed + """ + from distributed import RemoteProtocol + extra = str(py.code.Source(""" + from distributed import remote_loop, RemoteProtocol + remote_loop(RemoteProtocol(channel.send, channel.receive, globals())) + """)) + channel = gw.remote_exec(code + "\n" + extra) + return RemoteProtocol(channel.send, channel.receive) Added: pypy/dist/pypy/lib/distributed/test/test_greensock.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/lib/distributed/test/test_greensock.py Wed Mar 7 18:32:20 2007 @@ -0,0 +1,54 @@ + +from pypy.conftest import gettestobjspace + +class AppTestDistributedGreensock(object): + def setup_class(cls): + cls.space = gettestobjspace(**{"objspace.std.withtproxy": True, + "usemodules":("_stackless",)}) + cls.w_remote_side_code = cls.space.appexec([], """(): + import py + remote_side_code = str(py.code.Source(''' + class A: + def __init__(self, x): + self.x = x + + def __len__(self): + return self.x + 8 + + def raising(self): + 1/0 + + def method(self, x): + return x() + self.x + + a = A(3) + + def count(): + x = 10 + # naive counting :) + result = 1 + for i in range(x): + result += 1 + return result + ''')) + return remote_side_code + """) + + def test_remote_call(self): + from distributed import socklayer + from py.__.net.greenexecnet import PopenGateway + gw = PopenGateway() + rp = socklayer.spawn_remote_side(self.remote_side_code, gw) + a = rp.get_remote("a") + assert a.method(lambda : 13) == 16 + + def test_remote_counting(self): + from distributed import socklayer + from py.__.net.greensock2 import allof + from py.__.net.greenexecnet import PopenGateway + gws = [PopenGateway() for i in range(3)] + rps = [socklayer.spawn_remote_side(self.remote_side_code, gw) + for gw in gws] + counters = [rp.get_remote("count") for rp in rps] + assert allof(*counters) == (11, 11, 11) + From cfbolz at codespeak.net Wed Mar 7 20:44:44 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 7 Mar 2007 20:44:44 +0100 (CET) Subject: [pypy-svn] r40042 - pypy/branch/rope-branch2 Message-ID: <20070307194444.1480610068@code0.codespeak.net> Author: cfbolz Date: Wed Mar 7 20:44:42 2007 New Revision: 40042 Added: pypy/branch/rope-branch2/ - copied from r40041, pypy/dist/ Log: create a new rope branch From cfbolz at codespeak.net Wed Mar 7 20:53:52 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 7 Mar 2007 20:53:52 +0100 (CET) Subject: [pypy-svn] r40045 - in pypy/branch/rope-branch2/pypy: config module/marshal/test objspace/std objspace/std/test Message-ID: <20070307195352.AF17910068@code0.codespeak.net> Author: cfbolz Date: Wed Mar 7 20:53:51 2007 New Revision: 40045 Added: pypy/branch/rope-branch2/pypy/objspace/std/rope.py - copied unchanged from r40043, pypy/branch/rope-branch/pypy/objspace/std/rope.py pypy/branch/rope-branch2/pypy/objspace/std/ropeobject.py - copied unchanged from r40043, pypy/branch/rope-branch/pypy/objspace/std/ropeobject.py pypy/branch/rope-branch2/pypy/objspace/std/test/test_rope.py - copied unchanged from r40043, pypy/branch/rope-branch/pypy/objspace/std/test/test_rope.py pypy/branch/rope-branch2/pypy/objspace/std/test/test_ropeobject.py - copied unchanged from r40043, pypy/branch/rope-branch/pypy/objspace/std/test/test_ropeobject.py Modified: pypy/branch/rope-branch2/pypy/config/pypyoption.py pypy/branch/rope-branch2/pypy/module/marshal/test/test_marshal.py pypy/branch/rope-branch2/pypy/objspace/std/marshal_impl.py pypy/branch/rope-branch2/pypy/objspace/std/model.py pypy/branch/rope-branch2/pypy/objspace/std/objspace.py pypy/branch/rope-branch2/pypy/objspace/std/stringtype.py pypy/branch/rope-branch2/pypy/objspace/std/unicodeobject.py Log: svn merge -r 39693:HEAD svn+ssh://codespeak.net/svn/pypy/branch/rope-branch Modified: pypy/branch/rope-branch2/pypy/config/pypyoption.py ============================================================================== --- pypy/branch/rope-branch2/pypy/config/pypyoption.py (original) +++ pypy/branch/rope-branch2/pypy/config/pypyoption.py Wed Mar 7 20:53:51 2007 @@ -129,6 +129,8 @@ BoolOption("withprebuiltchar", "use prebuilt single-character string objects", + + BoolOption("withrope", "use ropes as the string implementation", default=False), BoolOption("sharesmallstr", Modified: pypy/branch/rope-branch2/pypy/module/marshal/test/test_marshal.py ============================================================================== --- pypy/branch/rope-branch2/pypy/module/marshal/test/test_marshal.py (original) +++ pypy/branch/rope-branch2/pypy/module/marshal/test/test_marshal.py Wed Mar 7 20:53:51 2007 @@ -12,12 +12,12 @@ print "case: %-30s func=None" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) - assert x == case + assert x == case and type(x) is type(case) f = StringIO.StringIO() marshal.dump(case, f) f.seek(0) x = marshal.load(f) - assert x == case + assert x == case and type(x) is type(case) def test_False(self): import sys @@ -31,12 +31,12 @@ print "case: %-30s func=False" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) - assert x == case + assert x == case and type(x) is type(case) f = StringIO.StringIO() marshal.dump(case, f) f.seek(0) x = marshal.load(f) - assert x == case + assert x == case and type(x) is type(case) def test_True(self): import sys @@ -50,12 +50,12 @@ print "case: %-30s func=True" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) - assert x == case + assert x == case and type(x) is type(case) f = StringIO.StringIO() marshal.dump(case, f) f.seek(0) x = marshal.load(f) - assert x == case + assert x == case and type(x) is type(case) def test_StopIteration(self): import sys @@ -69,12 +69,12 @@ print "case: %-30s func=StopIteration" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) - assert x == case + assert x == case and type(x) is type(case) f = StringIO.StringIO() marshal.dump(case, f) f.seek(0) x = marshal.load(f) - assert x == case + assert x == case and type(x) is type(case) def test_Ellipsis(self): import sys @@ -88,12 +88,12 @@ print "case: %-30s func=Ellipsis" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) - assert x == case + assert x == case and type(x) is type(case) f = StringIO.StringIO() marshal.dump(case, f) f.seek(0) x = marshal.load(f) - assert x == case + assert x == case and type(x) is type(case) def test_42(self): import sys @@ -107,12 +107,12 @@ print "case: %-30s func=42" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) - assert x == case + assert x == case and type(x) is type(case) f = StringIO.StringIO() marshal.dump(case, f) f.seek(0) x = marshal.load(f) - assert x == case + assert x == case and type(x) is type(case) def test__minus_17(self): import sys @@ -126,12 +126,12 @@ print "case: %-30s func=_minus_17" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) - assert x == case + assert x == case and type(x) is type(case) f = StringIO.StringIO() marshal.dump(case, f) f.seek(0) x = marshal.load(f) - assert x == case + assert x == case and type(x) is type(case) def test_sys_dot_maxint(self): import sys @@ -145,12 +145,12 @@ print "case: %-30s func=sys_dot_maxint" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) - assert x == case + assert x == case and type(x) is type(case) f = StringIO.StringIO() marshal.dump(case, f) f.seek(0) x = marshal.load(f) - assert x == case + assert x == case and type(x) is type(case) def test__minus_1_dot_25(self): import sys @@ -164,12 +164,12 @@ print "case: %-30s func=_minus_1_dot_25" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) - assert x == case + assert x == case and type(x) is type(case) f = StringIO.StringIO() marshal.dump(case, f) f.seek(0) x = marshal.load(f) - assert x == case + assert x == case and type(x) is type(case) def test__minus_1_dot_25__2(self): import sys @@ -183,12 +183,12 @@ print "case: %-30s func=_minus_1_dot_25__2" % (case, ) s = marshal.dumps(case, 2); assert len(s) in (9, 17) x = marshal.loads(s) - assert x == case + assert x == case and type(x) is type(case) f = StringIO.StringIO() marshal.dump(case, f) f.seek(0) x = marshal.load(f) - assert x == case + assert x == case and type(x) is type(case) def test_2_plus_5j(self): import sys @@ -202,12 +202,12 @@ print "case: %-30s func=2_plus_5j" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) - assert x == case + assert x == case and type(x) is type(case) f = StringIO.StringIO() marshal.dump(case, f) f.seek(0) x = marshal.load(f) - assert x == case + assert x == case and type(x) is type(case) def test_2_plus_5j__2(self): import sys @@ -221,12 +221,12 @@ print "case: %-30s func=2_plus_5j__2" % (case, ) s = marshal.dumps(case, 2); assert len(s) in (9, 17) x = marshal.loads(s) - assert x == case + assert x == case and type(x) is type(case) f = StringIO.StringIO() marshal.dump(case, f) f.seek(0) x = marshal.load(f) - assert x == case + assert x == case and type(x) is type(case) def test_42L(self): import sys @@ -240,12 +240,12 @@ print "case: %-30s func=42L" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) - assert x == case + assert x == case and type(x) is type(case) f = StringIO.StringIO() marshal.dump(case, f) f.seek(0) x = marshal.load(f) - assert x == case + assert x == case and type(x) is type(case) def test__minus_1234567890123456789012345678901234567890L(self): import sys @@ -259,12 +259,12 @@ print "case: %-30s func=_minus_1234567890123456789012345678901234567890L" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) - assert x == case + assert x == case and type(x) is type(case) f = StringIO.StringIO() marshal.dump(case, f) f.seek(0) x = marshal.load(f) - assert x == case + assert x == case and type(x) is type(case) def test_hello_____not_interned(self): import sys @@ -278,12 +278,12 @@ print "case: %-30s func=hello_____not_interned" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) - assert x == case + assert x == case and type(x) is type(case) f = StringIO.StringIO() marshal.dump(case, f) f.seek(0) x = marshal.load(f) - assert x == case + assert x == case and type(x) is type(case) def test__Quote_hello_Quote_(self): import sys @@ -297,12 +297,12 @@ print "case: %-30s func=_Quote_hello_Quote_" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) - assert x == case + assert x == case and type(x) is type(case) f = StringIO.StringIO() marshal.dump(case, f) f.seek(0) x = marshal.load(f) - assert x == case + assert x == case and type(x) is type(case) def test__brace__ecarb_(self): import sys @@ -316,12 +316,12 @@ print "case: %-30s func=_brace__ecarb_" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) - assert x == case + assert x == case and type(x) is type(case) f = StringIO.StringIO() marshal.dump(case, f) f.seek(0) x = marshal.load(f) - assert x == case + assert x == case and type(x) is type(case) def test__brace_1_comma__2_ecarb_(self): import sys @@ -335,12 +335,12 @@ print "case: %-30s func=_brace_1_comma__2_ecarb_" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) - assert x == case + assert x == case and type(x) is type(case) f = StringIO.StringIO() marshal.dump(case, f) f.seek(0) x = marshal.load(f) - assert x == case + assert x == case and type(x) is type(case) def test__list__tsil_(self): import sys @@ -354,12 +354,12 @@ print "case: %-30s func=_list__tsil_" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) - assert x == case + assert x == case and type(x) is type(case) f = StringIO.StringIO() marshal.dump(case, f) f.seek(0) x = marshal.load(f) - assert x == case + assert x == case and type(x) is type(case) def test__list_3_comma__4_tsil_(self): import sys @@ -373,12 +373,12 @@ print "case: %-30s func=_list_3_comma__4_tsil_" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) - assert x == case + assert x == case and type(x) is type(case) f = StringIO.StringIO() marshal.dump(case, f) f.seek(0) x = marshal.load(f) - assert x == case + assert x == case and type(x) is type(case) def test__dict__tcid_(self): import sys @@ -392,12 +392,12 @@ print "case: %-30s func=_dict__tcid_" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) - assert x == case + assert x == case and type(x) is type(case) f = StringIO.StringIO() marshal.dump(case, f) f.seek(0) x = marshal.load(f) - assert x == case + assert x == case and type(x) is type(case) def test__dict_5_colon__6_comma__7_colon__8_tcid_(self): import sys @@ -411,12 +411,12 @@ print "case: %-30s func=_dict_5_colon__6_comma__7_colon__8_tcid_" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) - assert x == case + assert x == case and type(x) is type(case) f = StringIO.StringIO() marshal.dump(case, f) f.seek(0) x = marshal.load(f) - assert x == case + assert x == case and type(x) is type(case) def test_func_dot_func_code(self): import sys @@ -430,12 +430,12 @@ print "case: %-30s func=func_dot_func_code" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) - assert x == case + assert x == case and type(x) is type(case) f = StringIO.StringIO() marshal.dump(case, f) f.seek(0) x = marshal.load(f) - assert x == case + assert x == case and type(x) is type(case) def test_scopefunc_dot_func_code(self): import sys @@ -449,12 +449,12 @@ print "case: %-30s func=scopefunc_dot_func_code" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) - assert x == case + assert x == case and type(x) is type(case) f = StringIO.StringIO() marshal.dump(case, f) f.seek(0) x = marshal.load(f) - assert x == case + assert x == case and type(x) is type(case) def test_u_quote_hello_quote_(self): import sys @@ -468,12 +468,12 @@ print "case: %-30s func=u_quote_hello_quote_" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) - assert x == case + assert x == case and type(x) is type(case) f = StringIO.StringIO() marshal.dump(case, f) f.seek(0) x = marshal.load(f) - assert x == case + assert x == case and type(x) is type(case) def test_buffer_brace_hello_ecarb_(self): import sys @@ -487,12 +487,12 @@ print "case: %-30s func=buffer_brace_hello_ecarb_" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) - assert x == case + assert x == case and type(x) is type(case) f = StringIO.StringIO() marshal.dump(case, f) f.seek(0) x = marshal.load(f) - assert x == case + assert x == case and type(x) is type(case) def test_buffer_brace_u_quote_unicode_comma__too_quote__ecarb_(self): import sys @@ -506,12 +506,12 @@ print "case: %-30s func=buffer_brace_u_quote_unicode_comma__too_quote__ecarb_" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) - assert x == case + assert x == case and type(x) is type(case) f = StringIO.StringIO() marshal.dump(case, f) f.seek(0) x = marshal.load(f) - assert x == case + assert x == case and type(x) is type(case) def test_set_brace__ecarb_(self): import sys @@ -525,12 +525,12 @@ print "case: %-30s func=set_brace__ecarb_" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) - assert x == case + assert x == case and type(x) is type(case) f = StringIO.StringIO() marshal.dump(case, f) f.seek(0) x = marshal.load(f) - assert x == case + assert x == case and type(x) is type(case) def test_set_brace__list_1_comma__2_tsil__ecarb_(self): import sys @@ -544,12 +544,12 @@ print "case: %-30s func=set_brace__list_1_comma__2_tsil__ecarb_" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) - assert x == case + assert x == case and type(x) is type(case) f = StringIO.StringIO() marshal.dump(case, f) f.seek(0) x = marshal.load(f) - assert x == case + assert x == case and type(x) is type(case) def test_frozenset_brace__ecarb_(self): import sys @@ -563,12 +563,12 @@ print "case: %-30s func=frozenset_brace__ecarb_" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) - assert x == case + assert x == case and type(x) is type(case) f = StringIO.StringIO() marshal.dump(case, f) f.seek(0) x = marshal.load(f) - assert x == case + assert x == case and type(x) is type(case) def test_frozenset_brace__list_3_comma__4_tsil__ecarb_(self): import sys @@ -582,12 +582,12 @@ print "case: %-30s func=frozenset_brace__list_3_comma__4_tsil__ecarb_" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) - assert x == case + assert x == case and type(x) is type(case) f = StringIO.StringIO() marshal.dump(case, f) f.seek(0) x = marshal.load(f) - assert x == case + assert x == case and type(x) is type(case) class AppTestMultiDict(object): @@ -597,3 +597,8 @@ 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 + +class AppTestRope(AppTestMarshal): + def setup_class(cls): + from pypy.conftest import gettestobjspace + cls.space = gettestobjspace(**{"objspace.std.withrope": True}) Modified: pypy/branch/rope-branch2/pypy/objspace/std/marshal_impl.py ============================================================================== --- pypy/branch/rope-branch2/pypy/objspace/std/marshal_impl.py (original) +++ pypy/branch/rope-branch2/pypy/objspace/std/marshal_impl.py Wed Mar 7 20:53:51 2007 @@ -27,6 +27,7 @@ from pypy.objspace.std.dictobject import W_DictObject from pypy.objspace.std.dictmultiobject import W_DictMultiObject from pypy.objspace.std.stringobject import W_StringObject +from pypy.objspace.std.ropeobject import W_RopeObject from pypy.objspace.std.typeobject import W_TypeObject from pypy.objspace.std.longobject import W_LongObject from pypy.objspace.std.noneobject import W_NoneObject @@ -301,6 +302,8 @@ else: m.atom_str(TYPE_STRING, s) +marshal_w__Rope = marshal_w__String + def unmarshal_String(space, u, tc): return space.wrap(u.get_str()) register(TYPE_STRING, unmarshal_String) Modified: pypy/branch/rope-branch2/pypy/objspace/std/model.py ============================================================================== --- pypy/branch/rope-branch2/pypy/objspace/std/model.py (original) +++ pypy/branch/rope-branch2/pypy/objspace/std/model.py Wed Mar 7 20:53:51 2007 @@ -15,6 +15,8 @@ "withmultidict" : ["dictmultiobject.W_DictMultiObject", "dictmultiobject.W_DictMultiIterObject"], "withmultilist" : ["listmultiobject.W_ListMultiObject"], + "withrope" : ["ropeobject.W_RopeObject", + "ropeobject.W_RopeIterObject"], "withrangelist" : ["rangeobject.W_RangeListObject", "rangeobject.W_RangeIterObject"], "withtproxy" : ["proxyobject.W_TransparentList", @@ -65,6 +67,7 @@ from pypy.objspace.std import dictmultiobject from pypy.objspace.std import listmultiobject from pypy.objspace.std import stringobject + from pypy.objspace.std import ropeobject from pypy.objspace.std import strsliceobject from pypy.objspace.std import strjoinobject from pypy.objspace.std import typeobject @@ -108,10 +111,11 @@ self.typeorder[setobject.W_FrozensetObject] = [] self.typeorder[setobject.W_SetIterObject] = [] - imported_but_not_registered = { + self.imported_but_not_registered = { dictobject.W_DictObject: True, dictobject.W_DictIterObject: True, listobject.W_ListObject: True, + stringobject.W_StringObject: True, } for option, value in config.objspace.std: if option.startswith("with") and option in option_to_typename: @@ -120,7 +124,7 @@ if value: self.typeorder[implcls] = [] else: - imported_but_not_registered[implcls] = True + self.imported_but_not_registered[implcls] = True if config.objspace.std.withmultidict: del self.typeorder[dictobject.W_DictObject] @@ -128,12 +132,14 @@ if config.objspace.std.withmultilist: del self.typeorder[listobject.W_ListObject] + if config.objspace.std.withrope: + del self.typeorder[stringobject.W_StringObject] #check if we missed implementations from pypy.objspace.std.objspace import _registered_implementations for implcls in _registered_implementations: assert (implcls in self.typeorder or - implcls in imported_but_not_registered), ( + implcls in self.imported_but_not_registered), ( "please add %r in StdTypeModel.typeorder" % (implcls,)) @@ -175,9 +181,14 @@ (complexobject.W_ComplexObject, complexobject.delegate_Float2Complex), ] - self.typeorder[stringobject.W_StringObject] += [ - (unicodeobject.W_UnicodeObject, unicodeobject.delegate_String2Unicode), - ] + if not config.objspace.std.withrope: + self.typeorder[stringobject.W_StringObject] += [ + (unicodeobject.W_UnicodeObject, unicodeobject.delegate_String2Unicode), + ] + else: + self.typeorder[ropeobject.W_RopeObject] += [ + (unicodeobject.W_UnicodeObject, unicodeobject.delegate_String2Unicode), + ] if config.objspace.std.withstrslice: self.typeorder[strsliceobject.W_StringSliceObject] += [ Modified: pypy/branch/rope-branch2/pypy/objspace/std/objspace.py ============================================================================== --- pypy/branch/rope-branch2/pypy/objspace/std/objspace.py (original) +++ pypy/branch/rope-branch2/pypy/objspace/std/objspace.py Wed Mar 7 20:53:51 2007 @@ -157,6 +157,8 @@ # hack to avoid imports in the time-critical functions below for cls in self.model.typeorder: globals()[cls.__name__] = cls + for cls in self.model.imported_but_not_registered: + globals()[cls.__name__] = cls # singletons self.w_None = W_NoneObject() Modified: pypy/branch/rope-branch2/pypy/objspace/std/stringtype.py ============================================================================== --- pypy/branch/rope-branch2/pypy/objspace/std/stringtype.py (original) +++ pypy/branch/rope-branch2/pypy/objspace/std/stringtype.py Wed Mar 7 20:53:51 2007 @@ -18,6 +18,9 @@ # only share the empty string if len(s) == 0: return W_StringObject.EMPTY + if self.config.objspace.std.withrope: + from pypy.objspace.std.ropeobject import rope, W_RopeObject + return W_RopeObject(rope.LiteralStringNode(s)) return W_StringObject(s) def wrapchar(space, c): @@ -30,6 +33,7 @@ def sliced(space, s, start, stop): assert start >= 0 assert stop >= 0 + assert not space.config.objspace.std.withrope if space.config.objspace.std.withstrslice: from pypy.objspace.std.strsliceobject import W_StringSliceObject # XXX heuristic, should be improved! @@ -38,6 +42,7 @@ return wrapstr(space, s[start:stop]) def joined(space, strlist): + assert not space.config.objspace.std.withrope if space.config.objspace.std.withstrjoin: from pypy.objspace.std.strjoinobject import W_StringJoinObject return W_StringJoinObject(strlist) @@ -254,9 +259,15 @@ if space.is_w(w_stringtype, space.w_str): return w_obj # XXX might be reworked when space.str() typechecks value = space.str_w(w_obj) - w_obj = space.allocate_instance(W_StringObject, w_stringtype) - W_StringObject.__init__(w_obj, value) - return w_obj + if space.config.objspace.std.withrope: + from pypy.objspace.std.ropeobject import rope, W_RopeObject + w_obj = space.allocate_instance(W_RopeObject, w_stringtype) + W_RopeObject.__init__(w_obj, rope.LiteralStringNode(value)) + return w_obj + else: + w_obj = space.allocate_instance(W_StringObject, w_stringtype) + W_StringObject.__init__(w_obj, value) + return w_obj # ____________________________________________________________ Modified: pypy/branch/rope-branch2/pypy/objspace/std/unicodeobject.py ============================================================================== --- pypy/branch/rope-branch2/pypy/objspace/std/unicodeobject.py (original) +++ pypy/branch/rope-branch2/pypy/objspace/std/unicodeobject.py Wed Mar 7 20:53:51 2007 @@ -1,6 +1,7 @@ from pypy.objspace.std.objspace import * from pypy.interpreter import gateway from pypy.objspace.std.stringobject import W_StringObject +from pypy.objspace.std.ropeobject import W_RopeObject from pypy.objspace.std.noneobject import W_NoneObject from pypy.objspace.std.sliceobject import W_SliceObject from pypy.objspace.std.tupleobject import W_TupleObject @@ -101,11 +102,17 @@ def add__String_Unicode(space, w_left, w_right): return space.add(space.call_function(space.w_unicode, w_left) , w_right) +add__Rope_Unicode = add__String_Unicode + def add__Unicode_String(space, w_left, w_right): return space.add(w_left, space.call_function(space.w_unicode, w_right)) +add__Unicode_Rope = add__Unicode_String + def contains__String_Unicode(space, w_container, w_item): return space.contains(space.call_function(space.w_unicode, w_container), w_item ) +contains__Rope_Unicode = contains__String_Unicode + def _find(self, sub, start, end): if len(sub) == 0: @@ -188,15 +195,25 @@ def hash__Unicode(space, w_uni): if w_uni.w_hash is None: + # hrmpf chars = w_uni._value if len(chars) == 0: return space.wrap(0) - x = ord(chars[0]) << 7 - for c in chars: - x = intmask((1000003 * x) ^ ord(c)) - h = intmask(x ^ len(chars)) - if h == -1: - h = -2 + if space.config.objspace.std.withrope: + x = 0 + for c in chars: + x = intmask((1000003 * x) + ord(c)) + x <<= 1 + x ^= len(chars) + x ^= ord(chars[0]) + h = intmask(x) + else: + x = ord(chars[0]) << 7 + for c in chars: + x = intmask((1000003 * x) ^ ord(c)) + h = intmask(x ^ len(chars)) + if h == -1: + h = -2 w_uni.w_hash = space.wrap(h) return w_uni.w_hash @@ -394,6 +411,7 @@ def unicode_strip__Unicode_String(space, w_self, w_chars): return space.call_method(w_self, 'strip', space.call_function(space.w_unicode, w_chars)) +unicode_strip__Unicode_Rope = unicode_strip__Unicode_String def unicode_lstrip__Unicode_None(space, w_self, w_chars): return _strip_none(space, w_self, 1, 0) @@ -403,6 +421,8 @@ return space.call_method(w_self, 'lstrip', space.call_function(space.w_unicode, w_chars)) +unicode_lstrip__Unicode_Rope = unicode_lstrip__Unicode_String + def unicode_rstrip__Unicode_None(space, w_self, w_chars): return _strip_none(space, w_self, 0, 1) def unicode_rstrip__Unicode_Unicode(space, w_self, w_chars): @@ -411,6 +431,8 @@ return space.call_method(w_self, 'rstrip', space.call_function(space.w_unicode, w_chars)) +unicode_rstrip__Unicode_Rope = unicode_rstrip__Unicode_String + def unicode_capitalize__Unicode(space, w_self): input = w_self._value if len(input) == 0: @@ -1034,41 +1056,49 @@ import stringtype W_UnicodeObject = W_UnicodeObject from pypy.objspace.std.stringobject import W_StringObject + from pypy.objspace.std.ropeobject import W_RopeObject def str_strip__String_Unicode(space, w_self, w_chars): return space.call_method(space.call_function(space.w_unicode, w_self), 'strip', w_chars) + str_strip__Rope_Unicode = str_strip__String_Unicode def str_lstrip__String_Unicode(space, w_self, w_chars): return space.call_method(space.call_function(space.w_unicode, w_self), 'lstrip', w_chars) + str_lstrip__Rope_Unicode = str_lstrip__String_Unicode def str_rstrip__String_Unicode(space, w_self, w_chars): return space.call_method(space.call_function(space.w_unicode, w_self), 'rstrip', w_chars) + str_rstrip__Rope_Unicode = str_rstrip__String_Unicode def str_count__String_Unicode_ANY_ANY(space, w_self, w_substr, w_start, w_end): return space.call_method(space.call_function(space.w_unicode, w_self), 'count', w_substr, w_start, w_end) + str_count__Rope_Unicode_ANY_ANY = str_count__String_Unicode_ANY_ANY def str_find__String_Unicode_ANY_ANY(space, w_self, w_substr, w_start, w_end): return space.call_method(space.call_function(space.w_unicode, w_self), 'find', w_substr, w_start, w_end) + str_find__Rope_Unicode_ANY_ANY = str_find__String_Unicode_ANY_ANY def str_rfind__String_Unicode_ANY_ANY(space, w_self, w_substr, w_start, w_end): return space.call_method(space.call_function(space.w_unicode, w_self), 'rfind', w_substr, w_start, w_end) + str_rfind__Rope_Unicode_ANY_ANY = str_rfind__String_Unicode_ANY_ANY def str_index__String_Unicode_ANY_ANY(space, w_self, w_substr, w_start, w_end): return space.call_method(space.call_function(space.w_unicode, w_self), 'index', w_substr, w_start, w_end) + str_index__Rope_Unicode_ANY_ANY = str_index__String_Unicode_ANY_ANY def str_rindex__String_Unicode_ANY_ANY(space, w_self, w_substr, w_start, w_end): return space.call_method(space.call_function(space.w_unicode, w_self), 'rindex', w_substr, w_start, w_end) - + str_rindex__Rope_Unicode_ANY_ANY = str_rindex__String_Unicode_ANY_ANY def str_replace__String_Unicode_Unicode_ANY(space, w_self, w_old, w_new, w_maxsplit): return space.call_method(space.call_function(space.w_unicode, w_self), 'replace', w_old, w_new, w_maxsplit) - + str_replace__Rope_Unicode_Unicode_ANY = str_replace__String_Unicode_Unicode_ANY def str_split__String_Unicode_ANY(space, w_self, w_delim, w_maxsplit): return space.call_method(space.call_function(space.w_unicode, w_self), 'split', w_delim, w_maxsplit) - + str_split__Rope_Unicode_ANY = str_split__String_Unicode_ANY def str_rsplit__String_Unicode_ANY(space, w_self, w_delim, w_maxsplit): return space.call_method(space.call_function(space.w_unicode, w_self), 'rsplit', w_delim, w_maxsplit) - + str_rsplit__Rope_Unicode_ANY = str_rsplit__String_Unicode_ANY register_all(vars(), stringtype) From cfbolz at codespeak.net Wed Mar 7 20:59:26 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 7 Mar 2007 20:59:26 +0100 (CET) Subject: [pypy-svn] r40046 - in pypy/branch/rope-branch2/pypy: config objspace/std Message-ID: <20070307195926.514C710068@code0.codespeak.net> Author: cfbolz Date: Wed Mar 7 20:59:25 2007 New Revision: 40046 Modified: pypy/branch/rope-branch2/pypy/config/pypyoption.py pypy/branch/rope-branch2/pypy/objspace/std/ropeobject.py pypy/branch/rope-branch2/pypy/objspace/std/stringtype.py Log: fix two embarassing problems, add georg's patch (thanks!) Modified: pypy/branch/rope-branch2/pypy/config/pypyoption.py ============================================================================== --- pypy/branch/rope-branch2/pypy/config/pypyoption.py (original) +++ pypy/branch/rope-branch2/pypy/config/pypyoption.py Wed Mar 7 20:59:25 2007 @@ -128,7 +128,7 @@ default=False), BoolOption("withprebuiltchar", - "use prebuilt single-character string objects", + "use prebuilt single-character string objects"), BoolOption("withrope", "use ropes as the string implementation", default=False), Modified: pypy/branch/rope-branch2/pypy/objspace/std/ropeobject.py ============================================================================== --- pypy/branch/rope-branch2/pypy/objspace/std/ropeobject.py (original) +++ pypy/branch/rope-branch2/pypy/objspace/std/ropeobject.py Wed Mar 7 20:59:25 2007 @@ -413,13 +413,10 @@ def _convert_idx_params(space, w_self, w_sub, w_start, w_end): self = w_self._node sub = w_sub._node - w_len = space.wrap(self.length()) - w_start = slicetype.adapt_bound(space, w_start, w_len) - w_end = slicetype.adapt_bound(space, w_end, w_len) - start = space.int_w(w_start) - end = space.int_w(w_end) + start = slicetype.adapt_bound(space, self.length(), w_start) assert start >= 0 + end = slicetype.adapt_bound(space, self.length(), w_end) assert end >= 0 return (self, sub, start, end) @@ -834,7 +831,12 @@ return space.newbool(rope.compare(n1, n2) >= 0) def getitem__Rope_ANY(space, w_str, w_index): - ival = space.int_w(w_index) + if not space.lookup(w_index, '__index__'): + raise OperationError( + space.w_TypeError, + space.wrap("string indices must be integers, not %s" % + space.type(w_index).getname(space, '?'))) + ival = space.getindex_w(w_index, space.w_IndexError) node = w_str._node slen = node.length() if ival < 0: @@ -855,7 +857,7 @@ def mul_string_times(space, w_str, w_times): try: - mul = space.int_w(w_times) + mul = space.getindex_w(w_times, space.w_OverflowError) except OperationError, e: if e.match(space, space.w_TypeError): raise FailedToImplement Modified: pypy/branch/rope-branch2/pypy/objspace/std/stringtype.py ============================================================================== --- pypy/branch/rope-branch2/pypy/objspace/std/stringtype.py (original) +++ pypy/branch/rope-branch2/pypy/objspace/std/stringtype.py Wed Mar 7 20:59:25 2007 @@ -18,7 +18,7 @@ # only share the empty string if len(s) == 0: return W_StringObject.EMPTY - if self.config.objspace.std.withrope: + if space.config.objspace.std.withrope: from pypy.objspace.std.ropeobject import rope, W_RopeObject return W_RopeObject(rope.LiteralStringNode(s)) return W_StringObject(s) From cfbolz at codespeak.net Wed Mar 7 21:05:06 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 7 Mar 2007 21:05:06 +0100 (CET) Subject: [pypy-svn] r40047 - pypy/branch/rope-branch2/pypy/objspace/std Message-ID: <20070307200506.429A510063@code0.codespeak.net> Author: cfbolz Date: Wed Mar 7 21:05:04 2007 New Revision: 40047 Modified: pypy/branch/rope-branch2/pypy/objspace/std/ropeobject.py Log: adapt to the new interface of adapt_bound Modified: pypy/branch/rope-branch2/pypy/objspace/std/ropeobject.py ============================================================================== --- pypy/branch/rope-branch2/pypy/objspace/std/ropeobject.py (original) +++ pypy/branch/rope-branch2/pypy/objspace/std/ropeobject.py Wed Mar 7 21:05:04 2007 @@ -602,10 +602,8 @@ length = selfnode.length() argnode = w_arg._node - w_start = slicetype.adapt_bound(space, w_start, space.wrap(length)) - w_end = slicetype.adapt_bound(space, w_end, space.wrap(length)) - u_start = space.int_w(w_start) - u_end = space.int_w(w_end) + u_start = slicetype.adapt_bound(space, length, w_start) + u_end = slicetype.adapt_bound(space, length, w_end) assert u_start >= 0 assert u_end >= 0 iter = rope.FindIterator(selfnode, argnode, u_start, u_end) From cfbolz at codespeak.net Wed Mar 7 21:16:21 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 7 Mar 2007 21:16:21 +0100 (CET) Subject: [pypy-svn] r40048 - pypy/branch/rope-branch Message-ID: <20070307201621.CFA3010063@code0.codespeak.net> Author: cfbolz Date: Wed Mar 7 21:16:19 2007 New Revision: 40048 Removed: pypy/branch/rope-branch/ Log: remove merged branch From cfbolz at codespeak.net Wed Mar 7 21:21:48 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 7 Mar 2007 21:21:48 +0100 (CET) Subject: [pypy-svn] r40049 - pypy/branch/rope-branch2/pypy/objspace/std Message-ID: <20070307202148.8CBD610063@code0.codespeak.net> Author: cfbolz Date: Wed Mar 7 21:21:47 2007 New Revision: 40049 Modified: pypy/branch/rope-branch2/pypy/objspace/std/ropeobject.py Log: implement partition and rpartition (the latter poorly) Modified: pypy/branch/rope-branch2/pypy/objspace/std/ropeobject.py ============================================================================== --- pypy/branch/rope-branch2/pypy/objspace/std/ropeobject.py (original) +++ pypy/branch/rope-branch2/pypy/objspace/std/ropeobject.py Wed Mar 7 21:21:47 2007 @@ -440,6 +440,42 @@ res = self.rfind(sub, start, end) return wrapint(space, res) +def str_partition__Rope_Rope(space, w_self, w_sub): + self = w_self._node + sub = w_sub._node + if not sub.length(): + raise OperationError(space.w_ValueError, + space.wrap("empty separator")) + pos = rope.find(self, sub) + if pos == -1: + return space.newtuple([w_self, W_RopeObject.empty, + W_RopeObject.empty]) + else: + return space.newtuple( + [W_RopeObject(rope.getslice_one(self, 0, pos)), + w_sub, + W_RopeObject(rope.getslice_one(self, pos + sub.length(), + self.length()))]) + +def str_rpartition__Rope_Rope(space, w_self, w_sub): + # XXX works but flattens + self = w_self._node + sub = w_sub._node + if not sub.length(): + raise OperationError(space.w_ValueError, + space.wrap("empty separator")) + flattened_self = self.flatten() + flattened_sub = sub.flatten() + pos = flattened_self.rfind(flattened_sub) + if pos == -1: + return space.newtuple([W_RopeObject.empty, W_RopeObject.empty, w_self]) + else: + return space.newtuple( + [W_RopeObject(rope.getslice_one(self, 0, pos)), + w_sub, + W_RopeObject(rope.getslice_one(self, pos + sub.length(), + self.length()))]) + def str_index__Rope_Rope_ANY_ANY(space, w_self, w_sub, w_start, w_end): (self, sub, start, end) = _convert_idx_params(space, w_self, w_sub, w_start, w_end) From cfbolz at codespeak.net Wed Mar 7 21:41:08 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 7 Mar 2007 21:41:08 +0100 (CET) Subject: [pypy-svn] r40050 - pypy/branch/rope-branch2/pypy/objspace/std Message-ID: <20070307204108.73D701006E@code0.codespeak.net> Author: cfbolz Date: Wed Mar 7 21:41:07 2007 New Revision: 40050 Modified: pypy/branch/rope-branch2/pypy/objspace/std/ropeobject.py Log: implement startswith and endswith with tuple arguments Modified: pypy/branch/rope-branch2/pypy/objspace/std/ropeobject.py ============================================================================== --- pypy/branch/rope-branch2/pypy/objspace/std/ropeobject.py (original) +++ pypy/branch/rope-branch2/pypy/objspace/std/ropeobject.py Wed Mar 7 21:41:07 2007 @@ -31,6 +31,11 @@ W_RopeObject.empty = W_RopeObject(rope.LiteralStringNode("")) +def rope_w(space, w_str): + if isinstance(w_str, W_RopeObject): + return w_str._node + return rope.LiteralStringNode(space.str_w(w_str)) + registerimplementation(W_RopeObject) class W_RopeIterObject(W_Object): @@ -347,7 +352,6 @@ def str_join__Rope_ANY(space, w_self, w_list): list_w = space.unpackiterable(w_list) - str_w = space.str_w if list_w: self = w_self._node l = [] @@ -652,43 +656,69 @@ i += 1 return wrapint(space, i) -def str_endswith__Rope_Rope_ANY_ANY(space, w_self, w_suffix, w_start, w_end): - (self, suffix, start, end) = _convert_idx_params(space, w_self, - w_suffix, w_start, w_end) +def ropeendswith(self, suffix, start, end): if suffix.length() == 0: - return space.w_True + return True if self.length() == 0: - return space.w_False + return False begin = end - suffix.length() if begin < start: - return space.w_False + return False iter1 = rope.SeekableCharIterator(self) iter1.seekforward(begin) iter2 = rope.CharIterator(suffix) for i in range(suffix.length()): if iter1.next() != iter2.next(): - return space.w_False - return space.w_True - -def str_startswith__Rope_Rope_ANY_ANY(space, w_self, w_prefix, w_start, w_end): - (self, prefix, start, end) = _convert_idx_params(space, w_self, - w_prefix, w_start, w_end) + return False + return True + + +def str_endswith__Rope_Rope_ANY_ANY(space, w_self, w_suffix, w_start, w_end): + (self, suffix, start, end) = _convert_idx_params(space, w_self, + w_suffix, w_start, w_end) + return space.newbool(ropeendswith(self, suffix, start, end)) + +def str_endswith__Rope_Tuple_ANY_ANY(space, w_self, w_suffixes, w_start, w_end): + (self, _, start, end) = _convert_idx_params(space, w_self, + space.wrap(''), w_start, w_end) + for w_suffix in space.unpacktuple(w_suffixes): + suffix = rope_w(space, w_suffix) + if ropeendswith(self, suffix, start, end): + return space.w_True + return space.w_False + +def ropestartswith(self, prefix, start, end): if prefix.length() == 0: - return space.w_True + return True if self.length() == 0: - return space.w_False + return False stop = start + prefix.length() if stop > end: - return space.w_False + return False iter1 = rope.SeekableCharIterator(self) iter1.seekforward(start) iter2 = rope.CharIterator(prefix) for i in range(prefix.length()): if iter1.next() != iter2.next(): - return space.w_False - return space.w_True - + return False + return True + + +def str_startswith__Rope_Rope_ANY_ANY(space, w_self, w_prefix, w_start, w_end): + (self, prefix, start, end) = _convert_idx_params(space, w_self, + w_prefix, w_start, w_end) + return space.newbool(ropestartswith(self, prefix, start, end)) +def str_startswith__Rope_Tuple_ANY_ANY(space, w_self, w_prefixes, w_start, w_end): + (self, _, start, end) = _convert_idx_params(space, w_self, space.wrap(''), + w_start, w_end) + for w_prefix in space.unpacktuple(w_prefixes): + prefix = rope_w(space, w_prefix) + if ropestartswith(self, prefix, start, end): + return space.w_True + return space.w_False + + def _tabindent(node, tabsize): "calculates distance after the token to the next tabstop" # XXX implement reverse char iterator From cfbolz at codespeak.net Wed Mar 7 21:44:01 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 7 Mar 2007 21:44:01 +0100 (CET) Subject: [pypy-svn] r40051 - pypy/branch/rope-branch2/pypy/objspace/std Message-ID: <20070307204401.8B4E21006E@code0.codespeak.net> Author: cfbolz Date: Wed Mar 7 21:43:59 2007 New Revision: 40051 Modified: pypy/branch/rope-branch2/pypy/objspace/std/ropeobject.py Log: capitalize the prebuilt empty rope to be consistant with stringobject.py Modified: pypy/branch/rope-branch2/pypy/objspace/std/ropeobject.py ============================================================================== --- pypy/branch/rope-branch2/pypy/objspace/std/ropeobject.py (original) +++ pypy/branch/rope-branch2/pypy/objspace/std/ropeobject.py Wed Mar 7 21:43:59 2007 @@ -29,7 +29,7 @@ return w_self return W_RopeObject(w_self._node) -W_RopeObject.empty = W_RopeObject(rope.LiteralStringNode("")) +W_RopeObject.EMPTY = W_RopeObject(rope.LiteralStringNode("")) def rope_w(space, w_str): if isinstance(w_str, W_RopeObject): @@ -211,7 +211,7 @@ else: buffer[i] = ch else: - return W_RopeObject.empty + return W_RopeObject.EMPTY return W_RopeObject(rope.rope_from_charlist(buffer)) @@ -377,7 +377,7 @@ raise OperationError(space.w_OverflowError, space.wrap("string too long")) else: - return W_RopeObject.empty + return W_RopeObject.EMPTY def str_rjust__Rope_ANY_ANY(space, w_self, w_arg, w_fillchar): u_arg = space.int_w(w_arg) @@ -452,8 +452,8 @@ space.wrap("empty separator")) pos = rope.find(self, sub) if pos == -1: - return space.newtuple([w_self, W_RopeObject.empty, - W_RopeObject.empty]) + return space.newtuple([w_self, W_RopeObject.EMPTY, + W_RopeObject.EMPTY]) else: return space.newtuple( [W_RopeObject(rope.getslice_one(self, 0, pos)), @@ -472,7 +472,7 @@ flattened_sub = sub.flatten() pos = flattened_self.rfind(flattened_sub) if pos == -1: - return space.newtuple([W_RopeObject.empty, W_RopeObject.empty, w_self]) + return space.newtuple([W_RopeObject.EMPTY, W_RopeObject.EMPTY, w_self]) else: return space.newtuple( [W_RopeObject(rope.getslice_one(self, 0, pos)), @@ -751,7 +751,7 @@ node = w_self._node length = node.length() if length == 0: - return W_RopeObject.empty + return W_RopeObject.EMPTY tabsize = space.int_w(w_tabsize) expanded = [] @@ -916,7 +916,7 @@ length = node.length() start, stop, step, sl = w_slice.indices4(space, length) if sl == 0: - return W_RopeObject.empty + return W_RopeObject.EMPTY return W_RopeObject(rope.getslice(node, start, stop, step, sl)) def mul_string_times(space, w_str, w_times): @@ -927,7 +927,7 @@ raise FailedToImplement raise if mul <= 0: - return W_RopeObject.empty + return W_RopeObject.EMPTY node = w_str._node length = node.length() # try: From cfbolz at codespeak.net Wed Mar 7 22:07:46 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 7 Mar 2007 22:07:46 +0100 (CET) Subject: [pypy-svn] r40052 - in pypy/branch/rope-branch2/pypy/objspace/std: . test Message-ID: <20070307210746.EE09510069@code0.codespeak.net> Author: cfbolz Date: Wed Mar 7 22:07:45 2007 New Revision: 40052 Modified: pypy/branch/rope-branch2/pypy/objspace/std/ropeobject.py pypy/branch/rope-branch2/pypy/objspace/std/stringtype.py pypy/branch/rope-branch2/pypy/objspace/std/test/test_ropeobject.py Log: make ropes work with the prebuilt string options Modified: pypy/branch/rope-branch2/pypy/objspace/std/ropeobject.py ============================================================================== --- pypy/branch/rope-branch2/pypy/objspace/std/ropeobject.py (original) +++ pypy/branch/rope-branch2/pypy/objspace/std/ropeobject.py Wed Mar 7 22:07:45 2007 @@ -8,6 +8,7 @@ from pypy.objspace.std.noneobject import W_NoneObject from pypy.objspace.std.tupleobject import W_TupleObject from pypy.rlib.rarithmetic import ovfcheck +from pypy.objspace.std.stringtype import wrapchar from pypy.objspace.std import rope @@ -30,6 +31,10 @@ return W_RopeObject(w_self._node) W_RopeObject.EMPTY = W_RopeObject(rope.LiteralStringNode("")) +W_RopeObject.PREBUILT = [W_RopeObject(rope.LiteralStringNode(chr(i))) + for i in range(256)] +del i + def rope_w(space, w_str): if isinstance(w_str, W_RopeObject): @@ -48,9 +53,6 @@ registerimplementation(W_RopeIterObject) -def wrap_rpystr(s): - return W_RopeObject(rope.LiteralStringNode(s)) - def _is_generic(space, w_self, fun): l = w_self._node.length() if l == 0: @@ -319,7 +321,7 @@ # the word is value[j+1:i+1] j1 = j + 1 assert j1 >= 0 - res_w.append(wrap_rpystr(value[j1:i+1])) + res_w.append(space.wrap(value[j1:i+1])) # continue to look from the character before the space before the word i = j - 1 @@ -342,11 +344,11 @@ next = value.rfind(by, 0, end) if next < 0: break - res_w.append(wrap_rpystr(value[next+bylen: end])) + res_w.append(space.wrap(value[next+bylen: end])) end = next maxsplit -= 1 # NB. if it's already < 0, it stays < 0 - res_w.append(wrap_rpystr(value[:end])) + res_w.append(space.wrap(value[:end])) res_w.reverse() return space.newlist(res_w) @@ -909,7 +911,7 @@ exc = space.call_function(space.w_IndexError, space.wrap("string index out of range")) raise OperationError(space.w_IndexError, exc) - return wrap_rpystr(node.getitem(ival)) + return wrapchar(space, node.getitem(ival)) def getitem__Rope_Slice(space, w_str, w_slice): node = w_str._node @@ -1097,7 +1099,7 @@ raise OperationError(space.w_StopIteration, space.w_None) try: char = w_ropeiter.char_iter.next() - w_item = wrap_rpystr(char) + w_item = space.wrap(char) except StopIteration: w_ropeiter.node = None w_ropeiter.char_iter = None Modified: pypy/branch/rope-branch2/pypy/objspace/std/stringtype.py ============================================================================== --- pypy/branch/rope-branch2/pypy/objspace/std/stringtype.py (original) +++ pypy/branch/rope-branch2/pypy/objspace/std/stringtype.py Wed Mar 7 22:07:45 2007 @@ -5,11 +5,14 @@ def wrapstr(space, s): from pypy.objspace.std.stringobject import W_StringObject + from pypy.objspace.std.ropeobject import rope, W_RopeObject if space.config.objspace.std.sharesmallstr: if space.config.objspace.std.withprebuiltchar: # share characters and empty string if len(s) <= 1: if len(s) == 0: + if space.config.objspace.std.withrope: + return W_RopeObject.EMPTY return W_StringObject.EMPTY else: s = s[0] # annotator hint: a single char @@ -17,17 +20,23 @@ else: # only share the empty string if len(s) == 0: + if space.config.objspace.std.withrope: + return W_RopeObject.EMPTY return W_StringObject.EMPTY if space.config.objspace.std.withrope: - from pypy.objspace.std.ropeobject import rope, W_RopeObject return W_RopeObject(rope.LiteralStringNode(s)) return W_StringObject(s) def wrapchar(space, c): from pypy.objspace.std.stringobject import W_StringObject + from pypy.objspace.std.ropeobject import rope, W_RopeObject if space.config.objspace.std.withprebuiltchar: + if space.config.objspace.std.withrope: + return W_RopeObject.PREBUILT[ord(c)] return W_StringObject.PREBUILT[ord(c)] else: + if space.config.objspace.std.withrope: + return W_RopeObject(rope.LiteralStringNode(c)) return W_StringObject(c) def sliced(space, s, start, stop): Modified: pypy/branch/rope-branch2/pypy/objspace/std/test/test_ropeobject.py ============================================================================== --- pypy/branch/rope-branch2/pypy/objspace/std/test/test_ropeobject.py (original) +++ pypy/branch/rope-branch2/pypy/objspace/std/test/test_ropeobject.py Wed Mar 7 22:07:45 2007 @@ -72,3 +72,33 @@ def setup_class(cls): cls.space = gettestobjspace(**{"objspace.std.withrope": True}) + +class AppTestPrebuilt(test_stringobject.AppTestStringObject): + def setup_class(cls): + cls.space = gettestobjspace(**{"objspace.std.withrope": True, + "objspace.std.withprebuiltchar": True}) + + def test_hash(self): + # does not make sense, since our hash is different than CPython's + pass + + +class AppTestShare(test_stringobject.AppTestStringObject): + def setup_class(cls): + cls.space = gettestobjspace(**{"objspace.std.withrope": True, + "objspace.std.sharesmallstr": True}) + + def test_hash(self): + # does not make sense, since our hash is different than CPython's + pass + +class AppTestPrebuiltShare(test_stringobject.AppTestStringObject): + def setup_class(cls): + cls.space = gettestobjspace(**{"objspace.std.withrope": True, + "objspace.std.withprebuiltchar": True, + "objspace.std.sharesmallstr": True}) + + def test_hash(self): + # does not make sense, since our hash is different than CPython's + pass + From cfbolz at codespeak.net Wed Mar 7 22:13:40 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 7 Mar 2007 22:13:40 +0100 (CET) Subject: [pypy-svn] r40053 - in pypy/branch/rope-branch2/pypy: config objspace/std/test Message-ID: <20070307211340.29C961006E@code0.codespeak.net> Author: cfbolz Date: Wed Mar 7 22:13:39 2007 New Revision: 40053 Modified: pypy/branch/rope-branch2/pypy/config/pypyoption.py pypy/branch/rope-branch2/pypy/objspace/std/test/test_ropeobject.py Log: suggest the prebuilt string options when using ropes, since they have an even heavier allocation penalty Modified: pypy/branch/rope-branch2/pypy/config/pypyoption.py ============================================================================== --- pypy/branch/rope-branch2/pypy/config/pypyoption.py (original) +++ pypy/branch/rope-branch2/pypy/config/pypyoption.py Wed Mar 7 22:13:39 2007 @@ -130,14 +130,16 @@ BoolOption("withprebuiltchar", "use prebuilt single-character string objects"), - BoolOption("withrope", "use ropes as the string implementation", - default=False), - BoolOption("sharesmallstr", "always reuse the prebuilt string objects " "(the empty string and potentially single-char strings)", default=False), + BoolOption("withrope", "use ropes as the string implementation", + default=False, + suggests=[("objspace.std.withprebuiltchar", True), + ("objspace.std.sharesmallstr", True)]), + BoolOption("withmultidict", "use dictionaries optimized for flexibility", default=False), Modified: pypy/branch/rope-branch2/pypy/objspace/std/test/test_ropeobject.py ============================================================================== --- pypy/branch/rope-branch2/pypy/objspace/std/test/test_ropeobject.py (original) +++ pypy/branch/rope-branch2/pypy/objspace/std/test/test_ropeobject.py Wed Mar 7 22:13:39 2007 @@ -73,30 +73,30 @@ def setup_class(cls): cls.space = gettestobjspace(**{"objspace.std.withrope": True}) -class AppTestPrebuilt(test_stringobject.AppTestStringObject): +class AppTestPrebuilt(AppTestRopeObject): def setup_class(cls): cls.space = gettestobjspace(**{"objspace.std.withrope": True, - "objspace.std.withprebuiltchar": True}) + "objspace.std.withprebuiltchar": False}) def test_hash(self): # does not make sense, since our hash is different than CPython's pass -class AppTestShare(test_stringobject.AppTestStringObject): +class AppTestShare(AppTestRopeObject): def setup_class(cls): cls.space = gettestobjspace(**{"objspace.std.withrope": True, - "objspace.std.sharesmallstr": True}) + "objspace.std.sharesmallstr": False}) def test_hash(self): # does not make sense, since our hash is different than CPython's pass -class AppTestPrebuiltShare(test_stringobject.AppTestStringObject): +class AppTestPrebuiltShare(AppTestRopeObject): def setup_class(cls): cls.space = gettestobjspace(**{"objspace.std.withrope": True, - "objspace.std.withprebuiltchar": True, - "objspace.std.sharesmallstr": True}) + "objspace.std.withprebuiltchar": False, + "objspace.std.sharesmallstr": False}) def test_hash(self): # does not make sense, since our hash is different than CPython's From santagada at codespeak.net Thu Mar 8 02:26:59 2007 From: santagada at codespeak.net (santagada at codespeak.net) Date: Thu, 8 Mar 2007 02:26:59 +0100 (CET) Subject: [pypy-svn] r40054 - pypy/dist/pypy/lang/js Message-ID: <20070308012659.BFDA910063@code0.codespeak.net> Author: santagada Date: Thu Mar 8 02:26:57 2007 New Revision: 40054 Modified: pypy/dist/pypy/lang/js/jsparser.py Log: some cleanups Modified: pypy/dist/pypy/lang/js/jsparser.py ============================================================================== --- pypy/dist/pypy/lang/js/jsparser.py (original) +++ pypy/dist/pypy/lang/js/jsparser.py Thu Mar 8 02:26:57 2007 @@ -21,6 +21,7 @@ jsdefspath = path.join(jsdir, "jsdefs.js") jsparsepath = path.join(jsdir, "jsparse.js") fname = path.join(path.dirname(__file__) ,"tobeparsed.js") +command = 'js -f %s -f %s -f %s'%(jsdefspath, jsparsepath, fname) def read_js_output(code_string): tmp = [] @@ -41,14 +42,8 @@ print code_string print "------ put:" print stripped_code - f_jsdefs = open_file_as_stream(jsdefspath) - jsdefs = f_jsdefs.readall() - f_jsdefs.close() - f_jsparse = open_file_as_stream(jsparsepath) - jsparse = f_jsparse.readall() - f_jsparse.close() f = open_file_as_stream(fname, 'w') - f.write(jsdefs+jsparse+"print(parse('%s'));\n" % stripped_code) + f.write("print(parse('%s'));\n" % stripped_code) f.close() c2pread, c2pwrite = os.pipe() if os.fork() == 0: @@ -59,7 +54,7 @@ os.close(i) except OSError: pass - cmd = ['/bin/sh', '-c', 'js -f '+fname] + cmd = ['/bin/sh', '-c', command] os.execv(cmd[0], cmd) os.close(c2pwrite) f = fdopen_as_stream(c2pread, 'r', 0) From mwh at codespeak.net Thu Mar 8 11:35:18 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Thu, 8 Mar 2007 11:35:18 +0100 (CET) Subject: [pypy-svn] r40057 - pypy/dist/pypy/translator/goal Message-ID: <20070308103518.5AB241006E@code0.codespeak.net> Author: mwh Date: Thu Mar 8 11:35:17 2007 New Revision: 40057 Modified: pypy/dist/pypy/translator/goal/bench-cronjob.py Log: include uname -a in the benchmark.html Modified: pypy/dist/pypy/translator/goal/bench-cronjob.py ============================================================================== --- pypy/dist/pypy/translator/goal/bench-cronjob.py (original) +++ pypy/dist/pypy/translator/goal/bench-cronjob.py Thu Mar 8 11:35:17 2007 @@ -151,6 +151,7 @@ def benchmark(): os.chdir(homedir + '/projects/pypy-dist/pypy/translator/goal') + uname = os.popen('uname -a', 'r').read() startload = get_load() result = run('/usr/local/bin/withlock /tmp/cpu_cycles_lock /usr/local/bin/python bench-unix.py 2>&1 | tee benchmark.txt' % locals()) endload = get_load() @@ -158,6 +159,7 @@ f = open('benchmark.html', 'w') print >> f, "" print >> f, "
"
+        print >> f, "uname -a:", uname
         print >> f, "Benchmark started:", startload
         print >> f, "            ended:", endload
         print >> f


From guido at codespeak.net  Thu Mar  8 11:50:32 2007
From: guido at codespeak.net (guido at codespeak.net)
Date: Thu,  8 Mar 2007 11:50:32 +0100 (CET)
Subject: [pypy-svn] r40058 - pypy/dist/pypy/doc
Message-ID: <20070308105032.0C7BC10069@code0.codespeak.net>

Author: guido
Date: Thu Mar  8 11:50:31 2007
New Revision: 40058

Modified:
   pypy/dist/pypy/doc/distribution.txt
Log:
Reformatting, rewording, typos.


Modified: pypy/dist/pypy/doc/distribution.txt
==============================================================================
--- pypy/dist/pypy/doc/distribution.txt	(original)
+++ pypy/dist/pypy/doc/distribution.txt	Thu Mar  8 11:50:31 2007
@@ -5,62 +5,62 @@
 
 Stuff & things. mostly
 
-Distributed library is an attempt to build a transparent, lazy
+The 'distributed' library is an attempt to provide transparent, lazy
 access to remote objects. This is accomplished using
-the `transparent proxy`_ approach and build on application
-level (pure python module).
+`transparent proxies`_ and in application level code (so as a pure
+python module).
 
-The main idea is to provide kind-of-RPC protocol, which
-accesses only necessary parts of objects (not whole objects)
-and also not to rely on objects being picklable nor having
-the same source code on both sides.
-
-In order to provide this, only necessary parts of remote objects
-are retrieved for every call, keeping remote references to objects
-which are not needed yet.
+The implementation uses an RPC-like protocol, which accesses
+only members of objects, rather than whole objects. This means it
+does not rely on objects being picklable, nor on having the same
+source code available on both sides. On each call, only the members
+that are used on the client side are retrieved, objects which
+are not used are merely references to their remote counterparts.
 
-Imagine remote object, which is locally available under name `x`.
-Let's call::
+As an example, let's imagine we have a remote object, locally available
+under the name `x`. Now we call::
 
     >>>> x.foo(1, [1,2,3], y)
 
-Where y is some instance of local, user-created class. So, what
-is really called, is a call to x.__getattribute__ with argument ('foo')
-which is copied, so remote side replies with a bound method. Locally
-this bound method appears as a remote reference which is again called
-with a remote reference to x as self, 1 (which is copied as a primitive type),
-reference to a list and refence to y. Remote side receives call to bound
-method x.foo, with x being resolved as local object, 1 as a immutable
-primitive, [1,2,3] as a reference to mutable primitive and y as a reference
-to remote object. If type of y is not known on remote side, the type of
-y is faked, given enough shape to be able to perform operations. The contents
-of a list are not retrieved as long as thei're not needed.
-
-This approach transfers minimal data over network, but tends to send
-tones of small packages to remote side. This might be improved at some
-point in future. Also this approach allows to have remote references to
-internal interpreter types, like frames, code objects and tracebacks. In
-a demo directory there is an example of using this to attach pdb.post\_mortem()
-to a remote traceback.
-
-Distributed lib is build with an abstract network layer, which means you
-can provide it any possible communication channel which can
-send/receive marshallable objects (no pickle needed!) via
-two functions - send and receive.
+where y is some instance of a local, user-created class.
+
+Under water, x.\_\_getattribute\_\_ is called, with argument 'foo'. In the
+\_\_getattribute\_\_ implementation, the 'foo' attribute is requested, and the
+remote side replies by providing a bound method. On the client this bound
+method appears as a remote reference: this reference is called with a remote
+reference to x as self, the integer 1 which is copied as a primitive type, a
+reference to a list and a refence to y. The remote side receives this call,
+processes it as a call to the bound method x.foo, where 'x' is resolved as a
+local object, 1 as an immutable primitive, [1,2,3] as a reference to a mutable
+primitive and y as a reference to a remote object. If the type of y is not
+known on the remote side, it is faked with just about enough shape (XXX?!?) to
+be able to perform the required operations.  The contents of the list are
+retrieved when they're needed.
+
+An advantage of this approach is that a user can have remote references to
+internal interpreter types, like frames, code objects and tracebacks. In a demo
+directory there is an example of using this to attach pdb.post\_mortem() to a
+remote traceback. Another advantage is that there's a minimal amount of data
+transferred over the network. On the other hand, there are a large amount of
+packages sent to the remote side - hopefully this will be improved in future.
+
+The 'distributed' lib is uses an abstract network layer, which means you
+can provide custom communication channels just by implementing
+two functions that send and receive marshallable objects (no pickle needed!).
 
 Exact rules of copying
 ----------------------
 
-- Immutable primitives are always transfered
+- Immutable primitives are always transferred
 
-- Mutable primitives are transfered as reference, but several operations
-  (like iter()) force them to appear
+- Mutable primitives are transferred as a reference, but several operations
+  (like iter()) force them to be transferred fully
 
-- Builtin exceptions are transfered by name
+- Builtin exceptions are transferred by name
 
 - User objects are always faked on the other side, with enough shape
-  transfered
+  transferred
 
 XXX finish, basic interface, example, build some stuff on top of greenlets
 
-.. _`transparent proxy`: objspace-proxies.html#tproxy
+.. _`transparent proxies`: objspace-proxies.html#tproxy


From cfbolz at codespeak.net  Thu Mar  8 12:19:05 2007
From: cfbolz at codespeak.net (cfbolz at codespeak.net)
Date: Thu,  8 Mar 2007 12:19:05 +0100 (CET)
Subject: [pypy-svn] r40059 - in pypy/branch/rope-branch2/pypy/objspace/std:
	. test
Message-ID: <20070308111905.2E9161006E@code0.codespeak.net>

Author: cfbolz
Date: Thu Mar  8 12:19:04 2007
New Revision: 40059

Modified:
   pypy/branch/rope-branch2/pypy/objspace/std/rope.py
   pypy/branch/rope-branch2/pypy/objspace/std/test/test_rope.py
Log:
fix bug


Modified: pypy/branch/rope-branch2/pypy/objspace/std/rope.py
==============================================================================
--- pypy/branch/rope-branch2/pypy/objspace/std/rope.py	(original)
+++ pypy/branch/rope-branch2/pypy/objspace/std/rope.py	Thu Mar  8 12:19:04 2007
@@ -546,15 +546,18 @@
         searchstop = min(stop - i, nodelength)
         if isinstance(fringenode, LiteralStringNode):
             st = fringenode.s
-        elif isinstance(fringenode, SliceNode):
+            localoffset = 0
+        else:
+            assert isinstance(fringenode, SliceNode)
             n = fringenode.node
             assert isinstance(n, LiteralStringNode)
             st = n.s
+            localoffset = -fringenode.start
             searchstart += fringenode.start
             searchstop += fringenode.stop
-        pos = fringenode.s.find(c, searchstart, searchstop)
+        pos = st.find(c, searchstart, searchstop)
         if pos != -1:
-            return pos + i + offset
+            return pos + i + offset + localoffset
         i += nodelength
     return -1
 

Modified: pypy/branch/rope-branch2/pypy/objspace/std/test/test_rope.py
==============================================================================
--- pypy/branch/rope-branch2/pypy/objspace/std/test/test_rope.py	(original)
+++ pypy/branch/rope-branch2/pypy/objspace/std/test/test_rope.py	Thu Mar  8 12:19:04 2007
@@ -254,6 +254,10 @@
     assert r == -1
     r = find_char(LiteralStringNode("a"), "a")
     assert r == 0
+    r = find_char(BinaryConcatNode(
+        LiteralStringNode("x"),
+        SliceNode(1, 9, LiteralStringNode("a" * 10))), "a")
+    assert r == 1
 
 
 def test_restart_positions():


From cfbolz at codespeak.net  Thu Mar  8 14:02:29 2007
From: cfbolz at codespeak.net (cfbolz at codespeak.net)
Date: Thu,  8 Mar 2007 14:02:29 +0100 (CET)
Subject: [pypy-svn] r40063 - pypy/branch/rope-branch2/pypy/config
Message-ID: <20070308130229.D2FAD10063@code0.codespeak.net>

Author: cfbolz
Date: Thu Mar  8 14:02:28 2007
New Revision: 40063

Modified:
   pypy/branch/rope-branch2/pypy/config/pypyoption.py
Log:
add conflicts between strjoin, strslice and ropes


Modified: pypy/branch/rope-branch2/pypy/config/pypyoption.py
==============================================================================
--- pypy/branch/rope-branch2/pypy/config/pypyoption.py	(original)
+++ pypy/branch/rope-branch2/pypy/config/pypyoption.py	Thu Mar  8 14:02:28 2007
@@ -137,6 +137,8 @@
 
         BoolOption("withrope", "use ropes as the string implementation",
                    default=False,
+                   requires=[("objspace.std.withstrslice", False),
+                             ("objspace.std.withstrjoin", False)],
                    suggests=[("objspace.std.withprebuiltchar", True),
                              ("objspace.std.sharesmallstr", True)]),
 


From guido at codespeak.net  Thu Mar  8 14:07:00 2007
From: guido at codespeak.net (guido at codespeak.net)
Date: Thu,  8 Mar 2007 14:07:00 +0100 (CET)
Subject: [pypy-svn] r40064 - in
	pypy/branch/guido-buildtool-web/pypy/tool/build: . test web
	web/templates web/test
Message-ID: <20070308130700.CB3C71006E@code0.codespeak.net>

Author: guido
Date: Thu Mar  8 14:06:58 2007
New Revision: 40064

Added:
   pypy/branch/guido-buildtool-web/pypy/tool/build/web/templates/build.html
Modified:
   pypy/branch/guido-buildtool-web/pypy/tool/build/build.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/app.py
   pypy/branch/guido-buildtool-web/pypy/tool/build/web/templates/builds.html
   pypy/branch/guido-buildtool-web/pypy/tool/build/web/test/test_app.py
Log:
Moved presentation logic to a seperate class (MetaServerAccessor in
web/app.py), added page with a list of all builds and one for a single build.


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	Thu Mar  8 14:06:58 2007
@@ -149,12 +149,14 @@
 
     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)
+        sorted_sysinfo = sorted(self.sysinfo.items())
+        sorted_compileinfo = sorted(self.compileinfo.items())
+        str = '%r\n%r\n%r\n%r\n%r' % (self.email, sorted_sysinfo,
+                                      sorted_compileinfo, self.svnurl,
+                                      self.normalized_rev)
         return '%s.%s' % (self.request_time, py.std.md5.new(str).hexdigest())
 
-    def _fromstring(cls, s):
+    def fromstring(cls, s):
         data = {}
         for line in s.strip().split('\n'):
             try:
@@ -170,7 +172,7 @@
         ret.build_start_time = eval(data['build_start_time'])
         ret.build_end_time = eval(data['build_end_time'])
         return ret
-    fromstring = classmethod(_fromstring)
+    fromstring = classmethod(fromstring)
 
     def has_satisfying_data(self, other):
         """ return True if other request's data satisfies our needs """

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	Thu Mar  8 14:06:58 2007
@@ -172,28 +172,6 @@
         finally:
             self._queuelock.release()
 
-    def status(self):
-        # XXX temporary
-        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) + running,
-                'done': len(self._done)}
-
-    def buildersinfo(self):
-        ret = []
-        for b in self._builders:
-            ret.append({
-                'hostname': b.hostname,
-                'sysinfo': b.sysinfo,
-                'busy_on': b.busy_on and b.busy_on.serialize() or None,
-            })
-        return ret
-
-    def buildids(self):
-        pass
-
     def _cleanup_builders(self):
         self._queuelock.acquire()
         try:

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	Thu Mar  8 14:06:58 2007
@@ -159,39 +159,3 @@
     assert not bp1.check()
     assert bp2.check()
 
-def test_status():
-    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)
-    print svr.status()
-    assert svr.status() == {
-        'done': 2,
-        'queued': 3,
-        '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]}
-    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'] == 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	Thu Mar  8 14:06:58 2007
@@ -32,7 +32,8 @@
         sys.path += %r
 
         from pypy.tool.build import metaserver_instance
-        ret = metaserver_instance.%s(%s)
+        from pypy.tool.build.web.app import MetaServerAccessor
+        ret = MetaServerAccessor(metaserver_instance).%s(%s)
         channel.send(ret)
         channel.close()
     """
@@ -112,7 +113,26 @@
         self._buildid = buildid
 
     def __call__(self, handler, path, query):
-        pass
+        template = templess.template(
+            mypath.join('templates/build.html').read())
+        return ({'Content-Type': 'text/html; charset=UTF-8'},
+                fix_html(template.unicode(self.get_info())))
+
+    def get_info(self):
+        br = BuildRequest.fromstring(self.call_method('buildrequest',
+                                                      '"%s"' % (
+                                                       self._buildid,)))
+        buildurl = self.call_method('buildurl', '"%s"' % (self._buildid,))
+        return {
+            'url': buildurl,
+            'id': br.id(),
+            'email': br.email,
+            'svnurl': br.svnurl,
+            'svnrev': br.normalized_rev,
+            'request_time': br.request_time,
+            'build_start_time': br.build_start_time,
+            'build_end_time': br.build_end_time,
+        }
 
 class BuildsIndexPage(ServerPage):
     """ display the list of available builds """
@@ -124,7 +144,16 @@
                 fix_html(template.unicode({'builds': self.get_builds()})))
 
     def get_builds(self):
-        return []
+        return [{'id': b.id(),
+                 'href': '/builds/%s' % (b.id(),),
+                 'email': b.email,
+                 'svnurl': b.svnurl,
+                 'svnrev': b.normalized_rev,
+                 'request_time': b.request_time,
+                 'build_start_time': b.build_start_time,
+                 'build_end_time': b.build_end_time} for b in
+                [BuildRequest.fromstring(b) for b in
+                 self.call_method('buildrequests')]]
 
 class Builds(Collection):
     """ container for BuildsIndexPage and BuildPage """
@@ -164,6 +193,47 @@
 class AppHandler(Handler):
     application = Application()
 
+class MetaServerAccessor(object):
+    def __init__(self, ms):
+        self.server = ms
+
+    def status(self):
+        running = len([b for b in self.server._builders if b.busy_on])
+        return {'builders': len(self.server._builders),
+                'running': running,
+                'queued': len(self.server._queued),
+                'waiting': len(self.server._waiting) + running,
+                'done': len(self.server._done)}
+
+    def buildersinfo(self):
+        ret = []
+        for b in self.server._builders:
+            ret.append({
+                'hostname': b.hostname,
+                'sysinfo': b.sysinfo,
+                'busy_on': b.busy_on and b.busy_on.serialize() or None,
+            })
+        return ret
+
+    def buildrequests(self):
+        ret = [b.serialize() for b in self._all_requests()]
+        return ret
+
+    def buildrequest(self, id):
+        for r in self._all_requests():
+            if r.id() == id:
+                return r.serialize()
+
+    def buildurl(self, id):
+        for r in self.server._done:
+            if r.request.id() == id:
+                return self.server.config.path_to_url(r)
+
+    def _all_requests(self):
+        running = [b.busy_on for b in self.server._builders if b.busy_on]
+        done = [b.request for b in self.server._done]
+        return self.server._queued + self.server._waiting + running + done
+
 if __name__ == '__main__':
     from pypy.tool.build.web.server import run_server
     run_server(('', 8080), AppHandler)

Added: pypy/branch/guido-buildtool-web/pypy/tool/build/web/templates/build.html
==============================================================================
--- (empty file)
+++ pypy/branch/guido-buildtool-web/pypy/tool/build/web/templates/build.html	Thu Mar  8 14:06:58 2007
@@ -0,0 +1,23 @@
+
+  
+    Build meta server build <t:tag t:replace="id" />
+  
+  
+    

Build

+
+
url
+
+
svn url
+
+
svn revision
+
+
request time
+
+
started
+
+
ended
+
+
+ + + 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 Thu Mar 8 14:06:58 2007 @@ -9,8 +9,10 @@ for download) and waiting or in-progress ones, ordered by date. Click on the build to get more information.

-
-
+
+
+ +
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 Thu Mar 8 14:06:58 2007 @@ -5,6 +5,7 @@ from pypy.tool.build.test import fake from pypy.tool.build import config as build_config from pypy.tool.build import build +from pypy.tool.build import metaserver TESTPORT = build_config.testport @@ -20,30 +21,32 @@ def __init__(self): self._status = {} self._builders = [] - - def status(self): - return self._status - - def buildersinfo(self): - return self._builders + self._queued = [] + self._waiting = [] + self._done = [] _metaserver_init = """ import sys sys.path += %r from pypy.tool.build.web.test.test_app import FakeMetaServer + from pypy.tool.build.build import BuildRequest + from pypy.tool.build.test import fake from pypy.tool import build build.metaserver_instance = s = FakeMetaServer() + channel.send(None) 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 + if command == 'add_queued': + s._queued.append(BuildRequest.fromstring(data)) + elif command == 'add_builder': + info, compile_info = data + s._builders.append(fake.FakeBuildserver(info, compile_info)) + channel.send(None) finally: channel.close() """ @@ -52,6 +55,7 @@ gw = py.execnet.PopenGateway() conference = execnetconference.conference(gw, port, True) channel = conference.remote_exec(_metaserver_init % (path,)) + channel.receive() return channel def setup_module(mod): @@ -76,14 +80,25 @@ 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'} + status = p.get_status() + assert status == {'builders': 0, + 'running': 0, + 'done': 0, + 'queued': 0, + 'waiting': 0} + br = BuildRequest('foo at bar.com', {'foo': 'bar'}, {}, 'file:///foo', + '1234', 1) + br._nr = '1234' + server_channel.send(('add_queued', br.serialize())) + server_channel.receive() + status = p.get_status() + assert status == {'builders': 0, + 'running': 0, + 'done': 0, + 'queued': 1, + 'waiting': 0} 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(None, '/serverstatus', '') assert headers == {'Content-Type': 'text/html; charset=UTF-8'} @@ -91,34 +106,38 @@ assert html.strip().endswith('') html_validate(html) -class TestBuilderInfoPage(object): +class TestBuildersInfoPage(object): def test_get_builderinfo(self): p = BuildersInfoPage(config, gateway) assert p.get_buildersinfo() == [] - server_channel.send(('set_buildersinfo', [{'sysinfo': 'foo', - 'busy_on': None}])) - assert p.get_buildersinfo() == [{'sysinfo': ['foo'], 'busy_on': None}] + server_channel.send(('add_builder', [{'foo': 'bar'}, {}])) + server_channel.receive() + info = p.get_buildersinfo() + assert info == [{'sysinfo': [{'foo': 'bar'}], + 'hostname': 'fake', + 'busy_on': None}] def test_call(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': { - 'os': 'linux2', - 'maxint': - 9223372036854775807, - 'byteorder': 'little'}, - 'busy_on': None}, - {'hostname': 'host2', - 'sysinfo': { - 'os': 'zx81', - 'maxint': 255, - 'byteorder': 'little'}, - 'busy_on': busy_on, - }])) - p = BuildersInfoPage(config, gateway) + class TestPage(BuildersInfoPage): + def get_buildersinfo(self): + b = build.BuildRequest('foo at bar.com', {}, {'foo': 'bar'}, + 'http://codespeak.net/svn/pypy/dist', + 10, 2, 123456789) + return [ + {'hostname': 'host1', + 'sysinfo': [{ + 'os': 'linux2', + 'maxint': 9223372036854775807L, + 'byteorder': 'little'}], + 'busy_on': None}, + {'hostname': 'host2', + 'sysinfo': [{ + 'os': 'zx81', + 'maxint': 255, + 'byteorder': 'little'}], + 'busy_on': b.todict()}, + ] + p = TestPage(config, gateway) headers, html = p(None, '/buildersinfo', '') assert headers == {'Content-Type': 'text/html; charset=UTF-8'} assert html.strip().startswith(' Author: antocuni Date: Thu Mar 8 15:30:58 2007 New Revision: 40070 Modified: pypy/dist/pypy/rpython/ootypesystem/ootype.py Log: all these operations could raise an exception depending of the hashing and equality functions. Modified: pypy/dist/pypy/rpython/ootypesystem/ootype.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/ootype.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/ootype.py Thu Mar 8 15:30:58 2007 @@ -573,7 +573,7 @@ HASH_FUNC = StaticMethod([self.KEYTYPE_T], Signed) self._GENERIC_METHODS['ll_set_functions'] = Meth([EQ_FUNC, HASH_FUNC], Void) self._GENERIC_METHODS['ll_copy'] = Meth([], self.SELFTYPE_T) - self._setup_methods(self._generic_types) + self._setup_methods(self._generic_types, can_raise=['ll_get', 'll_set', 'll_remove', 'll_contains']) def _get_interp_class(self): return _custom_dict From mwh at codespeak.net Thu Mar 8 15:40:06 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Thu, 8 Mar 2007 15:40:06 +0100 (CET) Subject: [pypy-svn] r40072 - in pypy/dist/pypy: config doc/config objspace/std objspace/std/test Message-ID: <20070308144006.4CF3F1006F@code0.codespeak.net> Author: mwh Date: Thu Mar 8 15:40:04 2007 New Revision: 40072 Added: pypy/dist/pypy/doc/config/objspace.std.withsmalldicts.txt (contents, props changed) Modified: pypy/dist/pypy/config/pypyoption.py pypy/dist/pypy/objspace/std/dictmultiobject.py pypy/dist/pypy/objspace/std/test/test_dictmultiobject.py pypy/dist/pypy/objspace/std/test/test_dictobject.py Log: add a config option for using the small dictionary implementations. Modified: pypy/dist/pypy/config/pypyoption.py ============================================================================== --- pypy/dist/pypy/config/pypyoption.py (original) +++ pypy/dist/pypy/config/pypyoption.py Thu Mar 8 15:40:04 2007 @@ -157,6 +157,11 @@ default=False, requires=[("objspace.std.withmultidict", True)]), + BoolOption("withsmalldicts", + "handle small dictionaries differently", + default=False, + requires=[("objspace.std.withmultidict", True)]), + BoolOption("withrangelist", "enable special range list implementation that does not " "actually create the full list until the resulting " Added: pypy/dist/pypy/doc/config/objspace.std.withsmalldicts.txt ============================================================================== --- (empty file) +++ pypy/dist/pypy/doc/config/objspace.std.withsmalldicts.txt Thu Mar 8 15:40:04 2007 @@ -0,0 +1 @@ +Use a specialized implementation for small (<5 elements) dictionaries. Modified: pypy/dist/pypy/objspace/std/dictmultiobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/dictmultiobject.py (original) +++ pypy/dist/pypy/objspace/std/dictmultiobject.py Thu Mar 8 15:40:04 2007 @@ -140,13 +140,17 @@ return None def setitem(self, w_key, w_value): - if _is_str(self.space, w_key): - return StrDictImplementation(self.space).setitem_str(w_key, w_value) - #return SmallStrDictImplementation(self.space, w_key, w_value) - else: - space = self.space - return space.DefaultDictImpl(space).setitem(w_key, w_value) - #return SmallDictImplementation(self.space, w_key, w_value) + space = self.space + if _is_str(space, w_key): + if space.config.objspace.std.withsmalldicts: + return SmallStrDictImplementation(space, w_key, w_value) + else: + return StrDictImplementation(space).setitem_str(w_key, w_value) + else: + if space.config.objspace.std.withsmalldicts: + return SmallDictImplementation(space, w_key, w_value) + else: + return space.DefaultDictImpl(space).setitem(w_key, w_value) def setitem_str(self, w_key, w_value, shadows_type=True): return StrDictImplementation(self.space).setitem_str(w_key, w_value) #return SmallStrDictImplementation(self.space, w_key, w_value) @@ -241,12 +245,17 @@ return self.space.emptydictimpl return self else: - raise KeyError - + entry.w_key = None + raise KeyError + def length(self): return self.valid def get(self, w_lookup): - return self._lookup(w_lookup).w_value + entry = self._lookup(w_lookup) + val = entry.w_value + if val is None: + entry.w_key = None + return val def iteritems(self): return self._convert_to_rdict().iteritems() @@ -266,7 +275,6 @@ class StrEntry(object): def __init__(self): - self.hash = 0 self.key = None self.w_value = None def __repr__(self): @@ -274,12 +282,11 @@ class SmallStrDictImplementation(DictImplementation): # XXX document the invariants here! - + def __init__(self, space, w_key, w_value): self.space = space self.entries = [StrEntry(), StrEntry(), StrEntry(), StrEntry(), StrEntry()] key = space.str_w(w_key) - self.entries[0].hash = hash(key) self.entries[0].key = key self.entries[0].w_value = w_value self.valid = 1 @@ -289,11 +296,10 @@ _hash = hash(key) i = 0 last = self.entries[self.valid] - last.hash = _hash last.key = key while 1: look_entry = self.entries[i] - if look_entry.hash == _hash and look_entry.key == key: + if hash(look_entry.key) == _hash and look_entry.key == key: return look_entry i += 1 @@ -326,7 +332,7 @@ if not _is_str(self.space, w_key): return self._convert_to_rdict().setitem(w_key, w_value) return self.setitem_str(w_key, w_value) - + def setitem_str(self, w_key, w_value, shadows_type=True): entry = self._lookup(self.space.str_w(w_key)) if entry.w_value is None: @@ -351,20 +357,25 @@ return self.space.emptydictimpl return self else: + entry.key = None raise KeyError elif _is_sane_hash(self.space, w_key_type): raise KeyError else: return self._convert_to_rdict().delitem(w_key) - + def length(self): return self.valid - + def get(self, w_lookup): space = self.space w_lookup_type = space.type(w_lookup) if space.is_w(w_lookup_type, space.w_str): - return self._lookup(space.str_w(w_lookup)).w_value + entry = self._lookup(space.str_w(w_lookup)) + val = entry.w_value + if val is None: + entry.key = None + return val elif _is_sane_hash(self.space, w_lookup_type): return None else: Modified: pypy/dist/pypy/objspace/std/test/test_dictmultiobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/test/test_dictmultiobject.py (original) +++ pypy/dist/pypy/objspace/std/test/test_dictmultiobject.py Thu Mar 8 15:40:04 2007 @@ -46,6 +46,15 @@ l[0] = 24 assert a.abc == 12 +class TestW_DictSmall(test_dictobject.TestW_DictObject): + def setup_class(cls): + cls.space = gettestobjspace(**{"objspace.std.withsmalldicts": True}) + +class AppTest_DictSmall(test_dictobject.AppTest_DictObject): + def setup_class(cls): + cls.space = gettestobjspace(**{"objspace.std.withsmalldicts": True}) + +class C: pass class FakeSpace(test_dictobject.FakeSpace): def str_w(self, string): Modified: pypy/dist/pypy/objspace/std/test/test_dictobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/test/test_dictobject.py (original) +++ pypy/dist/pypy/objspace/std/test/test_dictobject.py Thu Mar 8 15:40:04 2007 @@ -384,6 +384,7 @@ FakeSpace.config.objspace.std = Config() FakeSpace.config.objspace.std.withdictmeasurement = False FakeSpace.config.objspace.std.withsharingdict = False +FakeSpace.config.objspace.std.withsmalldicts = False FakeSpace.config.objspace.opcodes = Config() FakeSpace.config.objspace.opcodes.CALL_LIKELY_BUILTIN = False From mwh at codespeak.net Thu Mar 8 17:28:10 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Thu, 8 Mar 2007 17:28:10 +0100 (CET) Subject: [pypy-svn] r40079 - pypy/dist/pypy/translator/benchmark Message-ID: <20070308162810.0829810060@code0.codespeak.net> Author: mwh Date: Thu Mar 8 17:28:09 2007 New Revision: 40079 Modified: pypy/dist/pypy/translator/benchmark/bench-custom.py Log: save the pickle and print the table after every benchmark run, not just after --runcount runs. 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 Thu Mar 8 17:28:09 2007 @@ -44,24 +44,25 @@ if not options.nocpython: exes = full_pythons + exes - for i in range(int(options.runcount)): - for exe in exes: - for b in benchmarks: - benchmark_result.result(exe, allowcreate=True).run_benchmark(b, verbose=True) + for i in range(int(options.runcount)) + [None]: + if i is not None: + for exe in exes: + for b in benchmarks: + benchmark_result.result(exe, allowcreate=True).run_benchmark(b, verbose=True) - pickle.dump(benchmark_result, open(options.picklefile, 'wb')) + 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=relto, - filteron=lambda r: r.exe_name in exes): - print row + 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=relto, + filteron=lambda r: r.exe_name in exes): + print row if __name__ == '__main__': from optparse import OptionParser From mwh at codespeak.net Thu Mar 8 17:28:58 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Thu, 8 Mar 2007 17:28:58 +0100 (CET) Subject: [pypy-svn] r40080 - pypy/dist/pypy/translator/benchmark Message-ID: <20070308162858.4C54310060@code0.codespeak.net> Author: mwh Date: Thu Mar 8 17:28:57 2007 New Revision: 40080 Modified: pypy/dist/pypy/translator/benchmark/benchmarks.py Log: disable the translate benchmark for now. Modified: pypy/dist/pypy/translator/benchmark/benchmarks.py ============================================================================== --- pypy/dist/pypy/translator/benchmark/benchmarks.py (original) +++ pypy/dist/pypy/translator/benchmark/benchmarks.py Thu Mar 8 17:28:57 2007 @@ -116,10 +116,12 @@ templessdir = py.magic.autopath().dirpath().join('templess') return templessdir.check() +def check_translate(): + return False BENCHMARKS = [Benchmark('richards', run_richards, RICHARDS_ASCENDING_GOOD, 'ms'), Benchmark('pystone', run_pystone, PYSTONE_ASCENDING_GOOD, ''), - Benchmark('translate', run_translate, RICHARDS_ASCENDING_GOOD, 'ms'), + Benchmark('translate', run_translate, RICHARDS_ASCENDING_GOOD, 'ms', check_translate), Benchmark('docutils', run_docutils, RICHARDS_ASCENDING_GOOD, 's', check_docutils), Benchmark('templess', run_templess, RICHARDS_ASCENDING_GOOD, From cfbolz at codespeak.net Thu Mar 8 18:02:58 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 8 Mar 2007 18:02:58 +0100 (CET) Subject: [pypy-svn] r40081 - pypy/branch/rope-branch2/pypy/doc/config Message-ID: <20070308170258.5A9E010063@code0.codespeak.net> Author: cfbolz Date: Thu Mar 8 18:02:56 2007 New Revision: 40081 Added: pypy/branch/rope-branch2/pypy/doc/config/objspace.std.withrope.txt Log: add rope config documentation Added: pypy/branch/rope-branch2/pypy/doc/config/objspace.std.withrope.txt ============================================================================== --- (empty file) +++ pypy/branch/rope-branch2/pypy/doc/config/objspace.std.withrope.txt Thu Mar 8 18:02:56 2007 @@ -0,0 +1,3 @@ +Implement the Python ``str`` types using *ropes*, described in the paper +"Ropes: an Alternative to Strings" by Hans-J. Boehm, Russ Atkinson and Michael +Plass. From cfbolz at codespeak.net Thu Mar 8 18:13:11 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 8 Mar 2007 18:13:11 +0100 (CET) Subject: [pypy-svn] r40083 - in pypy/dist/pypy: config doc/config module/marshal/test objspace/std objspace/std/test Message-ID: <20070308171311.3A13E10063@code0.codespeak.net> Author: cfbolz Date: Thu Mar 8 18:13:10 2007 New Revision: 40083 Added: pypy/dist/pypy/doc/config/objspace.std.withrope.txt - copied unchanged from r40081, pypy/branch/rope-branch2/pypy/doc/config/objspace.std.withrope.txt pypy/dist/pypy/objspace/std/rope.py - copied unchanged from r40081, pypy/branch/rope-branch2/pypy/objspace/std/rope.py pypy/dist/pypy/objspace/std/ropeobject.py - copied unchanged from r40081, pypy/branch/rope-branch2/pypy/objspace/std/ropeobject.py pypy/dist/pypy/objspace/std/test/test_rope.py - copied unchanged from r40081, pypy/branch/rope-branch2/pypy/objspace/std/test/test_rope.py pypy/dist/pypy/objspace/std/test/test_ropeobject.py - copied unchanged from r40081, pypy/branch/rope-branch2/pypy/objspace/std/test/test_ropeobject.py Modified: pypy/dist/pypy/config/pypyoption.py pypy/dist/pypy/module/marshal/test/test_marshal.py pypy/dist/pypy/objspace/std/marshal_impl.py pypy/dist/pypy/objspace/std/model.py pypy/dist/pypy/objspace/std/objspace.py pypy/dist/pypy/objspace/std/stringtype.py pypy/dist/pypy/objspace/std/unicodeobject.py Log: svn merge -r 40042:HEAD svn+ssh://codespeak.net/svn/pypy/branch/rope-branch2 Modified: pypy/dist/pypy/config/pypyoption.py ============================================================================== --- pypy/dist/pypy/config/pypyoption.py (original) +++ pypy/dist/pypy/config/pypyoption.py Thu Mar 8 18:13:10 2007 @@ -128,14 +128,21 @@ default=False), BoolOption("withprebuiltchar", - "use prebuilt single-character string objects", - default=False), + default=False, + "use prebuilt single-character string objects"), BoolOption("sharesmallstr", "always reuse the prebuilt string objects " "(the empty string and potentially single-char strings)", default=False), + BoolOption("withrope", "use ropes as the string implementation", + default=False, + requires=[("objspace.std.withstrslice", False), + ("objspace.std.withstrjoin", False)], + suggests=[("objspace.std.withprebuiltchar", True), + ("objspace.std.sharesmallstr", True)]), + BoolOption("withmultidict", "use dictionaries optimized for flexibility", default=False), Modified: pypy/dist/pypy/module/marshal/test/test_marshal.py ============================================================================== --- pypy/dist/pypy/module/marshal/test/test_marshal.py (original) +++ pypy/dist/pypy/module/marshal/test/test_marshal.py Thu Mar 8 18:13:10 2007 @@ -12,12 +12,12 @@ print "case: %-30s func=None" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) - assert x == case + assert x == case and type(x) is type(case) f = StringIO.StringIO() marshal.dump(case, f) f.seek(0) x = marshal.load(f) - assert x == case + assert x == case and type(x) is type(case) def test_False(self): import sys @@ -31,12 +31,12 @@ print "case: %-30s func=False" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) - assert x == case + assert x == case and type(x) is type(case) f = StringIO.StringIO() marshal.dump(case, f) f.seek(0) x = marshal.load(f) - assert x == case + assert x == case and type(x) is type(case) def test_True(self): import sys @@ -50,12 +50,12 @@ print "case: %-30s func=True" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) - assert x == case + assert x == case and type(x) is type(case) f = StringIO.StringIO() marshal.dump(case, f) f.seek(0) x = marshal.load(f) - assert x == case + assert x == case and type(x) is type(case) def test_StopIteration(self): import sys @@ -69,12 +69,12 @@ print "case: %-30s func=StopIteration" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) - assert x == case + assert x == case and type(x) is type(case) f = StringIO.StringIO() marshal.dump(case, f) f.seek(0) x = marshal.load(f) - assert x == case + assert x == case and type(x) is type(case) def test_Ellipsis(self): import sys @@ -88,12 +88,12 @@ print "case: %-30s func=Ellipsis" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) - assert x == case + assert x == case and type(x) is type(case) f = StringIO.StringIO() marshal.dump(case, f) f.seek(0) x = marshal.load(f) - assert x == case + assert x == case and type(x) is type(case) def test_42(self): import sys @@ -107,12 +107,12 @@ print "case: %-30s func=42" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) - assert x == case + assert x == case and type(x) is type(case) f = StringIO.StringIO() marshal.dump(case, f) f.seek(0) x = marshal.load(f) - assert x == case + assert x == case and type(x) is type(case) def test__minus_17(self): import sys @@ -126,12 +126,12 @@ print "case: %-30s func=_minus_17" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) - assert x == case + assert x == case and type(x) is type(case) f = StringIO.StringIO() marshal.dump(case, f) f.seek(0) x = marshal.load(f) - assert x == case + assert x == case and type(x) is type(case) def test_sys_dot_maxint(self): import sys @@ -145,12 +145,12 @@ print "case: %-30s func=sys_dot_maxint" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) - assert x == case + assert x == case and type(x) is type(case) f = StringIO.StringIO() marshal.dump(case, f) f.seek(0) x = marshal.load(f) - assert x == case + assert x == case and type(x) is type(case) def test__minus_1_dot_25(self): import sys @@ -164,12 +164,12 @@ print "case: %-30s func=_minus_1_dot_25" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) - assert x == case + assert x == case and type(x) is type(case) f = StringIO.StringIO() marshal.dump(case, f) f.seek(0) x = marshal.load(f) - assert x == case + assert x == case and type(x) is type(case) def test__minus_1_dot_25__2(self): import sys @@ -183,12 +183,12 @@ print "case: %-30s func=_minus_1_dot_25__2" % (case, ) s = marshal.dumps(case, 2); assert len(s) in (9, 17) x = marshal.loads(s) - assert x == case + assert x == case and type(x) is type(case) f = StringIO.StringIO() marshal.dump(case, f) f.seek(0) x = marshal.load(f) - assert x == case + assert x == case and type(x) is type(case) def test_2_plus_5j(self): import sys @@ -202,12 +202,12 @@ print "case: %-30s func=2_plus_5j" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) - assert x == case + assert x == case and type(x) is type(case) f = StringIO.StringIO() marshal.dump(case, f) f.seek(0) x = marshal.load(f) - assert x == case + assert x == case and type(x) is type(case) def test_2_plus_5j__2(self): import sys @@ -221,12 +221,12 @@ print "case: %-30s func=2_plus_5j__2" % (case, ) s = marshal.dumps(case, 2); assert len(s) in (9, 17) x = marshal.loads(s) - assert x == case + assert x == case and type(x) is type(case) f = StringIO.StringIO() marshal.dump(case, f) f.seek(0) x = marshal.load(f) - assert x == case + assert x == case and type(x) is type(case) def test_42L(self): import sys @@ -240,12 +240,12 @@ print "case: %-30s func=42L" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) - assert x == case + assert x == case and type(x) is type(case) f = StringIO.StringIO() marshal.dump(case, f) f.seek(0) x = marshal.load(f) - assert x == case + assert x == case and type(x) is type(case) def test__minus_1234567890123456789012345678901234567890L(self): import sys @@ -259,12 +259,12 @@ print "case: %-30s func=_minus_1234567890123456789012345678901234567890L" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) - assert x == case + assert x == case and type(x) is type(case) f = StringIO.StringIO() marshal.dump(case, f) f.seek(0) x = marshal.load(f) - assert x == case + assert x == case and type(x) is type(case) def test_hello_____not_interned(self): import sys @@ -278,12 +278,12 @@ print "case: %-30s func=hello_____not_interned" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) - assert x == case + assert x == case and type(x) is type(case) f = StringIO.StringIO() marshal.dump(case, f) f.seek(0) x = marshal.load(f) - assert x == case + assert x == case and type(x) is type(case) def test__Quote_hello_Quote_(self): import sys @@ -297,12 +297,12 @@ print "case: %-30s func=_Quote_hello_Quote_" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) - assert x == case + assert x == case and type(x) is type(case) f = StringIO.StringIO() marshal.dump(case, f) f.seek(0) x = marshal.load(f) - assert x == case + assert x == case and type(x) is type(case) def test__brace__ecarb_(self): import sys @@ -316,12 +316,12 @@ print "case: %-30s func=_brace__ecarb_" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) - assert x == case + assert x == case and type(x) is type(case) f = StringIO.StringIO() marshal.dump(case, f) f.seek(0) x = marshal.load(f) - assert x == case + assert x == case and type(x) is type(case) def test__brace_1_comma__2_ecarb_(self): import sys @@ -335,12 +335,12 @@ print "case: %-30s func=_brace_1_comma__2_ecarb_" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) - assert x == case + assert x == case and type(x) is type(case) f = StringIO.StringIO() marshal.dump(case, f) f.seek(0) x = marshal.load(f) - assert x == case + assert x == case and type(x) is type(case) def test__list__tsil_(self): import sys @@ -354,12 +354,12 @@ print "case: %-30s func=_list__tsil_" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) - assert x == case + assert x == case and type(x) is type(case) f = StringIO.StringIO() marshal.dump(case, f) f.seek(0) x = marshal.load(f) - assert x == case + assert x == case and type(x) is type(case) def test__list_3_comma__4_tsil_(self): import sys @@ -373,12 +373,12 @@ print "case: %-30s func=_list_3_comma__4_tsil_" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) - assert x == case + assert x == case and type(x) is type(case) f = StringIO.StringIO() marshal.dump(case, f) f.seek(0) x = marshal.load(f) - assert x == case + assert x == case and type(x) is type(case) def test__dict__tcid_(self): import sys @@ -392,12 +392,12 @@ print "case: %-30s func=_dict__tcid_" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) - assert x == case + assert x == case and type(x) is type(case) f = StringIO.StringIO() marshal.dump(case, f) f.seek(0) x = marshal.load(f) - assert x == case + assert x == case and type(x) is type(case) def test__dict_5_colon__6_comma__7_colon__8_tcid_(self): import sys @@ -411,12 +411,12 @@ print "case: %-30s func=_dict_5_colon__6_comma__7_colon__8_tcid_" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) - assert x == case + assert x == case and type(x) is type(case) f = StringIO.StringIO() marshal.dump(case, f) f.seek(0) x = marshal.load(f) - assert x == case + assert x == case and type(x) is type(case) def test_func_dot_func_code(self): import sys @@ -430,12 +430,12 @@ print "case: %-30s func=func_dot_func_code" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) - assert x == case + assert x == case and type(x) is type(case) f = StringIO.StringIO() marshal.dump(case, f) f.seek(0) x = marshal.load(f) - assert x == case + assert x == case and type(x) is type(case) def test_scopefunc_dot_func_code(self): import sys @@ -449,12 +449,12 @@ print "case: %-30s func=scopefunc_dot_func_code" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) - assert x == case + assert x == case and type(x) is type(case) f = StringIO.StringIO() marshal.dump(case, f) f.seek(0) x = marshal.load(f) - assert x == case + assert x == case and type(x) is type(case) def test_u_quote_hello_quote_(self): import sys @@ -468,12 +468,12 @@ print "case: %-30s func=u_quote_hello_quote_" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) - assert x == case + assert x == case and type(x) is type(case) f = StringIO.StringIO() marshal.dump(case, f) f.seek(0) x = marshal.load(f) - assert x == case + assert x == case and type(x) is type(case) def test_buffer_brace_hello_ecarb_(self): import sys @@ -487,12 +487,12 @@ print "case: %-30s func=buffer_brace_hello_ecarb_" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) - assert x == case + assert x == case and type(x) is type(case) f = StringIO.StringIO() marshal.dump(case, f) f.seek(0) x = marshal.load(f) - assert x == case + assert x == case and type(x) is type(case) def test_buffer_brace_u_quote_unicode_comma__too_quote__ecarb_(self): import sys @@ -506,12 +506,12 @@ print "case: %-30s func=buffer_brace_u_quote_unicode_comma__too_quote__ecarb_" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) - assert x == case + assert x == case and type(x) is type(case) f = StringIO.StringIO() marshal.dump(case, f) f.seek(0) x = marshal.load(f) - assert x == case + assert x == case and type(x) is type(case) def test_set_brace__ecarb_(self): import sys @@ -525,12 +525,12 @@ print "case: %-30s func=set_brace__ecarb_" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) - assert x == case + assert x == case and type(x) is type(case) f = StringIO.StringIO() marshal.dump(case, f) f.seek(0) x = marshal.load(f) - assert x == case + assert x == case and type(x) is type(case) def test_set_brace__list_1_comma__2_tsil__ecarb_(self): import sys @@ -544,12 +544,12 @@ print "case: %-30s func=set_brace__list_1_comma__2_tsil__ecarb_" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) - assert x == case + assert x == case and type(x) is type(case) f = StringIO.StringIO() marshal.dump(case, f) f.seek(0) x = marshal.load(f) - assert x == case + assert x == case and type(x) is type(case) def test_frozenset_brace__ecarb_(self): import sys @@ -563,12 +563,12 @@ print "case: %-30s func=frozenset_brace__ecarb_" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) - assert x == case + assert x == case and type(x) is type(case) f = StringIO.StringIO() marshal.dump(case, f) f.seek(0) x = marshal.load(f) - assert x == case + assert x == case and type(x) is type(case) def test_frozenset_brace__list_3_comma__4_tsil__ecarb_(self): import sys @@ -582,12 +582,12 @@ print "case: %-30s func=frozenset_brace__list_3_comma__4_tsil__ecarb_" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) - assert x == case + assert x == case and type(x) is type(case) f = StringIO.StringIO() marshal.dump(case, f) f.seek(0) x = marshal.load(f) - assert x == case + assert x == case and type(x) is type(case) class AppTestMultiDict(object): @@ -597,3 +597,8 @@ 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 + +class AppTestRope(AppTestMarshal): + def setup_class(cls): + from pypy.conftest import gettestobjspace + cls.space = gettestobjspace(**{"objspace.std.withrope": True}) Modified: pypy/dist/pypy/objspace/std/marshal_impl.py ============================================================================== --- pypy/dist/pypy/objspace/std/marshal_impl.py (original) +++ pypy/dist/pypy/objspace/std/marshal_impl.py Thu Mar 8 18:13:10 2007 @@ -27,6 +27,7 @@ from pypy.objspace.std.dictobject import W_DictObject from pypy.objspace.std.dictmultiobject import W_DictMultiObject from pypy.objspace.std.stringobject import W_StringObject +from pypy.objspace.std.ropeobject import W_RopeObject from pypy.objspace.std.typeobject import W_TypeObject from pypy.objspace.std.longobject import W_LongObject from pypy.objspace.std.noneobject import W_NoneObject @@ -301,6 +302,8 @@ else: m.atom_str(TYPE_STRING, s) +marshal_w__Rope = marshal_w__String + def unmarshal_String(space, u, tc): return space.wrap(u.get_str()) register(TYPE_STRING, unmarshal_String) Modified: pypy/dist/pypy/objspace/std/model.py ============================================================================== --- pypy/dist/pypy/objspace/std/model.py (original) +++ pypy/dist/pypy/objspace/std/model.py Thu Mar 8 18:13:10 2007 @@ -15,6 +15,8 @@ "withmultidict" : ["dictmultiobject.W_DictMultiObject", "dictmultiobject.W_DictMultiIterObject"], "withmultilist" : ["listmultiobject.W_ListMultiObject"], + "withrope" : ["ropeobject.W_RopeObject", + "ropeobject.W_RopeIterObject"], "withrangelist" : ["rangeobject.W_RangeListObject", "rangeobject.W_RangeIterObject"], "withtproxy" : ["proxyobject.W_TransparentList", @@ -65,6 +67,7 @@ from pypy.objspace.std import dictmultiobject from pypy.objspace.std import listmultiobject from pypy.objspace.std import stringobject + from pypy.objspace.std import ropeobject from pypy.objspace.std import strsliceobject from pypy.objspace.std import strjoinobject from pypy.objspace.std import typeobject @@ -108,10 +111,11 @@ self.typeorder[setobject.W_FrozensetObject] = [] self.typeorder[setobject.W_SetIterObject] = [] - imported_but_not_registered = { + self.imported_but_not_registered = { dictobject.W_DictObject: True, dictobject.W_DictIterObject: True, listobject.W_ListObject: True, + stringobject.W_StringObject: True, } for option, value in config.objspace.std: if option.startswith("with") and option in option_to_typename: @@ -120,7 +124,7 @@ if value: self.typeorder[implcls] = [] else: - imported_but_not_registered[implcls] = True + self.imported_but_not_registered[implcls] = True if config.objspace.std.withmultidict: del self.typeorder[dictobject.W_DictObject] @@ -128,12 +132,14 @@ if config.objspace.std.withmultilist: del self.typeorder[listobject.W_ListObject] + if config.objspace.std.withrope: + del self.typeorder[stringobject.W_StringObject] #check if we missed implementations from pypy.objspace.std.objspace import _registered_implementations for implcls in _registered_implementations: assert (implcls in self.typeorder or - implcls in imported_but_not_registered), ( + implcls in self.imported_but_not_registered), ( "please add %r in StdTypeModel.typeorder" % (implcls,)) @@ -175,9 +181,14 @@ (complexobject.W_ComplexObject, complexobject.delegate_Float2Complex), ] - self.typeorder[stringobject.W_StringObject] += [ - (unicodeobject.W_UnicodeObject, unicodeobject.delegate_String2Unicode), - ] + if not config.objspace.std.withrope: + self.typeorder[stringobject.W_StringObject] += [ + (unicodeobject.W_UnicodeObject, unicodeobject.delegate_String2Unicode), + ] + else: + self.typeorder[ropeobject.W_RopeObject] += [ + (unicodeobject.W_UnicodeObject, unicodeobject.delegate_String2Unicode), + ] if config.objspace.std.withstrslice: self.typeorder[strsliceobject.W_StringSliceObject] += [ Modified: pypy/dist/pypy/objspace/std/objspace.py ============================================================================== --- pypy/dist/pypy/objspace/std/objspace.py (original) +++ pypy/dist/pypy/objspace/std/objspace.py Thu Mar 8 18:13:10 2007 @@ -157,6 +157,8 @@ # hack to avoid imports in the time-critical functions below for cls in self.model.typeorder: globals()[cls.__name__] = cls + for cls in self.model.imported_but_not_registered: + globals()[cls.__name__] = cls # singletons self.w_None = W_NoneObject() Modified: pypy/dist/pypy/objspace/std/stringtype.py ============================================================================== --- pypy/dist/pypy/objspace/std/stringtype.py (original) +++ pypy/dist/pypy/objspace/std/stringtype.py Thu Mar 8 18:13:10 2007 @@ -5,11 +5,14 @@ def wrapstr(space, s): from pypy.objspace.std.stringobject import W_StringObject + from pypy.objspace.std.ropeobject import rope, W_RopeObject if space.config.objspace.std.sharesmallstr: if space.config.objspace.std.withprebuiltchar: # share characters and empty string if len(s) <= 1: if len(s) == 0: + if space.config.objspace.std.withrope: + return W_RopeObject.EMPTY return W_StringObject.EMPTY else: s = s[0] # annotator hint: a single char @@ -17,19 +20,29 @@ else: # only share the empty string if len(s) == 0: + if space.config.objspace.std.withrope: + return W_RopeObject.EMPTY return W_StringObject.EMPTY + if space.config.objspace.std.withrope: + return W_RopeObject(rope.LiteralStringNode(s)) return W_StringObject(s) def wrapchar(space, c): from pypy.objspace.std.stringobject import W_StringObject + from pypy.objspace.std.ropeobject import rope, W_RopeObject if space.config.objspace.std.withprebuiltchar: + if space.config.objspace.std.withrope: + return W_RopeObject.PREBUILT[ord(c)] return W_StringObject.PREBUILT[ord(c)] else: + if space.config.objspace.std.withrope: + return W_RopeObject(rope.LiteralStringNode(c)) return W_StringObject(c) def sliced(space, s, start, stop): assert start >= 0 assert stop >= 0 + assert not space.config.objspace.std.withrope if space.config.objspace.std.withstrslice: from pypy.objspace.std.strsliceobject import W_StringSliceObject # XXX heuristic, should be improved! @@ -38,6 +51,7 @@ return wrapstr(space, s[start:stop]) def joined(space, strlist): + assert not space.config.objspace.std.withrope if space.config.objspace.std.withstrjoin: from pypy.objspace.std.strjoinobject import W_StringJoinObject return W_StringJoinObject(strlist) @@ -254,9 +268,15 @@ if space.is_w(w_stringtype, space.w_str): return w_obj # XXX might be reworked when space.str() typechecks value = space.str_w(w_obj) - w_obj = space.allocate_instance(W_StringObject, w_stringtype) - W_StringObject.__init__(w_obj, value) - return w_obj + if space.config.objspace.std.withrope: + from pypy.objspace.std.ropeobject import rope, W_RopeObject + w_obj = space.allocate_instance(W_RopeObject, w_stringtype) + W_RopeObject.__init__(w_obj, rope.LiteralStringNode(value)) + return w_obj + else: + w_obj = space.allocate_instance(W_StringObject, w_stringtype) + W_StringObject.__init__(w_obj, value) + return w_obj # ____________________________________________________________ Modified: pypy/dist/pypy/objspace/std/unicodeobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/unicodeobject.py (original) +++ pypy/dist/pypy/objspace/std/unicodeobject.py Thu Mar 8 18:13:10 2007 @@ -1,6 +1,7 @@ from pypy.objspace.std.objspace import * from pypy.interpreter import gateway from pypy.objspace.std.stringobject import W_StringObject +from pypy.objspace.std.ropeobject import W_RopeObject from pypy.objspace.std.noneobject import W_NoneObject from pypy.objspace.std.sliceobject import W_SliceObject from pypy.objspace.std.tupleobject import W_TupleObject @@ -101,11 +102,17 @@ def add__String_Unicode(space, w_left, w_right): return space.add(space.call_function(space.w_unicode, w_left) , w_right) +add__Rope_Unicode = add__String_Unicode + def add__Unicode_String(space, w_left, w_right): return space.add(w_left, space.call_function(space.w_unicode, w_right)) +add__Unicode_Rope = add__Unicode_String + def contains__String_Unicode(space, w_container, w_item): return space.contains(space.call_function(space.w_unicode, w_container), w_item ) +contains__Rope_Unicode = contains__String_Unicode + def _find(self, sub, start, end): if len(sub) == 0: @@ -188,15 +195,25 @@ def hash__Unicode(space, w_uni): if w_uni.w_hash is None: + # hrmpf chars = w_uni._value if len(chars) == 0: return space.wrap(0) - x = ord(chars[0]) << 7 - for c in chars: - x = intmask((1000003 * x) ^ ord(c)) - h = intmask(x ^ len(chars)) - if h == -1: - h = -2 + if space.config.objspace.std.withrope: + x = 0 + for c in chars: + x = intmask((1000003 * x) + ord(c)) + x <<= 1 + x ^= len(chars) + x ^= ord(chars[0]) + h = intmask(x) + else: + x = ord(chars[0]) << 7 + for c in chars: + x = intmask((1000003 * x) ^ ord(c)) + h = intmask(x ^ len(chars)) + if h == -1: + h = -2 w_uni.w_hash = space.wrap(h) return w_uni.w_hash @@ -394,6 +411,7 @@ def unicode_strip__Unicode_String(space, w_self, w_chars): return space.call_method(w_self, 'strip', space.call_function(space.w_unicode, w_chars)) +unicode_strip__Unicode_Rope = unicode_strip__Unicode_String def unicode_lstrip__Unicode_None(space, w_self, w_chars): return _strip_none(space, w_self, 1, 0) @@ -403,6 +421,8 @@ return space.call_method(w_self, 'lstrip', space.call_function(space.w_unicode, w_chars)) +unicode_lstrip__Unicode_Rope = unicode_lstrip__Unicode_String + def unicode_rstrip__Unicode_None(space, w_self, w_chars): return _strip_none(space, w_self, 0, 1) def unicode_rstrip__Unicode_Unicode(space, w_self, w_chars): @@ -411,6 +431,8 @@ return space.call_method(w_self, 'rstrip', space.call_function(space.w_unicode, w_chars)) +unicode_rstrip__Unicode_Rope = unicode_rstrip__Unicode_String + def unicode_capitalize__Unicode(space, w_self): input = w_self._value if len(input) == 0: @@ -1034,41 +1056,49 @@ import stringtype W_UnicodeObject = W_UnicodeObject from pypy.objspace.std.stringobject import W_StringObject + from pypy.objspace.std.ropeobject import W_RopeObject def str_strip__String_Unicode(space, w_self, w_chars): return space.call_method(space.call_function(space.w_unicode, w_self), 'strip', w_chars) + str_strip__Rope_Unicode = str_strip__String_Unicode def str_lstrip__String_Unicode(space, w_self, w_chars): return space.call_method(space.call_function(space.w_unicode, w_self), 'lstrip', w_chars) + str_lstrip__Rope_Unicode = str_lstrip__String_Unicode def str_rstrip__String_Unicode(space, w_self, w_chars): return space.call_method(space.call_function(space.w_unicode, w_self), 'rstrip', w_chars) + str_rstrip__Rope_Unicode = str_rstrip__String_Unicode def str_count__String_Unicode_ANY_ANY(space, w_self, w_substr, w_start, w_end): return space.call_method(space.call_function(space.w_unicode, w_self), 'count', w_substr, w_start, w_end) + str_count__Rope_Unicode_ANY_ANY = str_count__String_Unicode_ANY_ANY def str_find__String_Unicode_ANY_ANY(space, w_self, w_substr, w_start, w_end): return space.call_method(space.call_function(space.w_unicode, w_self), 'find', w_substr, w_start, w_end) + str_find__Rope_Unicode_ANY_ANY = str_find__String_Unicode_ANY_ANY def str_rfind__String_Unicode_ANY_ANY(space, w_self, w_substr, w_start, w_end): return space.call_method(space.call_function(space.w_unicode, w_self), 'rfind', w_substr, w_start, w_end) + str_rfind__Rope_Unicode_ANY_ANY = str_rfind__String_Unicode_ANY_ANY def str_index__String_Unicode_ANY_ANY(space, w_self, w_substr, w_start, w_end): return space.call_method(space.call_function(space.w_unicode, w_self), 'index', w_substr, w_start, w_end) + str_index__Rope_Unicode_ANY_ANY = str_index__String_Unicode_ANY_ANY def str_rindex__String_Unicode_ANY_ANY(space, w_self, w_substr, w_start, w_end): return space.call_method(space.call_function(space.w_unicode, w_self), 'rindex', w_substr, w_start, w_end) - + str_rindex__Rope_Unicode_ANY_ANY = str_rindex__String_Unicode_ANY_ANY def str_replace__String_Unicode_Unicode_ANY(space, w_self, w_old, w_new, w_maxsplit): return space.call_method(space.call_function(space.w_unicode, w_self), 'replace', w_old, w_new, w_maxsplit) - + str_replace__Rope_Unicode_Unicode_ANY = str_replace__String_Unicode_Unicode_ANY def str_split__String_Unicode_ANY(space, w_self, w_delim, w_maxsplit): return space.call_method(space.call_function(space.w_unicode, w_self), 'split', w_delim, w_maxsplit) - + str_split__Rope_Unicode_ANY = str_split__String_Unicode_ANY def str_rsplit__String_Unicode_ANY(space, w_self, w_delim, w_maxsplit): return space.call_method(space.call_function(space.w_unicode, w_self), 'rsplit', w_delim, w_maxsplit) - + str_rsplit__Rope_Unicode_ANY = str_rsplit__String_Unicode_ANY register_all(vars(), stringtype) From cfbolz at codespeak.net Thu Mar 8 18:14:44 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 8 Mar 2007 18:14:44 +0100 (CET) Subject: [pypy-svn] r40084 - pypy/dist/pypy/config Message-ID: <20070308171444.6230710070@code0.codespeak.net> Author: cfbolz Date: Thu Mar 8 18:14:42 2007 New Revision: 40084 Modified: pypy/dist/pypy/config/pypyoption.py Log: what the heck? Modified: pypy/dist/pypy/config/pypyoption.py ============================================================================== --- pypy/dist/pypy/config/pypyoption.py (original) +++ pypy/dist/pypy/config/pypyoption.py Thu Mar 8 18:14:42 2007 @@ -128,8 +128,8 @@ default=False), BoolOption("withprebuiltchar", - default=False, - "use prebuilt single-character string objects"), + "use prebuilt single-character string objects", + default=False), BoolOption("sharesmallstr", "always reuse the prebuilt string objects " From afayolle at codespeak.net Thu Mar 8 18:19:18 2007 From: afayolle at codespeak.net (afayolle at codespeak.net) Date: Thu, 8 Mar 2007 18:19:18 +0100 (CET) Subject: [pypy-svn] r40085 - pypy/dist/pypy/interpreter/astcompiler Message-ID: <20070308171918.F1C3210072@code0.codespeak.net> Author: afayolle Date: Thu Mar 8 18:19:16 2007 New Revision: 40085 Modified: pypy/dist/pypy/interpreter/astcompiler/ast.py pypy/dist/pypy/interpreter/astcompiler/ast.txt pypy/dist/pypy/interpreter/astcompiler/astgen.py Log: Fix lambda __new__ in ast.txt Regenerate ast.py, and manually enable __repr__ on ast nodes Modified: pypy/dist/pypy/interpreter/astcompiler/ast.py ============================================================================== --- pypy/dist/pypy/interpreter/astcompiler/ast.py (original) +++ pypy/dist/pypy/interpreter/astcompiler/ast.py Thu Mar 8 18:19:16 2007 @@ -85,7 +85,7 @@ Node.typedef = TypeDef('ASTNode', __new__ = interp2app(descr_Node_new, unwrap_spec=[ObjSpace, W_Root, int]), - #__repr__ = interp2app(descr_node_repr, unwrap_spec=['self', ObjSpace] ), + __repr__ = interp2app(Node.descr_repr, unwrap_spec=['self', ObjSpace] ), getChildNodes = interp2app(Node.descr_getChildNodes, unwrap_spec=[ 'self', ObjSpace ] ), accept = interp2app(descr_node_accept, unwrap_spec=[ ObjSpace, W_Root, W_Root ] ), mutate = interp2app(descr_node_mutate, unwrap_spec=[ ObjSpace, W_Root, W_Root ] ), @@ -2538,6 +2538,7 @@ + def descr_From_accept( space, w_self, w_visitor): return space.call_method(w_visitor, 'visitFrom', w_self) @@ -3505,8 +3506,16 @@ code = space.interp_w(Node, w_code, can_be_None=False) self.code = code self.lineno = lineno + self.varargs = 0 + self.kwargs = 0 + if flags & CO_VARARGS: + self.varargs = 1 + if flags & CO_VARKEYWORDS: + self.kwargs = 1 return space.wrap(self) + + def descr_Lambda_accept( space, w_self, w_visitor): return space.call_method(w_visitor, 'visitLambda', w_self) Modified: pypy/dist/pypy/interpreter/astcompiler/ast.txt ============================================================================== --- pypy/dist/pypy/interpreter/astcompiler/ast.txt (original) +++ pypy/dist/pypy/interpreter/astcompiler/ast.txt Thu Mar 8 18:19:16 2007 @@ -289,6 +289,26 @@ self.lineno = lineno return space.wrap(self) + +def descr_Lambda_new(space, w_subtype, w_argnames, w_defaults, w_flags, w_code, lineno=-1): + self = space.allocate_instance(Lambda, w_subtype) + argnames = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_argnames)] + self.argnames = argnames + defaults = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_defaults)] + self.defaults = defaults + flags = space.int_w(w_flags) + self.flags = flags + code = space.interp_w(Node, w_code, can_be_None=False) + self.code = code + self.lineno = lineno + self.varargs = 0 + self.kwargs = 0 + if flags & CO_VARARGS: + self.varargs = 1 + if flags & CO_VARKEYWORDS: + self.kwargs = 1 + return space.wrap(self) + def descr_Function_new(space, w_subtype, w_decorators, w_name, w_argnames, w_defaults, w_flags, w_doc, w_code, lineno=-1): self = space.allocate_instance(Function, w_subtype) decorators = space.interp_w(Node, w_decorators, can_be_None=True) Modified: pypy/dist/pypy/interpreter/astcompiler/astgen.py ============================================================================== --- pypy/dist/pypy/interpreter/astcompiler/astgen.py (original) +++ pypy/dist/pypy/interpreter/astcompiler/astgen.py Thu Mar 8 18:19:16 2007 @@ -733,7 +733,7 @@ Node.typedef = TypeDef('ASTNode', __new__ = interp2app(descr_Node_new, unwrap_spec=[ObjSpace, W_Root, int]), - #__repr__ = interp2app(descr_node_repr, unwrap_spec=['self', ObjSpace] ), + #__repr__ = interp2app(Node.descr_repr, unwrap_spec=['self', ObjSpace] ), getChildNodes = interp2app(Node.descr_getChildNodes, unwrap_spec=[ 'self', ObjSpace ] ), accept = interp2app(descr_node_accept, unwrap_spec=[ ObjSpace, W_Root, W_Root ] ), mutate = interp2app(descr_node_mutate, unwrap_spec=[ ObjSpace, W_Root, W_Root ] ), From afayolle at codespeak.net Thu Mar 8 18:19:56 2007 From: afayolle at codespeak.net (afayolle at codespeak.net) Date: Thu, 8 Mar 2007 18:19:56 +0100 (CET) Subject: [pypy-svn] r40086 - pypy/dist/pypy/module/recparser Message-ID: <20070308171956.2A5D810076@code0.codespeak.net> Author: afayolle Date: Thu Mar 8 18:19:54 2007 New Revision: 40086 Modified: pypy/dist/pypy/module/recparser/__init__.py Log: export flag constants to app-level Modified: pypy/dist/pypy/module/recparser/__init__.py ============================================================================== --- pypy/dist/pypy/module/recparser/__init__.py (original) +++ pypy/dist/pypy/module/recparser/__init__.py Thu Mar 8 18:19:54 2007 @@ -54,3 +54,10 @@ from pypy.interpreter.astcompiler.ast import nodeclasses for klass_name in nodeclasses: Module.interpleveldefs['AST' + klass_name] = 'pypy.interpreter.astcompiler.ast.%s' % klass_name + +from pypy.interpreter.astcompiler import consts +for name in dir(consts): + if name.startswith('__') or name in Module.interpleveldefs: + continue + Module.interpleveldefs[name] = ("space.wrap(%s)" % + (getattr(consts, name), )) From afayolle at codespeak.net Thu Mar 8 18:21:08 2007 From: afayolle at codespeak.net (afayolle at codespeak.net) Date: Thu, 8 Mar 2007 18:21:08 +0100 (CET) Subject: [pypy-svn] r40087 - in pypy/dist/pypy/lib: . app_test Message-ID: <20070308172108.3295D10072@code0.codespeak.net> Author: afayolle Date: Thu Mar 8 18:21:07 2007 New Revision: 40087 Modified: pypy/dist/pypy/lib/aop.py pypy/dist/pypy/lib/app_test/sample_aop_code.py pypy/dist/pypy/lib/app_test/test_aop.py Log: implement advice before and after call Modified: pypy/dist/pypy/lib/aop.py ============================================================================== --- pypy/dist/pypy/lib/aop.py (original) +++ pypy/dist/pypy/lib/aop.py Thu Mar 8 18:21:07 2007 @@ -2,7 +2,7 @@ heavily influenced by Aspect++""" - +__all__ = ('around', 'before', 'after', 'introduce', 'PointCut', 'Aspect') ########################### # API ########################### @@ -16,6 +16,15 @@ if self.requires_dynamic_pointcut != pointcut.isdynamic: raise TypeError('Expecting a static pointcut') self.pointcut = pointcut + dispatch = {ExecutionPointCut: self.weave_at_execution_pointcut, + CallPointCut: self.weave_at_call_pointcut, + InitializationPointCut: self.weave_at_initialization_pointcut, + DestructionPointCut: self.weave_at_destruction_pointcut, + PointCut: self.weave_at_static_pointcut, + } + self.weave_at_pointcut = dispatch[pointcut.__class__] + + def __call__(self, function): print 'wrapping advice %s on %s' % (self.pointcut, function.__name__) @@ -23,54 +32,43 @@ return self def weave(self, ast, enc): - return ast.accept(self) + return ast.mutate(self) - def visitFunction(self, node): + def default(self, node): if self.pointcut.match(node): node = self.weave_at_pointcut(node, self.pointcut.joinpoint(node)) return node - def vistClass(self, node): - if self.pointcut.match(node): - print "found match", node.name - return node - +## def visitClass(self, node): +## if self.pointcut.match(node): +## print "found match", node.name +## return node -def make_aop_call(id, targetname=None, discard=True): - """return an AST for a call to a woven function - id is the integer returned when the advice was stored in the registry""" - p = parser - arguments = [p.ASTConst(id),] - if targetname is not None: - arguments.append(p.ASTName(targetname)) - else: - arguments.append(p.ASTConst(None)) - arguments.append(p.ASTCallFunc(p.ASTName('locals'), - [], None, None) - ) - - if discard: - returnclass = p.ASTDiscard - else: - returnclass = p.ASTReturn - return returnclass(p.ASTCallFunc(p.ASTName('__aop__'), - arguments, - None, # *args - None # *kwargs - ) - ) - -def is_aop_call(node): - p = parser - return node.__class__ == p.ASTDiscard and \ - node.expr.__class__ == p.ASTCallFunc and \ - node.expr.node.varname == '__aop__' + def weave_at_execution_pointcut(self, node, tjp): + raise NotImplementedError("abstract method") + + def weave_at_call_pointcut(self, node, tjp): + raise NotImplementedError("abstract method") + + def weave_at_initialization_pointcut(self, node, tjp): + raise NotImplementedError("abstract method") + + def weave_at_destruction_pointcut(self, node, tjp): + raise NotImplementedError("abstract method") + + def weave_at_static_pointcut(self, node, tjp): + raise NotImplementedError("abstract method") class around(Advice): """specify code to be run instead of the pointcut""" - def weave_at_pointcut(self, node, tjp): - print "WEAVE around!!!" + def weave_at_execution_pointcut(self, node, tjp): + """weaving around a function execution moves the body of the + function to an inner function called + __aoptarget__, and generate the following code: + return __aop__(id, __aoptarget__) + """ + print"WEAVE around!!!" p = parser id = __aop__.register_joinpoint(self.woven_code, tjp) statement = node.code @@ -91,9 +89,20 @@ node.code = newcode return node + def weave_at_call_pointcut(self, node, tjp): + raise NotImplementedError("abstract method") + + def weave_at_initialization_pointcut(self, node, tjp): + raise NotImplementedError("abstract method") + + def weave_at_destruction_pointcut(self, node, tjp): + raise NotImplementedError("abstract method") + class before(Advice): """specify code to be run before the pointcut""" - def weave_at_pointcut(self, node, tjp): + def weave_at_execution_pointcut(self, node, tjp): + """weaving before execution inserts a call to __aop__(id) at + the beginning of the wrapped function definition""" print "WEAVE before!!!" id = __aop__.register_joinpoint(self.woven_code, tjp) statement_list = node.code.nodes @@ -101,11 +110,46 @@ node.code.nodes = statement_list return node - - + def weave_at_call_pointcut(self, node, tjp): + """weaving before call replaces a call to foo(bar) with the + following code: + (lambda *args,**kwargs: (__aop__(id), foo(*args,**kwargs)))(bar)[1] + """ + id = __aop__.register_joinpoint(self.woven_code, tjp) + p = parser + lambda_ret = p.ASTTuple((make_aop_call(id).expr, # we don't want the ASTDiscard + p.ASTCallFunc(node.node, + [], + p.ASTName('args'), + p.ASTName('kwargs'))) + ) + lambda_func = p.ASTLambda([p.ASTAssName('args', 0), p.ASTAssName('kwargs', 0)], + [], # defaults + p.CO_VARARGS | p.CO_VARKEYWORDS, + lambda_ret + ) + call = p.ASTCallFunc(lambda_func, + node.args, + node.star_args, + node.dstar_args) + newnode = p.ASTSubscript(call, + p.OP_APPLY, + p.ASTConst(1)) + print `newnode` + return newnode + + def weave_at_initialization_pointcut(self, node, tjp): + raise NotImplementedError("abstract method") + + def weave_at_destruction_pointcut(self, node, tjp): + raise NotImplementedError("abstract method") + class after(Advice): """specify code to be run after the pointcut""" - def weave_at_pointcut(self, node, tjp): + def weave_at_execution_pointcut(self, node, tjp): + """weaving after execution wraps the code of the function in a + try...finally block, and calls __aop__(id) in the finally + block""" print "WEAVE after!!!" id = __aop__.register_joinpoint(self.woven_code, tjp) statement = node.code @@ -113,6 +157,42 @@ node.code = tryfinally return node + def weave_at_call_pointcut(self, node, tjp): + """weaving before call replaces a call to foo(bar) with the + following code: + (lambda *args,**kwargs: (foo(*args,**kwargs), __aop__(id)))(bar)[0] + """ + id = __aop__.register_joinpoint(self.woven_code, tjp) + p = parser + lambda_ret = p.ASTTuple((p.ASTCallFunc(node.node, + [], + p.ASTName('args'), + p.ASTName('kwargs')), + make_aop_call(id).expr, # we don't want the ASTDiscard + ) + ) + lambda_func = p.ASTLambda([p.ASTAssName('args', 0), p.ASTAssName('kwargs', 0)], + [], # defaults + p.CO_VARARGS | p.CO_VARKEYWORDS, + lambda_ret + ) + call = p.ASTCallFunc(lambda_func, + node.args, + node.star_args, + node.dstar_args) + newnode = p.ASTSubscript(call, + p.OP_APPLY, + p.ASTConst(0)) + print `newnode` + return newnode + + + def weave_at_initialization_pointcut(self, node, tjp): + raise NotImplementedError("abstract method") + + def weave_at_destruction_pointcut(self, node, tjp): + raise NotImplementedError("abstract method") + class introduce(Advice): """insert new code in the pointcut this is the only advice available on static point cuts""" @@ -124,8 +204,6 @@ -# TODO: add new base classes to a pointcut. Maybe with introduce ? - # JoinPoint # -------- @@ -171,6 +249,7 @@ if arguments is None: arguments = (), {} self._arguments = arguments + self._argnames = None self.func = func @@ -210,6 +289,7 @@ def call(self): """return a dynamic pointcut representing places where the pointcut is called""" return CallPointCut(self) + def execution(self): """return a dynamic pointcut representing places where the pointcut is executed""" return ExecutionPointCut(self) @@ -239,10 +319,7 @@ class ExecutionPointCut(AbstractDynamicPointCut): def match(self, astnode): - try: - return astnode.name == self.pointcutdef - except AttributeError: - return False + return isinstance(astnode, parser.ASTFunction) and astnode.name == self.pointcutdef def joinpoint(self, node): """returns a join point instance for the node""" @@ -255,7 +332,8 @@ return jp class CallPointCut(AbstractDynamicPointCut): - pass + def match(self, node): + return isinstance(node, parser.ASTCallFunc) and isinstance(node.node, parser.ASTName) and node.node.varname == self.pointcutdef class DestructionPointCut(AbstractDynamicPointCut): pass @@ -327,8 +405,9 @@ def __call__(self, id, target=None, target_locals = None): woven_code, (aspect, joinpoint, arguments) = self.joinpoints[id] joinpoint.func = target + print 'target_locals', target_locals if target_locals is not None: - joinpoint._arguments = (), dict([(n, target_locals[n]) for n in joinpoint._argnames]) + joinpoint._arguments = (), dict([(n, target_locals[n]) for n in joinpoint._argnames or ()]) args = (aspect, joinpoint,) + arguments return woven_code(*args) @@ -354,6 +433,30 @@ return instance +# helper functions +def make_aop_call(id, targetname=None, discard=True): + """return an AST for a call to a woven function + id is the integer returned when the advice was stored in the registry""" + p = parser + arguments = [p.ASTConst(id),] + if targetname is not None: + arguments.append(p.ASTName(targetname)) + else: + arguments.append(p.ASTName('None')) + arguments.append(p.ASTCallFunc(p.ASTName('locals'), + [], None, None) + ) + + if discard: + returnclass = p.ASTDiscard + else: + returnclass = p.ASTReturn + return returnclass(p.ASTCallFunc(p.ASTName('__aop__'), + arguments, + None, # *args + None # *kwargs + ) + ) # debugging visitor class Debug(parser.ASTVisitor): Modified: pypy/dist/pypy/lib/app_test/sample_aop_code.py ============================================================================== --- pypy/dist/pypy/lib/app_test/sample_aop_code.py (original) +++ pypy/dist/pypy/lib/app_test/sample_aop_code.py Thu Mar 8 18:21:07 2007 @@ -2,12 +2,13 @@ def foo(b,c): print 'foo' a = 2 - d = bar() + d = bar(a) + print d return b+a+c+d -def bar(): - print 'bar' +def bar(val): + print 'bar', val return 42 def baz(b,c): Modified: pypy/dist/pypy/lib/app_test/test_aop.py ============================================================================== --- pypy/dist/pypy/lib/app_test/test_aop.py (original) +++ pypy/dist/pypy/lib/app_test/test_aop.py Thu Mar 8 18:21:07 2007 @@ -28,18 +28,6 @@ adv = advice(dyn_pc) assert adv is not None - def test_is_aop(self): - from aop import is_aop_call - import parser - func = """ -def f(): - __aop__(1) - g(12) - __aop__(12) -""" - funcast = parser.source2ast(func).node.nodes[0] - result = [is_aop_call(n) for n in funcast.code.nodes] - assert result == [True, False, True] def test_simple_aspect_before_execution(self): from aop import PointCut, Aspect, before @@ -127,3 +115,62 @@ assert answ == 47 sample_aop_code.clean_module('aop_around_execution') + + def test_simple_aspect_before_call(self): + from aop import PointCut, Aspect, before + from app_test import sample_aop_code + __aop__._clear_all() + sample_aop_code.write_module('aop_before_call') + + class AspectTest: + __metaclass__ = Aspect + def __init__(self): + self.executed = False + @before(PointCut('bar').call()) + def advice_before_call(self, tjp): + print "IN advice before call" + self.executed = True + self.arguments = tjp._arguments + print "OUT advice before call" + + assert __aop__.advices == [] + aspect = AspectTest() + assert __aop__.advices == [(aspect, AspectTest.advice_before_call)] + assert not aspect.executed + + from app_test import aop_before_call + assert aspect.executed == 0 + answ = aop_before_call.foo(1,2) + assert aspect.executed == 1 + assert answ == 47 + sample_aop_code.clean_module('aop_before_call') + + def test_simple_aspect_after_call(self): + from aop import PointCut, Aspect, after + from app_test import sample_aop_code + __aop__._clear_all() + sample_aop_code.write_module('aop_after_call') + + class AspectTest: + __metaclass__ = Aspect + def __init__(self): + self.executed = False + @after(PointCut('bar').call()) + def advice_after_call(self, tjp): + print "IN advice after call" + self.executed = True + self.arguments = tjp._arguments + print "OUT advice after call" + + assert __aop__.advices == [] + aspect = AspectTest() + assert __aop__.advices == [(aspect, AspectTest.advice_after_call)] + assert not aspect.executed + + from app_test import aop_after_call + assert aspect.executed == 0 + answ = aop_after_call.foo(1,2) + assert aspect.executed == 1 + assert answ == 47 + sample_aop_code.clean_module('aop_after_call') + From cfbolz at codespeak.net Thu Mar 8 18:21:53 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 8 Mar 2007 18:21:53 +0100 (CET) Subject: [pypy-svn] r40088 - pypy/branch/rope-branch2 Message-ID: <20070308172153.9F88310072@code0.codespeak.net> Author: cfbolz Date: Thu Mar 8 18:21:52 2007 New Revision: 40088 Removed: pypy/branch/rope-branch2/ Log: remove merged branch From cfbolz at codespeak.net Thu Mar 8 18:39:09 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 8 Mar 2007 18:39:09 +0100 (CET) Subject: [pypy-svn] r40089 - pypy/dist/pypy/module/gc/test Message-ID: <20070308173909.440EE1006E@code0.codespeak.net> Author: cfbolz Date: Thu Mar 8 18:39:08 2007 New Revision: 40089 Added: pypy/dist/pypy/module/gc/test/ pypy/dist/pypy/module/gc/test/__init__.py pypy/dist/pypy/module/gc/test/test_gc.py Log: add one (idiotic) test to the gc module Added: pypy/dist/pypy/module/gc/test/__init__.py ============================================================================== Added: pypy/dist/pypy/module/gc/test/test_gc.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/gc/test/test_gc.py Thu Mar 8 18:39:08 2007 @@ -0,0 +1,4 @@ +class AppTestGC(object): + def test_collect(self): + import gc + gc.collect() # mostly a "does not crash" kind of test From cfbolz at codespeak.net Thu Mar 8 18:39:38 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 8 Mar 2007 18:39:38 +0100 (CET) Subject: [pypy-svn] r40090 - pypy/dist/pypy/module/gc/test Message-ID: <20070308173938.06B2B1007A@code0.codespeak.net> Author: cfbolz Date: Thu Mar 8 18:39:37 2007 New Revision: 40090 Modified: pypy/dist/pypy/module/gc/test/ (props changed) pypy/dist/pypy/module/gc/test/__init__.py (props changed) pypy/dist/pypy/module/gc/test/test_gc.py (props changed) Log: fixeol From santagada at codespeak.net Thu Mar 8 18:48:30 2007 From: santagada at codespeak.net (santagada at codespeak.net) Date: Thu, 8 Mar 2007 18:48:30 +0100 (CET) Subject: [pypy-svn] r40091 - in pypy/dist/pypy/lang/js: . test/ecma Message-ID: <20070308174830.967AE1007C@code0.codespeak.net> Author: santagada Date: Thu Mar 8 18:48:27 2007 New Revision: 40091 Added: pypy/dist/pypy/lang/js/js.cleanup (contents, props changed) Modified: pypy/dist/pypy/lang/js/interpreter.py pypy/dist/pypy/lang/js/js_interactive.py pypy/dist/pypy/lang/js/operations.py pypy/dist/pypy/lang/js/test/ecma/conftest.py Log: some bug fixes and now using cpickle to not parse files multiple times Modified: pypy/dist/pypy/lang/js/interpreter.py ============================================================================== --- pypy/dist/pypy/lang/js/interpreter.py (original) +++ pypy/dist/pypy/lang/js/interpreter.py Thu Mar 8 18:48:27 2007 @@ -2,6 +2,8 @@ import math from pypy.lang.js.jsparser import parse, parse_bytecode from pypy.lang.js.operations import * +from pypy.rlib.objectmodel import we_are_translated + def writer(x): print x @@ -14,6 +16,26 @@ temp_tree = parse_bytecode(bytecode) return from_tree(temp_tree) +def load_file(filename): + # NOT RPYTHON + import cPickle as pickle + import os.path + base, ext = os.path.splitext(filename) + jscname = base+".jsc" + if os.path.isfile(jscname): + jsc = open(jscname, 'r') + t = pickle.load(jsc) + jsc.close() + else: + f = open(filename) + t = parse(f.read()) + f.close() + jsc = open(jscname, 'w') + pickle.dump(t, jsc, protocol=2) + jsc.close() + return from_tree(t) + + def evaljs(ctx, args, this): if len(args) >= 1: code = args[0] Added: pypy/dist/pypy/lang/js/js.cleanup ============================================================================== --- (empty file) +++ pypy/dist/pypy/lang/js/js.cleanup Thu Mar 8 18:48:27 2007 @@ -0,0 +1,24 @@ +#!/usr/bin/env python + +"""\ +js.cleanup [PATH] + +Delete jsc file recursively, starting from PATH (which defaults to the current +working directory). Don't follow links and don't recurse into directories with +a ".". +""" +import autopath +import py + +parser = py.compat.optparse.OptionParser(usage=__doc__) + +if __name__ == '__main__': + (options, args) = parser.parse_args() + + if not args: + args = ["."] + for arg in args: + path = py.path.local(arg) + print "cleaning path", path + for x in path.visit('*.jsc', lambda x: x.check(dotfile=0, link=0)): + x.remove() 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 Thu Mar 8 18:48:27 2007 @@ -41,9 +41,7 @@ def loadjs(ctx, args, this): filename = args[0] - f = open(filename.ToString()) - t = load_source(f.read()) - f.close() + t = load_file(filename.ToString()) return t.execute(ctx) def tracejs(ctx, args, this): Modified: pypy/dist/pypy/lang/js/operations.py ============================================================================== --- pypy/dist/pypy/lang/js/operations.py (original) +++ pypy/dist/pypy/lang/js/operations.py Thu Mar 8 18:48:27 2007 @@ -127,7 +127,6 @@ opcode = 'ARRAY_INIT' def eval(self, ctx): - #d = dict(enumerate(self.items)) array = W_Array() for i in range(len(self.list)): array.Put(str(i), self.list[i].eval(ctx).GetValue()) 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 Mar 8 18:48:27 2007 @@ -36,7 +36,7 @@ cls.interp = Interpreter() ctx = cls.interp.global_context shellpath = rootdir/'shell.js' - t = load_source(shellpath.read()) + t = load_file(str(shellpath)) t.execute(ctx) cls.testcases = cls.interp.global_context.resolve_identifier('testcases') cls.tc = cls.interp.global_context.resolve_identifier('tc') @@ -54,7 +54,7 @@ return self.init_interp() #actually run the file :) - t = load_source(self.fspath.read()) + t = load_file(str(self.fspath)) try: t.execute(self.interp.global_context) except JsSyntaxError: From cfbolz at codespeak.net Thu Mar 8 18:58:02 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 8 Mar 2007 18:58:02 +0100 (CET) Subject: [pypy-svn] r40092 - in pypy/dist/pypy/module/gc: . test Message-ID: <20070308175802.66E5F1007E@code0.codespeak.net> Author: cfbolz Date: Thu Mar 8 18:58:01 2007 New Revision: 40092 Modified: pypy/dist/pypy/module/gc/__init__.py pypy/dist/pypy/module/gc/interp_gc.py pypy/dist/pypy/module/gc/test/test_gc.py Log: a somewhat hackish way to estimate heap size by looking at /proc Modified: pypy/dist/pypy/module/gc/__init__.py ============================================================================== --- pypy/dist/pypy/module/gc/__init__.py (original) +++ pypy/dist/pypy/module/gc/__init__.py Thu Mar 8 18:58:01 2007 @@ -8,4 +8,5 @@ } interpleveldefs = { 'collect': 'interp_gc.collect', + 'estimate_heap_size': 'interp_gc.estimate_heap_size', } Modified: pypy/dist/pypy/module/gc/interp_gc.py ============================================================================== --- pypy/dist/pypy/module/gc/interp_gc.py (original) +++ pypy/dist/pypy/module/gc/interp_gc.py Thu Mar 8 18:58:01 2007 @@ -1,4 +1,5 @@ from pypy.interpreter.gateway import ObjSpace +from pypy.interpreter.error import OperationError from pypy.rlib import rgc # Force registration of gc.collect import gc @@ -8,3 +9,28 @@ collect.unwrap_spec = [ObjSpace] +def estimate_heap_size(space): + import sys + # XXX should be done with the help of the GCs + if sys.platform == "linux2": + import os + pid = os.getpid() + try: + fd = os.open("/proc/" + str(pid) + "/status", os.O_RDONLY, 0777) + except OSError: + pass + else: + try: + content = os.read(fd, 1000000) + finally: + os.close(fd) + lines = content.split("\n") + for line in lines: + if line.startswith("VmSize:"): + stop = len(line) - 3 + assert stop > 0 + result = int(line[len("VmSize:"):stop].strip(" ")) * 1024 + return space.wrap(result) + raise OperationError(space.w_RuntimeError, + space.wrap("can't estimate the heap size")) +estimate_heap_size.unwrap_spec = [ObjSpace] Modified: pypy/dist/pypy/module/gc/test/test_gc.py ============================================================================== --- pypy/dist/pypy/module/gc/test/test_gc.py (original) +++ pypy/dist/pypy/module/gc/test/test_gc.py Thu Mar 8 18:58:01 2007 @@ -2,3 +2,10 @@ def test_collect(self): import gc gc.collect() # mostly a "does not crash" kind of test + + def test_estimate_heap_size(self): + import sys, gc + if sys.platform == "linux2": + assert gc.estimate_heap_size() > 1024 + else: + raises(RuntimeError, gc.estimate_heap_size) From cfbolz at codespeak.net Thu Mar 8 19:26:39 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 8 Mar 2007 19:26:39 +0100 (CET) Subject: [pypy-svn] r40094 - pypy/dist/pypy/module/gc Message-ID: <20070308182639.F145D1006E@code0.codespeak.net> Author: cfbolz Date: Thu Mar 8 19:26:39 2007 New Revision: 40094 Modified: pypy/dist/pypy/module/gc/interp_gc.py Log: be more translatable Modified: pypy/dist/pypy/module/gc/interp_gc.py ============================================================================== --- pypy/dist/pypy/module/gc/interp_gc.py (original) +++ pypy/dist/pypy/module/gc/interp_gc.py Thu Mar 8 19:26:39 2007 @@ -9,10 +9,12 @@ collect.unwrap_spec = [ObjSpace] +import sys +platform = sys.platform + def estimate_heap_size(space): - import sys # XXX should be done with the help of the GCs - if sys.platform == "linux2": + if platform == "linux2": import os pid = os.getpid() try: From gbrandl at codespeak.net Thu Mar 8 19:49:53 2007 From: gbrandl at codespeak.net (gbrandl at codespeak.net) Date: Thu, 8 Mar 2007 19:49:53 +0100 (CET) Subject: [pypy-svn] r40095 - in pypy/dist/pypy: annotation/test objspace/std rpython/raisingops translator/c/src translator/c/test Message-ID: <20070308184953.D7B9910060@code0.codespeak.net> Author: gbrandl Date: Thu Mar 8 19:49:52 2007 New Revision: 40095 Modified: pypy/dist/pypy/annotation/test/test_annrpython.py pypy/dist/pypy/objspace/std/floatobject.py pypy/dist/pypy/objspace/std/listmultiobject.py pypy/dist/pypy/rpython/raisingops/raisingops.py pypy/dist/pypy/translator/c/src/int.h pypy/dist/pypy/translator/c/test/test_backendoptimized.py Log: some random spelling nitpicking 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 Thu Mar 8 19:49:52 2007 @@ -325,7 +325,7 @@ a = self.RPythonAnnotator() s = a.build_types(snippet.flow_type_info, [annmodel.SomeInteger(nonneg=True)]) - # this checks that isinstance(i, int) didn't loose the + # this checks that isinstance(i, int) didn't lose the # actually more precise information that i is non-negative assert s == annmodel.SomeInteger(nonneg=True) Modified: pypy/dist/pypy/objspace/std/floatobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/floatobject.py (original) +++ pypy/dist/pypy/objspace/std/floatobject.py Thu Mar 8 19:49:52 2007 @@ -120,7 +120,7 @@ # for overflowing comparisons between longs and floats # XXX we might have to worry (later) about eq__Float_Int, for the case -# where int->float conversion may loose precision :-( +# where int->float conversion may lose precision :-( def eq__Float_Long(space, w_float1, w_long2): # XXX naive implementation x = w_float1.floatval Modified: pypy/dist/pypy/objspace/std/listmultiobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/listmultiobject.py (original) +++ pypy/dist/pypy/objspace/std/listmultiobject.py Thu Mar 8 19:49:52 2007 @@ -734,7 +734,7 @@ if self.detached_impl is None: self.detached_impl = self.listimpl.getitem_true_slice( self.start, self.stop) - self.listimpl = None # loose the reference + self.listimpl = None # lose the reference def detach_and_unregister(self): if self.detached_impl is None: Modified: pypy/dist/pypy/rpython/raisingops/raisingops.py ============================================================================== --- pypy/dist/pypy/rpython/raisingops/raisingops.py (original) +++ pypy/dist/pypy/rpython/raisingops/raisingops.py Thu Mar 8 19:49:52 2007 @@ -85,11 +85,11 @@ '''#define OP_INT_LSHIFT_OVF(x,y,r,err) \ OP_INT_LSHIFT(x,y,r,err); \ if ((x) != Py_ARITHMETIC_RIGHT_SHIFT(long, r, (y))) \ - FAIL_OVF(err, "x< Author: ludal Date: Thu Mar 8 20:07:24 2007 New Revision: 40096 Modified: pypy/dist/pypy/interpreter/astcompiler/ast.py Log: hopefully fix annotation Modified: pypy/dist/pypy/interpreter/astcompiler/ast.py ============================================================================== --- pypy/dist/pypy/interpreter/astcompiler/ast.py (original) +++ pypy/dist/pypy/interpreter/astcompiler/ast.py Thu Mar 8 20:07:24 2007 @@ -85,7 +85,7 @@ Node.typedef = TypeDef('ASTNode', __new__ = interp2app(descr_Node_new, unwrap_spec=[ObjSpace, W_Root, int]), - __repr__ = interp2app(Node.descr_repr, unwrap_spec=['self', ObjSpace] ), + #__repr__ = interp2app(Node.descr_repr, unwrap_spec=['self', ObjSpace] ), getChildNodes = interp2app(Node.descr_getChildNodes, unwrap_spec=[ 'self', ObjSpace ] ), accept = interp2app(descr_node_accept, unwrap_spec=[ ObjSpace, W_Root, W_Root ] ), mutate = interp2app(descr_node_mutate, unwrap_spec=[ ObjSpace, W_Root, W_Root ] ), From cfbolz at codespeak.net Thu Mar 8 21:50:16 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 8 Mar 2007 21:50:16 +0100 (CET) Subject: [pypy-svn] r40098 - in pypy/dist/pypy: config doc/config objspace/std Message-ID: <20070308205016.C97CC10060@code0.codespeak.net> Author: cfbolz Date: Thu Mar 8 21:50:13 2007 New Revision: 40098 Added: pypy/dist/pypy/doc/config/objspace.std.methodcachesizeexp.txt - copied unchanged from r40094, pypy/dist/pypy/doc/config/objspace.std.methodcachesize.txt Removed: pypy/dist/pypy/doc/config/objspace.std.methodcachesize.txt Modified: pypy/dist/pypy/config/pypyoption.py pypy/dist/pypy/objspace/std/objspace.py pypy/dist/pypy/objspace/std/typeobject.py Log: use a mask instead of a modulo for the method cache index determination Modified: pypy/dist/pypy/config/pypyoption.py ============================================================================== --- pypy/dist/pypy/config/pypyoption.py (original) +++ pypy/dist/pypy/config/pypyoption.py Thu Mar 8 21:50:13 2007 @@ -195,9 +195,9 @@ "for testing purposes only.", default=False, requires=[("objspace.std.withmethodcache", True)]), - IntOption("methodcachesize", - "size of the method cache (should be a power of 2)", - default=2048), + IntOption("methodcachesizeexp", + "2 ** methodcachesizeexp is the size of the of the method cache ", + default=11), BoolOption("withmultilist", "use lists optimized for flexibility", default=False, Modified: pypy/dist/pypy/objspace/std/objspace.py ============================================================================== --- pypy/dist/pypy/objspace/std/objspace.py (original) +++ pypy/dist/pypy/objspace/std/objspace.py Thu Mar 8 21:50:13 2007 @@ -299,7 +299,7 @@ ec = ObjSpace.createexecutioncontext(self) ec._py_repr = self.newdict() if self.config.objspace.std.withmethodcache: - SIZE = self.config.objspace.std.methodcachesize + SIZE = 2 ** self.config.objspace.std.methodcachesizeexp ec.method_cache_versions = [None] * SIZE ec.method_cache_names = [None] * SIZE ec.method_cache_lookup_where = [(None, None)] * SIZE Modified: pypy/dist/pypy/objspace/std/typeobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/typeobject.py (original) +++ pypy/dist/pypy/objspace/std/typeobject.py Thu Mar 8 21:50:13 2007 @@ -320,8 +320,8 @@ if version_tag is None: tup = w_self._lookup_where(name) return tup - SIZE = space.config.objspace.std.methodcachesize - method_hash = (id(version_tag) ^ position_hash ^ hash(name)) % SIZE + MASK = 2 ** space.config.objspace.std.methodcachesizeexp - 1 + method_hash = (id(version_tag) ^ position_hash ^ hash(name)) & MASK cached_version_tag = ec.method_cache_versions[method_hash] if cached_version_tag is version_tag: cached_name = ec.method_cache_names[method_hash] From cfbolz at codespeak.net Thu Mar 8 22:22:04 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 8 Mar 2007 22:22:04 +0100 (CET) Subject: [pypy-svn] r40099 - in pypy/dist/pypy: config doc/config translator/c translator/c/test translator/llvm Message-ID: <20070308212204.5DCB51006F@code0.codespeak.net> Author: cfbolz Date: Thu Mar 8 22:22:03 2007 New Revision: 40099 Added: pypy/dist/pypy/doc/config/translation.noprofopt.txt Modified: pypy/dist/pypy/config/translationoption.py pypy/dist/pypy/translator/c/genc.py pypy/dist/pypy/translator/c/test/test_standalone.py pypy/dist/pypy/translator/llvm/buildllvm.py Log: add a --noprofopt option to disable profile based optimizations again Modified: pypy/dist/pypy/config/translationoption.py ============================================================================== --- pypy/dist/pypy/config/translationoption.py (original) +++ pypy/dist/pypy/config/translationoption.py Thu Mar 8 22:22:03 2007 @@ -56,6 +56,8 @@ StrOption("cc", "Specify compiler to use for compiling generated C", cmdline="--cc"), StrOption("profopt", "Specify profile based optimization script", cmdline="--profopt"), + BoolOption("noprofopt", "Don't use profile based optimization", + default=False, cmdline="--no-profopt", negation=False), BoolOption("instrument", "internal: turn instrumentation on", default=False, cmdline=None), Added: pypy/dist/pypy/doc/config/translation.noprofopt.txt ============================================================================== Modified: pypy/dist/pypy/translator/c/genc.py ============================================================================== --- pypy/dist/pypy/translator/c/genc.py (original) +++ pypy/dist/pypy/translator/c/genc.py Thu Mar 8 22:22:03 2007 @@ -229,7 +229,7 @@ profbased = self.config.translation.instrumentctl else: profopt = self.config.translation.profopt - if profopt is not None: + if profopt is not None and not self.config.translation.noprofopt: profbased = (ProfOpt, profopt) return CCompiler( Modified: pypy/dist/pypy/translator/c/test/test_standalone.py ============================================================================== --- pypy/dist/pypy/translator/c/test/test_standalone.py (original) +++ pypy/dist/pypy/translator/c/test/test_standalone.py Thu Mar 8 22:22:03 2007 @@ -135,3 +135,32 @@ cbuilder.compile() data = cbuilder.cmdexec('hi there') assert map(float, data.split()) == [0.0, 0.0] + +def test_profopt(): + if sys.platform == 'win32': + py.test.skip("instrumentation support is unix only for now") + def add(a,b): + return a + b - b + b - b + b - b + b - b + b - b + b - b + b + def entry_point(argv): + tot = 0 + x = int(argv[1]) + while x > 0: + tot = add(tot, x) + x -= 1 + os.write(1, str(tot)) + return 0 + from pypy.translator.interactive import Translation + # XXX this is mostly a "does not crash option" + t = Translation(entry_point, backend='c', standalone=True, profopt="") + # no counters + t.backendopt() + exe = t.compile() + out = py.process.cmdexec("%s 500" % exe) + assert int(out) == 500*501/2 + t = Translation(entry_point, backend='c', standalone=True, profopt="", + noprofopt=True) + # no counters + t.backendopt() + exe = t.compile() + out = py.process.cmdexec("%s 500" % exe) + assert int(out) == 500*501/2 Modified: pypy/dist/pypy/translator/llvm/buildllvm.py ============================================================================== --- pypy/dist/pypy/translator/llvm/buildllvm.py (original) +++ pypy/dist/pypy/translator/llvm/buildllvm.py Thu Mar 8 22:22:03 2007 @@ -200,7 +200,8 @@ object_files.append("%s.o" % b) else: self.cmds.append("llc %s.bc -march=c -f -o %s.c" % (b, b)) - if self.genllvm.config.translation.profopt is not None: + if (self.genllvm.config.translation.profopt is not None and + not self.genllvm.config.translation.noprofopt): cmd = "gcc -fprofile-generate %s.c -c -O3 -pipe -o %s.o" % (b, b) self.cmds.append(cmd) cmd = "gcc -fprofile-generate %s.o %s %s -lm -pipe -o %s_gen" % \ From cfbolz at codespeak.net Thu Mar 8 22:53:13 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 8 Mar 2007 22:53:13 +0100 (CET) Subject: [pypy-svn] r40101 - pypy/dist/pypy/objspace/std/test Message-ID: <20070308215313.0AB8810034@code0.codespeak.net> Author: cfbolz Date: Thu Mar 8 22:53:12 2007 New Revision: 40101 Modified: pypy/dist/pypy/objspace/std/test/test_dictobject.py Log: since when can tests be too slow? Modified: pypy/dist/pypy/objspace/std/test/test_dictobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/test/test_dictobject.py (original) +++ pypy/dist/pypy/objspace/std/test/test_dictobject.py Thu Mar 8 22:53:12 2007 @@ -144,14 +144,14 @@ assert d == dd assert not d is dd - def tooslow_test_get(self): + def test_get(self): d = {1:2, 3:4} assert d.get(1) == 2 assert d.get(1,44) == 2 assert d.get(33) == None assert d.get(33,44) == 44 - def tooslow_test_pop(self): + def test_pop(self): d = {1:2, 3:4} dd = d.copy() result = dd.pop(1) From cfbolz at codespeak.net Thu Mar 8 23:03:07 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 8 Mar 2007 23:03:07 +0100 (CET) Subject: [pypy-svn] r40102 - in pypy/dist/pypy/objspace/std: . test Message-ID: <20070308220307.4A74910063@code0.codespeak.net> Author: cfbolz Date: Thu Mar 8 23:03:06 2007 New Revision: 40102 Modified: pypy/dist/pypy/objspace/std/dictmultiobject.py pypy/dist/pypy/objspace/std/test/test_dictmultiobject.py Log: fix bug. sharing dicts are not really that well tested, I fear, since the dict tests don't instantiate sharing dicts. Modified: pypy/dist/pypy/objspace/std/dictmultiobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/dictmultiobject.py (original) +++ pypy/dist/pypy/objspace/std/dictmultiobject.py Thu Mar 8 23:03:06 2007 @@ -767,7 +767,7 @@ def items(self): space = self.space - return [(space.wrap(key), self.entries[item]) + return [space.newtuple([space.wrap(key), self.entries[item]]) for (key, item) in self.structure.keys.iteritems() if item >= 0] Modified: pypy/dist/pypy/objspace/std/test/test_dictmultiobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/test/test_dictmultiobject.py (original) +++ pypy/dist/pypy/objspace/std/test/test_dictmultiobject.py Thu Mar 8 23:03:06 2007 @@ -46,6 +46,14 @@ l[0] = 24 assert a.abc == 12 + def test_items(self): + class A(object): + pass + a = A() + a.abc = 12 + a.__dict__.items() == [("abc", 12)] + + class TestW_DictSmall(test_dictobject.TestW_DictObject): def setup_class(cls): cls.space = gettestobjspace(**{"objspace.std.withsmalldicts": True}) From cfbolz at codespeak.net Fri Mar 9 11:12:19 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 9 Mar 2007 11:12:19 +0100 (CET) Subject: [pypy-svn] r40103 - pypy/dist/pypy/objspace/std Message-ID: <20070309101219.A1EB31006F@code0.codespeak.net> Author: cfbolz Date: Fri Mar 9 11:12:17 2007 New Revision: 40103 Modified: pypy/dist/pypy/objspace/std/typeobject.py Log: 2 ** ... is not rpython, and I keep forgetting it. Modified: pypy/dist/pypy/objspace/std/typeobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/typeobject.py (original) +++ pypy/dist/pypy/objspace/std/typeobject.py Fri Mar 9 11:12:17 2007 @@ -320,7 +320,7 @@ if version_tag is None: tup = w_self._lookup_where(name) return tup - MASK = 2 ** space.config.objspace.std.methodcachesizeexp - 1 + MASK = 1 << space.config.objspace.std.methodcachesizeexp - 1 method_hash = (id(version_tag) ^ position_hash ^ hash(name)) & MASK cached_version_tag = ec.method_cache_versions[method_hash] if cached_version_tag is version_tag: From mwh at codespeak.net Fri Mar 9 12:39:04 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 9 Mar 2007 12:39:04 +0100 (CET) Subject: [pypy-svn] r40107 - pypy/dist/pypy/objspace/std Message-ID: <20070309113904.D82E210072@code0.codespeak.net> Author: mwh Date: Fri Mar 9 12:39:02 2007 New Revision: 40107 Modified: pypy/dist/pypy/objspace/std/objspace.py Log: another int ** int :( Modified: pypy/dist/pypy/objspace/std/objspace.py ============================================================================== --- pypy/dist/pypy/objspace/std/objspace.py (original) +++ pypy/dist/pypy/objspace/std/objspace.py Fri Mar 9 12:39:02 2007 @@ -299,7 +299,7 @@ ec = ObjSpace.createexecutioncontext(self) ec._py_repr = self.newdict() if self.config.objspace.std.withmethodcache: - SIZE = 2 ** self.config.objspace.std.methodcachesizeexp + SIZE = 1 << self.config.objspace.std.methodcachesizeexp ec.method_cache_versions = [None] * SIZE ec.method_cache_names = [None] * SIZE ec.method_cache_lookup_where = [(None, None)] * SIZE From pedronis at codespeak.net Fri Mar 9 14:35:47 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Fri, 9 Mar 2007 14:35:47 +0100 (CET) Subject: [pypy-svn] r40109 - in pypy/dist/pypy: annotation annotation/test interpreter Message-ID: <20070309133547.C940610070@code0.codespeak.net> Author: pedronis Date: Fri Mar 9 14:35:45 2007 New Revision: 40109 Modified: pypy/dist/pypy/annotation/classdef.py pypy/dist/pypy/annotation/description.py pypy/dist/pypy/annotation/test/test_annrpython.py pypy/dist/pypy/interpreter/baseobjspace.py Log: introduce a _settled_ flag that can be attached to classes. method demotion to a "settled" class will trigger an exception. Set _settled_ on W_Root and Wrappable. Modified: pypy/dist/pypy/annotation/classdef.py ============================================================================== --- pypy/dist/pypy/annotation/classdef.py (original) +++ pypy/dist/pypy/annotation/classdef.py Fri Mar 9 14:35:45 2007 @@ -112,12 +112,21 @@ # check for method demotion and after-the-fact method additions if isinstance(s_newvalue, SomePBC): attr = self.name - if not s_newvalue.isNone() and s_newvalue.getKind() == description.MethodDesc: - if homedef.classdesc.read_attribute(attr, None) is None: # is method + if (not s_newvalue.isNone() and + s_newvalue.getKind() == description.MethodDesc): + # is method + if homedef.classdesc.read_attribute(attr, None) is None: if not homedef.check_missing_attribute_update(attr): for desc in s_newvalue.descriptions: if desc.selfclassdef is None: - self.bookkeeper.warning("demoting method %s to base class %s" % + if homedef.classdesc.settled: + raise Exception("demoting method %s " + "to settled class %s not " + "allowed" % + (self.name, homedef) + ) + self.bookkeeper.warning("demoting method %s " + "to base class %s" % (self.name, homedef)) break Modified: pypy/dist/pypy/annotation/description.py ============================================================================== --- pypy/dist/pypy/annotation/description.py (original) +++ pypy/dist/pypy/annotation/description.py Fri Mar 9 14:35:45 2007 @@ -351,6 +351,7 @@ knowntype = type instance_level = False all_enforced_attrs = None # or a set + settled = False def __init__(self, bookkeeper, pyobj=None, name=None, basedesc=None, classdict=None, @@ -400,6 +401,9 @@ if base is not object: self.basedesc = bookkeeper.getdesc(base) + if '_settled_' in cls.__dict__: + self.settled = bool(cls.__dict__['_settled_']) + if '__slots__' in cls.__dict__ or '_attrs_' in cls.__dict__: attrs = {} for decl in ('__slots__', '_attrs_'): 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 Fri Mar 9 14:35:45 2007 @@ -2559,6 +2559,44 @@ a = self.RPythonAnnotator() a.build_types(f, [bool]) + def test_enforce_settled(self): + class A(object): + _settled_ = True + + def m(self): + raise NotImplementedError + + class B(A): + + def m(self): + return 1 + + def n(self): + return 1 + + def fun(x): + if x: + a = A() + else: + a = B() + + return a.m() + + a = self.RPythonAnnotator() + s = a.build_types(fun, [bool]) + assert s.knowntype == int + + def fun(x): + if x: + a = A() + else: + a = B() + + return a.n() + + a = self.RPythonAnnotator() + py.test.raises(Exception, a.build_types, fun, [bool]) + def test_float_cmp(self): def fun(x, y): return (x < y, Modified: pypy/dist/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/dist/pypy/interpreter/baseobjspace.py (original) +++ pypy/dist/pypy/interpreter/baseobjspace.py Fri Mar 9 14:35:45 2007 @@ -14,6 +14,7 @@ """This is the abstract root class of all wrapped objects that live in a 'normal' object space like StdObjSpace.""" __slots__ = () + _settled_ = True def getdict(self): return None @@ -115,6 +116,7 @@ """A subclass of Wrappable is an internal, interpreter-level class that can nevertheless be exposed at application-level by space.wrap().""" __slots__ = () + _settled_ = True def __spacebind__(self, space): return self From pedronis at codespeak.net Fri Mar 9 15:00:31 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Fri, 9 Mar 2007 15:00:31 +0100 (CET) Subject: [pypy-svn] r40110 - in pypy/dist/pypy/objspace: . std Message-ID: <20070309140031.8A9B81006E@code0.codespeak.net> Author: pedronis Date: Fri Mar 9 15:00:27 2007 New Revision: 40110 Modified: pypy/dist/pypy/objspace/std/objecttype.py pypy/dist/pypy/objspace/std/typeobject.py pypy/dist/pypy/objspace/std/typetype.py pypy/dist/pypy/objspace/taint.py Log: Fix taint translation. Don't have methods demoted to W_Root. One more XXX, add some details to another one. Modified: pypy/dist/pypy/objspace/std/objecttype.py ============================================================================== --- pypy/dist/pypy/objspace/std/objecttype.py (original) +++ pypy/dist/pypy/objspace/std/objecttype.py Fri Mar 9 15:00:27 2007 @@ -28,6 +28,8 @@ raise OperationError(space.w_TypeError, space.wrap("__class__ assignment: only for heap types")) w_oldcls = space.type(w_obj) + # XXX taint space should raise a TaintError here if w_oldcls is tainted + assert isinstance(w_oldcls, W_TypeObject) if w_oldcls.get_full_instance_layout() == w_newcls.get_full_instance_layout(): w_obj.setclass(space, w_newcls) else: Modified: pypy/dist/pypy/objspace/std/typeobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/typeobject.py (original) +++ pypy/dist/pypy/objspace/std/typeobject.py Fri Mar 9 15:00:27 2007 @@ -204,7 +204,7 @@ if space.config.objspace.std.withtypeversion: w_self.version_tag = None w_self.mro_w = [] - mro_func = w_type.lookup('mro') + mro_func = space.lookup(w_self, 'mro') mro_func_args = Arguments(space, [w_self]) w_mro = space.call_args(mro_func, mro_func_args) w_self.mro_w = space.unpackiterable(w_mro) Modified: pypy/dist/pypy/objspace/std/typetype.py ============================================================================== --- pypy/dist/pypy/objspace/std/typetype.py (original) +++ pypy/dist/pypy/objspace/std/typetype.py Fri Mar 9 15:00:27 2007 @@ -106,7 +106,7 @@ def mro_internal(space, w_type): if not space.is_w(space.type(w_type), space.w_type): #w_type.mro_w = [] - mro_func = space.type(w_type).lookup('mro') + mro_func = space.lookup(w_type, 'mro') mro_func_args = Arguments(space, [w_type]) w_mro = space.call_args(mro_func, mro_func_args) w_type.mro_w = space.unpackiterable(w_mro) Modified: pypy/dist/pypy/objspace/taint.py ============================================================================== --- pypy/dist/pypy/objspace/taint.py (original) +++ pypy/dist/pypy/objspace/taint.py Fri Mar 9 15:00:27 2007 @@ -205,7 +205,7 @@ self.wrap(app_taint_look)) patch_space_in_place(self, 'taint', proxymaker) - # XXX may leak info, perfomance hit + # XXX may leak info, perfomance hit, what about taint bombs? from pypy.objspace.std.typeobject import W_TypeObject def taint_lookup(w_obj, name): From pedronis at codespeak.net Fri Mar 9 15:36:57 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Fri, 9 Mar 2007 15:36:57 +0100 (CET) Subject: [pypy-svn] r40111 - pypy/dist/demo/sqlinj Message-ID: <20070309143657.DC9C51006F@code0.codespeak.net> Author: pedronis Date: Fri Mar 9 15:36:56 2007 New Revision: 40111 Added: pypy/dist/demo/sqlinj/ pypy/dist/demo/sqlinj/populate.py - copied, changed from r40105, user/pedronis/sqlinj/populate.py pypy/dist/demo/sqlinj/server.py - copied, changed from r40105, user/pedronis/sqlinj/server.py Log: sql injection demo From pedronis at codespeak.net Fri Mar 9 15:40:24 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Fri, 9 Mar 2007 15:40:24 +0100 (CET) Subject: [pypy-svn] r40112 - pypy/dist/demo/sqlinj Message-ID: <20070309144024.147DC10070@code0.codespeak.net> Author: pedronis Date: Fri Mar 9 15:40:23 2007 New Revision: 40112 Added: pypy/dist/demo/sqlinj/tserver.py - copied, changed from r40111, pypy/dist/demo/sqlinj/server.py Modified: pypy/dist/demo/sqlinj/server.py Log: tserver has the hole fixed using the taint space. Modified: pypy/dist/demo/sqlinj/server.py ============================================================================== --- pypy/dist/demo/sqlinj/server.py (original) +++ pypy/dist/demo/sqlinj/server.py Fri Mar 9 15:40:23 2007 @@ -1,5 +1,6 @@ -"""SQL injection example, needs gadfly - (sf.net/projects/gadfly) to be on the python path. +"""SQL injection example + + Needs gadfly (sf.net/projects/gadfly) to be on the python path. Use populate.py to create the example db. From ac at codespeak.net Fri Mar 9 15:54:25 2007 From: ac at codespeak.net (ac at codespeak.net) Date: Fri, 9 Mar 2007 15:54:25 +0100 (CET) Subject: [pypy-svn] r40113 - in pypy/dist/pypy/lib/distributed: . test Message-ID: <20070309145425.A5E971006F@code0.codespeak.net> Author: ac Date: Fri Mar 9 15:54:23 2007 New Revision: 40113 Modified: pypy/dist/pypy/lib/distributed/protocol.py pypy/dist/pypy/lib/distributed/test/test_distributed.py Log: Fix for bound methods of objects that are 'False'. Modified: pypy/dist/pypy/lib/distributed/protocol.py ============================================================================== --- pypy/dist/pypy/lib/distributed/protocol.py (original) +++ pypy/dist/pypy/lib/distributed/protocol.py Fri Mar 9 15:54:23 2007 @@ -183,8 +183,8 @@ tp = self.unwrap(w_class) name = self.unwrap(w_name) self_ = self.unwrap(w_self) - if self_: - if not tp: + if self_ is not None: + if tp is None: setattr(self_, name, classmethod(self.unwrap(w_func))) return getattr(self_, name) return getattr(tp, name).__get__(self_, tp) 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 Fri Mar 9 15:54:23 2007 @@ -30,6 +30,13 @@ assert type(protocol.unwrap(protocol.wrap(f))) is type(f) + def test_method_of_false_obj(self): + from distributed.protocol import AbstractProtocol + protocol = AbstractProtocol() + lst = [] + m = lst.append + assert type(protocol.unwrap(protocol.wrap(m))) is type(m) + def test_protocol_run(self): l = [1,2,3] from distributed.protocol import LocalProtocol From pedronis at codespeak.net Fri Mar 9 16:41:44 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Fri, 9 Mar 2007 16:41:44 +0100 (CET) Subject: [pypy-svn] r40117 - pypy/dist/pypy/doc Message-ID: <20070309154144.627C51006E@code0.codespeak.net> Author: pedronis Date: Fri Mar 9 16:41:42 2007 New Revision: 40117 Modified: pypy/dist/pypy/doc/objspace.txt Log: consistent formatting for types Modified: pypy/dist/pypy/doc/objspace.txt ============================================================================== --- pypy/dist/pypy/doc/objspace.txt (original) +++ pypy/dist/pypy/doc/objspace.txt Fri Mar 9 16:41:42 2007 @@ -382,7 +382,7 @@ From the user's point of view, the multiple internal ``W_XxxObject`` classes are not visible: they are still all instances of exactly the same Python type. PyPy knows that (e.g.) the application-level type of -its interpreter-level ``W_StringObject`` instances is "str" because +its interpreter-level ``W_StringObject`` instances is str because there is a ``typedef`` class attribute in ``W_StringObject`` which points back to the string type specification from `stringtype.py`_; all other implementations of strings use the same ``typedef`` from From mwh at codespeak.net Fri Mar 9 16:42:54 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 9 Mar 2007 16:42:54 +0100 (CET) Subject: [pypy-svn] r40118 - pypy/dist/pypy/translator/benchmark Message-ID: <20070309154254.C9D261006E@code0.codespeak.net> Author: mwh Date: Fri Mar 9 16:42:51 2007 New Revision: 40118 Modified: pypy/dist/pypy/translator/benchmark/benchmarks.py Log: don't crash when the benchmark fails... Modified: pypy/dist/pypy/translator/benchmark/benchmarks.py ============================================================================== --- pypy/dist/pypy/translator/benchmark/benchmarks.py (original) +++ pypy/dist/pypy/translator/benchmark/benchmarks.py Fri Mar 9 16:42:51 2007 @@ -109,7 +109,7 @@ try: result = float([line for line in txt.split('\n') if line.strip()][-1]) except ValueError: - raise IOError(txt) + raise BenchmarkFailed return result def check_templess(): From mwh at codespeak.net Fri Mar 9 18:18:15 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 9 Mar 2007 18:18:15 +0100 (CET) Subject: [pypy-svn] r40132 - pypy/dist/pypy/doc Message-ID: <20070309171815.8DA891006F@code0.codespeak.net> Author: mwh Date: Fri Mar 9 18:18:12 2007 New Revision: 40132 Modified: pypy/dist/pypy/doc/cleanup-todo.txt Log: another thing Modified: pypy/dist/pypy/doc/cleanup-todo.txt ============================================================================== --- pypy/dist/pypy/doc/cleanup-todo.txt (original) +++ pypy/dist/pypy/doc/cleanup-todo.txt Fri Mar 9 18:18:12 2007 @@ -13,6 +13,7 @@ - geninterp is a hack - keepalives need to die, finally - change weakrefs to work together with the GC + - delegate finding type stuff like vtables etc to GC interpreter ----------- From ac at codespeak.net Fri Mar 9 18:19:54 2007 From: ac at codespeak.net (ac at codespeak.net) Date: Fri, 9 Mar 2007 18:19:54 +0100 (CET) Subject: [pypy-svn] r40133 - pypy/dist/pypy/objspace/std Message-ID: <20070309171954.9C34F1006F@code0.codespeak.net> Author: ac Date: Fri Mar 9 18:19:53 2007 New Revision: 40133 Modified: pypy/dist/pypy/objspace/std/typeobject.py Log: (pedronis, arre) Stop the mutated method from moving up to W_Root. Modified: pypy/dist/pypy/objspace/std/typeobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/typeobject.py (original) +++ pypy/dist/pypy/objspace/std/typeobject.py Fri Mar 9 18:19:53 2007 @@ -223,6 +223,7 @@ w_self.version_tag = VersionTag() subclasses_w = w_self.get_subclasses() for w_subclass in subclasses_w: + assert isinstance(w_subclass, W_TypeObject) w_subclass.mutated() def ready(w_self): From afayolle at codespeak.net Fri Mar 9 18:30:01 2007 From: afayolle at codespeak.net (afayolle at codespeak.net) Date: Fri, 9 Mar 2007 18:30:01 +0100 (CET) Subject: [pypy-svn] r40134 - in pypy/dist/pypy/module/recparser: . hooksamples Message-ID: <20070309173001.CEACD10072@code0.codespeak.net> Author: afayolle Date: Fri Mar 9 18:30:00 2007 New Revision: 40134 Modified: pypy/dist/pypy/module/recparser/__init__.py pypy/dist/pypy/module/recparser/app_class.py pypy/dist/pypy/module/recparser/hooksamples/constchanger.py Log: Added ASTMutator app-level class Changed constchanger to use ASTMutator Modified: pypy/dist/pypy/module/recparser/__init__.py ============================================================================== --- pypy/dist/pypy/module/recparser/__init__.py (original) +++ pypy/dist/pypy/module/recparser/__init__.py Fri Mar 9 18:30:00 2007 @@ -18,6 +18,7 @@ appleveldefs = { 'ParserError' : 'app_class.ParserError', 'ASTVisitor': 'app_class.ASTVisitor', + 'ASTMutator': 'app_class.ASTMutator', } interpleveldefs = { '__name__' : '(space.wrap("parser"))', Modified: pypy/dist/pypy/module/recparser/app_class.py ============================================================================== --- pypy/dist/pypy/module/recparser/app_class.py (original) +++ pypy/dist/pypy/module/recparser/app_class.py Fri Mar 9 18:30:00 2007 @@ -20,11 +20,8 @@ def visitExpression(self, node): return self.default(node) - def visitEmptyNode(self, node): return self.default(node) - - def visitAbstractFunction(self, node): return self.default( node ) def visitAbstractTest(self, node): @@ -183,3 +180,11 @@ return self.default( node ) def visitYield(self, node): return self.default( node ) + +class ASTMutator(ASTVisitor): + """This class is similar to ASTVisitor, but will call + node.mutate(self) instead of node.accept(self). The visitXXX + methods of derived class should return the mutated node""" + def default(self, node): + return node + Modified: pypy/dist/pypy/module/recparser/hooksamples/constchanger.py ============================================================================== --- pypy/dist/pypy/module/recparser/hooksamples/constchanger.py (original) +++ pypy/dist/pypy/module/recparser/hooksamples/constchanger.py Fri Mar 9 18:30:00 2007 @@ -1,21 +1,14 @@ -class ChangeConstVisitor: +import parser +class ConstMutator(parser.ASTMutator): def visitConst(self, node): if node.value == 3: node.value = 2 + return node - 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()) + ast.mutate(ConstMutator()) return ast # install the hook -import parser parser.install_compiler_hook(threebecomestwo) +print eval('3*2') From arigo at codespeak.net Fri Mar 9 23:21:38 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 9 Mar 2007 23:21:38 +0100 (CET) Subject: [pypy-svn] r40148 - pypy/dist/pypy/translator/benchmark Message-ID: <20070309222138.7A13A1006F@code0.codespeak.net> Author: arigo Date: Fri Mar 9 23:21:35 2007 New Revision: 40148 Modified: pypy/dist/pypy/translator/benchmark/result.py Log: Improve table column titles. Modified: pypy/dist/pypy/translator/benchmark/result.py ============================================================================== --- pypy/dist/pypy/translator/benchmark/result.py (original) +++ pypy/dist/pypy/translator/benchmark/result.py Fri Mar 9 23:21:35 2007 @@ -1,12 +1,17 @@ import os, pickle, sys, time, re -stat2title = { +STAT2TITLE = { 'stat:st_mtime': "date", 'exe_name': "executable", - 'bench:richards': "richards", - 'bench:pystone': "pystone", } +def stat2title(s): + if s.startswith('bench:'): + return s[6:] + else: + return STAT2TITLE.get(s, s) + + class BenchmarkResultSet(object): def __init__(self, max_results=10): self.benchmarks = {} @@ -27,7 +32,7 @@ filteron = kw['filteron'] lst = [r for r in lst if filteron(r)] relto = kw.get('relto', None) - table = [[(stat2title.get(s,s),0) for s in stats]] + table = [[(stat2title(s),0) for s in stats]] for r in lst: row = [] for stat in stats: From arigo at codespeak.net Fri Mar 9 23:42:45 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 9 Mar 2007 23:42:45 +0100 (CET) Subject: [pypy-svn] r40150 - in pypy: benchmark dist/pypy/translator/benchmark Message-ID: <20070309224245.13A9910070@code0.codespeak.net> Author: arigo Date: Fri Mar 9 23:42:44 2007 New Revision: 40150 Removed: pypy/benchmark/ Modified: pypy/dist/pypy/translator/benchmark/ (props changed) pypy/dist/pypy/translator/benchmark/benchmarks.py Log: Changed my mind about the top-level benchmark directory. It's just as easy to add calls to 'svn co' from benchmark.py instead of playing with svn:externals, and avoids spreading things too much around. Modified: pypy/dist/pypy/translator/benchmark/benchmarks.py ============================================================================== --- pypy/dist/pypy/translator/benchmark/benchmarks.py (original) +++ pypy/dist/pypy/translator/benchmark/benchmarks.py Fri Mar 9 23:42:44 2007 @@ -32,6 +32,18 @@ except BenchmarkFailed: return '-FAILED-' +def external_dependency(dirname, svnurl, revision): + """Check out (if necessary) a given fixed revision of a svn url.""" + dirpath = py.magic.autopath().dirpath().join(dirname) + if not dirpath.check(): + CMD = "svn co -r%d %s@%d %s" % (revision, svnurl, revision, dirpath) + print >> sys.stderr, CMD + err = os.system(CMD) + if err != 0: + print >> sys.stderr, "* checkout failed, skipping this benchmark" + return False + return True + def run_cmd(cmd): #print "running", cmd pipe = os.popen(cmd + ' 2>&1') @@ -64,8 +76,7 @@ return r def run_docutils(executable='/usr/local/bin/python'): - docutilssvnpathfile = py.magic.autopath().dirpath().join("docutilssvnpath") - docutilssvnpath = docutilssvnpathfile.read().strip() + docutilssvnpath = 'docutils' # subdir of the local dir translatetxt = py.magic.autopath().dirpath().dirpath().dirpath().join('doc').join('translation.txt') command = """import sys sys.modules['unicodedata'] = sys # docutils need 'import unicodedata' to work, but no more... @@ -90,14 +101,15 @@ return r def check_docutils(): - docutilssvnpathfile = py.magic.autopath().dirpath().join("docutilssvnpath") - return docutilssvnpathfile.check() + return external_dependency('docutils', + 'svn://svn.berlios.de/docutils/trunk/docutils', + 4821) def run_templess(executable='/usr/local/bin/python'): """ run some script in the templess package templess is some simple templating language, to check out use - 'svn co http://johnnydebris.net/templess/trunk templess' + 'svn co -r100 http://johnnydebris.net/templess/trunk templess' """ here = py.magic.autopath().dirpath() pypath = py.__package__.getpath().dirpath() @@ -113,11 +125,12 @@ return result def check_templess(): - templessdir = py.magic.autopath().dirpath().join('templess') - return templessdir.check() - + return external_dependency('templess', + 'http://johnnydebris.net/templess/trunk', + 100) + def check_translate(): - return False + return False # XXX what should we do about the dependency on ctypes? BENCHMARKS = [Benchmark('richards', run_richards, RICHARDS_ASCENDING_GOOD, 'ms'), Benchmark('pystone', run_pystone, PYSTONE_ASCENDING_GOOD, ''), From santagada at codespeak.net Sat Mar 10 03:44:50 2007 From: santagada at codespeak.net (santagada at codespeak.net) Date: Sat, 10 Mar 2007 03:44:50 +0100 (CET) Subject: [pypy-svn] r40153 - in pypy/dist/pypy/lang/js: . test/ecma Message-ID: <20070310024450.9729D10072@code0.codespeak.net> Author: santagada Date: Sat Mar 10 03:44:48 2007 New Revision: 40153 Modified: pypy/dist/pypy/lang/js/interpreter.py pypy/dist/pypy/lang/js/jsobj.py pypy/dist/pypy/lang/js/test/ecma/conftest.py Log: last changes before reinstalling python Modified: pypy/dist/pypy/lang/js/interpreter.py ============================================================================== --- pypy/dist/pypy/lang/js/interpreter.py (original) +++ pypy/dist/pypy/lang/js/interpreter.py Sat Mar 10 03:44:48 2007 @@ -16,10 +16,11 @@ temp_tree = parse_bytecode(bytecode) return from_tree(temp_tree) +import cPickle as pickle +import os.path + def load_file(filename): # NOT RPYTHON - import cPickle as pickle - import os.path base, ext = os.path.splitext(filename) jscname = base+".jsc" if os.path.isfile(jscname): Modified: pypy/dist/pypy/lang/js/jsobj.py ============================================================================== --- pypy/dist/pypy/lang/js/jsobj.py (original) +++ pypy/dist/pypy/lang/js/jsobj.py Sat Mar 10 03:44:48 2007 @@ -303,6 +303,7 @@ if x > self.Get('length').ToNumber() - 1: currsize = len(self.array) self.propdict['length'].value = W_Number(x+1) + print 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/ecma/conftest.py ============================================================================== --- pypy/dist/pypy/lang/js/test/ecma/conftest.py (original) +++ pypy/dist/pypy/lang/js/test/ecma/conftest.py Sat Mar 10 03:44:48 2007 @@ -61,6 +61,8 @@ raise Failed(msg="Syntax Error",excinfo=py.code.ExceptionInfo()) except JsBaseExcept: raise Failed(msg="Javascript Error", excinfo=py.code.ExceptionInfo()) + except: + raise Failed(excinfo=py.code.ExceptionInfo()) testcases = self.interp.global_context.resolve_identifier('testcases') self.tc = self.interp.global_context.resolve_identifier('tc') testcount = testcases.GetValue().Get('length').GetValue().ToInt32() From arigo at codespeak.net Sat Mar 10 11:38:27 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 10 Mar 2007 11:38:27 +0100 (CET) Subject: [pypy-svn] r40155 - in pypy/dist/pypy/objspace: . test Message-ID: <20070310103827.ACFE110075@code0.codespeak.net> Author: arigo Date: Sat Mar 10 11:38:26 2007 New Revision: 40155 Modified: pypy/dist/pypy/objspace/descroperation.py pypy/dist/pypy/objspace/test/test_descroperation.py Log: Test and fix for a segfault. Modified: pypy/dist/pypy/objspace/descroperation.py ============================================================================== --- pypy/dist/pypy/objspace/descroperation.py (original) +++ pypy/dist/pypy/objspace/descroperation.py Sat Mar 10 11:38:26 2007 @@ -124,6 +124,8 @@ def getattr(space, w_obj, w_name): w_descr = space.lookup(w_obj, '__getattribute__') try: + if w_descr is None: # obscure case + raise OperationError(space.w_AttributeError, space.w_None) return space.get_and_call_function(w_descr, w_obj, w_name) except OperationError, e: if not e.match(space, space.w_AttributeError): 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 Sat Mar 10 11:38:26 2007 @@ -268,3 +268,15 @@ assert type(operate(A())) is str answer = 42 raises(TypeError, operate, A()) + + def test_missing_getattribute(self): + class X(object): pass + + class Y(X): + class __metaclass__(type): + def mro(cls): + return [cls, X] + + x = X() + x.__class__ = Y + raises(AttributeError, getattr, x, 'a') From arigo at codespeak.net Sat Mar 10 11:49:32 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 10 Mar 2007 11:49:32 +0100 (CET) Subject: [pypy-svn] r40156 - pypy/dist/pypy/interpreter Message-ID: <20070310104932.BC0BA10079@code0.codespeak.net> Author: arigo Date: Sat Mar 10 11:49:31 2007 New Revision: 40156 Modified: pypy/dist/pypy/interpreter/callmethod.py Log: * stick even closer to the logic of space.getattr() in CALL_METHOD * avoid the allocation of a temporary tuple Modified: pypy/dist/pypy/interpreter/callmethod.py ============================================================================== --- pypy/dist/pypy/interpreter/callmethod.py (original) +++ pypy/dist/pypy/interpreter/callmethod.py Sat Mar 10 11:49:31 2007 @@ -13,6 +13,13 @@ from pypy.interpreter import pyframe, function +def object_getattribute(space): + w_src, w_getattribute = space.lookup_in_type_where(space.w_object, + '__getattribute__') + return w_getattribute +object_getattribute._annspecialcase_ = 'specialize:memo' + + class __extend__(pyframe.PyFrame): def LOOKUP_METHOD(f, nameindex, *ignored): @@ -27,18 +34,16 @@ 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): + w_getattribute = space.lookup(w_obj, '__getattribute__') + if w_getattribute is object_getattribute(space): name = space.str_w(w_name) w_descr = space.lookup(w_obj, name) - descr = space.interpclass_w(w_descr) - if descr is None: + if w_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: + elif type(w_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, From pedronis at codespeak.net Sat Mar 10 12:30:29 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 10 Mar 2007 12:30:29 +0100 (CET) Subject: [pypy-svn] r40158 - in pypy/dist/pypy: interpreter objspace/std objspace/std/test Message-ID: <20070310113029.A395E10078@code0.codespeak.net> Author: pedronis Date: Sat Mar 10 12:30:28 2007 New Revision: 40158 Modified: pypy/dist/pypy/interpreter/typedef.py pypy/dist/pypy/objspace/std/dictmultiobject.py pypy/dist/pypy/objspace/std/test/test_shadowtracking.py Log: (pedronis, cfbolz) test and fix for shadowtracking. Modified: pypy/dist/pypy/interpreter/typedef.py ============================================================================== --- pypy/dist/pypy/interpreter/typedef.py (original) +++ pypy/dist/pypy/interpreter/typedef.py Sat Mar 10 12:30:28 2007 @@ -204,13 +204,12 @@ # only used by descr_set___class__ self.w__class__ = w_subtype if space.config.objspace.std.withshadowtracking: - self.w__dict__.implementation.shadows_anything = True + self.w__dict__.implementation.set_shadows_anything() def getdictvalue_attr_is_in_class(self, space, w_name): w_dict = self.w__dict__ if space.config.objspace.std.withshadowtracking: - if (not w_dict.implementation.shadows_anything and - self.w__class__.version_tag is not None): + if not w_dict.implementation.shadows_anything(): return None return space.finditem(w_dict, w_name) Modified: pypy/dist/pypy/objspace/std/dictmultiobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/dictmultiobject.py (original) +++ pypy/dist/pypy/objspace/std/dictmultiobject.py Sat Mar 10 12:30:28 2007 @@ -94,8 +94,12 @@ w_key = self.space.wrap(OPTIMIZED_BUILTINS[i]) return self.get(w_key) -# this attribute will only be seen whan a certain config option is used - shadows_anything = True +# this method will only be seen whan a certain config option is used + def shadows_anything(self): + return True + + def set_shadows_anything(self): + pass # Iterator Implementation base classes @@ -511,26 +515,37 @@ def __init__(self, space, w_type): StrDictImplementation.__init__(self, space) self.w_type = w_type - self.shadows_anything = False + self.original_version_tag = w_type.version_tag + if self.original_version_tag is None: + self._shadows_anything = True + else: + self._shadows_anything = False def setitem_str(self, w_key, w_value, shadows_type=True): if shadows_type: - self.shadows_anything = True + self._shadows_anything = True return StrDictImplementation.setitem_str( self, w_key, w_value, shadows_type) def setitem(self, w_key, w_value): space = self.space if space.is_w(space.type(w_key), space.w_str): - if not self.shadows_anything: + if not self._shadows_anything: w_obj = self.w_type.lookup(space.str_w(w_key)) if w_obj is not None: - self.shadows_anything = True + self._shadows_anything = True return StrDictImplementation.setitem_str( self, w_key, w_value, False) else: return self._as_rdict().setitem(w_key, w_value) + def shadows_anything(self): + return (self._shadows_anything or + self.w_type.version_tag is not self.original_version_tag) + + def set_shadows_anything(self): + self._shadows_anything = True + class WaryDictImplementation(StrDictImplementation): def __init__(self, space): StrDictImplementation.__init__(self, space) 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 Sat Mar 10 12:30:28 2007 @@ -13,15 +13,15 @@ a = A() return a """) - assert not w_inst.w__dict__.implementation.shadows_anything + assert not w_inst.w__dict__.implementation.shadows_anything() space.appexec([w_inst], """(a): a.g = "foo" """) - assert not w_inst.w__dict__.implementation.shadows_anything + assert not w_inst.w__dict__.implementation.shadows_anything() space.appexec([w_inst], """(a): a.f = "foo" """) - assert w_inst.w__dict__.implementation.shadows_anything + assert w_inst.w__dict__.implementation.shadows_anything() def test_shadowing_via__dict__(self): space = self.space @@ -32,15 +32,15 @@ a = A() return a """) - assert not w_inst.w__dict__.implementation.shadows_anything + assert not w_inst.w__dict__.implementation.shadows_anything() space.appexec([w_inst], """(a): a.__dict__["g"] = "foo" """) - assert not w_inst.w__dict__.implementation.shadows_anything + assert not w_inst.w__dict__.implementation.shadows_anything() space.appexec([w_inst], """(a): a.__dict__["f"] = "foo" """) - assert w_inst.w__dict__.implementation.shadows_anything + assert w_inst.w__dict__.implementation.shadows_anything() def test_changing__dict__(self): space = self.space @@ -51,11 +51,11 @@ a = A() return a """) - assert not w_inst.w__dict__.implementation.shadows_anything + assert not w_inst.w__dict__.implementation.shadows_anything() space.appexec([w_inst], """(a): a.__dict__ = {} """) - assert w_inst.w__dict__.implementation.shadows_anything + assert w_inst.w__dict__.implementation.shadows_anything() def test_changing__class__(self): space = self.space @@ -66,14 +66,31 @@ a = A() return a """) - assert not w_inst.w__dict__.implementation.shadows_anything + assert not w_inst.w__dict__.implementation.shadows_anything() space.appexec([w_inst], """(a): class B(object): def g(self): return 42 a.__class__ = B """) - assert w_inst.w__dict__.implementation.shadows_anything + assert w_inst.w__dict__.implementation.shadows_anything() + + def test_changing_the_type(self): + space = self.space + w_inst = space.appexec([], """(): + class A(object): + pass + a = A() + a.x = 72 + return a + """) + assert not w_inst.w__dict__.implementation.shadows_anything() + w_x = space.appexec([w_inst], """(a): + a.__class__.x = 42 + return a.x + """) + assert space.unwrap(w_x) == 72 + assert w_inst.w__dict__.implementation.shadows_anything() class AppTestShadowTracking(object): def setup_class(cls): From arigo at codespeak.net Sat Mar 10 13:18:49 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 10 Mar 2007 13:18:49 +0100 (CET) Subject: [pypy-svn] r40159 - pypy/dist/pypy/interpreter Message-ID: <20070310121849.CFD8F10063@code0.codespeak.net> Author: arigo Date: Sat Mar 10 13:18:47 2007 New Revision: 40159 Modified: pypy/dist/pypy/interpreter/callmethod.py Log: Inline all the logic in callmethod, and try to clean things up a bit. Still hugeish code. Modified: pypy/dist/pypy/interpreter/callmethod.py ============================================================================== --- pypy/dist/pypy/interpreter/callmethod.py (original) +++ pypy/dist/pypy/interpreter/callmethod.py Sat Mar 10 13:18:47 2007 @@ -11,13 +11,8 @@ """ from pypy.interpreter import pyframe, function - - -def object_getattribute(space): - w_src, w_getattribute = space.lookup_in_type_where(space.w_object, - '__getattribute__') - return w_getattribute -object_getattribute._annspecialcase_ = 'specialize:memo' +from pypy.interpreter.error import OperationError +from pypy.objspace.descroperation import DescrOperation, raiseattrerror class __extend__(pyframe.PyFrame): @@ -34,16 +29,18 @@ space = f.space w_obj = f.popvalue() w_name = f.getname_w(nameindex) - w_value = None - w_getattribute = space.lookup(w_obj, '__getattribute__') - if w_getattribute is object_getattribute(space): + if isinstance(space, DescrOperation): + w_getattribute = space.lookup(w_obj, '__getattribute__') + ok_to_optimize = w_getattribute is object_getattribute(space) + else: + ok_to_optimize = False + + if not ok_to_optimize: + w_value = space.getattr(w_obj, w_name) + else: name = space.str_w(w_name) w_descr = space.lookup(w_obj, name) - if w_descr is None: - # this handles directly the common case - # module.function(args..) - w_value = w_obj.getdictvalue(space, w_name) - elif type(w_descr) is function.Function: + if type(w_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, @@ -51,8 +48,13 @@ f.pushvalue(w_descr) f.pushvalue(w_obj) return - if w_value is None: - w_value = space.getattr(w_obj, w_name) + # else we have a function object in the class, but shadowed + # by an instance attribute + else: + # anything else than a function object in the class + # => use the default lookup logic, without re-looking-up + # w_descr and __getattribute__, though + w_value = default_lookup_logic(space, w_obj, w_descr, w_name) f.pushvalue(w_value) f.pushvalue(None) @@ -66,3 +68,37 @@ finally: f.dropvalues(nargs + 2) f.pushvalue(w_result) + + +def object_getattribute(space): + w_src, w_getattribute = space.lookup_in_type_where(space.w_object, + '__getattribute__') + return w_getattribute +object_getattribute._annspecialcase_ = 'specialize:memo' + + +def default_getattribute(space, w_obj, w_descr, w_name): + # code copied from descroperation.Object.descr__getattribute__() + if w_descr is not None: + if space.is_data_descr(w_descr): + return space.get(w_descr, w_obj) + w_value = w_obj.getdictvalue_attr_is_in_class(space, w_name) + else: + w_value = w_obj.getdictvalue(space, w_name) + if w_value is not None: + return w_value + if w_descr is not None: + return space.get(w_descr, w_obj) + raiseattrerror(space, w_obj, space.str_w(w_name)) + +def default_lookup_logic(space, w_obj, w_descr, w_name): + # code copied from descroperation.DescrOperation.getattr() + try: + return default_getattribute(space, w_obj, w_descr, w_name) + except OperationError, e: + if not e.match(space, space.w_AttributeError): + raise + w_descr = space.lookup(w_obj, '__getattr__') + if w_descr is None: + raise + return space.get_and_call_function(w_descr, w_obj, w_name) From arigo at codespeak.net Sat Mar 10 14:01:34 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 10 Mar 2007 14:01:34 +0100 (CET) Subject: [pypy-svn] r40160 - pypy/dist/pypy/translator/benchmark Message-ID: <20070310130134.C50B41006F@code0.codespeak.net> Author: arigo Date: Sat Mar 10 14:01:32 2007 New Revision: 40160 Modified: pypy/dist/pypy/translator/benchmark/benchmarks.py Log: Disable docutils benchmark by default. Modified: pypy/dist/pypy/translator/benchmark/benchmarks.py ============================================================================== --- pypy/dist/pypy/translator/benchmark/benchmarks.py (original) +++ pypy/dist/pypy/translator/benchmark/benchmarks.py Sat Mar 10 14:01:32 2007 @@ -101,9 +101,11 @@ return r def check_docutils(): - return external_dependency('docutils', - 'svn://svn.berlios.de/docutils/trunk/docutils', - 4821) + return False # useless benchmark - I've seen 15% of difference + # between two successive runs on the same machine! + #return external_dependency('docutils', + # 'svn://svn.berlios.de/docutils/trunk/docutils', + # 4821) def run_templess(executable='/usr/local/bin/python'): """ run some script in the templess package From arigo at codespeak.net Sat Mar 10 14:45:30 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 10 Mar 2007 14:45:30 +0100 (CET) Subject: [pypy-svn] r40161 - pypy/dist/pypy/interpreter Message-ID: <20070310134530.E37251006F@code0.codespeak.net> Author: arigo Date: Sat Mar 10 14:45:29 2007 New Revision: 40161 Modified: pypy/dist/pypy/interpreter/callmethod.py Log: Revert this change for now. It's still in the svn history, and (little though I trust them) the measures say it makes things slower. Nonsense, but at least it's less code. Modified: pypy/dist/pypy/interpreter/callmethod.py ============================================================================== --- pypy/dist/pypy/interpreter/callmethod.py (original) +++ pypy/dist/pypy/interpreter/callmethod.py Sat Mar 10 14:45:29 2007 @@ -11,8 +11,13 @@ """ from pypy.interpreter import pyframe, function -from pypy.interpreter.error import OperationError -from pypy.objspace.descroperation import DescrOperation, raiseattrerror + + +def object_getattribute(space): + w_src, w_getattribute = space.lookup_in_type_where(space.w_object, + '__getattribute__') + return w_getattribute +object_getattribute._annspecialcase_ = 'specialize:memo' class __extend__(pyframe.PyFrame): @@ -29,18 +34,16 @@ space = f.space w_obj = f.popvalue() w_name = f.getname_w(nameindex) - if isinstance(space, DescrOperation): - w_getattribute = space.lookup(w_obj, '__getattribute__') - ok_to_optimize = w_getattribute is object_getattribute(space) - else: - ok_to_optimize = False - - if not ok_to_optimize: - w_value = space.getattr(w_obj, w_name) - else: + w_value = None + w_getattribute = space.lookup(w_obj, '__getattribute__') + if w_getattribute is object_getattribute(space): name = space.str_w(w_name) w_descr = space.lookup(w_obj, name) - if type(w_descr) is function.Function: + if w_descr is None: + # this handles directly the common case + # module.function(args..) + w_value = w_obj.getdictvalue(space, w_name) + elif type(w_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, @@ -48,13 +51,8 @@ f.pushvalue(w_descr) f.pushvalue(w_obj) return - # else we have a function object in the class, but shadowed - # by an instance attribute - else: - # anything else than a function object in the class - # => use the default lookup logic, without re-looking-up - # w_descr and __getattribute__, though - w_value = default_lookup_logic(space, w_obj, w_descr, w_name) + if w_value is None: + w_value = space.getattr(w_obj, w_name) f.pushvalue(w_value) f.pushvalue(None) @@ -68,37 +66,3 @@ finally: f.dropvalues(nargs + 2) f.pushvalue(w_result) - - -def object_getattribute(space): - w_src, w_getattribute = space.lookup_in_type_where(space.w_object, - '__getattribute__') - return w_getattribute -object_getattribute._annspecialcase_ = 'specialize:memo' - - -def default_getattribute(space, w_obj, w_descr, w_name): - # code copied from descroperation.Object.descr__getattribute__() - if w_descr is not None: - if space.is_data_descr(w_descr): - return space.get(w_descr, w_obj) - w_value = w_obj.getdictvalue_attr_is_in_class(space, w_name) - else: - w_value = w_obj.getdictvalue(space, w_name) - if w_value is not None: - return w_value - if w_descr is not None: - return space.get(w_descr, w_obj) - raiseattrerror(space, w_obj, space.str_w(w_name)) - -def default_lookup_logic(space, w_obj, w_descr, w_name): - # code copied from descroperation.DescrOperation.getattr() - try: - return default_getattribute(space, w_obj, w_descr, w_name) - except OperationError, e: - if not e.match(space, space.w_AttributeError): - raise - w_descr = space.lookup(w_obj, '__getattr__') - if w_descr is None: - raise - return space.get_and_call_function(w_descr, w_obj, w_name) From arigo at codespeak.net Sat Mar 10 15:27:05 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 10 Mar 2007 15:27:05 +0100 (CET) Subject: [pypy-svn] r40163 - pypy/dist/pypy/config Message-ID: <20070310142705.6057E1006E@code0.codespeak.net> Author: arigo Date: Sat Mar 10 15:27:04 2007 New Revision: 40163 Modified: pypy/dist/pypy/config/pypyoption.py Log: 'withmethodcache' does not need 'withshadowtracking' any more, nor even multidicts, but only the version_tag on types. WARNING benchmarkers, future translations with the method cache won't include shadow tracking and multidicts by default now! Modified: pypy/dist/pypy/config/pypyoption.py ============================================================================== --- pypy/dist/pypy/config/pypyoption.py (original) +++ pypy/dist/pypy/config/pypyoption.py Sat Mar 10 15:27:04 2007 @@ -189,7 +189,7 @@ BoolOption("withmethodcache", "try to cache method lookups", default=False, - requires=[("objspace.std.withshadowtracking", True)]), + requires=[("objspace.std.withtypeversion", True)]), BoolOption("withmethodcachecounter", "try to cache methods and provide a counter in pypymagic. " "for testing purposes only.", From arigo at codespeak.net Sat Mar 10 15:29:40 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 10 Mar 2007 15:29:40 +0100 (CET) Subject: [pypy-svn] r40164 - pypy/dist/pypy/objspace/std Message-ID: <20070310142940.D61651006E@code0.codespeak.net> Author: arigo Date: Sat Mar 10 15:29:39 2007 New Revision: 40164 Modified: pypy/dist/pypy/objspace/std/typeobject.py Log: There is no longer a good reason for the method cache to depend on the bytecode position, so let's comment it out. That's less code and less things to explain in the EU report :-) Modified: pypy/dist/pypy/objspace/std/typeobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/typeobject.py (original) +++ pypy/dist/pypy/objspace/std/typeobject.py Sat Mar 10 15:29:39 2007 @@ -312,21 +312,22 @@ space = w_self.space assert space.config.objspace.std.withmethodcache ec = space.getexecutioncontext() - try: - frame = ec.framestack.top() - position_hash = frame.last_instr ^ id(frame.pycode) - except IndexError: - position_hash = 0 + #try: + # frame = ec.framestack.top() + # position_hash = frame.last_instr ^ id(frame.pycode) + #except IndexError: + # position_hash = 0 version_tag = w_self.version_tag if version_tag is None: tup = w_self._lookup_where(name) return tup MASK = 1 << space.config.objspace.std.methodcachesizeexp - 1 - method_hash = (id(version_tag) ^ position_hash ^ hash(name)) & MASK + #method_hash = (id(version_tag) ^ position_hash ^ hash(name)) & MASK + method_hash = ((id(version_tag) >> 3) ^ hash(name)) & MASK cached_version_tag = ec.method_cache_versions[method_hash] if cached_version_tag is version_tag: cached_name = ec.method_cache_names[method_hash] - if cached_name == name: + if cached_name is name: tup = ec.method_cache_lookup_where[method_hash] if space.config.objspace.std.withmethodcachecounter: ec.method_cache_hits[name] = \ From arigo at codespeak.net Sat Mar 10 16:26:58 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 10 Mar 2007 16:26:58 +0100 (CET) Subject: [pypy-svn] r40166 - pypy/dist/pypy/objspace/std Message-ID: <20070310152658.C8FC51006F@code0.codespeak.net> Author: arigo Date: Sat Mar 10 16:26:57 2007 New Revision: 40166 Modified: pypy/dist/pypy/objspace/std/typeobject.py Log: Argh! Argh! Argh! Argh. Modified: pypy/dist/pypy/objspace/std/typeobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/typeobject.py (original) +++ pypy/dist/pypy/objspace/std/typeobject.py Sat Mar 10 16:26:57 2007 @@ -321,7 +321,7 @@ if version_tag is None: tup = w_self._lookup_where(name) return tup - MASK = 1 << space.config.objspace.std.methodcachesizeexp - 1 + MASK = (1 << space.config.objspace.std.methodcachesizeexp) - 1 #method_hash = (id(version_tag) ^ position_hash ^ hash(name)) & MASK method_hash = ((id(version_tag) >> 3) ^ hash(name)) & MASK cached_version_tag = ec.method_cache_versions[method_hash] From arigo at codespeak.net Sat Mar 10 16:39:27 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 10 Mar 2007 16:39:27 +0100 (CET) Subject: [pypy-svn] r40167 - pypy/dist/pypy/objspace/std/test Message-ID: <20070310153927.AF7611006F@code0.codespeak.net> Author: arigo Date: Sat Mar 10 16:39:26 2007 New Revision: 40167 Modified: pypy/dist/pypy/objspace/std/test/test_shadowtracking.py Log: (pedronis, arigo) Better tests for method caching, though in theory they can fail if there are too many collisions. 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 Sat Mar 10 16:39:26 2007 @@ -126,6 +126,7 @@ for i, a in enumerate(l): assert a.f() == 42 + i % 3 cache_counter = pypymagic.method_cache_counter("f") + assert cache_counter[0] >= 15 assert cache_counter[1] >= 3 # should be (27, 3) assert sum(cache_counter) == 30 @@ -149,6 +150,7 @@ for i, a in enumerate(l): assert a.f() == 42 + i % 3 cache_counter = pypymagic.method_cache_counter("f") + assert cache_counter[0] >= 9 assert cache_counter[1] >= 2 # should be (18, 2) assert sum(cache_counter) == 20 @@ -180,6 +182,32 @@ for i, a in enumerate(l): assert a.f() == 42 + (i % 3 == 1) cache_counter = pypymagic.method_cache_counter("f") + assert cache_counter[0] >= 15 assert cache_counter[1] >= 3 # should be (27, 3) assert sum(cache_counter) == 30 + def test_many_names(self): + import pypymagic + class A(object): + foo = 5 + bar = 6 + baz = 7 + xyz = 8 + stuff = 9 + a = 10 + foobar = 11 + + a = A() + names = [name for name in A.__dict__.keys() + if not name.startswith('_')] + names_repeated = names * 10 + result = [] + pypymagic.reset_method_cache_counter() + for name in names_repeated: + result.append(getattr(a, name)) + append_counter = pypymagic.method_cache_counter("append") + names_counters = [pypymagic.method_cache_counter(name) + for name in names] + assert append_counter[0] >= 5 * len(names) + for name, count in zip(names, names_counters): + assert count >= 5 From cfbolz at codespeak.net Sat Mar 10 17:45:13 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sat, 10 Mar 2007 17:45:13 +0100 (CET) Subject: [pypy-svn] r40169 - pypy/dist/pypy/doc Message-ID: <20070310164513.0535D1006E@code0.codespeak.net> Author: cfbolz Date: Sat Mar 10 17:45:13 2007 New Revision: 40169 Modified: pypy/dist/pypy/doc/news.txt Log: add news item about the end of the sprint Modified: pypy/dist/pypy/doc/news.txt ============================================================================== --- pypy/dist/pypy/doc/news.txt (original) +++ pypy/dist/pypy/doc/news.txt Sat Mar 10 17:45:13 2007 @@ -15,6 +15,27 @@ .. _`iCalendar format`: webcal://pypycal.sabi.net///calendars/PyPy.ics .. _eventhistory: eventhistory.html +PyPy Trillke Sprints (25-28th Feb and 1-5th March 2007) finished, +================================================================== + +Both of the sprints that mark the end of the EU period are over. There were very +good results, both on a `report level`_ as well as on a `technical level`_. +The sprint also had a good discussion about the future of PyPy after the EU +project ends, see the `mail Armin wrote`_ and `the meeting's minutes`_. You can +also look at the pictures that `Carl Friedrich`_ and that `Lene took`_ during +the sprint or read the `sprint announcement`_. *(March 10th, 2007)* + +.. _`sprint announcement`: http://codespeak.net/pypy/extradoc/sprintinfo/trillke-2007/announcement.html +.. _`report level`: http://codespeak.net/pipermail/pypy-dev/2007q1/003578.html +.. _`technical level`: http://codespeak.net/pipermail/pypy-dev/2007q1/003579.html +.. _`Carl Friedrich`: http://codespeak.net/~cfbolz/hildesheim3-sprint-pictures/ +.. _`Lene took`: http://codespeak.net/~lene/trillke-sprint-web/Page1.html +.. _`mail Armin wrote`: http://codespeak.net/pipermail/pypy-dev/2007q1/003577.html +.. _`the meeting's minutes`: http://codespeak.net/svn/pypy/extradoc/minute/post-eu-structure.txt + + + + PyPy 0.99.0: optimizations, backends, new object spaces and more ================================================================== @@ -32,19 +53,8 @@ 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 -================================================================== - -The end of the EU project period is nearing and we are going -for two sprints, one on particular EU related issues and -one for public coding and discussing the time ahead. -Read the `full announcement here`_ and `people known to come`_ already. +*(February 15th, 2007)* -.. _`full announcement here`: http://codespeak.net/pypy/extradoc/sprintinfo/trillke-2007/announcement.html -.. _`people known to come`: http://codespeak.net/pypy/extradoc/sprintinfo/trillke-2007/people.html Leysin Winter Sports Sprint, 8th - 14th January 2007 From arigo at codespeak.net Sat Mar 10 18:03:42 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 10 Mar 2007 18:03:42 +0100 (CET) Subject: [pypy-svn] r40170 - pypy/dist/pypy/config Message-ID: <20070310170342.56B6110072@code0.codespeak.net> Author: arigo Date: Sat Mar 10 18:03:39 2007 New Revision: 40170 Modified: pypy/dist/pypy/config/pypyoption.py Log: Explicitly include multidicts in a faassen build. Explicit is better than implicit (via withshadowtracking...) Modified: pypy/dist/pypy/config/pypyoption.py ============================================================================== --- pypy/dist/pypy/config/pypyoption.py (original) +++ pypy/dist/pypy/config/pypyoption.py Sat Mar 10 18:03:39 2007 @@ -232,6 +232,7 @@ ("translation.withsmallfuncsets", 5), ("translation.profopt", "-c 'from richards import main;main(); from test import pystone; pystone.main()'"), + ("objspace.std.withmultidict", True), ("objspace.std.withstrjoin", True), ("objspace.std.withshadowtracking", True), ("objspace.std.withstrslice", True), From xoraxax at codespeak.net Sat Mar 10 18:36:50 2007 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sat, 10 Mar 2007 18:36:50 +0100 (CET) Subject: [pypy-svn] r40173 - in pypy/dist/pypy/translator: . goal Message-ID: <20070310173650.6D89410063@code0.codespeak.net> Author: xoraxax Date: Sat Mar 10 18:36:47 2007 New Revision: 40173 Modified: pypy/dist/pypy/translator/driver.py pypy/dist/pypy/translator/goal/ann_override.py pypy/dist/pypy/translator/interactive.py Log: Make pypy translation quieter, old behaviour can be enabled by using the particular command line option. Modified: pypy/dist/pypy/translator/driver.py ============================================================================== --- pypy/dist/pypy/translator/driver.py (original) +++ pypy/dist/pypy/translator/driver.py Sat Mar 10 18:36:47 2007 @@ -197,11 +197,9 @@ self.extra = extra if empty_translator: - # set verbose flags - empty_translator.config.translation.verbose = True translator = empty_translator else: - translator = TranslationContext(config=self.config, verbose=True) + translator = TranslationContext(config=self.config) self.entry_point = entry_point self.translator = translator 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 Sat Mar 10 18:36:47 2007 @@ -122,7 +122,7 @@ if s_name.is_constant(): attr = s_name.const def builder(translator, func): - print "LOOKUP", attr + #print "LOOKUP", attr pol.consider_lookup(funcdesc.bookkeeper, attr) d = {} exec CACHED_LOOKUP % {'attr': attr} in d @@ -137,7 +137,7 @@ if s_name.is_constant(): attr = s_name.const def builder(translator, func): - print "LOOKUP_IN_TYPE_WHERE", attr + #print "LOOKUP_IN_TYPE_WHERE", attr pol.consider_lookup_in_type_where(funcdesc.bookkeeper, attr) d = {} exec CACHED_LOOKUP_IN_TYPE_WHERE % {'attr': attr} in d @@ -153,7 +153,7 @@ from pypy.annotation.classdef import InstanceSource clsdef = bookkeeper.getuniqueclassdef(typeobject.W_TypeObject) pol.pypytypes[x] = True - print "TYPE", x + #print "TYPE", x for attr in pol.lookups: if attr and pol.attach_lookup(x, attr): cached = "cached_%s" % attr Modified: pypy/dist/pypy/translator/interactive.py ============================================================================== --- pypy/dist/pypy/translator/interactive.py (original) +++ pypy/dist/pypy/translator/interactive.py Sat Mar 10 18:36:47 2007 @@ -31,6 +31,8 @@ graph = self.context.buildflowgraph(entry_point) self.context._prebuilt_graphs[entry_point] = graph + self.config.translation.verbose = True # enable messages + def view(self): self.context.view() From xoraxax at codespeak.net Sat Mar 10 18:51:54 2007 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sat, 10 Mar 2007 18:51:54 +0100 (CET) Subject: [pypy-svn] r40175 - in pypy/dist/pypy: tool translator Message-ID: <20070310175154.740581006E@code0.codespeak.net> Author: xoraxax Date: Sat Mar 10 18:51:53 2007 New Revision: 40175 Modified: pypy/dist/pypy/tool/ansi_print.py pypy/dist/pypy/translator/translator.py Log: Oh, the translation became much too boring. Lets generate a few dots ... Modified: pypy/dist/pypy/tool/ansi_print.py ============================================================================== --- pypy/dist/pypy/tool/ansi_print.py (original) +++ pypy/dist/pypy/tool/ansi_print.py Sat Mar 10 18:51:53 2007 @@ -44,6 +44,10 @@ if tty: print >> sys.stderr return + elif 'dot' in keywords: + if tty: + sys.stderr.write(".") + return esc = tuple(esc) for line in msg.content().splitlines(): ansi_print("[%s] %s" %(":".join(keywords), line), esc, Modified: pypy/dist/pypy/translator/translator.py ============================================================================== --- pypy/dist/pypy/translator/translator.py (original) +++ pypy/dist/pypy/translator/translator.py Sat Mar 10 18:51:53 2007 @@ -81,6 +81,8 @@ simplify.detect_list_comprehension(graph) if self.config.translation.verbose: log.done(func.__name__) + else: + log.dot() self.graphs.append(graph) # store the graph in our list return graph From xoraxax at codespeak.net Sat Mar 10 19:28:07 2007 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sat, 10 Mar 2007 19:28:07 +0100 (CET) Subject: [pypy-svn] r40176 - in pypy/dist/pypy: rpython tool Message-ID: <20070310182807.61D091006F@code0.codespeak.net> Author: xoraxax Date: Sat Mar 10 19:28:05 2007 New Revision: 40176 Modified: pypy/dist/pypy/rpython/rtyper.py pypy/dist/pypy/tool/ansi_print.py Log: Show rtyper progress only every 5 percent, get line breaks right for messages after the dots. Modified: pypy/dist/pypy/rpython/rtyper.py ============================================================================== --- pypy/dist/pypy/rpython/rtyper.py (original) +++ pypy/dist/pypy/rpython/rtyper.py Sat Mar 10 19:28:05 2007 @@ -218,6 +218,7 @@ else: tracking = lambda block: None + previous_percentage = 0 # specialize all blocks in the 'pending' list for block in pending: tracking(block) @@ -228,12 +229,15 @@ n = len(self.already_seen) if n % 100 == 0: total = len(self.annotator.annotated) - if self.typererror_count: - error_report = " but %d errors" % self.typererror_count - else: - error_report = '' - self.log.event('specializing: %d / %d blocks (%d%%)%s' % - (n, total, 100 * n // total, error_report)) + percentage = 100 * n // total + if percentage >= previous_percentage + 5: + previous_percentage = percentage + if self.typererror_count: + error_report = " but %d errors" % self.typererror_count + else: + error_report = '' + self.log.event('specializing: %d / %d blocks (%d%%)%s' % + (n, total, percentage, error_report)) # make sure all reprs so far have had their setup() called self.call_all_setups() Modified: pypy/dist/pypy/tool/ansi_print.py ============================================================================== --- pypy/dist/pypy/tool/ansi_print.py (original) +++ pypy/dist/pypy/tool/ansi_print.py Sat Mar 10 19:28:05 2007 @@ -7,6 +7,7 @@ from py.__.misc.terminal_helper import ansi_print class AnsiLog: + wrote_dot = False # XXX sharing state with all instances KW_TO_COLOR = { # color supress @@ -47,7 +48,11 @@ elif 'dot' in keywords: if tty: sys.stderr.write(".") + AnsiLog.wrote_dot = True return + if AnsiLog.wrote_dot: + AnsiLog.wrote_dot = False + sys.stderr.write("\n") esc = tuple(esc) for line in msg.content().splitlines(): ansi_print("[%s] %s" %(":".join(keywords), line), esc, From xoraxax at codespeak.net Sat Mar 10 20:18:50 2007 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sat, 10 Mar 2007 20:18:50 +0100 (CET) Subject: [pypy-svn] r40181 - pypy/dist/pypy/config Message-ID: <20070310191850.AD3FD1006E@code0.codespeak.net> Author: xoraxax Date: Sat Mar 10 20:18:49 2007 New Revision: 40181 Modified: pypy/dist/pypy/config/config.py Log: Fix exception message in pypy.config.config Modified: pypy/dist/pypy/config/config.py ============================================================================== --- pypy/dist/pypy/config/config.py (original) +++ pypy/dist/pypy/config/config.py Sat Mar 10 20:18:49 2007 @@ -83,7 +83,7 @@ if oldvalue != value and oldowner not in ("default", "suggested"): if who in ("default", "suggested"): return - raise ValueError('cannot override value %s for option %s' % + raise ValueError('cannot override value to %s for option %s' % (value, name)) child.setoption(self, value, who) self._cfgimpl_value_owners[name] = who From xoraxax at codespeak.net Sat Mar 10 20:19:19 2007 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sat, 10 Mar 2007 20:19:19 +0100 (CET) Subject: [pypy-svn] r40182 - pypy/dist/pypy/translator/backendopt Message-ID: <20070310191919.47ACD1006E@code0.codespeak.net> Author: xoraxax Date: Sat Mar 10 20:19:15 2007 New Revision: 40182 Modified: pypy/dist/pypy/translator/backendopt/all.py pypy/dist/pypy/translator/backendopt/inline.py pypy/dist/pypy/translator/backendopt/malloc.py pypy/dist/pypy/translator/backendopt/merge_if_blocks.py pypy/dist/pypy/translator/backendopt/removeassert.py pypy/dist/pypy/translator/backendopt/removenoops.py pypy/dist/pypy/translator/backendopt/support.py Log: Make backendopts less chatty if verbose is false. Modified: pypy/dist/pypy/translator/backendopt/all.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/all.py (original) +++ pypy/dist/pypy/translator/backendopt/all.py Sat Mar 10 20:19:15 2007 @@ -116,7 +116,7 @@ if config.merge_if_blocks: for graph in graphs: - merge_if_blocks(graph) + merge_if_blocks(graph, translator.config.translation.verbose) if config.print_statistics: print "after if-to-switch:" @@ -151,6 +151,7 @@ # vaporize mallocs if config.mallocs: + log.malloc("starting malloc removal") remove_mallocs(translator, graphs, type_system) if config.print_statistics: Modified: pypy/dist/pypy/translator/backendopt/inline.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/inline.py (original) +++ pypy/dist/pypy/translator/backendopt/inline.py Sat Mar 10 20:19:15 2007 @@ -704,7 +704,10 @@ heappop(heap) if callers[graph]: - log.inlining('%7.2f %50s' % (weight, graph.name)) + if translator.config.translation.verbose: + log.inlining('%7.2f %50s' % (weight, graph.name)) + else: + log.dot() for parentgraph in callers[graph]: if parentgraph == graph: continue Modified: pypy/dist/pypy/translator/backendopt/malloc.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/malloc.py (original) +++ pypy/dist/pypy/translator/backendopt/malloc.py Sat Mar 10 20:19:15 2007 @@ -29,6 +29,9 @@ SUBSTRUCT_ACCESS = {} CHECK_ARRAY_INDEX = {} + def __init__(self, verbose=True): + self.verbose = verbose + def get_STRUCT(self, TYPE): raise NotImplementedError @@ -301,7 +304,10 @@ while True: count = self.remove_mallocs_once(graph) if count: - log.malloc('%d simple mallocs removed in %r' % (count, graph.name)) + if self.verbose: + log.malloc('%d simple mallocs removed in %r' % (count, graph.name)) + else: + log.dot() tot += count else: break @@ -597,11 +603,11 @@ def insert_keepalives(self, newvars): pass -def remove_simple_mallocs(graph, type_system='lltypesystem'): +def remove_simple_mallocs(graph, type_system='lltypesystem', verbose=True): if type_system == 'lltypesystem': - remover = LLTypeMallocRemover() + remover = LLTypeMallocRemover(verbose) else: - remover = OOTypeMallocRemover() + remover = OOTypeMallocRemover(verbose) return remover.remove_simple_mallocs(graph) @@ -610,7 +616,7 @@ graphs = translator.graphs tot = 0 for graph in graphs: - count = remove_simple_mallocs(graph, type_system=type_system) + count = remove_simple_mallocs(graph, type_system=type_system, verbose=translator.config.translation.verbose) if count: # remove typical leftovers from malloc removal removenoops.remove_same_as(graph) Modified: pypy/dist/pypy/translator/backendopt/merge_if_blocks.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/merge_if_blocks.py (original) +++ pypy/dist/pypy/translator/backendopt/merge_if_blocks.py Sat Mar 10 20:19:15 2007 @@ -105,9 +105,12 @@ checkgraph(graph) return True -def merge_if_blocks(graph): +def merge_if_blocks(graph, verbose=True): merge = False while merge_if_blocks_once(graph): merge = True if merge: - log("merging blocks in %s" % (graph.name, )) + if verbose: + log("merging blocks in %s" % (graph.name, )) + else: + log.dot() Modified: pypy/dist/pypy/translator/backendopt/removeassert.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/removeassert.py (original) +++ pypy/dist/pypy/translator/backendopt/removeassert.py Sat Mar 10 20:19:15 2007 @@ -32,7 +32,8 @@ if count: # now melt away the (hopefully) dead operation that compute # the condition - log.removeassert("removed %d asserts in %s" % (count, graph.name)) + if translator.config.translation.verbose: + log.removeassert("removed %d asserts in %s" % (count, graph.name)) checkgraph(graph) transform_dead_op_vars(graph, translator) Modified: pypy/dist/pypy/translator/backendopt/removenoops.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/removenoops.py (original) +++ pypy/dist/pypy/translator/backendopt/removenoops.py Sat Mar 10 20:19:15 2007 @@ -96,8 +96,9 @@ else: for arg in op.args: used[arg] = True - log.removecasts( - "removed %s cast_pointers in %s" % (num_removed, graph.name)) + if translator.config.translation.verbose: + log.removecasts( + "removed %s cast_pointers in %s" % (num_removed, graph.name)) return num_removed def remove_superfluous_keep_alive(graph): Modified: pypy/dist/pypy/translator/backendopt/support.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/support.py (original) +++ pypy/dist/pypy/translator/backendopt/support.py Sat Mar 10 20:19:15 2007 @@ -8,9 +8,11 @@ from pypy.objspace.flow.model import Constant, Variable, SpaceOperation, c_last_exception from pypy.rpython.lltypesystem import lltype + log = py.log.Producer("backendopt") py.log.setconsumer("backendopt", ansi_log) + def graph_operations(graph): for block in graph.iterblocks(): for op in block.operations: From xoraxax at codespeak.net Sat Mar 10 20:48:32 2007 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sat, 10 Mar 2007 20:48:32 +0100 (CET) Subject: [pypy-svn] r40186 - pypy/dist/pypy/translator/backendopt Message-ID: <20070310194832.B1CAB1006E@code0.codespeak.net> Author: xoraxax Date: Sat Mar 10 20:48:31 2007 New Revision: 40186 Modified: pypy/dist/pypy/translator/backendopt/all.py Log: Add a heading to the merge if blocks pass to give the dots a sense of belonging. Modified: pypy/dist/pypy/translator/backendopt/all.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/all.py (original) +++ pypy/dist/pypy/translator/backendopt/all.py Sat Mar 10 20:48:31 2007 @@ -115,6 +115,7 @@ malloc_to_stack(translator) if config.merge_if_blocks: + log.mergeifblocks("starting to merge if blocks") for graph in graphs: merge_if_blocks(graph, translator.config.translation.verbose) From arigo at codespeak.net Sun Mar 11 09:13:09 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 11 Mar 2007 09:13:09 +0100 (CET) Subject: [pypy-svn] r40193 - in pypy/dist/pypy: interpreter interpreter/test objspace/cpy objspace/std Message-ID: <20070311081309.4E39B10079@code0.codespeak.net> Author: arigo Date: Sun Mar 11 09:13:06 2007 New Revision: 40193 Modified: pypy/dist/pypy/interpreter/baseobjspace.py pypy/dist/pypy/interpreter/gateway.py pypy/dist/pypy/interpreter/test/test_gateway.py pypy/dist/pypy/interpreter/test/test_objspace.py pypy/dist/pypy/objspace/cpy/function.py pypy/dist/pypy/objspace/std/listtype.py pypy/dist/pypy/objspace/std/objspace.py pypy/dist/pypy/objspace/std/rangeobject.py pypy/dist/pypy/objspace/std/ropeobject.py pypy/dist/pypy/objspace/std/slicetype.py pypy/dist/pypy/objspace/std/stringobject.py pypy/dist/pypy/objspace/std/strsliceobject.py pypy/dist/pypy/objspace/std/tupleobject.py pypy/dist/pypy/objspace/std/unicodeobject.py Log: Details about __index__: * gateways should not clamp by default, but raise OverflowError * make w_exception=None be no longer a default argument, to avoid clamping-by-surprize if we forget it * better hack (maybe) for the bootstrap issue in getitem__Tuple_ANY() * unified the way error messages are built * (unrelated) 'int * unicode' should not use space.mul() Modified: pypy/dist/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/dist/pypy/interpreter/baseobjspace.py (original) +++ pypy/dist/pypy/interpreter/baseobjspace.py Sun Mar 11 09:13:06 2007 @@ -795,12 +795,23 @@ step = 0 return start, stop, step - def getindex_w(self, w_obj, w_exception=None): + def getindex_w(self, w_obj, w_exception, objdescr=None): + """Return w_obj.__index__() as an RPython int. + If w_exception is None, silently clamp in case of overflow; + else raise w_exception. + """ # shortcut for int objects if self.is_w(self.type(w_obj), self.w_int): return self.int_w(w_obj) - w_index = self.index(w_obj) + try: + w_index = self.index(w_obj) + except OperationError, err: + if objdescr is None or not err.match(self, self.w_TypeError): + raise + msg = "%s must be an integer, not %s" % ( + objdescr, self.type(w_obj).getname(self, '?')) + raise OperationError(self.w_TypeError, self.wrap(msg)) try: index = self.int_w(w_index) except OperationError, err: Modified: pypy/dist/pypy/interpreter/gateway.py ============================================================================== --- pypy/dist/pypy/interpreter/gateway.py (original) +++ pypy/dist/pypy/interpreter/gateway.py Sun Mar 11 09:13:06 2007 @@ -107,11 +107,11 @@ def visit_self(self, cls, app_sig): self.visit__Wrappable(cls, app_sig) - def checked_space_method(self, typ, app_sig): + def checked_space_method(self, typname, app_sig): argname = self.orig_arg() assert not argname.startswith('w_'), ( "unwrapped %s argument %s of built-in function %r should " - "not start with 'w_'" % (typ.__name__, argname, self.func)) + "not start with 'w_'" % (typname, argname, self.func)) app_sig.append(argname) def visit_index(self, index, app_sig): @@ -164,7 +164,7 @@ def visit__object(self, typ, app_sig): if typ not in (int, str, float): assert False, "unsupported basic type in unwrap_spec" - self.checked_space_method(typ, app_sig) + self.checked_space_method(typ.__name__, app_sig) class UnwrapSpec_EmitRun(UnwrapSpecEmit): @@ -214,7 +214,8 @@ (typ.__name__, self.scopenext())) def visit_index(self, typ): - self.run_args.append("space.getindex_w(%s)" % (self.scopenext(), )) + self.run_args.append("space.getindex_w(%s, space.w_OverflowError)" + % (self.scopenext(), )) def _make_unwrap_activation_class(self, unwrap_spec, cache={}): try: @@ -326,7 +327,8 @@ self.nextarg())) def visit_index(self, typ): - self.unwrap.append("space.getindex_w(%s)" % (self.nextarg()), ) + self.unwrap.append("space.getindex_w(%s, space.w_OverflowError)" + % (self.nextarg()), ) def make_fastfunc(unwrap_spec, func): unwrap_info = UnwrapSpec_FastFunc_Unwrap() Modified: pypy/dist/pypy/interpreter/test/test_gateway.py ============================================================================== --- pypy/dist/pypy/interpreter/test/test_gateway.py (original) +++ pypy/dist/pypy/interpreter/test/test_gateway.py Sun Mar 11 09:13:06 2007 @@ -209,6 +209,27 @@ space.call_function(w_app_g3_if, w(1), w(1.0)), w(2.0)) + def test_interp2app_unwrap_spec_index(self): + space = self.space + w = space.wrap + def g3_idx(space, idx0): + return space.wrap(idx0 + 1) + app_g3_idx = gateway.interp2app_temp(g3_idx, + unwrap_spec=[gateway.ObjSpace, + 'index']) + w_app_g3_idx = space.wrap(app_g3_idx) + assert space.eq_w( + space.call_function(w_app_g3_idx, w(123)), + w(124)) + space.raises_w(space.w_OverflowError, + space.call_function, + w_app_g3_idx, + space.mul(space.wrap(sys.maxint), space.wrap(7))) + space.raises_w(space.w_OverflowError, + space.call_function, + w_app_g3_idx, + space.mul(space.wrap(sys.maxint), space.wrap(-7))) + def test_interp2app_unwrap_spec_typechecks(self): space = self.space w = space.wrap Modified: pypy/dist/pypy/interpreter/test/test_objspace.py ============================================================================== --- pypy/dist/pypy/interpreter/test/test_objspace.py (original) +++ pypy/dist/pypy/interpreter/test/test_objspace.py Sun Mar 11 09:13:06 2007 @@ -1,4 +1,5 @@ from py.test import raises +from pypy.interpreter.error import OperationError from pypy.interpreter.function import Function from pypy.interpreter.pycode import PyCode import sys @@ -149,12 +150,19 @@ class Y(object): def __index__(self): return 2**70 return Y()""") - first = self.space.getindex_w(w_instance1) + first = self.space.getindex_w(w_instance1, None) assert first == 42 - second = self.space.getindex_w(w_instance2) + second = self.space.getindex_w(w_instance2, None) assert second == sys.maxint self.space.raises_w(self.space.w_IndexError, self.space.getindex_w, w_instance2, self.space.w_IndexError) + try: + self.space.getindex_w(self.space.w_tuple, None, "foobar") + except OperationError, e: + assert e.match(self.space, self.space.w_TypeError) + assert "foobar" in e.errorstr(self.space) + else: + assert 0, "should have raised" class TestModuleMinimal: Modified: pypy/dist/pypy/objspace/cpy/function.py ============================================================================== --- pypy/dist/pypy/objspace/cpy/function.py (original) +++ pypy/dist/pypy/objspace/cpy/function.py Sun Mar 11 09:13:06 2007 @@ -53,7 +53,6 @@ convertermap = {int: 'int_w', str: 'str_w', float: 'float_w', - "index": 'getindex_w' } argname = self.orig_arg() assert not argname.startswith('w_') @@ -65,7 +64,14 @@ self.passedargs.append(argname) def visit_index(self, el): - self.visit__object("index") + argname = self.orig_arg() + assert not argname.startswith('w_') + self.inputargs.append(argname) + self.wrappings.append('%s = ___space.getindex_w(___W_Object(%s),' + ' ___space.w_OverflowError)' % + (argname, + argname)) + self.passedargs.append(argname) def visit_args_w(self, el): argname = self.orig_arg() Modified: pypy/dist/pypy/objspace/std/listtype.py ============================================================================== --- pypy/dist/pypy/objspace/std/listtype.py (original) +++ pypy/dist/pypy/objspace/std/listtype.py Sun Mar 11 09:13:06 2007 @@ -66,9 +66,4 @@ # ____________________________________________________________ def get_list_index(space, w_index): - if not space.lookup(w_index, '__index__'): - raise OperationError( - space.w_TypeError, - space.wrap("list indices must be integers, not %s" % - space.type(w_index).getname(space, '?'))) - return space.getindex_w(w_index, space.w_IndexError) + return space.getindex_w(w_index, space.w_IndexError, "list index") Modified: pypy/dist/pypy/objspace/std/objspace.py ============================================================================== --- pypy/dist/pypy/objspace/std/objspace.py (original) +++ pypy/dist/pypy/objspace/std/objspace.py Sun Mar 11 09:13:06 2007 @@ -627,7 +627,7 @@ if space.is_w(w_start, space.w_None): w_start = space.wrap(0) else: - w_start = space.wrap(space.getindex_w(w_start)) + w_start = space.wrap(space.getindex_w(w_start, None)) if space.is_true(space.lt(w_start, space.wrap(0))): w_start = space.add(w_start, space.len(w_obj)) # NB. the language ref is inconsistent with the new-style class @@ -636,7 +636,7 @@ if space.is_w(w_stop, space.w_None): w_stop = space.wrap(slice_max) else: - w_stop = space.wrap(space.getindex_w(w_stop)) + w_stop = space.wrap(space.getindex_w(w_stop, None)) if space.is_true(space.lt(w_stop, space.wrap(0))): w_stop = space.add(w_stop, space.len(w_obj)) return w_start, w_stop Modified: pypy/dist/pypy/objspace/std/rangeobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/rangeobject.py (original) +++ pypy/dist/pypy/objspace/std/rangeobject.py Sun Mar 11 09:13:06 2007 @@ -78,7 +78,7 @@ def getitem__RangeList_ANY(space, w_rangelist, w_index): if w_rangelist.w_list is not None: return space.getitem(w_rangelist.w_list, w_index) - idx = space.getindex_w(w_index, space.w_IndexError) + idx = space.getindex_w(w_index, space.w_IndexError, "list index") try: return wrapint(space, w_rangelist.getitem(idx)) except IndexError: Modified: pypy/dist/pypy/objspace/std/ropeobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/ropeobject.py (original) +++ pypy/dist/pypy/objspace/std/ropeobject.py Sun Mar 11 09:13:06 2007 @@ -897,12 +897,7 @@ return space.newbool(rope.compare(n1, n2) >= 0) def getitem__Rope_ANY(space, w_str, w_index): - if not space.lookup(w_index, '__index__'): - raise OperationError( - space.w_TypeError, - space.wrap("string indices must be integers, not %s" % - space.type(w_index).getname(space, '?'))) - ival = space.getindex_w(w_index, space.w_IndexError) + ival = space.getindex_w(w_index, space.w_IndexError, "string index") node = w_str._node slen = node.length() if ival < 0: Modified: pypy/dist/pypy/objspace/std/slicetype.py ============================================================================== --- pypy/dist/pypy/objspace/std/slicetype.py (original) +++ pypy/dist/pypy/objspace/std/slicetype.py Sun Mar 11 09:13:06 2007 @@ -16,7 +16,7 @@ # utility functions def _Eval_SliceIndex(space, w_int): try: - return space.getindex_w(w_int) # clamp if long integer is too large + return space.getindex_w(w_int, None) # clamp if long integer too large except OperationError, err: if not err.match(space, space.w_TypeError): raise Modified: pypy/dist/pypy/objspace/std/stringobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/stringobject.py (original) +++ pypy/dist/pypy/objspace/std/stringobject.py Sun Mar 11 09:13:06 2007 @@ -749,12 +749,7 @@ return space.w_False def getitem__String_ANY(space, w_str, w_index): - if not space.lookup(w_index, '__index__'): - raise OperationError( - space.w_TypeError, - space.wrap("string indices must be integers, not %s" % - space.type(w_index).getname(space, '?'))) - ival = space.getindex_w(w_index, space.w_IndexError) + ival = space.getindex_w(w_index, space.w_IndexError, "string index") str = w_str._value slen = len(str) if ival < 0: Modified: pypy/dist/pypy/objspace/std/strsliceobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/strsliceobject.py (original) +++ pypy/dist/pypy/objspace/std/strsliceobject.py Sun Mar 11 09:13:06 2007 @@ -167,12 +167,7 @@ def getitem__StringSlice_ANY(space, w_str, w_index): - if not space.lookup(w_index, '__index__'): - raise OperationError( - space.w_TypeError, - space.wrap("string indices must be integers, not %s" % - space.type(w_index).getname(space, '?'))) - ival = space.getindex_w(w_index, space.w_IndexError) + ival = space.getindex_w(w_index, space.w_IndexError, "string index") slen = w_str.stop - w_str.start if ival < 0: ival += slen Modified: pypy/dist/pypy/objspace/std/tupleobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/tupleobject.py (original) +++ pypy/dist/pypy/objspace/std/tupleobject.py Sun Mar 11 09:13:06 2007 @@ -28,15 +28,15 @@ return wrapint(space, result) def getitem__Tuple_ANY(space, w_tuple, w_index): - if not space.lookup(w_index, '__index__'): - raise OperationError( - space.w_TypeError, - space.wrap("tuple indices must be integers, not %s" % - space.type(w_index).getname(space, '?'))) + # getindex_w should get a second argument space.w_IndexError, + # but that doesn't exist the first time this is called. try: - # XXX: getindex_w should get a second argument space.w_IndexError, - # but that doesn't exist the first time this is called. - return w_tuple.wrappeditems[space.getindex_w(w_index)] + w_IndexError = space.w_IndexError + except AttributeError: + w_IndexError = None + index = space.getindex_w(w_index, w_IndexError, "tuple index") + try: + return w_tuple.wrappeditems[index] except IndexError: raise OperationError(space.w_IndexError, space.wrap("tuple index out of range")) Modified: pypy/dist/pypy/objspace/std/unicodeobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/unicodeobject.py (original) +++ pypy/dist/pypy/objspace/std/unicodeobject.py Sun Mar 11 09:13:06 2007 @@ -221,12 +221,7 @@ return space.wrap(len(w_uni._value)) def getitem__Unicode_ANY(space, w_uni, w_index): - if not space.lookup(w_index, '__index__'): - raise OperationError( - space.w_TypeError, - space.wrap("string indices must be integers, not %s" % - space.type(w_index).getname(space, '?'))) - ival = space.getindex_w(w_index, space.w_IndexError) + ival = space.getindex_w(w_index, space.w_IndexError, "string index") uni = w_uni._value ulen = len(uni) if ival < 0: @@ -251,9 +246,14 @@ return W_UnicodeObject(r) def mul__Unicode_ANY(space, w_uni, w_times): + try: + times = space.getindex_w(w_times, space.w_OverflowError) + except OperationError, e: + if e.match(space, space.w_TypeError): + raise FailedToImplement + raise chars = w_uni._value charlen = len(chars) - times = space.getindex_w(w_times, space.w_OverflowError) if times <= 0 or charlen == 0: return W_UnicodeObject([]) if times == 1: @@ -273,7 +273,7 @@ return W_UnicodeObject(result) def mul__ANY_Unicode(space, w_times, w_uni): - return space.mul(w_uni, w_times) + return mul__Unicode_ANY(space, w_uni, w_times) def _isspace(uchar): return unicodedb.isspace(ord(uchar)) From fijal at codespeak.net Sun Mar 11 12:43:06 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 11 Mar 2007 12:43:06 +0100 (CET) Subject: [pypy-svn] r40196 - in pypy/dist/pypy: lib/distributed/test translator/js/examples/console/test translator/js/examples/test Message-ID: <20070311114306.8531210079@code0.codespeak.net> Author: fijal Date: Sun Mar 11 12:43:03 2007 New Revision: 40196 Modified: pypy/dist/pypy/lib/distributed/test/test_greensock.py pypy/dist/pypy/translator/js/examples/console/test/test_console.py pypy/dist/pypy/translator/js/examples/test/test_examples.py Log: Skip those tests, we need pylib trunk->dist merge for them to work Modified: pypy/dist/pypy/lib/distributed/test/test_greensock.py ============================================================================== --- pypy/dist/pypy/lib/distributed/test/test_greensock.py (original) +++ pypy/dist/pypy/lib/distributed/test/test_greensock.py Sun Mar 11 12:43:03 2007 @@ -1,4 +1,6 @@ +import py +py.test.skip("Skip this till pylib trunk->dist merge") from pypy.conftest import gettestobjspace class AppTestDistributedGreensock(object): Modified: pypy/dist/pypy/translator/js/examples/console/test/test_console.py ============================================================================== --- pypy/dist/pypy/translator/js/examples/console/test/test_console.py (original) +++ pypy/dist/pypy/translator/js/examples/console/test/test_console.py Sun Mar 11 12:43:03 2007 @@ -1,4 +1,6 @@ +py.test.skip("Skip this till pylib trunk->dist merge") + def test_line_skip(): from pypy.translator.js.examples.console.console import line_split assert line_split("asdf", 80) == "asdf" 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 Sun Mar 11 12:43:03 2007 @@ -1,7 +1,8 @@ """ Various build tests """ - +import py +py.test.skip("Skip this till pylib trunk->dist merge") from pypy.translator.js.main import rpython2javascript def test_console_build(): From arigo at codespeak.net Sun Mar 11 13:00:23 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 11 Mar 2007 13:00:23 +0100 (CET) Subject: [pypy-svn] r40199 - pypy/dist/pypy/objspace/std Message-ID: <20070311120023.A3D4010079@code0.codespeak.net> Author: arigo Date: Sun Mar 11 13:00:22 2007 New Revision: 40199 Modified: pypy/dist/pypy/objspace/std/inttype.py Log: A pair of tricks that seem to help prebuiltint a bit: * use r_uint to do a single comparison instead of two * store the 'intval' in all cases, to avoid cache misses the next time it is read Modified: pypy/dist/pypy/objspace/std/inttype.py ============================================================================== --- pypy/dist/pypy/objspace/std/inttype.py (original) +++ pypy/dist/pypy/objspace/std/inttype.py Sun Mar 11 13:00:22 2007 @@ -2,6 +2,8 @@ from pypy.objspace.std.strutil import string_to_int, string_to_w_long, ParseStringError, ParseStringOverflowError from pypy.interpreter.error import OperationError from pypy.interpreter.gateway import NoneNotWrapped +from pypy.rlib.rarithmetic import r_uint +from pypy.rlib.objectmodel import instantiate # ____________________________________________________________ @@ -18,11 +20,13 @@ from pypy.objspace.std.intobject import W_IntObject lower = space.config.objspace.std.prebuiltintfrom upper = space.config.objspace.std.prebuiltintto - index = x - lower - if 0 <= index < upper - lower: - return W_IntObject.PREBUILT[index] + index = r_uint(x - lower) + if index >= r_uint(upper - lower): + w_res = instantiate(W_IntObject) else: - return W_IntObject(x) + w_res = W_IntObject.PREBUILT[index] + w_res.intval = x + return w_res else: from pypy.objspace.std.intobject import W_IntObject return W_IntObject(x) From fijal at codespeak.net Sun Mar 11 13:06:03 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 11 Mar 2007 13:06:03 +0100 (CET) Subject: [pypy-svn] r40200 - pypy/dist/pypy/config Message-ID: <20070311120603.ABF7310079@code0.codespeak.net> Author: fijal Date: Sun Mar 11 13:06:02 2007 New Revision: 40200 Modified: pypy/dist/pypy/config/pypyoption.py Log: fix (WARNING!) rest Modified: pypy/dist/pypy/config/pypyoption.py ============================================================================== --- pypy/dist/pypy/config/pypyoption.py (original) +++ pypy/dist/pypy/config/pypyoption.py Sun Mar 11 13:06:02 2007 @@ -196,7 +196,7 @@ default=False, requires=[("objspace.std.withmethodcache", True)]), IntOption("methodcachesizeexp", - "2 ** methodcachesizeexp is the size of the of the method cache ", + " 2 ** methodcachesizeexp is the size of the of the method cache ", default=11), BoolOption("withmultilist", "use lists optimized for flexibility", From arigo at codespeak.net Sun Mar 11 13:07:08 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 11 Mar 2007 13:07:08 +0100 (CET) Subject: [pypy-svn] r40201 - pypy/dist/pypy/objspace/std Message-ID: <20070311120708.759E110079@code0.codespeak.net> Author: arigo Date: Sun Mar 11 13:07:06 2007 New Revision: 40201 Modified: pypy/dist/pypy/objspace/std/inttype.py Log: Comments for r40199. Modified: pypy/dist/pypy/objspace/std/inttype.py ============================================================================== --- pypy/dist/pypy/objspace/std/inttype.py (original) +++ pypy/dist/pypy/objspace/std/inttype.py Sun Mar 11 13:07:06 2007 @@ -20,11 +20,18 @@ from pypy.objspace.std.intobject import W_IntObject lower = space.config.objspace.std.prebuiltintfrom upper = space.config.objspace.std.prebuiltintto + # use r_uint to perform a single comparison (this whole function + # is getting inlined into every caller so keeping the branching + # to a minimum is a good idea) index = r_uint(x - lower) if index >= r_uint(upper - lower): w_res = instantiate(W_IntObject) else: w_res = W_IntObject.PREBUILT[index] + # obscure hack to help the CPU cache: we store 'x' even into + # a prebuilt integer's intval. This makes sure that the intval + # field is present in the cache in the common case where it is + # quickly reused. (we could use a prefetch hint if we had that) w_res.intval = x return w_res else: From fijal at codespeak.net Sun Mar 11 14:13:35 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 11 Mar 2007 14:13:35 +0100 (CET) Subject: [pypy-svn] r40206 - pypy/dist/pypy/doc Message-ID: <20070311131335.C5C9A1007A@code0.codespeak.net> Author: fijal Date: Sun Mar 11 14:13:34 2007 New Revision: 40206 Modified: pypy/dist/pypy/doc/distribution.txt Log: Remove headline Modified: pypy/dist/pypy/doc/distribution.txt ============================================================================== --- pypy/dist/pypy/doc/distribution.txt (original) +++ pypy/dist/pypy/doc/distribution.txt Sun Mar 11 14:13:34 2007 @@ -3,8 +3,6 @@ lib/distributed features ======================== -Stuff & things. mostly - The 'distributed' library is an attempt to provide transparent, lazy access to remote objects. This is accomplished using `transparent proxies`_ and in application level code (so as a pure From fijal at codespeak.net Sun Mar 11 14:20:15 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 11 Mar 2007 14:20:15 +0100 (CET) Subject: [pypy-svn] r40208 - pypy/dist/pypy/doc Message-ID: <20070311132015.734291007A@code0.codespeak.net> Author: fijal Date: Sun Mar 11 14:20:14 2007 New Revision: 40208 Modified: pypy/dist/pypy/doc/distribution.txt Log: Write a chapter about Pyro Modified: pypy/dist/pypy/doc/distribution.txt ============================================================================== --- pypy/dist/pypy/doc/distribution.txt (original) +++ pypy/dist/pypy/doc/distribution.txt Sun Mar 11 14:20:14 2007 @@ -61,4 +61,29 @@ XXX finish, basic interface, example, build some stuff on top of greenlets +Related work comparison +----------------------- + +There are a lot of attempts to incorporate RPC mechanism into +Python, some of them are listed below: + +* `Pyro`_ - Pyro stands for PYthon Remote Objects, it's a mechanism of + implementing remotely accessible objects in pure python (without modifying + interpreter). This is only a remote method call implementation, with + all limitations, so: + + - No attribute access + + - Arguments of calls must be picklable on one side and unpicklable on + remote side, which means they must share source code, they do not + become remote references + + - Exported objects must inherit from specific class and follow certain + standards, like \_\_init\_\_ shape. + + - Remote tracebacks only as strings + + - Remote calls usually invokes new threads + +.. _`Pyro`: http://pyro.sourceforge.net/ .. _`transparent proxies`: objspace-proxies.html#tproxy From fijal at codespeak.net Sun Mar 11 14:31:53 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 11 Mar 2007 14:31:53 +0100 (CET) Subject: [pypy-svn] r40209 - pypy/dist/pypy/doc Message-ID: <20070311133153.4C4CA1007A@code0.codespeak.net> Author: fijal Date: Sun Mar 11 14:31:50 2007 New Revision: 40209 Modified: pypy/dist/pypy/doc/distribution.txt Log: Related work section Modified: pypy/dist/pypy/doc/distribution.txt ============================================================================== --- pypy/dist/pypy/doc/distribution.txt (original) +++ pypy/dist/pypy/doc/distribution.txt Sun Mar 11 14:31:50 2007 @@ -85,5 +85,27 @@ - Remote calls usually invokes new threads +* XMLRPC - There are several implementations of xmlrpc protocol in Python, + one even in the standard library. Xmlrpc is cross-language, cross-platform + protocol of communication, which implies great flexibility of tools to + choose, but also implies several limitations, like: + + - No remote tracebacks + + - Only simple types to be passed as function arguments + +* Twisted Perspective Broker + + - involves twisted, which ties user to network stack/programming style + + - event driven programming (might be good, might be bad, but it's fixed) + + - copies object (by pickling), but provides sophisticated layer of + caching to avoid multiple copies of the same object. + + - two way RPC (unlike Pyro) + + - also heavy restrictions on objects - they must sublcass certain class + .. _`Pyro`: http://pyro.sourceforge.net/ .. _`transparent proxies`: objspace-proxies.html#tproxy From arigo at codespeak.net Sun Mar 11 16:13:41 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 11 Mar 2007 16:13:41 +0100 (CET) Subject: [pypy-svn] r40227 - pypy/dist/pypy/translator/benchmark Message-ID: <20070311151341.7F7071007C@code0.codespeak.net> Author: arigo Date: Sun Mar 11 16:13:40 2007 New Revision: 40227 Removed: pypy/dist/pypy/translator/benchmark/gadtest.py Modified: pypy/dist/pypy/translator/benchmark/ (props changed) pypy/dist/pypy/translator/benchmark/benchmarks.py Log: Add gadfly as an "official" benchmark. Modified: pypy/dist/pypy/translator/benchmark/benchmarks.py ============================================================================== --- pypy/dist/pypy/translator/benchmark/benchmarks.py (original) +++ pypy/dist/pypy/translator/benchmark/benchmarks.py Sun Mar 11 16:13:40 2007 @@ -131,6 +131,30 @@ 'http://johnnydebris.net/templess/trunk', 100) +def run_gadfly(executable='/usr/local/bin/python'): + """ run some tests in the gadfly pure Python database """ + here = py.magic.autopath().dirpath() + gadfly = here.join('gadfly') + testscript = gadfly.join('test', 'testsubset.py') + command = 'PYTHONPATH="%s" "%s" "%s"' % (gadfly, executable, testscript) + txt = run_cmd(command) + lines = [line for line in txt.split('\n') if line.strip()] + if lines[-1].strip() != 'OK': + raise BenchmarkFailed + lastword = lines[-2].split()[-1] + if not lastword.endswith('s'): + raise BenchmarkFailed + try: + result = float(lastword[:-1]) + except ValueError: + raise BenchmarkFailed + return result + +def check_gadfly(): + return external_dependency('gadfly', + 'http://codespeak.net/svn/user/arigo/hack/pypy-hack/gadflyZip', + 40225) + def check_translate(): return False # XXX what should we do about the dependency on ctypes? @@ -141,6 +165,8 @@ 's', check_docutils), Benchmark('templess', run_templess, RICHARDS_ASCENDING_GOOD, 's', check_templess), + Benchmark('gadfly', run_gadfly, RICHARDS_ASCENDING_GOOD, + 's', check_gadfly), ] BENCHMARKS_BY_NAME = {} From arigo at codespeak.net Sun Mar 11 17:27:11 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 11 Mar 2007 17:27:11 +0100 (CET) Subject: [pypy-svn] r40234 - in pypy/dist/pypy/objspace/std: . test Message-ID: <20070311162711.280651007A@code0.codespeak.net> Author: arigo Date: Sun Mar 11 17:27:09 2007 New Revision: 40234 Modified: pypy/dist/pypy/objspace/std/test/test_unicodeobject.py pypy/dist/pypy/objspace/std/unicodetype.py Log: Fix for unicode(None) incorrectly returning u''. 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 Mar 11 17:27:09 2007 @@ -258,3 +258,9 @@ a = x.__getnewargs__() assert a == (u"foo\u1234",) assert type(a[0]) is unicode + + def test_call_unicode(self): + assert unicode() == u'' + assert unicode(None) == u'None' + assert unicode(123) == u'123' + assert unicode([2, 3]) == u'[2, 3]' Modified: pypy/dist/pypy/objspace/std/unicodetype.py ============================================================================== --- pypy/dist/pypy/objspace/std/unicodetype.py (original) +++ pypy/dist/pypy/objspace/std/unicodetype.py Sun Mar 11 17:27:09 2007 @@ -273,7 +273,7 @@ return W_UnicodeObject(codelist) -def descr__new__(space, w_unicodetype, w_string=None, w_encoding=None, w_errors=None): +def descr__new__(space, w_unicodetype, w_string='', w_encoding=None, w_errors=None): from pypy.objspace.std.unicodeobject import W_UnicodeObject w_obj = w_string w_obj_type = space.type(w_obj) @@ -286,8 +286,6 @@ if space.is_w(w_unicodetype, space.w_unicode): return w_obj w_value = w_obj - elif space.is_w(w_obj, space.w_None): - w_value = W_UnicodeObject([]) elif (space.is_w(w_encoding, space.w_None) and space.is_w(w_errors, space.w_None)): if space.is_true(space.isinstance(w_obj, space.w_str)): From arigo at codespeak.net Sun Mar 11 17:35:52 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 11 Mar 2007 17:35:52 +0100 (CET) Subject: [pypy-svn] r40235 - pypy/dist/pypy/objspace/std Message-ID: <20070311163552.626451007A@code0.codespeak.net> Author: arigo Date: Sun Mar 11 17:35:51 2007 New Revision: 40235 Modified: pypy/dist/pypy/objspace/std/stringtype.py pypy/dist/pypy/objspace/std/unicodetype.py Log: Comments to clarify r40234. Modified: pypy/dist/pypy/objspace/std/stringtype.py ============================================================================== --- pypy/dist/pypy/objspace/std/stringtype.py (original) +++ pypy/dist/pypy/objspace/std/stringtype.py Sun Mar 11 17:35:51 2007 @@ -263,6 +263,8 @@ # ____________________________________________________________ def descr__new__(space, w_stringtype, w_object=''): + # NB. the default value of w_object is really a *wrapped* empty string: + # there is gateway magic at work from pypy.objspace.std.stringobject import W_StringObject w_obj = space.str(w_object) if space.is_w(w_stringtype, space.w_str): Modified: pypy/dist/pypy/objspace/std/unicodetype.py ============================================================================== --- pypy/dist/pypy/objspace/std/unicodetype.py (original) +++ pypy/dist/pypy/objspace/std/unicodetype.py Sun Mar 11 17:35:51 2007 @@ -274,6 +274,8 @@ def descr__new__(space, w_unicodetype, w_string='', w_encoding=None, w_errors=None): + # NB. the default value of w_string is really a *wrapped* empty string: + # there is gateway magic at work from pypy.objspace.std.unicodeobject import W_UnicodeObject w_obj = w_string w_obj_type = space.type(w_obj) From arigo at codespeak.net Sun Mar 11 17:42:33 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 11 Mar 2007 17:42:33 +0100 (CET) Subject: [pypy-svn] r40236 - pypy/dist/pypy/translator/benchmark Message-ID: <20070311164233.01DD41007A@code0.codespeak.net> Author: arigo Date: Sun Mar 11 17:42:31 2007 New Revision: 40236 Modified: pypy/dist/pypy/translator/benchmark/benchmarks.py Log: Add mako as a benchmark. Modified: pypy/dist/pypy/translator/benchmark/benchmarks.py ============================================================================== --- pypy/dist/pypy/translator/benchmark/benchmarks.py (original) +++ pypy/dist/pypy/translator/benchmark/benchmarks.py Sun Mar 11 17:42:31 2007 @@ -155,6 +155,29 @@ 'http://codespeak.net/svn/user/arigo/hack/pypy-hack/gadflyZip', 40225) +def run_mako(executable='/usr/local/bin/python'): + """ run some tests in the mako templating system """ + here = py.magic.autopath().dirpath() + mako = here.join('mako') + testscript = mako.join('examples', 'bench', 'basic.py') + command = 'PYTHONPATH="%s" "%s" "%s" mako' % (mako.join('lib'), + executable, testscript) + txt = run_cmd(command) + lines = [line for line in txt.split('\n') if line.strip()] + words = lines[-1].split() + if words[0] != 'Mako:': + raise BenchmarkFailed + try: + result = float(words[1]) + except ValueError: + raise BenchmarkFailed + return result + +def check_mako(): + return external_dependency('mako', + 'http://codespeak.net/svn/user/arigo/hack/pypy-hack/mako', + 40235) + def check_translate(): return False # XXX what should we do about the dependency on ctypes? @@ -167,6 +190,8 @@ 's', check_templess), Benchmark('gadfly', run_gadfly, RICHARDS_ASCENDING_GOOD, 's', check_gadfly), + Benchmark('mako', run_mako, RICHARDS_ASCENDING_GOOD, + 's', check_mako), ] BENCHMARKS_BY_NAME = {} From hpk at codespeak.net Sun Mar 11 22:18:09 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sun, 11 Mar 2007 22:18:09 +0100 (CET) Subject: [pypy-svn] r40265 - pypy/dist/demo Message-ID: <20070311211809.99C3410080@code0.codespeak.net> Author: hpk Date: Sun Mar 11 22:18:06 2007 New Revision: 40265 Added: pypy/dist/demo/tp-persistence.py (contents, props changed) Log: adding a small orthogonal persistence example based on transparent proxies Added: pypy/dist/demo/tp-persistence.py ============================================================================== --- (empty file) +++ pypy/dist/demo/tp-persistence.py Sun Mar 11 22:18:06 2007 @@ -0,0 +1,70 @@ +""" + +This small example implements a basic orthogonal persistence +mechanism on top of PyPy's transparent proxies. + +""" +from pypymagic import transparent_proxy, get_transparent_controller +from types import MethodType + +class PersistentListController(object): + _changeops = ('__iadd__ __imul__ __delitem__ __setitem__ __delslice__ ' + '__imul__ __init__ __setslice__ ' + 'append extend insert pop remove reverse sort').split() + + def __init__(self, obj, storage): + self._obj = obj + self._storage = storage + self.persist() + self.proxy = transparent_proxy(list, self.perform) + + def persist(self): + self._storage.pickle(self._obj) + + def perform(self, operation, *args, **kwargs): + result = getattr(self._obj, operation)(*args, **kwargs) + if operation in self._changeops: + # state was modified, do maximally eager checkpointing + self.persist() + if result is self._obj: + # If the result is the proxied list + # return the proxy instead. + result = self.proxy + elif (isinstance(result, MethodType) and + result.im_self is self._obj): + # Convert methods bound to the proxied list + # to methods bound to the proxy. + # This is to have calls to the method become calls + # to perform. + result = MethodType(result.im_func, self.proxy, result.im_class) + return result + + @classmethod + def load(cls, storage): + obj = storage.unpickle(storage) + return cls(obj, storage) + + +class Storage: + def __init__(self, path): + self.path = py.path.local(path) + + def pickle(self, obj): + self.path.dump(obj) + + def unpickle(self, storage): + return self.path.load() + +if __name__ == '__main__': + import py + storage = Storage("/tmp/mystorage") + + somelist = [1,2,3] + newlist = PersistentListController(somelist, storage).proxy + newlist.append(4) + newlist += [5,6,7] + #call_some_function(newlist) # will see a regular list + del somelist, newlist + restoredlist = PersistentListController.load(storage).proxy + print "restored list", restoredlist + print restoredlist == [1,2,3,4,5,6,7] From hpk at codespeak.net Sun Mar 11 22:22:00 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sun, 11 Mar 2007 22:22:00 +0100 (CET) Subject: [pypy-svn] r40266 - pypy/dist/demo Message-ID: <20070311212200.1A79E10078@code0.codespeak.net> Author: hpk Date: Sun Mar 11 22:21:58 2007 New Revision: 40266 Modified: pypy/dist/demo/tp-persistence.py Log: strip down example (no need for an actual Storage class in this example) Modified: pypy/dist/demo/tp-persistence.py ============================================================================== --- pypy/dist/demo/tp-persistence.py (original) +++ pypy/dist/demo/tp-persistence.py Sun Mar 11 22:21:58 2007 @@ -19,7 +19,7 @@ self.proxy = transparent_proxy(list, self.perform) def persist(self): - self._storage.pickle(self._obj) + self._storage.dump(self._obj) def perform(self, operation, *args, **kwargs): result = getattr(self._obj, operation)(*args, **kwargs) @@ -41,28 +41,18 @@ @classmethod def load(cls, storage): - obj = storage.unpickle(storage) + obj = storage.load() return cls(obj, storage) - -class Storage: - def __init__(self, path): - self.path = py.path.local(path) - - def pickle(self, obj): - self.path.dump(obj) - - def unpickle(self, storage): - return self.path.load() - if __name__ == '__main__': import py - storage = Storage("/tmp/mystorage") + storage = py.path.local("/tmp/mystorage") somelist = [1,2,3] newlist = PersistentListController(somelist, storage).proxy newlist.append(4) newlist += [5,6,7] + assert isinstance(newlist, list) #call_some_function(newlist) # will see a regular list del somelist, newlist restoredlist = PersistentListController.load(storage).proxy From hpk at codespeak.net Sun Mar 11 22:27:57 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sun, 11 Mar 2007 22:27:57 +0100 (CET) Subject: [pypy-svn] r40269 - pypy/dist/demo Message-ID: <20070311212757.85BA210080@code0.codespeak.net> Author: hpk Date: Sun Mar 11 22:27:55 2007 New Revision: 40269 Modified: pypy/dist/demo/tp-persistence.py Log: clarifying example a bit Modified: pypy/dist/demo/tp-persistence.py ============================================================================== --- pypy/dist/demo/tp-persistence.py (original) +++ pypy/dist/demo/tp-persistence.py Sun Mar 11 22:27:55 2007 @@ -44,17 +44,20 @@ obj = storage.load() return cls(obj, storage) +def work_with_list(mylist): + assert isinstance(mylist, list) + mylist.append(4) + mylist += [5,6,7] + if __name__ == '__main__': import py storage = py.path.local("/tmp/mystorage") somelist = [1,2,3] newlist = PersistentListController(somelist, storage).proxy - newlist.append(4) - newlist += [5,6,7] - assert isinstance(newlist, list) - #call_some_function(newlist) # will see a regular list + work_with_list(newlist) del somelist, newlist + restoredlist = PersistentListController.load(storage).proxy print "restored list", restoredlist print restoredlist == [1,2,3,4,5,6,7] From hpk at codespeak.net Sun Mar 11 22:32:59 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sun, 11 Mar 2007 22:32:59 +0100 (CET) Subject: [pypy-svn] r40270 - pypy/dist/demo Message-ID: <20070311213259.9A7931007B@code0.codespeak.net> Author: hpk Date: Sun Mar 11 22:32:55 2007 New Revision: 40270 Modified: pypy/dist/demo/tp-persistence.py Log: comment for noting the particular transparency Modified: pypy/dist/demo/tp-persistence.py ============================================================================== --- pypy/dist/demo/tp-persistence.py (original) +++ pypy/dist/demo/tp-persistence.py Sun Mar 11 22:32:55 2007 @@ -55,6 +55,10 @@ somelist = [1,2,3] newlist = PersistentListController(somelist, storage).proxy + + # here we may call into application code which can + # not detect easily that it is dealing with a persistent + # object work_with_list(newlist) del somelist, newlist From hpk at codespeak.net Sun Mar 11 22:45:32 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sun, 11 Mar 2007 22:45:32 +0100 (CET) Subject: [pypy-svn] r40272 - pypy/dist/demo Message-ID: <20070311214532.D504C1007B@code0.codespeak.net> Author: hpk Date: Sun Mar 11 22:45:31 2007 New Revision: 40272 Modified: pypy/dist/demo/tp-persistence.py Log: fixing changeops Modified: pypy/dist/demo/tp-persistence.py ============================================================================== --- pypy/dist/demo/tp-persistence.py (original) +++ pypy/dist/demo/tp-persistence.py Sun Mar 11 22:45:31 2007 @@ -8,8 +8,8 @@ from types import MethodType class PersistentListController(object): - _changeops = ('__iadd__ __imul__ __delitem__ __setitem__ __delslice__ ' - '__imul__ __init__ __setslice__ ' + _changeops = ('__iadd__ __imul__ __delitem__ __setitem__ ' + '__delslice__ __setslice__ __init__ ' 'append extend insert pop remove reverse sort').split() def __init__(self, obj, storage): From cfbolz at codespeak.net Sun Mar 11 23:55:42 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sun, 11 Mar 2007 23:55:42 +0100 (CET) Subject: [pypy-svn] r40278 - pypy/dist/pypy/doc Message-ID: <20070311225542.56CAB1007D@code0.codespeak.net> Author: cfbolz Date: Sun Mar 11 23:55:41 2007 New Revision: 40278 Modified: pypy/dist/pypy/doc/cleanup-todo.txt Log: add a todo item about the header-inclusion mess Modified: pypy/dist/pypy/doc/cleanup-todo.txt ============================================================================== --- pypy/dist/pypy/doc/cleanup-todo.txt (original) +++ pypy/dist/pypy/doc/cleanup-todo.txt Sun Mar 11 23:55:41 2007 @@ -14,6 +14,7 @@ - keepalives need to die, finally - change weakrefs to work together with the GC - delegate finding type stuff like vtables etc to GC + - clean up the tangle of including headers in the C backend interpreter ----------- From arigo at codespeak.net Mon Mar 12 10:49:00 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 12 Mar 2007 10:49:00 +0100 (CET) Subject: [pypy-svn] r40280 - in pypy/dist/pypy/interpreter: . test Message-ID: <20070312094900.077701008F@code0.codespeak.net> Author: arigo Date: Mon Mar 12 10:48:57 2007 New Revision: 40280 Modified: pypy/dist/pypy/interpreter/main.py pypy/dist/pypy/interpreter/test/test_py.py Log: Starting from CPython 2.3, the __main__ module also has a __file__ if it comes from a file. Fix this for py.py. Modified: pypy/dist/pypy/interpreter/main.py ============================================================================== --- pypy/dist/pypy/interpreter/main.py (original) +++ pypy/dist/pypy/interpreter/main.py Mon Mar 12 10:48:57 2007 @@ -36,12 +36,14 @@ w = space.wrap - pycode = compilecode(space, source, filename, cmd) + pycode = compilecode(space, source, filename or '', cmd) mainmodule = ensure__main__(space) w_globals = mainmodule.w_dict space.setitem(w_globals, w('__builtins__'), space.builtin) + if filename is not None: + space.setitem(w_globals, w('__file__'), w(filename)) retval = pycode.exec_code(space, w_globals, w_globals) if eval: @@ -53,10 +55,10 @@ operationerr.record_interpreter_traceback() raise -def run_string(source, filename='', space=None): +def run_string(source, filename=None, space=None): _run_eval_string(source, filename, space, False) -def eval_string(source, filename='', space=None): +def eval_string(source, filename=None, space=None): return _run_eval_string(source, filename, space, True) def run_file(filename, space=None): Modified: pypy/dist/pypy/interpreter/test/test_py.py ============================================================================== --- pypy/dist/pypy/interpreter/test/test_py.py (original) +++ pypy/dist/pypy/interpreter/test/test_py.py Mon Mar 12 10:48:57 2007 @@ -15,13 +15,30 @@ def test_prefix(): """Make sure py.py sys.prefix and exec_prefix are the same as C Python's""" - output = py.process.cmdexec( '''"%s" "%s" -c "import sys;print sys.prefix" ''' % - (sys.executable, pypypath) ) - assert output.splitlines()[-1] == sys.prefix - output = py.process.cmdexec( '''"%s" "%s" -c "import sys;print sys.exec_prefix" ''' % - (sys.executable, pypypath) ) + cmd = "import sys;print sys.prefix;print sys.exec_prefix" + output = py.process.cmdexec( '''"%s" "%s" -c "%s" ''' % + (sys.executable, pypypath, cmd) ) + assert output.splitlines()[-2] == sys.prefix assert output.splitlines()[-1] == sys.exec_prefix +def test_special_names(): + """Test the __name__ and __file__ special global names""" + cmd = "print __name__; print '__file__' in globals()" + output = py.process.cmdexec( '''"%s" "%s" -c "%s" ''' % + (sys.executable, pypypath, cmd) ) + assert output.splitlines()[-2] == '__main__' + assert output.splitlines()[-1] == 'False' + + tmpfilepath = str(udir.join("test_py_script_1.py")) + tmpfile = file( tmpfilepath, "w" ) + tmpfile.write("print __name__; print __file__\n") + tmpfile.close() + + output = py.process.cmdexec( '''"%s" "%s" "%s" ''' % + (sys.executable, pypypath, tmpfilepath) ) + assert output.splitlines()[-2] == '__main__' + assert output.splitlines()[-1] == str(tmpfilepath) + def test_argv_command(): """Some tests on argv""" # test 1 : no arguments @@ -91,16 +108,3 @@ pass assert e," expected failure" assert e.err.splitlines()[-1] == 'KeyError: ' - - -def test_no__file__in_main(): - tmpfilepath = udir.join("test_py_script.py") - tmpfilepath.write(str(py.code.Source(""" - try: - print __file__ - except NameError: - print 'no __file__.' - """))) - output = py.process.cmdexec( '''"%s" "%s" "%s" ''' % - (sys.executable, pypypath, tmpfilepath) ) - assert 'no __file__.\n' in output From arigo at codespeak.net Mon Mar 12 12:15:12 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 12 Mar 2007 12:15:12 +0100 (CET) Subject: [pypy-svn] r40297 - in pypy/dist/pypy/translator/goal: . test Message-ID: <20070312111512.3F1AD10088@code0.codespeak.net> Author: arigo Date: Mon Mar 12 12:15:10 2007 New Revision: 40297 Added: pypy/dist/pypy/translator/goal/test/ (props changed) pypy/dist/pypy/translator/goal/test/autopath.py - copied unchanged from r40255, pypy/dist/pypy/tool/autopath.py pypy/dist/pypy/translator/goal/test/test_app_main.py (contents, props changed) Modified: pypy/dist/pypy/translator/goal/app_main.py Log: Start some tests for app_main. They skip unless you have 'pexpect' (unix only). More tests to come... 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 Mon Mar 12 12:15:10 2007 @@ -1,6 +1,6 @@ #! /usr/bin/env python # App-level version of py.py. -# XXX this is probably still incomplete. +# See test/test_app_main. """ options: -i inspect interactively after running script @@ -261,6 +261,7 @@ runpy.run_module(sys.argv[0], None, '__main__', True) success = run_toplevel(run_it) else: + mainmodule.__file__ = sys.argv[0] scriptdir = resolvedirof(sys.argv[0]) sys.path.insert(0, scriptdir) success = run_toplevel(execfile, sys.argv[0], mainmodule.__dict__) @@ -319,5 +320,5 @@ from pypy.module.sys.version import PYPY_VERSION sys.pypy_version_info = PYPY_VERSION sys.pypy_initial_path = pypy_initial_path - #sys.exit(entry_point(sys.argv[0], sys.argv[1:])) - sys.exit(entry_point('app_main.py', sys.argv[1:])) + sys.exit(entry_point(sys.argv[0], sys.argv[1:])) + #sys.exit(entry_point('app_main.py', sys.argv[1:])) Added: pypy/dist/pypy/translator/goal/test/test_app_main.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/goal/test/test_app_main.py Mon Mar 12 12:15:10 2007 @@ -0,0 +1,80 @@ +""" +Tests for the entry point of pypy-c, app_main.py. +""" +import py +import sys, os, re +import autopath +from pypy.tool.udir import udir + +DEMO_SCRIPT = """ +print 'hello' +print 'Name:', __name__ +print 'File:', __file__ +import sys +print 'Exec:', sys.executable +print 'Argv:', sys.argv +print 'goodbye' +""" + +def relpath(path): + # force 'path' to be a relative path, for testing purposes + curdir = py.path.local() + p = py.path.local(path) + result = [] + while not p.relto(curdir): + result.append(os.pardir) + if curdir == curdir.dirpath(): + return str(path) # no relative path found, give up + curdir = curdir.dirpath() + result.append(p.relto(curdir)) + return os.path.join(*result) + +app_main = os.path.join(autopath.this_dir, os.pardir, 'app_main.py') +app_main = os.path.abspath(app_main) +demo_script_p = udir.join('demo_test_app_main.py') +demo_script_p.write(DEMO_SCRIPT) +demo_script = relpath(demo_script_p) + + +class TestInteraction: + """ + Install pexpect to run these tests (UNIX-only) + http://pexpect.sourceforge.net/ + """ + + def spawn(self, *args, **kwds): + try: + import pexpect + except ImportError, e: + py.test.skip(str(e)) + kwds.setdefault('timeout', 10) + print 'SPAWN:', args, kwds + return pexpect.spawn(*args, **kwds) + + def test_interactive(self): + child = self.spawn(sys.executable, [app_main]) + child.expect('Python ') # banner + child.expect('>>> ') # prompt + child.sendline('[6*7]') + child.expect(re.escape('[42]')) + child.sendline('def f(x):') + child.expect(re.escape('... ')) + child.sendline(' return x + 100') + child.expect(re.escape('... ')) + child.sendline('') + child.expect('>>> ') + child.sendline('f(98)') + child.expect('198') + child.expect('>>> ') + child.sendline('__name__') + child.expect("'__main__'") + + def test_run_script(self): + child = self.spawn(sys.executable, [app_main, demo_script]) + idx = child.expect(['hello', 'Python ', '>>> ']) + assert idx == 0 # no banner or prompt + child.expect(re.escape("Name: __main__")) + child.expect(re.escape('File: ' + demo_script)) + child.expect(re.escape('Exec: ' + app_main)) + child.expect(re.escape('Argv: ' + repr([demo_script]))) + child.expect('goodbye') From arigo at codespeak.net Mon Mar 12 12:50:59 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 12 Mar 2007 12:50:59 +0100 (CET) Subject: [pypy-svn] r40303 - in pypy/dist/pypy/translator/goal: . test Message-ID: <20070312115059.8A58E1008E@code0.codespeak.net> Author: arigo Date: Mon Mar 12 12:50:58 2007 New Revision: 40303 Modified: pypy/dist/pypy/translator/goal/app_main.py pypy/dist/pypy/translator/goal/test/test_app_main.py Log: More tests for app_main, and according fixes. 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 Mon Mar 12 12:50:58 2007 @@ -178,6 +178,7 @@ import_site = True i = 0 run_module = False + run_stdin = False while i < len(argv): arg = argv[i] if not arg.startswith('-'): @@ -205,6 +206,9 @@ return 0 elif arg == '-S': import_site = False + elif arg == '-': + run_stdin = True + break # not an option but a file name representing stdin elif arg == '-m': i += 1 if i >= len(argv): @@ -220,6 +224,9 @@ return 2 i += 1 sys.argv = argv[i:] + if not sys.argv: + sys.argv.append('') + run_stdin = True # with PyPy in top of CPython we can only have around 100 # but we need more in the translated PyPy for the compiler package @@ -249,25 +256,29 @@ success = True try: - if sys.argv: - if run_command: - cmd = sys.argv.pop(1) - def run_it(): - exec cmd in mainmodule.__dict__ - success = run_toplevel(run_it) - elif run_module: + if run_command: + cmd = sys.argv.pop(1) + def run_it(): + exec cmd in mainmodule.__dict__ + success = run_toplevel(run_it) + elif run_module: + def run_it(): + import runpy + runpy.run_module(sys.argv[0], None, '__main__', True) + success = run_toplevel(run_it) + elif run_stdin: + if sys.stdin.isatty(): + go_interactive = True + else: def run_it(): - import runpy - runpy.run_module(sys.argv[0], None, '__main__', True) + exec sys.stdin.read() in mainmodule.__dict__ + mainmodule.__file__ = '' success = run_toplevel(run_it) - else: - mainmodule.__file__ = sys.argv[0] - scriptdir = resolvedirof(sys.argv[0]) - sys.path.insert(0, scriptdir) - success = run_toplevel(execfile, sys.argv[0], mainmodule.__dict__) - else: - sys.argv.append('') - go_interactive = True + else: + mainmodule.__file__ = sys.argv[0] + scriptdir = resolvedirof(sys.argv[0]) + sys.path.insert(0, scriptdir) + success = run_toplevel(execfile, sys.argv[0], mainmodule.__dict__) if go_interactive or os.getenv('PYTHONINSPECT'): python_startup = os.getenv('PYTHONSTARTUP') Modified: pypy/dist/pypy/translator/goal/test/test_app_main.py ============================================================================== --- pypy/dist/pypy/translator/goal/test/test_app_main.py (original) +++ pypy/dist/pypy/translator/goal/test/test_app_main.py Mon Mar 12 12:50:58 2007 @@ -16,6 +16,12 @@ print 'goodbye' """ +CRASHING_DEMO_SCRIPT = """ +print 'hello' +ooups +print 'goodbye' # should not be reached +""" + def relpath(path): # force 'path' to be a relative path, for testing purposes curdir = py.path.local() @@ -31,18 +37,23 @@ app_main = os.path.join(autopath.this_dir, os.pardir, 'app_main.py') app_main = os.path.abspath(app_main) + demo_script_p = udir.join('demo_test_app_main.py') demo_script_p.write(DEMO_SCRIPT) demo_script = relpath(demo_script_p) +crashing_demo_script_p = udir.join('crashing_demo_test_app_main.py') +crashing_demo_script_p.write(CRASHING_DEMO_SCRIPT) +crashing_demo_script = relpath(crashing_demo_script_p) + class TestInteraction: """ - Install pexpect to run these tests (UNIX-only) + These tests require pexpect (UNIX-only). http://pexpect.sourceforge.net/ """ - def spawn(self, *args, **kwds): + def _spawn(self, *args, **kwds): try: import pexpect except ImportError, e: @@ -51,8 +62,11 @@ print 'SPAWN:', args, kwds return pexpect.spawn(*args, **kwds) + def spawn(self, argv): + return self._spawn(sys.executable, [app_main] + argv) + def test_interactive(self): - child = self.spawn(sys.executable, [app_main]) + child = self.spawn([]) child.expect('Python ') # banner child.expect('>>> ') # prompt child.sendline('[6*7]') @@ -70,7 +84,7 @@ child.expect("'__main__'") def test_run_script(self): - child = self.spawn(sys.executable, [app_main, demo_script]) + child = self.spawn([demo_script]) idx = child.expect(['hello', 'Python ', '>>> ']) assert idx == 0 # no banner or prompt child.expect(re.escape("Name: __main__")) @@ -78,3 +92,55 @@ child.expect(re.escape('Exec: ' + app_main)) child.expect(re.escape('Argv: ' + repr([demo_script]))) child.expect('goodbye') + + def test_run_script_with_args(self): + argv = [demo_script, 'hello', 'world'] + child = self.spawn(argv) + child.expect(re.escape('Argv: ' + repr(argv))) + child.expect('goodbye') + + def test_no_such_script(self): + import errno + msg = os.strerror(errno.ENOENT) # 'No such file or directory' + child = self.spawn(['xxx-no-such-file-xxx']) + child.expect(re.escape(msg)) + + +class TestNonInteractive: + + def run(self, cmdline): + cmdline = '"%s" "%s" %s' % (sys.executable, app_main, cmdline) + print 'POPEN:', cmdline + child_in, child_out_err = os.popen4(cmdline) + child_in.close() + data = child_out_err.read() + child_out_err.close() + assert sys.version not in data # no banner + assert '>>> ' not in data # no prompt + return data + + def test_script_on_stdin(self): + for extraargs, expected_argv in [ + ('', ['']), + ('-', ['-']), + ('- hello world', ['-', 'hello', 'world']), + ]: + data = self.run('%s < "%s"' % (extraargs, demo_script)) + assert "hello" in data + assert "Name: __main__" in data + assert "File: " in data + assert ("Exec: " + app_main) in data + assert ("Argv: " + repr(expected_argv)) in data + assert "goodbye" in data + + def test_run_crashing_script(self): + data = self.run('"%s"' % (crashing_demo_script,)) + assert 'hello' in data + assert 'NameError' in data + assert 'goodbye' not in data + + def test_crashing_script_on_stdin(self): + data = self.run(' < "%s"' % (crashing_demo_script,)) + assert 'hello' in data + assert 'NameError' in data + assert 'goodbye' not in data From gbrandl at codespeak.net Mon Mar 12 13:14:41 2007 From: gbrandl at codespeak.net (gbrandl at codespeak.net) Date: Mon, 12 Mar 2007 13:14:41 +0100 (CET) Subject: [pypy-svn] r40314 - in pypy/dist/pypy: doc doc/config objspace rpython/ootypesystem translator/microbench/pybench Message-ID: <20070312121441.BE7521008E@code0.codespeak.net> Author: gbrandl Date: Mon Mar 12 13:14:35 2007 New Revision: 40314 Modified: pypy/dist/pypy/doc/config/objspace.std.withshadowtracking.txt pypy/dist/pypy/doc/parser.txt pypy/dist/pypy/doc/project-ideas.txt pypy/dist/pypy/objspace/trace.py pypy/dist/pypy/rpython/ootypesystem/rstr.py pypy/dist/pypy/translator/microbench/pybench/README pypy/dist/pypy/translator/microbench/pybench/pybench.py Log: it's -> its where appropriate. 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 Mon Mar 12 13:14:35 2007 @@ -1,7 +1,7 @@ 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 +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. Usually, when a method is found, the instance dictionary is then checked for instance attributes shadowing the class Modified: pypy/dist/pypy/doc/parser.txt ============================================================================== --- pypy/dist/pypy/doc/parser.txt (original) +++ pypy/dist/pypy/doc/parser.txt Mon Mar 12 13:14:35 2007 @@ -195,7 +195,7 @@ ----------------------- For now we are working at translating the existing compiler module without -changing it's design too much. That means we won't have enough flexibility +changing its design too much. That means we won't have enough flexibility to be able to handle new AST nodes at runtime. parser module Modified: pypy/dist/pypy/doc/project-ideas.txt ============================================================================== --- pypy/dist/pypy/doc/project-ideas.txt (original) +++ pypy/dist/pypy/doc/project-ideas.txt Mon Mar 12 13:14:35 2007 @@ -90,7 +90,7 @@ * 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 +* profile pypy-c and its variants with these benchmarks, identify slow areas * try to come up with optimized implementations for these slow areas Modified: pypy/dist/pypy/objspace/trace.py ============================================================================== --- pypy/dist/pypy/objspace/trace.py (original) +++ pypy/dist/pypy/objspace/trace.py Mon Mar 12 13:14:35 2007 @@ -206,7 +206,7 @@ # XXX Rename def reset_trace(self): - """ Returns the class to it's original form. """ + """ Returns the class to its original form. """ space.__class__ = space.__oldclass__ del space.__oldclass__ Modified: pypy/dist/pypy/rpython/ootypesystem/rstr.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/rstr.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/rstr.py Mon Mar 12 13:14:35 2007 @@ -6,7 +6,7 @@ from pypy.rpython.lltypesystem.lltype import Ptr, Char, UniChar from pypy.rpython.ootypesystem import ootype -# TODO: investigate if it's possibile and it's worth to concatenate a +# TODO: investigate if it's possible and it's worth to concatenate a # String and a Char directly without passing to Char-->String # conversion Modified: pypy/dist/pypy/translator/microbench/pybench/README ============================================================================== --- pypy/dist/pypy/translator/microbench/pybench/README (original) +++ pypy/dist/pypy/translator/microbench/pybench/README Mon Mar 12 13:14:35 2007 @@ -5,7 +5,7 @@ ------------ Run 'pybench.py -h' to see the help screen. -Run 'pybench.py' to just let the benchmark suite do it's thing and +Run 'pybench.py' to just let the benchmark suite do its thing and 'pybench.py -f ' to have it store the results in a file too. Change list Modified: pypy/dist/pypy/translator/microbench/pybench/pybench.py ============================================================================== --- pypy/dist/pypy/translator/microbench/pybench/pybench.py (original) +++ pypy/dist/pypy/translator/microbench/pybench/pybench.py Mon Mar 12 13:14:35 2007 @@ -66,7 +66,7 @@ call of .run(). If you change a test in some way, don't forget to increase - it's version number. + its version number. """ operations = 1 # number of operations done per test()-call From arigo at codespeak.net Mon Mar 12 13:36:32 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 12 Mar 2007 13:36:32 +0100 (CET) Subject: [pypy-svn] r40318 - pypy/dist/lib-python/modified-2.4.1 Message-ID: <20070312123632.2AE0F1008E@code0.codespeak.net> Author: arigo Date: Mon Mar 12 13:36:30 2007 New Revision: 40318 Added: pypy/dist/lib-python/modified-2.4.1/site.py - copied, changed from r40255, pypy/dist/lib-python/2.4.1/site.py Log: Proper __builtin__.credits and __builtin__.license for PyPy. From arigo at codespeak.net Mon Mar 12 14:00:51 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 12 Mar 2007 14:00:51 +0100 (CET) Subject: [pypy-svn] r40329 - in pypy/dist/pypy/translator/goal: . test Message-ID: <20070312130051.5246F10091@code0.codespeak.net> Author: arigo Date: Mon Mar 12 14:00:50 2007 New Revision: 40329 Modified: pypy/dist/pypy/translator/goal/app_main.py pypy/dist/pypy/translator/goal/test/test_app_main.py Log: More tests for app_main. Only print the banner and run $PYTHONSTARTUP when not running anything else, not every time we specify the -i option. 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 Mon Mar 12 14:00:50 2007 @@ -268,10 +268,25 @@ success = run_toplevel(run_it) elif run_stdin: if sys.stdin.isatty(): + print_banner() + python_startup = os.getenv('PYTHONSTARTUP') + if python_startup: + try: + startup = open(python_startup).read() + except IOError: + pass + else: + def run_it(): + co_python_startup = compile(startup, + python_startup, + 'exec') + exec co_python_startup in mainmodule.__dict__ + run_toplevel(run_it) go_interactive = True else: def run_it(): - exec sys.stdin.read() in mainmodule.__dict__ + co_stdin = compile(sys.stdin.read(), '', 'exec') + exec co_stdin in mainmodule.__dict__ mainmodule.__file__ = '' success = run_toplevel(run_it) else: @@ -281,20 +296,7 @@ success = run_toplevel(execfile, sys.argv[0], mainmodule.__dict__) if go_interactive or os.getenv('PYTHONINSPECT'): - python_startup = os.getenv('PYTHONSTARTUP') - if python_startup: - try: - startup = open(python_startup).read() - except IOError: - pass - else: - def run_it(): - exec startup in mainmodule.__dict__ - run_toplevel(run_it) - print >> sys.stderr, "debug: importing code" - import code - print >> sys.stderr, "debug: calling code.interact()" - success = run_toplevel(code.interact, local=mainmodule.__dict__) + success = run_toplevel(interactive_console, mainmodule) except SystemExit, e: return e.code else: @@ -315,10 +317,47 @@ return resolvedirof(os.path.join(dirname, link)) return dirname +def print_banner(): + print 'Python %s on %s' % (sys.version, sys.platform) + print ('Type "help", "copyright", "credits" or ' + '"license" for more information.') + +def interactive_console(mainmodule): + # some parts of code.py are copied here because it seems to be impossible + # to start an interactive console without printing at least one line + # of banner + import code + console = code.InteractiveConsole(mainmodule.__dict__) + try: + import readline + except ImportError: + pass + more = 0 + while 1: + try: + if more: + prompt = sys.ps2 + else: + prompt = sys.ps1 + try: + line = raw_input(prompt) + except EOFError: + console.write("\n") + break + else: + more = console.push(line) + except KeyboardInterrupt: + console.write("\nKeyboardInterrupt\n") + console.resetbuffer() + more = 0 + + if __name__ == '__main__': # obscure! try removing the following line, see how it crashes, and # guess why... ImStillAroundDontForgetMe = sys.modules['__main__'] + sys.ps1 = '>>>> ' + sys.ps2 = '.... ' # debugging only def pypy_initial_path(s): Modified: pypy/dist/pypy/translator/goal/test/test_app_main.py ============================================================================== --- pypy/dist/pypy/translator/goal/test/test_app_main.py (original) +++ pypy/dist/pypy/translator/goal/test/test_app_main.py Mon Mar 12 14:00:50 2007 @@ -14,14 +14,19 @@ print 'Exec:', sys.executable print 'Argv:', sys.argv print 'goodbye' +myvalue = 6*7 """ CRASHING_DEMO_SCRIPT = """ -print 'hello' +print 'Hello2' +myvalue2 = 11 ooups -print 'goodbye' # should not be reached +myvalue2 = 22 +print 'Goodbye2' # should not be reached """ +banner = sys.version.splitlines()[0] + def relpath(path): # force 'path' to be a relative path, for testing purposes curdir = py.path.local() @@ -60,7 +65,9 @@ py.test.skip(str(e)) kwds.setdefault('timeout', 10) print 'SPAWN:', args, kwds - return pexpect.spawn(*args, **kwds) + child = pexpect.spawn(*args, **kwds) + child.logfile = sys.stdout + return child def spawn(self, argv): return self._spawn(sys.executable, [app_main] + argv) @@ -105,6 +112,100 @@ child = self.spawn(['xxx-no-such-file-xxx']) child.expect(re.escape(msg)) + def test_option_i(self): + argv = [demo_script, 'foo', 'bar'] + child = self.spawn(['-i'] + argv) + idx = child.expect(['hello', re.escape(banner)]) + assert idx == 0 # no banner + child.expect(re.escape('File: ' + demo_script)) + child.expect(re.escape('Argv: ' + repr(argv))) + child.expect('goodbye') + idx = child.expect(['>>> ', re.escape(banner)]) + assert idx == 0 # prompt, but still no banner + child.sendline('myvalue * 102') + child.expect('4284') + child.sendline('__name__') + child.expect('__main__') + + def test_option_i_crashing(self): + argv = [crashing_demo_script, 'foo', 'bar'] + child = self.spawn(['-i'] + argv) + idx = child.expect(['Hello2', re.escape(banner)]) + assert idx == 0 # no banner + child.expect('NameError') + child.sendline('myvalue2 * 1001') + child.expect('11011') + child.sendline('import sys; sys.argv') + child.expect(re.escape(repr(argv))) + child.sendline('sys.last_type.__name__') + child.expect(re.escape(repr('NameError'))) + + def test_options_i_c(self): + child = self.spawn(['-i', '-c', 'x=555']) + idx = child.expect(['>>> ', re.escape(banner)]) + assert idx == 0 # prompt, but no banner + child.sendline('x') + child.expect('555') + child.sendline('__name__') + child.expect('__main__') + child.sendline('import sys; sys.argv') + child.expect(re.escape("['-c']")) + + def test_options_i_c_crashing(self): + child = self.spawn(['-i', '-c', 'x=666;foobar']) + child.expect('NameError') + idx = child.expect(['>>> ', re.escape(banner)]) + assert idx == 0 # prompt, but no banner + child.sendline('x') + child.expect('666') + child.sendline('__name__') + child.expect('__main__') + child.sendline('import sys; sys.argv') + child.expect(re.escape("['-c']")) + child.sendline('sys.last_type.__name__') + child.expect(re.escape(repr('NameError'))) + + def test_atexit(self): + child = self.spawn([]) + child.expect('>>> ') + child.sendline('def f(): print "foobye"') + child.sendline('') + child.sendline('import atexit; atexit.register(f)') + child.sendline('6*7') + child.expect('42') + # pexpect's sendeof() is confused by py.test capturing, though + # I think that it is a bug of sendeof() + old = sys.stdin + try: + sys.stdin = child + child.sendeof() + finally: + sys.stdin = old + child.expect('foobye') + + def test_pythonstartup(self): + old = os.environ['PYTHONSTARTUP'] + try: + os.environ['PYTHONSTARTUP'] = crashing_demo_script + child = self.spawn([]) + child.expect(re.escape(banner)) + child.expect('Traceback') + child.expect('NameError') + child.expect('>>> ') + child.sendline('[myvalue2]') + child.expect(re.escape('[11]')) + child.expect('>>> ') + + child = self.spawn(['-i', demo_script]) + for line in ['hello', 'goodbye', '>>> ']: + idx = child.expect([line, 'Hello2']) + assert idx == 0 # no PYTHONSTARTUP run here + child.sendline('myvalue2') + child.expect('Traceback') + child.expect('NameError') + finally: + os.environ['PYTHONSTARTUP'] = old + class TestNonInteractive: @@ -115,7 +216,7 @@ child_in.close() data = child_out_err.read() child_out_err.close() - assert sys.version not in data # no banner + assert banner not in data # no banner assert '>>> ' not in data # no prompt return data @@ -135,12 +236,27 @@ def test_run_crashing_script(self): data = self.run('"%s"' % (crashing_demo_script,)) - assert 'hello' in data + assert 'Hello2' in data assert 'NameError' in data - assert 'goodbye' not in data + assert 'Goodbye2' not in data def test_crashing_script_on_stdin(self): data = self.run(' < "%s"' % (crashing_demo_script,)) - assert 'hello' in data + assert 'Hello2' in data assert 'NameError' in data - assert 'goodbye' not in data + assert 'Goodbye2' not in data + + def test_option_c(self): + data = self.run('-c "print 6**5"') + assert '7776' in data + + def test_no_pythonstartup(self): + old = os.environ['PYTHONSTARTUP'] + try: + os.environ['PYTHONSTARTUP'] = crashing_demo_script + data = self.run('"%s"' % (demo_script,)) + assert 'Hello2' not in data + data = self.run('-c pass') + assert 'Hello2' not in data + finally: + os.environ['PYTHONSTARTUP'] = old From arigo at codespeak.net Mon Mar 12 14:29:02 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 12 Mar 2007 14:29:02 +0100 (CET) Subject: [pypy-svn] r40335 - in pypy/dist/pypy/translator/goal: . test Message-ID: <20070312132902.776D510091@code0.codespeak.net> Author: arigo Date: Mon Mar 12 14:29:00 2007 New Revision: 40335 Added: pypy/dist/pypy/translator/goal/test/__init__.py (contents, props changed) pypy/dist/pypy/translator/goal/test/mymodule.py (contents, props changed) Modified: pypy/dist/pypy/translator/goal/app_main.py pypy/dist/pypy/translator/goal/test/test_app_main.py Log: More tests for app_main. 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 Mon Mar 12 14:29:00 2007 @@ -239,7 +239,7 @@ try: import site except: - print >> sys.stderr, "import site' failed" + print >> sys.stderr, "'import site' failed" # set up the Ctrl-C => KeyboardInterrupt signal handler, if the @@ -353,6 +353,7 @@ if __name__ == '__main__': + import autopath # obscure! try removing the following line, see how it crashes, and # guess why... ImStillAroundDontForgetMe = sys.modules['__main__'] Added: pypy/dist/pypy/translator/goal/test/__init__.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/goal/test/__init__.py Mon Mar 12 14:29:00 2007 @@ -0,0 +1 @@ +#empty Added: pypy/dist/pypy/translator/goal/test/mymodule.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/goal/test/mymodule.py Mon Mar 12 14:29:00 2007 @@ -0,0 +1,10 @@ +# for test_app_main + +import sys + +print 'mymodule running' +print 'Name:', __name__ +print 'File:', __file__ +print 'Argv:', sys.argv + +somevalue = "foobar" Modified: pypy/dist/pypy/translator/goal/test/test_app_main.py ============================================================================== --- pypy/dist/pypy/translator/goal/test/test_app_main.py (original) +++ pypy/dist/pypy/translator/goal/test/test_app_main.py Mon Mar 12 14:29:00 2007 @@ -206,6 +206,33 @@ finally: os.environ['PYTHONSTARTUP'] = old + def test_unbuffered(self): + line = 'import os,sys;sys.stdout.write(str(789));os.read(0,1)' + child = self.spawn(['-u', '-c', line]) + child.expect('789') # expect to see it before the timeout hits + child.sendline('X') + + def test_options_i_m(self): + p = os.path.join(autopath.this_dir, 'mymodule.py') + p = os.path.abspath(p) + child = self.spawn(['-i', + '-m', 'pypy.translator.goal.test.mymodule', + 'extra']) + child.expect('mymodule running') + child.expect('Name: __main__') + child.expect(re.escape('File: ' + p)) + child.expect(re.escape('Argv: ' + repr([p, 'extra']))) + child.expect('>>> ') + #XXX the following doesn't work on CPython 2.5 either + #child.sendline('somevalue') + #child.expect(re.escape(repr("foobar"))) + #child.expect('>>> ') + child.sendline('import sys') + child.sendline('"pypy.translator.goal.test" in sys.modules') + child.expect('True') + child.sendline('"pypy.translator.goal.test.mymodule" in sys.modules') + child.expect('False') + class TestNonInteractive: @@ -260,3 +287,12 @@ assert 'Hello2' not in data finally: os.environ['PYTHONSTARTUP'] = old + + def test_option_m(self): + p = os.path.join(autopath.this_dir, 'mymodule.py') + p = os.path.abspath(p) + data = self.run('-m pypy.translator.goal.test.mymodule extra') + assert 'mymodule running' in data + assert 'Name: __main__' in data + assert ('File: ' + p) in data + assert ('Argv: ' + repr([p, 'extra'])) in data From cfbolz at codespeak.net Mon Mar 12 16:16:46 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 12 Mar 2007 16:16:46 +0100 (CET) Subject: [pypy-svn] r40364 - pypy/extradoc/eu-report Message-ID: <20070312151646.816CA1009D@code0.codespeak.net> Author: cfbolz Date: Mon Mar 12 16:16:42 2007 New Revision: 40364 Added: pypy/extradoc/eu-report/D02.3_Testing_Framework-interim-2007-03-12.pdf - copied, changed from r40361, pypy/eu-tracking/deliverable/D02_3_Testing_Framework/D02.3-deliverablereport.pdf Log: add 2.3 interim From gbrandl at codespeak.net Mon Mar 12 16:18:53 2007 From: gbrandl at codespeak.net (gbrandl at codespeak.net) Date: Mon, 12 Mar 2007 16:18:53 +0100 (CET) Subject: [pypy-svn] r40365 - pypy/dist/pypy/doc Message-ID: <20070312151853.B273D1009C@code0.codespeak.net> Author: gbrandl Date: Mon Mar 12 16:18:51 2007 New Revision: 40365 Modified: pypy/dist/pypy/doc/rtyper.txt Log: Typo fixes. Modified: pypy/dist/pypy/doc/rtyper.txt ============================================================================== --- pypy/dist/pypy/doc/rtyper.txt (original) +++ pypy/dist/pypy/doc/rtyper.txt Mon Mar 12 16:18:51 2007 @@ -23,7 +23,7 @@ structure. In theory, this step is optional; some code generators might be able to read -directly the high-level types. However, we expect that case to be the +the high-level types directly. However, we expect that case to be the exception. "Compiling" high-level types into low-level ones is rather more messy than one would expect. This was the motivation for making this step explicit and isolated in a single place. After Typing, the graphs can only @@ -34,7 +34,8 @@ Example: Integer operations --------------------------- -Integer operations are the easiest. Assume a graph containing the following operation:: +Integer operations are the easiest. Assume a graph containing the following +operation:: v3 = add(v1, v2) @@ -495,14 +496,14 @@ The target platform is assumed to be **statically typed**, i.e. the type of each object is known at compile time. -As usual, it is possibile to convert an object from type to type only -under certain conditions; there is a number of predefined conversion +As usual, it is possible to convert an object from type to type only +under certain conditions; there is a number of predefined conversions between primitive types such as from ``Bool`` to ``Signed`` or from ``Signed`` to ``Float``. For each one of these conversions there is a corresponding low level operation, such as ``cast_bool_to_int`` and ``cast_int_to_float``. -Moreover it is possibile to cast instances of a class up and down the +Moreover it is possible to cast instances of a class up and down the inheritance hierarchy with the ``ooupcast`` and ``oodowncast`` low level operations. Implicit upcasting is not allowed, so you really need to do a ``ooupcast`` for converting from a subclass to a @@ -518,8 +519,8 @@ ++++++++++++ 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: +following is a list of key features of the ootype object model which +have a direct correspondence in the Java or .NET object model: - classes have a static set of strongly typed methods and attributes; @@ -528,7 +529,7 @@ (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 + - classes support single inheritance; all classes inherit directly or indirectly from the ROOT class; - there is some support for method overloading. This feature is not @@ -541,10 +542,10 @@ 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 + can be easily simulated by backends for platforms on which it is not a native feature; - - there is a set of `built-in types`_ offering standard features; + - there is a set of `built-in types`_ offering standard features. Exception handling ++++++++++++++++++ From cfbolz at codespeak.net Mon Mar 12 16:33:23 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 12 Mar 2007 16:33:23 +0100 (CET) Subject: [pypy-svn] r40369 - pypy/extradoc/eu-report Message-ID: <20070312153323.BE28310098@code0.codespeak.net> Author: cfbolz Date: Mon Mar 12 16:33:22 2007 New Revision: 40369 Removed: pypy/extradoc/eu-report/D02.3_Testing_Framework-interim-2007-01-28.pdf Log: remove old version From cfbolz at codespeak.net Mon Mar 12 16:33:42 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 12 Mar 2007 16:33:42 +0100 (CET) Subject: [pypy-svn] r40370 - pypy/dist/pypy/doc Message-ID: <20070312153342.8D2971009A@code0.codespeak.net> Author: cfbolz Date: Mon Mar 12 16:33:40 2007 New Revision: 40370 Modified: pypy/dist/pypy/doc/index-report.txt Log: point to new 2.3 Modified: pypy/dist/pypy/doc/index-report.txt ============================================================================== --- pypy/dist/pypy/doc/index-report.txt (original) +++ pypy/dist/pypy/doc/index-report.txt Mon Mar 12 16:33:40 2007 @@ -12,12 +12,15 @@ Reports of 2007 =============== +`Interim 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)* + `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 @@ -40,9 +43,6 @@ 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)* .. _`py-lib`: http://codespeak.net/py/current/doc/ .. _`py.test`: http://codespeak.net/py/current/doc/test.html @@ -101,7 +101,7 @@ .. _`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 -.. _`Draft D02.3 Testing Tool`: http://codespeak.net/pypy/extradoc/eu-report/D02.3_Testing_Framework-interim-2007-01-28.pdf +.. _`Interim D02.3 Testing Tool`: http://codespeak.net/pypy/extradoc/eu-report/D02.3_Testing_Framework-interim-2007-03-12.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 Mon Mar 12 16:52:43 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 12 Mar 2007 16:52:43 +0100 (CET) Subject: [pypy-svn] r40378 - pypy/extradoc/eu-report Message-ID: <20070312155243.02DFD10094@code0.codespeak.net> Author: cfbolz Date: Mon Mar 12 16:52:42 2007 New Revision: 40378 Added: pypy/extradoc/eu-report/D02.1_Development_Tools_and_Website-interim-2007-03-12.pdf - copied unchanged from r40375, pypy/eu-tracking/deliverable/D02_1_Development_Tools_and_Website/D02.1-deliverablereport.pdf Log: publish 2.1 report From cfbolz at codespeak.net Mon Mar 12 17:00:57 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 12 Mar 2007 17:00:57 +0100 (CET) Subject: [pypy-svn] r40379 - pypy/dist/pypy/doc Message-ID: <20070312160057.C7FD510094@code0.codespeak.net> Author: cfbolz Date: Mon Mar 12 17:00:56 2007 New Revision: 40379 Modified: pypy/dist/pypy/doc/index-report.txt Log: published 2.1 Modified: pypy/dist/pypy/doc/index-report.txt ============================================================================== --- pypy/dist/pypy/doc/index-report.txt (original) +++ pypy/dist/pypy/doc/index-report.txt Mon Mar 12 17:00:56 2007 @@ -5,16 +5,21 @@ We have written several reports for the EU of which some are also quite useful as documentation. The ones not so useful as documentation mostly contain text -that can also be found in the regular documentation section. All of these -documents are preliminary versions, none of them have been approved by the -European Union. +that can also be found in the regular documentation section. All of these +documents from the years 2006 and 2007 are preliminary versions, none of them +have been approved by the European Union. Reports of 2007 =============== +`Interim D02.1 Development Tools and Website`_ is an interim version of a report +about the codespeak_ development environment and aditional tool support for the +PyPy development process. The report is still a +draft, all feedback for it is welcome. *(2007-03-12)* + `Interim 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)* +draft, all feedback for it is welcome. *(2007-03-12)* `D07.1 Massive Parallelism and Translation Aspects`_ is a report about PyPy's optimization efforts, garbage collectors and massive parallelism @@ -46,6 +51,7 @@ .. _`py-lib`: http://codespeak.net/py/current/doc/ .. _`py.test`: http://codespeak.net/py/current/doc/test.html +.. _codespeak: http://codespeak.net/ Reports of 2006 @@ -102,6 +108,7 @@ .. _`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 .. _`Interim D02.3 Testing Tool`: http://codespeak.net/pypy/extradoc/eu-report/D02.3_Testing_Framework-interim-2007-03-12.pdf +.. _`Interim D02.1 Development Tools and Website`: http://codespeak.net/pypy/extradoc/eu-report/D02.1_Development_Tools_and_Website-interim-2007-03-12.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 Mon Mar 12 17:29:19 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 12 Mar 2007 17:29:19 +0100 (CET) Subject: [pypy-svn] r40389 - pypy/extradoc/eu-report Message-ID: <20070312162919.184201009C@code0.codespeak.net> Author: cfbolz Date: Mon Mar 12 17:29:12 2007 New Revision: 40389 Added: pypy/extradoc/eu-report/D01.2-4_Project_Organization-interim-2007-03-12.pdf - copied unchanged from r40388, pypy/eu-tracking/deliverable/D01_2-4_Overview_on_Project_Organization_Activities/D01.2-4-deliverablereport.pdf Log: publish D01.2-4 From cfbolz at codespeak.net Mon Mar 12 17:31:50 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 12 Mar 2007 17:31:50 +0100 (CET) Subject: [pypy-svn] r40390 - pypy/dist/pypy/doc Message-ID: <20070312163150.AE8A010094@code0.codespeak.net> Author: cfbolz Date: Mon Mar 12 17:31:49 2007 New Revision: 40390 Modified: pypy/dist/pypy/doc/index-report.txt Log: publish 1.2-4 Modified: pypy/dist/pypy/doc/index-report.txt ============================================================================== --- pypy/dist/pypy/doc/index-report.txt (original) +++ pypy/dist/pypy/doc/index-report.txt Mon Mar 12 17:31:49 2007 @@ -12,6 +12,10 @@ Reports of 2007 =============== +`Interim D01.2-4 Project Organization`_ is an interim version of a report about +the management activities within the PyPy project PyPy development process. The +report is still a draft, all feedback for it is welcome. *(2007-03-12)* + `Interim D02.1 Development Tools and Website`_ is an interim version of a report about the codespeak_ development environment and aditional tool support for the PyPy development process. The report is still a @@ -108,6 +112,7 @@ .. _`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 .. _`Interim D02.3 Testing Tool`: http://codespeak.net/pypy/extradoc/eu-report/D02.3_Testing_Framework-interim-2007-03-12.pdf +.. _`Interim D01.2-4 Project Organization`: http://codespeak.net/pypy/extradoc/eu-report/D01.2-4_Project_Organization-interim-2007-03-12.pdf .. _`Interim D02.1 Development Tools and Website`: http://codespeak.net/pypy/extradoc/eu-report/D02.1_Development_Tools_and_Website-interim-2007-03-12.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 Mon Mar 12 17:47:23 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 12 Mar 2007 17:47:23 +0100 (CET) Subject: [pypy-svn] r40395 - pypy/extradoc/eu-report Message-ID: <20070312164723.6F26D1008A@code0.codespeak.net> Author: cfbolz Date: Mon Mar 12 17:47:21 2007 New Revision: 40395 Added: pypy/extradoc/eu-report/D12.1_H-L-Backends_and_Feature_Prototypes-interim-2007-03-12.pdf - copied unchanged from r40393, pypy/eu-tracking/deliverable/D12_1_H-L_Backends_and_Feature_Prototypes/D12.1-deliverablereport.pdf Log: publish D12 From cfbolz at codespeak.net Mon Mar 12 17:47:58 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 12 Mar 2007 17:47:58 +0100 (CET) Subject: [pypy-svn] r40396 - pypy/dist/pypy/doc Message-ID: <20070312164758.8985910098@code0.codespeak.net> Author: cfbolz Date: Mon Mar 12 17:47:56 2007 New Revision: 40396 Modified: pypy/dist/pypy/doc/index-report.txt Log: publish D12.1. could somebody please add a description? Modified: pypy/dist/pypy/doc/index-report.txt ============================================================================== --- pypy/dist/pypy/doc/index-report.txt (original) +++ pypy/dist/pypy/doc/index-report.txt Mon Mar 12 17:47:56 2007 @@ -12,6 +12,10 @@ Reports of 2007 =============== +`Interim D12.1 High-Level-Backends and Feature Prototypes`_ is an interim +version of a report about XXX add a nice description here. The report is still +a draft, all feedback for it is welcome. *(2007-03-12)* + `Interim D01.2-4 Project Organization`_ is an interim version of a report about the management activities within the PyPy project PyPy development process. The report is still a draft, all feedback for it is welcome. *(2007-03-12)* @@ -115,5 +119,6 @@ .. _`Interim D01.2-4 Project Organization`: http://codespeak.net/pypy/extradoc/eu-report/D01.2-4_Project_Organization-interim-2007-03-12.pdf .. _`Interim D02.1 Development Tools and Website`: http://codespeak.net/pypy/extradoc/eu-report/D02.1_Development_Tools_and_Website-interim-2007-03-12.pdf .. _`Draft D08.2 JIT Compiler Architecture`: http://codespeak.net/pypy/extradoc/eu-report/D08.2_JIT_Compiler_Architecture-interim-2007-01-28.pdf +.. _`Interim D12.1 High-Level-Backends and Feature Prototypes`: http://codespeak.net/pypy/extradoc/eu-report/D12.1_H-L-Backends_and_Feature_Prototypes-interim-2007-03-12.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 Mon Mar 12 17:54:51 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 12 Mar 2007 17:54:51 +0100 (CET) Subject: [pypy-svn] r40397 - pypy/extradoc/eu-report Message-ID: <20070312165451.24BCB10098@code0.codespeak.net> Author: cfbolz Date: Mon Mar 12 17:54:49 2007 New Revision: 40397 Removed: pypy/extradoc/eu-report/D01.2-4_Project_Organization-interim-2007-03-12.pdf Log: remove old version From cfbolz at codespeak.net Mon Mar 12 17:55:06 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 12 Mar 2007 17:55:06 +0100 (CET) Subject: [pypy-svn] r40398 - pypy/extradoc/eu-report Message-ID: <20070312165506.E41D91009A@code0.codespeak.net> Author: cfbolz Date: Mon Mar 12 17:55:04 2007 New Revision: 40398 Added: pypy/extradoc/eu-report/D01.2-4_Project_Organization-interim-2007-03-12.pdf - copied, changed from r40396, pypy/eu-tracking/deliverable/D01_2-4_Overview_on_Project_Organization_Activities/D01.2-4-deliverablereport.pdf Log: add regenerated one From pedronis at codespeak.net Mon Mar 12 18:00:58 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Mon, 12 Mar 2007 18:00:58 +0100 (CET) Subject: [pypy-svn] r40399 - pypy/dist/pypy/doc Message-ID: <20070312170058.5D34E1009A@code0.codespeak.net> Author: pedronis Date: Mon Mar 12 18:00:57 2007 New Revision: 40399 Modified: pypy/dist/pypy/doc/index-report.txt Log: - d12 description - draft -> non-final for the interim reports - added an "and" in D02.1 descr Modified: pypy/dist/pypy/doc/index-report.txt ============================================================================== --- pypy/dist/pypy/doc/index-report.txt (original) +++ pypy/dist/pypy/doc/index-report.txt Mon Mar 12 18:00:57 2007 @@ -12,22 +12,25 @@ Reports of 2007 =============== -`Interim D12.1 High-Level-Backends and Feature Prototypes`_ is an interim -version of a report about XXX add a nice description here. The report is still -a draft, all feedback for it is welcome. *(2007-03-12)* - -`Interim D01.2-4 Project Organization`_ is an interim version of a report about -the management activities within the PyPy project PyPy development process. The -report is still a draft, all feedback for it is welcome. *(2007-03-12)* +`Interim D12.1 High-Level-Backends and Feature Prototypes`_ is an +interim version of a report about our high-level backends and our +several validation prototypes: an information flow security prototype, +a distribution prototype and a persistence proof-of-concept. The +report is still non-final, all feedback for it is +welcome. *(2007-03-12)* + +`Interim D01.2-4 Project Organization`_ is an interim version of a +report about the management activities within the PyPy project and +PyPy development process. The report is still non-final, all feedback +for it is welcome. *(2007-03-12)* `Interim D02.1 Development Tools and Website`_ is an interim version of a report about the codespeak_ development environment and aditional tool support for the -PyPy development process. The report is still a -draft, all feedback for it is welcome. *(2007-03-12)* +PyPy development process. The report is still non-final, all feedback for it is welcome. *(2007-03-12)* `Interim 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-03-12)* +`py.test`_ testing tool which is part of the `py-lib`_. The report is still +non-final, all feedback for it is welcome. *(2007-03-12)* `D07.1 Massive Parallelism and Translation Aspects`_ is a report about PyPy's optimization efforts, garbage collectors and massive parallelism From cfbolz at codespeak.net Mon Mar 12 18:02:56 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 12 Mar 2007 18:02:56 +0100 (CET) Subject: [pypy-svn] r40401 - pypy/extradoc/eu-report Message-ID: <20070312170256.231AB1009C@code0.codespeak.net> Author: cfbolz Date: Mon Mar 12 18:02:52 2007 New Revision: 40401 Removed: pypy/extradoc/eu-report/D01.2-4_Project_Organization-interim-2007-03-12.pdf Log: remove From cfbolz at codespeak.net Mon Mar 12 18:03:08 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 12 Mar 2007 18:03:08 +0100 (CET) Subject: [pypy-svn] r40402 - pypy/extradoc/eu-report Message-ID: <20070312170308.B7C0A1009C@code0.codespeak.net> Author: cfbolz Date: Mon Mar 12 18:03:05 2007 New Revision: 40402 Added: pypy/extradoc/eu-report/D01.2-4_Project_Organization-interim-2007-03-12.pdf - copied unchanged from r40400, pypy/eu-tracking/deliverable/D01_2-4_Overview_on_Project_Organization_Activities/D01.2-4-deliverablereport.pdf Log: add again From simonb at codespeak.net Mon Mar 12 18:27:09 2007 From: simonb at codespeak.net (simonb at codespeak.net) Date: Mon, 12 Mar 2007 18:27:09 +0100 (CET) Subject: [pypy-svn] r40403 - in pypy/dist/pypy: rpython rpython/lltypesystem rpython/test translator/c/src Message-ID: <20070312172709.6D61F10092@code0.codespeak.net> Author: simonb Date: Mon Mar 12 18:27:07 2007 New Revision: 40403 Modified: pypy/dist/pypy/rpython/lltypesystem/lloperation.py pypy/dist/pypy/rpython/lltypesystem/opimpl.py pypy/dist/pypy/rpython/rfloat.py pypy/dist/pypy/rpython/test/test_rint.py pypy/dist/pypy/translator/c/src/float.h Log: allow rtyper to convert r_longlong to float (w help from richard) Modified: pypy/dist/pypy/rpython/lltypesystem/lloperation.py ============================================================================== --- pypy/dist/pypy/rpython/lltypesystem/lloperation.py (original) +++ pypy/dist/pypy/rpython/lltypesystem/lloperation.py Mon Mar 12 18:27:07 2007 @@ -293,6 +293,7 @@ 'cast_int_to_longlong': LLOp(canfold=True), 'cast_uint_to_int': LLOp(canfold=True), 'cast_uint_to_float': LLOp(canfold=True), + 'cast_longlong_to_float':LLOp(canfold=True), 'cast_float_to_int': LLOp(canraise=(OverflowError,)), 'cast_float_to_uint': LLOp(canfold=True), 'truncate_longlong_to_int':LLOp(canfold=True), Modified: pypy/dist/pypy/rpython/lltypesystem/opimpl.py ============================================================================== --- pypy/dist/pypy/rpython/lltypesystem/opimpl.py (original) +++ pypy/dist/pypy/rpython/lltypesystem/opimpl.py Mon Mar 12 18:27:07 2007 @@ -183,6 +183,13 @@ assert type(u) is r_uint return float(u) +def op_cast_longlong_to_float(i): + assert type(i) is r_longlong + # take first 31 bits + li = float(int(i & r_longlong(0x7fffffff))) + ui = float(int(i >> 31)) * float(0x80000000) + return ui + li + def op_cast_int_to_char(b): assert type(b) is int return chr(b) Modified: pypy/dist/pypy/rpython/rfloat.py ============================================================================== --- pypy/dist/pypy/rpython/rfloat.py (original) +++ pypy/dist/pypy/rpython/rfloat.py Mon Mar 12 18:27:07 2007 @@ -1,7 +1,7 @@ from pypy.annotation.pairtype import pairtype from pypy.annotation import model as annmodel from pypy.rpython.lltypesystem.lltype import \ - Signed, Unsigned, Bool, Float, Void, pyobjectptr + Signed, Unsigned, SignedLongLong, Bool, Float, Void, pyobjectptr from pypy.rpython.error import TyperError from pypy.rpython.rmodel import FloatRepr from pypy.rpython.rmodel import IntegerRepr, BoolRepr @@ -173,6 +173,9 @@ if r_from.lowleveltype == Signed and r_to.lowleveltype == Float: log.debug('explicit cast_int_to_float') return llops.genop('cast_int_to_float', [v], resulttype=Float) + if r_from.lowleveltype == SignedLongLong and r_to.lowleveltype == Float: + log.debug('explicit cast_longlong_to_float') + return llops.genop('cast_longlong_to_float', [v], resulttype=Float) return NotImplemented class __extend__(pairtype(FloatRepr, IntegerRepr)): 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 Mar 12 18:27:07 2007 @@ -158,6 +158,25 @@ assert type(res) is float assert res == 5.0 + def test_float_conversion(self): + def f(ii): + return float(ii) + res = self.interpret(f, [r_longlong(100000000)]) + assert type(res) is float + assert res == 100000000. + res = self.interpret(f, [r_longlong(1234567890123456789)]) + assert type(res) is float + assert res == 1.2345678901234568e+18 + + def test_float_conversion_implicit(self): + def f(ii): + return 1.0 + ii + res = self.interpret(f, [r_longlong(100000000)]) + assert type(res) is float + assert res == 100000001. + res = self.interpret(f, [r_longlong(1234567890123456789)]) + assert type(res) is float + assert res == 1.2345678901234568e+18 def test_rarithmetic(self): inttypes = [int, r_uint, r_longlong, r_ulonglong] Modified: pypy/dist/pypy/translator/c/src/float.h ============================================================================== --- pypy/dist/pypy/translator/c/src/float.h (original) +++ pypy/dist/pypy/translator/c/src/float.h Mon Mar 12 18:27:07 2007 @@ -35,4 +35,5 @@ #define OP_CAST_FLOAT_TO_UINT(x,r) r = (unsigned long)(x) #define OP_CAST_INT_TO_FLOAT(x,r) r = (double)(x) #define OP_CAST_UINT_TO_FLOAT(x,r) r = (double)(x) +#define OP_CAST_LONGLONG_TO_FLOAT(x,r) r = (double)(x) #define OP_CAST_BOOL_TO_FLOAT(x,r) r = (double)(x) From arigo at codespeak.net Mon Mar 12 19:31:03 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 12 Mar 2007 19:31:03 +0100 (CET) Subject: [pypy-svn] r40407 - pypy/dist/pypy/translator/benchmark Message-ID: <20070312183103.8254F10098@code0.codespeak.net> Author: arigo Date: Mon Mar 12 19:31:02 2007 New Revision: 40407 Modified: pypy/dist/pypy/translator/benchmark/ (props changed) pypy/dist/pypy/translator/benchmark/benchmarks.py Log: Add logic to allow the benchmark checkout requests to be changed to point to a newer revision, when the benchmark really needs fixing. Right now it means that you'll have to remove all three checkouts by hand and let the script redo them, even though only gadfly was updated. Modified: pypy/dist/pypy/translator/benchmark/benchmarks.py ============================================================================== --- pypy/dist/pypy/translator/benchmark/benchmarks.py (original) +++ pypy/dist/pypy/translator/benchmark/benchmarks.py Mon Mar 12 19:31:02 2007 @@ -35,14 +35,22 @@ def external_dependency(dirname, svnurl, revision): """Check out (if necessary) a given fixed revision of a svn url.""" dirpath = py.magic.autopath().dirpath().join(dirname) - if not dirpath.check(): - CMD = "svn co -r%d %s@%d %s" % (revision, svnurl, revision, dirpath) - print >> sys.stderr, CMD - err = os.system(CMD) - if err != 0: - print >> sys.stderr, "* checkout failed, skipping this benchmark" - return False - return True + revtag = dirpath.join('-svn-rev-') + if dirpath.check(): + if not revtag.check() or int(revtag.read()) != revision: + print >> sys.stderr, ("Out-of-date benchmark checkout!" + " I won't update it automatically.") + print >> sys.stderr, ("To continue, move away or remove the " + "%r directory." % (dirname,)) + sys.exit(1) + return True + CMD = "svn co -r%d %s@%d %s" % (revision, svnurl, revision, dirpath) + print >> sys.stderr, CMD + err = os.system(CMD) + if err != 0: + print >> sys.stderr, "* checkout failed, skipping this benchmark" + return False + revtag.write(str(revision)) def run_cmd(cmd): #print "running", cmd @@ -153,7 +161,7 @@ def check_gadfly(): return external_dependency('gadfly', 'http://codespeak.net/svn/user/arigo/hack/pypy-hack/gadflyZip', - 40225) + 40406) def run_mako(executable='/usr/local/bin/python'): """ run some tests in the mako templating system """ From arigo at codespeak.net Mon Mar 12 19:36:20 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 12 Mar 2007 19:36:20 +0100 (CET) Subject: [pypy-svn] r40408 - pypy/dist/pypy/translator/benchmark Message-ID: <20070312183620.0A8C81009D@code0.codespeak.net> Author: arigo Date: Mon Mar 12 19:36:18 2007 New Revision: 40408 Modified: pypy/dist/pypy/translator/benchmark/benchmarks.py Log: Oups. And also, rename the benchmark from gadfly to gadfly2 to avoid using older results. Modified: pypy/dist/pypy/translator/benchmark/benchmarks.py ============================================================================== --- pypy/dist/pypy/translator/benchmark/benchmarks.py (original) +++ pypy/dist/pypy/translator/benchmark/benchmarks.py Mon Mar 12 19:36:18 2007 @@ -51,6 +51,7 @@ print >> sys.stderr, "* checkout failed, skipping this benchmark" return False revtag.write(str(revision)) + return True def run_cmd(cmd): #print "running", cmd @@ -196,7 +197,7 @@ 's', check_docutils), Benchmark('templess', run_templess, RICHARDS_ASCENDING_GOOD, 's', check_templess), - Benchmark('gadfly', run_gadfly, RICHARDS_ASCENDING_GOOD, + Benchmark('gadfly2', run_gadfly, RICHARDS_ASCENDING_GOOD, 's', check_gadfly), Benchmark('mako', run_mako, RICHARDS_ASCENDING_GOOD, 's', check_mako), From fijal at codespeak.net Mon Mar 12 19:36:31 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 12 Mar 2007 19:36:31 +0100 (CET) Subject: [pypy-svn] r40409 - pypy/dist/pypy/translator/js/examples/console/test Message-ID: <20070312183631.A0E43100A0@code0.codespeak.net> Author: fijal Date: Mon Mar 12 19:36:29 2007 New Revision: 40409 Modified: pypy/dist/pypy/translator/js/examples/console/test/test_console.py Log: import py to skip Modified: pypy/dist/pypy/translator/js/examples/console/test/test_console.py ============================================================================== --- pypy/dist/pypy/translator/js/examples/console/test/test_console.py (original) +++ pypy/dist/pypy/translator/js/examples/console/test/test_console.py Mon Mar 12 19:36:29 2007 @@ -1,4 +1,5 @@ +import py py.test.skip("Skip this till pylib trunk->dist merge") def test_line_skip(): From fijal at codespeak.net Mon Mar 12 19:36:53 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 12 Mar 2007 19:36:53 +0100 (CET) Subject: [pypy-svn] r40410 - pypy/dist/pypy/translator/js/examples/console/test Message-ID: <20070312183653.451921009F@code0.codespeak.net> Author: fijal Date: Mon Mar 12 19:36:51 2007 New Revision: 40410 Modified: pypy/dist/pypy/translator/js/examples/console/test/test_session.py Log: Skip this one as well Modified: pypy/dist/pypy/translator/js/examples/console/test/test_session.py ============================================================================== --- pypy/dist/pypy/translator/js/examples/console/test/test_session.py (original) +++ pypy/dist/pypy/translator/js/examples/console/test/test_session.py Mon Mar 12 19:36:51 2007 @@ -3,6 +3,7 @@ """ import py +py.test.skip("Skip this till pylib trunk->dist merge") from py.__.net.greensock2 import allof from py.__.net.pipe.fd import FDInput From fijal at codespeak.net Mon Mar 12 20:25:39 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 12 Mar 2007 20:25:39 +0100 (CET) Subject: [pypy-svn] r40412 - pypy/extradoc/talk/warsaw2007 Message-ID: <20070312192539.79F0A10094@code0.codespeak.net> Author: fijal Date: Mon Mar 12 20:25:37 2007 New Revision: 40412 Added: pypy/extradoc/talk/warsaw2007/ pypy/extradoc/talk/warsaw2007/talk.txt Log: Add preliminary version of my talk Added: pypy/extradoc/talk/warsaw2007/talk.txt ============================================================================== --- (empty file) +++ pypy/extradoc/talk/warsaw2007/talk.txt Mon Mar 12 20:25:37 2007 @@ -0,0 +1,211 @@ +=================== +Massive parallelism +=================== + +:Authors: Maciej Fijalkowski +:Location: Warsaw Univeristy +:Date: 13.III.2007 + +Writing concurrent programs +=========================== + +* threads + +* events + +* everyone has it's own problems + +Threads problems +================ + +* deadlock + +* hard to debug + +* implicit, non-voluntary scheduling + +Events problems +=============== + +* strange programming style + +* deferred problems + +Alternative approach +==================== + +* concept of greenlet (microthread) + +* way more functionall + +* scales better + +* composable + +Implementation overview +======================= + +* copies stack to heap + +* explicit, voluntary scheduling + +* can employ many policies of scheduling + +Goodies built on top (1) +======================== + +* tasklets + +* communication over channels + +* (example) + +Goodies built on top (2) +======================== + +* cooperative I/O + +* oneof, allof + +* cannot use blocking I/O + +* doesn't work on win32 + +* scales well (application built on top) + +Composable greenlets +===================== + +* keep different parent greenlet for different tasks + +* composable! + +Implementation - RPython +========================= + +* Restricted subset of python + +* full type inference (static, implicit typing) + +* translated to C/LLVM/CLI/JVM/JavaScript + +* fast (~20-50x faster than python) + +Implementation - flowgraphs +============================ + +* flowing of live python objects + +* allows of a wide range of metaprogramming + +* creates flow graph + +* (demo) + +Implementation - annotation +============================ + +* top to bottom type inference + +* explicit type declarations only for topmost functions + +* python type system + +Implementation - rtyping +========================= + +* changes type system to low-level one + +* two type-systems: lltype (C) and ootype (CLI) + +Flow graphs transformation +=========================== + +* stackless transform + +* we create different return values for blocks + +* no direct stack access, no magic, plain C + +Use case - python console +=================================== + +* ajax using pypy's toolkit + +* pypy-c to play + +* multiple consoles + +* web server + +* dispatching of http/console + +* very easy + +Use case - distribution +================================= + +* (demo) + +Multimethods +============= + +* multiple implementation of types + +* so called sliced multimethods + +* works quite well (benchmarks) + +Transparent proxy +================== + +* just another implementation for types + +* also works for interpreter-level types + +* provides a controllable object + +* (demo) + +* ~300 LOC + +* easy :) + +Distribution +============= + +* works quite well on top of tproxy + +* doesn't need to serialize types + +* sends small packets + +* can access any possible object + +* ~500 LOC + +* (demo) + +Back to use case +================= + +* distributed computations + +* easy to debug + +* server over http without changes + +More PyPy! +=========== + +* translator toolchain (prolog interp, js interp) + +* taint object space + +* JIT + +* sponsored by EU as STReP + +* open source (MIT license) + +* Summer of Code From fijal at codespeak.net Mon Mar 12 21:01:41 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 12 Mar 2007 21:01:41 +0100 (CET) Subject: [pypy-svn] r40413 - pypy/extradoc/talk/warsaw2007 Message-ID: <20070312200141.1453910093@code0.codespeak.net> Author: fijal Date: Mon Mar 12 21:01:40 2007 New Revision: 40413 Modified: pypy/extradoc/talk/warsaw2007/talk.txt Log: (birkenfeld) typos Modified: pypy/extradoc/talk/warsaw2007/talk.txt ============================================================================== --- pypy/extradoc/talk/warsaw2007/talk.txt (original) +++ pypy/extradoc/talk/warsaw2007/talk.txt Mon Mar 12 21:01:40 2007 @@ -13,7 +13,7 @@ * events -* everyone has it's own problems +* everything has it's own problems Threads problems ================ @@ -36,7 +36,7 @@ * concept of greenlet (microthread) -* way more functionall +* way more functional * scales better @@ -96,7 +96,7 @@ * flowing of live python objects -* allows of a wide range of metaprogramming +* allows a wide range of metaprogramming * creates flow graph From fijal at codespeak.net Mon Mar 12 21:34:53 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 12 Mar 2007 21:34:53 +0100 (CET) Subject: [pypy-svn] r40414 - pypy/extradoc/talk/warsaw2007 Message-ID: <20070312203453.8BDD010098@code0.codespeak.net> Author: fijal Date: Mon Mar 12 21:34:50 2007 New Revision: 40414 Modified: pypy/extradoc/talk/warsaw2007/talk.txt Log: A slide about debugging (thanks guido) Modified: pypy/extradoc/talk/warsaw2007/talk.txt ============================================================================== --- pypy/extradoc/talk/warsaw2007/talk.txt (original) +++ pypy/extradoc/talk/warsaw2007/talk.txt Mon Mar 12 21:34:50 2007 @@ -3,7 +3,7 @@ =================== :Authors: Maciej Fijalkowski -:Location: Warsaw Univeristy +:Location: Warsaw University :Date: 13.III.2007 Writing concurrent programs @@ -51,6 +51,15 @@ * can employ many policies of scheduling +Debugging +========== + +* two consecutive runs has the same behaviour + +* attaching a debugger in the middle stops whole execution + +* deadlock is explicitly stated by exception + Goodies built on top (1) ======================== @@ -60,7 +69,7 @@ * (example) -Goodies built on top (2) +Greensock ======================== * cooperative I/O From mwh at codespeak.net Tue Mar 13 09:21:21 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Tue, 13 Mar 2007 09:21:21 +0100 (CET) Subject: [pypy-svn] r40415 - pypy/dist/pypy/translator/c Message-ID: <20070313082121.08E86100A7@code0.codespeak.net> Author: mwh Date: Tue Mar 13 09:21:19 2007 New Revision: 40415 Modified: pypy/dist/pypy/translator/c/gc.py Log: fix the windows builds again (thanks Scott Dial) Modified: pypy/dist/pypy/translator/c/gc.py ============================================================================== --- pypy/dist/pypy/translator/c/gc.py (original) +++ pypy/dist/pypy/translator/c/gc.py Tue Mar 13 09:21:19 2007 @@ -218,8 +218,10 @@ if sys.platform == "linux2": yield "#define _REENTRANT 1" yield "#define GC_LINUX_THREADS 1" + if sys.platform != "win32": + # GC_REDIRECT_TO_LOCAL is not supported on Win32 by gc6.8 + yield "#define GC_REDIRECT_TO_LOCAL 1" yield "#define GC_I_HIDE_POINTERS 1" - yield "#define GC_REDIRECT_TO_LOCAL 1" yield '#include ' yield '#define USING_BOEHM_GC' From ale at codespeak.net Tue Mar 13 10:48:16 2007 From: ale at codespeak.net (ale at codespeak.net) Date: Tue, 13 Mar 2007 10:48:16 +0100 (CET) Subject: [pypy-svn] r40417 - in pypy/dist/pypy/module/cclp: . constraint Message-ID: <20070313094816.F3E91100A7@code0.codespeak.net> Author: ale Date: Tue Mar 13 10:48:15 2007 New Revision: 40417 Modified: pypy/dist/pypy/module/cclp/constraint/constraint.py pypy/dist/pypy/module/cclp/constraint/domain.py pypy/dist/pypy/module/cclp/constraint/variable.py pypy/dist/pypy/module/cclp/variable.py Log: Fixes for not demoting methods - still not translatable with --faasen Modified: pypy/dist/pypy/module/cclp/constraint/constraint.py ============================================================================== --- pypy/dist/pypy/module/cclp/constraint/constraint.py (original) +++ pypy/dist/pypy/module/cclp/constraint/constraint.py Tue Mar 13 10:48:15 2007 @@ -10,7 +10,7 @@ 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 + W_Var, W_CVar as W_Variable from pypy.objspace.std.model import StdObjSpaceMultiMethod @@ -30,6 +30,7 @@ self._space.newint(1))) self._names_to_vars = {} for var in w_variables.wrappeditems: + assert isinstance(var, W_Var) self._names_to_vars[var.name_w()] = var self._variables = w_variables.wrappeditems #unwrap once ... @@ -57,10 +58,12 @@ assert isinstance(w_variables, W_ListObject) assert isinstance(w_formula, W_StringObject) items = object_space.unpackiterable(w_variables) + lst = [] for it in items: assert isinstance(it, W_Variable) - var_ids = ','.join([var.name_w() - for var in items]) + lst.append(it.name_w()) + var_ids = ','.join(lst) #[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(), @@ -103,7 +106,7 @@ result_cache = self._space.newdict() for var in self._variables: assert isinstance(var, W_Variable) - result_cache.content[var.w_name()] = self._space.newdict() + self._space.setitem(result_cache, var.w_name(), self._space.newdict()) return result_cache def _assign_values(self): Modified: pypy/dist/pypy/module/cclp/constraint/domain.py ============================================================================== --- pypy/dist/pypy/module/cclp/constraint/domain.py (original) +++ pypy/dist/pypy/module/cclp/constraint/domain.py Tue Mar 13 10:48:15 2007 @@ -75,7 +75,7 @@ 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._space.delitem(self._values, w_value) self._value_removed() def w_remove_values(self, w_values): @@ -91,7 +91,7 @@ assert isinstance(values, list) if len(values) > 0: for w_val in values: - del self._values.content[w_val] + self._space.delitem(self._values,w_val) self._value_removed() def w_size(self): @@ -110,7 +110,7 @@ return self._space.newlist(self.get_values()) def get_values(self): - return [x for x in self._values.content.keys()] + return [x for x in self._space.unpackiterable(self._values)] def __repr__(self): return '' % str(self.w_get_values()) @@ -143,8 +143,8 @@ 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 + w_v1 = space.unpackiterable(w_fd1._values) + res = [w_v for w_v in space.unpackiterable(w_fd2._values) if w_v in w_v1] return make_fd(space, space.newlist(res)) Modified: pypy/dist/pypy/module/cclp/constraint/variable.py ============================================================================== --- pypy/dist/pypy/module/cclp/constraint/variable.py (original) +++ pypy/dist/pypy/module/cclp/constraint/variable.py Tue Mar 13 10:48:15 2007 @@ -24,7 +24,7 @@ def bind__CVar_Root(space, w_cvar, w_obj): #XXX we should (want to) be able to test membership # in a wrapped against wrappeds into a non-wrapped dict - if [True for elt in w_cvar.w_dom._values.content + if [True for elt in space.unpackiterable(w_cvar.w_dom._values) if space.is_true(space.eq(w_obj, elt))]: return bind__Var_Root(space, w_cvar, w_obj) raise_unification_failure(space, "value not in variable domain") Modified: pypy/dist/pypy/module/cclp/variable.py ============================================================================== --- pypy/dist/pypy/module/cclp/variable.py (original) +++ pypy/dist/pypy/module/cclp/variable.py Tue Mar 13 10:48:15 2007 @@ -289,7 +289,7 @@ 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: + if not w_val in space.unpackiterable(w_var.w_dom._values): raise_unification_failure(space, "assignment out of domain") w_var.w_bound_to = w_val @@ -402,7 +402,7 @@ 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(): + for w_xk in space.unpackiterable(w_m1): 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)): From arigo at codespeak.net Tue Mar 13 11:03:29 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 13 Mar 2007 11:03:29 +0100 (CET) Subject: [pypy-svn] r40419 - pypy/dist/pypy/objspace/cpy Message-ID: <20070313100329.CF7BE100A7@code0.codespeak.net> Author: arigo Date: Tue Mar 13 11:03:28 2007 New Revision: 40419 Modified: pypy/dist/pypy/objspace/cpy/objspace.py Log: A hack to fix compilemodule for extension modules using 'index' in unwrap_spec. Modified: pypy/dist/pypy/objspace/cpy/objspace.py ============================================================================== --- pypy/dist/pypy/objspace/cpy/objspace.py (original) +++ pypy/dist/pypy/objspace/cpy/objspace.py Tue Mar 13 11:03:28 2007 @@ -1,4 +1,4 @@ -import types +import types, sys from pypy.objspace.cpy.capi import * from pypy.objspace.cpy.capi import _PyType_Lookup from pypy.objspace.cpy.capi import _PyLong_Sign, _PyLong_NumBits, _PyLong_AsByteArray @@ -153,6 +153,28 @@ # hack here to have index working return self.wrap(self.int_w(w_obj)) + def getindex_w(self, w_obj, w_exception, objdescr=None): + # XXX mess with type(w_obj).getname() in the baseobjspace, + # XXX give a simplified naive version + w_index = w_obj + try: + index = self.int_w(w_index) + except OperationError, err: + if not err.match(self, self.w_OverflowError): + raise + if not w_exception: + # w_index should be a long object, but can't be sure of that + if self.is_true(self.lt(w_index, self.wrap(0))): + return -sys.maxint-1 + else: + return sys.maxint + else: + raise OperationError( + w_exception, self.wrap( + "cannot fit number into an index-sized integer")) + else: + return index + def bigint_w(self, w_obj): if self.is_true(self.isinstance(w_obj, self.w_long)): sign = _PyLong_Sign(w_obj) From arigo at codespeak.net Tue Mar 13 11:04:12 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 13 Mar 2007 11:04:12 +0100 (CET) Subject: [pypy-svn] r40420 - pypy/dist/pypy/objspace/std/test Message-ID: <20070313100412.5D99B100A8@code0.codespeak.net> Author: arigo Date: Tue Mar 13 11:04:11 2007 New Revision: 40420 Modified: pypy/dist/pypy/objspace/std/test/test_shadowtracking.py Log: Fix test. 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 Tue Mar 13 11:04:11 2007 @@ -210,4 +210,4 @@ for name in names] assert append_counter[0] >= 5 * len(names) for name, count in zip(names, names_counters): - assert count >= 5 + assert count[0] >= 5 From arigo at codespeak.net Tue Mar 13 11:06:29 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 13 Mar 2007 11:06:29 +0100 (CET) Subject: [pypy-svn] r40421 - pypy/dist/pypy/doc/config Message-ID: <20070313100629.72777100AA@code0.codespeak.net> Author: arigo Date: Tue Mar 13 11:06:27 2007 New Revision: 40421 Added: pypy/dist/pypy/doc/config/objspace.usemodules.operator.txt (contents, props changed) Log: Auto-generate this. Added: pypy/dist/pypy/doc/config/objspace.usemodules.operator.txt ============================================================================== --- (empty file) +++ pypy/dist/pypy/doc/config/objspace.usemodules.operator.txt Tue Mar 13 11:06:27 2007 @@ -0,0 +1,2 @@ +Use the 'operator' module. +This module is expected to be working and is included by default. From arigo at codespeak.net Tue Mar 13 11:09:27 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 13 Mar 2007 11:09:27 +0100 (CET) Subject: [pypy-svn] r40422 - pypy/dist/pypy/tool/bench/test Message-ID: <20070313100927.2F810100AA@code0.codespeak.net> Author: arigo Date: Tue Mar 13 11:09:25 2007 New Revision: 40422 Modified: pypy/dist/pypy/tool/bench/test/ (props changed) pypy/dist/pypy/tool/bench/test/test_benchmark_report.py Log: Skip test if Image cannot be imported. Fixeol. Modified: pypy/dist/pypy/tool/bench/test/test_benchmark_report.py ============================================================================== --- pypy/dist/pypy/tool/bench/test/test_benchmark_report.py (original) +++ pypy/dist/pypy/tool/bench/test/test_benchmark_report.py Tue Mar 13 11:09:25 2007 @@ -1,5 +1,11 @@ import os import py + +try: + import Image +except ImportError, e: + py.test.skip(str(e)) + from pypy.tool.bench.htmlreport import ( PerfResult, PerfTable, PerfResultCollection, PerfResultDelta, Page From arigo at codespeak.net Tue Mar 13 11:13:40 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 13 Mar 2007 11:13:40 +0100 (CET) Subject: [pypy-svn] r40423 - pypy/dist/pypy/translator/goal/test Message-ID: <20070313101340.8F24B100AA@code0.codespeak.net> Author: arigo Date: Tue Mar 13 11:13:39 2007 New Revision: 40423 Modified: pypy/dist/pypy/translator/goal/test/test_app_main.py Log: Don't crash if $PYTHONSTARTUP is not set in the outside shell. Modified: pypy/dist/pypy/translator/goal/test/test_app_main.py ============================================================================== --- pypy/dist/pypy/translator/goal/test/test_app_main.py (original) +++ pypy/dist/pypy/translator/goal/test/test_app_main.py Tue Mar 13 11:13:39 2007 @@ -184,7 +184,7 @@ child.expect('foobye') def test_pythonstartup(self): - old = os.environ['PYTHONSTARTUP'] + old = os.environ.get('PYTHONSTARTUP', '') try: os.environ['PYTHONSTARTUP'] = crashing_demo_script child = self.spawn([]) @@ -278,7 +278,7 @@ assert '7776' in data def test_no_pythonstartup(self): - old = os.environ['PYTHONSTARTUP'] + old = os.environ.get('PYTHONSTARTUP', '') try: os.environ['PYTHONSTARTUP'] = crashing_demo_script data = self.run('"%s"' % (demo_script,)) From fijal at codespeak.net Tue Mar 13 11:38:00 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 13 Mar 2007 11:38:00 +0100 (CET) Subject: [pypy-svn] r40426 - pypy/dist/pypy/doc Message-ID: <20070313103800.905BC100A5@code0.codespeak.net> Author: fijal Date: Tue Mar 13 11:37:59 2007 New Revision: 40426 Modified: pypy/dist/pypy/doc/objspace-proxies.txt Log: Steal example for report Modified: pypy/dist/pypy/doc/objspace-proxies.txt ============================================================================== --- pypy/dist/pypy/doc/objspace-proxies.txt (original) +++ pypy/dist/pypy/doc/objspace-proxies.txt Tue Mar 13 11:37:59 2007 @@ -489,17 +489,36 @@ Suppose we want to have list which stores all operations performed on 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) + from pypymagic import transparent_proxy, get_transparent_controller + from types import MethodType + + class ListController(object): + def __init__(self, l): + assert isinstance(l, list) + self.l = l + self.history = [] + self.proxy = transparent_proxy(list, self.perform) + + def perform(self, operation, *args, **kwargs): + self.history.append(operation) # remember the operation performed + # perform the operation on the proxied object + result = getattr(self.l, operation)(*args, **kwargs) + if result is self.l: + # If the result is the proxied list + # return the proxy instead. + result = self.proxy + elif (isinstance(result, MethodType) and + result.im_self is self.l): + # Convert methods bound to the proxied list + # to methods bound to the proxy. + # This is to have calls to the method become calls + # to perform. + result = MethodType(result.im_func, self.proxy, result.im_class) + return result + + >>>> l = [] + >>>> c = Controller(l) + >>>> lst = c.proxy Now we can perform:: @@ -509,7 +528,7 @@ >>>> l [3] >>>> c.history - [__getattribute__, __len__] + [__getattribute__, append, __len__] >>>> type(lst) is type(l) True From arigo at codespeak.net Tue Mar 13 11:43:53 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 13 Mar 2007 11:43:53 +0100 (CET) Subject: [pypy-svn] r40427 - pypy/dist/pypy/objspace/std Message-ID: <20070313104353.09FFC100AB@code0.codespeak.net> Author: arigo Date: Tue Mar 13 11:43:51 2007 New Revision: 40427 Modified: pypy/dist/pypy/objspace/std/typeobject.py Log: Improve the hash function used by the method cache. Seems to give good speed-ups on some of our benchmarks. Modified: pypy/dist/pypy/objspace/std/typeobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/typeobject.py (original) +++ pypy/dist/pypy/objspace/std/typeobject.py Tue Mar 13 11:43:51 2007 @@ -7,6 +7,7 @@ from pypy.objspace.std.objecttype import object_typedef from pypy.objspace.std.dictproxyobject import W_DictProxyObject from pypy.rlib.objectmodel import we_are_translated +from pypy.rlib.rarithmetic import intmask, r_uint from copy_reg import _HEAPTYPE @@ -312,18 +313,12 @@ space = w_self.space assert space.config.objspace.std.withmethodcache ec = space.getexecutioncontext() - #try: - # frame = ec.framestack.top() - # position_hash = frame.last_instr ^ id(frame.pycode) - #except IndexError: - # position_hash = 0 version_tag = w_self.version_tag if version_tag is None: tup = w_self._lookup_where(name) return tup - MASK = (1 << space.config.objspace.std.methodcachesizeexp) - 1 - #method_hash = (id(version_tag) ^ position_hash ^ hash(name)) & MASK - method_hash = ((id(version_tag) >> 3) ^ hash(name)) & MASK + SHIFT = r_uint.BITS - space.config.objspace.std.methodcachesizeexp + method_hash = r_uint(intmask(id(version_tag) * hash(name))) >> SHIFT cached_version_tag = ec.method_cache_versions[method_hash] if cached_version_tag is version_tag: cached_name = ec.method_cache_names[method_hash] From arigo at codespeak.net Tue Mar 13 11:59:09 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 13 Mar 2007 11:59:09 +0100 (CET) Subject: [pypy-svn] r40429 - pypy/branch/jit-virtual-world/pypy/jit Message-ID: <20070313105909.07B09100AB@code0.codespeak.net> Author: arigo Date: Tue Mar 13 11:59:08 2007 New Revision: 40429 Modified: pypy/branch/jit-virtual-world/pypy/jit/TODO.txt Log: Update the jit/TODO. Modified: pypy/branch/jit-virtual-world/pypy/jit/TODO.txt ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/TODO.txt (original) +++ pypy/branch/jit-virtual-world/pypy/jit/TODO.txt Tue Mar 13 11:59:08 2007 @@ -1,9 +1,3 @@ -- fix the XXXs in codegen - -- IN-PROGRESS: [] (getitem) used inside complex try/except ends up using the bound - checking version: transformation after flowgraphing that marks op - with implicit exceptions only if they are inside a precise - try:except: - global merge point and portal should delegate their cache impl. to the application (to allow keeping things alive correctly) @@ -23,17 +17,12 @@ Improvements ------------- -- make frames virtual - - promotions for "python dispatching" - do something correct about bytecode_trace - floats -- improve backends (reg. allocation, produce code more lazily in larger units and avoid for example - many open machine blocks at the same time without resorting to many jumps...) - - jit-friendlier interpreter (whatever, as needed) - reduce the size of the timeshifted code: no dispatch for no @@ -46,3 +35,6 @@ - share code between the machine code backends (MachineCodeBlock, possibly register allocation) + +- more green vars in the hintannotator: for y=frozen_list[x] + and for y=hint(x, deepfreeze=True) if x is green From arigo at codespeak.net Tue Mar 13 12:23:37 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 13 Mar 2007 12:23:37 +0100 (CET) Subject: [pypy-svn] r40431 - pypy/branch/jit-virtual-world Message-ID: <20070313112337.70C3F100AB@code0.codespeak.net> Author: arigo Date: Tue Mar 13 12:23:33 2007 New Revision: 40431 Modified: pypy/branch/jit-virtual-world/ (props changed) Log: fix the py lib revision for this branch. From arigo at codespeak.net Tue Mar 13 12:24:40 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 13 Mar 2007 12:24:40 +0100 (CET) Subject: [pypy-svn] r40432 - pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test Message-ID: <20070313112440.8F400100B0@code0.codespeak.net> Author: arigo Date: Tue Mar 13 12:24:39 2007 New Revision: 40432 Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_timeshift.py Log: A passing test, and a test showing the next thing we need to do. 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 Tue Mar 13 12:24:39 2007 @@ -1446,3 +1446,42 @@ res = self.timeshift(f, [7, 3], policy=P) assert res == f(7,3) self.check_insns(indirect_call=1) + + def test_constant_indirect_red_call(self): + def h1(x): + return x-2 + def h2(x): + return x*4 + l = [h1, h2] + def f(n, x): + frozenl = hint(l, deepfreeze=True) + h = frozenl[n&1] + return h(x) + + P = StopAtXPolicy() + res = self.timeshift(f, [7, 3], [0], policy=P) + assert res == f(7,3) + self.check_insns({'int_mul': 1}) + res = self.timeshift(f, [4, 113], [0], policy=P) + assert res == f(4,113) + self.check_insns({'int_sub': 1}) + + def test_indirect_sometimes_residual_red_call(self): + py.test.skip("in-progress") + def h1(x): + return x-2 + def h2(x): + return x*4 + l = [h1, h2] + def f(n, x): + frozenl = hint(l, deepfreeze=True) + h = frozenl[n&1] + return h(x) + + P = StopAtXPolicy(h1) + res = self.timeshift(f, [7, 3], [0], policy=P) + assert res == f(7,3) + self.check_insns({'int_mul': 1}) + res = self.timeshift(f, [4, 113], [0], policy=P) + assert res == f(4,113) + self.check_insns({'direct_call': 1}) From guido at codespeak.net Tue Mar 13 13:03:03 2007 From: guido at codespeak.net (guido at codespeak.net) Date: Tue, 13 Mar 2007 13:03:03 +0100 (CET) Subject: [pypy-svn] r40434 - in pypy/branch/guido-buildtool-web/pypy/tool/build: . test web web/templates web/test Message-ID: <20070313120303.4505E100AB@code0.codespeak.net> Author: guido Date: Tue Mar 13 13:02:59 2007 New Revision: 40434 Modified: pypy/branch/guido-buildtool-web/pypy/tool/build/buildserver.py pypy/branch/guido-buildtool-web/pypy/tool/build/metaserver.py pypy/branch/guido-buildtool-web/pypy/tool/build/test/test_buildserver.py pypy/branch/guido-buildtool-web/pypy/tool/build/web/app.py pypy/branch/guido-buildtool-web/pypy/tool/build/web/conftest.py pypy/branch/guido-buildtool-web/pypy/tool/build/web/templates/build.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: Fixed config problem in tests, added some more info (like log and error) to the build page, fixed build_start_time and build_end_time, added nav to all pages (hard-coded for now). Modified: pypy/branch/guido-buildtool-web/pypy/tool/build/buildserver.py ============================================================================== --- pypy/branch/guido-buildtool-web/pypy/tool/build/buildserver.py (original) +++ pypy/branch/guido-buildtool-web/pypy/tool/build/buildserver.py Tue Mar 13 13:02:59 2007 @@ -28,6 +28,7 @@ accepted = self.channel.receive() if accepted: self.busy_on = request + request.build_start_time = py.std.time.time() thread.start_new_thread(self.wait_until_done, (request,)) else: self.refused.append(request) @@ -62,6 +63,8 @@ # pretend we're compiling by sleeping a bit... py.std.time.sleep(self.testing_sleeptime) + request.build_end_time = py.std.time.time() + buildpath.request = request # re-write to disk self.metaserver.compilation_done(buildpath) self.busy_on = None 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 Tue Mar 13 13:02:59 2007 @@ -100,7 +100,7 @@ # we don't have a build for this yet, find a builder to compile it hostname = self.run(request) if hostname is not None: - return (False, "found a suitable server, going to build on '%s'" % + return (False, "found a suitable server, going to build on '%s'" % (hostname, )) self._queuelock.acquire() try: Modified: pypy/branch/guido-buildtool-web/pypy/tool/build/test/test_buildserver.py ============================================================================== --- pypy/branch/guido-buildtool-web/pypy/tool/build/test/test_buildserver.py (original) +++ pypy/branch/guido-buildtool-web/pypy/tool/build/test/test_buildserver.py Tue Mar 13 13:02:59 2007 @@ -40,8 +40,8 @@ accepted = c1.compile(br) assert accepted ret = c1.channel.receive() - assert ret == br.serialize() # this was still in the buffer - assert c1.busy_on.serialize() == br.serialize() + assert build.BuildRequest.fromstring(ret).id() == br.id() # this was still in the buffer + assert c1.busy_on.id() == br.id() c1.channel.send('foo bar') c1.channel.send(None) c1.channel.send('log') 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 Tue Mar 13 13:02:59 2007 @@ -18,6 +18,12 @@ '"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">\n%s' % ( html.strip().encode('UTF-8'),)) +def format_time(t): + if t is None: + return None + time = py.std.time + return time.strftime('%Y/%m/%d %H:%M', time.gmtime(t)) + class ServerPage(object): """ base class for pages that communicate with the server """ @@ -122,16 +128,37 @@ br = BuildRequest.fromstring(self.call_method('buildrequest', '"%s"' % ( self._buildid,))) - buildurl = self.call_method('buildurl', '"%s"' % (self._buildid,)) + buildurl = None + log = None + error = None + if br.build_start_time: + if br.build_end_time: + buildurl = self.call_method('buildurl', + '"%s"' % (self._buildid,)) + info = self.call_method('buildpathinfo', + '"%s"' % (self._buildid,)) + log = info['log'] + error = info['error'] + if error: + status = 'failed' + else: + status = 'done' + else: + status = 'in progress' + else: + status = 'waiting' return { 'url': buildurl, 'id': br.id(), 'email': br.email, 'svnurl': br.svnurl, 'svnrev': br.normalized_rev, - 'request_time': br.request_time, - 'build_start_time': br.build_start_time, - 'build_end_time': br.build_end_time, + 'request_time': format_time(br.request_time), + 'build_start_time': format_time(br.build_start_time), + 'build_end_time': format_time(br.build_end_time), + 'status': status, + 'log': log, + 'error': error, } class BuildsIndexPage(ServerPage): @@ -144,6 +171,9 @@ fix_html(template.unicode({'builds': self.get_builds()}))) def get_builds(self): + buildrequests = [BuildRequest.fromstring(b) for b in + self.call_method('buildrequests')] + buildrequests.sort(lambda a, b: cmp(a.request_time, b.request_time)) return [{'id': b.id(), 'href': '/builds/%s' % (b.id(),), 'email': b.email, @@ -151,9 +181,7 @@ 'svnrev': b.normalized_rev, 'request_time': b.request_time, 'build_start_time': b.build_start_time, - 'build_end_time': b.build_end_time} for b in - [BuildRequest.fromstring(b) for b in - self.call_method('buildrequests')]] + 'build_end_time': b.build_end_time} for b in buildrequests] class Builds(Collection): """ container for BuildsIndexPage and BuildPage """ @@ -178,10 +206,11 @@ class Application(Collection): """ the application root """ - style = FsFile(mypath.join('theme/style.css'), 'text/css') - serverstatus = ServerStatusPage(config) - buildersinfo = BuildersInfoPage(config) - builds = Builds(config) + def __init__(self, config): + self.style = FsFile(mypath.join('theme/style.css'), 'text/css') + self.serverstatus = ServerStatusPage(config) + self.buildersinfo = BuildersInfoPage(config) + self.builds = Builds(config) def index(self, handler, path, query): template = templess.template( @@ -191,7 +220,9 @@ index.exposed = True class AppHandler(Handler): - application = Application() + def __init__(self, *args, **kwargs): + self.application = Application(config) + super(AppHandler, self).__init__(*args, **kwargs) class MetaServerAccessor(object): def __init__(self, ms): @@ -224,6 +255,14 @@ if r.id() == id: return r.serialize() + def buildpathinfo(self, requestid): + for bp in self.server._done: + if bp.request.id() == requestid: + return { + 'log': str(bp.log), + 'error': str(bp.error), + } + def buildurl(self, id): for r in self.server._done: if r.request.id() == id: Modified: pypy/branch/guido-buildtool-web/pypy/tool/build/web/conftest.py ============================================================================== --- pypy/branch/guido-buildtool-web/pypy/tool/build/web/conftest.py (original) +++ pypy/branch/guido-buildtool-web/pypy/tool/build/web/conftest.py Tue Mar 13 13:02:59 2007 @@ -1,6 +1,9 @@ import py from py.__.doc.conftest import Directory as Dir, DoctestText, \ ReSTChecker + +mypath = py.magic.autopath().dirpath() + Option = py.test.config.Option option = py.test.config.addoptions("pypybuilder test options", Option('', '--webcheck', @@ -10,3 +13,8 @@ ), ) +class Directory(Dir): + def run(self): + if self.fspath == mypath: + return ['test', 'README.txt', 'README_TEMPLESSER.txt'] + return super(Directory, self).run() Modified: pypy/branch/guido-buildtool-web/pypy/tool/build/web/templates/build.html ============================================================================== --- pypy/branch/guido-buildtool-web/pypy/tool/build/web/templates/build.html (original) +++ pypy/branch/guido-buildtool-web/pypy/tool/build/web/templates/build.html Tue Mar 13 13:02:59 2007 @@ -3,20 +3,48 @@ Build meta server build <t:tag t:replace="id" /> +

Build

-
url
-
-
svn url
-
-
svn revision
-
-
request time
-
-
started
-
-
ended
-
+
+ url: + +
+
+ status: + +
+
+ error: + +
+
+ svn url: + +
+
+ svn revision: + +
+
+ request time: + +
+
+ started: + +
+
+ ended: + +
+
+
+      
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 Tue Mar 13 13:02:59 2007 @@ -4,6 +4,11 @@ +

Connected build servers

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 Tue Mar 13 13:02:59 2007 @@ -3,6 +3,11 @@ Build meta server builds page +

Overview of builds

Here you see an overview of all builds, both completed (and available 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 Tue Mar 13 13:02:59 2007 @@ -3,9 +3,10 @@ Build meta server web interface (temp index page) -

    + 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 Tue Mar 13 13:02:59 2007 @@ -3,6 +3,11 @@ Build meta server status page +

    Server status

    • Connected build servers:
    • 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 Tue Mar 13 13:02:59 2007 @@ -61,7 +61,7 @@ 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.config = fake.Container(port=TESTPORT, path=path, server='localhost') mod.gateway = py.execnet.PopenGateway() def teardown_module(mod): @@ -70,7 +70,7 @@ class TestIndexPage(object): def test_call(self): - a = Application() + a = Application(config) headers, html = a.index(None, '/', '') assert headers == {'Content-Type': 'text/html; charset=UTF-8'} assert html.strip().startswith(' Author: arigo Date: Tue Mar 13 13:21:50 2007 New Revision: 40436 Added: pypy/dist/pypy/translator/goal/test2/ - copied from r40427, pypy/dist/pypy/translator/goal/test/ Removed: pypy/dist/pypy/translator/goal/test/ Modified: pypy/dist/pypy/translator/goal/test2/test_app_main.py Log: Rename test to test2 to avoid clashes with the stdlib :-( Modified: pypy/dist/pypy/translator/goal/test2/test_app_main.py ============================================================================== --- pypy/dist/pypy/translator/goal/test/test_app_main.py (original) +++ pypy/dist/pypy/translator/goal/test2/test_app_main.py Tue Mar 13 13:21:50 2007 @@ -216,7 +216,7 @@ p = os.path.join(autopath.this_dir, 'mymodule.py') p = os.path.abspath(p) child = self.spawn(['-i', - '-m', 'pypy.translator.goal.test.mymodule', + '-m', 'pypy.translator.goal.test2.mymodule', 'extra']) child.expect('mymodule running') child.expect('Name: __main__') @@ -228,9 +228,9 @@ #child.expect(re.escape(repr("foobar"))) #child.expect('>>> ') child.sendline('import sys') - child.sendline('"pypy.translator.goal.test" in sys.modules') + child.sendline('"pypy.translator.goal.test2" in sys.modules') child.expect('True') - child.sendline('"pypy.translator.goal.test.mymodule" in sys.modules') + child.sendline('"pypy.translator.goal.test2.mymodule" in sys.modules') child.expect('False') @@ -291,7 +291,7 @@ def test_option_m(self): p = os.path.join(autopath.this_dir, 'mymodule.py') p = os.path.abspath(p) - data = self.run('-m pypy.translator.goal.test.mymodule extra') + data = self.run('-m pypy.translator.goal.test2.mymodule extra') assert 'mymodule running' in data assert 'Name: __main__' in data assert ('File: ' + p) in data From guido at codespeak.net Tue Mar 13 14:38:17 2007 From: guido at codespeak.net (guido at codespeak.net) Date: Tue, 13 Mar 2007 14:38:17 +0100 (CET) Subject: [pypy-svn] r40438 - in pypy/branch/guido-buildtool-web/pypy/tool/build/web: . templates test Message-ID: <20070313133817.45EBD100A7@code0.codespeak.net> Author: guido Date: Tue Mar 13 14:38:15 2007 New Revision: 40438 Added: pypy/branch/guido-buildtool-web/pypy/tool/build/web/README_TEMPLESSER.txt pypy/branch/guido-buildtool-web/pypy/tool/build/web/templesser.py pypy/branch/guido-buildtool-web/pypy/tool/build/web/test/test_templesser.py Modified: pypy/branch/guido-buildtool-web/pypy/tool/build/web/README.txt pypy/branch/guido-buildtool-web/pypy/tool/build/web/app.py pypy/branch/guido-buildtool-web/pypy/tool/build/web/templates/build.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/serverstatus.html Log: Replaced Templess with Templesser, which is basically an extension to string interpolation that allows repeating blocks and marking blocks as conditional. This removes the dependency on a third-party library. Modified: pypy/branch/guido-buildtool-web/pypy/tool/build/web/README.txt ============================================================================== --- pypy/branch/guido-buildtool-web/pypy/tool/build/web/README.txt (original) +++ pypy/branch/guido-buildtool-web/pypy/tool/build/web/README.txt Tue Mar 13 14:38:15 2007 @@ -31,19 +31,11 @@ ------------ 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. +and a recent PyPy checkout or release (which you have, else you wouldn't be +reading this ;). Questions, remarks, etc. ------------------------ For questions, remarks, etc. about this product, mail guido at merlinux.de. + Added: pypy/branch/guido-buildtool-web/pypy/tool/build/web/README_TEMPLESSER.txt ============================================================================== --- (empty file) +++ pypy/branch/guido-buildtool-web/pypy/tool/build/web/README_TEMPLESSER.txt Tue Mar 13 14:38:15 2007 @@ -0,0 +1,75 @@ +Templesser +=========== + +What is it? +----------- + +Templesser is basically an extension to string interpolation that introduces +blocks that can be repeated and conditional blocks. + +Blocks start with '%()[b', where is the name of the block, +and end with '%()]b', where is again the name of the block +and must match the opening name. + +The 'b' in the previous case marks a basic repeat block, which is repeated for +all items in a list; there are also 'c' (conditional) blocks that are rendered +only if the value for the context key resolves to False (and not to an empty +string). + +This module is a drop-in replacement for Templess' basic functionality, +see the Templess documentation (http://templess.johnnydebris.net) for more +details. + +Let's show some examples, the first displays how Templesser can do +normal string interpolation:: + + >>> from pypy.tool.build.web.templesser import template + >>> t = template(u'foo %(bar)s baz') + >>> t.unicode({'bar': 'qux'}) + u'foo qux baz' + +The second example displays how to deal with a simple conditional block:: + + >>> t = template(u'foo %(bar)[cbar %(bar)]cbaz') + >>> t.unicode({'bar': False}) + u'foo baz' + >>> t.unicode({'bar': True}) + u'foo bar baz' + +Now an example with a repeat block, note how the context value is a list +type - this can be any type of iterable, but _must_ be a list type, even +if there's only a single item to interpolate:: + + >>> t = template(u'foo %(bar)[b %(bar)]b baz') + >>> t.unicode({'bar': [1, 2, 3]}) + u'foo 1 2 3 baz' + +A more useful example with a repeat block uses nested dictionaries as +values for the list, resulting in a nested interpolation:: + + >>> t = template(u'foo %(bar)[b%(baz)s qux %(quux)s%(bar)]b quuux') + >>> t.unicode({'bar': [{'baz': 1, 'quux': 2}, + ... {'baz': 'spam', 'quux': 'eggs'}]}) + u'foo 1 qux 2 spam qux eggs quuux' + +Some quick notes +================= + +* yes, this is ugly stuff... + +* my motivation? simplicity... it's inspired on templess + (http://templess.johnnydebris.net) which does similar things + but with a more elegant (XML based) syntax, we decided to remove + the templess dependency, but i didn't feel like modifying the + code too much, so i wanted to have something very simple with the + same api and similar behaviour + +* there has been no time spent on error reporting at all, so + it most probably sucks... + +Questions, remarks, etc. +========================= + +For questions, remarks, bug reports and patches, send email to +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 Tue Mar 13 14:38:15 2007 @@ -9,7 +9,7 @@ from pypy.tool.build.build import BuildRequest from pypy.tool.build.web.server import HTTPError, Collection, Handler, FsFile -from templess import templess +from pypy.tool.build.web import templesser mypath = py.magic.autopath().dirpath() @@ -71,7 +71,7 @@ """ a page displaying overall meta server statistics """ def __call__(self, handler, path, query): - template = templess.template( + template = templesser.template( mypath.join('templates/serverstatus.html').read()) return ({'Content-Type': 'text/html; charset=UTF-8'}, fix_html(template.unicode(self.get_status()))) @@ -81,7 +81,7 @@ class BuildersInfoPage(ServerPage): def __call__(self, handler, path, query): - template = templess.template( + template = templesser.template( mypath.join('templates/buildersinfo.html').read()) return ({'Content-Type': 'text/html; charset=UTF-8'}, fix_html(template.unicode({'builders': @@ -92,6 +92,7 @@ # some massaging of the data for Templess for binfo in infos: binfo['sysinfo'] = [binfo['sysinfo']] + binfo['not_busy'] = not binfo['busy_on'] if binfo['busy_on']: b = binfo['busy_on'] req = BuildRequest.fromstring(binfo['busy_on']) @@ -101,7 +102,7 @@ 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... + # templesser 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']: @@ -119,7 +120,7 @@ self._buildid = buildid def __call__(self, handler, path, query): - template = templess.template( + template = templesser.template( mypath.join('templates/build.html').read()) return ({'Content-Type': 'text/html; charset=UTF-8'}, fix_html(template.unicode(self.get_info()))) @@ -165,7 +166,7 @@ """ display the list of available builds """ def __call__(self, handler, path, query): - template = templess.template( + template = templesser.template( mypath.join('templates/builds.html').read()) return ({'Content-Type': 'text/html; charset=UTF-8'}, fix_html(template.unicode({'builds': self.get_builds()}))) @@ -213,7 +214,7 @@ self.builds = Builds(config) def index(self, handler, path, query): - template = templess.template( + template = templesser.template( mypath.join('templates/index.html').read()) return ({'Content-Type': 'text/html; charset=UTF-8'}, fix_html(template.unicode({}))) @@ -222,7 +223,7 @@ class AppHandler(Handler): def __init__(self, *args, **kwargs): self.application = Application(config) - super(AppHandler, self).__init__(*args, **kwargs) + Handler.__init__(self, *args, **kwargs) class MetaServerAccessor(object): def __init__(self, ms): Modified: pypy/branch/guido-buildtool-web/pypy/tool/build/web/templates/build.html ============================================================================== --- pypy/branch/guido-buildtool-web/pypy/tool/build/web/templates/build.html (original) +++ pypy/branch/guido-buildtool-web/pypy/tool/build/web/templates/build.html Tue Mar 13 14:38:15 2007 @@ -1,6 +1,6 @@ - + - Build meta server build <t:tag t:replace="id" /> + Build meta server build %(id)s -

      Build

      +

      Build %(id)s

      -
      - url: - -
      + %(url)[c +
      + url: + %(url)s +
      + %(url)]c
      status: - -
      -
      - error: - + %(status)s
      + %(error)[c +
      + error: + %(error)s +
      + %(error)]c
      svn url: - + %(svnurl)s
      svn revision: - + %(svnrev)s
      request time: - -
      -
      - started: - + %(request_time)s
      -
      - ended: - -
      -
      -
      +      %(build_start_time)[c
      +        
      + started: + %(build_start_time)s +
      + %(build_start_time)]c + %(build_end_time)[c +
      + ended: + %(build_end_time)s +
      + %(build_end_time)]c + %(log)[c +
      +
      %(log)s
      + %(log)]c
      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 Tue Mar 13 14:38:15 2007 @@ -1,4 +1,4 @@ - + Build meta server builders page @@ -11,62 +11,70 @@

    Connected build servers

    -
    -

    -
    -
    -
    sysinfo:
    -
    -
    - os: - -
    -
    - maxint: - -
    -
    - byteorder: - + %(builders)[b +
    +

    %(hostname)s

    +
    +
    +
    sysinfo:
    + %(sysinfo)[b +
    +
    + os: + %(os)s +
    +
    + maxint: + %(maxint)s +
    +
    + byteorder: + %(byteorder)s +
    + %(sysinfo)]b
    -
    - - --> + %(busy_on)]c
    -
    + %(builders)]b
    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 Tue Mar 13 14:38:15 2007 @@ -1,4 +1,4 @@ - + Build meta server builds page @@ -14,11 +14,13 @@ for download) and waiting or in-progress ones, ordered by date. Click on the build to get more information.

    -
    - + %(builds)]b 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 Tue Mar 13 14:38:15 2007 @@ -10,11 +10,11 @@

Server status

    -
  • Connected build servers:
  • -
  • Currently running builds:
  • -
  • Builds done:
  • -
  • Clients waiting for a build:
  • -
  • Builds for which no suitable server is available:
  • +
  • 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
Added: pypy/branch/guido-buildtool-web/pypy/tool/build/web/templesser.py ============================================================================== --- (empty file) +++ pypy/branch/guido-buildtool-web/pypy/tool/build/web/templesser.py Tue Mar 13 14:38:15 2007 @@ -0,0 +1,74 @@ +""" even lighter weight replacement for templess + + see README_TEMPLESSER.txt for more details +""" + +import re + +class template(object): + """ string interpolation on steriods """ + def __init__(self, input): + self.input = input + + def unicode(self, context): + """ resolve interpolations using context as data dict """ + data = self.input + data = self._resolve_repeats(data, context) + data = self._resolve_conditionals(data, context) + data = data % context + return data + + _reg_cond_1 = re.compile(r'([^%])([%]{2})*[%][(]([^)]+)[)][[]c(.*)' + r'[%][(]\3[)][]]c(.*?)$', re.S | re.U) + _reg_cond_2 = re.compile(r'^[%][(]([^)]+)[)][[]c(.*)' + r'[%][(]\1[)][]]c(.*?)$', re.S | re.U) + def _resolve_conditionals(self, data, context): + while 1: + match = self._reg_cond_1.search(data) + offset = 2 + if not match: + match = self._reg_cond_2.search(data) + if not match: + break + offset = 0 + key = match.group(offset + 1) + pre = data[:data.find(match.group(0))] + data = pre + if offset == 2: + data += (match.group(1) or '') + (match.group(2) or '') + if context[key]: + data += match.group(offset + 2) or '' + data += match.group(offset + 3) or '' + return data + + _reg_rept_1 = re.compile(r'([^%])([%]{2})*[%][(]([^)]+)[)][[]b(.*)' + r'[%][(]\3[)][]]b(.*?)$', re.S | re.U) + _reg_rept_2 = re.compile(r'^[%][(]([^)]+)[)][[]b(.*)' + r'[%][(]\1[)][]]b(.*?)$', re.S | re.U) + def _resolve_repeats(self, data, context): + while 1: + match = self._reg_rept_1.search(data) + offset = 2 + if not match: + match = self._reg_rept_2.search(data) + if not match: + break + offset = 0 + key = match.group(offset + 1) + # here we just assume the content is an iterable + processed = [] + for subcontext in context[key]: + if isinstance(subcontext, dict): + t = template(match.group(offset + 2)) + processed.append(t.unicode(subcontext)) + else: + if not type(subcontext) in [str, unicode]: + subcontext = str(subcontext) + processed.append(subcontext) + pre = data[:data.find(match.group(0))] + data = pre + if offset == 2: + data += (match.group(1) or '') + (match.group(2) or '') + data += ' '.join(processed) + match.group(offset + 3) or '' + return data + Added: pypy/branch/guido-buildtool-web/pypy/tool/build/web/test/test_templesser.py ============================================================================== --- (empty file) +++ pypy/branch/guido-buildtool-web/pypy/tool/build/web/test/test_templesser.py Tue Mar 13 14:38:15 2007 @@ -0,0 +1,71 @@ +import py +from pypy.tool.build.web.templesser import template + +def test_template_conditionals(): + t = template('%(cond)[cfoo%(cond)]c') + u = t.unicode({'cond': True}) + assert u == u'foo' + u = t.unicode({'cond': False}) + assert u == u'' + +def test_template_block(): + t = template('%(block)[b%(foo)s%(block)]b') + u = t.unicode({'block': [{'foo': 'spam'}, {'foo': 'eggs'}]}) + assert u == u'spam eggs' + +def test_combined(): + t = template(u'%(block)[b%(cond)[cfoo%(cond)]c%(block)]b') + u = t.unicode({'block': [{'cond': False}]}) + assert u == u'' + u = t.unicode({'block': [{'cond': True}]}) + assert u == u'foo' + +def test_nested_resolve_conditionals(): + t = template(u'%(cond1)[cfoo%(cond2)[cbar%(cond2)]cbaz%(cond1)]c') + u = t.unicode({'cond1': False, 'cond2': True}) + assert u == u'' + u = t.unicode({'cond1': True, 'cond2': False}) + assert u == u'foobaz' + u = t.unicode({'cond1': True, 'cond2': True}) + assert u == u'foobarbaz' + +def test_newlines_block(): + t = template(u'foo\n%(block)[b%(bar)s%(block)]b\nbaz') + u = t.unicode({'block': [{'bar': '1'}, {'bar': '2'}]}) + assert u == u'foo\n1 2\nbaz' + +def test_keyerror(): + t = template(u'%(cond)[c foo %(cond)]c') + py.test.raises(KeyError, 't.unicode({})') + +def test_escaping_conditional(): + t = template(u'%%(cond)[c foo %%(cond)]c') + u = t.unicode({}) + assert u == u'%(cond)[c foo %(cond)]c' + +def test_escaping_broken(): + t = template(u'%%(cond)[c foo %(cond)]c') + py.test.raises(KeyError, 't.unicode({})') + +def test_quick_functional(): + t = template(u"""\ + + + %(title)s + + + %(header)[c +

%(header)s

+ %(header)]c + %(items)[b + %(name)[c
%(name)s
%(name)]c + %(values)[b +
%(value)s
+ %(values)]b + %(items)]b + + +""") + u = t.unicode({'title': 'foo', 'header': False, 'items': []}) + u = u.replace(' ', '').replace('\n', '') + assert u == u'foo' From guido at codespeak.net Tue Mar 13 15:25:39 2007 From: guido at codespeak.net (guido at codespeak.net) Date: Tue, 13 Mar 2007 15:25:39 +0100 (CET) Subject: [pypy-svn] r40439 - in pypy/branch/guido-buildtool-web/pypy/tool/build/web: . templates test Message-ID: <20070313142539.0EB30100AC@code0.codespeak.net> Author: guido Date: Tue Mar 13 15:25:37 2007 New Revision: 40439 Modified: 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/templesser.py pypy/branch/guido-buildtool-web/pypy/tool/build/web/test/test_app.py Log: Fixed escaping bug in templesser, fixed problem in buildersinfo template, added support for HTTP headers to avoid caching to server, and code to use it in the pages. 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 Tue Mar 13 15:25:37 2007 @@ -7,7 +7,8 @@ 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, Collection, Handler, FsFile +from pypy.tool.build.web.server import HTTPError, Collection, Handler, \ + FsFile, get_nocache_headers from pypy.tool.build.web import templesser @@ -24,6 +25,11 @@ time = py.std.time return time.strftime('%Y/%m/%d %H:%M', time.gmtime(t)) +def get_headers(): + headers = {'Content-Type': 'text/html; charset=UTF-8'} + headers.update(get_nocache_headers()) + return headers + class ServerPage(object): """ base class for pages that communicate with the server """ @@ -73,8 +79,7 @@ def __call__(self, handler, path, query): template = templesser.template( mypath.join('templates/serverstatus.html').read()) - return ({'Content-Type': 'text/html; charset=UTF-8'}, - fix_html(template.unicode(self.get_status()))) + return (get_headers(), fix_html(template.unicode(self.get_status()))) def get_status(self): return self.call_method('status') @@ -83,9 +88,8 @@ def __call__(self, handler, path, query): template = templesser.template( mypath.join('templates/buildersinfo.html').read()) - return ({'Content-Type': 'text/html; charset=UTF-8'}, - fix_html(template.unicode({'builders': - self.get_buildersinfo()}))) + return (get_headers(), fix_html(template.unicode( + {'builders': self.get_buildersinfo()}))) def get_buildersinfo(self): infos = self.call_method('buildersinfo') @@ -110,6 +114,8 @@ d[key] = time.strftime('%Y/%m/%d %H:%M:%S', time.gmtime(d[key])) binfo['busy_on'] = [d] + else: + binfo['busy_on'] = [] return infos class BuildPage(ServerPage): @@ -122,7 +128,7 @@ def __call__(self, handler, path, query): template = templesser.template( mypath.join('templates/build.html').read()) - return ({'Content-Type': 'text/html; charset=UTF-8'}, + return (get_headers(), fix_html(template.unicode(self.get_info()))) def get_info(self): @@ -168,7 +174,7 @@ def __call__(self, handler, path, query): template = templesser.template( mypath.join('templates/builds.html').read()) - return ({'Content-Type': 'text/html; charset=UTF-8'}, + return (get_headers(), fix_html(template.unicode({'builds': self.get_builds()}))) def get_builds(self): @@ -216,7 +222,7 @@ def index(self, handler, path, query): template = templesser.template( mypath.join('templates/index.html').read()) - return ({'Content-Type': 'text/html; charset=UTF-8'}, + return (get_headers(), fix_html(template.unicode({}))) index.exposed = True 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 Tue Mar 13 15:25:37 2007 @@ -1,5 +1,6 @@ import sys import traceback +import time from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler # some generic stuff to make working with BaseHTTPServer a bit nicer... @@ -119,6 +120,7 @@ status = 200 if not 'content-type' in [k.lower() for k in headers]: headers['Content-Type'] = 'text/html; charset=UTF-8' + headers['Connection'] = 'close' # for now? :| self.response(status, headers, data, send_body) do_POST = do_GET @@ -152,7 +154,9 @@ def process_http_error(self, e): """ create the response body and headers for errors """ - headers = {'Content-Type': 'text/plain'} # XXX need more headers here? + headers = {'Content-Type': 'text/plain', + } + headers.update(get_nocache_headers()) if e.status in [301, 302]: headers['Location'] = e.data body = 'Redirecting to %s' % (e.data,) @@ -189,6 +193,15 @@ server = HTTPServer(address, handler) server.serve_forever() +def get_nocache_headers(): + return {'Connection': 'close', + 'Pragma': 'no-cache', + 'Expires': 'Mon, 26 Jul 1997 05:00:00 GMT', + 'Last-Modified': time.strftime("%a, %d %b %Y %H:%M:%S GMT"), + 'Cache-Control': 'no-cache, must-revalidate', + 'Cache-Control': 'post-check=0, pre-check=0', + } + # ready-to-use Collection and resource implementations class FsFile(object): exposed = True @@ -201,5 +214,6 @@ def __call__(self, handler, path, query): if self._data is None or self.debug: self._data = self._path.read() + # XXX should handle caching here... 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 Tue Mar 13 15:25:37 2007 @@ -37,8 +37,8 @@
busy on build:
%(not_busy)[c
nothing
%(not_busy)]c - %(busy_on)[c -
%(busy_on)s
+ %(busy_on)[b +
%(id)s
request time: @@ -70,7 +70,7 @@
-->
- %(busy_on)]c + %(busy_on)]b
Modified: pypy/branch/guido-buildtool-web/pypy/tool/build/web/templesser.py ============================================================================== --- pypy/branch/guido-buildtool-web/pypy/tool/build/web/templesser.py (original) +++ pypy/branch/guido-buildtool-web/pypy/tool/build/web/templesser.py Tue Mar 13 15:25:37 2007 @@ -60,7 +60,7 @@ for subcontext in context[key]: if isinstance(subcontext, dict): t = template(match.group(offset + 2)) - processed.append(t.unicode(subcontext)) + processed.append(t.unicode(subcontext).replace('%', '%%')) else: if not type(subcontext) in [str, unicode]: subcontext = str(subcontext) 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 Tue Mar 13 15:25:37 2007 @@ -72,7 +72,7 @@ def test_call(self): a = Application(config) headers, html = a.index(None, '/', '') - assert headers == {'Content-Type': 'text/html; charset=UTF-8'} + assert headers['Content-Type'] == 'text/html; charset=UTF-8' assert html.strip().startswith('') html_validate(html) @@ -101,7 +101,7 @@ def test_call(self): p = ServerStatusPage(config, gateway) headers, html = p(None, '/serverstatus', '') - assert headers == {'Content-Type': 'text/html; charset=UTF-8'} + assert headers['Content-Type'] == 'text/html; charset=UTF-8' assert html.strip().startswith('') html_validate(html) @@ -115,7 +115,8 @@ info = p.get_buildersinfo() assert info == [{'sysinfo': [{'foo': 'bar'}], 'hostname': 'fake', - 'busy_on': None}] + 'busy_on': [], + 'not_busy': True}] def test_call(self): class TestPage(BuildersInfoPage): @@ -123,23 +124,30 @@ b = build.BuildRequest('foo at bar.com', {}, {'foo': 'bar'}, 'http://codespeak.net/svn/pypy/dist', 10, 2, 123456789) + binfo = b.todict() + binfo.update({'href': 'file:///foo', + 'log': 'everything went well', + 'error': None, + 'id': 'somebuild'}) return [ {'hostname': 'host1', 'sysinfo': [{ 'os': 'linux2', 'maxint': 9223372036854775807L, 'byteorder': 'little'}], - 'busy_on': None}, + 'busy_on': [], + 'not_busy': True}, {'hostname': 'host2', 'sysinfo': [{ 'os': 'zx81', 'maxint': 255, 'byteorder': 'little'}], - 'busy_on': b.todict()}, + 'busy_on': [binfo], + 'not_busy': False}, ] p = TestPage(config, gateway) headers, html = p(None, '/buildersinfo', '') - assert headers == {'Content-Type': 'text/html; charset=UTF-8'} + assert headers['Content-Type'] == 'text/html; charset=UTF-8' assert html.strip().startswith('') html_validate(html) @@ -155,7 +163,7 @@ def test_call(self): p = BuildsIndexPage(config, gateway) headers, html = p(None, '/builds/', '') - assert headers == {'Content-Type': 'text/html; charset=UTF-8'} + assert headers['Content-Type'] == 'text/html; charset=UTF-8' assert html.strip().startswith('') html_validate(html) From antocuni at codespeak.net Tue Mar 13 15:44:18 2007 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Tue, 13 Mar 2007 15:44:18 +0100 (CET) Subject: [pypy-svn] r40440 - pypy/dist/pypy/translator/cli Message-ID: <20070313144418.0F15C10078@code0.codespeak.net> Author: antocuni Date: Tue Mar 13 15:44:16 2007 New Revision: 40440 Modified: pypy/dist/pypy/translator/cli/entrypoint.py Log: Use the real name of the executable instead of "" for argv[0]. This is not the same behaviour as we have in C because in .NET there is no way to know the exact command line that started the process, so its value is always the absolute path referring to the exe. Still better than nothing... Modified: pypy/dist/pypy/translator/cli/entrypoint.py ============================================================================== --- pypy/dist/pypy/translator/cli/entrypoint.py (original) +++ pypy/dist/pypy/translator/cli/entrypoint.py Tue Mar 13 15:44:16 2007 @@ -42,9 +42,10 @@ ilasm.begin_function('main', [('string[]', 'argv')], 'void', True, 'static') ilasm.new('instance void class [pypylib]pypy.runtime.List`1::.ctor()') - # fake argv[0] + # fake argv[0] ilasm.opcode('dup') - ilasm.opcode('ldstr ""') + ilasm.call('class [mscorlib]System.Reflection.Assembly class [mscorlib]System.Reflection.Assembly::GetEntryAssembly()') + ilasm.call_method('string class [mscorlib]System.Reflection.Assembly::get_Location()', True) ilasm.call_method('void class [mscorlib]System.Collections.Generic.List`1::Add(!0)', True) # add real argv From antocuni at codespeak.net Tue Mar 13 15:47:18 2007 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Tue, 13 Mar 2007 15:47:18 +0100 (CET) Subject: [pypy-svn] r40441 - in pypy/dist/pypy: rpython rpython/test translator/cli translator/cli/src translator/cli/test Message-ID: <20070313144718.E0F25100A7@code0.codespeak.net> Author: antocuni Date: Tue Mar 13 15:47:17 2007 New Revision: 40441 Added: pypy/dist/pypy/translator/cli/src/ll_os_path.cs Modified: pypy/dist/pypy/rpython/extfuncregistry.py pypy/dist/pypy/rpython/test/test_rbuiltin.py pypy/dist/pypy/translator/cli/rte.py pypy/dist/pypy/translator/cli/test/test_builtin.py Log: We can't use the default os.path.join with ootype because we would get the version for the platform we did the translation on. Instead, rely on the backend doing the proper thing. Modified: pypy/dist/pypy/rpython/extfuncregistry.py ============================================================================== --- pypy/dist/pypy/rpython/extfuncregistry.py (original) +++ pypy/dist/pypy/rpython/extfuncregistry.py Tue Mar 13 15:47:17 2007 @@ -1,12 +1,12 @@ # this registry use the new interface for external functions # all the above declarations in extfunctable should be moved here at some point. -import math from extfunc import register_external # ___________________________ # math functions +import math from pypy.rpython.lltypesystem.module import ll_math from pypy.rpython.ootypesystem.module import ll_math as oo_math from pypy.rpython.module import ll_os @@ -49,3 +49,29 @@ register_external(func, args, res, 'll_math.ll_math_%s' % name, llfakeimpl=llfake, oofakeimpl=oofake, annotation_hook = hook) + +# ___________________________ +# os.path functions + +from pypy.tool.sourcetools import func_with_new_name +import os.path + +# os.path.join is RPython, but we don't want to compile it directly +# because it's platform dependant. This is ok for lltype where the +# execution platform is the same as the translation platform, but not +# for ootype where the executable produced by some backends (e.g. CLI, +# JVM) are expected to run everywhere. Thus, we register it as an +# external function, but we provide a clone for lltype using +# func_with_new_name. + +# XXX: I can't see any easy way to provide an oofakeimpl for the +# llinterpreter + +path_functions = [ + ('join', [str, str], str), + ] + +for name, args, res in path_functions: + func = getattr(os.path, name) + llimpl = func_with_new_name(func, name) + register_external(func, args, res, 'll_os_path.ll_%s' % name, llimpl=llimpl) Modified: pypy/dist/pypy/rpython/test/test_rbuiltin.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_rbuiltin.py (original) +++ pypy/dist/pypy/rpython/test/test_rbuiltin.py Tue Mar 13 15:47:17 2007 @@ -336,7 +336,14 @@ assert self.class_name(res) == 'A' res = self.interpret(f, [2]) assert self.class_name(res) == 'B' - + + def test_os_path_join(self): + self._skip_oo('os.path.join oofakeimpl') + import os.path + def fn(a, b): + return os.path.join(a, b) + res = self.ll_to_string(self.interpret(fn, ['a', 'b'])) + assert res == os.path.join('a', 'b') class TestLLtype(BaseTestRbuiltin, LLRtypeMixin): from pypy.rpython.lltypesystem.module import ll_os Modified: pypy/dist/pypy/translator/cli/rte.py ============================================================================== --- pypy/dist/pypy/translator/cli/rte.py (original) +++ pypy/dist/pypy/translator/cli/rte.py Tue Mar 13 15:47:17 2007 @@ -77,7 +77,7 @@ get_COMPILER = classmethod(get_COMPILER) class FrameworkDLL(Target): - SOURCES = ['pypylib.cs', 'll_os.cs', 'errno.cs', 'll_math.cs'] + SOURCES = ['pypylib.cs', 'll_os.cs', 'll_os_path.cs', 'errno.cs', 'll_math.cs'] OUTPUT = 'pypylib.dll' ALIAS = 'pypylib-framework.dll' FLAGS = ['/t:library', '/unsafe', '/r:main.exe'] Added: pypy/dist/pypy/translator/cli/src/ll_os_path.cs ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/cli/src/ll_os_path.cs Tue Mar 13 15:47:17 2007 @@ -0,0 +1,14 @@ +using System; +using System.IO; +using pypy.runtime; + +namespace pypy.builtin +{ + public class ll_os_path + { + public static string ll_join(string a, string b) + { + return Path.Combine(a, b); + } + } +} Modified: pypy/dist/pypy/translator/cli/test/test_builtin.py ============================================================================== --- pypy/dist/pypy/translator/cli/test/test_builtin.py (original) +++ pypy/dist/pypy/translator/cli/test/test_builtin.py Tue Mar 13 15:47:17 2007 @@ -124,3 +124,10 @@ # XXX: remember to test ll_os_readlink and ll_os_pipe as soon as # they are implemented + + def test_os_path_join(self): + import os.path + def fn(a, b): + return os.path.join(a, b) + res = self.ll_to_string(self.interpret(fn, ['a', 'b'])) + assert res == os.path.join('a', 'b') From arigo at codespeak.net Tue Mar 13 16:20:51 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 13 Mar 2007 16:20:51 +0100 (CET) Subject: [pypy-svn] r40444 - in pypy/branch/jit-virtual-world/pypy/jit/hintannotator: . test Message-ID: <20070313152051.B77C6100AF@code0.codespeak.net> Author: arigo Date: Tue Mar 13 16:20:46 2007 New Revision: 40444 Modified: pypy/branch/jit-virtual-world/pypy/jit/hintannotator/annotator.py pypy/branch/jit-virtual-world/pypy/jit/hintannotator/model.py pypy/branch/jit-virtual-world/pypy/jit/hintannotator/test/test_annotator.py Log: (pedronis, arigo) * deepfrozenlist[index] => return SomeLLAbstractConstant, which allows us to fix back through the getitem * support for indirect calls to a family of graphs, some of which are recursively followed and some of which are not. Modified: pypy/branch/jit-virtual-world/pypy/jit/hintannotator/annotator.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/hintannotator/annotator.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/hintannotator/annotator.py Tue Mar 13 16:20:46 2007 @@ -29,6 +29,23 @@ return True +class StopAtXPolicy(HintAnnotatorPolicy): + """Useful for tests.""" + + def __init__(self, *funcs): + HintAnnotatorPolicy.__init__(self, novirtualcontainer=True, + oopspec=True) + self.funcs = funcs + + def look_inside_graph(self, graph): + try: + if graph.func in self.funcs: + return False + except AttributeError: + pass + return True + + class HintAnnotator(RPythonAnnotator): def __init__(self, translator=None, base_translator=None, policy=None): 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 Tue Mar 13 16:20:46 2007 @@ -105,6 +105,16 @@ deps.append(v) +class PureCallOpOriginFlags(CallOpOriginFlags): + + def record_dependencies(self, greenorigindependencies, + callreturndependencies): + OriginFlags.record_dependencies(self, greenorigindependencies, + callreturndependencies) + CallOpOriginFlags.record_dependencies(self, greenorigindependencies, + callreturndependencies) + + class InputArgOriginFlags(OriginFlags): def __init__(self, bookkeeper, graph, i): @@ -623,11 +633,6 @@ # ____________________________________________________________ def handle_highlevel_operation(bookkeeper, ll_func, *args_hs): - if bookkeeper.annotator.policy.novirtualcontainer: - # "blue variables" disabled, we just return a red var all the time. - RESULT = bookkeeper.current_op_concretetype() - return variableoftype(RESULT) - # parse the oopspec and fill in the arguments operation_name, args = ll_func.oopspec.split('(', 1) assert args.endswith(')') @@ -644,6 +649,20 @@ args_hs.append(hs) # end of rather XXX'edly hackish parsing + if bookkeeper.annotator.policy.novirtualcontainer: + # "blue variables" disabled, we just return a red var all the time. + # Exception: an operation on a frozen container is constant-foldable. + RESULT = bookkeeper.current_op_concretetype() + if '.' in operation_name and args_hs[0].deepfrozen: + myorigin = bookkeeper.myorigin() + d = newset({myorigin: True}, *[hs_c.origins for hs_c in args_hs]) + return SomeLLAbstractConstant(RESULT, d, + eager_concrete = False, # probably + myorigin = myorigin) + else: + return variableoftype(RESULT) + + # --- the code below is not used any more except by test_annotator.py --- if operation_name == 'newlist': from pypy.jit.hintannotator.vlist import oop_newlist handler = oop_newlist @@ -669,21 +688,46 @@ # the policy prevents us from following the call if not graph_list: # no known target, give up return variableoftype(RESTYPE) + pure_call = True for graph in graph_list: if not bookkeeper.is_pure_graph(graph): # it's not calling pure graphs either, so the result # is entierely unknown - return variableoftype(RESTYPE) + pure_call = False + break # when calling pure graphs, consider the call as an operation. for hs in args_hs: if not isinstance(hs, SomeLLAbstractConstant): - return variableoftype(RESTYPE) - # if all arguments are SomeLLAbstractConstant, so can the result be. - origin = bookkeeper.myorigin() - d = newset({origin: True}, *[hs_c.origins for hs_c in args_hs]) - return SomeLLAbstractConstant(RESTYPE, d, - eager_concrete = False, # probably - myorigin = origin) + pure_call = False + break + if pure_call: + # if all arguments are SomeLLAbstractConstant, so can the result be. + myorigin = bookkeeper.myorigin() + d = newset({myorigin: True}, *[hs_c.origins for hs_c in args_hs]) + h_res = SomeLLAbstractConstant(RESTYPE, d, + eager_concrete = False, # probably + myorigin = myorigin) + fixed = myorigin.read_fixed() + else: + h_res = variableoftype(RESTYPE) + fixed = False + + look_inside_graph = bookkeeper.annotator.policy.look_inside_graph + followable_graphs = [graph for graph in graph_list + if look_inside_graph(graph)] + if followable_graphs: + # we can still follow this graph, even if we cannot follow all of them + tsgraphs_accum = [] + bookkeeper.graph_family_call(followable_graphs, fixed, args_hs[1:], + tsgraphs_accum) + myorigin = bookkeeper.myorigin() + myorigin.any_called_graph = tsgraphs_accum[0] + if pure_call: + myorigin.__class__ = PureCallOpOriginFlags # thud + else: + myorigin.__class__ = CallOpOriginFlags # thud + + return h_res # ____________________________________________________________ # 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 Tue Mar 13 16:20:46 2007 @@ -1,6 +1,7 @@ import py from pypy.translator.translator import TranslationContext, graphof from pypy.jit.hintannotator.annotator import HintAnnotator, HintAnnotatorPolicy +from pypy.jit.hintannotator.annotator import StopAtXPolicy from pypy.jit.hintannotator.bookkeeper import HintBookkeeper from pypy.jit.hintannotator.model import * from pypy.rpython.lltypesystem import lltype @@ -339,6 +340,16 @@ hs = hannotate(ll_function, [int, int], policy=P_OOPSPEC) assert isinstance(hs, SomeLLAbstractContainer) +def test_frozen_list(): + lst = [5, 7, 9] + def ll_function(x): + mylist = hint(lst, deepfreeze=True) + z = mylist[x] + hint(z, concrete=True) + return z + hs = hannotate(ll_function, [int], policy=P_OOPSPEC_NOVIRTUAL) + assert hs.is_green() + def test_simple_cast_pointer(): GCS1 = lltype.GcStruct('s1', ('x', lltype.Signed)) GCS2 = lltype.GcStruct('s2', ('sub', GCS1), ('y', lltype.Signed)) @@ -766,3 +777,80 @@ hs = hannotate(ll_function, [int, int], policy=P_NOVIRTUAL) assert not hs.is_green() + + +def test_indirect_sometimes_residual_pure_red_call(): + def h1(x): + return x-2 + def h2(x): + return x*4 + l = [h1, h2] + def f(n, x): + frozenl = hint(l, deepfreeze=True) + h = frozenl[n&1] + return h(x) + + P = StopAtXPolicy(h1) + P.oopspec = True + P.entrypoint_returns_red = False + hs, hannotator = hannotate(f, [int, int], policy=P, annotator=True) + assert not hs.is_green() + assert isinstance(hs, SomeLLAbstractConstant) + + tsgraph = graphof(hannotator.translator, h2) + hs = hannotator.binding(tsgraph.getargs()[0]) + assert not hs.is_green() + + +def test_indirect_sometimes_residual_red_call(): + class Stuff: + pass + stuff = Stuff() + def h1(x): + stuff.hello = 123 + return x-2 + def h2(x): + return x*4 + l = [h1, h2] + def f(n, x): + frozenl = hint(l, deepfreeze=True) + h = frozenl[n&1] + return h(x) + + P = StopAtXPolicy(h1) + P.entrypoint_returns_red = False + hs, hannotator = hannotate(f, [int, int], policy=P, annotator=True) + assert not hs.is_green() + + tsgraph = graphof(hannotator.translator, h2) + hs = hannotator.binding(tsgraph.getargs()[0]) + assert not hs.is_green() + + +def test_indirect_sometimes_residual_pure_but_fixed_red_call(): + def h1(x): + return x-2 + def h2(x): + return x*4 + l = [h1, h2] + def f(n, x): + frozenl = hint(l, deepfreeze=True) + h = frozenl[n&1] + z = h(x) + hint(z, concrete=True) + return z + + P = StopAtXPolicy(h1) + P.entrypoint_returns_red = False + hs, hannotator = hannotate(f, [int, int], policy=P, annotator=True) + assert hs.is_green() + + #tsgraph = graphof(hannotator.translator, h2) + #hs = hannotator.binding(tsgraph.getargs()[0]) + #assert hs.is_green() + + tsgraph = graphof(hannotator.translator, f) + hs = hannotator.binding(tsgraph.getargs()[0]) + assert hs.is_green() + hs = hannotator.binding(tsgraph.getargs()[1]) + assert hs.is_green() From guido at codespeak.net Tue Mar 13 16:40:11 2007 From: guido at codespeak.net (guido at codespeak.net) Date: Tue, 13 Mar 2007 16:40:11 +0100 (CET) Subject: [pypy-svn] r40446 - in pypy/branch/guido-buildtool-web/pypy/tool/build: . test web web/templates Message-ID: <20070313154011.9499F100AF@code0.codespeak.net> Author: guido Date: Tue Mar 13 16:40:10 2007 New Revision: 40446 Modified: 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/app.py pypy/branch/guido-buildtool-web/pypy/tool/build/web/templates/build.html pypy/branch/guido-buildtool-web/pypy/tool/build/web/templates/serverstatus.html Log: Removed log from the build page for now because it seems to make browsers barf ;), changed the return value of MetaServer.compile() from a tuple to a dict so it can contain more info a bit easier, removed some lost xmlns declaration from a template. 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 Tue Mar 13 16:40:10 2007 @@ -84,30 +84,36 @@ """ # store the request, if there's already a build available the # storage will return that path + requestid = request.id() for bp in self._done: if request.has_satisfying_data(bp.request): path = str(bp) self._channel.send('already a build for this info available') - return (True, path) + return {'path': path, 'id': requestid, 'isbuilding': True, + 'message': 'build is already available'} 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 on '%s'" % ( request, builder.hostname)) self._waiting.append(request) - return (False, "this build is already in progress on '%s'" % ( - builder.hostname, )) + return {'path': None, 'id': requestid, 'isbuilding': True, + 'message': "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 hostname = self.run(request) if hostname is not None: - return (False, "found a suitable server, going to build on '%s'" % - (hostname, )) + return {'path': None, 'id': requestid, 'isbuilding': True, + 'message': "found a suitable server, going to build " + "on '%s'" % (hostname, )} self._queuelock.acquire() try: self._queued.append(request) finally: self._queuelock.release() - return (False, 'no suitable build server found; your request is queued') + return {'path': None, 'id': requestid, 'isbuilding': False, + 'message': 'no suitable build server found; your request ' + 'is queued'} def run(self, request): """find a suitable build server and run the job if possible""" 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 Tue Mar 13 16:40:10 2007 @@ -54,9 +54,10 @@ br = build.BuildRequest('foo at bar.com', {'foo': 1}, {}, str(repodir), 'HEAD', 0) ret = svr.compile(br) - assert not ret[0] - assert ret[1].find('found a suitable server') > -1 - assert "fake" in ret[1] # hostname + assert not ret['path'] + assert ret['isbuilding'] + assert ret['message'].find('found a suitable server') > -1 + assert "fake" in ret['message'] # hostname ret = svr._channel.receive() assert ret.find('going to send compile job') > -1 acceptedmsg = svr._channel.receive() @@ -87,8 +88,9 @@ br4 = build.BuildRequest('foo at spam.com', {'foo': 1}, {}, str(repodir), 'HEAD', 0) ret = svr.compile(br4) - assert not ret[0] - assert ret[1].find('this build is already') > -1 + assert not ret['path'] + assert ret['message'].find('this build is already') > -1 + assert ret['isbuilding'] assert svr._channel.receive().find('currently in progress') > -1 c1.busy_on = None @@ -99,9 +101,10 @@ clone = build.BuildRequest.fromstring(bp.request.serialize()) clone.email = 'test at domain.com' ret = svr.compile(clone) - assert ret[0] - assert isinstance(ret[1], str) - assert build.BuildPath(ret[1]) == bp + assert ret['path'] + assert ret['isbuilding'] + assert isinstance(ret['path'], str) + assert build.BuildPath(ret['path']) == bp ret = svr._channel.receive() assert ret.find('compilation done for') > -1 for i in range(2): 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 Tue Mar 13 16:40:10 2007 @@ -146,6 +146,8 @@ '"%s"' % (self._buildid,)) log = info['log'] error = info['error'] + if error == 'None': + error = None if error: status = 'failed' else: Modified: pypy/branch/guido-buildtool-web/pypy/tool/build/web/templates/build.html ============================================================================== --- pypy/branch/guido-buildtool-web/pypy/tool/build/web/templates/build.html (original) +++ pypy/branch/guido-buildtool-web/pypy/tool/build/web/templates/build.html Tue Mar 13 16:40:10 2007 @@ -50,11 +50,13 @@ %(build_end_time)s
%(build_end_time)]c - %(log)[c +
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 Tue Mar 13 16:40:10 2007 @@ -1,4 +1,4 @@ - + Build meta server status page From arigo at codespeak.net Tue Mar 13 17:10:28 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 13 Mar 2007 17:10:28 +0100 (CET) Subject: [pypy-svn] r40450 - pypy/dist/pypy/lib/pyontology Message-ID: <20070313161028.268EF100A5@code0.codespeak.net> Author: arigo Date: Tue Mar 13 17:10:27 2007 New Revision: 40450 Modified: pypy/dist/pypy/lib/pyontology/pyontology.py Log: Use a relative import, to make it work in the various ways this package is imported. Modified: pypy/dist/pypy/lib/pyontology/pyontology.py ============================================================================== --- pypy/dist/pypy/lib/pyontology/pyontology.py (original) +++ pypy/dist/pypy/lib/pyontology/pyontology.py Tue Mar 13 17:10:27 2007 @@ -9,7 +9,7 @@ from logilab.constraint.fd import FiniteDomain as fd from logilab.constraint.propagation import AbstractDomain, AbstractConstraint,\ ConsistencyFailure -from pyontology.sparql_grammar import SPARQLGrammar as SP # name clash ? +from sparql_grammar import SPARQLGrammar as SP # name clash ? from constraint_classes import * Solver = MySolver Expression = MyExpression From arigo at codespeak.net Tue Mar 13 20:42:43 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 13 Mar 2007 20:42:43 +0100 (CET) Subject: [pypy-svn] r40452 - in pypy/branch/jit-virtual-world/pypy/jit: . hintannotator hintannotator/test timeshifter timeshifter/test Message-ID: <20070313194243.266C2100A4@code0.codespeak.net> Author: arigo Date: Tue Mar 13 20:42:39 2007 New Revision: 40452 Modified: pypy/branch/jit-virtual-world/pypy/jit/TODO.txt pypy/branch/jit-virtual-world/pypy/jit/hintannotator/annotator.py 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/rtimeshift.py pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_timeshift.py pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_vlist.py pypy/branch/jit-virtual-world/pypy/jit/timeshifter/transform.py Log: (pedronis, arigo) * a more elegant approach to indirect calls: make a ts stub for the functions that shouldn't be looked in. * timeshift support for green oopspec calls, done by having general support for green calls that can raise. Modified: pypy/branch/jit-virtual-world/pypy/jit/TODO.txt ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/TODO.txt (original) +++ pypy/branch/jit-virtual-world/pypy/jit/TODO.txt Tue Mar 13 20:42:39 2007 @@ -36,5 +36,5 @@ - share code between the machine code backends (MachineCodeBlock, possibly register allocation) -- more green vars in the hintannotator: for y=frozen_list[x] - and for y=hint(x, deepfreeze=True) if x is green +- more green vars in the hintannotator: for y=hint(x, deepfreeze=True) + if x is green Modified: pypy/branch/jit-virtual-world/pypy/jit/hintannotator/annotator.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/jit/hintannotator/annotator.py (original) +++ pypy/branch/jit-virtual-world/pypy/jit/hintannotator/annotator.py Tue Mar 13 20:42:39 2007 @@ -20,14 +20,6 @@ def look_inside_graph(self, graph): return True - def look_inside_graphs(self, graph_list): - if not graph_list: - return False # cannot follow indirect call with no known targets - for graph in graph_list: - if not self.look_inside_graph(graph): - return False - return True - class StopAtXPolicy(HintAnnotatorPolicy): """Useful for tests.""" 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 Tue Mar 13 20:42:39 2007 @@ -2,10 +2,12 @@ from pypy.tool.tls import tlsobject from pypy.tool.ansi_print import ansi_log from pypy.objspace.flow.model import copygraph, SpaceOperation, Constant +from pypy.objspace.flow.model import Variable, Block, Link, FunctionGraph from pypy.annotation import model as annmodel from pypy.rpython.lltypesystem import lltype, lloperation from pypy.tool.algo.unionfind import UnionFind from pypy.translator.backendopt import graphanalyze +from pypy.translator.unsimplify import copyvar TLS = tlsobject() @@ -42,7 +44,10 @@ return self._cache[key] except KeyError: bk = self.bookkeeper - graph = copygraph(self.origgraph) + if bk.annotator.policy.look_inside_graph(self.origgraph): + graph = copygraph(self.origgraph) + else: + graph = self.build_callback_graph(self.origgraph) graph.tag = 'timeshifted' try: etrafo = bk.annotator.exceptiontransformer @@ -58,6 +63,20 @@ log(str(graph)) return graph + def build_callback_graph(self, graph): + args_v = [copyvar(None, v) for v in graph.getargs()] + v_res = copyvar(None, graph.getreturnvar()) + rtyper = self.bookkeeper.annotator.base_translator.rtyper # fish + fnptr = rtyper.getcallable(graph) + v_ptr = Constant(fnptr, lltype.typeOf(fnptr)) + newstartblock = Block(args_v) + newstartblock.operations.append( + SpaceOperation('direct_call', [v_ptr] + args_v, v_res)) + newgraph = FunctionGraph(graph.name, newstartblock) + newgraph.getreturnvar().concretetype = v_res.concretetype + newstartblock.closeblock(Link([v_res], newgraph.returnblock)) + return newgraph + class TsGraphCallFamily: def __init__(self, tsgraph): 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 Tue Mar 13 20:42:39 2007 @@ -105,16 +105,6 @@ deps.append(v) -class PureCallOpOriginFlags(CallOpOriginFlags): - - def record_dependencies(self, greenorigindependencies, - callreturndependencies): - OriginFlags.record_dependencies(self, greenorigindependencies, - callreturndependencies) - CallOpOriginFlags.record_dependencies(self, greenorigindependencies, - callreturndependencies) - - class InputArgOriginFlags(OriginFlags): def __init__(self, bookkeeper, graph, i): @@ -351,14 +341,11 @@ args_hs = args_hs[:-1] assert hs_graph_list.is_constant() graph_list = hs_graph_list.const + if graph_list is None: + # cannot follow indirect calls to unknown targets + return variableoftype(hs_v1.concretetype.TO.RESULT) bookkeeper = getbookkeeper() - if not bookkeeper.annotator.policy.look_inside_graphs(graph_list): - # cannot follow - return cannot_follow_call(bookkeeper, graph_list, - (hs_v1,) + args_hs, - hs_v1.concretetype.TO.RESULT) - myorigin = bookkeeper.myorigin() myorigin.__class__ = CallOpOriginFlags # thud fixed = myorigin.read_fixed() @@ -418,7 +405,7 @@ if not hasattr(fnobj, 'graph'): raise NotImplementedError("XXX call to externals or primitives") if not bookkeeper.annotator.policy.look_inside_graph(fnobj.graph): - return cannot_follow_call(bookkeeper, [fnobj.graph], args_hs, + return cannot_follow_call(bookkeeper, fnobj.graph, args_hs, lltype.typeOf(fnobj).RESULT) # recursive call from the entry point to itself: ignore them and @@ -654,13 +641,17 @@ # Exception: an operation on a frozen container is constant-foldable. RESULT = bookkeeper.current_op_concretetype() if '.' in operation_name and args_hs[0].deepfrozen: - myorigin = bookkeeper.myorigin() - d = newset({myorigin: True}, *[hs_c.origins for hs_c in args_hs]) - return SomeLLAbstractConstant(RESULT, d, - eager_concrete = False, # probably - myorigin = myorigin) - else: - return variableoftype(RESULT) + for hs_v in args_hs: + if not isinstance(hs_v, SomeLLAbstractConstant): + break + else: + myorigin = bookkeeper.myorigin() + d = newset({myorigin: True}, *[hs_c.origins + for hs_c in args_hs]) + return SomeLLAbstractConstant(RESULT, d, + eager_concrete = False, # probably + myorigin = myorigin) + return variableoftype(RESULT) # --- the code below is not used any more except by test_annotator.py --- if operation_name == 'newlist': @@ -684,17 +675,9 @@ hs_result = handler(*args_hs) # which may raise NotImplementedError return hs_result -def cannot_follow_call(bookkeeper, graph_list, args_hs, RESTYPE): +def cannot_follow_call(bookkeeper, graph, args_hs, RESTYPE): # the policy prevents us from following the call - if not graph_list: # no known target, give up - return variableoftype(RESTYPE) - pure_call = True - for graph in graph_list: - if not bookkeeper.is_pure_graph(graph): - # it's not calling pure graphs either, so the result - # is entierely unknown - pure_call = False - break + pure_call = bookkeeper.is_pure_graph(graph) # when calling pure graphs, consider the call as an operation. for hs in args_hs: if not isinstance(hs, SomeLLAbstractConstant): @@ -707,26 +690,8 @@ h_res = SomeLLAbstractConstant(RESTYPE, d, eager_concrete = False, # probably myorigin = myorigin) - fixed = myorigin.read_fixed() else: h_res = variableoftype(RESTYPE) - fixed = False - - look_inside_graph = bookkeeper.annotator.policy.look_inside_graph - followable_graphs = [graph for graph in graph_list - if look_inside_graph(graph)] - if followable_graphs: - # we can still follow this graph, even if we cannot follow all of them - tsgraphs_accum = [] - bookkeeper.graph_family_call(followable_graphs, fixed, args_hs[1:], - tsgraphs_accum) - myorigin = bookkeeper.myorigin() - myorigin.any_called_graph = tsgraphs_accum[0] - if pure_call: - myorigin.__class__ = PureCallOpOriginFlags # thud - else: - myorigin.__class__ = CallOpOriginFlags # thud - return h_res # ____________________________________________________________ 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 Tue Mar 13 20:42:39 2007 @@ -818,6 +818,7 @@ return h(x) P = StopAtXPolicy(h1) + P.oopspec = True P.entrypoint_returns_red = False hs, hannotator = hannotate(f, [int, int], policy=P, annotator=True) assert not hs.is_green() @@ -841,6 +842,7 @@ return z P = StopAtXPolicy(h1) + P.oopspec = True P.entrypoint_returns_red = False hs, hannotator = hannotate(f, [int, int], policy=P, annotator=True) assert 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 Tue Mar 13 20:42:39 2007 @@ -1321,9 +1321,33 @@ for r_arg in hop.args_r: assert isinstance(r_arg, GreenRepr) assert isinstance(hop.r_result, GreenRepr) + + FUNC = hop.args_v[0].concretetype + calldesc = rtimeshift.CallDesc(self.RGenOp, FUNC.TO) + args_v = hop.args_v + args_s = [annmodel.lltype_to_annotation(v.concretetype) + for v in args_v] + s_result = annmodel.lltype_to_annotation(FUNC.TO.RESULT) + v_jitstate = hop.llops.getjitstate() + return hop.llops.genmixlevelhelpercall(calldesc.green_call, + [self.s_JITState] + args_s, + [v_jitstate ] + args_v, + s_result) + + def translate_op_green_call_noexc(self, hop): + for r_arg in hop.args_r: + assert isinstance(r_arg, GreenRepr) + assert isinstance(hop.r_result, GreenRepr) v = hop.genop('direct_call', hop.args_v, hop.r_result.lowleveltype) return v + def translate_op_green_indirect_call_noexc(self, hop): + for r_arg in hop.args_r[:-1]: + assert isinstance(r_arg, GreenRepr) + assert isinstance(hop.r_result, GreenRepr) + v = hop.genop('indirect_call', hop.args_v, hop.r_result.lowleveltype) + return v + def translate_op_red_call(self, hop): bk = self.annotator.bookkeeper v_jitstate = hop.llops.getjitstate() 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 Tue Mar 13 20:42:39 2007 @@ -500,6 +500,15 @@ self.result_kind = RGenOp.kindToken(FUNCTYPE.RESULT) # xxx what if the result is virtualizable? self.redboxbuilder = rvalue.ll_redboxbuilder(FUNCTYPE.RESULT) + whatever_return_value = FUNCTYPE.RESULT._defl() + def green_call(jitstate, fnptr, *args): + try: + result = fnptr(*args) + except Exception, e: + jitstate.residual_exception(e) + result = whatever_return_value + return result + self.green_call = green_call def _freeze_(self): return True @@ -532,6 +541,7 @@ else: gv_flags = builder.genop2("int_or", gv_flags, gv_flag) else: + assert gv_flags is None exceptiondesc.fetch_global_excdata(jitstate) if gv_flags is None: gv_flags = builder.rgenop.constPrebuiltGlobal(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 Tue Mar 13 20:42:39 2007 @@ -1,6 +1,7 @@ import py from pypy.translator.translator import TranslationContext, graphof from pypy.jit.hintannotator.annotator import HintAnnotator, HintAnnotatorPolicy +from pypy.jit.hintannotator.annotator import StopAtXPolicy from pypy.jit.hintannotator.bookkeeper import HintBookkeeper from pypy.jit.hintannotator.model import * from pypy.jit.timeshifter.hrtyper import HintRTyper, originalconcretetype @@ -348,21 +349,6 @@ assert count == expected_count -class StopAtXPolicy(HintAnnotatorPolicy): - def __init__(self, *funcs): - HintAnnotatorPolicy.__init__(self, novirtualcontainer=True, - oopspec=True) - self.funcs = funcs - - def look_inside_graph(self, graph): - try: - if graph.func in self.funcs: - return False - except AttributeError: - pass - return True - - class TestTimeshift(TimeshiftingTests): def test_simple_fixed(self): @@ -1466,22 +1452,47 @@ assert res == f(4,113) self.check_insns({'int_sub': 1}) - def test_indirect_sometimes_residual_red_call(self): - py.test.skip("in-progress") + def test_indirect_sometimes_residual_pure_red_call(self): def h1(x): return x-2 def h2(x): return x*4 l = [h1, h2] def f(n, x): + hint(None, global_merge_point=True) + hint(n, concrete=True) frozenl = hint(l, deepfreeze=True) h = frozenl[n&1] return h(x) P = StopAtXPolicy(h1) - res = self.timeshift(f, [7, 3], [0], policy=P) + P.oopspec = True + res = self.timeshift(f, [7, 3], [], policy=P) assert res == f(7,3) self.check_insns({'int_mul': 1}) - res = self.timeshift(f, [4, 113], [0], policy=P) + res = self.timeshift(f, [4, 113], [], policy=P) assert res == f(4,113) self.check_insns({'direct_call': 1}) + + def test_indirect_sometimes_residual_pure_but_fixed_red_call(self): + def h1(x): + return x-2 + def h2(x): + return x*4 + l = [h1, h2] + def f(n, x): + hint(None, global_merge_point=True) + frozenl = hint(l, deepfreeze=True) + h = frozenl[n&1] + z = h(x) + hint(z, concrete=True) + return z + + P = StopAtXPolicy(h1) + P.oopspec = True + res = self.timeshift(f, [7, 3], [], policy=P) + assert res == f(7,3) + self.check_insns({}) + res = self.timeshift(f, [4, 113], [], policy=P) + assert res == f(4,113) + 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 Tue Mar 13 20:42:39 2007 @@ -129,3 +129,30 @@ res = self.timeshift(ll_function, [3, 4], [0, 1], policy=P_OOPSPEC) assert res == 5 self.check_insns({}) + + def test_frozen_list(self): + lst = [5, 7, 9] + def ll_function(x): + mylist = hint(lst, deepfreeze=True) + z = mylist[x] + hint(z, concrete=True) + return z + + res = self.timeshift(ll_function, [1], policy=P_OOPSPEC) + assert res == 7 + self.check_insns({}) + + def test_frozen_list_indexerror(self): + lst = [5, 7, 9] + def ll_function(x): + mylist = hint(lst, deepfreeze=True) + try: + z = mylist[x] + except IndexError: + return -42 + hint(z, concrete=True) + return z + + res = self.timeshift(ll_function, [4], policy=P_OOPSPEC) + assert res == -42 + 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 Tue Mar 13 20:42:39 2007 @@ -492,11 +492,19 @@ args_v = spaceop.args[1:] elif spaceop.opname == 'indirect_call': graphs = spaceop.args[-1].value + if graphs is None: + return # cannot follow at all args_v = spaceop.args[1:-1] else: raise AssertionError(spaceop.opname) - if not self.hannotator.policy.look_inside_graphs(graphs): - return # cannot follow this call + # if the graph - or all the called graphs - are marked as "don't + # follow", directly return None as a special case. (This is only + # an optimization for the indirect_call case.) + for graph in graphs: + if self.hannotator.policy.look_inside_graph(graph): + break + else: + return for graph in graphs: tsgraph = self.timeshifted_graph_of(graph, args_v, spaceop.result) yield graph, tsgraph @@ -511,6 +519,10 @@ self.hannotator.policy.oopspec): if fnobj._callable.oopspec.startswith('vable.'): return 'vable', None + hs_result = self.hannotator.binding(spaceop.result) + if (hs_result.is_green() and + hs_result.concretetype is not lltype.Void): + return 'green', self.can_raise(spaceop) return 'oopspec', self.can_raise(spaceop) if self.hannotator.bookkeeper.is_green_call(spaceop): return 'green', None @@ -726,12 +738,20 @@ 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 + def handle_green_call(self, block, pos, withexc=False): + # an all-green function that we can just call op = block.operations[pos] - assert op.opname == 'direct_call' - op.opname = 'green_call' + if op.opname == 'indirect_call': + if withexc: + op.args.pop() # remove the graph list + op.opname = 'green_call' + else: + op.opname = 'green_indirect_call_noexc' + else: + if withexc: + op.opname = 'green_call' + else: + op.opname = 'green_call_noexc' def handle_yellow_call(self, block, pos, withexc): self.handle_red_call(block, pos, color='yellow', withexc=withexc) @@ -804,6 +824,8 @@ else: promoteblock = block v_flags2 = v_flags + # if there is no global merge point, this 'promote' will actually + # always see a constant red box v_finished_flag = self.genop(promoteblock, 'promote', [v_flags2], resulttype = lltype.Bool) self.go_to_dispatcher_if(promoteblock, v_finished_flag) From fijal at codespeak.net Tue Mar 13 21:25:05 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 13 Mar 2007 21:25:05 +0100 (CET) Subject: [pypy-svn] r40453 - pypy/dist/pypy/doc Message-ID: <20070313202505.D6F6E100A4@code0.codespeak.net> Author: fijal Date: Tue Mar 13 21:25:03 2007 New Revision: 40453 Modified: pypy/dist/pypy/doc/project-ideas.txt Log: Remove SoP info Modified: pypy/dist/pypy/doc/project-ideas.txt ============================================================================== --- pypy/dist/pypy/doc/project-ideas.txt (original) +++ pypy/dist/pypy/doc/project-ideas.txt Tue Mar 13 21:25:03 2007 @@ -8,11 +8,6 @@ yet and also do not require too much in depth knowledge to get started with. -If you are a student, maybe you will be inspired to make a proposal for our -`Summer of PyPy`_ campaign: you will have an experienced PyPy developer as a -mentor and be invited to attend one or two of our sprints, with travel and -accomodation costs refunded. - Feel free to suggest new ideas and discuss them in #pypy on the freenode IRC network or the pypy-dev mailing list (see the contact_ page). From fijal at codespeak.net Tue Mar 13 21:49:01 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 13 Mar 2007 21:49:01 +0100 (CET) Subject: [pypy-svn] r40454 - pypy/dist/pypy/doc Message-ID: <20070313204901.5A6FB100A6@code0.codespeak.net> Author: fijal Date: Tue Mar 13 21:48:59 2007 New Revision: 40454 Modified: pypy/dist/pypy/doc/project-ideas.txt Log: in-progress checkin. A bit of refactoring of project-ideas Modified: pypy/dist/pypy/doc/project-ideas.txt ============================================================================== --- pypy/dist/pypy/doc/project-ideas.txt (original) +++ pypy/dist/pypy/doc/project-ideas.txt Tue Mar 13 21:48:59 2007 @@ -39,39 +39,14 @@ * dictionaries which use a different strategy when very small. -* in-progress: caching the lookups of builtin names (by special forms of +* 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 @@ -84,18 +59,15 @@ * do benchmark runs to see how much speedup the currently written optimizations give - * profile pypy-c and its variants with these benchmarks, identify slow areas * try to come up with optimized implementations for these slow areas - - Start or improve a back-end --------------------------- -PyPy has complete, or nearly so, back-ends for C, LLVM and CLI/.NET and partial -backends for JavaScript, Common Lisp, Squeak and the JVM. It would be an +PyPy has complete, or nearly so, back-ends for C, LLVM, CLI/.NET and JVM and partial +backends for JavaScript, Common Lisp, Squeak. It would be an interesting project to improve either of these partial backends, or start one for another platform (Objective C comes to mind as one that should not be too terribly hard). @@ -114,14 +86,18 @@ * Improve the facilities for testing RPython intended to be translated to JavaScript on top of CPython, mostly by improving existing DOM interface. +* Write down the mochikit bindings (or any other interesting JS effects library), + including tests + +* Write down better object layer over DOM in RPython to make writing applications + easier + Improve one of the JIT back-ends -------------------------------- 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 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. +generation, one for PowerPC and the other for i386. Idea would be start a new backend +for ie. mobile device. Another idea in a similar vein would be to use LLVM to re-compile functions that are executed particularly frequently (LLVM cannot be used for *all* code From guido at codespeak.net Tue Mar 13 21:49:12 2007 From: guido at codespeak.net (guido at codespeak.net) Date: Tue, 13 Mar 2007 21:49:12 +0100 (CET) Subject: [pypy-svn] r40455 - in pypy/branch/guido-buildtool-web/pypy/tool/build/web: . templates theme Message-ID: <20070313204912.B0003100AD@code0.codespeak.net> Author: guido Date: Tue Mar 13 21:49:07 2007 New Revision: 40455 Modified: pypy/branch/guido-buildtool-web/pypy/tool/build/web/app.py pypy/branch/guido-buildtool-web/pypy/tool/build/web/templates/build.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/theme/style.css Log: Added some more info to the builds and build pages, added stylesheet to all pages. 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 Tue Mar 13 21:49:07 2007 @@ -165,8 +165,11 @@ 'request_time': format_time(br.request_time), 'build_start_time': format_time(br.build_start_time), 'build_end_time': format_time(br.build_end_time), + 'sysinfo': [{'key': k, 'value': v} for (k, v) in + sorted(br.sysinfo.items())], + 'compileinfo': [{'key': k, 'value': v} for (k, v) in + sorted(br.compileinfo.items())], 'status': status, - 'log': log, 'error': error, } @@ -188,9 +191,10 @@ 'email': b.email, 'svnurl': b.svnurl, 'svnrev': b.normalized_rev, - 'request_time': b.request_time, - 'build_start_time': b.build_start_time, - 'build_end_time': b.build_end_time} for b in buildrequests] + 'request_time': format_time(b.request_time), + 'build_start_time': format_time(b.build_start_time) or '-', + 'build_end_time': format_time(b.build_end_time) or '-'} + for b in buildrequests] class Builds(Collection): """ container for BuildsIndexPage and BuildPage """ @@ -217,7 +221,7 @@ """ the application root """ def __init__(self, config): self.style = FsFile(mypath.join('theme/style.css'), 'text/css') - self.serverstatus = ServerStatusPage(config) + self.index = ServerStatusPage(config) self.buildersinfo = BuildersInfoPage(config) self.builds = Builds(config) Modified: pypy/branch/guido-buildtool-web/pypy/tool/build/web/templates/build.html ============================================================================== --- pypy/branch/guido-buildtool-web/pypy/tool/build/web/templates/build.html (original) +++ pypy/branch/guido-buildtool-web/pypy/tool/build/web/templates/build.html Tue Mar 13 21:49:07 2007 @@ -1,6 +1,7 @@ Build meta server build %(id)s +
%(build_end_time)]c +
+
sysinfo:
+ %(sysinfo)[b +
+ %(key)s + %(value)s +
+ %(sysinfo)]b +
compileinfo:
+ %(compileinfo)[b +
+ %(key)s: + %(value)s +
+ %(compileinfo)]b metaserver Modified: pypy/dist/pypy/tool/build/web/templates/serverstatus.html ============================================================================== --- pypy/dist/pypy/tool/build/web/templates/serverstatus.html (original) +++ pypy/dist/pypy/tool/build/web/templates/serverstatus.html Wed Mar 14 12:10:09 2007 @@ -5,7 +5,7 @@ From mwh at codespeak.net Wed Mar 14 12:30:23 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Wed, 14 Mar 2007 12:30:23 +0100 (CET) Subject: [pypy-svn] r40473 - pypy/dist/pypy/jit/codegen/ppc Message-ID: <20070314113023.BB80410090@code0.codespeak.net> Author: mwh Date: Wed Mar 14 12:30:19 2007 New Revision: 40473 Modified: pypy/dist/pypy/jit/codegen/ppc/instruction.py Log: old changes from my wc that reduce rtyper warning spam from the jit's ppc backend. 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 Wed Mar 14 12:30:19 2007 @@ -6,6 +6,8 @@ rFP = r2 # the ABI doesn't specify a frame pointer. however, we want one class AllocationSlot(object): + offset = 0 + number = 0 def __init__(self): # The field alloc points to a singleton used by the register # allocator to detect conflicts. No two AllocationSlot @@ -127,6 +129,8 @@ _insn_index[0] += 1 def __repr__(self): return "<%s %d>" % (self.__class__.__name__, self._magic_index) + def emit(self, asm): + pass class Insn_GPR__GPR_GPR(Insn): def __init__(self, methptr, result, args): From cfbolz at codespeak.net Wed Mar 14 12:31:39 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 14 Mar 2007 12:31:39 +0100 (CET) Subject: [pypy-svn] r40474 - in pypy/dist/pypy/tool/build/web: . templates test Message-ID: <20070314113139.F0BB010090@code0.codespeak.net> Author: cfbolz Date: Wed Mar 14 12:31:37 2007 New Revision: 40474 Added: pypy/dist/pypy/tool/build/web/templates/metaserverstatus.html - copied, changed from r40472, pypy/dist/pypy/tool/build/web/templates/serverstatus.html Removed: pypy/dist/pypy/tool/build/web/templates/serverstatus.html Modified: pypy/dist/pypy/tool/build/web/app.py pypy/dist/pypy/tool/build/web/templates/build.html pypy/dist/pypy/tool/build/web/templates/buildersinfo.html pypy/dist/pypy/tool/build/web/templates/builds.html pypy/dist/pypy/tool/build/web/templates/index.html pypy/dist/pypy/tool/build/web/test/test_app.py Log: server -> meta server Modified: pypy/dist/pypy/tool/build/web/app.py ============================================================================== --- pypy/dist/pypy/tool/build/web/app.py (original) +++ pypy/dist/pypy/tool/build/web/app.py Wed Mar 14 12:31:37 2007 @@ -73,12 +73,12 @@ gw = py.execnet.SshGateway(self.config.server) return gw -class ServerStatusPage(ServerPage): +class MetaServerStatusPage(ServerPage): """ a page displaying overall meta server statistics """ def __call__(self, handler, path, query): template = templesser.template( - mypath.join('templates/serverstatus.html').read()) + mypath.join('templates/metaserverstatus.html').read()) return (get_headers(), fix_html(template.unicode(self.get_status()))) def get_status(self): @@ -221,7 +221,7 @@ """ the application root """ def __init__(self, config): self.style = FsFile(mypath.join('theme/style.css'), 'text/css') - self.index = self.serverstatus = ServerStatusPage(config) + self.index = self.metaserverstatus = MetaServerStatusPage(config) self.buildersinfo = BuildersInfoPage(config) self.builds = Builds(config) @@ -239,19 +239,19 @@ class MetaServerAccessor(object): def __init__(self, ms): - self.server = ms + self.metaserver = ms def status(self): - running = len([b for b in self.server._builders if b.busy_on]) - return {'builders': len(self.server._builders), + running = len([b for b in self.metaserver._builders if b.busy_on]) + return {'builders': len(self.metaserver._builders), 'running': running, - 'queued': len(self.server._queued), - 'waiting': len(self.server._waiting) + running, - 'done': len(self.server._done)} + 'queued': len(self.metaserver._queued), + 'waiting': len(self.metaserver._waiting) + running, + 'done': len(self.metaserver._done)} def buildersinfo(self): ret = [] - for b in self.server._builders: + for b in self.metaserver._builders: ret.append({ 'hostname': b.hostname, 'sysinfo': b.sysinfo, @@ -269,7 +269,7 @@ return r.serialize() def buildpathinfo(self, requestid): - for bp in self.server._done: + for bp in self.metaserver._done: if bp.request.id() == requestid: return { 'log': str(bp.log), @@ -277,14 +277,14 @@ } def buildurl(self, id): - for r in self.server._done: + for r in self.metaserver._done: if r.request.id() == id: - return self.server.config.path_to_url(r) + return self.metaserver.config.path_to_url(r) def _all_requests(self): - running = [b.busy_on for b in self.server._builders if b.busy_on] - done = [b.request for b in self.server._done] - return self.server._queued + self.server._waiting + running + done + running = [b.busy_on for b in self.metaserver._builders if b.busy_on] + done = [b.request for b in self.metaserver._done] + return self.metaserver._queued + self.metaserver._waiting + running + done if __name__ == '__main__': from pypy.tool.build.web.server import run_server Modified: pypy/dist/pypy/tool/build/web/templates/build.html ============================================================================== --- pypy/dist/pypy/tool/build/web/templates/build.html (original) +++ pypy/dist/pypy/tool/build/web/templates/build.html Wed Mar 14 12:31:37 2007 @@ -5,7 +5,7 @@ Modified: pypy/dist/pypy/tool/build/web/templates/buildersinfo.html ============================================================================== --- pypy/dist/pypy/tool/build/web/templates/buildersinfo.html (original) +++ pypy/dist/pypy/tool/build/web/templates/buildersinfo.html Wed Mar 14 12:31:37 2007 @@ -5,7 +5,7 @@ Modified: pypy/dist/pypy/tool/build/web/templates/builds.html ============================================================================== --- pypy/dist/pypy/tool/build/web/templates/builds.html (original) +++ pypy/dist/pypy/tool/build/web/templates/builds.html Wed Mar 14 12:31:37 2007 @@ -5,7 +5,7 @@ Modified: pypy/dist/pypy/tool/build/web/templates/index.html ============================================================================== --- pypy/dist/pypy/tool/build/web/templates/index.html (original) +++ pypy/dist/pypy/tool/build/web/templates/index.html Wed Mar 14 12:31:37 2007 @@ -5,7 +5,7 @@ Modified: pypy/dist/pypy/tool/build/web/test/test_app.py ============================================================================== --- pypy/dist/pypy/tool/build/web/test/test_app.py (original) +++ pypy/dist/pypy/tool/build/web/test/test_app.py Wed Mar 14 12:31:37 2007 @@ -77,9 +77,9 @@ assert html.strip().endswith('') html_validate(html) -class TestServerStatusPage(object): +class TestMetaServerStatusPage(object): def test_get_status(self): - p = ServerStatusPage(config, gateway) + p = MetaServerStatusPage(config, gateway) status = p.get_status() assert status == {'builders': 0, 'running': 0, @@ -99,8 +99,8 @@ 'waiting': 0} def test_call(self): - p = ServerStatusPage(config, gateway) - headers, html = p(None, '/serverstatus', '') + p = MetaServerStatusPage(config, gateway) + headers, html = p(None, '/metaserverstatus', '') assert headers['Content-Type'] == 'text/html; charset=UTF-8' assert html.strip().startswith('') From guido at codespeak.net Wed Mar 14 13:12:56 2007 From: guido at codespeak.net (guido at codespeak.net) Date: Wed, 14 Mar 2007 13:12:56 +0100 (CET) Subject: [pypy-svn] r40475 - in pypy/dist/pypy/tool/build: . web web/templates web/test web/theme Message-ID: <20070314121256.3C75010091@code0.codespeak.net> Author: guido Date: Wed Mar 14 13:12:53 2007 New Revision: 40475 Modified: pypy/dist/pypy/tool/build/config.py pypy/dist/pypy/tool/build/web/app.py pypy/dist/pypy/tool/build/web/templates/build.html pypy/dist/pypy/tool/build/web/templates/builds.html pypy/dist/pypy/tool/build/web/test/test_app.py pypy/dist/pypy/tool/build/web/theme/style.css Log: Displaying status in builds page, and made that the status both here and in the build page are coloured. To make this possible I refactored the code a bit so that information about builds and builtpaths are now sent in one server call, rather than having to ask for the build path information seperately. Modified: pypy/dist/pypy/tool/build/config.py ============================================================================== --- pypy/dist/pypy/tool/build/config.py (original) +++ pypy/dist/pypy/tool/build/config.py Wed Mar 14 13:12:53 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' webserver = '' port = 12321 testport = 32123 Modified: pypy/dist/pypy/tool/build/web/app.py ============================================================================== --- pypy/dist/pypy/tool/build/web/app.py (original) +++ pypy/dist/pypy/tool/build/web/app.py Wed Mar 14 13:12:53 2007 @@ -132,32 +132,12 @@ fix_html(template.unicode(self.get_info()))) def get_info(self): - br = BuildRequest.fromstring(self.call_method('buildrequest', - '"%s"' % ( - self._buildid,))) - buildurl = None - log = None - error = None - if br.build_start_time: - if br.build_end_time: - buildurl = self.call_method('buildurl', - '"%s"' % (self._buildid,)) - info = self.call_method('buildpathinfo', - '"%s"' % (self._buildid,)) - log = info['log'] - error = info['error'] - if error == 'None': - error = None - if error: - status = 'failed' - else: - status = 'done' - else: - status = 'in progress' - else: - status = 'waiting' + bpinfo, brstr = self.call_method('buildrequest', '"%s"' % (self._buildid,)) + br = BuildRequest.fromstring(brstr) + if bpinfo == None: + bpinfo = {} return { - 'url': buildurl, + 'url': bpinfo['buildurl'], 'id': br.id(), 'email': br.email, 'svnurl': br.svnurl, @@ -169,8 +149,9 @@ sorted(br.sysinfo.items())], 'compileinfo': [{'key': k, 'value': v} for (k, v) in sorted(br.compileinfo.items())], - 'status': status, - 'error': error, + 'status': bpinfo['status'], + 'statusclass': bpinfo['status'].replace(' ', '_'), + 'error': bpinfo['error'], } class BuildsIndexPage(ServerPage): @@ -183,9 +164,9 @@ fix_html(template.unicode({'builds': self.get_builds()}))) def get_builds(self): - buildrequests = [BuildRequest.fromstring(b) for b in + data = [(i, BuildRequest.fromstring(b)) for(i, b) in self.call_method('buildrequests')] - buildrequests.sort(lambda a, b: cmp(a.request_time, b.request_time)) + data.sort(lambda a, b: cmp(b[1].request_time, a[1].request_time)) return [{'id': b.id(), 'href': '/builds/%s' % (b.id(),), 'email': b.email, @@ -193,8 +174,11 @@ 'svnrev': b.normalized_rev, 'request_time': format_time(b.request_time), 'build_start_time': format_time(b.build_start_time) or '-', - 'build_end_time': format_time(b.build_end_time) or '-'} - for b in buildrequests] + 'build_end_time': format_time(b.build_end_time) or '-', + 'status': i['status'], + 'statusclass': i['status'].replace(' ', '_'), + 'error': i.get('error', '')} + for (i, b) in data] class Builds(Collection): """ container for BuildsIndexPage and BuildPage """ @@ -260,20 +244,22 @@ return ret def buildrequests(self): - ret = [b.serialize() for b in self._all_requests()] + ret = [(self._getinfo(b), b.serialize()) for b in + self._all_requests()] return ret def buildrequest(self, id): for r in self._all_requests(): if r.id() == id: - return r.serialize() + return (self._getinfo(r), r.serialize()) def buildpathinfo(self, requestid): for bp in self.metaserver._done: if bp.request.id() == requestid: return { - 'log': str(bp.log), + #'log': str(bp.log), 'error': str(bp.error), + 'buildurl': self.metaserver.config.path_to_url(bp), } def buildurl(self, id): @@ -286,6 +272,19 @@ done = [b.request for b in self.metaserver._done] return self.metaserver._queued + self.metaserver._waiting + running + done + def _getinfo(self, br): + status = 'waiting' + info = self.buildpathinfo(br.id()) or {} + if br.build_end_time: + if info['error'] and info['error'] != 'None': + status = 'failed' + else: + status = 'done' + elif br.build_start_time: + status = 'in progress' + info.update({'status': status}) + return info + if __name__ == '__main__': from pypy.tool.build.web.server import run_server run_server(('', 8080), AppHandler) Modified: pypy/dist/pypy/tool/build/web/templates/build.html ============================================================================== --- pypy/dist/pypy/tool/build/web/templates/build.html (original) +++ pypy/dist/pypy/tool/build/web/templates/build.html Wed Mar 14 13:12:53 2007 @@ -19,7 +19,7 @@ %(url)]c
status: - %(status)s + %(status)s
%(error)[c
Modified: pypy/dist/pypy/tool/build/web/templates/builds.html ============================================================================== --- pypy/dist/pypy/tool/build/web/templates/builds.html (original) +++ pypy/dist/pypy/tool/build/web/templates/builds.html Wed Mar 14 13:12:53 2007 @@ -22,6 +22,7 @@ requested started ended + status @@ -31,6 +32,7 @@ %(request_time)s %(build_start_time)s %(build_end_time)s + %(status)s %(builds)]b Modified: pypy/dist/pypy/tool/build/web/test/test_app.py ============================================================================== --- pypy/dist/pypy/tool/build/web/test/test_app.py (original) +++ pypy/dist/pypy/tool/build/web/test/test_app.py Wed Mar 14 13:12:53 2007 @@ -222,7 +222,8 @@ def test_buildrequests(self): temppath = py.test.ensuretemp( 'TestMetaServerAccessor.test_buildersinfo') - config = fake.Container(projectname='test', buildpath=temppath) + config = fake.Container(projectname='test', buildpath=temppath, + path_to_url=lambda p: 'file:///foo') svr = metaserver.MetaServer(config, fake.FakeChannel()) s = MetaServerAccessor(svr) req = build.BuildRequest('foo at bar.com', {'foo': 'bar'}, {}, @@ -231,13 +232,18 @@ svr._queued.append(req) brs = s.buildrequests() assert len(brs) == 1 - assert brs[0] == req.serialize() + assert brs[0][0] == {'status': 'waiting'} + assert brs[0][1] == req.serialize() svr._queued = [] assert len(s.buildrequests()) == 0 - svr._done.append(fake.Container(request=req)) + req.build_start_time = py.std.time.time() + req.build_end_time = py.std.time.time() + svr._done.append(fake.Container(request=req, error=None)) brs = s.buildrequests() assert len(brs) == 1 - assert brs[0] == req.serialize() + assert brs[0][0] == {'status': 'done', 'error': 'None', + 'buildurl': 'file:///foo'} + assert brs[0][1] == req.serialize() def test_buildrequest(self): temppath = py.test.ensuretemp( @@ -250,7 +256,8 @@ req._nr = '10' svr._queued.append(req) br = s.buildrequest(req.id()) - assert br == req.serialize() + assert br[0] == {'status': 'waiting'} + assert br[1] == req.serialize() def test_buildurl(self): temppath = py.test.ensuretemp( Modified: pypy/dist/pypy/tool/build/web/theme/style.css ============================================================================== --- pypy/dist/pypy/tool/build/web/theme/style.css (original) +++ pypy/dist/pypy/tool/build/web/theme/style.css Wed Mar 14 13:12:53 2007 @@ -25,3 +25,19 @@ text-align: center; } +.failed { + color: red; +} + +.done { + color: blue; +} + +.in_progress { + color: green; +} + +.waiting { + color: yellow; +} + From guido at codespeak.net Wed Mar 14 13:17:25 2007 From: guido at codespeak.net (guido at codespeak.net) Date: Wed, 14 Mar 2007 13:17:25 +0100 (CET) Subject: [pypy-svn] r40476 - pypy/dist/pypy/tool/build Message-ID: <20070314121725.5C74510091@code0.codespeak.net> Author: guido Date: Wed Mar 14 13:17:23 2007 New Revision: 40476 Modified: pypy/dist/pypy/tool/build/config.py Log: oops :( (thanks cf!) Modified: pypy/dist/pypy/tool/build/config.py ============================================================================== --- pypy/dist/pypy/tool/build/config.py (original) +++ pypy/dist/pypy/tool/build/config.py Wed Mar 14 13:17:23 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' webserver = '' port = 12321 testport = 32123 From arigo at codespeak.net Wed Mar 14 13:50:37 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 14 Mar 2007 13:50:37 +0100 (CET) Subject: [pypy-svn] r40479 - in pypy/branch/jit-virtual-world/pypy/translator: . backendopt Message-ID: <20070314125037.2B6AA10091@code0.codespeak.net> Author: arigo Date: Wed Mar 14 13:50:31 2007 New Revision: 40479 Modified: pypy/branch/jit-virtual-world/pypy/translator/backendopt/support.py pypy/branch/jit-virtual-world/pypy/translator/transform.py Log: (arre, pedronis, arigo) Fix a bug in the call graph generation (the dict couldn't represent a function that contains several calls to another). Modified: pypy/branch/jit-virtual-world/pypy/translator/backendopt/support.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/translator/backendopt/support.py (original) +++ pypy/branch/jit-virtual-world/pypy/translator/backendopt/support.py Wed Mar 14 13:50:31 2007 @@ -105,24 +105,20 @@ afterblock.operations[pos:pos] = generate_keepalive(keep_alive_vars) return splitlink -def calculate_call_graph(translator): - calls = {} - for graph in translator.graphs: - if getattr(getattr(graph, "func", None), "suggested_primitive", False): - continue - calls[graph] = {} - for block in graph.iterblocks(): - for op in block.operations: - if op.opname == "direct_call": - called_graph = get_graph(op.args[0], translator) - if called_graph is not None: - calls[graph][called_graph] = block - if op.opname == "indirect_call": - graphs = op.args[-1].value - if graphs is not None: - for called_graph in graphs: - calls[graph][called_graph] = block - return calls +def find_calls_from(translator, graph): + if getattr(getattr(graph, "func", None), "suggested_primitive", False): + return + for block in graph.iterblocks(): + for op in block.operations: + if op.opname == "direct_call": + called_graph = get_graph(op.args[0], translator) + if called_graph is not None: + yield block, called_graph + if op.opname == "indirect_call": + graphs = op.args[-1].value + if graphs is not None: + for called_graph in graphs: + yield block, called_graph def find_backedges(graph, block=None, seen=None, seeing=None): """finds the backedges in the flow graph""" Modified: pypy/branch/jit-virtual-world/pypy/translator/transform.py ============================================================================== --- pypy/branch/jit-virtual-world/pypy/translator/transform.py (original) +++ pypy/branch/jit-virtual-world/pypy/translator/transform.py Wed Mar 14 13:50:31 2007 @@ -180,7 +180,7 @@ caller_block.operations.insert(0, unwind_op) def insert_ll_stackcheck(translator): - from pypy.translator.backendopt.support import calculate_call_graph + from pypy.translator.backendopt.support import find_calls_from from pypy.rpython.module.ll_stack import ll_stack_check from pypy.tool.algo.graphlib import Edge, make_edge_dict, break_cycles rtyper = translator.rtyper @@ -188,12 +188,11 @@ rtyper.specialize_more_blocks() stack_check_ptr = rtyper.getcallable(graph) stack_check_ptr_const = Constant(stack_check_ptr, lltype.typeOf(stack_check_ptr)) - call_graph = calculate_call_graph(translator) edges = [] graphs_to_patch = {} insert_in = {} - for caller, all_callees in call_graph.iteritems(): - for callee, block in all_callees.iteritems(): + for caller in translator.graphs: + for block, callee in find_calls_from(translator, caller): if getattr(getattr(callee, 'func', None), 'insert_stack_check_here', False): insert_in[callee.startblock] = True From arigo at codespeak.net Wed Mar 14 13:51:19 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 14 Mar 2007 13:51:19 +0100 (CET) Subject: [pypy-svn] r40480 - pypy/branch/jit-virtual-world/pypy/jit/goal Message-ID: <20070314125119.BA1EA10091@code0.codespeak.net> Author: arigo Date: Wed Mar 14 13:51:18 2007 New Revision: 40480 Modified: pypy/branch/jit-virtual-world/pypy/jit/goal/jitstep.py pypy/branch/jit-virtual-world/pypy/jit/goal/targetjit.py Log: (arre, pedronis, arigo) Heuristics for now to timeshift all graphs leading to add__Int_Int. Crashes ATM on missing 'int_add_ovf' support in the front- and back-end. 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 Mar 14 13:51:18 2007 @@ -1,3 +1,4 @@ +import types from pypy.module.pypyjit.interp_jit import PORTAL from pypy.objspace.flow.model import checkgraph @@ -10,7 +11,14 @@ class PyPyHintAnnotatorPolicy(HintAnnotatorPolicy): + def __init__(self, timeshift_graphs): + HintAnnotatorPolicy.__init__(self, novirtualcontainer = True, + oopspec = True) + self.timeshift_graphs = timeshift_graphs + def look_inside_graph(self, graph): + if graph in self.timeshift_graphs: + return True try: func = graph.func except AttributeError: @@ -26,20 +34,109 @@ return True forbidden_modules = {'pypy.interpreter.gateway': True, - 'pypy.interpreter.baseobjspace': True, + #'pypy.interpreter.baseobjspace': True, 'pypy.interpreter.typedef': True, 'pypy.interpreter.eval': True, 'pypy.interpreter.function': True, 'pypy.interpreter.pytraceback': True, } -POLICY = PyPyHintAnnotatorPolicy(novirtualcontainer = True, - oopspec = True) +def enumerate_reachable_graphs(translator, startgraph): + from pypy.translator.backendopt.support import find_calls_from + pending = [(startgraph, None)] + yield pending[0] + seen = {startgraph: True} + while pending: + yield None # hack: a separator meaning "length increases now" + nextlengthlist = [] + nextseen = {} + for node in pending: + head, tail = node + for block, callee in find_calls_from(translator, head): + if callee not in seen: + newnode = callee, node + yield newnode + nextlengthlist.append(newnode) + nextseen[callee] = True + pending = nextlengthlist + seen.update(nextseen) + yield None + +def graphs_on_the_path_to(translator, startgraph, targetgraphs): + targetgraphs = targetgraphs.copy() + result = {} + found = {} + for node in enumerate_reachable_graphs(translator, startgraph): + if node is None: # hack: a separator meaning "length increases now" + for graph in found: + del targetgraphs[graph] + found.clear() + if not targetgraphs: + return result + elif node[0] in targetgraphs: + found[node[0]] = True + while node is not None: + head, tail = node + result[head] = True + node = tail + raise Exception("did not reach all targets:\nmissing %r" % ( + targetgraphs.keys(),)) + + +def timeshift_graphs(t, portal_graph): + result_graphs = {} + + def _graph(func): + func = getattr(func, 'im_func', func) + return graphof(t, func) + + def seefunc(fromfunc, *tofuncs): + targetgraphs = {} + for tofunc in tofuncs: + targetgraphs[_graph(tofunc)] = True + graphs = graphs_on_the_path_to(t, _graph(fromfunc), targetgraphs) + result_graphs.update(graphs) + + def seepath(*path): + for i in range(1, len(path)): + seefunc(path[i-1], path[i]) + + # -------------------- + import pypy + seepath(pypy.interpreter.pyframe.PyFrame.BINARY_ADD, + pypy.objspace.descroperation.DescrOperation.add, + pypy.objspace.std.intobject.add__Int_Int, + pypy.objspace.std.inttype.wrapint, + pypy.objspace.std.intobject.W_IntObject.__init__) + seepath(pypy.objspace.descroperation._invoke_binop, + pypy.objspace.descroperation._check_notimplemented) + seepath(pypy.objspace.descroperation.DescrOperation.add, + pypy.objspace.std.Space.type) + #seepath(pypy.objspace.descroperation.DescrOperation.xxx, + # pypy.objspace.std.typeobject.W_TypeObject.lookup, + # pypy.objspace.std.typeobject.W_TypeObject.getdictvalue_w) + seepath(pypy.objspace.descroperation.DescrOperation.add, + pypy.objspace.std.typeobject.W_TypeObject.lookup_where, + pypy.objspace.std.typeobject.W_TypeObject.getdictvalue_w) + # -------------------- + + return result_graphs + def hintannotate(drv): t = drv.translator portal_graph = graphof(t, PORTAL) - + + POLICY = PyPyHintAnnotatorPolicy(timeshift_graphs(t, portal_graph)) + + graphnames = [str(_g) for _g in POLICY.timeshift_graphs] + graphnames.sort() + print '-' * 20 + for graphname in graphnames: + print graphname + print '-' * 20 + import pdb; pdb.set_trace() + hannotator = HintAnnotator(base_translator=t, policy=POLICY) hs = hannotator.build_types(portal_graph, [SomeLLAbstractConstant(v.concretetype, 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 Mar 14 13:51:18 2007 @@ -46,10 +46,12 @@ return super(PyPyJITTarget, self).target(driver, args) def handle_config(self, config): + super(PyPyJITTarget, self).handle_config(config) config.translation.fork_before = 'hintannotate' config.translation.backendopt.inline_threshold = 20.1 def handle_translate_config(self, translateconfig): + super(PyPyJITTarget, self).handle_translate_config(translateconfig) translateconfig.goals = ['timeshift'] From guido at codespeak.net Wed Mar 14 14:46:59 2007 From: guido at codespeak.net (guido at codespeak.net) Date: Wed, 14 Mar 2007 14:46:59 +0100 (CET) Subject: [pypy-svn] r40481 - in pypy/dist/pypy/tool/build: . test web web/test web/theme Message-ID: <20070314134659.AC44410091@code0.codespeak.net> Author: guido Date: Wed Mar 14 14:46:55 2007 New Revision: 40481 Modified: pypy/dist/pypy/tool/build/metaserver.py pypy/dist/pypy/tool/build/test/test_pypybuilder.py pypy/dist/pypy/tool/build/web/app.py pypy/dist/pypy/tool/build/web/test/test_app.py pypy/dist/pypy/tool/build/web/theme/style.css Log: Updated functional test, changed status colours, made that the connection to the server is now persistent, re-connecting on failures, removed unused stub. Modified: pypy/dist/pypy/tool/build/metaserver.py ============================================================================== --- pypy/dist/pypy/tool/build/metaserver.py (original) +++ pypy/dist/pypy/tool/build/metaserver.py Wed Mar 14 14:46:55 2007 @@ -25,9 +25,6 @@ return False return True -def make_id(build): - """ generate a unique, but predictable id for a build """ - class MetaServer(object): """ the build meta-server 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 Wed Mar 14 14:46:55 2007 @@ -139,9 +139,9 @@ # then we request a compilation for sysinfo foo=1, obviously this can not # be fulfilled yet - ispath, data = compile(foo=1) - assert not ispath - assert 'no suitable build server' in data + data = compile(foo=1) + assert not data.get('path') + assert 'no suitable build server' in data['message'] queued = get_info('_queued') assert len(queued) == 1 @@ -157,9 +157,9 @@ # 4 * SLEEP_INTERVAL seconds to fake the compilation... here we should # (if all is well) still be compiling - ispath, data = compile(foo=1) - assert not ispath - assert 'in progress' in data + data = compile(foo=1) + assert not data.get('path') + assert 'in progress' in data['message'] waiting = get_info('_waiting') assert len(waiting) == 1 @@ -177,8 +177,8 @@ # now a new request for the same build should return in a path being # returned - ispath, data = compile(foo=1) - assert ispath + data = compile(foo=1) + assert data['path'] queued = get_info('_queued') assert len(queued) == 0 Modified: pypy/dist/pypy/tool/build/web/app.py ============================================================================== --- pypy/dist/pypy/tool/build/web/app.py (original) +++ pypy/dist/pypy/tool/build/web/app.py Wed Mar 14 14:46:55 2007 @@ -34,6 +34,7 @@ """ base class for pages that communicate with the server """ exposed = True + _channel_holder = [] def __init__(self, config, gateway=None): self.config = config @@ -45,27 +46,49 @@ from pypy.tool.build import metaserver_instance from pypy.tool.build.web.app import MetaServerAccessor - ret = MetaServerAccessor(metaserver_instance).%s(%s) - channel.send(ret) + msi = MetaServerAccessor(metaserver_instance) + while 1: + try: + methodname, args = channel.receive() + ret = getattr(msi, methodname)(*args) + channel.send(ret) + except IOError: # XXX anything else? + break channel.close() """ - def call_method(self, methodname, args=''): + 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() + performed = False + if self._channel_holder: + channel = self._channel_holder[0] + try: + channel.send((methodname, args)) + ret = channel.receive() + except: + exc, e, tb = py.std.sys.exc_info() + del tb + print ('exception occurred when calling %s(%s): ' + '%s - %s' % (methodname, args, exc, e)) + else: + performed = True + if not performed: + conference = execnetconference.conference(self.gateway, + self.config.port, False) + channel = conference.remote_exec(self.remote_code % ( + self.config.path,)) + channel.send((methodname, args)) + ret = channel.receive() + while self._channel_holder: + self._channel_holder.pop() + self._channel_holder.append(channel) return ret - + def init_gateway(self): if self.config.server in ['localhost', '127.0.0.1']: gw = py.execnet.PopenGateway() @@ -132,7 +155,7 @@ fix_html(template.unicode(self.get_info()))) def get_info(self): - bpinfo, brstr = self.call_method('buildrequest', '"%s"' % (self._buildid,)) + bpinfo, brstr = self.call_method('buildrequest', (self._buildid,)) br = BuildRequest.fromstring(brstr) if bpinfo == None: bpinfo = {} Modified: pypy/dist/pypy/tool/build/web/test/test_app.py ============================================================================== --- pypy/dist/pypy/tool/build/web/test/test_app.py (original) +++ pypy/dist/pypy/tool/build/web/test/test_app.py Wed Mar 14 14:46:55 2007 @@ -273,3 +273,26 @@ url = s.buildurl(req.id()) assert url == 'http://foo/bar' +class TestServerPage(object): + def test_call_method_simple(self): + p = ServerPage(fake.Container(port=build_config.testport, path=str(path)), + py.execnet.PopenGateway()) + ret = p.call_method('status', []) + assert ret + + def test_call_method_reconnect(self): + p = ServerPage(fake.Container(port=build_config.testport, path=str(path)), + py.execnet.PopenGateway()) + ret = p.call_method('status', []) + assert len(p._channel_holder) == 1 + channel = p._channel_holder[0] + + ret = p.call_method('status', []) + assert len(p._channel_holder) == 1 + assert p._channel_holder[0] is channel + channel.close() + + ret = p.call_method('status', []) + assert len(p._channel_holder) == 1 + assert p._channel_holder is not channel + Modified: pypy/dist/pypy/tool/build/web/theme/style.css ============================================================================== --- pypy/dist/pypy/tool/build/web/theme/style.css (original) +++ pypy/dist/pypy/tool/build/web/theme/style.css Wed Mar 14 14:46:55 2007 @@ -30,14 +30,14 @@ } .done { - color: blue; + color: green; } .in_progress { - color: green; + color: yellow; } .waiting { - color: yellow; + color: orange; } From guido at codespeak.net Wed Mar 14 14:49:57 2007 From: guido at codespeak.net (guido at codespeak.net) Date: Wed, 14 Mar 2007 14:49:57 +0100 (CET) Subject: [pypy-svn] r40482 - pypy/dist/pypy/tool/build Message-ID: <20070314134957.84B1110091@code0.codespeak.net> Author: guido Date: Wed Mar 14 14:49:51 2007 New Revision: 40482 Modified: pypy/dist/pypy/tool/build/config.py Log: Links now point directly to the zip. Modified: pypy/dist/pypy/tool/build/config.py ============================================================================== --- pypy/dist/pypy/tool/build/config.py (original) +++ pypy/dist/pypy/tool/build/config.py Wed Mar 14 14:49:51 2007 @@ -58,6 +58,6 @@ # create an URL from a path, the URL is used in emails def path_to_url(p): - return 'http://codespeak.net/pypy/%s' % ( + return 'http://codespeak.net/pypy/%s/data.zip' % ( p.relto(py.magic.autopath().dirpath()),) From arigo at codespeak.net Wed Mar 14 14:56:02 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 14 Mar 2007 14:56:02 +0100 (CET) Subject: [pypy-svn] r40483 - pypy/dist/pypy/doc Message-ID: <20070314135602.DEAA310091@code0.codespeak.net> Author: arigo Date: Wed Mar 14 14:55:54 2007 New Revision: 40483 Modified: pypy/dist/pypy/doc/faq.txt Log: Add a FAQ entry: can PyPy compile Python? Modified: pypy/dist/pypy/doc/faq.txt ============================================================================== --- pypy/dist/pypy/doc/faq.txt (original) +++ pypy/dist/pypy/doc/faq.txt Wed Mar 14 14:55:54 2007 @@ -215,6 +215,27 @@ PyPy translation tool chain ======================================================================== +---------------------------------------- +Can PyPy compile normal Python programs? +---------------------------------------- + +No, PyPy is not a Python compiler. + +In Python, it is mostly impossible to *prove* anything about the types +that a program will manipulate by doing a static analysis. It should be +clear if you are familiar with Python, but if in doubt see [BRETT]_. + +What could be attempted is static "soft typing", where you would use a +whole bunch of heuristics to guess what types are probably going to show +up where. In this way, you could compile the program into two copies of +itself: a "fast" version and a "slow" version. The former would contain +many guards that allow it to fall back to the latter if needed. That +would be a wholly different project than PyPy, though. + +.. [BRETT] Brett Cannon, + Localized Type Inference of Atomic Types in Python, + http://www.ocf.berkeley.edu/~bac/thesis.pdf + ------------------------------ What is this RPython language? ------------------------------ From arigo at codespeak.net Wed Mar 14 15:00:36 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 14 Mar 2007 15:00:36 +0100 (CET) Subject: [pypy-svn] r40484 - pypy/dist/pypy/doc Message-ID: <20070314140036.BAE991009F@code0.codespeak.net> Author: arigo Date: Wed Mar 14 15:00:31 2007 New Revision: 40484 Modified: pypy/dist/pypy/doc/jit.txt Log: A better title. Modified: pypy/dist/pypy/doc/jit.txt ============================================================================== --- pypy/dist/pypy/doc/jit.txt (original) +++ pypy/dist/pypy/doc/jit.txt Wed Mar 14 15:00:31 2007 @@ -1,5 +1,5 @@ ======================================================================== - JIT Compilers in PyPy + JIT Generation in PyPy ======================================================================== .. contents:: From antocuni at codespeak.net Wed Mar 14 15:23:15 2007 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Wed, 14 Mar 2007 15:23:15 +0100 (CET) Subject: [pypy-svn] r40485 - in pypy/dist/pypy: rpython/test translator/cli translator/cli/test Message-ID: <20070314142315.4990C100A0@code0.codespeak.net> Author: antocuni Date: Wed Mar 14 15:23:12 2007 New Revision: 40485 Modified: pypy/dist/pypy/rpython/test/test_rint.py pypy/dist/pypy/translator/cli/opcodes.py pypy/dist/pypy/translator/cli/test/runtest.py Log: implement cast_longlong_to_float for cli and fix the tests 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 Wed Mar 14 15:23:12 2007 @@ -166,7 +166,7 @@ assert res == 100000000. res = self.interpret(f, [r_longlong(1234567890123456789)]) assert type(res) is float - assert res == 1.2345678901234568e+18 + assert self.float_eq(res, 1.2345678901234568e+18) def test_float_conversion_implicit(self): def f(ii): @@ -176,7 +176,7 @@ assert res == 100000001. res = self.interpret(f, [r_longlong(1234567890123456789)]) assert type(res) is float - assert res == 1.2345678901234568e+18 + assert self.float_eq(res, 1.2345678901234568e+18) def test_rarithmetic(self): inttypes = [int, r_uint, r_longlong, r_ulonglong] Modified: pypy/dist/pypy/translator/cli/opcodes.py ============================================================================== --- pypy/dist/pypy/translator/cli/opcodes.py (original) +++ pypy/dist/pypy/translator/cli/opcodes.py Wed Mar 14 15:23:12 2007 @@ -224,6 +224,7 @@ 'cast_uint_to_float': [PushAllArgs, 'conv.u8', 'conv.r8'], 'cast_float_to_int': 'conv.i4', 'cast_float_to_uint': 'conv.u4', + 'cast_longlong_to_float': 'conv.r8', 'truncate_longlong_to_int': 'conv.i4', } 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 Wed Mar 14 15:23:12 2007 @@ -23,7 +23,7 @@ from pypy.translator.cli.entrypoint import BaseEntryPoint from pypy.translator.cli.support import patch, unpatch -FLOAT_PRECISION = 8 +FLOAT_PRECISION = 10 def check(func, annotation, args): mono = compile_function(func, annotation) @@ -287,7 +287,8 @@ assert False, 'function did raise no exception at all' def float_eq(self, x, y): - return round(x, FLOAT_PRECISION) == round(y, FLOAT_PRECISION) + diff = abs(x-y) + return diff/x < 10**-FLOAT_PRECISION def ll_to_string(self, s): return s From guido at codespeak.net Wed Mar 14 15:27:35 2007 From: guido at codespeak.net (guido at codespeak.net) Date: Wed, 14 Mar 2007 15:27:35 +0100 (CET) Subject: [pypy-svn] r40486 - in pypy/dist/pypy/tool/build/web: . templates test Message-ID: <20070314142735.693931009F@code0.codespeak.net> Author: guido Date: Wed Mar 14 15:27:21 2007 New Revision: 40486 Modified: pypy/dist/pypy/tool/build/web/app.py pypy/dist/pypy/tool/build/web/templates/build.html pypy/dist/pypy/tool/build/web/test/test_app.py Log: Added cache for execnetconference results in ServerPage, added test for BuildPage, fixed some bugs after adding test for BuildPage :| (thanks, cf! ;), fixed XHTML validity problem. Modified: pypy/dist/pypy/tool/build/web/app.py ============================================================================== --- pypy/dist/pypy/tool/build/web/app.py (original) +++ pypy/dist/pypy/tool/build/web/app.py Wed Mar 14 15:27:21 2007 @@ -34,7 +34,10 @@ """ base class for pages that communicate with the server """ exposed = True + _calllock = py.std.thread.allocate_lock() _channel_holder = [] + _result_cache = {} + MAX_CACHE_TIME = 30 # seconds def __init__(self, config, gateway=None): self.config = config @@ -56,38 +59,50 @@ break 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') + methodname is the name of the method to call, args is a tuple + + careful with args, as it's used as dict key for caching (and + also sent over the wire) so should be fairly simple """ - performed = False - if self._channel_holder: - channel = self._channel_holder[0] + self._calllock.acquire() + try: try: + time, value = self._result_cache[(methodname, args)] + except KeyError: + pass + else: + if time > py.std.time.time() - self.MAX_CACHE_TIME: + return value + performed = False + if self._channel_holder: + channel = self._channel_holder[0] + try: + channel.send((methodname, args)) + ret = channel.receive() + except: + exc, e, tb = py.std.sys.exc_info() + del tb + print ('exception occurred when calling %s(%s): ' + '%s - %s' % (methodname, args, exc, e)) + else: + performed = True + if not performed: + conference = execnetconference.conference(self.gateway, + self.config.port, False) + channel = conference.remote_exec(self.remote_code % ( + self.config.path,)) channel.send((methodname, args)) ret = channel.receive() - except: - exc, e, tb = py.std.sys.exc_info() - del tb - print ('exception occurred when calling %s(%s): ' - '%s - %s' % (methodname, args, exc, e)) - else: - performed = True - if not performed: - conference = execnetconference.conference(self.gateway, - self.config.port, False) - channel = conference.remote_exec(self.remote_code % ( - self.config.path,)) - channel.send((methodname, args)) - ret = channel.receive() - while self._channel_holder: - self._channel_holder.pop() - self._channel_holder.append(channel) - return ret + while self._channel_holder: + self._channel_holder.pop() + self._channel_holder.append(channel) + self._result_cache[(methodname, args)] = (py.std.time.time(), ret) + return ret + finally: + self._calllock.release() def init_gateway(self): if self.config.server in ['localhost', '127.0.0.1']: @@ -158,9 +173,9 @@ bpinfo, brstr = self.call_method('buildrequest', (self._buildid,)) br = BuildRequest.fromstring(brstr) if bpinfo == None: - bpinfo = {} + bpinfo = {'status': 'waiting'} return { - 'url': bpinfo['buildurl'], + 'url': bpinfo.get('buildurl', None), 'id': br.id(), 'email': br.email, 'svnurl': br.svnurl, @@ -174,7 +189,7 @@ sorted(br.compileinfo.items())], 'status': bpinfo['status'], 'statusclass': bpinfo['status'].replace(' ', '_'), - 'error': bpinfo['error'], + 'error': bpinfo.get('error', None), } class BuildsIndexPage(ServerPage): Modified: pypy/dist/pypy/tool/build/web/templates/build.html ============================================================================== --- pypy/dist/pypy/tool/build/web/templates/build.html (original) +++ pypy/dist/pypy/tool/build/web/templates/build.html Wed Mar 14 15:27:21 2007 @@ -51,7 +51,6 @@ %(build_end_time)s
%(build_end_time)]c -
sysinfo:
%(sysinfo)[b
Modified: pypy/dist/pypy/tool/build/web/test/test_app.py ============================================================================== --- pypy/dist/pypy/tool/build/web/test/test_app.py (original) +++ pypy/dist/pypy/tool/build/web/test/test_app.py Wed Mar 14 15:27:21 2007 @@ -63,6 +63,7 @@ mod.server_channel = init_fake_metaserver(TESTPORT, path) mod.config = fake.Container(port=TESTPORT, path=path, server='localhost') mod.gateway = py.execnet.PopenGateway() + ServerPage.MAX_CACHE_TIME = -1 def teardown_module(mod): mod.server_channel.send('quit') @@ -153,8 +154,29 @@ html_validate(html) class TestBuildPage(object): + def test_get_info(self): + br = build.BuildRequest('foo at bar.com', {}, {'foo': 'bar'}, + 'http://codespeak.net/svn/pypy/dist', + 10, 2, 123456789) + server_channel.send(('add_queued', br.serialize())) + server_channel.receive() + p = BuildPage(br.id(), config, gateway) + info = p.get_info() + assert isinstance(info, dict) + assert info['id'] == br.id() + def test_call(self): - pass + br = build.BuildRequest('foo at bar.com', {}, {'foo': 'bar'}, + 'http://codespeak.net/svn/pypy/dist', + 10, 2, 123456789) + server_channel.send(('add_queued', br.serialize())) + server_channel.receive() + p = BuildPage(br.id(), config, gateway) + headers, html = p(None, '/build/', '') + assert headers['Content-Type'] == 'text/html; charset=UTF-8' + assert html.strip().startswith('') + html_validate(html) class TestBuildsIndexPage(object): def test_get_builds(self): @@ -277,22 +299,35 @@ def test_call_method_simple(self): p = ServerPage(fake.Container(port=build_config.testport, path=str(path)), py.execnet.PopenGateway()) - ret = p.call_method('status', []) + ret = p.call_method('status', ()) assert ret def test_call_method_reconnect(self): p = ServerPage(fake.Container(port=build_config.testport, path=str(path)), py.execnet.PopenGateway()) - ret = p.call_method('status', []) + ret = p.call_method('status', ()) assert len(p._channel_holder) == 1 channel = p._channel_holder[0] - ret = p.call_method('status', []) + ret = p.call_method('status', ()) assert len(p._channel_holder) == 1 assert p._channel_holder[0] is channel channel.close() - ret = p.call_method('status', []) + ret = p.call_method('status', ()) assert len(p._channel_holder) == 1 assert p._channel_holder is not channel + def test_call_method_cache(self): + p = ServerPage(fake.Container(port=build_config.testport, path=str(path)), + py.execnet.PopenGateway()) + p._result_cache = {} + p.MAX_CACHE_TIME = 1000 + try: + ret = p.call_method('status', ()) + assert len(p._result_cache) == 1 + cached = p._result_cache.get(('status', ())) + assert cached[1] is ret + finally: + p.MAX_CACHE_TIME = -1 + From antocuni at codespeak.net Wed Mar 14 15:27:52 2007 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Wed, 14 Mar 2007 15:27:52 +0100 (CET) Subject: [pypy-svn] r40487 - pypy/dist/pypy/translator/cli/src Message-ID: <20070314142752.CFCA2100A6@code0.codespeak.net> Author: antocuni Date: Wed Mar 14 15:27:37 2007 New Revision: 40487 Modified: pypy/dist/pypy/translator/cli/src/ll_os.cs Log: Implement isatty at best of what .NET let us to do. Add warnings for not-implemented stubs. Modified: pypy/dist/pypy/translator/cli/src/ll_os.cs ============================================================================== --- pypy/dist/pypy/translator/cli/src/ll_os.cs (original) +++ pypy/dist/pypy/translator/cli/src/ll_os.cs Wed Mar 14 15:27:37 2007 @@ -392,60 +392,74 @@ public static void ll_os__exit(int x) { + Console.Error.WriteLine("WARNING: ll_os__exit has been called, but it's only a stub"); Helpers.raise_OSError(Errno.EPERM); // this is only a stub } public static void ll_os_chdir(string s) { + Console.Error.WriteLine("WARNING: ll_os_chdir has been called, but it's only a stub"); Helpers.raise_OSError(Errno.EPERM); // this is only a stub } public static void ll_os_chmod(string s, int x) { + Console.Error.WriteLine("WARNING: ll_os_chmod has been called, but it's only a stub"); Helpers.raise_OSError(Errno.EPERM); // this is only a stub } public static int ll_os_dup(int x) { + Console.Error.WriteLine("WARNING: ll_os_dup has been called, but it's only a stub"); Helpers.raise_OSError(Errno.EPERM); // this is only a stub return -1; } public static void ll_os_dup2(int x, int y) { + Console.Error.WriteLine("WARNING: ll_os_dup2 has been called, but it's only a stub"); Helpers.raise_OSError(Errno.EPERM); // this is only a stub } public static int ll_os_fork() { + Console.Error.WriteLine("WARNING: ll_os_fork has been called, but it's only a stub"); Helpers.raise_OSError(Errno.EPERM); // this is only a stub return -1; } public static void ll_os_ftruncate(int x, int y) { + Console.Error.WriteLine("WARNING: ll_os_ftruncate has been called, but it's only a stub"); Helpers.raise_OSError(Errno.EPERM); // this is only a stub } public static int ll_os_getpid() { + Console.Error.WriteLine("WARNING: ll_os_getpid has been called, but it's only a stub"); Helpers.raise_OSError(Errno.EPERM); // this is only a stub return -1; } public static bool ll_os_isatty(int x) { - Helpers.raise_OSError(Errno.EPERM); // this is only a stub - return false; + // XXX: this is not the right behaviour, but it's needed + // to have the interactive interpreter working + if (x == 0 || x == 1 || x == 2) + return true; + else + return false; } public static void ll_os_link(string s1, string s2) { + Console.Error.WriteLine("WARNING: ll_os_link has been called, but it's only a stub"); Helpers.raise_OSError(Errno.EPERM); // this is only a stub } public static void ll_os_mkdir(string s, int x) { + Console.Error.WriteLine("WARNING: ll_os_mkdir has been called, but it's only a stub"); Helpers.raise_OSError(Errno.EPERM); // this is only a stub } From antocuni at codespeak.net Wed Mar 14 15:29:13 2007 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Wed, 14 Mar 2007 15:29:13 +0100 (CET) Subject: [pypy-svn] r40488 - in pypy/dist/pypy/translator/cli: . src Message-ID: <20070314142913.3A3B5100A0@code0.codespeak.net> Author: antocuni Date: Wed Mar 14 15:29:01 2007 New Revision: 40488 Removed: pypy/dist/pypy/translator/cli/src/ll_os-unix.cs Modified: pypy/dist/pypy/translator/cli/rte.py Log: kill the unused UnixDll Modified: pypy/dist/pypy/translator/cli/rte.py ============================================================================== --- pypy/dist/pypy/translator/cli/rte.py (original) +++ pypy/dist/pypy/translator/cli/rte.py Wed Mar 14 15:29:01 2007 @@ -76,20 +76,12 @@ return SDK.ilasm() get_COMPILER = classmethod(get_COMPILER) -class FrameworkDLL(Target): +class PyPyLibDLL(Target): SOURCES = ['pypylib.cs', 'll_os.cs', 'll_os_path.cs', 'errno.cs', 'll_math.cs'] OUTPUT = 'pypylib.dll' - ALIAS = 'pypylib-framework.dll' FLAGS = ['/t:library', '/unsafe', '/r:main.exe'] DEPENDENCIES = [MainStub] -class UnixDLL(Target): - SOURCES = ['pypylib.cs', 'll_os-unix.cs', 'll_math.cs'] - OUTPUT = 'pypylib.dll' - ALIAS = 'pypylib-unix.dll' - FLAGS = ['/t:library', '/unsafe', '/r:Mono.Posix', '/r:main.exe'] - DEPENDENCIES = [MainStub] - class Query(Target): SOURCES = ['query.cs'] OUTPUT = 'query.exe' @@ -109,12 +101,7 @@ FLAGS = ['/t:library'] def get_pypy_dll(): - if os.environ.get('PYPYLIB', '').lower() == 'unix': - DLL = UnixDLL - else: - DLL = FrameworkDLL - return DLL.get() - + return PyPyLibDLL.get() if __name__ == '__main__': get_pypy_dll() From guido at codespeak.net Wed Mar 14 15:31:36 2007 From: guido at codespeak.net (guido at codespeak.net) Date: Wed, 14 Mar 2007 15:31:36 +0100 (CET) Subject: [pypy-svn] r40489 - pypy/dist/pypy/tool/build/web/test Message-ID: <20070314143136.3177B1009F@code0.codespeak.net> Author: guido Date: Wed Mar 14 15:31:23 2007 New Revision: 40489 Modified: pypy/dist/pypy/tool/build/web/test/test_app.py Log: Another 'missing test'. Modified: pypy/dist/pypy/tool/build/web/test/test_app.py ============================================================================== --- pypy/dist/pypy/tool/build/web/test/test_app.py (original) +++ pypy/dist/pypy/tool/build/web/test/test_app.py Wed Mar 14 15:31:23 2007 @@ -180,7 +180,16 @@ class TestBuildsIndexPage(object): def test_get_builds(self): - pass + br = build.BuildRequest('foo at bar.com', {}, {'foo': 'bar'}, + 'http://codespeak.net/svn/pypy/dist', + 10, 2, 123456789) + server_channel.send(('add_queued', br.serialize())) + server_channel.receive() + p = BuildsIndexPage(config, gateway) + builds = p.get_builds() + assert isinstance(builds, list) + assert isinstance(builds[-1], dict) + assert builds[-1]['id'] == br.id() def test_call(self): p = BuildsIndexPage(config, gateway) From cfbolz at codespeak.net Wed Mar 14 16:37:44 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 14 Mar 2007 16:37:44 +0100 (CET) Subject: [pypy-svn] r40490 - in pypy/dist/pypy/tool/build/web: . templates test Message-ID: <20070314153744.9989410091@code0.codespeak.net> Author: cfbolz Date: Wed Mar 14 16:37:43 2007 New Revision: 40490 Modified: pypy/dist/pypy/tool/build/web/app.py pypy/dist/pypy/tool/build/web/templates/build.html pypy/dist/pypy/tool/build/web/test/test_app.py Log: rather hairy code to format the chosen options. Guido, please look at this. Modified: pypy/dist/pypy/tool/build/web/app.py ============================================================================== --- pypy/dist/pypy/tool/build/web/app.py (original) +++ pypy/dist/pypy/tool/build/web/app.py Wed Mar 14 16:37:43 2007 @@ -30,6 +30,44 @@ headers.update(get_nocache_headers()) return headers +def format_compileinfo(compileinfo): + # XXX hack and partially copied from Config.__str__ + from pypy.config.pypyoption import get_pypy_config + from pypy.config.config import Config + from pypy.translator.driver import DEFAULTS + config1 = get_pypy_config(DEFAULTS, translating=True) + config2 = get_pypy_config(DEFAULTS, translating=True) + config1.set(**compileinfo) + def add(c1, c2, path_upto_here="", outermost=False): + items = [] + children = [(child._name, child) + for child in c1._cfgimpl_descr._children] + children.sort() + for name, child in children: + value = getattr(c1, name) + if isinstance(value, Config): + if path_upto_here: + subpath = path_upto_here + "." + name + else: + subpath = name + substr = add(value, getattr(c2, name), subpath) + if substr: + items.append("
  • [%s]
      " % (name, )) + items.append(" " + substr.replace("\n", "\n ")) + items.append("
  • ") + elif value == getattr(c2, name): + continue + else: + url = "http://codespeak.net/pypy/dist/pypy/doc/config/" + url += path_upto_here + "." + name + ".html" + items.append('
  • %s = %s
  • ' % ( + url, name, value)) + if outermost and not lines: + return "" + return "\n ".join(items) + return "
      %s
    " % (add(config1, config2, outermost=False), ) + + class ServerPage(object): """ base class for pages that communicate with the server """ @@ -144,9 +182,7 @@ d['href'] = '/builds/%s' % (id,) d.pop('sysinfo', None) # same as builder d.pop('build_end_time', None) # it's still busy ;) - # templesser doesn't understand dicts this way... - d['compileinfo'] = [{'key': k, 'value': v} for (k, v) in - d['compileinfo'].items()] + d['compileinfo'] = format_compileinfo(d['compileinfo']) for key in ['request_time', 'build_start_time']: if d[key]: d[key] = time.strftime('%Y/%m/%d %H:%M:%S', @@ -185,8 +221,7 @@ 'build_end_time': format_time(br.build_end_time), 'sysinfo': [{'key': k, 'value': v} for (k, v) in sorted(br.sysinfo.items())], - 'compileinfo': [{'key': k, 'value': v} for (k, v) in - sorted(br.compileinfo.items())], + 'compileinfo': format_compileinfo(br.compileinfo), 'status': bpinfo['status'], 'statusclass': bpinfo['status'].replace(' ', '_'), 'error': bpinfo.get('error', None), Modified: pypy/dist/pypy/tool/build/web/templates/build.html ============================================================================== --- pypy/dist/pypy/tool/build/web/templates/build.html (original) +++ pypy/dist/pypy/tool/build/web/templates/build.html Wed Mar 14 16:37:43 2007 @@ -59,12 +59,7 @@
    %(sysinfo)]b
    compileinfo:
    - %(compileinfo)[b -
    - %(key)s: - %(value)s -
    - %(compileinfo)]b + %(compileinfo)s ->->---%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 Place(StorageInStack): + +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() +gv_frame_base = GenVar() + +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): + # force the variable to be in the stack + srcop = allocator.get_operand(self.x) + if not isinstance(srcop, MODRM): + oldop = 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/debug-jit/pypy/jit/codegen/i386/rgenop.py ============================================================================== --- pypy/branch/debug-jit/pypy/jit/codegen/i386/rgenop.py (original) +++ pypy/branch/debug-jit/pypy/jit/codegen/i386/rgenop.py Sun Mar 18 11:42:26 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, DEBUG_STACK +from pypy.jit.codegen.i386.regalloc import gv_frame_base, StorageInStack +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 @@ -82,18 +84,20 @@ # ____________________________________________________________ class FlexSwitch(CodeGenSwitch): - REG = eax - def __init__(self, rgenop, 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 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: @@ -138,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 @@ -205,45 +209,41 @@ class Builder(GenBuilder): coming_from = 0 - operations = None update_defaultcaseaddr_of = None - force_in_stack = None + paused_alive_gv = None + order_dependency = None + keepalives_gv = 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 = [] 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): - allocator = RegAllocator() - if self.force_in_stack is not None: - allocator.force_stack_storage(self.force_in_stack) - allocator.set_final(final_vars_gv) + 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 + allocator = RegAllocator(self.operations) + allocator.set_final(final_vars_gv, final_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 + 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.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 - self.operations = None + allocator.generate_operations(mc) + 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[:] if renaming: self.inputargs_gv = [GenVar() for v in final_vars_gv] else: @@ -252,18 +252,19 @@ 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): -## 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() + # we get better register allocation if we write a single large mc block + self.insert_keepalives() for i in range(len(args_gv)): 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 @@ -272,7 +273,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): @@ -301,58 +302,62 @@ 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) - # 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)) + 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 + 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 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 - mc = self.generate_block_code(outputargs_gv, outputargs_gv, operands, - minimal_stack_depth = targetlbl.targetstackdepth) + 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): - mc = self.generate_block_code([gv_returnvar], [gv_returnvar], [eax]) + gvs = [gv_returnvar] + mc = self.generate_block_code(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() 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 @@ -366,12 +371,30 @@ return op @specialize.arg(1) + def genraisingop1(self, opname, gv_arg): + cls = getopclass1(opname) + op = cls(gv_arg) + self.operations.append(op) + op_excflag = OpFetchCC(op.ccexcflag) + self.operations.append(op_excflag) + return op, op_excflag + + @specialize.arg(1) def genop2(self, opname, gv_arg1, gv_arg2): cls = getopclass2(opname) op = cls(gv_arg1, gv_arg2) self.operations.append(op) return op + @specialize.arg(1) + def genraisingop2(self, opname, gv_arg1, gv_arg2): + cls = getopclass2(opname) + op = cls(gv_arg1, gv_arg2) + self.operations.append(op) + op_excflag = OpFetchCC(op.ccexcflag) + self.operations.append(op_excflag) + return op, op_excflag + def genop_ptr_iszero(self, kind, gv_ptr): cls = getopclass1('ptr_iszero') op = cls(gv_ptr) @@ -464,10 +487,11 @@ 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.inputargs_gv, self.inputoperands) + 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() self.rgenop.close_mc(mc) @@ -481,43 +505,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)) - v = place + if self.keepalives_gv is None: + self.keepalives_gv = [] + self.keepalives_gv.append(v) + sis = StorageInStack(v) + self.operations.append(sis) + v = sis result.append(v) return result - def alloc_frame_place(self, kind, gv_initial_value): - if self.force_in_stack is None: - self.force_in_stack = [] - v = OpSameAs(gv_initial_value) - self.operations.append(v) - place = Place() - place.stackvar = v - self.force_in_stack.append((v, place)) + def alloc_frame_place(self, kind, gv_initial_value=None): + place = Place(gv_initial_value) + 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 + v = OpAbsorbPlace(place) + self.operations.append(v) return v 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 + # ____________________________________________________________ @@ -530,39 +589,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 @@ -570,8 +628,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... @@ -600,10 +659,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 +757,6 @@ global_rgenop = RI386GenOp() RI386GenOp.constPrebuiltGlobal = global_rgenop.genconst +zero_const = AddrConst(llmemory.NULL) MALLOC_SIGTOKEN = RI386GenOp.sigToken(GC_MALLOC.TO) Modified: pypy/branch/debug-jit/pypy/jit/codegen/i386/ri386.py ============================================================================== --- pypy/branch/debug-jit/pypy/jit/codegen/i386/ri386.py (original) +++ pypy/branch/debug-jit/pypy/jit/codegen/i386/ri386.py Sun Mar 18 11:42:26 2007 @@ -1,16 +1,22 @@ +from pypy.rlib.rarithmetic import intmask 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 @@ -46,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 @@ -64,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 @@ -185,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 @@ -256,6 +271,9 @@ else: return cls(0x84, SIB + packimm32(offset)) +def fixedsize_ebp_ofs(offset): + return MODRM(0x80 | EBP.op, packimm32(offset)) + def single_byte(value): return -128 <= value < 128 @@ -276,15 +294,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/debug-jit/pypy/jit/codegen/i386/ri386setup.py ============================================================================== --- pypy/branch/debug-jit/pypy/jit/codegen/i386/ri386setup.py (original) +++ pypy/branch/debug-jit/pypy/jit/codegen/i386/ri386setup.py Sun Mar 18 11:42:26 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/debug-jit/pypy/jit/codegen/i386/test/test_auto_encoding.py ============================================================================== --- pypy/branch/debug-jit/pypy/jit/codegen/i386/test/test_auto_encoding.py (original) +++ pypy/branch/debug-jit/pypy/jit/codegen/i386/test/test_auto_encoding.py Sun Mar 18 11:42:26 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/debug-jit/pypy/jit/codegen/i386/test/test_genc_tl.py ============================================================================== --- pypy/branch/debug-jit/pypy/jit/codegen/i386/test/test_genc_tl.py (original) +++ pypy/branch/debug-jit/pypy/jit/codegen/i386/test/test_genc_tl.py Sun Mar 18 11:42:26 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/debug-jit/pypy/jit/codegen/i386/test/test_genc_tlc.py ============================================================================== --- pypy/branch/debug-jit/pypy/jit/codegen/i386/test/test_genc_tlc.py (original) +++ pypy/branch/debug-jit/pypy/jit/codegen/i386/test/test_genc_tlc.py Sun Mar 18 11:42:26 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 Modified: pypy/branch/debug-jit/pypy/jit/codegen/i386/test/test_ri386.py ============================================================================== --- pypy/branch/debug-jit/pypy/jit/codegen/i386/test/test_ri386.py (original) +++ pypy/branch/debug-jit/pypy/jit/codegen/i386/test/test_ri386.py Sun Mar 18 11:42:26 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 Modified: pypy/branch/debug-jit/pypy/jit/codegen/i386/viewcode.py ============================================================================== --- pypy/branch/debug-jit/pypy/jit/codegen/i386/viewcode.py (original) +++ pypy/branch/debug-jit/pypy/jit/codegen/i386/viewcode.py Sun Mar 18 11:42:26 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) Modified: pypy/branch/debug-jit/pypy/jit/codegen/llgraph/llimpl.py ============================================================================== --- pypy/branch/debug-jit/pypy/jit/codegen/llgraph/llimpl.py (original) +++ pypy/branch/debug-jit/pypy/jit/codegen/llgraph/llimpl.py Sun Mar 18 11:42:26 2007 @@ -168,6 +168,10 @@ return to_opaque_object(erasedvar(v, block)) def guess_result_type(opname, opvars): + if opname.endswith('_zer'): # h + opname = opname[:-4] # a + if opname.endswith('_ovf'): # c + opname = opname[:-4] # k op = getattr(llop, opname) need_result_type = getattr(op.fold, 'need_result_type', False) assert not need_result_type, ("cannot guess the result type of %r" @@ -198,6 +202,13 @@ 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 + TYPE = lltype.erasedType(TYPE) + 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 +561,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/debug-jit/pypy/jit/codegen/llgraph/rgenop.py ============================================================================== --- pypy/branch/debug-jit/pypy/jit/codegen/llgraph/rgenop.py (original) +++ pypy/branch/debug-jit/pypy/jit/codegen/llgraph/rgenop.py Sun Mar 18 11:42:26 2007 @@ -111,12 +111,31 @@ return LLVar(llimpl.genop(self.b, opname, [gv_arg], llimpl.guess)) @specialize.arg(1) + def genraisingop1(self, opname, gv_arg): + debug_assert(self.rgenop.currently_writing is self, + "genraisingop1: bad currently_writing") + gv_res = LLVar(llimpl.genop(self.b, opname, [gv_arg], llimpl.guess)) + gv_exc = LLVar(llimpl.genop(self.b, "check_and_clear_exc", [], + gv_Bool.v)) + return gv_res, gv_exc + + @specialize.arg(1) def genop2(self, opname, gv_arg1, gv_arg2): debug_assert(self.rgenop.currently_writing is self, "genop2: bad currently_writing") return LLVar(llimpl.genop(self.b, opname, [gv_arg1, gv_arg2], llimpl.guess)) + @specialize.arg(1) + def genraisingop2(self, opname, gv_arg1, gv_arg2): + debug_assert(self.rgenop.currently_writing is self, + "genraisingop2: bad currently_writing") + gv_res = LLVar(llimpl.genop(self.b, opname, [gv_arg1, gv_arg2], + llimpl.guess)) + gv_exc = LLVar(llimpl.genop(self.b, "check_and_clear_exc", [], + gv_Bool.v)) + return gv_res, gv_exc + def genop_call(self, (ARGS_gv, gv_RESULT, _), gv_callable, args_gv): debug_assert(self.rgenop.currently_writing is self, "genop_call: bad currently_writing") @@ -326,9 +345,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)) @@ -404,6 +425,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/debug-jit/pypy/jit/codegen/llgraph/test/test_rgenop.py ============================================================================== --- pypy/branch/debug-jit/pypy/jit/codegen/llgraph/test/test_rgenop.py (original) +++ pypy/branch/debug-jit/pypy/jit/codegen/llgraph/test/test_rgenop.py Sun Mar 18 11:42:26 2007 @@ -9,6 +9,10 @@ class TestLLGraphRGenop(AbstractRGenOpTests): RGenOp = RGenOp + def setup_method(self, meth): + if 'ovfcheck' in meth.__name__: + py.test.skip("no chance (the llinterpreter has no rtyper)") + def getcompiled(self, runner, argtypes, annotatorpolicy): def quasi_compiled_runner(*args): return interpret(runner, args, policy=annotatorpolicy) Modified: pypy/branch/debug-jit/pypy/jit/codegen/llvm/rgenop.py ============================================================================== --- pypy/branch/debug-jit/pypy/jit/codegen/llvm/rgenop.py (original) +++ pypy/branch/debug-jit/pypy/jit/codegen/llvm/rgenop.py Sun Mar 18 11:42:26 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 @@ -862,6 +862,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 @@ -944,3 +948,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/debug-jit/pypy/jit/codegen/model.py ============================================================================== --- pypy/branch/debug-jit/pypy/jit/codegen/model.py (original) +++ pypy/branch/debug-jit/pypy/jit/codegen/model.py Sun Mar 18 11:42:26 2007 @@ -65,6 +65,14 @@ ## @specialize.arg(1) ## def genop2(self, opname, gv_arg1, gv_arg2): +## @specialize.arg(1) +## def genraisingop1(self, opname, gv_arg): +## return a pair (gv_result, gv_flag_set_if_exception) + +## @specialize.arg(1) +## def genraisingop2(self, opname, gv_arg1, gv_arg2): +## return a pair (gv_result, gv_flag_set_if_exception) + ## def genop_getfield(self, fieldtoken, gv_ptr): ## def genop_setfield(self, fieldtoken, gv_ptr, gv_value): ## def genop_getsubstruct(self, fieldtoken, gv_ptr): @@ -196,7 +204,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. @@ -261,6 +269,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 @@ -396,9 +410,17 @@ return dummy_var @specialize.arg(1) + def genraisingop1(self, opname, gv_arg): + return dummy_var, dummy_var + + @specialize.arg(1) def genop2(self, opname, gv_arg1, gv_arg2): return dummy_var + @specialize.arg(1) + def genraisingop2(self, opname, gv_arg1, gv_arg2): + return dummy_var, dummy_var + def genop_ptr_iszero(self, kind, gv_ptr): return dummy_var @@ -475,7 +497,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): Modified: pypy/branch/debug-jit/pypy/jit/codegen/ppc/rgenop.py ============================================================================== --- pypy/branch/debug-jit/pypy/jit/codegen/ppc/rgenop.py (original) +++ pypy/branch/debug-jit/pypy/jit/codegen/ppc/rgenop.py Sun Mar 18 11:42:26 2007 @@ -1132,6 +1132,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) @@ -1355,3 +1359,5 @@ from ctypes import cast, c_void_p, c_int, POINTER p = cast(c_void_p(addr), POINTER(c_int)) p[0] = value + +zero_const = AddrConst(llmemory.NULL) Modified: pypy/branch/debug-jit/pypy/jit/codegen/test/operation_tests.py ============================================================================== --- pypy/branch/debug-jit/pypy/jit/codegen/test/operation_tests.py (original) +++ pypy/branch/debug-jit/pypy/jit/codegen/test/operation_tests.py Sun Mar 18 11:42:26 2007 @@ -3,7 +3,7 @@ from pypy.jit.codegen import graph2rgenop from pypy.rpython.lltypesystem import lltype from pypy.rpython.lltypesystem.lloperation import llop -from pypy.rlib.rarithmetic import r_uint, intmask +from pypy.rlib.rarithmetic import r_uint, intmask, ovfcheck from ctypes import cast, c_void_p, CFUNCTYPE, c_int, c_float from pypy import conftest Modified: pypy/branch/debug-jit/pypy/jit/codegen/test/rgenop_tests.py ============================================================================== --- pypy/branch/debug-jit/pypy/jit/codegen/test/rgenop_tests.py (original) +++ pypy/branch/debug-jit/pypy/jit/codegen/test/rgenop_tests.py Sun Mar 18 11:42:26 2007 @@ -1,5 +1,6 @@ -import random +import random, sys from pypy.rpython.annlowlevel import MixLevelAnnotatorPolicy, llhelper +from pypy.rlib.rarithmetic import intmask from pypy.rlib.objectmodel import keepalive_until_here from pypy.rpython.lltypesystem import lltype, llmemory from pypy.translator.c.test import test_boehm @@ -13,6 +14,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' @@ -642,6 +644,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() @@ -666,10 +672,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): @@ -682,11 +691,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 @@ -728,6 +740,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() @@ -745,6 +758,29 @@ return res return read_frame_place_runner +def make_ovfcheck_adder(rgenop, n): + sigtoken = rgenop.sigToken(FUNC) + builder, gv_fn, [gv_x] = rgenop.newgraph(sigtoken, "ovfcheck_adder") + builder.start_writing() + gv_result, gv_flag = builder.genraisingop2("int_add_ovf", gv_x, + rgenop.genconst(n)) + gv_flag = builder.genop1("cast_bool_to_int", gv_flag) + gv_result = builder.genop2("int_lshift", gv_result, rgenop.genconst(1)) + gv_result = builder.genop2("int_or", gv_result, gv_flag) + builder.finish_and_return(sigtoken, gv_result) + builder.end() + return gv_fn + +def get_ovfcheck_adder_runner(RGenOp): + def runner(x, y): + rgenop = RGenOp() + gv_add_x = make_ovfcheck_adder(rgenop, x) + add_x = gv_add_x.revealconst(lltype.Ptr(FUNC)) + res = add_x(y) + keepalive_until_here(rgenop) # to keep the code blocks alive + return res + return runner + class AbstractRGenOpTests(test_boehm.AbstractGCTestClass): RGenOp = None @@ -1329,9 +1365,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 @@ -1339,16 +1376,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): @@ -1368,6 +1405,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: @@ -1662,3 +1731,242 @@ res = fnptr(10, 29, 12) assert res == 29 + + def test_from_random_5_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)) + 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 + + def test_ovfcheck_adder_direct(self): + rgenop = self.RGenOp() + gv_add_5 = make_ovfcheck_adder(rgenop, 5) + fnptr = self.cast(gv_add_5, 1) + res = fnptr(37) + assert res == (42 << 1) | 0 + res = fnptr(sys.maxint-2) + assert (res & 1) == 1 + + def test_ovfcheck_adder_compile(self): + fn = self.compile(get_ovfcheck_adder_runner(self.RGenOp), [int, int]) + res = fn(9080983, -9080941) + assert res == (42 << 1) | 0 + res = fn(-sys.maxint, -10) + assert (res & 1) == 1 + + def test_ovfcheck1_direct(self): + yield self.ovfcheck1_direct, "int_neg_ovf", [(18, -18), + (-18, 18), + (sys.maxint, -sys.maxint), + (-sys.maxint, sys.maxint), + (-sys.maxint-1, None)] + yield self.ovfcheck1_direct, "int_abs_ovf", [(18, 18), + (-18, 18), + (sys.maxint, sys.maxint), + (-sys.maxint, sys.maxint), + (-sys.maxint-1, None)] + + def ovfcheck1_direct(self, opname, testcases): + rgenop = self.RGenOp() + sigtoken = rgenop.sigToken(FUNC) + builder, gv_fn, [gv_x] = rgenop.newgraph(sigtoken, "ovfcheck1") + builder.start_writing() + gv_result, gv_flag = builder.genraisingop1(opname, gv_x) + gv_flag = builder.genop1("cast_bool_to_int", gv_flag) + gv_result = builder.genop2("int_lshift", gv_result, rgenop.genconst(1)) + gv_result = builder.genop2("int_or", gv_result, gv_flag) + builder.finish_and_return(sigtoken, gv_result) + builder.end() + + fnptr = self.cast(gv_fn, 1) + for x, expected in testcases: + res = fnptr(x) + if expected is None: + assert (res & 1) == 1 + else: + assert res == intmask(expected << 1) | 0 + + def test_ovfcheck2_direct(self): + yield self.ovfcheck2_direct, "int_sub_ovf", [(18, 25, -7), + (sys.maxint, -1, None), + (-2, sys.maxint, None)] + yield self.ovfcheck2_direct, "int_mul_ovf", [(6, 7, 42), + (sys.maxint-100, 2, None), + (-2, sys.maxint-100, None)] + # XXX the rest in-progress + # XXX also missing the _zer versions +## yield self.ovfcheck2_direct, "int_mod_ovf", [ +## (100, 8, 4), +## (-sys.maxint-1, 1, 0), +## (-sys.maxint-1, -1, None)] +## yield self.ovfcheck2_direct, "int_floordiv_ovf", [ +## (100, 2, 50), +## (-sys.maxint-1, 1, -sys.maxint-1), +## (-sys.maxint-1, -1, None)] +## yield self.ovfcheck2_direct, "int_lshift_ovf", [ +## (1, 30, 1<<30), +## (1, 31, None), +## (0xf23c, 14, 0xf23c << 14), +## (0xf23c, 15, None), +## (-1, 31, (-1) << 31), +## (-2, 31, None), +## (-3, 31, None), +## (-sys.maxint-1, 0, -sys.maxint-1)] + + def ovfcheck2_direct(self, opname, testcases): + rgenop = self.RGenOp() + sigtoken = rgenop.sigToken(FUNC2) + builder, gv_fn, [gv_x, gv_y] = rgenop.newgraph(sigtoken, "ovfcheck2") + builder.start_writing() + gv_result, gv_flag = builder.genraisingop2(opname, gv_x, gv_y) + gv_flag = builder.genop1("cast_bool_to_int", gv_flag) + gv_result = builder.genop2("int_lshift", gv_result, rgenop.genconst(1)) + gv_result = builder.genop2("int_or", gv_result, gv_flag) + builder.finish_and_return(sigtoken, gv_result) + builder.end() + + fnptr = self.cast(gv_fn, 1) + for x, y, expected in testcases: + res = fnptr(x, y) + if expected is None: + assert (res & 1) == 1 + else: + assert res == intmask(expected << 1) | 0 Modified: pypy/branch/debug-jit/pypy/jit/goal/jitstep.py ============================================================================== --- pypy/branch/debug-jit/pypy/jit/goal/jitstep.py (original) +++ pypy/branch/debug-jit/pypy/jit/goal/jitstep.py Sun Mar 18 11:42:26 2007 @@ -1,3 +1,4 @@ +import types from pypy.module.pypyjit.interp_jit import PORTAL from pypy.objspace.flow.model import checkgraph @@ -10,7 +11,14 @@ class PyPyHintAnnotatorPolicy(HintAnnotatorPolicy): + def __init__(self, timeshift_graphs): + HintAnnotatorPolicy.__init__(self, novirtualcontainer = True, + oopspec = True) + self.timeshift_graphs = timeshift_graphs + def look_inside_graph(self, graph): + if graph in self.timeshift_graphs: + return self.timeshift_graphs[graph] try: func = graph.func except AttributeError: @@ -19,26 +27,161 @@ 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 + if func.__name__.startswith('_mm_') or '_mth_mm_' in func.__name__: + return False + if func.__name__.startswith('fastfunc_'): + return False return True forbidden_modules = {'pypy.interpreter.gateway': True, - 'pypy.interpreter.baseobjspace': True, + #'pypy.interpreter.baseobjspace': True, 'pypy.interpreter.typedef': True, 'pypy.interpreter.eval': True, 'pypy.interpreter.function': True, 'pypy.interpreter.pytraceback': True, } -POLICY = PyPyHintAnnotatorPolicy(novirtualcontainer = True, - oopspec = True) +def enumerate_reachable_graphs(translator, startgraph): + from pypy.translator.backendopt.support import find_calls_from + pending = [(startgraph, None)] + yield pending[0] + seen = {startgraph: True} + while pending: + yield None # hack: a separator meaning "length increases now" + nextlengthlist = [] + nextseen = {} + for node in pending: + head, tail = node + for block, callee in find_calls_from(translator, head): + if callee not in seen: + newnode = callee, node + yield newnode + nextlengthlist.append(newnode) + nextseen[callee] = True + pending = nextlengthlist + seen.update(nextseen) + yield None + +def graphs_on_the_path_to(translator, startgraph, targetgraphs): + targetgraphs = targetgraphs.copy() + result = {} + found = {} + for node in enumerate_reachable_graphs(translator, startgraph): + if node is None: # hack: a separator meaning "length increases now" + for graph in found: + del targetgraphs[graph] + found.clear() + if not targetgraphs: + return result + elif node[0] in targetgraphs: + found[node[0]] = True + while node is not None: + head, tail = node + result[head] = True + node = tail + raise Exception("did not reach all targets:\nmissing %r" % ( + targetgraphs.keys(),)) + + +def timeshift_graphs(t, portal_graph): + result_graphs = {} + + def _graph(func): + func = getattr(func, 'im_func', func) + return graphof(t, func) + + def seefunc(fromfunc, *tofuncs): + targetgraphs = {} + for tofunc in tofuncs: + targetgraphs[_graph(tofunc)] = True + graphs = graphs_on_the_path_to(t, _graph(fromfunc), targetgraphs) + result_graphs.update(graphs) + + def seepath(*path): + for i in range(1, len(path)): + seefunc(path[i-1], path[i]) + + def dontsee(func): + result_graphs[_graph(func)] = False + + # -------------------- + import pypy + seepath(pypy.interpreter.pyframe.PyFrame.BINARY_ADD, + pypy.objspace.descroperation.DescrOperation.add, + pypy.objspace.std.intobject.add__Int_Int, + pypy.objspace.std.inttype.wrapint, + pypy.objspace.std.intobject.W_IntObject.__init__) + seepath(pypy.interpreter.pyframe.PyFrame.BINARY_SUBTRACT, + pypy.objspace.descroperation.DescrOperation.sub, + pypy.objspace.std.intobject.sub__Int_Int) + seepath(pypy.interpreter.pyframe.PyFrame.BINARY_MULTIPLY, + pypy.objspace.descroperation.DescrOperation.mul, + pypy.objspace.std.intobject.mul__Int_Int) + seepath(pypy.interpreter.pyframe.PyFrame.BINARY_AND, + pypy.objspace.descroperation.DescrOperation.and_, + pypy.objspace.std.intobject.and__Int_Int) + seepath(pypy.interpreter.pyframe.PyFrame.BINARY_OR, + pypy.objspace.descroperation.DescrOperation.or_, + pypy.objspace.std.intobject.or__Int_Int) + seepath(pypy.interpreter.pyframe.PyFrame.BINARY_XOR, + pypy.objspace.descroperation.DescrOperation.xor, + pypy.objspace.std.intobject.xor__Int_Int) + seepath(pypy.interpreter.pyframe.PyFrame.COMPARE_OP, + pypy.objspace.descroperation.DescrOperation.lt, + pypy.objspace.std.intobject.lt__Int_Int) + seepath(pypy.interpreter.pyframe.PyFrame.COMPARE_OP, + pypy.objspace.descroperation.DescrOperation.le, + pypy.objspace.std.intobject.le__Int_Int) + seepath(pypy.interpreter.pyframe.PyFrame.COMPARE_OP, + pypy.objspace.descroperation.DescrOperation.eq, + pypy.objspace.std.intobject.eq__Int_Int) + seepath(pypy.interpreter.pyframe.PyFrame.COMPARE_OP, + pypy.objspace.descroperation.DescrOperation.ne, + pypy.objspace.std.intobject.ne__Int_Int) + seepath(pypy.interpreter.pyframe.PyFrame.COMPARE_OP, + pypy.objspace.descroperation.DescrOperation.gt, + pypy.objspace.std.intobject.gt__Int_Int) + seepath(pypy.interpreter.pyframe.PyFrame.COMPARE_OP, + pypy.objspace.descroperation.DescrOperation.ge, + pypy.objspace.std.intobject.ge__Int_Int) + seepath(pypy.objspace.descroperation._invoke_binop, + pypy.objspace.descroperation._check_notimplemented) + seepath(pypy.objspace.descroperation.DescrOperation.add, + pypy.objspace.std.Space.type, + pypy.objspace.std.Space.gettypeobject) + #seepath(pypy.objspace.descroperation.DescrOperation.xxx, + # pypy.objspace.std.typeobject.W_TypeObject.lookup, + # pypy.objspace.std.typeobject.W_TypeObject.getdictvalue_w) + seepath(pypy.objspace.descroperation.DescrOperation.add, + pypy.objspace.std.typeobject.W_TypeObject.lookup_where, + pypy.objspace.std.typeobject.W_TypeObject.getdictvalue_w) + seepath(pypy.objspace.std.typeobject.W_TypeObject.lookup_where, + pypy.objspace.std.typeobject.W_TypeObject.is_heaptype) + seepath(pypy.objspace.descroperation.DescrOperation.add, + pypy.objspace.std.Space.is_w) + dontsee(pypy.interpreter.pyframe.PyFrame.execute_frame) + # -------------------- + + return result_graphs + def hintannotate(drv): t = drv.translator portal_graph = graphof(t, PORTAL) - + + POLICY = PyPyHintAnnotatorPolicy(timeshift_graphs(t, portal_graph)) + + graphnames = [str(_g) for _g in POLICY.timeshift_graphs] + graphnames.sort() + print '-' * 20 + for graphname in graphnames: + print graphname + print '-' * 20 + hannotator = HintAnnotator(base_translator=t, policy=POLICY) hs = hannotator.build_types(portal_graph, [SomeLLAbstractConstant(v.concretetype, @@ -49,8 +192,12 @@ 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.tool.udir import udir + udir.ensure(dir=1) # fork-friendly hack + udir.join('.lock').ensure() from pypy.jit.timeshifter.hrtyper import HintRTyper #from pypy.jit.codegen.llgraph.rgenop import RGenOp from pypy.jit.codegen.i386.rgenop import RI386GenOp as RGenOp @@ -62,9 +209,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/debug-jit/pypy/jit/goal/targetjit.py ============================================================================== --- pypy/branch/debug-jit/pypy/jit/goal/targetjit.py (original) +++ pypy/branch/debug-jit/pypy/jit/goal/targetjit.py Sun Mar 18 11:42:26 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], @@ -44,9 +46,12 @@ return super(PyPyJITTarget, self).target(driver, args) def handle_config(self, config): + super(PyPyJITTarget, self).handle_config(config) config.translation.fork_before = 'hintannotate' + config.translation.backendopt.inline_threshold = 20.1 def handle_translate_config(self, translateconfig): + super(PyPyJITTarget, self).handle_translate_config(translateconfig) translateconfig.goals = ['timeshift'] Modified: pypy/branch/debug-jit/pypy/jit/hintannotator/annotator.py ============================================================================== --- pypy/branch/debug-jit/pypy/jit/hintannotator/annotator.py (original) +++ pypy/branch/debug-jit/pypy/jit/hintannotator/annotator.py Sun Mar 18 11:42:26 2007 @@ -20,12 +20,21 @@ def look_inside_graph(self, graph): return True - def look_inside_graphs(self, graph_list): - if not graph_list: - return False # cannot follow indirect call with no known targets - for graph in graph_list: - if not self.look_inside_graph(graph): + +class StopAtXPolicy(HintAnnotatorPolicy): + """Useful for tests.""" + + def __init__(self, *funcs): + HintAnnotatorPolicy.__init__(self, novirtualcontainer=True, + oopspec=True) + self.funcs = funcs + + def look_inside_graph(self, graph): + try: + if graph.func in self.funcs: return False + except AttributeError: + pass return True Modified: pypy/branch/debug-jit/pypy/jit/hintannotator/bookkeeper.py ============================================================================== --- pypy/branch/debug-jit/pypy/jit/hintannotator/bookkeeper.py (original) +++ pypy/branch/debug-jit/pypy/jit/hintannotator/bookkeeper.py Sun Mar 18 11:42:26 2007 @@ -1,17 +1,22 @@ import py from pypy.tool.tls import tlsobject from pypy.tool.ansi_print import ansi_log +from pypy.rlib import objectmodel from pypy.objspace.flow.model import copygraph, SpaceOperation, Constant +from pypy.objspace.flow.model import Variable, Block, Link, FunctionGraph from pypy.annotation import model as annmodel from pypy.rpython.lltypesystem import lltype, lloperation from pypy.tool.algo.unionfind import UnionFind from pypy.translator.backendopt import graphanalyze +from pypy.translator.unsimplify import copyvar TLS = tlsobject() log = py.log.Producer("hintannotate") py.log.setconsumer("hintannotate", ansi_log) +TIMESHIFTMAP = {Constant(objectmodel._we_are_jitted): + Constant(1, lltype.Signed)} class GraphDesc(object): @@ -42,7 +47,12 @@ return self._cache[key] except KeyError: bk = self.bookkeeper - graph = copygraph(self.origgraph) + if bk.annotator.policy.look_inside_graph(self.origgraph): + graph = copygraph(self.origgraph, varmap=TIMESHIFTMAP) + log(str(graph)) + else: + graph = self.build_callback_graph(self.origgraph) + log.stub(str(graph)) graph.tag = 'timeshifted' try: etrafo = bk.annotator.exceptiontransformer @@ -55,9 +65,22 @@ graph.name = alt_name self._cache[key] = graph self.bookkeeper.annotator.translator.graphs.append(graph) - log(str(graph)) return graph + def build_callback_graph(self, graph): + args_v = [copyvar(None, v) for v in graph.getargs()] + v_res = copyvar(None, graph.getreturnvar()) + rtyper = self.bookkeeper.annotator.base_translator.rtyper # fish + fnptr = rtyper.getcallable(graph) + v_ptr = Constant(fnptr, lltype.typeOf(fnptr)) + newstartblock = Block(args_v) + newstartblock.operations.append( + SpaceOperation('direct_call', [v_ptr] + args_v, v_res)) + newgraph = FunctionGraph(graph.name, newstartblock) + newgraph.getreturnvar().concretetype = v_res.concretetype + newstartblock.closeblock(Link([v_res], newgraph.returnblock)) + return newgraph + class TsGraphCallFamily: def __init__(self, tsgraph): @@ -317,7 +340,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 +361,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/debug-jit/pypy/jit/hintannotator/model.py ============================================================================== --- pypy/branch/debug-jit/pypy/jit/hintannotator/model.py (original) +++ pypy/branch/debug-jit/pypy/jit/hintannotator/model.py Sun Mar 18 11:42:26 2007 @@ -7,7 +7,8 @@ cast_pointer direct_call indirect_call - int_is_true int_neg int_invert bool_not + int_is_true int_neg int_abs int_invert bool_not + int_neg_ovf int_abs_ovf uint_is_true cast_int_to_char cast_int_to_uint @@ -16,10 +17,13 @@ cast_bool_to_int ptr_nonzero ptr_iszero + is_early_constant """.split() BINARY_OPERATIONS = """int_add int_sub int_mul int_mod int_and int_rshift int_lshift int_floordiv int_xor int_or + int_add_ovf int_sub_ovf int_mul_ovf int_mod_ovf + int_floordiv_ovf int_lshift_ovf uint_add uint_sub uint_mul uint_mod uint_and uint_lshift uint_rshift uint_floordiv char_gt char_lt char_le char_ge char_eq char_ne @@ -83,6 +87,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) @@ -145,6 +154,11 @@ def is_green(self): return False + def clone(self): + c = object.__new__(self.__class__) + c.__dict__.update(self.__dict__) + return c + class SomeLLAbstractConstant(SomeLLAbstractValue): " color: dont know yet.. " @@ -182,11 +196,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): @@ -281,11 +295,8 @@ def deepunfreeze(hs): if hs.deepfrozen: - hs1 = annmodel.SomeObject() - hs1.__class__ = hs.__class__ - hs1.__dict__ = hs.__dict__.copy() - hs1.deepfrozen = False - hs = hs1 + hs = hs.clone() + hs.deepfrozen = False return hs # ____________________________________________________________ @@ -307,12 +318,18 @@ hs_concrete = SomeLLAbstractConstant(hs_v1.concretetype, {}) #hs_concrete.eager_concrete = True return hs_concrete + if hs_flags.const.get('deepfreeze', False): + hs_clone = hs_v1.clone() + hs_clone.deepfrozen = True + return hs_clone for name in ["reverse_split_queue", "global_merge_point"]: if hs_flags.const.get(name, False): return raise HintError("hint %s makes no sense on %r" % (hs_flags.const, hs_v1)) + def is_early_constant(hs_v1): + return SomeLLAbstractConstant(lltype.Bool, {}) def getfield(hs_v1, hs_fieldname): S = hs_v1.concretetype.TO @@ -336,20 +353,17 @@ args_hs = args_hs[:-1] assert hs_graph_list.is_constant() graph_list = hs_graph_list.const + if graph_list is None: + # cannot follow indirect calls to unknown targets + return variableoftype(hs_v1.concretetype.TO.RESULT) bookkeeper = getbookkeeper() - if not bookkeeper.annotator.policy.look_inside_graphs(graph_list): - # cannot follow - return cannot_follow_call(bookkeeper, graph_list, - (hs_v1,) + args_hs, - hs_v1.concretetype.TO.RESULT) - myorigin = bookkeeper.myorigin() myorigin.__class__ = CallOpOriginFlags # thud 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): @@ -378,10 +392,6 @@ if hs_flags.const.get('forget', False): assert isinstance(hs_c1, SomeLLAbstractConstant) return reorigin(hs_c1) - if hs_flags.const.get('deepfreeze', False): - return SomeLLAbstractConstant(hs_c1.concretetype, - hs_c1.origins, - deepfrozen = True) return SomeLLAbstractValue.hint(hs_c1, hs_flags) def direct_call(hs_f1, *args_hs): @@ -403,7 +413,7 @@ if not hasattr(fnobj, 'graph'): raise NotImplementedError("XXX call to externals or primitives") if not bookkeeper.annotator.policy.look_inside_graph(fnobj.graph): - return cannot_follow_call(bookkeeper, [fnobj.graph], args_hs, + return cannot_follow_call(bookkeeper, fnobj.graph, args_hs, lltype.typeOf(fnobj).RESULT) # recursive call from the entry point to itself: ignore them and @@ -618,11 +628,6 @@ # ____________________________________________________________ def handle_highlevel_operation(bookkeeper, ll_func, *args_hs): - if bookkeeper.annotator.policy.novirtualcontainer: - # "blue variables" disabled, we just return a red var all the time. - RESULT = bookkeeper.current_op_concretetype() - return variableoftype(RESULT) - # parse the oopspec and fill in the arguments operation_name, args = ll_func.oopspec.split('(', 1) assert args.endswith(')') @@ -639,6 +644,24 @@ args_hs.append(hs) # end of rather XXX'edly hackish parsing + if bookkeeper.annotator.policy.novirtualcontainer: + # "blue variables" disabled, we just return a red var all the time. + # Exception: an operation on a frozen container is constant-foldable. + RESULT = bookkeeper.current_op_concretetype() + if '.' in operation_name and args_hs[0].deepfrozen: + for hs_v in args_hs: + if not isinstance(hs_v, SomeLLAbstractConstant): + break + else: + myorigin = bookkeeper.myorigin() + d = newset({myorigin: True}, *[hs_c.origins + for hs_c in args_hs]) + return SomeLLAbstractConstant(RESULT, d, + eager_concrete = False, # probably + myorigin = myorigin) + return variableoftype(RESULT) + + # --- the code below is not used any more except by test_annotator.py --- if operation_name == 'newlist': from pypy.jit.hintannotator.vlist import oop_newlist handler = oop_newlist @@ -660,25 +683,24 @@ hs_result = handler(*args_hs) # which may raise NotImplementedError return hs_result -def cannot_follow_call(bookkeeper, graph_list, args_hs, RESTYPE): +def cannot_follow_call(bookkeeper, graph, args_hs, RESTYPE): # the policy prevents us from following the call - if not graph_list: # no known target, give up - return variableoftype(RESTYPE) - for graph in graph_list: - if not bookkeeper.is_pure_graph(graph): - # it's not calling pure graphs either, so the result - # is entierely unknown - return variableoftype(RESTYPE) + pure_call = bookkeeper.is_pure_graph(graph) # when calling pure graphs, consider the call as an operation. for hs in args_hs: if not isinstance(hs, SomeLLAbstractConstant): - return variableoftype(RESTYPE) - # if all arguments are SomeLLAbstractConstant, so can the result be. - origin = bookkeeper.myorigin() - d = newset({origin: True}, *[hs_c.origins for hs_c in args_hs]) - return SomeLLAbstractConstant(RESTYPE, d, - eager_concrete = False, # probably - myorigin = origin) + pure_call = False + break + if pure_call: + # if all arguments are SomeLLAbstractConstant, so can the result be. + myorigin = bookkeeper.myorigin() + d = newset({myorigin: True}, *[hs_c.origins for hs_c in args_hs]) + h_res = SomeLLAbstractConstant(RESTYPE, d, + eager_concrete = False, # probably + myorigin = myorigin) + else: + h_res = variableoftype(RESTYPE) + return h_res # ____________________________________________________________ # @@ -692,36 +714,49 @@ RESTYPE = getbookkeeper().current_op_concretetype() return SomeLLAbstractVariable(RESTYPE) -def const_unary(hs_c1): +def const_unary(llop, hs_c1): #XXX unsure hacks bk = getbookkeeper() origin = bk.myorigin() d = setadd(hs_c1.origins, origin) RESTYPE = bk.current_op_concretetype() - return SomeLLAbstractConstant(RESTYPE, d, - eager_concrete = hs_c1.eager_concrete, - myorigin = origin) + hs_res = SomeLLAbstractConstant(RESTYPE, d, + eager_concrete = hs_c1.eager_concrete, + myorigin = origin) + if hs_c1.is_constant(): + try: + hs_res.const = llop(RESTYPE, hs_c1.const) + except Exception: # XXX not too nice + pass + return hs_res -def const_binary((hs_c1, hs_c2)): +def const_binary(llop, (hs_c1, hs_c2)): #XXX unsure hacks bk = getbookkeeper() origin = bk.myorigin() d = newset(hs_c1.origins, hs_c2.origins, {origin: True}) RESTYPE = bk.current_op_concretetype() - return SomeLLAbstractConstant(RESTYPE, d, - eager_concrete = hs_c1.eager_concrete or - hs_c2.eager_concrete, - myorigin = origin) + hs_res = SomeLLAbstractConstant(RESTYPE, d, + eager_concrete = hs_c1.eager_concrete or + hs_c2.eager_concrete, + myorigin = origin) + if hs_c1.is_constant() and hs_c2.is_constant(): + try: + hs_res.const = llop(RESTYPE, hs_c1.const, hs_c2.const) + except Exception: # XXX not too nice + pass + return hs_res def setup(oplist, ValueCls, var_fn, ConstantCls, const_fn): for name in oplist: llop = getattr(lloperation.llop, name) - if not llop.sideeffects: + if not llop.sideeffects or llop.tryfold: if name not in ValueCls.__dict__: setattr(ValueCls, name, var_fn) - if llop.canfold: + if llop.canfold or llop.tryfold: if name not in ConstantCls.__dict__: - setattr(ConstantCls, name, const_fn) + setattr(ConstantCls, name, + lambda s, llop=llop: const_fn(llop, s)) setup(UNARY_OPERATIONS, SomeLLAbstractValue, var_unary, SomeLLAbstractConstant, const_unary) Modified: pypy/branch/debug-jit/pypy/jit/hintannotator/test/test_annotator.py ============================================================================== --- pypy/branch/debug-jit/pypy/jit/hintannotator/test/test_annotator.py (original) +++ pypy/branch/debug-jit/pypy/jit/hintannotator/test/test_annotator.py Sun Mar 18 11:42:26 2007 @@ -1,10 +1,11 @@ import py from pypy.translator.translator import TranslationContext, graphof from pypy.jit.hintannotator.annotator import HintAnnotator, HintAnnotatorPolicy +from pypy.jit.hintannotator.annotator import StopAtXPolicy from pypy.jit.hintannotator.bookkeeper import HintBookkeeper from pypy.jit.hintannotator.model import * from pypy.rpython.lltypesystem import lltype -from pypy.rlib.objectmodel import hint +from pypy.rlib.objectmodel import hint, we_are_jitted from pypy.annotation import model as annmodel from pypy.objspace.flow import model as flowmodel from pypy.translator.backendopt.inline import auto_inlining @@ -339,6 +340,16 @@ hs = hannotate(ll_function, [int, int], policy=P_OOPSPEC) assert isinstance(hs, SomeLLAbstractContainer) +def test_frozen_list(): + lst = [5, 7, 9] + def ll_function(x): + mylist = hint(lst, deepfreeze=True) + z = mylist[x] + hint(z, concrete=True) + return z + hs = hannotate(ll_function, [int], policy=P_OOPSPEC_NOVIRTUAL) + assert hs.is_green() + def test_simple_cast_pointer(): GCS1 = lltype.GcStruct('s1', ('x', lltype.Signed)) GCS2 = lltype.GcStruct('s2', ('sub', GCS1), ('y', lltype.Signed)) @@ -728,3 +739,145 @@ 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() + + +def test_indirect_sometimes_residual_pure_red_call(): + def h1(x): + return x-2 + def h2(x): + return x*4 + l = [h1, h2] + def f(n, x): + frozenl = hint(l, deepfreeze=True) + h = frozenl[n&1] + return h(x) + + P = StopAtXPolicy(h1) + P.oopspec = True + P.entrypoint_returns_red = False + hs, hannotator = hannotate(f, [int, int], policy=P, annotator=True) + assert not hs.is_green() + assert isinstance(hs, SomeLLAbstractConstant) + + tsgraph = graphof(hannotator.translator, h2) + hs = hannotator.binding(tsgraph.getargs()[0]) + assert not hs.is_green() + + +def test_indirect_sometimes_residual_red_call(): + class Stuff: + pass + stuff = Stuff() + def h1(x): + stuff.hello = 123 + return x-2 + def h2(x): + return x*4 + l = [h1, h2] + def f(n, x): + frozenl = hint(l, deepfreeze=True) + h = frozenl[n&1] + return h(x) + + P = StopAtXPolicy(h1) + P.oopspec = True + P.entrypoint_returns_red = False + hs, hannotator = hannotate(f, [int, int], policy=P, annotator=True) + assert not hs.is_green() + + tsgraph = graphof(hannotator.translator, h2) + hs = hannotator.binding(tsgraph.getargs()[0]) + assert not hs.is_green() + + +def test_indirect_sometimes_residual_pure_but_fixed_red_call(): + def h1(x): + return x-2 + def h2(x): + return x*4 + l = [h1, h2] + def f(n, x): + frozenl = hint(l, deepfreeze=True) + h = frozenl[n&1] + z = h(x) + hint(z, concrete=True) + return z + + P = StopAtXPolicy(h1) + P.oopspec = True + P.entrypoint_returns_red = False + hs, hannotator = hannotate(f, [int, int], policy=P, annotator=True) + assert hs.is_green() + + #tsgraph = graphof(hannotator.translator, h2) + #hs = hannotator.binding(tsgraph.getargs()[0]) + #assert hs.is_green() + + tsgraph = graphof(hannotator.translator, f) + hs = hannotator.binding(tsgraph.getargs()[0]) + assert hs.is_green() + hs = hannotator.binding(tsgraph.getargs()[1]) + assert hs.is_green() + +def test_ignore_nonjitted_path(): + def f(n): + if we_are_jitted(): + return 5 + else: + return n + hs = hannotate(f, [int]) + assert hs.is_green() + + def g(n): + if not we_are_jitted(): + return n + else: + return 5 + hs = hannotate(g, [int]) + assert hs.is_green() + + def g(n): + if not we_are_jitted(): + return n + else: + return 5 + hs = hannotate(g, [int], backendoptimize=True) + assert hs.is_green() Modified: pypy/branch/debug-jit/pypy/jit/timeshifter/hrtyper.py ============================================================================== --- pypy/branch/debug-jit/pypy/jit/timeshifter/hrtyper.py (original) +++ pypy/branch/debug-jit/pypy/jit/timeshifter/hrtyper.py Sun Mar 18 11:42:26 2007 @@ -21,7 +21,7 @@ from pypy.jit.hintannotator import container as hintcontainer 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): @@ -79,70 +79,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): - assert jitstate.resuming is None + def ll_finish_jitstate(jitstate, exceptiondesc, graphsigtoken): returnbox = rtimeshift.getreturnbox(jitstate) gv_ret = returnbox.getgenvar(jitstate) builder = jitstate.curbuilder @@ -151,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 @@ -166,10 +109,13 @@ self.portalstate = PortalState() self.portalstate.compile_more_functions = compile_more_functions - def specialize(self, origportalgraph=None, view=False): + def specialize(self, origportalgraph=None, view=False, + dont_simplify_again=False): """ Driver for running the timeshifter. """ + if not dont_simplify_again: + self.annotator.simplify() ## self.type_system.perform_normalizations(self) bk = self.annotator.bookkeeper ## bk.compute_after_normalization() @@ -185,30 +131,51 @@ # returns leaveportalgraph = entrygraph + self.contains_promotion = False + self.portal_contains_global_mp = False pending = [entrygraph] 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) 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)'?") + 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 for graph in self.annotator.translator.graphs 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) 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 @@ -261,6 +228,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 @@ -307,7 +275,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": @@ -334,7 +302,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() @@ -363,7 +331,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 @@ -403,7 +371,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) @@ -437,21 +405,32 @@ 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 + from pypy.jit.timeshifter.transform import HintGraphTransformer assert graph.startblock in self.annotator.annotated transformer = HintGraphTransformer(self.annotator, graph, 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): + 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) @@ -673,6 +652,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 @@ -687,12 +682,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,)) @@ -767,12 +762,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,)) @@ -942,11 +937,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) @@ -954,18 +948,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) @@ -1020,6 +1013,12 @@ [v_jitstate , c_index , c_TYPE], s_result) + def translate_op_is_early_constant(self, hop): + hs = hop.args_s[0] + if hs.is_green(): + return hop.inputconst(lltype.Bool, True) + return self.translate_op_is_constant(hop) + def translate_op_is_constant(self, hop): hs = hop.args_s[0] r_arg = self.getredrepr(originalconcretetype(hs)) @@ -1051,25 +1050,72 @@ [v_jitstate, var ], self.s_ConstOrVar) - def translate_op_split(self, hop): + def translate_op_split(self, hop, splitfn=rtimeshift.split, + reverse=False, + s_result=annmodel.s_Bool): + 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 rtimeshift.split_raisingop: + r_switch = lltype.Void + extra_r.insert(0, lltype.Void) + elif 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 rtimeshift.split_raisingop: + bk = self.rtyper.annotator.bookkeeper + excclass = vlist[2].value + exccdef = bk.getuniqueclassdef(excclass) + ll_exc = self.rtyper.exceptiondata.get_standard_ll_exc_instance( + self.rtyper, exccdef) + LL_EXC = lltype.typeOf(ll_exc) + c_excinstance = hop.inputconst(LL_EXC, ll_exc) + s_excinstance = annmodel.lltype_to_annotation(LL_EXC) + del args_s[1] # no v_switch in this case + del args_v[1] + args_s += [s_excinstance] + args_v += [c_excinstance] + elif 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()) + s_result) + + 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_split_raisingop(self, hop): + self.translate_op_split(hop, rtimeshift.split_raisingop, + s_result=annmodel.s_None) def translate_op_collect_split(self, hop): GREENS = [v.concretetype for v in hop.args_v[1:]] @@ -1125,6 +1171,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, @@ -1155,6 +1203,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:]] @@ -1163,12 +1212,15 @@ 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: - ll_finish_jitstate(finaljitstate, residualSigToken) + ll_finish_jitstate(finaljitstate, exceptiondesc, + residualSigToken) return self.translate_op_merge_point(hop, global_resumer = call_for_global_resuming) @@ -1181,11 +1233,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): @@ -1209,15 +1260,35 @@ [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): + def translate_op_oopspec_was_residual(self, hop): + 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, 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 = [] @@ -1275,13 +1346,40 @@ [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) assert isinstance(hop.r_result, GreenRepr) + + FUNC = hop.args_v[0].concretetype + calldesc = rtimeshift.CallDesc(self.RGenOp, FUNC.TO) + args_v = hop.args_v + args_s = [annmodel.lltype_to_annotation(v.concretetype) + for v in args_v] + s_result = annmodel.lltype_to_annotation(FUNC.TO.RESULT) + v_jitstate = hop.llops.getjitstate() + return hop.llops.genmixlevelhelpercall(calldesc.green_call, + [self.s_JITState] + args_s, + [v_jitstate ] + args_v, + s_result) + + def translate_op_green_call_noexc(self, hop): + for r_arg in hop.args_r: + assert isinstance(r_arg, GreenRepr) + assert isinstance(hop.r_result, GreenRepr) v = hop.genop('direct_call', hop.args_v, hop.r_result.lowleveltype) return v + def translate_op_green_indirect_call_noexc(self, hop): + for r_arg in hop.args_r[:-1]: + assert isinstance(r_arg, GreenRepr) + assert isinstance(hop.r_result, GreenRepr) + v = hop.genop('indirect_call', hop.args_v, hop.r_result.lowleveltype) + return v + def translate_op_red_call(self, hop): bk = self.annotator.bookkeeper v_jitstate = hop.llops.getjitstate() @@ -1292,11 +1390,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) @@ -1316,11 +1410,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) @@ -1330,52 +1420,57 @@ 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) 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) - - if exc: - hop.llops.genmixlevelhelpercall(self.fetch_global_excdata, - [self.s_JITState], [v_jitstate], - annmodel.s_None) + self.s_RedBox) 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 def translate_op_after_residual_call(self, hop): - v_jitstate = hop.llops.getjitstate() - 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)) - return hop.llops.genmixlevelhelpercall(rtimeshift.reshape, - [self.s_JITState, self.s_RedBox], - [v_jitstate , v_shape ], - annmodel.s_None) + dopts = hop.args_v[0].value + withexc = dopts['withexc'] + oop = dopts['oop'] + v_jitstate = hop.llops.getjitstate() + if withexc: + 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_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, @@ -1587,25 +1682,25 @@ 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) - boxcls = rvalue.ll_redboxcls(TYPE) - + def make_arg_redbox(jitstate, inputargs_gv, i): 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].genvar = inputargs_gv[i] + for fieldesc, j in redirected_fielddescs: + content_boxes[j] = fieldesc.makebox(None, 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 @@ -1617,7 +1712,7 @@ typedesc = self.gettypedesc() for fielddesc, _ in typedesc.redirected_fielddescs: FIELDTYPE = fielddesc.RESTYPE - argtypes += getredrepr(FIELDTYPE).residual_argtypes() + argtypes.append(FIELDTYPE) return argtypes def residual_args_collector(self): Modified: pypy/branch/debug-jit/pypy/jit/timeshifter/oop.py ============================================================================== --- pypy/branch/debug-jit/pypy/jit/timeshifter/oop.py (original) +++ pypy/branch/debug-jit/pypy/jit/timeshifter/oop.py Sun Mar 18 11:42:26 2007 @@ -4,8 +4,12 @@ from pypy.jit.timeshifter import rvalue, rtimeshift from pypy.translator.c import exceptiontransform from pypy.rlib.unroll import unrolling_iterable +from pypy.tool.sourcetools import func_with_new_name +class SegfaultException(Exception): + "Signals a run-time segfault detected at compile-time." + class Index: def __init__(self, n): self.n = n @@ -16,11 +20,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(')') @@ -32,10 +38,15 @@ self.argtuple = eval(args, d) # end of rather XXX'edly hackish parsing + OOPARGTYPES = [] arg_llsig_to_oopsig = {} for i, obj in enumerate(self.argtuple): if isinstance(obj, Index): arg_llsig_to_oopsig[obj.n] = i + OOPARG = FUNCTYPE.ARGS[obj.n] + else: + OOPARG = lltype.typeOf(obj) + OOPARGTYPES.append(OOPARG) self.residualargsources = [] for i in range(nb_args): @@ -79,18 +90,23 @@ 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: + oopargcheck = ll_func.oopargcheck # required if couldfold=True + # make a copy of the function, for specialization purposes + oopargcheck = func_with_new_name(oopargcheck, + 'argcheck_%s' % (method,)) ARGS = FUNCTYPE.ARGS residualargsources = self.residualargsources unrolling_ARGS = unrolling_iterable(ARGS) + unrolling_OOPARGS = unrolling_iterable(enumerate(OOPARGTYPES)) def do_call(jitstate, argboxes): + oopargs = () + for i, ARG in unrolling_OOPARGS: + v = rvalue.ll_getvalue(argboxes[i], ARG) + oopargs += (v,) + if not oopargcheck(*oopargs): + raise SegfaultException args = () j = 0 for ARG in unrolling_ARGS: @@ -99,7 +115,7 @@ else: argsrc = residualargsources[j] j = j + 1 - v = rvalue.ll_getvalue(argboxes[argsrc], ARG) + v = oopargs[argsrc] args += (v,) result = fnptr(*args) if FUNCTYPE.RESULT == lltype.Void: @@ -129,7 +145,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/debug-jit/pypy/jit/timeshifter/rcontainer.py ============================================================================== --- pypy/branch/debug-jit/pypy/jit/timeshifter/rcontainer.py (original) +++ pypy/branch/debug-jit/pypy/jit/timeshifter/rcontainer.py Sun Mar 18 11:42:26 2007 @@ -81,16 +81,22 @@ self.immutable = TYPE._hints.get('immutable', False) self.noidentity = TYPE._hints.get('noidentity', False) - if not TYPE._is_varsize(): - self.alloctoken = RGenOp.allocToken(TYPE) + fixsize = not TYPE._is_varsize() + if fixsize: + self.alloctoken = RGenOp.allocToken(TYPE) + self.null = self.PTRTYPE._defl() self.gv_null = RGenOp.constPrebuiltGlobal(self.null) self._compute_fielddescs(hrtyper) - self._define_devirtualize() + if self.immutable and self.noidentity: self._define_materialize() + + if fixsize: + self._define_devirtualize() + def _compute_fielddescs(self, hrtyper): RGenOp = hrtyper.RGenOp @@ -172,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 @@ -185,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): @@ -347,6 +354,7 @@ gv_default = None canbevirtual = False gcref = False + fieldnonnull = False def __init__(self, hrtyper, PTRTYPE, RESTYPE): RGenOp = hrtyper.RGenOp @@ -355,16 +363,20 @@ 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'): - self.virtualizable = T._hints.get('virtualizable', False) + # xxx hack for simple recursive cases + if not PTRTYPE.TO._hints.get('virtualizable', False): + self.virtualizable = T._hints.get('virtualizable', False) self.gcref = T._gckind == 'gc' if isinstance(T, lltype.ContainerType): if not T._is_varsize() or hasattr(T, 'll_newlist'): 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) @@ -372,9 +384,9 @@ self.gv_default = RGenOp.constPrebuiltGlobal(self.RESTYPE._defl()) if RESTYPE is lltype.Void and self.allow_void: pass # no redboxcls at all - elif self.virtualizable: - self.structdesc = StructTypeDesc(hrtyper, T) else: + if self.virtualizable: + self.structdesc = StructTypeDesc(hrtyper, T) self.redboxcls = rvalue.ll_redboxcls(RESTYPE) self.immutable = PTRTYPE.TO._hints.get('immutable', False) @@ -383,8 +395,6 @@ return True def makedefaultbox(self): - if self.virtualizable: - return self.structdesc.factory() return self.redboxcls(self.kind, self.gv_default) def makebox(self, jitstate, gvar): @@ -394,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): @@ -512,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): @@ -526,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) @@ -590,10 +604,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 @@ -612,9 +626,7 @@ 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): @@ -651,7 +663,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 @@ -671,8 +686,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, @@ -739,7 +757,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/debug-jit/pypy/jit/timeshifter/rtimeshift.py ============================================================================== --- pypy/branch/debug-jit/pypy/jit/timeshifter/rtimeshift.py (original) +++ pypy/branch/debug-jit/pypy/jit/timeshifter/rtimeshift.py Sun Mar 18 11:42:26 2007 @@ -8,12 +8,12 @@ from pypy.rpython.annlowlevel import cast_instance_to_base_ptr from pypy.rpython.annlowlevel import cast_base_ptr_to_instance -FOLDABLE_OPS = dict.fromkeys(lloperation.enum_foldable_ops()) - -FOLDABLE_GREEN_OPS = FOLDABLE_OPS.copy() +FOLDABLE_GREEN_OPS = dict.fromkeys(lloperation.enum_foldable_ops()) FOLDABLE_GREEN_OPS['getfield'] = None FOLDABLE_GREEN_OPS['getarrayitem'] = None +NULL_OBJECT = base_ptr_lltype()._defl() + debug_view = lloperation.llop.debug_view debug_print = lloperation.llop.debug_print debug_pdb = lloperation.llop.debug_pdb @@ -28,7 +28,8 @@ that can be passed around to low level helpers to inform op generation """ - + canraise = False + def _freeze_(self): return True @@ -40,8 +41,14 @@ self.ARGS = ARGS self.RESULT = RESULT self.result_kind = RGenOp.kindToken(RESULT) + self.whatever_result = RESULT._defl() self.redboxcls = rvalue.ll_redboxcls(RESULT) - self.canfold = opname in FOLDABLE_OPS + self.canfold = self.llop.canfold + self.tryfold = self.llop.tryfold + if self.tryfold and self.llop.canraise: + self.canraise = True + self.gv_True = RGenOp.constPrebuiltGlobal(True) + self.gv_False = RGenOp.constPrebuiltGlobal(False) def __getattr__(self, name): # .ARGx -> .ARGS[x] if name.startswith('ARG'): @@ -71,12 +78,27 @@ ARG0 = opdesc.ARG0 RESULT = opdesc.RESULT opname = opdesc.name - if opdesc.canfold and argbox.is_constant(): + if opdesc.tryfold and argbox.is_constant(): arg = rvalue.ll_getvalue(argbox, ARG0) - res = opdesc.llop(RESULT, arg) + if not opdesc.canraise: + res = opdesc.llop(RESULT, arg) + else: + try: + res = opdesc.llop(RESULT, arg) + except Exception: # shouldn't raise anything unexpected + res = opdesc.whatever_result + gv_flag = opdesc.gv_True + else: + gv_flag = opdesc.gv_False + jitstate.greens.append(gv_flag) return rvalue.ll_fromvalue(jitstate, res) gv_arg = argbox.getgenvar(jitstate) - genvar = jitstate.curbuilder.genop1(opdesc.opname, gv_arg) + if not opdesc.canraise: + genvar = jitstate.curbuilder.genop1(opdesc.opname, gv_arg) + else: + genvar, gv_raised = jitstate.curbuilder.genraisingop1(opdesc.opname, + gv_arg) + jitstate.greens.append(gv_raised) # for split_raisingop() return opdesc.redboxcls(opdesc.result_kind, genvar) def ll_gen2(opdesc, jitstate, argbox0, argbox1): @@ -84,28 +106,49 @@ ARG1 = opdesc.ARG1 RESULT = opdesc.RESULT opname = opdesc.name - if opdesc.canfold and argbox0.is_constant() and argbox1.is_constant(): + if opdesc.tryfold and argbox0.is_constant() and argbox1.is_constant(): # const propagate arg0 = rvalue.ll_getvalue(argbox0, ARG0) arg1 = rvalue.ll_getvalue(argbox1, ARG1) - res = opdesc.llop(RESULT, arg0, arg1) + if not opdesc.canraise: + res = opdesc.llop(RESULT, arg0, arg1) + else: + try: + res = opdesc.llop(RESULT, arg0, arg1) + except Exception: # shouldn't raise anything unexpected + res = opdesc.whatever_result + gv_flag = opdesc.gv_True + else: + gv_flag = opdesc.gv_False + jitstate.greens.append(gv_flag) return rvalue.ll_fromvalue(jitstate, res) gv_arg0 = argbox0.getgenvar(jitstate) gv_arg1 = argbox1.getgenvar(jitstate) - genvar = jitstate.curbuilder.genop2(opdesc.opname, gv_arg0, gv_arg1) + if not opdesc.canraise: + genvar = jitstate.curbuilder.genop2(opdesc.opname, gv_arg0, gv_arg1) + else: + genvar, gv_raised = jitstate.curbuilder.genraisingop2(opdesc.opname, + gv_arg0, gv_arg1) + jitstate.greens.append(gv_raised) # for split_raisingop() 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) - 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(): - res = getattr(rvalue.ll_getvalue(argbox, fielddesc.PTRTYPE), - fielddesc.fieldname) - return rvalue.ll_fromvalue(jitstate, res) + ptr = rvalue.ll_getvalue(argbox, fielddesc.PTRTYPE) + if ptr: # else don't constant-fold the segfault... + res = getattr(ptr, fielddesc.fieldname) + return rvalue.ll_fromvalue(jitstate, res) return argbox.op_getfield(jitstate, fielddesc) def ll_gensetfield(jitstate, fielddesc, destbox, valuebox): @@ -113,17 +156,20 @@ def ll_gengetsubstruct(jitstate, fielddesc, argbox): if argbox.is_constant(): - res = getattr(rvalue.ll_getvalue(argbox, fielddesc.PTRTYPE), - fielddesc.fieldname) - return rvalue.ll_fromvalue(jitstate, res) + ptr = rvalue.ll_getvalue(argbox, fielddesc.PTRTYPE) + if ptr: # else don't constant-fold - we'd get a bogus pointer + res = getattr(ptr, fielddesc.fieldname) + return rvalue.ll_fromvalue(jitstate, res) return argbox.op_getsubstruct(jitstate, fielddesc) def ll_gengetarrayitem(jitstate, deepfrozen, fielddesc, argbox, indexbox): if ((fielddesc.immutable or deepfrozen) and argbox.is_constant() and indexbox.is_constant()): array = rvalue.ll_getvalue(argbox, fielddesc.PTRTYPE) - res = array[rvalue.ll_getvalue(indexbox, lltype.Signed)] - return rvalue.ll_fromvalue(jitstate, res) + index = rvalue.ll_getvalue(indexbox, lltype.Signed) + if array and 0 <= index < len(array): # else don't constant-fold + res = array[index] + return rvalue.ll_fromvalue(jitstate, res) genvar = jitstate.curbuilder.genop_getarrayitem( fielddesc.arraytoken, argbox.getgenvar(jitstate), @@ -134,8 +180,10 @@ def ll_gengetarraysubstruct(jitstate, fielddesc, argbox, indexbox): if argbox.is_constant() and indexbox.is_constant(): array = rvalue.ll_getvalue(argbox, fielddesc.PTRTYPE) - res = array[rvalue.ll_getvalue(indexbox, lltype.Signed)] - return rvalue.ll_fromvalue(jitstate, res) + index = rvalue.ll_getvalue(indexbox, lltype.Signed) + if array and 0 <= index < len(array): # else don't constant-fold + res = array[index] + return rvalue.ll_fromvalue(jitstate, res) genvar = jitstate.curbuilder.genop_getarraysubstruct( fielddesc.arraytoken, argbox.getgenvar(jitstate), @@ -155,8 +203,9 @@ def ll_gengetarraysize(jitstate, fielddesc, argbox): if argbox.is_constant(): array = rvalue.ll_getvalue(argbox, fielddesc.PTRTYPE) - res = len(array) - return rvalue.ll_fromvalue(jitstate, res) + if array: # else don't constant-fold the segfault... + res = len(array) + return rvalue.ll_fromvalue(jitstate, res) genvar = jitstate.curbuilder.genop_getarraysize( fielddesc.arraytoken, argbox.getgenvar(jitstate)) @@ -167,14 +216,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 +250,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) @@ -208,7 +258,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): @@ -226,13 +276,16 @@ states_dic[key][index] = (frozen, newblock) if global_resumer is not None and global_resumer is not return_marker: + assert jitstate.get_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)" @@ -267,9 +320,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) @@ -292,7 +346,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: @@ -320,26 +374,72 @@ if exitgvar.is_const: return exitgvar.revealconst(lltype.Bool) else: - 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) - jitstate2 = jitstate.split(later_builder, resumepoint, list(greens_gv)) - 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): + exitgvar = switchredbox.getgenvar(jitstate) + if exitgvar.is_const: + return exitgvar.revealconst(lltype.Bool) + else: + return split_nonconstantcase(jitstate, exitgvar, resumepoint, + ptrbox, reverse, list(greens_gv)) + +def split_nonconstantcase(jitstate, exitgvar, resumepoint, + ptrbox, reverse, greens_gv, ll_evalue=NULL_OBJECT): + 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: + ok = ptrbox.learn_nonzeroness(jitstate, + nonzeroness = node.answer ^ reverse) + assert ok + return node.answer + later_gv = jitstate.get_locals_gv() # alive gvs on the later path + if ll_evalue: # special case - we want jump_if_true in split_raisingop + later_builder = jitstate.curbuilder.jump_if_true(exitgvar, later_gv) + else: + later_builder = jitstate.curbuilder.jump_if_false(exitgvar, later_gv) + memo = rvalue.copy_memo() + jitstate2 = jitstate.split(later_builder, resumepoint, greens_gv, memo) + if ptrbox is not None: + ok = ptrbox.learn_nonzeroness(jitstate, nonzeroness = True ^ reverse) + assert ok + try: + copybox = memo.boxes[ptrbox] + except KeyError: + pass + else: + ok = copybox.learn_nonzeroness(jitstate2, nonzeroness = reverse) + assert ok + if ll_evalue: + jitstate2.residual_ll_exception(ll_evalue) + if resuming is None: + node = jitstate.promotion_path + jitstate2.promotion_path = PromotionPathNo(node) + jitstate .promotion_path = PromotionPathYes(node) + return True + +def split_raisingop(jitstate, resumepoint, ll_evalue, *greens_gv): + exitgvar = jitstate.greens.pop() # pushed here by the raising op + if exitgvar.is_const: + gotexc = exitgvar.revealconst(lltype.Bool) + else: + gotexc = not split_nonconstantcase(jitstate, exitgvar, resumepoint, + None, False, list(greens_gv), + ll_evalue) + if gotexc: + jitstate.residual_ll_exception(ll_evalue) 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) 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) @@ -382,7 +482,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 @@ -394,17 +494,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) @@ -437,6 +533,15 @@ def setexcvaluebox(jitstate, box): jitstate.exc_value_box = box +def setexception(jitstate, typebox, valuebox): + ok1 = typebox .learn_nonzeroness(jitstate, True) + ok2 = valuebox.learn_nonzeroness(jitstate, True) + assert ok1 & ok2 # probably... maybe it's false but it would be + # nice to see what kind of contrieved code can + # make this fail :-) + jitstate.exc_type_box = typebox + jitstate.exc_value_box = valuebox + def save_return(jitstate): # add 'jitstate' to the chain of return-jitstates jitstate.pause() @@ -444,6 +549,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) @@ -458,11 +566,24 @@ self.result_kind = RGenOp.kindToken(FUNCTYPE.RESULT) # xxx what if the result is virtualizable? self.redboxbuilder = rvalue.ll_redboxbuilder(FUNCTYPE.RESULT) + whatever_return_value = FUNCTYPE.RESULT._defl() + def green_call(jitstate, fnptr, *args): + try: + result = fnptr(*args) + except Exception, e: + jitstate.residual_exception(e) + result = whatever_return_value + return result + self.green_call = green_call def _freeze_(self): 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 @@ -471,12 +592,39 @@ 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: + assert gv_flags is None + 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): @@ -538,13 +686,13 @@ 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 - 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): @@ -596,7 +744,7 @@ class PromotionDesc: - __metatype__ = cachedtype + __metaclass__ = cachedtype def __init__(self, ERASED, hrtyper): state = hrtyper.portalstate @@ -621,6 +769,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 @@ -629,6 +778,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: @@ -640,7 +793,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, @@ -649,9 +803,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)) @@ -659,7 +822,6 @@ return True else: assert jitstate.promotion_path is None - resuming = jitstate.resuming if resuming.mergesleft != 0: default_builder.pause_writing([]) return True @@ -679,15 +841,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 - jitstate.resuming = None + promotebox.setgenvar(promotenode.gv_value) + jitstate.clear_resuming() 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 @@ -696,11 +859,15 @@ # ____________________________________________________________ class BaseDispatchQueue(object): + resuming = None def __init__(self): 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 +878,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 @@ -761,6 +928,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, @@ -829,20 +1004,32 @@ class JITState(object): + _attrs_ = """curbuilder frame + exc_type_box exc_value_box + greens + returnbox + promotion_path + resumepoint resuming + next + virtualizables + shape_place + forced_boxes + 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, - 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. @@ -855,8 +1042,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) @@ -868,7 +1054,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 @@ -902,12 +1087,15 @@ if virtualizables: builder = self.curbuilder memo = rvalue.make_vrti_memo() - memo.bitcount = 0 + 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: @@ -928,29 +1116,35 @@ 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) + + 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: - 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: @@ -1012,7 +1206,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: @@ -1027,18 +1231,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) @@ -1055,7 +1263,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 @@ -1094,10 +1302,12 @@ 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 if resuming is not None: resuming.leave_call(dispatchqueue) jitstate = return_chain @@ -1109,9 +1319,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 @@ -1123,10 +1333,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: @@ -1139,16 +1350,17 @@ 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 - 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/debug-jit/pypy/jit/timeshifter/rvalue.py ============================================================================== --- pypy/branch/debug-jit/pypy/jit/timeshifter/rvalue.py (original) +++ pypy/branch/debug-jit/pypy/jit/timeshifter/rvalue.py Sun Mar 18 11:42:26 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,37 @@ 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): + ok = True + if nonzeroness: + if self.is_constant(): + ok = self.known_nonzero # not ok if constant zero + else: + self.known_nonzero = True + else: + if self.is_constant(): + ok = not self.genvar.revealconst(llmemory.Address) # ok if null + else: + gv_null = jitstate.curbuilder.rgenop.genzeroconst(self.kind) + self.setgenvar_hint(gv_null, known_nonzero=False) + return ok + def __repr__(self): if not self.genvar and self.content is not None: return '' % (self.content,) @@ -188,6 +215,7 @@ return RedBox.__repr__(self) def op_getfield(self, jitstate, fielddesc): + self.learn_nonzeroness(jitstate, True) if self.content is not None: box = self.content.op_getfield(jitstate, fielddesc) if box is not None: @@ -199,6 +227,7 @@ return box def op_setfield(self, jitstate, fielddesc, valuebox): + self.learn_nonzeroness(jitstate, True) gv_ptr = self.genvar if gv_ptr: fielddesc.generate_set(jitstate, gv_ptr, @@ -208,6 +237,7 @@ self.content.op_setfield(jitstate, fielddesc, valuebox) def op_getsubstruct(self, jitstate, fielddesc): + self.learn_nonzeroness(jitstate, True) gv_ptr = self.genvar if gv_ptr: return fielddesc.generate_getsubstruct(jitstate, gv_ptr) @@ -228,7 +258,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 +293,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 +317,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: @@ -309,6 +352,9 @@ def is_constant_equal(self, box): return False + def is_constant_nullptr(self): + return False + class FrozenConst(FrozenValue): @@ -403,14 +449,19 @@ 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 + 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 if isinstance(box.content, VirtualContainer): - raise DontMerge + raise DontMerge # XXX recursive data structures? return match def unfreeze(self, incomingvarboxes, memo): @@ -419,20 +470,28 @@ 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): - raise DontMerge + raise DontMerge # XXX recursive data structures? return match 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 @@ -454,7 +513,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/debug-jit/pypy/jit/timeshifter/test/test_exception.py ============================================================================== --- pypy/branch/debug-jit/pypy/jit/timeshifter/test/test_exception.py (original) +++ pypy/branch/debug-jit/pypy/jit/timeshifter/test/test_exception.py Sun Mar 18 11:42:26 2007 @@ -122,3 +122,32 @@ 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) + + def test_not_segregated_malloc_exception_path(self): + def help(l, x): + l.append("x is %s" % chr(x)) + + def ll_function(x): + l = [] + 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/debug-jit/pypy/jit/timeshifter/test/test_portal.py ============================================================================== --- pypy/branch/debug-jit/pypy/jit/timeshifter/test/test_portal.py (original) +++ pypy/branch/debug-jit/pypy/jit/timeshifter/test/test_portal.py Sun Mar 18 11:42:26 2007 @@ -2,10 +2,10 @@ 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 +from pypy.objspace.flow.model import summary from pypy.rlib.objectmodel import hint from pypy.jit.codegen.llgraph.rgenop import RGenOp as LLRGenOp @@ -64,12 +64,8 @@ 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() + #if conftest.option.view and self.small: + # t.view() self.postprocess_timeshifting() self.readportalgraph = self.hrtyper.readportalgraph @@ -90,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 @@ -338,11 +336,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) @@ -443,3 +443,77 @@ 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) + + 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/debug-jit/pypy/jit/timeshifter/test/test_promotion.py ============================================================================== --- pypy/branch/debug-jit/pypy/jit/timeshifter/test/test_promotion.py (original) +++ pypy/branch/debug-jit/pypy/jit/timeshifter/test/test_promotion.py Sun Mar 18 11:42:26 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): @@ -275,3 +276,133 @@ 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 + + def test_raise_result_mixup(self): + 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 + + 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 + + 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) + + 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/debug-jit/pypy/jit/timeshifter/test/test_timeshift.py ============================================================================== --- pypy/branch/debug-jit/pypy/jit/timeshifter/test/test_timeshift.py (original) +++ pypy/branch/debug-jit/pypy/jit/timeshifter/test/test_timeshift.py Sun Mar 18 11:42:26 2007 @@ -1,19 +1,21 @@ import py +import sys from pypy.translator.translator import TranslationContext, graphof from pypy.jit.hintannotator.annotator import HintAnnotator, HintAnnotatorPolicy +from pypy.jit.hintannotator.annotator import StopAtXPolicy from pypy.jit.hintannotator.bookkeeper import HintBookkeeper from pypy.jit.hintannotator.model import * from pypy.jit.timeshifter.hrtyper import HintRTyper, originalconcretetype 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.rlib.rarithmetic import ovfcheck from pypy.rpython.annlowlevel import PseudoHighLevelCallable 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 @@ -104,14 +106,12 @@ # make the timeshifted graphs hrtyper = HintRTyper(ha, rtyper, self.RGenOp) - hrtyper.specialize(view = conftest.option.view and self.small) - + hrtyper.specialize(view = conftest.option.view and self.small, + dont_simplify_again = True) fresh_jitstate = hrtyper.ll_fresh_jitstate finish_jitstate = hrtyper.ll_finish_jitstate + exceptiondesc = hrtyper.exceptiondesc t = rtyper.annotator.translator - for graph in ha.translator.graphs: - checkgraph(graph) - t.graphs.append(graph) # make an interface to the timeshifted graphs: # @@ -185,11 +185,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)) @@ -225,9 +225,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) @@ -272,12 +272,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: @@ -352,21 +352,6 @@ assert count == expected_count -class StopAtXPolicy(HintAnnotatorPolicy): - def __init__(self, *funcs): - HintAnnotatorPolicy.__init__(self, novirtualcontainer=True, - oopspec=True) - self.funcs = funcs - - def look_inside_graph(self, graph): - try: - if graph.func in self.funcs: - return False - except AttributeError: - pass - return True - - class TestTimeshift(TimeshiftingTests): def test_simple_fixed(self): @@ -785,14 +770,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 +793,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 +801,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}) @@ -1140,6 +1125,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): @@ -1292,3 +1281,314 @@ 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) + + 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 + 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, 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 -1111 + + 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 == -1111 + 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) + + def test_constant_indirect_red_call(self): + def h1(x): + return x-2 + def h2(x): + return x*4 + l = [h1, h2] + def f(n, x): + frozenl = hint(l, deepfreeze=True) + h = frozenl[n&1] + return h(x) + + P = StopAtXPolicy() + res = self.timeshift(f, [7, 3], [0], policy=P) + assert res == f(7,3) + self.check_insns({'int_mul': 1}) + res = self.timeshift(f, [4, 113], [0], policy=P) + assert res == f(4,113) + self.check_insns({'int_sub': 1}) + + def test_indirect_sometimes_residual_pure_red_call(self): + def h1(x): + return x-2 + def h2(x): + return x*4 + l = [h1, h2] + def f(n, x): + hint(None, global_merge_point=True) + hint(n, concrete=True) + frozenl = hint(l, deepfreeze=True) + h = frozenl[n&1] + return h(x) + + P = StopAtXPolicy(h1) + P.oopspec = True + res = self.timeshift(f, [7, 3], [], policy=P) + assert res == f(7,3) + self.check_insns({'int_mul': 1}) + res = self.timeshift(f, [4, 113], [], policy=P) + assert res == f(4,113) + self.check_insns({'direct_call': 1}) + + def test_indirect_sometimes_residual_pure_but_fixed_red_call(self): + def h1(x): + return x-2 + def h2(x): + return x*4 + l = [h1, h2] + def f(n, x): + hint(None, global_merge_point=True) + frozenl = hint(l, deepfreeze=True) + h = frozenl[n&1] + z = h(x) + hint(z, concrete=True) + return z + + P = StopAtXPolicy(h1) + P.oopspec = True + res = self.timeshift(f, [7, 3], [], policy=P) + assert res == f(7,3) + self.check_insns({}) + res = self.timeshift(f, [4, 113], [], policy=P) + assert res == f(4,113) + self.check_insns({}) + + def test_red_int_add_ovf(self): + def f(n, m): + try: + return ovfcheck(n + m) + except OverflowError: + return -42 + + res = self.timeshift(f, [100, 20]) + assert res == 120 + self.check_insns(int_add_ovf=1) + res = self.timeshift(f, [sys.maxint, 1]) + assert res == -42 + self.check_insns(int_add_ovf=1) + + def test_green_int_add_ovf(self): + def f(n, m): + try: + res = ovfcheck(n + m) + except OverflowError: + res = -42 + hint(res, concrete=True) + return res + + res = self.timeshift(f, [100, 20]) + assert res == 120 + self.check_insns({}) + res = self.timeshift(f, [sys.maxint, 1]) + assert res == -42 + self.check_insns({}) + + def test_nonzeroness_assert_while_compiling(self): + class X: + pass + class Y: + pass + + def g(x, y): + if y.flag: + return x.value + else: + return -7 + + def h(n): + if n: + x = X() + x.value = n + return x + else: + return None + + y = Y() + + def f(n): + y.flag = True + g(h(n), y) + y.flag = False + return g(h(0), y) + + res = self.timeshift(f, [42], policy=P_NOVIRTUAL) + assert res == -7 + + def test_segfault_while_compiling(self): + class X: + pass + class Y: + pass + + def g(x, y): + x = hint(x, deepfreeze=True) + if y.flag: + return x.value + else: + return -7 + + def h(n): + if n: + x = X() + x.value = n + return x + else: + return None + + y = Y() + + def f(n): + y.flag = True + g(h(n), y) + y.flag = False + return g(h(0), y) + + res = self.timeshift(f, [42], policy=P_NOVIRTUAL) + assert res == -7 Modified: pypy/branch/debug-jit/pypy/jit/timeshifter/test/test_vdict.py ============================================================================== --- pypy/branch/debug-jit/pypy/jit/timeshifter/test/test_vdict.py (original) +++ pypy/branch/debug-jit/pypy/jit/timeshifter/test/test_vdict.py Sun Mar 18 11:42:26 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/debug-jit/pypy/jit/timeshifter/test/test_virtualizable.py ============================================================================== --- pypy/branch/debug-jit/pypy/jit/timeshifter/test/test_virtualizable.py (original) +++ pypy/branch/debug-jit/pypy/jit/timeshifter/test/test_virtualizable.py Sun Mar 18 11:42:26 2007 @@ -419,36 +419,57 @@ 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 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 @@ -1208,3 +1229,133 @@ assert res == 42 self.check_oops(newlist=0) + + def test_recursive(self): + + class XY(object): + _virtualizable_ = True + + def __init__(self, x, back): + self.x = x + self.back = back + + def f(xy): + return xy.x + + def main(x, y): + xyy = XY(y, None) + xy = XY(x, xyy) + return f(xy) + + res = self.timeshift_from_portal(main, f, [20, 22], policy=P_OOPSPEC) + assert res == 20 + self.check_insns(getfield=0) + + + def test_recursive_load_from(self): + + class W(object): + def __init__(self, xy): + self.xy = xy + + class XY(object): + _virtualizable_ = True + + def __init__(self, x, back): + self.x = x + self.back = back + + def f(w): + xy = w.xy + return xy.x + + def main(x, y): + xyy = XY(y, None) + xy = XY(x, xyy) + return f(W(xy)) + + res = self.timeshift_from_portal(main, f, [20, 22], policy=P_OOPSPEC) + assert res == 20 + + def test_string_in_virtualizable(self): + class S(object): + def __init__(self, s): + self.s = s + + class XY(object): + _virtualizable_ = True + + def __init__(self, x, s): + self.x = x + self.s = s + def g(xy): + xy.x = 19 + len(xy.s.s) + + def f(x, n): + hint(None, global_merge_point=True) + s = S('2'*n) + xy = XY(x, s) + g(xy) + return xy.s + + def main(x, y): + return int(f(x, y).s) + + 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_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 + res = h(v, n) + return res - v.v.pop() + + P = StopAtXPolicy(g) + + 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/debug-jit/pypy/jit/timeshifter/test/test_vlist.py ============================================================================== --- pypy/branch/debug-jit/pypy/jit/timeshifter/test/test_vlist.py (original) +++ pypy/branch/debug-jit/pypy/jit/timeshifter/test/test_vlist.py Sun Mar 18 11:42:26 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,77 @@ 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({}) + + def test_frozen_list(self): + lst = [5, 7, 9] + def ll_function(x): + mylist = hint(lst, deepfreeze=True) + z = mylist[x] + hint(z, concrete=True) + return z + + res = self.timeshift(ll_function, [1], policy=P_OOPSPEC) + assert res == 7 + self.check_insns({}) + + def test_frozen_list_indexerror(self): + lst = [5, 7, 9] + def ll_function(x): + mylist = hint(lst, deepfreeze=True) + try: + z = mylist[x] + except IndexError: + return -42 + hint(z, concrete=True) + return z + + res = self.timeshift(ll_function, [4], policy=P_OOPSPEC) + assert res == -42 + self.check_insns({}) + + def test_bogus_index_while_compiling(self): + class Y: + pass + + def g(lst, y, n): + lst = hint(lst, deepfreeze=True) + if y.flag: + return lst[n] + else: + return -7 + + y = Y() + lst1 = [3, 4, 5] + lst2 = [6, 2] + + def h(i): + if i == 1: return lst1 + elif i == 2: return lst2 + else: return [] + + def f(n): + y.flag = n < 3 + g(h(1), y, n) + y.flag = n < 2 + return g(h(2), y, n) + + res = self.timeshift(f, [2], [0], policy=P_OOPSPEC) + assert res == -7 Modified: pypy/branch/debug-jit/pypy/jit/timeshifter/transform.py ============================================================================== --- pypy/branch/debug-jit/pypy/jit/timeshifter/transform.py (original) +++ pypy/branch/debug-jit/pypy/jit/timeshifter/transform.py Sun Mar 18 11:42:26 2007 @@ -3,12 +3,11 @@ from pypy.annotation import model as annmodel from pypy.jit.hintannotator import model as hintmodel from pypy.jit.hintannotator.model import originalconcretetype -from pypy.rpython.lltypesystem import lltype, llmemory +from pypy.rpython.lltypesystem import lltype, llmemory, lloperation from pypy.rpython.rmodel import inputconst 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): @@ -36,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 @@ -53,10 +54,12 @@ return self.raise_analyzer.analyze(op) def transform(self): + self.simplify_operations() self.compute_merge_points() self.insert_save_return() self.insert_splits() self.split_after_calls() + self.split_after_raisingop() self.handle_hints() self.insert_merge_points() self.insert_enter_frame() @@ -109,6 +112,33 @@ 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 + # 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] if originalconcretetype(hs_res) is lltype.Void: @@ -244,51 +274,57 @@ if not hs_switch.is_green(): self.insert_split_handling(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. + """ + 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_bool_var(block, block.exitswitch) + 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: @@ -457,11 +493,19 @@ args_v = spaceop.args[1:] elif spaceop.opname == 'indirect_call': graphs = spaceop.args[-1].value + if graphs is None: + return # cannot follow at all args_v = spaceop.args[1:-1] else: raise AssertionError(spaceop.opname) - if not self.hannotator.policy.look_inside_graphs(graphs): - return # cannot follow this call + # if the graph - or all the called graphs - are marked as "don't + # follow", directly return None as a special case. (This is only + # an optimization for the indirect_call case.) + for graph in graphs: + if self.hannotator.policy.look_inside_graph(graph): + break + else: + return for graph in graphs: tsgraph = self.timeshifted_graph_of(graph, args_v, spaceop.result) yield graph, tsgraph @@ -470,32 +514,40 @@ if spaceop.opname == 'direct_call': c_func = spaceop.args[0] fnobj = c_func.value._obj + if hasattr(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 + hs_result = self.hannotator.binding(spaceop.result) + if (hs_result.is_green() and + hs_result.concretetype is not lltype.Void): + return 'green', self.can_raise(spaceop) + return 'oopspec', self.can_raise(spaceop) 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 @@ -525,7 +577,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 @@ -534,7 +587,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': @@ -546,8 +599,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: @@ -573,17 +625,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, @@ -594,35 +649,74 @@ 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)) + blockset[conversionblock] = False + # 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)) + blockset[resumeblock] = True # reachable from outside if nonconstantblock is not None: - v_res, nonconstantblock2 = self.handle_residual_call_details( + nonconstantblock.recloseblock(Link(linkargs, nextblock)) + v_res = self.handle_residual_call_details( nonconstantblock, 0, op, - color, preserve_res = False) + color, blockset, preserve_res = + (color != 'gray'), + withexc=withexc) - 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 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): + 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 + 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)) + blockset = { block: True, + nextblock: False, + residualblock: False } + self.handle_after_residual_call_details( + residualblock, 0, [], blockset, oop=True, + withexc=True) + SSA_to_SSI(blockset, self.hannotator) + def handle_vable_call(self, block, pos): op = block.operations[pos] assert op.opname == 'direct_call' @@ -638,80 +732,46 @@ args = op.args[1:] args.insert(1, Constant(name, lltype.Void)) block.operations[pos] = SpaceOperation(opname, args, op.result) - - 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 + + def handle_rpyexc_raise_call(self, block, pos): op = block.operations[pos] assert op.opname == 'direct_call' - op.opname = 'green_call' + op.opname = 'rpyexc_raise' + op.args = op.args[1:] - def handle_yellow_call(self, block, pos): + def handle_green_call(self, block, pos, withexc=False): + # an all-green function that we can just call 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' + if op.opname == 'indirect_call': + if withexc: + op.args.pop() # remove the graph list + op.opname = 'green_call' + else: + op.opname = 'green_indirect_call_noexc' + else: + if withexc: + op.opname = 'green_call' + else: + op.opname = 'green_call_noexc' - SSA_to_SSI({block: True, - postblock: False}, self.hannotator) + 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) + 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_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=[]): + blockset, withexc, + preserve_res=True): if op.opname == 'direct_call': args_v = op.args[1:] elif op.opname == 'indirect_call': @@ -723,29 +783,108 @@ 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) - reshape_index = len(newops) - 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 + self.handle_after_residual_call_details(block, pos, + newops, blockset, + withexc) + return v_res - reds, greens = self.sort_by_color(link.args) + + 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], + resulttype=lltype.Signed, red=True) + 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_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_t.args) self.genop(block, 'save_locals', reds) - v_finished_flag = self.genop(block, 'promote', [v_shape], + + 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 + # if there is no global merge point, this 'promote' will actually + # always see a constant red box + 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) + + 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) + + # __________ raising ops (xxx_ovf & co) __________ + + def split_after_raisingop(self): + for block in list(self.graph.iterblocks()): + for i in range(len(block.operations)-1, -1, -1): + op = block.operations[i] + try: + opdesc = getattr(lloperation.llop, op.opname) + except AttributeError: + continue + if opdesc.tryfold and not opdesc.canfold and opdesc.canraise: + self.handle_raisingop(block, i, opdesc) + + def handle_raisingop(self, block, i, opdesc): + op = block.operations[i] + if self.hannotator.binding(op.result).is_green(): + # case not really well supported + v_red = Variable(op.result) + v_red.concretetype = op.result.concretetype + hs_red = hintmodel.SomeLLAbstractVariable(op.result.concretetype) + self.hannotator.setbinding(v_red, hs_red) + spaceop = SpaceOperation('revealconst', [v_red], op.result) + op.result = v_red + i += 1 + block.operations.insert(i, spaceop) - - return v_res, nextblock + link = split_block(self.hannotator, block, i+1) + + reds, greens = self.sort_by_color(link.args) + self.genop(block, 'save_locals', reds) + resumepoint = self.get_resume_point(link.target) + c_resumepoint = inputconst(lltype.Signed, resumepoint) + assert len(opdesc.canraise) == 1 # for now + c_canraise = inputconst(lltype.Void, opdesc.canraise[0]) + self.genop(block, 'split_raisingop', + [self.c_dummy, c_resumepoint, c_canraise] + greens) # __________ hints __________ @@ -785,6 +924,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) Modified: pypy/branch/debug-jit/pypy/jit/timeshifter/vdict.py ============================================================================== --- pypy/branch/debug-jit/pypy/jit/timeshifter/vdict.py (original) +++ pypy/branch/debug-jit/pypy/jit/timeshifter/vdict.py Sun Mar 18 11:42:26 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/debug-jit/pypy/jit/timeshifter/vlist.py ============================================================================== --- pypy/branch/debug-jit/pypy/jit/timeshifter/vlist.py (original) +++ pypy/branch/debug-jit/pypy/jit/timeshifter/vlist.py Sun Mar 18 11:42:26 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 @@ -72,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 @@ -151,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): @@ -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, @@ -217,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 @@ -239,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): @@ -284,19 +286,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 @@ -356,7 +362,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) @@ -365,7 +371,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 Modified: pypy/branch/debug-jit/pypy/module/_stackless/coroutine.py ============================================================================== --- pypy/branch/debug-jit/pypy/module/_stackless/coroutine.py (original) +++ pypy/branch/debug-jit/pypy/module/_stackless/coroutine.py Sun Mar 18 11:42:26 2007 @@ -212,8 +212,11 @@ # ("execute_frame", self, executioncontext, returns=w_exitvalue) chain = resume_state_create(chain, "execute_frame", frame, ec) code = frame.pycode.co_code - # ("dispatch", self, co_code, ec, returns=w_result) + # ("dispatch", self, co_code, ec, returns=next_instr) chain = resume_state_create(chain, "dispatch", frame, code, ec) + # ("handle_bytecode", self, co_code, ec, returns=next_instr) + chain = resume_state_create(chain, "handle_bytecode", frame, code, + ec) instr = frame.last_instr opcode = ord(code[instr]) assert opcode == pythonopcode.opmap['CALL_FUNCTION'] Modified: pypy/branch/debug-jit/pypy/module/pypyjit/interp_jit.py ============================================================================== --- pypy/branch/debug-jit/pypy/module/pypyjit/interp_jit.py (original) +++ pypy/branch/debug-jit/pypy/module/pypyjit/interp_jit.py Sun Mar 18 11:42:26 2007 @@ -7,89 +7,141 @@ pypy/jit/* """ import py +import sys +from pypy.tool.pairtype import extendabletype +from pypy.rlib.rarithmetic import r_uint, intmask +from pypy.rlib.objectmodel import hint, _is_early_constant import pypy.interpreter.pyopcode # for side-effects -from pypy.interpreter.pycode import PyCode +from pypy.interpreter.eval import Frame +from pypy.interpreter.pycode import PyCode, CO_VARARGS, CO_VARKEYWORDS from pypy.interpreter.pyframe import PyFrame -from pypy.tool.sourcetools import func_with_new_name +from pypy.interpreter.function import Function +from pypy.interpreter.pyopcode import Return, Yield +Frame._virtualizable_ = True PyCode.jit_enable = False # new default attribute super_dispatch = PyFrame.dispatch -super_dispatch_bytecode = PyFrame.dispatch_bytecode +class __extend__(PyFrame): -def setup(): - # create dispatch_jit() as a copy of dispatch() in which - # dispatch_bytecode() has been manually inlined. - # Do this with py.code.Source manipulations for now. - src = py.code.Source(super_dispatch) - CALL_SITE = 'w_result = self.dispatch_bytecode(co_code, next_instr, ec)' - for i, line in enumerate(src): - if line.strip() == CALL_SITE: - break - else: - raise Exception("fix me! call to dispatch_bytecode() not found") - - indent = line[:line.index(CALL_SITE)] - - src2 = py.code.Source(PyFrame.dispatch_bytecode) - hdr = src2[0].strip() - assert hdr == 'def dispatch_bytecode(self, co_code, next_instr, ec):' - src2 = src2[1:].deindent().indent(indent) - #print src2 - - src3 = py.code.Source('%s\n%s\n%s\n' % (src[1:i], src2, src[i+1:])) - - src3 = src3.putaround( - "def maker(BYTECODE_TRACE_ENABLED):\n" # no comma here - " def dispatch_jit(self, co_code, next_instr, ec):\n", - "#\n" # for indentation :-( - " return dispatch_jit") - - #print src3 - d = {} - exec src3.compile() in super_dispatch.func_globals, d - PyFrame.dispatch_jit = d['maker'](BYTECODE_TRACE_ENABLED=False) - - class __extend__(PyFrame): - - def dispatch(self, co_code, next_instr, ec): - if self.pycode.jit_enable: - return self.dispatch_jit(co_code, next_instr, ec) - else: - return super_dispatch(self, co_code, next_instr, ec) - -def setup2(): - # TEMPORARY: only patches dispatch_bytecode. - # make a copy of dispatch_bytecode in which BYTECODE_TRACE_ENABLED is False - # (hack hack!) - src2 = py.code.Source(PyFrame.dispatch_bytecode) - hdr = src2[0].strip() - assert hdr == 'def dispatch_bytecode(self, co_code, next_instr, ec):' - src2 = src2[1:].deindent() - - src2 = src2.putaround( - "def maker(BYTECODE_TRACE_ENABLED):\n" # no comma here - " def dispatch_jit(self, co_code, next_instr, ec):\n", - "#\n" # for indentation :-( - " return dispatch_jit") - #print src2 - d = {} - exec src2.compile() in super_dispatch.func_globals, d - PyFrame.dispatch_jit = d['maker'](BYTECODE_TRACE_ENABLED=False) - - class __extend__(PyFrame): - - def dispatch_bytecode(self, co_code, next_instr, ec): - if self.pycode.jit_enable: - return self.dispatch_jit(co_code, next_instr, ec) - else: - return super_dispatch_bytecode(self, co_code, next_instr, ec) + def dispatch(self, pycode, next_instr, ec): + if pycode.jit_enable: + return self.dispatch_jit(pycode, next_instr, ec) + else: + return super_dispatch(self, pycode, next_instr, ec) + + def dispatch_jit(self, pycode, next_instr, ec): + hint(None, global_merge_point=True) + pycode = hint(pycode, deepfreeze=True) + + entry_fastlocals_w = self.jit_enter_frame(pycode, next_instr) + + # For the sequel, force 'next_instr' to be unsigned for performance + next_instr = r_uint(next_instr) + co_code = pycode.co_code + + try: + try: + while True: + hint(None, global_merge_point=True) + next_instr = self.handle_bytecode(co_code, next_instr, ec) + except Return: + w_result = self.popvalue() + self.blockstack = None + self.valuestack_w = None + return w_result + except Yield: + w_result = self.popvalue() + return w_result + finally: + self.jit_leave_frame(pycode, entry_fastlocals_w) + + def jit_enter_frame(self, pycode, next_instr): + # *loads* of nonsense for now + + fastlocals_w = [None] * pycode.co_nlocals + + if next_instr == 0: + # first time we enter this function + depth = 0 + self.blockstack = [] + + 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 + + entry_fastlocals_w = self.fastlocals_w + self.fastlocals_w = fastlocals_w + + virtualstack_w = [None] * pycode.co_stacksize + while depth > 0: + depth -= 1 + hint(depth, concrete=True) + virtualstack_w[depth] = self.valuestack_w[depth] + self.valuestack_w = virtualstack_w + return entry_fastlocals_w + + def jit_leave_frame(self, pycode, entry_fastlocals_w): + 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 -setup2() PORTAL = PyFrame.dispatch_jit +class __extend__(Function): + __metaclass__ = extendabletype + + def getcode(self): + # if the self is a compile time constant and if its code + # is a BuiltinCode => grab and return its code as a constant + if _is_early_constant(self): + from pypy.interpreter.gateway import BuiltinCode + code = hint(self, deepfreeze=True).code + if not isinstance(code, BuiltinCode): code = self.code + else: + code = self.code + return code + + # ____________________________________________________________ # # Public interface Modified: pypy/branch/debug-jit/pypy/objspace/flow/flowcontext.py ============================================================================== --- pypy/branch/debug-jit/pypy/objspace/flow/flowcontext.py (original) +++ pypy/branch/debug-jit/pypy/objspace/flow/flowcontext.py Sun Mar 18 11:42:26 2007 @@ -262,7 +262,7 @@ self.framestack.push(frame) self.crnt_frame = frame try: - w_result = frame.dispatch(frame.pycode.co_code, + w_result = frame.dispatch(frame.pycode, frame.last_instr, self) finally: Modified: pypy/branch/debug-jit/pypy/objspace/flow/model.py ============================================================================== --- pypy/branch/debug-jit/pypy/objspace/flow/model.py (original) +++ pypy/branch/debug-jit/pypy/objspace/flow/model.py Sun Mar 18 11:42:26 2007 @@ -507,24 +507,24 @@ lst.append(link) return result -def copygraph(graph, shallow=False): +def copygraph(graph, shallow=False, varmap={}): "Make a copy of a flow graph." blockmap = {} - varmap = {} + varmap = varmap.copy() def copyvar(v): if shallow: return v - if isinstance(v, Variable): - try: - return varmap[v] - except KeyError: + try: + return varmap[v] + except KeyError: + if isinstance(v, Variable): v2 = varmap[v] = Variable(v) if hasattr(v, 'concretetype'): v2.concretetype = v.concretetype return v2 - else: - return v + else: + return v def copyblock(block): newblock = Block([copyvar(v) for v in block.inputargs]) Modified: pypy/branch/debug-jit/pypy/objspace/std/multimethod.py ============================================================================== --- pypy/branch/debug-jit/pypy/objspace/std/multimethod.py (original) +++ pypy/branch/debug-jit/pypy/objspace/std/multimethod.py Sun Mar 18 11:42:26 2007 @@ -749,9 +749,9 @@ attrname = self.mrdtable.attrname exprfn = "%d" % master_index for n in range(self.multimethod.arity-1): - exprfn = "indexarray.items[%s + arg%d.%s]" % (exprfn, n, attrname) + exprfn = "hint(indexarray.items, deepfreeze=True)[%s + arg%d.%s]" % (exprfn, n, attrname) n = self.multimethod.arity-1 - exprfn = "funcarray.items[(%s + arg%d.%s) & mmmask]" % (exprfn, n, + exprfn = "hint(funcarray.items, deepfreeze=True)[(%s + arg%d.%s) & mmmask]" % (exprfn, n, attrname) expr = Call(exprfn, self.fnargs) entry = self.build_funcentry([self.prefix, '0_perform_call'], @@ -794,6 +794,8 @@ bodylines.append(' pass') bodylines.append('return %s' % expr(calllist[-1])) + from pypy.rlib.objectmodel import hint + miniglobals['hint'] = hint entry = FuncEntry(bodylines, miniglobals, fallback) key = entry.key() try: Modified: pypy/branch/debug-jit/pypy/objspace/std/objspace.py ============================================================================== --- pypy/branch/debug-jit/pypy/objspace/std/objspace.py (original) +++ pypy/branch/debug-jit/pypy/objspace/std/objspace.py Sun Mar 18 11:42:26 2007 @@ -13,7 +13,7 @@ from pypy.objspace.descroperation import DescrOperation from pypy.objspace.std import stdtypedef from pypy.rlib.rarithmetic import base_int -from pypy.rlib.objectmodel import we_are_translated +from pypy.rlib.objectmodel import we_are_translated, hint import sys import os import __builtin__ @@ -492,6 +492,7 @@ return W_SeqIterObject(w_obj) def type(self, w_obj): + hint(w_obj.__class__, promote=True) return w_obj.getclass(self) def lookup(self, w_obj, name): Modified: pypy/branch/debug-jit/pypy/objspace/std/typeobject.py ============================================================================== --- pypy/branch/debug-jit/pypy/objspace/std/typeobject.py (original) +++ pypy/branch/debug-jit/pypy/objspace/std/typeobject.py Sun Mar 18 11:42:26 2007 @@ -6,7 +6,7 @@ from pypy.objspace.std.stdtypedef import std_dict_descr, issubtypedef, Member from pypy.objspace.std.objecttype import object_typedef from pypy.objspace.std.dictproxyobject import W_DictProxyObject -from pypy.rlib.objectmodel import we_are_translated +from pypy.rlib.objectmodel import we_are_translated, hint from pypy.rlib.rarithmetic import intmask, r_uint from copy_reg import _HEAPTYPE @@ -381,6 +381,7 @@ raise UnwrapError(w_self) def is_heaptype(w_self): + w_self = hint(w_self, deepfreeze=True) return w_self.__flags__&_HEAPTYPE def get_module(w_self): Modified: pypy/branch/debug-jit/pypy/rlib/objectmodel.py ============================================================================== --- pypy/branch/debug-jit/pypy/rlib/objectmodel.py (original) +++ pypy/branch/debug-jit/pypy/rlib/objectmodel.py Sun Mar 18 11:42:26 2007 @@ -109,9 +109,7 @@ def keepalive_until_here(*values): pass -def hint(x, **kwds): - return x - +# ____________________________________________________________ class FREED_OBJECT(object): def __getattribute__(self, attr): @@ -189,6 +187,50 @@ return hop.genop('cast_weakadr_to_int', vlist, resulttype = hop.r_result.lowleveltype) +# ____________________________________________________________ + +def hint(x, **kwds): + return x + +def we_are_jitted(): + return False +# timeshifts to True + +_we_are_jitted = CDefinedIntSymbolic('0 /* we are not jitted here */', + default=0) + +class Entry(ExtRegistryEntry): + _about_ = we_are_jitted + + def compute_result_annotation(self): + from pypy.annotation import model as annmodel + return annmodel.SomeInteger(nonneg=True) + + def specialize_call(self, hop): + from pypy.rpython.lltypesystem import lltype + return hop.inputconst(lltype.Signed, _we_are_jitted) + +def _is_early_constant(x): + return False + +class Entry(ExtRegistryEntry): + _about_ = _is_early_constant + + def compute_result_annotation(self, s_value): + from pypy.annotation import model as annmodel + s = annmodel.SomeBool() + if s_value.is_constant(): + s.const = True + return s + + def specialize_call(self, hop): + from pypy.rpython.lltypesystem import lltype + if hop.s_result.is_constant(): + assert hop.s_result.const + return hop.inputconst(lltype.Bool, True) + v, = hop.inputargs(hop.args_r[0]) + return hop.genop('is_early_constant', [v], resulttype=lltype.Bool) + def debug_assert(x, msg): """After translation to C, this becomes an RPyAssert.""" Modified: pypy/branch/debug-jit/pypy/rlib/test/test_objectmodel.py ============================================================================== --- pypy/branch/debug-jit/pypy/rlib/test/test_objectmodel.py (original) +++ pypy/branch/debug-jit/pypy/rlib/test/test_objectmodel.py Sun Mar 18 11:42:26 2007 @@ -312,6 +312,23 @@ res = self.interpret(f, []) assert res == 1 + def test_is_early_constant(self): + from pypy.rlib import objectmodel + def f(x): + if objectmodel._is_early_constant(x): + return 42 + return 0 + + assert f(3) == 0 + res = self.interpret(f, [5]) + assert res == 0 + + def g(): + return f(88) + + res = self.interpret(g, []) + assert res == 42 + class TestOOtype(BaseTestObjectModel, OORtypeMixin): pass Modified: pypy/branch/debug-jit/pypy/rpython/llinterp.py ============================================================================== --- pypy/branch/debug-jit/pypy/rpython/llinterp.py (original) +++ pypy/branch/debug-jit/pypy/rpython/llinterp.py Sun Mar 18 11:42:26 2007 @@ -4,7 +4,7 @@ from pypy.rpython.lltypesystem import lltype, llmemory, lloperation, llheap from pypy.rpython.lltypesystem import rclass from pypy.rpython.ootypesystem import ootype -from pypy.rlib.objectmodel import ComputedIntSymbolic +from pypy.rlib.objectmodel import ComputedIntSymbolic, CDefinedIntSymbolic import sys, os import math @@ -382,7 +382,21 @@ break else: raise TypeError("the operation %s is not expected to raise %s" % (operation, exc)) - raise + + # for exception-transformed graphs, store the LLException + # into the exc_data used by this graph + exc_data = self.llinterpreter.get_transformed_exc_data( + self.graph) + if exc_data: + etype = e.args[0] + evalue = e.args[1] + exc_data.exc_type = etype + exc_data.exc_value = evalue + from pypy.translator.c import exceptiontransform + retval = exceptiontransform.error_value( + operation.result.concretetype) + else: + raise self.setvar(operation.result, retval) if tracer: if retval is None: @@ -481,6 +495,9 @@ def op_hint(self, x, hints): return x + def op_is_early_constant(self, x): + return False + def op_resume_point(self, *args): pass @@ -557,19 +574,7 @@ def op_direct_call(self, f, *args): FTYPE = self.llinterpreter.typer.type_system.derefType(lltype.typeOf(f)) - try: - return self.perform_call(f, FTYPE.ARGS, args) - except LLException, e: - exc_data = self.llinterpreter.get_transformed_exc_data(self.graph) - if exc_data: - # store the LLException into the exc_data used by this graph - etype = e.args[0] - evalue = e.args[1] - exc_data.exc_type = etype - exc_data.exc_value = evalue - from pypy.translator.c import exceptiontransform - return exceptiontransform.error_value(FTYPE.RESULT) - raise + return self.perform_call(f, FTYPE.ARGS, args) def op_indirect_call(self, f, *args): graphs = args[-1] @@ -870,6 +875,13 @@ except OverflowError: self.make_llexception() + def op_int_is_true(self, x): + # special case + if type(x) is CDefinedIntSymbolic: + x = x.default + assert isinstance(x, int) + return bool(x) + # read frame var support def op_get_frame_base(self): @@ -878,7 +890,18 @@ def op_frame_info(self, *vars): pass op_frame_info.specialform = True - + + # hack for jit.codegen.llgraph + + def op_check_and_clear_exc(self): + exc_data = self.llinterpreter.get_transformed_exc_data(self.graph) + assert exc_data + etype = exc_data.exc_type + evalue = exc_data.exc_value + exc_data.exc_type = lltype.typeOf(etype )._defl() + exc_data.exc_value = lltype.typeOf(evalue)._defl() + return bool(etype) + #Operation of ootype def op_new(self, INST): Modified: pypy/branch/debug-jit/pypy/rpython/lltypesystem/lloperation.py ============================================================================== --- pypy/branch/debug-jit/pypy/rpython/lltypesystem/lloperation.py (original) +++ pypy/branch/debug-jit/pypy/rpython/lltypesystem/lloperation.py Sun Mar 18 11:42:26 2007 @@ -9,7 +9,8 @@ class LLOp(object): def __init__(self, sideeffects=True, canfold=False, canraise=(), - pyobj=False, canunwindgc=False, canrun=False, oo=False): + pyobj=False, canunwindgc=False, canrun=False, oo=False, + tryfold=False): # self.opname = ... (set afterwards) if canfold: @@ -23,6 +24,9 @@ # and always gives the same result for given args self.canfold = canfold + # Can *try* to fold the operation, but it may raise on you + self.tryfold = tryfold or canfold + # Exceptions that can be raised self.canraise = canraise assert isinstance(canraise, tuple) @@ -96,12 +100,12 @@ if not opdesc.canraise or raising_is_ok: yield opname -def enum_foldable_ops(raising_is_ok=False): +def enum_foldable_ops(_ignored=None): """Enumerate operations that can be constant-folded.""" for opname, opdesc in LL_OPERATIONS.iteritems(): if opdesc.canfold: - if not opdesc.canraise or raising_is_ok: - yield opname + assert not opdesc.canraise + yield opname class Entry(ExtRegistryEntry): @@ -152,18 +156,18 @@ 'int_is_true': LLOp(canfold=True), 'int_neg': LLOp(canfold=True), - 'int_neg_ovf': LLOp(canraise=(OverflowError,)), + 'int_neg_ovf': LLOp(canraise=(OverflowError,), tryfold=True), 'int_abs': LLOp(canfold=True), - 'int_abs_ovf': LLOp(canraise=(OverflowError,)), + 'int_abs_ovf': LLOp(canraise=(OverflowError,), tryfold=True), 'int_invert': LLOp(canfold=True), 'int_add': LLOp(canfold=True), 'int_sub': LLOp(canfold=True), 'int_mul': LLOp(canfold=True), 'int_floordiv': LLOp(canfold=True), - 'int_floordiv_zer': LLOp(canraise=(ZeroDivisionError,)), + 'int_floordiv_zer': LLOp(canraise=(ZeroDivisionError,), tryfold=True), 'int_mod': LLOp(canfold=True), - 'int_mod_zer': LLOp(canraise=(ZeroDivisionError,)), + 'int_mod_zer': LLOp(canraise=(ZeroDivisionError,), tryfold=True), 'int_lt': LLOp(canfold=True), 'int_le': LLOp(canfold=True), 'int_eq': LLOp(canfold=True), @@ -173,20 +177,23 @@ 'int_and': LLOp(canfold=True), 'int_or': LLOp(canfold=True), 'int_lshift': LLOp(canfold=True), - 'int_lshift_val': LLOp(canraise=(ValueError,)), + 'int_lshift_val': LLOp(canraise=(ValueError,), tryfold=True), 'int_rshift': LLOp(canfold=True), - 'int_rshift_val': LLOp(canraise=(ValueError,)), + 'int_rshift_val': LLOp(canraise=(ValueError,), tryfold=True), 'int_xor': LLOp(canfold=True), - 'int_add_ovf': LLOp(canraise=(OverflowError,)), - 'int_sub_ovf': LLOp(canraise=(OverflowError,)), - 'int_mul_ovf': LLOp(canraise=(OverflowError,)), - 'int_floordiv_ovf': LLOp(canraise=(OverflowError,)), - 'int_floordiv_ovf_zer': LLOp(canraise=(OverflowError, ZeroDivisionError)), - 'int_mod_ovf': LLOp(canraise=(OverflowError,)), - 'int_mod_ovf_zer': LLOp(canraise=(OverflowError, ZeroDivisionError)), - 'int_lshift_ovf': LLOp(canraise=(OverflowError,)), - 'int_lshift_ovf_val': LLOp(canraise=(OverflowError, ValueError,)), + 'int_add_ovf': LLOp(canraise=(OverflowError,), tryfold=True), + 'int_sub_ovf': LLOp(canraise=(OverflowError,), tryfold=True), + 'int_mul_ovf': LLOp(canraise=(OverflowError,), tryfold=True), + 'int_floordiv_ovf': LLOp(canraise=(OverflowError,), tryfold=True), + 'int_floordiv_ovf_zer': LLOp(canraise=(OverflowError, ZeroDivisionError), + tryfold=True), + 'int_mod_ovf': LLOp(canraise=(OverflowError,), tryfold=True), + 'int_mod_ovf_zer': LLOp(canraise=(OverflowError, ZeroDivisionError), + tryfold=True), + 'int_lshift_ovf': LLOp(canraise=(OverflowError,), tryfold=True), + 'int_lshift_ovf_val': LLOp(canraise=(OverflowError, ValueError,), + tryfold=True), 'uint_is_true': LLOp(canfold=True), 'uint_invert': LLOp(canfold=True), @@ -195,9 +202,9 @@ 'uint_sub': LLOp(canfold=True), 'uint_mul': LLOp(canfold=True), 'uint_floordiv': LLOp(canfold=True), - 'uint_floordiv_zer': LLOp(canraise=(ZeroDivisionError,)), + 'uint_floordiv_zer': LLOp(canraise=(ZeroDivisionError,), tryfold=True), 'uint_mod': LLOp(canfold=True), - 'uint_mod_zer': LLOp(canraise=(ZeroDivisionError,)), + 'uint_mod_zer': LLOp(canraise=(ZeroDivisionError,), tryfold=True), 'uint_lt': LLOp(canfold=True), 'uint_le': LLOp(canfold=True), 'uint_eq': LLOp(canfold=True), @@ -207,9 +214,9 @@ 'uint_and': LLOp(canfold=True), 'uint_or': LLOp(canfold=True), 'uint_lshift': LLOp(canfold=True), - 'uint_lshift_val': LLOp(canraise=(ValueError,)), + 'uint_lshift_val': LLOp(canraise=(ValueError,), tryfold=True), 'uint_rshift': LLOp(canfold=True), - 'uint_rshift_val': LLOp(canraise=(ValueError,)), + 'uint_rshift_val': LLOp(canraise=(ValueError,), tryfold=True), 'uint_xor': LLOp(canfold=True), 'float_is_true': LLOp(canfold=True), @@ -230,18 +237,18 @@ 'llong_is_true': LLOp(canfold=True), 'llong_neg': LLOp(canfold=True), - 'llong_neg_ovf': LLOp(canraise=(OverflowError,)), + 'llong_neg_ovf': LLOp(canraise=(OverflowError,), tryfold=True), 'llong_abs': LLOp(canfold=True), - 'llong_abs_ovf': LLOp(canraise=(OverflowError,)), + 'llong_abs_ovf': LLOp(canraise=(OverflowError,), tryfold=True), 'llong_invert': LLOp(canfold=True), 'llong_add': LLOp(canfold=True), 'llong_sub': LLOp(canfold=True), 'llong_mul': LLOp(canfold=True), 'llong_floordiv': LLOp(canfold=True), - 'llong_floordiv_zer': LLOp(canraise=(ZeroDivisionError,)), + 'llong_floordiv_zer': LLOp(canraise=(ZeroDivisionError,), tryfold=True), 'llong_mod': LLOp(canfold=True), - 'llong_mod_zer': LLOp(canraise=(ZeroDivisionError,)), + 'llong_mod_zer': LLOp(canraise=(ZeroDivisionError,), tryfold=True), 'llong_lt': LLOp(canfold=True), 'llong_le': LLOp(canfold=True), 'llong_eq': LLOp(canfold=True), @@ -251,9 +258,9 @@ 'llong_and': LLOp(canfold=True), 'llong_or': LLOp(canfold=True), 'llong_lshift': LLOp(canfold=True), - 'llong_lshift_val': LLOp(canraise=(ValueError,)), + 'llong_lshift_val': LLOp(canraise=(ValueError,), tryfold=True), 'llong_rshift': LLOp(canfold=True), - 'llong_rshift_val': LLOp(canraise=(ValueError,)), + 'llong_rshift_val': LLOp(canraise=(ValueError,), tryfold=True), 'llong_xor': LLOp(canfold=True), 'ullong_is_true': LLOp(canfold=True), @@ -263,9 +270,9 @@ 'ullong_sub': LLOp(canfold=True), 'ullong_mul': LLOp(canfold=True), 'ullong_floordiv': LLOp(canfold=True), - 'ullong_floordiv_zer': LLOp(canraise=(ZeroDivisionError,)), + 'ullong_floordiv_zer': LLOp(canraise=(ZeroDivisionError,), tryfold=True), 'ullong_mod': LLOp(canfold=True), - 'ullong_mod_zer': LLOp(canraise=(ZeroDivisionError,)), + 'ullong_mod_zer': LLOp(canraise=(ZeroDivisionError,), tryfold=True), 'ullong_lt': LLOp(canfold=True), 'ullong_le': LLOp(canfold=True), 'ullong_eq': LLOp(canfold=True), @@ -275,9 +282,9 @@ 'ullong_and': LLOp(canfold=True), 'ullong_or': LLOp(canfold=True), 'ullong_lshift': LLOp(canfold=True), - 'ullong_lshift_val': LLOp(canraise=(ValueError,)), + 'ullong_lshift_val': LLOp(canraise=(ValueError,), tryfold=True), 'ullong_rshift': LLOp(canfold=True), - 'ullong_rshift_val': LLOp(canraise=(ValueError,)), + 'ullong_rshift_val': LLOp(canraise=(ValueError,), tryfold=True), 'ullong_xor': LLOp(canfold=True), 'cast_primitive': LLOp(canfold=True), @@ -294,8 +301,8 @@ 'cast_uint_to_int': LLOp(canfold=True), 'cast_uint_to_float': LLOp(canfold=True), 'cast_longlong_to_float':LLOp(canfold=True), - 'cast_float_to_int': LLOp(canraise=(OverflowError,)), - 'cast_float_to_uint': LLOp(canfold=True), + 'cast_float_to_int': LLOp(canraise=(OverflowError,), tryfold=True), + 'cast_float_to_uint': LLOp(canfold=True), # XXX need OverflowError? 'cast_float_to_longlong':LLOp(canfold=True), 'truncate_longlong_to_int':LLOp(canfold=True), @@ -401,17 +408,19 @@ 'keepalive': LLOp(), 'same_as': LLOp(canfold=True), 'hint': LLOp(), + 'is_early_constant': LLOp(sideeffects=False), 'check_no_more_arg': LLOp(canraise=(Exception,)), 'check_self_nonzero': LLOp(canraise=(Exception,)), 'decode_arg': LLOp(canraise=(Exception,)), 'decode_arg_def': LLOp(canraise=(Exception,)), 'getslice': LLOp(canraise=(Exception,)), + 'check_and_clear_exc': LLOp(), # __________ debugging __________ 'debug_view': LLOp(), 'debug_print': LLOp(), 'debug_pdb': LLOp(), - 'debug_assert': LLOp(), + 'debug_assert': LLOp(tryfold=True), 'debug_fatalerror': LLOp(), # __________ instrumentation _________ @@ -438,8 +447,8 @@ 'oohash': LLOp(oo=True, sideeffects=False), # _____ read frame var support ___ - 'get_frame_base': LLOp(), - 'frame_info': LLOp(), + 'get_frame_base': LLOp(sideeffects=False), + 'frame_info': LLOp(sideeffects=False), } # ***** Run test_lloperation after changes. ***** Modified: pypy/branch/debug-jit/pypy/rpython/lltypesystem/opimpl.py ============================================================================== --- pypy/branch/debug-jit/pypy/rpython/lltypesystem/opimpl.py (original) +++ pypy/branch/debug-jit/pypy/rpython/lltypesystem/opimpl.py Sun Mar 18 11:42:26 2007 @@ -2,7 +2,6 @@ from pypy.tool.sourcetools import func_with_new_name from pypy.rpython.lltypesystem import lltype, llmemory from pypy.rpython.lltypesystem.lloperation import opimpls -from pypy.rlib.objectmodel import CDefinedIntSymbolic # ____________________________________________________________ # Implementation of the 'canfold' operations @@ -27,10 +26,6 @@ 'ullong': r_ulonglong, } -# this is just a flag, when we should check for -# CDefinedSymbolicInt -ops_to_check = {'is_true':True} - def no_op(x): return x @@ -63,16 +58,7 @@ fullopname,) argtype = type_by_name[typname] - if opname in ops_to_check: - def op_function(x): - # is instead of isinstance for performance - if type(x) is CDefinedIntSymbolic: - x = x.default - if not isinstance(x, argtype): - raise TypeError("%r arg must be %s, got %r instead" % ( - fullopname, typname, type(x).__name__)) - return adjust_result(func(x)) - elif opname in ops_unary: + if opname in ops_unary: def op_function(x): if not isinstance(x, argtype): raise TypeError("%r arg must be %s, got %r instead" % ( Modified: pypy/branch/debug-jit/pypy/rpython/lltypesystem/rclass.py ============================================================================== --- pypy/branch/debug-jit/pypy/rpython/lltypesystem/rclass.py (original) +++ pypy/branch/debug-jit/pypy/rpython/lltypesystem/rclass.py Sun Mar 18 11:42:26 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), Modified: pypy/branch/debug-jit/pypy/rpython/lltypesystem/rdict.py ============================================================================== --- pypy/branch/debug-jit/pypy/rpython/lltypesystem/rdict.py (original) +++ pypy/branch/debug-jit/pypy/rpython/lltypesystem/rdict.py Sun Mar 18 11:42:26 2007 @@ -397,6 +397,7 @@ else: raise KeyError ll_dict_getitem.oopspec = 'dict.getitem(d, key)' +ll_dict_getitem.oopargcheck = lambda d, key: bool(d) def ll_dict_setitem(d, key, value): hash = d.keyhash(key) @@ -736,3 +737,4 @@ entry = ll_dict_lookup(d, key, d.keyhash(key)) return entry.valid() ll_contains.oopspec = 'dict.contains(d, key)' +ll_contains.oopargcheck = lambda d, key: bool(d) Modified: pypy/branch/debug-jit/pypy/rpython/lltypesystem/rvirtualizable.py ============================================================================== --- pypy/branch/debug-jit/pypy/rpython/lltypesystem/rvirtualizable.py (original) +++ pypy/branch/debug-jit/pypy/rpython/lltypesystem/rvirtualizable.py Sun Mar 18 11:42:26 2007 @@ -45,13 +45,17 @@ redirected_fields = list(rbase.ACCESS.redirected_fields) name = self.lowleveltype.TO._name TOPPTR = self.get_top_virtualizable_type() + self.my_redirected_fields = my_redirected_fields = {} for name, (mangled_name, r) in self.fields.items(): T = r.lowleveltype + if T is lltype.Void: + continue GETTER = lltype.Ptr(lltype.FuncType([TOPPTR], T)) SETTER = lltype.Ptr(lltype.FuncType([TOPPTR, T], lltype.Void)) accessors.append(('get_'+mangled_name, GETTER)) accessors.append(('set_'+mangled_name, SETTER)) redirected_fields.append(mangled_name) + my_redirected_fields[name] = None ACCESS.become(lltype.Struct(name+'_access', hints = {'immutable': True}, adtmeths = {'redirected_fields': tuple(redirected_fields)}, @@ -124,7 +128,7 @@ def getfield(self, vinst, attr, llops, force_cast=False): """Read the given attribute (or __class__ for the type) of 'vinst'.""" - if attr in self.fields: + if attr in self.my_redirected_fields: mangled_name, r = self.fields[attr] if force_cast: vinst = llops.genop('cast_pointer', [vinst], resulttype=self) @@ -135,7 +139,7 @@ def setfield(self, vinst, attr, vvalue, llops, force_cast=False, opname='setfield'): """Write the given attribute (or __class__ for the type) of 'vinst'.""" - if attr in self.fields: + if attr in self.my_redirected_fields: mangled_name, r = self.fields[attr] if force_cast: vinst = llops.genop('cast_pointer', [vinst], resulttype=self) Modified: pypy/branch/debug-jit/pypy/rpython/lltypesystem/test/test_rvirtualizable.py ============================================================================== --- pypy/branch/debug-jit/pypy/rpython/lltypesystem/test/test_rvirtualizable.py (original) +++ pypy/branch/debug-jit/pypy/rpython/lltypesystem/test/test_rvirtualizable.py Sun Mar 18 11:42:26 2007 @@ -167,3 +167,36 @@ AA(3) py.test.raises(TyperError, interpret, f, []) + +def test_read_not_redirected_field(): + class V(object): + _virtualizable_ = True + + def __init__(self, v): + self.v = v + def f(v): + vinst = V(v) + return vinst, vinst.v, vinst.__class__ + res = interpret(f, [42]) + assert res.item1 == 42 + + +def test_void_fields(): + class F(object): + def _freeze_(self): + return True + + f = F() + + class V(object): + _virtualizable_ = True + + def __init__(self, v): + self.v = v + self.f = f + def f(v): + vinst = V(v) + return vinst, vinst.v, vinst.f + res = interpret(f, [42]) + assert res.item1 == 42 + Modified: pypy/branch/debug-jit/pypy/rpython/ootypesystem/rpbc.py ============================================================================== --- pypy/branch/debug-jit/pypy/rpython/ootypesystem/rpbc.py (original) +++ pypy/branch/debug-jit/pypy/rpython/ootypesystem/rpbc.py Sun Mar 18 11:42:26 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/debug-jit/pypy/rpython/rlist.py ============================================================================== --- pypy/branch/debug-jit/pypy/rpython/rlist.py (original) +++ pypy/branch/debug-jit/pypy/rpython/rlist.py Sun Mar 18 11:42:26 2007 @@ -464,11 +464,13 @@ def ll_len(l): return l.ll_length() ll_len.oopspec = 'list.len(l)' +ll_len.oopargcheck = lambda l: bool(l) def ll_list_is_true(l): # check if a list is True, allowing for None return bool(l) and l.ll_length() != 0 ll_list_is_true.oopspec = 'list.nonzero(l)' +ll_list_is_true.oopargcheck = lambda l: True def ll_append(l, newitem): length = l.ll_length() @@ -601,6 +603,8 @@ debug_assert(index < l.ll_length(), "list getitem index out of bound") return l.ll_getitem_fast(index) ll_getitem_nonneg.oopspec = 'list.getitem(l, index)' +ll_getitem_nonneg.oopargcheck = lambda l, index: (bool(l) and + 0 <= index < l.ll_length()) def ll_getitem(func, l, index): length = l.ll_length() @@ -614,6 +618,8 @@ debug_assert(index < length, "list getitem index out of bound") return l.ll_getitem_fast(index) ll_getitem.oopspec = 'list.getitem(l, index)' +ll_getitem.oopargcheck = lambda l, index: (bool(l) and -l.ll_length() <= + index < l.ll_length()) def ll_setitem_nonneg(func, l, index, newitem): debug_assert(index >= 0, "unexpectedly negative list setitem index") Modified: pypy/branch/debug-jit/pypy/rpython/rpbc.py ============================================================================== --- pypy/branch/debug-jit/pypy/rpython/rpbc.py (original) +++ pypy/branch/debug-jit/pypy/rpython/rpbc.py Sun Mar 18 11:42:26 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/debug-jit/pypy/rpython/test/test_llinterp.py ============================================================================== --- pypy/branch/debug-jit/pypy/rpython/test/test_llinterp.py (original) +++ pypy/branch/debug-jit/pypy/rpython/test/test_llinterp.py Sun Mar 18 11:42:26 2007 @@ -1,4 +1,5 @@ import py +import sys from pypy.rpython.lltypesystem.lltype import typeOf, pyobjectptr, Ptr, PyObject, Void from pypy.rpython.lltypesystem.lloperation import llop from pypy.rpython.llinterp import LLInterpreter, LLException, log @@ -563,3 +564,22 @@ assert res == 6 res = interp.eval_graph(graph, [3, -9831]) assert res == 7 + +def test_exceptiontransformed_add_ovf(): + from pypy.translator.c import exceptiontransform + def f(x, y): + try: + return ovfcheck(x + y) + except OverflowError: + return -42 + t = TranslationContext() + t.buildannotator().build_types(f, [int, int]) + t.buildrtyper().specialize() + etrafo = exceptiontransform.ExceptionTransformer(t) + graph = graphof(t, f) + etrafo.create_exception_handling(graph) + interp = LLInterpreter(t.rtyper) + res = interp.eval_graph(graph, [1, -64]) + assert res == -63 + res = interp.eval_graph(graph, [1, sys.maxint]) + assert res == -42 Modified: pypy/branch/debug-jit/pypy/rpython/test/test_rpbc.py ============================================================================== --- pypy/branch/debug-jit/pypy/rpython/test/test_rpbc.py (original) +++ pypy/branch/debug-jit/pypy/rpython/test/test_rpbc.py Sun Mar 18 11:42:26 2007 @@ -1543,6 +1543,29 @@ 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 Modified: pypy/branch/debug-jit/pypy/translator/backendopt/all.py ============================================================================== --- pypy/branch/debug-jit/pypy/translator/backendopt/all.py (original) +++ pypy/branch/debug-jit/pypy/translator/backendopt/all.py Sun Mar 18 11:42:26 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: @@ -73,6 +73,7 @@ inline_malloc_removal_phase(config, translator, graphs, threshold, inline_heuristic=heuristic) + constfold(config, graphs) if config.clever_malloc_removal: threshold = config.clever_malloc_removal_threshold @@ -106,6 +107,7 @@ threshold, inline_heuristic=heuristic, call_count_pred=call_count_pred) + constfold(config, graphs) if config.remove_asserts: remove_asserts(translator, graphs) @@ -158,6 +160,3 @@ if config.print_statistics: print "after malloc removal:" print_statistics(translator.graphs[0], translator) - - constfold(config, graphs) - Modified: pypy/branch/debug-jit/pypy/translator/backendopt/removeassert.py ============================================================================== --- pypy/branch/debug-jit/pypy/translator/backendopt/removeassert.py (original) +++ pypy/branch/debug-jit/pypy/translator/backendopt/removeassert.py Sun Mar 18 11:42:26 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 @@ -35,7 +36,7 @@ if translator.config.translation.verbose: 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): @@ -50,6 +51,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/debug-jit/pypy/translator/backendopt/support.py ============================================================================== --- pypy/branch/debug-jit/pypy/translator/backendopt/support.py (original) +++ pypy/branch/debug-jit/pypy/translator/backendopt/support.py Sun Mar 18 11:42:26 2007 @@ -107,24 +107,20 @@ afterblock.operations[pos:pos] = generate_keepalive(keep_alive_vars) return splitlink -def calculate_call_graph(translator): - calls = {} - for graph in translator.graphs: - if getattr(getattr(graph, "func", None), "suggested_primitive", False): - continue - calls[graph] = {} - for block in graph.iterblocks(): - for op in block.operations: - if op.opname == "direct_call": - called_graph = get_graph(op.args[0], translator) - if called_graph is not None: - calls[graph][called_graph] = block - if op.opname == "indirect_call": - graphs = op.args[-1].value - if graphs is not None: - for called_graph in graphs: - calls[graph][called_graph] = block - return calls +def find_calls_from(translator, graph): + if getattr(getattr(graph, "func", None), "suggested_primitive", False): + return + for block in graph.iterblocks(): + for op in block.operations: + if op.opname == "direct_call": + called_graph = get_graph(op.args[0], translator) + if called_graph is not None: + yield block, called_graph + if op.opname == "indirect_call": + graphs = op.args[-1].value + if graphs is not None: + for called_graph in graphs: + yield block, called_graph def find_backedges(graph, block=None, seen=None, seeing=None): """finds the backedges in the flow graph""" Modified: pypy/branch/debug-jit/pypy/translator/backendopt/test/test_removeassert.py ============================================================================== --- pypy/branch/debug-jit/pypy/translator/backendopt/test/test_removeassert.py (original) +++ pypy/branch/debug-jit/pypy/translator/backendopt/test/test_removeassert.py Sun Mar 18 11:42:26 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(): Modified: pypy/branch/debug-jit/pypy/translator/c/exceptiontransform.py ============================================================================== --- pypy/branch/debug-jit/pypy/translator/c/exceptiontransform.py (original) +++ pypy/branch/debug-jit/pypy/translator/c/exceptiontransform.py Sun Mar 18 11:42:26 2007 @@ -139,7 +139,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() @@ -330,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) Modified: pypy/branch/debug-jit/pypy/translator/c/funcgen.py ============================================================================== --- pypy/branch/debug-jit/pypy/translator/c/funcgen.py (original) +++ pypy/branch/debug-jit/pypy/translator/c/funcgen.py Sun Mar 18 11:42:26 2007 @@ -750,5 +750,7 @@ counter_label = self.expr(op.args[1]) return 'INSTRUMENT_COUNT(%s);' % counter_label - + def OP_IS_EARLY_CONSTANT(self, op): + return self.expr(op.result) + ' = 0;' # Allways false + assert not USESLOTS or '__dict__' not in dir(FunctionCodeGenerator) Modified: pypy/branch/debug-jit/pypy/translator/c/test/test_symbolic.py ============================================================================== --- pypy/branch/debug-jit/pypy/translator/c/test/test_symbolic.py (original) +++ pypy/branch/debug-jit/pypy/translator/c/test/test_symbolic.py Sun Mar 18 11:42:26 2007 @@ -110,3 +110,16 @@ fn = t.compile_c() res = fn() assert res == 42 + +def test_is_early_constant(): + from pypy.rlib import objectmodel + def f(x): + if objectmodel._is_early_constant(x): + return 42 + return 0 + + + fn, t = getcompiled(f, [int]) + res = fn(5) + assert res == 0 + Modified: pypy/branch/debug-jit/pypy/translator/cli/opcodes.py ============================================================================== --- pypy/branch/debug-jit/pypy/translator/cli/opcodes.py (original) +++ pypy/branch/debug-jit/pypy/translator/cli/opcodes.py Sun Mar 18 11:42:26 2007 @@ -3,8 +3,9 @@ CastWeakAdrToPtr, MapException, Box, Unbox, NewArray, GetArrayElem, SetArrayElem,\ TypeOf from pypy.translator.oosupport.metavm import PushArg, PushAllArgs, StoreResult, InstructionList,\ - New, RuntimeNew, CastTo + New, RuntimeNew, CastTo, PushPrimitive from pypy.translator.cli.cts import WEAKREF +from pypy.rpython.ootypesystem import ootype # some useful instruction patterns Not = ['ldc.i4.0', 'ceq'] @@ -227,6 +228,7 @@ 'cast_longlong_to_float': 'conv.r8', 'cast_float_to_longlong': 'conv.i8', 'truncate_longlong_to_int': 'conv.i4', + 'is_early_constant': [PushPrimitive(ootype.Bool, False)] } for key, value in opcodes.iteritems(): Modified: pypy/branch/debug-jit/pypy/translator/goal/ann_override.py ============================================================================== --- pypy/branch/debug-jit/pypy/translator/goal/ann_override.py (original) +++ pypy/branch/debug-jit/pypy/translator/goal/ann_override.py Sun Mar 18 11:42:26 2007 @@ -167,16 +167,20 @@ return CACHED_LOOKUP = """ +from pypy.rlib.objectmodel import hint def lookup_%(attr)s(space, w_obj, name): w_type = space.type(w_obj) if not w_type.is_heaptype(): + w_type = hint(w_type, deepfreeze=True) return w_type.cached_%(attr)s return w_type.lookup("%(attr)s") """ CACHED_LOOKUP_IN_TYPE_WHERE = """ +from pypy.rlib.objectmodel import hint def lookup_in_type_where_%(attr)s(space, w_type, name): if not w_type.is_heaptype(): + w_type = hint(w_type, deepfreeze=True) return w_type.cached_where_%(attr)s return w_type.lookup_where("%(attr)s") """ Modified: pypy/branch/debug-jit/pypy/translator/goal/richards.py ============================================================================== --- pypy/branch/debug-jit/pypy/translator/goal/richards.py (original) +++ pypy/branch/debug-jit/pypy/translator/goal/richards.py Sun Mar 18 11:42:26 2007 @@ -407,11 +407,12 @@ result, startTime, endTime = entry_point(iterations) if not result: print "Incorrect results!" - return + return -1 print "finished." total_s = endTime - startTime print "Total time for %d iterations: %.2f secs" %(iterations,total_s) print "Average time per iteration: %.2f ms" %(total_s*1000/iterations) + return 42 try: import sys Modified: pypy/branch/debug-jit/pypy/translator/js/function.py ============================================================================== --- pypy/branch/debug-jit/pypy/translator/js/function.py (original) +++ pypy/branch/debug-jit/pypy/translator/js/function.py Sun Mar 18 11:42:26 2007 @@ -128,6 +128,9 @@ self.load(item) self.ilasm.list_getitem() + def push_primitive_constant(self, TYPE, value): + self.db.load_const(TYPE, value, self.ilasm) + def branch_unconditionally(self, target_label): self.ilasm.jump_block(self.block_map[target_label]) Modified: pypy/branch/debug-jit/pypy/translator/js/opcodes.py ============================================================================== --- pypy/branch/debug-jit/pypy/translator/js/opcodes.py (original) +++ pypy/branch/debug-jit/pypy/translator/js/opcodes.py Sun Mar 18 11:42:26 2007 @@ -2,7 +2,7 @@ """ from pypy.translator.oosupport.metavm import PushArg, PushAllArgs, StoreResult,\ - InstructionList, New, SetField, GetField, MicroInstruction, RuntimeNew + InstructionList, New, SetField, GetField, MicroInstruction, RuntimeNew, PushPrimitive from pypy.translator.oosupport.metavm import _GetFieldDispatcher, _SetFieldDispatcher, \ _CallDispatcher, _MethodDispatcher @@ -12,6 +12,7 @@ IndirectCall, CallExternalObject, SetExternalField, _CastMethod, _LoadConst from pypy.translator.js.jsbuiltin import Builtins +from pypy.rpython.ootypesystem import ootype DoNothing = [PushAllArgs] @@ -147,6 +148,7 @@ 'truncate_longlong_to_int': CopyName, 'debug_assert' : DoNothing, + 'is_early_constant': [PushPrimitive(ootype.Bool, False)] } for key, value in opcodes.iteritems(): Modified: pypy/branch/debug-jit/pypy/translator/llvm/opwriter.py ============================================================================== --- pypy/branch/debug-jit/pypy/translator/llvm/opwriter.py (original) +++ pypy/branch/debug-jit/pypy/translator/llvm/opwriter.py Sun Mar 18 11:42:26 2007 @@ -562,3 +562,8 @@ def hint(self, opr): self.same_as(opr) + + def is_early_constant(self, opr): + # If it gets this far it is always false + self.codewriter.cast(opr.retref, 'bool', + 'false', opr.rettype) Modified: pypy/branch/debug-jit/pypy/translator/llvm/test/test_symbolic.py ============================================================================== --- pypy/branch/debug-jit/pypy/translator/llvm/test/test_symbolic.py (original) +++ pypy/branch/debug-jit/pypy/translator/llvm/test/test_symbolic.py Sun Mar 18 11:42:26 2007 @@ -167,3 +167,16 @@ assert fn(21) == 42 + +def test_is_early_constant(): + from pypy.rlib import objectmodel + def f(x): + if objectmodel._is_early_constant(x): + return 42 + return 0 + + + fn = compile_function(f, [int]) + res = fn(5) + assert res == 0 + Modified: pypy/branch/debug-jit/pypy/translator/oosupport/metavm.py ============================================================================== --- pypy/branch/debug-jit/pypy/translator/oosupport/metavm.py (original) +++ pypy/branch/debug-jit/pypy/translator/oosupport/metavm.py Sun Mar 18 11:42:26 2007 @@ -243,6 +243,14 @@ for arg in op.args: generator.load(arg) +class PushPrimitive(MicroInstruction): + def __init__(self, TYPE, value): + self.TYPE = TYPE + self.value = value + + def render(self, generator, op): + generator.push_primitive_constant(self.TYPE, self.value) + class _StoreResult(MicroInstruction): def render(self, generator, op): generator.store(op.result) @@ -437,3 +445,4 @@ RuntimeNew = _RuntimeNew() OOString = _OOString() CastTo = _CastTo() + Modified: pypy/branch/debug-jit/pypy/translator/oosupport/test_template/operations.py ============================================================================== --- pypy/branch/debug-jit/pypy/translator/oosupport/test_template/operations.py (original) +++ pypy/branch/debug-jit/pypy/translator/oosupport/test_template/operations.py Sun Mar 18 11:42:26 2007 @@ -190,3 +190,12 @@ def fn(x, y): return bool(x) self._check_all(fn) + + def test_is_early_constant(self): + from pypy.rlib import objectmodel + def f(x): + if objectmodel._is_early_constant(x): + return 42 + return 0 + assert self.interpret(f, [5]) == 0 + Modified: pypy/branch/debug-jit/pypy/translator/tool/pygame/graphdisplay.py ============================================================================== --- pypy/branch/debug-jit/pypy/translator/tool/pygame/graphdisplay.py (original) +++ pypy/branch/debug-jit/pypy/translator/tool/pygame/graphdisplay.py Sun Mar 18 11:42:26 2007 @@ -333,7 +333,8 @@ def highlight_found_item(self): item = self.searchresults[self.searchpos] self.sethighlight(obj=item) - msg = 'Found %%s containing %s (%d/%d)' % (self.searchstr, + msg = 'Found %%s containing %s (%d/%d)' % ( + self.searchstr.replace('%', '%%'), self.searchpos+1, len(self.searchresults)) if isinstance(item, Node): self.setstatusbar(msg % 'node') Modified: pypy/branch/debug-jit/pypy/translator/tool/taskengine.py ============================================================================== --- pypy/branch/debug-jit/pypy/translator/tool/taskengine.py (original) +++ pypy/branch/debug-jit/pypy/translator/tool/taskengine.py Sun Mar 18 11:42:26 2007 @@ -29,7 +29,11 @@ def subgoals(task_name): taskcallable, deps = self.tasks[task_name] for dep in deps: - if dep.startswith('?'): + if dep.startswith('??'): # optional + dep = dep[2:] + if dep not in goals: + continue + if dep.startswith('?'): # suggested dep = dep[1:] if dep in skip: continue Modified: pypy/branch/debug-jit/pypy/translator/tool/test/test_taskengine.py ============================================================================== --- pypy/branch/debug-jit/pypy/translator/tool/test/test_taskengine.py (original) +++ pypy/branch/debug-jit/pypy/translator/tool/test/test_taskengine.py Sun Mar 18 11:42:26 2007 @@ -99,3 +99,50 @@ assert test(['B', 'A'], ['C']) == trace(['B', 'A']) assert test(['B', 'A', 'C']) == trace(['B', 'C', 'A']) assert test(['B', 'A', 'C'], ['C']) == trace(['B', 'C', 'A']) + +def test_driver(): + class Drv(SimpleTaskEngine): + + def task_A(): + pass + task_A.task_deps = [] + + def task_R(): + pass + task_R.task_deps = ['A'] + + def task_b(): + pass + task_b.task_deps = ['R'] + + def task_H(): + pass + task_H.task_deps = ['b'] + + def task_T(): + pass + task_T.task_deps = ['H'] + + def task_B(): + pass + task_B.task_deps = ['R', '??T'] + + def task_D(): + pass + task_D.task_deps = ['R', '?B', '?A', '??T'] + + drv = Drv() + assert drv._plan(['R']) == ['A', 'R'] + assert drv._plan(['B']) == ['A', 'R', 'B'] + assert drv._plan(['D']) == ['A', 'R', 'B', 'D'] + assert drv._plan(['D'], skip=['B']) == ['A', 'R', 'D'] + assert drv._plan(['D', 'R']) == ['A', 'R', 'B', 'D'] + + + assert drv._plan(['H', 'R']) == ['A', 'R', 'b', 'H'] + assert drv._plan(['H']) == ['A', 'R', 'b', 'H'] + assert drv._plan(['T', 'B']) == ['A', 'R', 'b', 'H', 'T', 'B'] + assert drv._plan(['D', 'T']) == ['A', 'R', 'b', 'H', 'T', 'B', 'D'] + assert drv._plan(['D', 'T', 'R']) == ['A', 'R', 'b', 'H', 'T', 'B', 'D'] + assert drv._plan(['D', 'T']) == ['A', 'R', 'b', 'H', 'T', 'B', 'D'] + assert drv._plan(['D', 'T'], skip=['B']) == ['A', 'R', 'b', 'H', 'T', 'D'] Modified: pypy/branch/debug-jit/pypy/translator/transform.py ============================================================================== --- pypy/branch/debug-jit/pypy/translator/transform.py (original) +++ pypy/branch/debug-jit/pypy/translator/transform.py Sun Mar 18 11:42:26 2007 @@ -180,7 +180,7 @@ caller_block.operations.insert(0, unwind_op) def insert_ll_stackcheck(translator): - from pypy.translator.backendopt.support import calculate_call_graph + from pypy.translator.backendopt.support import find_calls_from from pypy.rpython.module.ll_stack import ll_stack_check from pypy.tool.algo.graphlib import Edge, make_edge_dict, break_cycles rtyper = translator.rtyper @@ -188,12 +188,11 @@ rtyper.specialize_more_blocks() stack_check_ptr = rtyper.getcallable(graph) stack_check_ptr_const = Constant(stack_check_ptr, lltype.typeOf(stack_check_ptr)) - call_graph = calculate_call_graph(translator) edges = [] graphs_to_patch = {} insert_in = {} - for caller, all_callees in call_graph.iteritems(): - for callee, block in all_callees.iteritems(): + for caller in translator.graphs: + for block, callee in find_calls_from(translator, caller): if getattr(getattr(callee, 'func', None), 'insert_stack_check_here', False): insert_in[callee.startblock] = True From fijal at codespeak.net Sun Mar 18 12:15:30 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 18 Mar 2007 12:15:30 +0100 (CET) Subject: [pypy-svn] r40658 - pypy/dist/pypy/translator/js/lib Message-ID: <20070318111530.2895C1007F@code0.codespeak.net> Author: fijal Date: Sun Mar 18 12:15:25 2007 New Revision: 40658 Modified: pypy/dist/pypy/translator/js/lib/server.py Log: Operator precedence 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 Sun Mar 18 12:15:25 2007 @@ -246,7 +246,7 @@ def traverse(self, path, orgpath): data = open(os.path.join(str(self.path), *path)).read() if self.type: - return lambda : self.type, data + return lambda : (self.type, data) return lambda : data def create_server(server_address = ('', 8000), handler=TestHandler, From fijal at codespeak.net Sun Mar 18 12:16:23 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 18 Mar 2007 12:16:23 +0100 (CET) Subject: [pypy-svn] r40659 - pypy/dist/pypy/translator/js Message-ID: <20070318111623.9CB311007F@code0.codespeak.net> Author: fijal Date: Sun Mar 18 12:16:17 2007 New Revision: 40659 Modified: pypy/dist/pypy/translator/js/opcodes.py Log: Add overflow opcode with no overflow at all. This is very dirty and needs fixes as soon as we'll sit on numbers seriously. Modified: pypy/dist/pypy/translator/js/opcodes.py ============================================================================== --- pypy/dist/pypy/translator/js/opcodes.py (original) +++ pypy/dist/pypy/translator/js/opcodes.py Sun Mar 18 12:16:17 2007 @@ -32,14 +32,18 @@ opcodes = {'int_mul': '*', 'int_add': '+', 'int_sub': '-', + 'int_sub_ovf': '-', # XXX overflow 'int_floordiv': '/', 'int_mod': '%', + 'int_mod_ovf': '%', # XXX: what's that? 'int_mod_zer': '%', # XXX: fix zero stuff 'int_and': '&', 'int_or': '|', 'int_xor': '^', 'int_lshift': '<<', + 'int_lshift_ovf': '<<', # XXX overflow 'int_rshift': '>>', + 'int_rshift_ovf': '>>', # XXX overflow 'int_lt': '<', 'int_le': '<=', 'int_eq': '==', @@ -147,6 +151,7 @@ 'truncate_longlong_to_int': CopyName, 'debug_assert' : DoNothing, + 'resume_point' : DoNothing, } for key, value in opcodes.iteritems(): From fijal at codespeak.net Sun Mar 18 12:17:04 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 18 Mar 2007 12:17:04 +0100 (CET) Subject: [pypy-svn] r40660 - pypy/dist/pypy/translator/js/examples Message-ID: <20070318111704.9771F1007F@code0.codespeak.net> Author: fijal Date: Sun Mar 18 12:17:01 2007 New Revision: 40660 Modified: pypy/dist/pypy/translator/js/examples/overmind.py Log: Move to new 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 Sun Mar 18 12:17:01 2007 @@ -68,7 +68,7 @@ if __name__ == '__main__': try: addr = ('', 8008) - from pypeers.httpserver import GreenHTTPServer + from py.__.net.server.httpserver import GreenHTTPServer httpd = server.create_server(server_address=addr, handler=Handler, server=GreenHTTPServer) httpd.serve_forever() From fijal at codespeak.net Sun Mar 18 12:17:49 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 18 Mar 2007 12:17:49 +0100 (CET) Subject: [pypy-svn] r40661 - pypy/dist/pypy/translator/js/examples/bnb Message-ID: <20070318111749.5382010082@code0.codespeak.net> Author: fijal Date: Sun Mar 18 12:17:46 2007 New Revision: 40661 Modified: pypy/dist/pypy/translator/js/examples/bnb/bnb.py Log: Move to new interface 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 Sun Mar 18 12:17:46 2007 @@ -234,7 +234,7 @@ exported_methods = ExportedMethods() -class BnbRoot(server.Handler): +class BnbHandler(server.Collection): """ BnB server handler """ exported_methods = exported_methods @@ -262,3 +262,7 @@ def close(self): self._close() return dict() + +class BnbRoot(server.NewHandler): + application = BnbHandler() + From fijal at codespeak.net Sun Mar 18 12:19:22 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 18 Mar 2007 12:19:22 +0100 (CET) Subject: [pypy-svn] r40662 - pypy/dist/pypy/translator/js/examples/bnb Message-ID: <20070318111922.F3CAA1007F@code0.codespeak.net> Author: fijal Date: Sun Mar 18 12:19:20 2007 New Revision: 40662 Modified: pypy/dist/pypy/translator/js/examples/bnb/start_bnb.py Log: Disable logging pane by default 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 Sun Mar 18 12:19:20 2007 @@ -267,7 +267,7 @@ bnb_dispatcher) def bnb(): - createLoggingPane(True) + #createLoggingPane(True) log("keys: [0-9] to select player, [wsad] to walk around") exported_methods.initialize_session(session_dispatcher) From fijal at codespeak.net Sun Mar 18 12:21:52 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 18 Mar 2007 12:21:52 +0100 (CET) Subject: [pypy-svn] r40663 - pypy/dist/pypy/translator/js Message-ID: <20070318112152.C6F9A1007F@code0.codespeak.net> Author: fijal Date: Sun Mar 18 12:21:49 2007 New Revision: 40663 Modified: pypy/dist/pypy/translator/js/opcodes.py Log: Cast float to long long Modified: pypy/dist/pypy/translator/js/opcodes.py ============================================================================== --- pypy/dist/pypy/translator/js/opcodes.py (original) +++ pypy/dist/pypy/translator/js/opcodes.py Sun Mar 18 12:21:49 2007 @@ -148,6 +148,7 @@ 'cast_uint_to_float': CopyName, 'cast_float_to_int': [PushAllArgs,_CastFun("Math.floor",1)], 'cast_float_to_uint': [PushAllArgs,_CastFun("Math.floor",1)], + 'cast_float_to_longlong': [PushAllArgs,_CastFun("Math.floor",1)], 'truncate_longlong_to_int': CopyName, 'debug_assert' : DoNothing, From fijal at codespeak.net Sun Mar 18 12:59:44 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 18 Mar 2007 12:59:44 +0100 (CET) Subject: [pypy-svn] r40664 - pypy/dist/pypy/translator/js Message-ID: <20070318115944.0FE9210078@code0.codespeak.net> Author: fijal Date: Sun Mar 18 12:59:42 2007 New Revision: 40664 Modified: pypy/dist/pypy/translator/js/database.py Log: Decrease verbosity by default Modified: pypy/dist/pypy/translator/js/database.py ============================================================================== --- pypy/dist/pypy/translator/js/database.py (original) +++ pypy/dist/pypy/translator/js/database.py Sun Mar 18 12:59:42 2007 @@ -112,9 +112,12 @@ self.consts[const] return self.reverse_consts[self.consts[const]] except KeyError: - log("New const:%r"%value) - if isinstance(value, ootype._string): - log(value._str) + if self.genoo.config.translation.verbose: + log("New const:%r"%value) + if isinstance(value, ootype._string): + log(value._str) + else: + log.dot() name = const.get_name() if name in self.const_names: name += '__%d' % len(self.consts) @@ -164,12 +167,14 @@ all_c.append(i) dep_ok.add(const) - log("Consts: %r"%self.consts) # We need to keep track of fields to make sure # our items appear earlier than us to_init = [] for const, name in generate_constants(self.consts): - log("Recording %r %r"%(const,name)) + if self.genoo.config.translation.verbose: + log("Recording %r %r"%(const,name)) + else: + log.dot() ilasm.load_local(self.const_var) const.init(ilasm) ilasm.set_field(None, name) From fijal at codespeak.net Sun Mar 18 13:00:36 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 18 Mar 2007 13:00:36 +0100 (CET) Subject: [pypy-svn] r40665 - in pypy/dist/pypy/translator/js/examples: . data Message-ID: <20070318120036.5167E10078@code0.codespeak.net> Author: fijal Date: Sun Mar 18 13:00:30 2007 New Revision: 40665 Added: pypy/dist/pypy/translator/js/examples/data/style.css Modified: pypy/dist/pypy/translator/js/examples/data/index.html pypy/dist/pypy/translator/js/examples/overmind.py Log: Improve style a bit (mostly by adding logo) 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 Sun Mar 18 13:00:30 2007 @@ -2,10 +2,10 @@ pypy.js various demos - + + PyPy

    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

    Added: pypy/dist/pypy/translator/js/examples/data/style.css ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/js/examples/data/style.css Sun Mar 18 13:00:30 2007 @@ -0,0 +1,5 @@ +body,body.editor,body.body { + font: 90% "Times New Roman", Arial, Verdana, Helvetica, serif; + background: White; + color: Black; +} 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 Sun Mar 18 13:00:30 2007 @@ -19,18 +19,6 @@ TIMEOUT = 300 pids = [] -#def launch_console_in_new_prcess(): -# from pypy.translator.js.examples import pythonconsole -# httpd = server.create_server(server_address=('', 0), -# handler=pythonconsole.RequestHandler, -# server=pythonconsole.Server) -# port = httpd.server_port -# pythonconsole.httpd = httpd -# pid = server.start_server_in_new_process(httpd, timeout=TIMEOUT) -# del httpd -# pids.append(pid) -# return port - def js_source(function_list): import over_client return rpython2javascript(over_client, FUNCTION_LIST) @@ -38,6 +26,7 @@ class Root(server.Collection): static_dir = py.path.local(__file__).dirpath().join("data") index = server.FsFile(static_dir.join("index.html")) + style_css = server.FsFile(static_dir.join("style.css")) terminal = server.Static(static_dir.join("terminal.html")) console = console.Root() From fijal at codespeak.net Sun Mar 18 13:00:54 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 18 Mar 2007 13:00:54 +0100 (CET) Subject: [pypy-svn] r40666 - pypy/dist/pypy/translator/js/test Message-ID: <20070318120054.3A09910082@code0.codespeak.net> Author: fijal Date: Sun Mar 18 13:00:50 2007 New Revision: 40666 Modified: pypy/dist/pypy/translator/js/test/test_bltn.py Log: Improve test Modified: pypy/dist/pypy/translator/js/test/test_bltn.py ============================================================================== --- pypy/dist/pypy/translator/js/test/test_bltn.py (original) +++ pypy/dist/pypy/translator/js/test/test_bltn.py Sun Mar 18 13:00:50 2007 @@ -6,6 +6,7 @@ from pypy.rpython.ootypesystem.bltregistry import BasicExternal, MethodDesc from pypy.translator.js.test.runtest import compile_function, check_source_contains from pypy.rpython.extfunc import _callable +from pypy.translator.js import commproxy # check rendering dom.document def test_simple_builtin(): @@ -33,11 +34,16 @@ SomeProxyInstance = SomeProxy() def test_simple_proxy(): - def simple_proxy(): - retval = SomeProxyInstance.some_method() - - fn = compile_function(simple_proxy, []) - assert check_source_contains(fn, "loadJSONDoc\('some_method'") + try: + oldproxy = commproxy.USE_MOCHIKIT + commproxy.USE_MOCHIKIT = True + def simple_proxy(): + retval = SomeProxyInstance.some_method() + + fn = compile_function(simple_proxy, []) + assert check_source_contains(fn, "loadJSONDoc\('some_method'") + finally: + commproxy.USE_MOCHIKIT = oldproxy SomeNodeInstance = SomeNode() SomeNodeInstance._render_name = 's' From arigo at codespeak.net Sun Mar 18 13:46:31 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 18 Mar 2007 13:46:31 +0100 (CET) Subject: [pypy-svn] r40667 - pypy/branch/jit-virtual-world/pypy/interpreter Message-ID: <20070318124631.D02BA10082@code0.codespeak.net> Author: arigo Date: Sun Mar 18 13:46:27 2007 New Revision: 40667 Modified: pypy/branch/jit-virtual-world/pypy/interpreter/pyopcode.py Log: Remove unused constant. 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 Mar 18 13:46:27 2007 @@ -41,9 +41,6 @@ return func_with_new_name(opimpl, "opcode_impl_for_%s" % operationname) -JITTING = False # see also pypy.module.pypyjit - - class __extend__(pyframe.PyFrame): """A PyFrame that knows about interpretation of standard Python opcodes minus the ones related to nested scopes.""" From arigo at codespeak.net Sun Mar 18 14:31:11 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 18 Mar 2007 14:31:11 +0100 (CET) Subject: [pypy-svn] r40669 - pypy/dist/pypy/rpython Message-ID: <20070318133111.6E31710086@code0.codespeak.net> Author: arigo Date: Sun Mar 18 14:31:09 2007 New Revision: 40669 Added: pypy/dist/pypy/rpython/llinterp.py.merge.tmp - copied, changed from r40668, pypy/dist/pypy/rpython/llinterp.py Log: merging of http://codespeak.net/svn/pypy/branch/jit-virtual-world/pypy/rpython/llinterp.py revisions 37673 to 40668: ------------------------------------------------------------------------ r40622 | arigo | 2007-03-16 23:06:38 +0100 (Fri, 16 Mar 2007) | 7 lines (arigo, pedronis) We should never constant-folding CDefinedIntSymbolics. Only the llinterpreter is allowed to use the 'default'. The hintannotator test failed because of that. ------------------------------------------------------------------------ r40583 | pedronis | 2007-03-16 14:04:32 +0100 (Fri, 16 Mar 2007) | 3 lines oops, forgot to add the new test file ------------------------------------------------------------------------ r40500 | arigo | 2007-03-14 19:48:50 +0100 (Wed, 14 Mar 2007) | 6 lines (arigo, arre, pedronis) Support for the 'int_xyz_ovf' kind of operations in the timeshifter and the llgraph back-end. ------------------------------------------------------------------------ r37966 | arigo | 2007-02-05 15:23:58 +0100 (Mon, 05 Feb 2007) | 10 lines (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). ------------------------------------------------------------------------ r37675 | arigo | 2007-01-31 16:50:27 +0100 (Wed, 31 Jan 2007) | 2 lines A branch in which to try to make PyPy frames virtualizable. ------------------------------------------------------------------------ From arigo at codespeak.net Sun Mar 18 14:31:18 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 18 Mar 2007 14:31:18 +0100 (CET) Subject: [pypy-svn] r40670 - pypy/dist/pypy/interpreter Message-ID: <20070318133118.B129410086@code0.codespeak.net> Author: arigo Date: Sun Mar 18 14:31:15 2007 New Revision: 40670 Added: pypy/dist/pypy/interpreter/function.py.merge.tmp - copied, changed from r40668, pypy/dist/pypy/interpreter/function.py Log: merging of http://codespeak.net/svn/pypy/branch/jit-virtual-world/pypy/interpreter/function.py revisions 37673 to 40668: ------------------------------------------------------------------------ r40598 | pedronis | 2007-03-16 18:25:36 +0100 (Fri, 16 Mar 2007) | 6 lines (arigo, pedronis) use a hook for the code to grab a *constant* object code for builtins at compile time. ------------------------------------------------------------------------ r40554 | arigo | 2007-03-15 19:23:57 +0100 (Thu, 15 Mar 2007) | 6 lines (same guys) Enough hints to produce good code (yay! yay! yay!) from a Python function that does nothing else but a chain of additions between integers. ------------------------------------------------------------------------ r37675 | arigo | 2007-01-31 16:50:27 +0100 (Wed, 31 Jan 2007) | 2 lines A branch in which to try to make PyPy frames virtualizable. ------------------------------------------------------------------------ From arigo at codespeak.net Sun Mar 18 14:31:29 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 18 Mar 2007 14:31:29 +0100 (CET) Subject: [pypy-svn] r40671 - pypy/dist/pypy/interpreter Message-ID: <20070318133129.758C110091@code0.codespeak.net> Author: arigo Date: Sun Mar 18 14:31:23 2007 New Revision: 40671 Added: pypy/dist/pypy/interpreter/gateway.py.merge.tmp - copied, changed from r40668, pypy/dist/pypy/interpreter/gateway.py Log: merging of http://codespeak.net/svn/pypy/branch/jit-virtual-world/pypy/interpreter/gateway.py revisions 37673 to 40668: ------------------------------------------------------------------------ r40554 | arigo | 2007-03-15 19:23:57 +0100 (Thu, 15 Mar 2007) | 6 lines (same guys) Enough hints to produce good code (yay! yay! yay!) from a Python function that does nothing else but a chain of additions between integers. ------------------------------------------------------------------------ r37675 | arigo | 2007-01-31 16:50:27 +0100 (Wed, 31 Jan 2007) | 2 lines A branch in which to try to make PyPy frames virtualizable. ------------------------------------------------------------------------ From arigo at codespeak.net Sun Mar 18 14:31:36 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 18 Mar 2007 14:31:36 +0100 (CET) Subject: [pypy-svn] r40672 - pypy/dist/pypy/interpreter Message-ID: <20070318133136.867691007F@code0.codespeak.net> Author: arigo Date: Sun Mar 18 14:31:30 2007 New Revision: 40672 Added: pypy/dist/pypy/interpreter/pyframe.py.merge.tmp - copied, changed from r40668, pypy/dist/pypy/interpreter/pyframe.py Log: merging of http://codespeak.net/svn/pypy/branch/jit-virtual-world/pypy/interpreter/pyframe.py revisions 37673 to 40668: ------------------------------------------------------------------------ r38073 | pedronis | 2007-02-07 16:26:17 +0100 (Wed, 07 Feb 2007) | 8 lines (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. ------------------------------------------------------------------------ r37681 | arigo | 2007-01-31 18:36:27 +0100 (Wed, 31 Jan 2007) | 4 lines Work in progress. Modified the dispatch() header in a JIT-friendly and overwhelmingly obscure way. Exposes a bug avoid Void fields in virtualizables. ------------------------------------------------------------------------ r37675 | arigo | 2007-01-31 16:50:27 +0100 (Wed, 31 Jan 2007) | 2 lines A branch in which to try to make PyPy frames virtualizable. ------------------------------------------------------------------------ From arigo at codespeak.net Sun Mar 18 14:31:42 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 18 Mar 2007 14:31:42 +0100 (CET) Subject: [pypy-svn] r40673 - pypy/dist/pypy/interpreter Message-ID: <20070318133142.2463E10089@code0.codespeak.net> Author: arigo Date: Sun Mar 18 14:31:36 2007 New Revision: 40673 Added: pypy/dist/pypy/interpreter/pyopcode.py.merge.tmp - copied, changed from r40668, pypy/dist/pypy/interpreter/pyopcode.py Log: merging of http://codespeak.net/svn/pypy/branch/jit-virtual-world/pypy/interpreter/pyopcode.py revisions 37673 to 40668: ------------------------------------------------------------------------ r40667 | arigo | 2007-03-18 13:46:27 +0100 (Sun, 18 Mar 2007) | 2 lines Remove unused constant. ------------------------------------------------------------------------ r40633 | arigo | 2007-03-17 13:51:01 +0100 (Sat, 17 Mar 2007) | 4 lines (pedronis, arigo) Trying to fix stackless pickling in the jit branch. ------------------------------------------------------------------------ r40594 | pedronis | 2007-03-16 18:04:02 +0100 (Fri, 16 Mar 2007) | 7 lines (arigo, pedronis) trying to improve the readability of jit changes to dispatch loop, we made the portal dispatch_jit a manual copy which uses factored out helpers, the common logic is now factored out in PyFrame.handle_bytecode. In the non timeshifted case dispatch_bytecode is still looping instead of doing one bytecode at a time. ------------------------------------------------------------------------ r38073 | pedronis | 2007-02-07 16:26:17 +0100 (Wed, 07 Feb 2007) | 8 lines (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. ------------------------------------------------------------------------ r37933 | arigo | 2007-02-04 23:14:50 +0100 (Sun, 04 Feb 2007) | 10 lines (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. ------------------------------------------------------------------------ r37697 | arigo | 2007-01-31 22:59:15 +0100 (Wed, 31 Jan 2007) | 2 lines Trivial fixes. ------------------------------------------------------------------------ r37681 | arigo | 2007-01-31 18:36:27 +0100 (Wed, 31 Jan 2007) | 4 lines Work in progress. Modified the dispatch() header in a JIT-friendly and overwhelmingly obscure way. Exposes a bug avoid Void fields in virtualizables. ------------------------------------------------------------------------ r37675 | arigo | 2007-01-31 16:50:27 +0100 (Wed, 31 Jan 2007) | 2 lines A branch in which to try to make PyPy frames virtualizable. ------------------------------------------------------------------------ From arigo at codespeak.net Sun Mar 18 14:31:51 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 18 Mar 2007 14:31:51 +0100 (CET) Subject: [pypy-svn] r40674 - pypy/dist/pypy/annotation Message-ID: <20070318133151.2EC461008D@code0.codespeak.net> Author: arigo Date: Sun Mar 18 14:31:43 2007 New Revision: 40674 Added: pypy/dist/pypy/annotation/binaryop.py.merge.tmp - copied, changed from r40668, pypy/dist/pypy/annotation/binaryop.py Log: merging of http://codespeak.net/svn/pypy/branch/jit-virtual-world/pypy/annotation/binaryop.py revisions 37673 to 40668: ------------------------------------------------------------------------ r37681 | arigo | 2007-01-31 18:36:27 +0100 (Wed, 31 Jan 2007) | 4 lines Work in progress. Modified the dispatch() header in a JIT-friendly and overwhelmingly obscure way. Exposes a bug avoid Void fields in virtualizables. ------------------------------------------------------------------------ r37675 | arigo | 2007-01-31 16:50:27 +0100 (Wed, 31 Jan 2007) | 2 lines A branch in which to try to make PyPy frames virtualizable. ------------------------------------------------------------------------ From arigo at codespeak.net Sun Mar 18 14:31:57 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 18 Mar 2007 14:31:57 +0100 (CET) Subject: [pypy-svn] r40675 - pypy/dist/pypy/module/_stackless Message-ID: <20070318133157.7AA0D1008D@code0.codespeak.net> Author: arigo Date: Sun Mar 18 14:31:52 2007 New Revision: 40675 Added: pypy/dist/pypy/module/_stackless/coroutine.py.merge.tmp - copied, changed from r40668, pypy/dist/pypy/module/_stackless/coroutine.py Log: merging of http://codespeak.net/svn/pypy/branch/jit-virtual-world/pypy/module/_stackless/coroutine.py revisions 37673 to 40668: ------------------------------------------------------------------------ r40633 | arigo | 2007-03-17 13:51:01 +0100 (Sat, 17 Mar 2007) | 4 lines (pedronis, arigo) Trying to fix stackless pickling in the jit branch. ------------------------------------------------------------------------ r37675 | arigo | 2007-01-31 16:50:27 +0100 (Wed, 31 Jan 2007) | 2 lines A branch in which to try to make PyPy frames virtualizable. ------------------------------------------------------------------------ From arigo at codespeak.net Sun Mar 18 14:32:04 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 18 Mar 2007 14:32:04 +0100 (CET) Subject: [pypy-svn] r40676 - pypy/dist/pypy/objspace/std Message-ID: <20070318133204.4224210086@code0.codespeak.net> Author: arigo Date: Sun Mar 18 14:31:56 2007 New Revision: 40676 Added: pypy/dist/pypy/objspace/std/objspace.py.merge.tmp - copied, changed from r40668, pypy/dist/pypy/objspace/std/objspace.py Log: merging of http://codespeak.net/svn/pypy/branch/jit-virtual-world/pypy/objspace/std/objspace.py revisions 37673 to 40668: ------------------------------------------------------------------------ r40554 | arigo | 2007-03-15 19:23:57 +0100 (Thu, 15 Mar 2007) | 6 lines (same guys) Enough hints to produce good code (yay! yay! yay!) from a Python function that does nothing else but a chain of additions between integers. ------------------------------------------------------------------------ r37675 | arigo | 2007-01-31 16:50:27 +0100 (Wed, 31 Jan 2007) | 2 lines A branch in which to try to make PyPy frames virtualizable. ------------------------------------------------------------------------ From arigo at codespeak.net Sun Mar 18 14:32:07 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 18 Mar 2007 14:32:07 +0100 (CET) Subject: [pypy-svn] r40677 - pypy/dist/pypy/objspace/std Message-ID: <20070318133207.9EE5F10086@code0.codespeak.net> Author: arigo Date: Sun Mar 18 14:32:01 2007 New Revision: 40677 Added: pypy/dist/pypy/objspace/std/typeobject.py.merge.tmp - copied, changed from r40668, pypy/dist/pypy/objspace/std/typeobject.py Log: merging of http://codespeak.net/svn/pypy/branch/jit-virtual-world/pypy/objspace/std/typeobject.py revisions 37673 to 40668: ------------------------------------------------------------------------ r40554 | arigo | 2007-03-15 19:23:57 +0100 (Thu, 15 Mar 2007) | 6 lines (same guys) Enough hints to produce good code (yay! yay! yay!) from a Python function that does nothing else but a chain of additions between integers. ------------------------------------------------------------------------ r37675 | arigo | 2007-01-31 16:50:27 +0100 (Wed, 31 Jan 2007) | 2 lines A branch in which to try to make PyPy frames virtualizable. ------------------------------------------------------------------------ From arigo at codespeak.net Sun Mar 18 14:32:13 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 18 Mar 2007 14:32:13 +0100 (CET) Subject: [pypy-svn] r40678 - pypy/dist/pypy/jit/timeshifter Message-ID: <20070318133213.E351110086@code0.codespeak.net> Author: arigo Date: Sun Mar 18 14:32:07 2007 New Revision: 40678 Added: pypy/dist/pypy/jit/timeshifter/hrtyper.py.merge.tmp - copied, changed from r40668, pypy/dist/pypy/jit/timeshifter/hrtyper.py Log: merging of http://codespeak.net/svn/pypy/branch/jit-virtual-world/pypy/jit/timeshifter/hrtyper.py revisions 37673 to 40668: ------------------------------------------------------------------------ r40624 | arigo | 2007-03-16 23:38:02 +0100 (Fri, 16 Mar 2007) | 6 lines (pedronis, arigo) The same interface for the hrtyper as the rtyper about the need to call hannotator.simplify() - i.e., just as obscure, but at least consistently so. ------------------------------------------------------------------------ r40586 | pedronis | 2007-03-16 16:45:29 +0100 (Fri, 16 Mar 2007) | 6 lines (arigo, pedronis) - implement _is_early_constant to timeshifts to a constant-check for red boxes and to true for green variables ------------------------------------------------------------------------ r40500 | arigo | 2007-03-14 19:48:50 +0100 (Wed, 14 Mar 2007) | 6 lines (arigo, arre, pedronis) Support for the 'int_xyz_ovf' kind of operations in the timeshifter and the llgraph back-end. ------------------------------------------------------------------------ r40452 | arigo | 2007-03-13 20:42:39 +0100 (Tue, 13 Mar 2007) | 8 lines (pedronis, arigo) * a more elegant approach to indirect calls: make a ts stub for the functions that shouldn't be looked in. * timeshift support for green oopspec calls, done by having general support for green calls that can raise. ------------------------------------------------------------------------ r38127 | arigo | 2007-02-08 00:18:54 +0100 (Thu, 08 Feb 2007) | 2 lines Reduce the amount of rtimeshift.py code that is duplicated by specialization. ------------------------------------------------------------------------ r38059 | arigo | 2007-02-07 13:39:28 +0100 (Wed, 07 Feb 2007) | 28 lines (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. ------------------------------------------------------------------------ r37966 | arigo | 2007-02-05 15:23:58 +0100 (Mon, 05 Feb 2007) | 10 lines (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). ------------------------------------------------------------------------ r37952 | pedronis | 2007-02-05 03:28:09 +0100 (Mon, 05 Feb 2007) | 8 lines details: transform_graph -> timeshift_cflow timeshift_graph -> timeshift_ops progress logging during timeshifting of operations (hrtyping) ------------------------------------------------------------------------ r37951 | pedronis | 2007-02-05 02:59:39 +0100 (Mon, 05 Feb 2007) | 6 lines 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. ------------------------------------------------------------------------ r37944 | pedronis | 2007-02-05 01:12:26 +0100 (Mon, 05 Feb 2007) | 6 lines 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. ------------------------------------------------------------------------ r37932 | arigo | 2007-02-04 23:12:02 +0100 (Sun, 04 Feb 2007) | 11 lines (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. ------------------------------------------------------------------------ r37925 | pedronis | 2007-02-04 22:05:26 +0100 (Sun, 04 Feb 2007) | 3 lines copy the graphs from the hint annotator translator to the base one in timeshifting specialize ------------------------------------------------------------------------ r37902 | arigo | 2007-02-04 14:11:49 +0100 (Sun, 04 Feb 2007) | 6 lines (pedronis, arigo) Add an explicit AssertionError when using promotion but forgetting the global merge point. ------------------------------------------------------------------------ r37892 | arigo | 2007-02-04 10:39:59 +0100 (Sun, 04 Feb 2007) | 6 lines (from pedronis) Test and fix: don't use PtrRedBox() to build boxes that are not necessarily pointers. ------------------------------------------------------------------------ r37844 | arigo | 2007-02-03 01:15:36 +0100 (Sat, 03 Feb 2007) | 5 lines (pedronis, arigo) When an exception is raised by the original graphs, the timeshifted graphs now assert that the exception cannot be None. See test. ------------------------------------------------------------------------ r37823 | arigo | 2007-02-02 20:59:02 +0100 (Fri, 02 Feb 2007) | 10 lines (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! ------------------------------------------------------------------------ r37683 | ac | 2007-01-31 20:24:47 +0100 (Wed, 31 Jan 2007) | 1 line (pedronis, arre) Some support for virtualizable in virtualizable. ------------------------------------------------------------------------ r37675 | arigo | 2007-01-31 16:50:27 +0100 (Wed, 31 Jan 2007) | 2 lines A branch in which to try to make PyPy frames virtualizable. ------------------------------------------------------------------------ From arigo at codespeak.net Sun Mar 18 14:32:25 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 18 Mar 2007 14:32:25 +0100 (CET) Subject: [pypy-svn] r40679 - pypy/dist/pypy/translator/goal Message-ID: <20070318133225.DE6951008D@code0.codespeak.net> Author: arigo Date: Sun Mar 18 14:32:10 2007 New Revision: 40679 Added: pypy/dist/pypy/translator/goal/ann_override.py.merge.tmp - copied, changed from r40668, pypy/dist/pypy/translator/goal/ann_override.py Log: merging of http://codespeak.net/svn/pypy/branch/jit-virtual-world/pypy/translator/goal/ann_override.py revisions 37673 to 40668: ------------------------------------------------------------------------ r40554 | arigo | 2007-03-15 19:23:57 +0100 (Thu, 15 Mar 2007) | 6 lines (same guys) Enough hints to produce good code (yay! yay! yay!) from a Python function that does nothing else but a chain of additions between integers. ------------------------------------------------------------------------ r37675 | arigo | 2007-01-31 16:50:27 +0100 (Wed, 31 Jan 2007) | 2 lines A branch in which to try to make PyPy frames virtualizable. ------------------------------------------------------------------------ From arigo at codespeak.net Sun Mar 18 14:32:27 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 18 Mar 2007 14:32:27 +0100 (CET) Subject: [pypy-svn] r40680 - pypy/dist/pypy/translator/c Message-ID: <20070318133227.B2A6C10089@code0.codespeak.net> Author: arigo Date: Sun Mar 18 14:32:17 2007 New Revision: 40680 Added: pypy/dist/pypy/translator/c/exceptiontransform.py.merge.tmp - copied, changed from r40668, pypy/dist/pypy/translator/c/exceptiontransform.py Log: merging of http://codespeak.net/svn/pypy/branch/jit-virtual-world/pypy/translator/c/exceptiontransform.py revisions 37673 to 40668: ------------------------------------------------------------------------ r38056 | arigo | 2007-02-07 13:25:25 +0100 (Wed, 07 Feb 2007) | 3 lines (pedronis, arigo) Change the direction of the check in exception transform. A pure JIT hack. ------------------------------------------------------------------------ r37966 | arigo | 2007-02-05 15:23:58 +0100 (Mon, 05 Feb 2007) | 10 lines (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). ------------------------------------------------------------------------ r37844 | arigo | 2007-02-03 01:15:36 +0100 (Sat, 03 Feb 2007) | 5 lines (pedronis, arigo) When an exception is raised by the original graphs, the timeshifted graphs now assert that the exception cannot be None. See test. ------------------------------------------------------------------------ r37675 | arigo | 2007-01-31 16:50:27 +0100 (Wed, 31 Jan 2007) | 2 lines A branch in which to try to make PyPy frames virtualizable. ------------------------------------------------------------------------ From arigo at codespeak.net Sun Mar 18 14:32:34 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 18 Mar 2007 14:32:34 +0100 (CET) Subject: [pypy-svn] r40681 - pypy/dist/pypy/translator/c Message-ID: <20070318133234.58EC610089@code0.codespeak.net> Author: arigo Date: Sun Mar 18 14:32:27 2007 New Revision: 40681 Added: pypy/dist/pypy/translator/c/funcgen.py.merge.tmp - copied, changed from r40668, pypy/dist/pypy/translator/c/funcgen.py Log: merging of http://codespeak.net/svn/pypy/branch/jit-virtual-world/pypy/translator/c/funcgen.py revisions 37673 to 40668: ------------------------------------------------------------------------ r40585 | ac | 2007-03-16 15:32:33 +0100 (Fri, 16 Mar 2007) | 1 line Support is_early_constant operasion in C backend. ------------------------------------------------------------------------ r37675 | arigo | 2007-01-31 16:50:27 +0100 (Wed, 31 Jan 2007) | 2 lines A branch in which to try to make PyPy frames virtualizable. ------------------------------------------------------------------------ From arigo at codespeak.net Sun Mar 18 14:32:42 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 18 Mar 2007 14:32:42 +0100 (CET) Subject: [pypy-svn] r40682 - pypy/dist/pypy/translator/cli Message-ID: <20070318133242.C92E210089@code0.codespeak.net> Author: arigo Date: Sun Mar 18 14:32:36 2007 New Revision: 40682 Added: pypy/dist/pypy/translator/cli/opcodes.py.merge.tmp - copied, changed from r40668, pypy/dist/pypy/translator/cli/opcodes.py Log: merging of http://codespeak.net/svn/pypy/branch/jit-virtual-world/pypy/translator/cli/opcodes.py revisions 37673 to 40668: ------------------------------------------------------------------------ r40591 | ac | 2007-03-16 17:49:30 +0100 (Fri, 16 Mar 2007) | 1 line is_early_constant for cli. ------------------------------------------------------------------------ r37675 | arigo | 2007-01-31 16:50:27 +0100 (Wed, 31 Jan 2007) | 2 lines A branch in which to try to make PyPy frames virtualizable. ------------------------------------------------------------------------ From arigo at codespeak.net Sun Mar 18 14:32:46 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 18 Mar 2007 14:32:46 +0100 (CET) Subject: [pypy-svn] r40683 - pypy/dist/pypy/translator/llvm Message-ID: <20070318133246.9EF1D1008A@code0.codespeak.net> Author: arigo Date: Sun Mar 18 14:32:43 2007 New Revision: 40683 Added: pypy/dist/pypy/translator/llvm/opwriter.py.merge.tmp - copied, changed from r40668, pypy/dist/pypy/translator/llvm/opwriter.py Log: merging of http://codespeak.net/svn/pypy/branch/jit-virtual-world/pypy/translator/llvm/opwriter.py revisions 37673 to 40668: ------------------------------------------------------------------------ r40587 | ac | 2007-03-16 17:05:04 +0100 (Fri, 16 Mar 2007) | 1 line is_early_constant for llvm. ------------------------------------------------------------------------ r37675 | arigo | 2007-01-31 16:50:27 +0100 (Wed, 31 Jan 2007) | 2 lines A branch in which to try to make PyPy frames virtualizable. ------------------------------------------------------------------------ From arigo at codespeak.net Sun Mar 18 14:32:53 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 18 Mar 2007 14:32:53 +0100 (CET) Subject: [pypy-svn] r40684 - pypy/dist/pypy/translator/backendopt Message-ID: <20070318133253.13F9710089@code0.codespeak.net> Author: arigo Date: Sun Mar 18 14:32:47 2007 New Revision: 40684 Added: pypy/dist/pypy/translator/backendopt/all.py.merge.tmp - copied, changed from r40668, pypy/dist/pypy/translator/backendopt/all.py Log: merging of http://codespeak.net/svn/pypy/branch/jit-virtual-world/pypy/translator/backendopt/all.py revisions 37673 to 40668: ------------------------------------------------------------------------ r38055 | arigo | 2007-02-07 13:24:34 +0100 (Wed, 07 Feb 2007) | 4 lines 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. ------------------------------------------------------------------------ r37848 | pedronis | 2007-02-03 04:21:59 +0100 (Sat, 03 Feb 2007) | 3 lines umph ------------------------------------------------------------------------ r37675 | arigo | 2007-01-31 16:50:27 +0100 (Wed, 31 Jan 2007) | 2 lines A branch in which to try to make PyPy frames virtualizable. ------------------------------------------------------------------------ From arigo at codespeak.net Sun Mar 18 14:33:00 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 18 Mar 2007 14:33:00 +0100 (CET) Subject: [pypy-svn] r40685 - pypy/dist/pypy/translator/backendopt Message-ID: <20070318133300.5FDE710089@code0.codespeak.net> Author: arigo Date: Sun Mar 18 14:32:51 2007 New Revision: 40685 Added: pypy/dist/pypy/translator/backendopt/removeassert.py.merge.tmp - copied, changed from r40668, pypy/dist/pypy/translator/backendopt/removeassert.py Log: merging of http://codespeak.net/svn/pypy/branch/jit-virtual-world/pypy/translator/backendopt/removeassert.py revisions 37673 to 40668: ------------------------------------------------------------------------ r38055 | arigo | 2007-02-07 13:24:34 +0100 (Wed, 07 Feb 2007) | 4 lines 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. ------------------------------------------------------------------------ r37675 | arigo | 2007-01-31 16:50:27 +0100 (Wed, 31 Jan 2007) | 2 lines A branch in which to try to make PyPy frames virtualizable. ------------------------------------------------------------------------ From arigo at codespeak.net Sun Mar 18 14:33:02 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 18 Mar 2007 14:33:02 +0100 (CET) Subject: [pypy-svn] r40686 - pypy/dist/pypy/translator/backendopt Message-ID: <20070318133302.E69E010086@code0.codespeak.net> Author: arigo Date: Sun Mar 18 14:32:57 2007 New Revision: 40686 Added: pypy/dist/pypy/translator/backendopt/support.py.merge.tmp - copied, changed from r40668, pypy/dist/pypy/translator/backendopt/support.py Log: merging of http://codespeak.net/svn/pypy/branch/jit-virtual-world/pypy/translator/backendopt/support.py revisions 37673 to 40668: ------------------------------------------------------------------------ r40479 | arigo | 2007-03-14 13:50:31 +0100 (Wed, 14 Mar 2007) | 5 lines (arre, pedronis, arigo) Fix a bug in the call graph generation (the dict couldn't represent a function that contains several calls to another). ------------------------------------------------------------------------ r37675 | arigo | 2007-01-31 16:50:27 +0100 (Wed, 31 Jan 2007) | 2 lines A branch in which to try to make PyPy frames virtualizable. ------------------------------------------------------------------------ From arigo at codespeak.net Sun Mar 18 14:33:07 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 18 Mar 2007 14:33:07 +0100 (CET) Subject: [pypy-svn] r40687 - pypy/dist/pypy/translator/oosupport Message-ID: <20070318133307.37F9910086@code0.codespeak.net> Author: arigo Date: Sun Mar 18 14:33:02 2007 New Revision: 40687 Added: pypy/dist/pypy/translator/oosupport/metavm.py.merge.tmp - copied, changed from r40668, pypy/dist/pypy/translator/oosupport/metavm.py Log: merging of http://codespeak.net/svn/pypy/branch/jit-virtual-world/pypy/translator/oosupport/metavm.py revisions 37673 to 40668: ------------------------------------------------------------------------ r40591 | ac | 2007-03-16 17:49:30 +0100 (Fri, 16 Mar 2007) | 1 line is_early_constant for cli. ------------------------------------------------------------------------ r37675 | arigo | 2007-01-31 16:50:27 +0100 (Wed, 31 Jan 2007) | 2 lines A branch in which to try to make PyPy frames virtualizable. ------------------------------------------------------------------------ From arigo at codespeak.net Sun Mar 18 14:33:17 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 18 Mar 2007 14:33:17 +0100 (CET) Subject: [pypy-svn] r40688 - pypy/dist/pypy/translator/js Message-ID: <20070318133317.6C05610086@code0.codespeak.net> Author: arigo Date: Sun Mar 18 14:33:11 2007 New Revision: 40688 Added: pypy/dist/pypy/translator/js/function.py.merge.tmp - copied, changed from r40668, pypy/dist/pypy/translator/js/function.py Log: merging of http://codespeak.net/svn/pypy/branch/jit-virtual-world/pypy/translator/js/function.py revisions 37673 to 40668: ------------------------------------------------------------------------ r40595 | ac | 2007-03-16 18:06:16 +0100 (Fri, 16 Mar 2007) | 1 line is_early_constant for JavaScript. ------------------------------------------------------------------------ r37675 | arigo | 2007-01-31 16:50:27 +0100 (Wed, 31 Jan 2007) | 2 lines A branch in which to try to make PyPy frames virtualizable. ------------------------------------------------------------------------ From arigo at codespeak.net Sun Mar 18 14:33:24 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 18 Mar 2007 14:33:24 +0100 (CET) Subject: [pypy-svn] r40689 - pypy/dist/pypy/translator/js Message-ID: <20070318133324.EC51B10086@code0.codespeak.net> Author: arigo Date: Sun Mar 18 14:33:16 2007 New Revision: 40689 Added: pypy/dist/pypy/translator/js/opcodes.py.merge.tmp - copied, changed from r40668, pypy/dist/pypy/translator/js/opcodes.py Log: merging of http://codespeak.net/svn/pypy/branch/jit-virtual-world/pypy/translator/js/opcodes.py revisions 37673 to 40668: ------------------------------------------------------------------------ r40595 | ac | 2007-03-16 18:06:16 +0100 (Fri, 16 Mar 2007) | 1 line is_early_constant for JavaScript. ------------------------------------------------------------------------ r37675 | arigo | 2007-01-31 16:50:27 +0100 (Wed, 31 Jan 2007) | 2 lines A branch in which to try to make PyPy frames virtualizable. ------------------------------------------------------------------------ From arigo at codespeak.net Sun Mar 18 14:33:30 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 18 Mar 2007 14:33:30 +0100 (CET) Subject: [pypy-svn] r40690 - pypy/dist/pypy/rpython/lltypesystem Message-ID: <20070318133330.1D03510086@code0.codespeak.net> Author: arigo Date: Sun Mar 18 14:33:20 2007 New Revision: 40690 Added: pypy/dist/pypy/rpython/lltypesystem/lloperation.py.merge.tmp - copied, changed from r40668, pypy/dist/pypy/rpython/lltypesystem/lloperation.py Log: merging of http://codespeak.net/svn/pypy/branch/jit-virtual-world/pypy/rpython/lltypesystem/lloperation.py revisions 37673 to 40668: ------------------------------------------------------------------------ r40621 | arigo | 2007-03-16 23:01:47 +0100 (Fri, 16 Mar 2007) | 2 lines Complete the operation table. ------------------------------------------------------------------------ r40583 | pedronis | 2007-03-16 14:04:32 +0100 (Fri, 16 Mar 2007) | 3 lines oops, forgot to add the new test file ------------------------------------------------------------------------ r40500 | arigo | 2007-03-14 19:48:50 +0100 (Wed, 14 Mar 2007) | 6 lines (arigo, arre, pedronis) Support for the 'int_xyz_ovf' kind of operations in the timeshifter and the llgraph back-end. ------------------------------------------------------------------------ r37675 | arigo | 2007-01-31 16:50:27 +0100 (Wed, 31 Jan 2007) | 2 lines A branch in which to try to make PyPy frames virtualizable. ------------------------------------------------------------------------ From arigo at codespeak.net Sun Mar 18 14:33:36 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 18 Mar 2007 14:33:36 +0100 (CET) Subject: [pypy-svn] r40691 - pypy/dist/pypy/rpython/lltypesystem Message-ID: <20070318133336.0882110092@code0.codespeak.net> Author: arigo Date: Sun Mar 18 14:33:24 2007 New Revision: 40691 Added: pypy/dist/pypy/rpython/lltypesystem/opimpl.py.merge.tmp - copied, changed from r40668, pypy/dist/pypy/rpython/lltypesystem/opimpl.py Log: merging of http://codespeak.net/svn/pypy/branch/jit-virtual-world/pypy/rpython/lltypesystem/opimpl.py revisions 37673 to 40668: ------------------------------------------------------------------------ r40622 | arigo | 2007-03-16 23:06:38 +0100 (Fri, 16 Mar 2007) | 7 lines (arigo, pedronis) We should never constant-folding CDefinedIntSymbolics. Only the llinterpreter is allowed to use the 'default'. The hintannotator test failed because of that. ------------------------------------------------------------------------ r37675 | arigo | 2007-01-31 16:50:27 +0100 (Wed, 31 Jan 2007) | 2 lines A branch in which to try to make PyPy frames virtualizable. ------------------------------------------------------------------------ From arigo at codespeak.net Sun Mar 18 14:34:04 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 18 Mar 2007 14:34:04 +0100 (CET) Subject: [pypy-svn] r40692 - pypy/dist/pypy/rpython/test Message-ID: <20070318133404.119561008A@code0.codespeak.net> Author: arigo Date: Sun Mar 18 14:33:38 2007 New Revision: 40692 Added: pypy/dist/pypy/rpython/test/test_rpbc.py.merge.tmp - copied, changed from r40668, pypy/dist/pypy/rpython/test/test_rpbc.py Log: merging of http://codespeak.net/svn/pypy/branch/jit-virtual-world/pypy/rpython/test/test_rpbc.py revisions 37673 to 40668: ------------------------------------------------------------------------ r37819 | arigo | 2007-02-02 20:35:23 +0100 (Fri, 02 Feb 2007) | 2 lines A strange case of method call that showed up in the JIT. ------------------------------------------------------------------------ r37675 | arigo | 2007-01-31 16:50:27 +0100 (Wed, 31 Jan 2007) | 2 lines A branch in which to try to make PyPy frames virtualizable. ------------------------------------------------------------------------ From arigo at codespeak.net Sun Mar 18 14:34:12 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 18 Mar 2007 14:34:12 +0100 (CET) Subject: [pypy-svn] r40693 - pypy/dist/pypy/jit/codegen/test Message-ID: <20070318133412.99FAD10086@code0.codespeak.net> Author: arigo Date: Sun Mar 18 14:33:57 2007 New Revision: 40693 Added: pypy/dist/pypy/jit/codegen/test/rgenop_tests.py.merge.tmp - copied, changed from r40668, pypy/dist/pypy/jit/codegen/test/rgenop_tests.py Log: merging of http://codespeak.net/svn/pypy/branch/jit-virtual-world/pypy/jit/codegen/test/rgenop_tests.py revisions 37673 to 40668: ------------------------------------------------------------------------ r40547 | arigo | 2007-03-15 17:18:00 +0100 (Thu, 15 Mar 2007) | 2 lines (arigo, pedronis, arre) Support for some of the _ovf operations in the 386 backend. ------------------------------------------------------------------------ r38136 | arigo | 2007-02-08 11:12:34 +0100 (Thu, 08 Feb 2007) | 2 lines Merge the new 386 jit backend into the jit-virtual-world branch. ------------------------------------------------------------------------ r38130 | arigo | 2007-02-08 00:21:58 +0100 (Thu, 08 Feb 2007) | 6 lines 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 :-) ------------------------------------------------------------------------ r38086 | arigo | 2007-02-07 19:06:07 +0100 (Wed, 07 Feb 2007) | 2 lines Forgot this with previous check-in. ------------------------------------------------------------------------ r38080 | arigo | 2007-02-07 17:09:11 +0100 (Wed, 07 Feb 2007) | 2 lines Fixes, and a new test, for places with no initial value. ------------------------------------------------------------------------ r38060 | arigo | 2007-02-07 13:44:55 +0100 (Wed, 07 Feb 2007) | 2 lines A branch with a refactoring of the i386 backend. ------------------------------------------------------------------------ r37842 | arigo | 2007-02-03 01:07:26 +0100 (Sat, 03 Feb 2007) | 2 lines This is the test that shows the problem solved by r37836. ------------------------------------------------------------------------ r37821 | arigo | 2007-02-02 20:55:35 +0100 (Fri, 02 Feb 2007) | 6 lines (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. ------------------------------------------------------------------------ r37675 | arigo | 2007-01-31 16:50:27 +0100 (Wed, 31 Jan 2007) | 2 lines A branch in which to try to make PyPy frames virtualizable. ------------------------------------------------------------------------ From arigo at codespeak.net Sun Mar 18 14:34:14 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 18 Mar 2007 14:34:14 +0100 (CET) Subject: [pypy-svn] r40694 - pypy/dist/pypy/jit/codegen/ppc Message-ID: <20070318133414.CF50710089@code0.codespeak.net> Author: arigo Date: Sun Mar 18 14:34:02 2007 New Revision: 40694 Added: pypy/dist/pypy/jit/codegen/ppc/rgenop.py.merge.tmp - copied, changed from r40668, pypy/dist/pypy/jit/codegen/ppc/rgenop.py Log: merging of http://codespeak.net/svn/pypy/branch/jit-virtual-world/pypy/jit/codegen/ppc/rgenop.py revisions 37673 to 40668: ------------------------------------------------------------------------ r38136 | arigo | 2007-02-08 11:12:34 +0100 (Thu, 08 Feb 2007) | 2 lines Merge the new 386 jit backend into the jit-virtual-world branch. ------------------------------------------------------------------------ r38060 | arigo | 2007-02-07 13:44:55 +0100 (Wed, 07 Feb 2007) | 2 lines A branch with a refactoring of the i386 backend. ------------------------------------------------------------------------ r37821 | arigo | 2007-02-02 20:55:35 +0100 (Fri, 02 Feb 2007) | 6 lines (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. ------------------------------------------------------------------------ r37675 | arigo | 2007-01-31 16:50:27 +0100 (Wed, 31 Jan 2007) | 2 lines A branch in which to try to make PyPy frames virtualizable. ------------------------------------------------------------------------ From arigo at codespeak.net Sun Mar 18 14:34:16 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 18 Mar 2007 14:34:16 +0100 (CET) Subject: [pypy-svn] r40695 - pypy/dist/pypy/jit/codegen/llvm Message-ID: <20070318133416.1932210086@code0.codespeak.net> Author: arigo Date: Sun Mar 18 14:34:07 2007 New Revision: 40695 Added: pypy/dist/pypy/jit/codegen/llvm/rgenop.py.merge.tmp - copied, changed from r40668, pypy/dist/pypy/jit/codegen/llvm/rgenop.py Log: merging of http://codespeak.net/svn/pypy/branch/jit-virtual-world/pypy/jit/codegen/llvm/rgenop.py revisions 37673 to 40668: ------------------------------------------------------------------------ r38136 | arigo | 2007-02-08 11:12:34 +0100 (Thu, 08 Feb 2007) | 2 lines Merge the new 386 jit backend into the jit-virtual-world branch. ------------------------------------------------------------------------ r38060 | arigo | 2007-02-07 13:44:55 +0100 (Wed, 07 Feb 2007) | 2 lines A branch with a refactoring of the i386 backend. ------------------------------------------------------------------------ r37821 | arigo | 2007-02-02 20:55:35 +0100 (Fri, 02 Feb 2007) | 6 lines (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. ------------------------------------------------------------------------ r37675 | arigo | 2007-01-31 16:50:27 +0100 (Wed, 31 Jan 2007) | 2 lines A branch in which to try to make PyPy frames virtualizable. ------------------------------------------------------------------------ From arigo at codespeak.net Sun Mar 18 14:35:40 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 18 Mar 2007 14:35:40 +0100 (CET) Subject: [pypy-svn] r40696 - in pypy/dist/pypy: annotation interpreter jit jit/codegen jit/codegen/demo jit/codegen/dump jit/codegen/i386 jit/codegen/llgraph jit/codegen/llvm jit/codegen/ppc jit/codegen/test jit/goal jit/hintannotator jit/timeshifter jit/timeshifter/test module/_stackless module/pypyjit objspace/flow objspace/std rlib rlib/test rpython rpython/lltypesystem rpython/lltypesystem/test rpython/ootypesystem rpython/test translator translator/backendopt translator/backendopt/test translator/c translator/c/test translator/cli translator/goal translator/js translator/llvm translator/llvm/test translator/oosupport translator/oosupport/test_template translator/tool translator/tool/pygame translator/tool/test Message-ID: <20070318133540.78CA810086@code0.codespeak.net> Author: arigo Date: Sun Mar 18 14:35:37 2007 New Revision: 40696 Added: pypy/dist/pypy/annotation/binaryop.py - copied unchanged from r40695, pypy/dist/pypy/annotation/binaryop.py.merge.tmp pypy/dist/pypy/interpreter/function.py - copied unchanged from r40695, pypy/dist/pypy/interpreter/function.py.merge.tmp pypy/dist/pypy/interpreter/gateway.py - copied unchanged from r40695, pypy/dist/pypy/interpreter/gateway.py.merge.tmp pypy/dist/pypy/interpreter/pyframe.py - copied unchanged from r40695, pypy/dist/pypy/interpreter/pyframe.py.merge.tmp pypy/dist/pypy/interpreter/pyopcode.py - copied unchanged from r40695, pypy/dist/pypy/interpreter/pyopcode.py.merge.tmp pypy/dist/pypy/jit/TODO.txt - copied unchanged from r40695, pypy/branch/jit-virtual-world/pypy/jit/TODO.txt pypy/dist/pypy/jit/codegen/demo/ - copied from r40695, pypy/branch/jit-virtual-world/pypy/jit/codegen/demo/ pypy/dist/pypy/jit/codegen/dump/ - copied from r40695, pypy/branch/jit-virtual-world/pypy/jit/codegen/dump/ pypy/dist/pypy/jit/codegen/i386/ - copied from r40695, pypy/branch/jit-virtual-world/pypy/jit/codegen/i386/ pypy/dist/pypy/jit/codegen/llgraph/ - copied from r40695, pypy/branch/jit-virtual-world/pypy/jit/codegen/llgraph/ pypy/dist/pypy/jit/codegen/llvm/rgenop.py - copied unchanged from r40695, pypy/dist/pypy/jit/codegen/llvm/rgenop.py.merge.tmp pypy/dist/pypy/jit/codegen/model.py - copied unchanged from r40695, pypy/branch/jit-virtual-world/pypy/jit/codegen/model.py pypy/dist/pypy/jit/codegen/ppc/rgenop.py - copied unchanged from r40695, pypy/dist/pypy/jit/codegen/ppc/rgenop.py.merge.tmp pypy/dist/pypy/jit/codegen/test/operation_tests.py - copied unchanged from r40695, pypy/branch/jit-virtual-world/pypy/jit/codegen/test/operation_tests.py pypy/dist/pypy/jit/codegen/test/rgenop_tests.py - copied unchanged from r40695, pypy/dist/pypy/jit/codegen/test/rgenop_tests.py.merge.tmp pypy/dist/pypy/jit/goal/ - copied from r40695, pypy/branch/jit-virtual-world/pypy/jit/goal/ pypy/dist/pypy/jit/hintannotator/ - copied from r40695, pypy/branch/jit-virtual-world/pypy/jit/hintannotator/ pypy/dist/pypy/jit/timeshifter/exception.py - copied unchanged from r40695, pypy/branch/jit-virtual-world/pypy/jit/timeshifter/exception.py pypy/dist/pypy/jit/timeshifter/hrtyper.py - copied unchanged from r40695, pypy/dist/pypy/jit/timeshifter/hrtyper.py.merge.tmp pypy/dist/pypy/jit/timeshifter/oop.py - copied unchanged from r40695, pypy/branch/jit-virtual-world/pypy/jit/timeshifter/oop.py pypy/dist/pypy/jit/timeshifter/rcontainer.py - copied unchanged from r40695, pypy/branch/jit-virtual-world/pypy/jit/timeshifter/rcontainer.py pypy/dist/pypy/jit/timeshifter/rtimeshift.py - copied unchanged from r40695, pypy/branch/jit-virtual-world/pypy/jit/timeshifter/rtimeshift.py pypy/dist/pypy/jit/timeshifter/rvalue.py - copied unchanged from r40695, pypy/branch/jit-virtual-world/pypy/jit/timeshifter/rvalue.py pypy/dist/pypy/jit/timeshifter/test/ - copied from r40695, pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/ pypy/dist/pypy/jit/timeshifter/transform.py - copied unchanged from r40695, pypy/branch/jit-virtual-world/pypy/jit/timeshifter/transform.py pypy/dist/pypy/jit/timeshifter/vdict.py - copied unchanged from r40695, pypy/branch/jit-virtual-world/pypy/jit/timeshifter/vdict.py pypy/dist/pypy/jit/timeshifter/vlist.py - copied unchanged from r40695, pypy/branch/jit-virtual-world/pypy/jit/timeshifter/vlist.py pypy/dist/pypy/module/_stackless/coroutine.py - copied unchanged from r40695, pypy/dist/pypy/module/_stackless/coroutine.py.merge.tmp pypy/dist/pypy/module/pypyjit/ - copied from r40695, pypy/branch/jit-virtual-world/pypy/module/pypyjit/ pypy/dist/pypy/objspace/flow/flowcontext.py - copied unchanged from r40695, pypy/branch/jit-virtual-world/pypy/objspace/flow/flowcontext.py pypy/dist/pypy/objspace/flow/model.py - copied unchanged from r40695, pypy/branch/jit-virtual-world/pypy/objspace/flow/model.py pypy/dist/pypy/objspace/std/multimethod.py - copied unchanged from r40695, pypy/branch/jit-virtual-world/pypy/objspace/std/multimethod.py pypy/dist/pypy/objspace/std/objspace.py - copied unchanged from r40695, pypy/dist/pypy/objspace/std/objspace.py.merge.tmp pypy/dist/pypy/objspace/std/typeobject.py - copied unchanged from r40695, pypy/dist/pypy/objspace/std/typeobject.py.merge.tmp pypy/dist/pypy/rlib/objectmodel.py - copied unchanged from r40695, pypy/branch/jit-virtual-world/pypy/rlib/objectmodel.py pypy/dist/pypy/rlib/test/test_objectmodel.py - copied unchanged from r40695, pypy/branch/jit-virtual-world/pypy/rlib/test/test_objectmodel.py pypy/dist/pypy/rpython/llinterp.py - copied unchanged from r40695, pypy/dist/pypy/rpython/llinterp.py.merge.tmp pypy/dist/pypy/rpython/lltypesystem/lloperation.py - copied unchanged from r40695, pypy/dist/pypy/rpython/lltypesystem/lloperation.py.merge.tmp pypy/dist/pypy/rpython/lltypesystem/opimpl.py - copied unchanged from r40695, pypy/dist/pypy/rpython/lltypesystem/opimpl.py.merge.tmp pypy/dist/pypy/rpython/lltypesystem/rclass.py - copied unchanged from r40695, pypy/branch/jit-virtual-world/pypy/rpython/lltypesystem/rclass.py pypy/dist/pypy/rpython/lltypesystem/rdict.py - copied unchanged from r40695, pypy/branch/jit-virtual-world/pypy/rpython/lltypesystem/rdict.py pypy/dist/pypy/rpython/lltypesystem/rstr.py - copied unchanged from r40695, pypy/branch/jit-virtual-world/pypy/rpython/lltypesystem/rstr.py pypy/dist/pypy/rpython/lltypesystem/rvirtualizable.py - copied unchanged from r40695, pypy/branch/jit-virtual-world/pypy/rpython/lltypesystem/rvirtualizable.py pypy/dist/pypy/rpython/lltypesystem/test/ - copied from r40695, pypy/branch/jit-virtual-world/pypy/rpython/lltypesystem/test/ pypy/dist/pypy/rpython/ootypesystem/rpbc.py - copied unchanged from r40695, pypy/branch/jit-virtual-world/pypy/rpython/ootypesystem/rpbc.py pypy/dist/pypy/rpython/rlist.py - copied unchanged from r40695, pypy/branch/jit-virtual-world/pypy/rpython/rlist.py pypy/dist/pypy/rpython/rpbc.py - copied unchanged from r40695, pypy/branch/jit-virtual-world/pypy/rpython/rpbc.py pypy/dist/pypy/rpython/test/test_llinterp.py - copied unchanged from r40695, pypy/branch/jit-virtual-world/pypy/rpython/test/test_llinterp.py pypy/dist/pypy/rpython/test/test_rpbc.py - copied unchanged from r40695, pypy/dist/pypy/rpython/test/test_rpbc.py.merge.tmp pypy/dist/pypy/translator/backendopt/all.py - copied unchanged from r40695, pypy/dist/pypy/translator/backendopt/all.py.merge.tmp pypy/dist/pypy/translator/backendopt/removeassert.py - copied unchanged from r40695, pypy/dist/pypy/translator/backendopt/removeassert.py.merge.tmp pypy/dist/pypy/translator/backendopt/support.py - copied unchanged from r40695, pypy/dist/pypy/translator/backendopt/support.py.merge.tmp pypy/dist/pypy/translator/backendopt/test/test_removeassert.py - copied unchanged from r40695, pypy/branch/jit-virtual-world/pypy/translator/backendopt/test/test_removeassert.py pypy/dist/pypy/translator/c/exceptiontransform.py - copied unchanged from r40695, pypy/dist/pypy/translator/c/exceptiontransform.py.merge.tmp pypy/dist/pypy/translator/c/funcgen.py - copied unchanged from r40695, pypy/dist/pypy/translator/c/funcgen.py.merge.tmp pypy/dist/pypy/translator/c/test/test_symbolic.py - copied unchanged from r40695, pypy/branch/jit-virtual-world/pypy/translator/c/test/test_symbolic.py pypy/dist/pypy/translator/cli/opcodes.py - copied unchanged from r40695, pypy/dist/pypy/translator/cli/opcodes.py.merge.tmp pypy/dist/pypy/translator/goal/ann_override.py - copied unchanged from r40695, pypy/dist/pypy/translator/goal/ann_override.py.merge.tmp pypy/dist/pypy/translator/goal/richards.py - copied unchanged from r40695, pypy/branch/jit-virtual-world/pypy/translator/goal/richards.py pypy/dist/pypy/translator/js/function.py - copied unchanged from r40695, pypy/dist/pypy/translator/js/function.py.merge.tmp pypy/dist/pypy/translator/js/opcodes.py - copied unchanged from r40695, pypy/dist/pypy/translator/js/opcodes.py.merge.tmp pypy/dist/pypy/translator/llvm/opwriter.py - copied unchanged from r40695, pypy/dist/pypy/translator/llvm/opwriter.py.merge.tmp pypy/dist/pypy/translator/llvm/test/test_symbolic.py - copied unchanged from r40695, pypy/branch/jit-virtual-world/pypy/translator/llvm/test/test_symbolic.py pypy/dist/pypy/translator/oosupport/metavm.py - copied unchanged from r40695, pypy/dist/pypy/translator/oosupport/metavm.py.merge.tmp pypy/dist/pypy/translator/oosupport/test_template/ - copied from r40695, pypy/branch/jit-virtual-world/pypy/translator/oosupport/test_template/ pypy/dist/pypy/translator/tool/pygame/ - copied from r40695, pypy/branch/jit-virtual-world/pypy/translator/tool/pygame/ pypy/dist/pypy/translator/tool/taskengine.py - copied unchanged from r40695, pypy/branch/jit-virtual-world/pypy/translator/tool/taskengine.py pypy/dist/pypy/translator/tool/test/ - copied from r40695, pypy/branch/jit-virtual-world/pypy/translator/tool/test/ pypy/dist/pypy/translator/transform.py - copied unchanged from r40695, pypy/branch/jit-virtual-world/pypy/translator/transform.py Removed: pypy/dist/pypy/annotation/binaryop.py.merge.tmp pypy/dist/pypy/interpreter/function.py.merge.tmp pypy/dist/pypy/interpreter/gateway.py.merge.tmp pypy/dist/pypy/interpreter/pyframe.py.merge.tmp pypy/dist/pypy/interpreter/pyopcode.py.merge.tmp pypy/dist/pypy/jit/codegen/llvm/rgenop.py.merge.tmp pypy/dist/pypy/jit/codegen/ppc/rgenop.py.merge.tmp pypy/dist/pypy/jit/codegen/test/rgenop_tests.py.merge.tmp pypy/dist/pypy/jit/timeshifter/hrtyper.py.merge.tmp pypy/dist/pypy/module/_stackless/coroutine.py.merge.tmp pypy/dist/pypy/objspace/std/objspace.py.merge.tmp pypy/dist/pypy/objspace/std/typeobject.py.merge.tmp pypy/dist/pypy/rpython/llinterp.py.merge.tmp pypy/dist/pypy/rpython/lltypesystem/lloperation.py.merge.tmp pypy/dist/pypy/rpython/lltypesystem/opimpl.py.merge.tmp pypy/dist/pypy/rpython/test/test_rpbc.py.merge.tmp pypy/dist/pypy/translator/backendopt/all.py.merge.tmp pypy/dist/pypy/translator/backendopt/removeassert.py.merge.tmp pypy/dist/pypy/translator/backendopt/support.py.merge.tmp pypy/dist/pypy/translator/c/exceptiontransform.py.merge.tmp pypy/dist/pypy/translator/c/funcgen.py.merge.tmp pypy/dist/pypy/translator/cli/opcodes.py.merge.tmp pypy/dist/pypy/translator/goal/ann_override.py.merge.tmp pypy/dist/pypy/translator/js/function.py.merge.tmp pypy/dist/pypy/translator/js/opcodes.py.merge.tmp pypy/dist/pypy/translator/llvm/opwriter.py.merge.tmp pypy/dist/pypy/translator/oosupport/metavm.py.merge.tmp Log: (pedronis, arigo) Complete the merge of the jit-virtual-world branch. From arigo at codespeak.net Sun Mar 18 14:36:28 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 18 Mar 2007 14:36:28 +0100 (CET) Subject: [pypy-svn] r40697 - pypy/branch/jit-virtual-world Message-ID: <20070318133628.1641510086@code0.codespeak.net> Author: arigo Date: Sun Mar 18 14:36:26 2007 New Revision: 40697 Removed: pypy/branch/jit-virtual-world/ Log: (pedronis, arigo) Remove merged branch. From arigo at codespeak.net Sun Mar 18 14:37:09 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 18 Mar 2007 14:37:09 +0100 (CET) Subject: [pypy-svn] r40698 - pypy/branch/debug-jit Message-ID: <20070318133709.6E47310086@code0.codespeak.net> Author: arigo Date: Sun Mar 18 14:37:07 2007 New Revision: 40698 Removed: pypy/branch/debug-jit/ Log: Remove temporary branch. From arigo at codespeak.net Sun Mar 18 14:38:23 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 18 Mar 2007 14:38:23 +0100 (CET) Subject: [pypy-svn] r40699 - pypy/branch/method-cache Message-ID: <20070318133823.E0BC510086@code0.codespeak.net> Author: arigo Date: Sun Mar 18 14:38:21 2007 New Revision: 40699 Removed: pypy/branch/method-cache/ Log: Kill old branch. From arigo at codespeak.net Sun Mar 18 14:41:18 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 18 Mar 2007 14:41:18 +0100 (CET) Subject: [pypy-svn] r40700 - pypy/dist/pypy/translator/js/test Message-ID: <20070318134118.5957310086@code0.codespeak.net> Author: arigo Date: Sun Mar 18 14:41:15 2007 New Revision: 40700 Modified: pypy/dist/pypy/translator/js/test/test_rsnippet.py Log: Leftover from the merge of the jit-virtual-world branch. Modified: pypy/dist/pypy/translator/js/test/test_rsnippet.py ============================================================================== --- pypy/dist/pypy/translator/js/test/test_rsnippet.py (original) +++ pypy/dist/pypy/translator/js/test/test_rsnippet.py Sun Mar 18 14:41:15 2007 @@ -441,3 +441,13 @@ fn = compile_function(symbolic1, []) assert fn() == 2 + +def test_is_early_constant(): + from pypy.rlib import objectmodel + def f(x): + if objectmodel._is_early_constant(x): + return 42 + return 0 + fn = compile_function(f, [int]) + res = fn(5) + assert res == 0 From arigo at codespeak.net Sun Mar 18 15:13:26 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 18 Mar 2007 15:13:26 +0100 (CET) Subject: [pypy-svn] r40701 - in pypy/dist/pypy/jit/codegen: i386 test Message-ID: <20070318141326.07B0210086@code0.codespeak.net> Author: arigo Date: Sun Mar 18 15:13:23 2007 New Revision: 40701 Modified: pypy/dist/pypy/jit/codegen/i386/operation.py pypy/dist/pypy/jit/codegen/test/operation_tests.py Log: More operation tests. Comment out the div- and mod-correction code in the 386 backend. Modified: pypy/dist/pypy/jit/codegen/i386/operation.py ============================================================================== --- pypy/dist/pypy/jit/codegen/i386/operation.py (original) +++ pypy/dist/pypy/jit/codegen/i386/operation.py Sun Mar 18 15:13:23 2007 @@ -281,7 +281,12 @@ mc.CDQ() op2 = allocator.grab_operand(self.y) - self.generate2(allocator, op2) + try: + self.generate2(allocator, op2) + except FailedToImplement: + tmp = allocator.create_scratch_reg(op2) + self.generate2(allocator, tmp) + allocator.end_clobber(tmp) allocator.end_clobber(eax) allocator.end_clobber(edx) @@ -290,102 +295,107 @@ # 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 - - def generate2(self, allocator, op2): - # from the PPC backend which has the same problem: - # - # grumble, the powerpc handles division when the signs of x - # and y differ the other way to how cpython wants it. this - # crawling horror is a branch-free way of computing the right - # remainder in all cases. it's probably not optimal. - # - # we need to adjust the result iff the remainder is non-zero - # and the signs of x and y differ. in the standard-ish PPC - # way, we compute boolean values as either all-bits-0 or - # all-bits-1 and "and" them together, resulting in either - # adding 0 or -1 as needed in the final step. - # - # 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() - 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(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(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(tmp, op2) - mc.IDIV(tmp) - else: - # subtract 1 to the result if the operand signs differ and - # the remainder is not zero - mc.MOV(tmp, eax) - mc.IDIV(op2) - 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 - - def generate2(self, allocator, op2): - # 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() - mc = allocator.mc - if isinstance(op2, IMM32): - 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(tmp, edx) - if op2.value < 0: - 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(tmp, eax) - mc.IDIV(op2) - 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) +## __________ logic for Python-like division and modulo _________ +## +## (disabled for now, as int_floordiv and int_mod have CPU-like +## semantics at the moment) + +##class OpIntFloorDiv(MulOrDivOp): +## opname = 'int_floordiv' +## input_is_64bits = True +## reg_containing_result = eax +## unsigned = False + +## def generate2(self, allocator, op2): +## # from the PPC backend which has the same problem: +## # +## # grumble, the powerpc handles division when the signs of x +## # and y differ the other way to how cpython wants it. this +## # crawling horror is a branch-free way of computing the right +## # remainder in all cases. it's probably not optimal. +## # +## # we need to adjust the result iff the remainder is non-zero +## # and the signs of x and y differ. in the standard-ish PPC +## # way, we compute boolean values as either all-bits-0 or +## # all-bits-1 and "and" them together, resulting in either +## # adding 0 or -1 as needed in the final step. +## # +## # 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() +## mc = allocator.mc +## if isinstance(op2, IMM32): XXX +## # 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(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(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(tmp, op2) +## mc.IDIV(tmp) +## else: +## # subtract 1 to the result if the operand signs differ and +## # the remainder is not zero +## mc.MOV(tmp, eax) +## mc.IDIV(op2) +## 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 + +## def generate2(self, allocator, op2): +## # 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() +## mc = allocator.mc +## if isinstance(op2, IMM32): XXX +## 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(tmp, edx) +## if op2.value < 0: +## 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(tmp, eax) +## mc.IDIV(op2) +## 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' @@ -411,6 +421,22 @@ def generate2(self, allocator, op2): allocator.mc.DIV(op2) +class OpIntFloorDiv(MulOrDivOp): + opname = 'int_floordiv' + input_is_64bits = True + reg_containing_result = eax + unsigned = False + def generate2(self, allocator, op2): + allocator.mc.IDIV(op2) + +class OpIntMod(MulOrDivOp): + opname = 'int_mod' + input_is_64bits = True + reg_containing_result = edx + unsigned = False + def generate2(self, allocator, op2): + allocator.mc.IDIV(op2) + class OpShift(Op2): side_effects = False countmax31 = False Modified: pypy/dist/pypy/jit/codegen/test/operation_tests.py ============================================================================== --- pypy/dist/pypy/jit/codegen/test/operation_tests.py (original) +++ pypy/dist/pypy/jit/codegen/test/operation_tests.py Sun Mar 18 15:13:23 2007 @@ -339,6 +339,11 @@ for operand1 in range(-33, 34): res = fp(operand1) assert res == eval(op, {'x': operand1, 'y': constant}) + fp = self.rgen(fn, [r_uint], r_uint) + for operand1 in range(-33, 34): + res = r_uint(fp(r_uint(operand1))) + assert res == eval(op, {'x': r_uint(operand1), + 'y': r_uint(constant)}) def test_constants_in_divmod(self): for op in ['x // y', 'x % y']: @@ -348,6 +353,11 @@ for operand1 in range(-32, 33): res = fp(operand1) assert res == eval(op, {'x': operand1, 'y': constant}) + fp = self.rgen(fn, [r_uint], r_uint) + for operand1 in range(-32, 33): + res = r_uint(fp(r_uint(operand1))) + assert res == eval(op, {'x': r_uint(operand1), + 'y': r_uint(constant)}) def test_ptr_comparison(self): S = lltype.GcStruct('S') From arigo at codespeak.net Sun Mar 18 17:00:56 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 18 Mar 2007 17:00:56 +0100 (CET) Subject: [pypy-svn] r40703 - in pypy/dist: . pypy/jit/codegen/dump pypy/jit/codegen/dump/test pypy/jit/codegen/llgraph/test pypy/jit/codegen/test Message-ID: <20070318160056.E70A010086@code0.codespeak.net> Author: arigo Date: Sun Mar 18 17:00:50 2007 New Revision: 40703 Modified: pypy/dist/ (props changed) pypy/dist/pypy/jit/codegen/dump/rgenop.py pypy/dist/pypy/jit/codegen/dump/test/test_rgenop.py pypy/dist/pypy/jit/codegen/llgraph/test/test_rgenop.py pypy/dist/pypy/jit/codegen/test/rgenop_tests.py Log: (pedronis, arigo) - switch PyPy to the py lib trunk until the next py lib merge. - fix some of the JIT tests broken by the jit branch merge. Modified: pypy/dist/pypy/jit/codegen/dump/rgenop.py ============================================================================== --- pypy/dist/pypy/jit/codegen/dump/rgenop.py (original) +++ pypy/dist/pypy/jit/codegen/dump/rgenop.py Sun Mar 18 17:00:50 2007 @@ -110,6 +110,17 @@ return v @specialize.arg(1) + def genraisingop1(self, opname, gv_arg): + v1, v2 = self.llbuilder.genraisingop1(opname, gv_arg) + self.dump("%s, %s = %s.genraisingop1('%s', %s)" % ( + self.rgenop.vname(v1), + self.rgenop.vname(v2), + self.name, + opname, + self.rgenop.vname(gv_arg))) + return v1, v2 + + @specialize.arg(1) def genop2(self, opname, gv_arg1, gv_arg2): v = self.llbuilder.genop2(opname, gv_arg1, gv_arg2) self.dump("%s = %s.genop2('%s', %s, %s)" % ( @@ -120,6 +131,18 @@ self.rgenop.vname(gv_arg2))) return v + @specialize.arg(1) + def genraisingop2(self, opname, gv_arg1, gv_arg2): + v1, v2 = self.llbuilder.genraisingop2(opname, gv_arg1, gv_arg2) + self.dump("%s, %s = %s.genraisingop2('%s', %s, %s)" % ( + self.rgenop.vname(v1), + self.rgenop.vname(v2), + self.name, + opname, + self.rgenop.vname(gv_arg1), + self.rgenop.vname(gv_arg2))) + return v1, v2 + def genop_ptr_iszero(self, kind, gv_ptr): v = self.llbuilder.genop_ptr_iszero(kind, gv_ptr) self.dump("%s = %s.genop_ptr_iszero(%s, %s)" % ( Modified: pypy/dist/pypy/jit/codegen/dump/test/test_rgenop.py ============================================================================== --- pypy/dist/pypy/jit/codegen/dump/test/test_rgenop.py (original) +++ pypy/dist/pypy/jit/codegen/dump/test/test_rgenop.py Sun Mar 18 17:00:50 2007 @@ -24,3 +24,5 @@ return True def __ne__(self, other): return False + def __and__(self, other): + return Whatever() # for test_ovfcheck_adder_direct Modified: pypy/dist/pypy/jit/codegen/llgraph/test/test_rgenop.py ============================================================================== --- pypy/dist/pypy/jit/codegen/llgraph/test/test_rgenop.py (original) +++ pypy/dist/pypy/jit/codegen/llgraph/test/test_rgenop.py Sun Mar 18 17:00:50 2007 @@ -12,6 +12,7 @@ def setup_method(self, meth): if 'ovfcheck' in meth.__name__: py.test.skip("no chance (the llinterpreter has no rtyper)") + AbstractRGenOpTests.setup_method(self, meth) def getcompiled(self, runner, argtypes, annotatorpolicy): def quasi_compiled_runner(*args): 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 Sun Mar 18 17:00:50 2007 @@ -1963,7 +1963,7 @@ builder.finish_and_return(sigtoken, gv_result) builder.end() - fnptr = self.cast(gv_fn, 1) + fnptr = self.cast(gv_fn, 2) for x, y, expected in testcases: res = fnptr(x, y) if expected is None: From arigo at codespeak.net Sun Mar 18 17:08:58 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 18 Mar 2007 17:08:58 +0100 (CET) Subject: [pypy-svn] r40704 - pypy/dist/pypy/jit Message-ID: <20070318160858.2050D10082@code0.codespeak.net> Author: arigo Date: Sun Mar 18 17:08:56 2007 New Revision: 40704 Modified: pypy/dist/pypy/jit/TODO.txt Log: The jit tasks we'd like to finish for the release. Modified: pypy/dist/pypy/jit/TODO.txt ============================================================================== --- pypy/dist/pypy/jit/TODO.txt (original) +++ pypy/dist/pypy/jit/TODO.txt Sun Mar 18 17:08:56 2007 @@ -6,6 +6,13 @@ - improve is_true() +- make jit builds not horribly slower than regular builds + when running non-jitted code + +- some --jit option for translate.py + +- basic docs and examples + Longer-term ------------------ From arigo at codespeak.net Sun Mar 18 18:09:33 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 18 Mar 2007 18:09:33 +0100 (CET) Subject: [pypy-svn] r40710 - pypy/dist/pypy/interpreter/astcompiler Message-ID: <20070318170933.E4A6B10086@code0.codespeak.net> Author: arigo Date: Sun Mar 18 18:09:30 2007 New Revision: 40710 Modified: pypy/dist/pypy/interpreter/astcompiler/ast.py pypy/dist/pypy/interpreter/astcompiler/astgen.py Log: Translation fix. Modified: pypy/dist/pypy/interpreter/astcompiler/ast.py ============================================================================== --- pypy/dist/pypy/interpreter/astcompiler/ast.py (original) +++ pypy/dist/pypy/interpreter/astcompiler/ast.py Sun Mar 18 18:09:30 2007 @@ -60,6 +60,7 @@ return "Node()" def descr_repr( self, space ): + # most of the __repr__ are not RPython, more work is needed return space.wrap( self.__repr__() ) def fget_parent(space, self): @@ -86,7 +87,7 @@ Node.typedef = TypeDef('ASTNode', __new__ = interp2app(descr_Node_new, unwrap_spec=[ObjSpace, W_Root, int]), #__repr__ = interp2app(Node.descr_repr, unwrap_spec=['self', ObjSpace] ), - __repr__ = interp2app(Node.descr_repr, unwrap_spec=['self', ObjSpace] ), + #__repr__ = interp2app(Node.descr_repr, unwrap_spec=['self', ObjSpace] ), getChildNodes = interp2app(Node.descr_getChildNodes, unwrap_spec=[ 'self', ObjSpace ] ), accept = interp2app(descr_node_accept, unwrap_spec=[ ObjSpace, W_Root, W_Root ] ), mutate = interp2app(descr_node_mutate, unwrap_spec=[ ObjSpace, W_Root, W_Root ] ), Modified: pypy/dist/pypy/interpreter/astcompiler/astgen.py ============================================================================== --- pypy/dist/pypy/interpreter/astcompiler/astgen.py (original) +++ pypy/dist/pypy/interpreter/astcompiler/astgen.py Sun Mar 18 18:09:30 2007 @@ -708,6 +708,7 @@ return "Node()" def descr_repr( self, space ): + # most of the __repr__ are not RPython, more work is needed return space.wrap( self.__repr__() ) def fget_parent(space, self): @@ -734,7 +735,7 @@ Node.typedef = TypeDef('ASTNode', __new__ = interp2app(descr_Node_new, unwrap_spec=[ObjSpace, W_Root, int]), #__repr__ = interp2app(Node.descr_repr, unwrap_spec=['self', ObjSpace] ), - __repr__ = interp2app(Node.descr_repr, unwrap_spec=['self', ObjSpace] ), + #__repr__ = interp2app(Node.descr_repr, unwrap_spec=['self', ObjSpace] ), getChildNodes = interp2app(Node.descr_getChildNodes, unwrap_spec=[ 'self', ObjSpace ] ), accept = interp2app(descr_node_accept, unwrap_spec=[ ObjSpace, W_Root, W_Root ] ), mutate = interp2app(descr_node_mutate, unwrap_spec=[ ObjSpace, W_Root, W_Root ] ), From arigo at codespeak.net Sun Mar 18 18:09:53 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 18 Mar 2007 18:09:53 +0100 (CET) Subject: [pypy-svn] r40711 - pypy/dist/pypy/jit/timeshifter Message-ID: <20070318170953.2FA791008A@code0.codespeak.net> Author: arigo Date: Sun Mar 18 18:09:51 2007 New Revision: 40711 Modified: pypy/dist/pypy/jit/timeshifter/hrtyper.py Log: The merge was done, remove the skip. Modified: pypy/dist/pypy/jit/timeshifter/hrtyper.py ============================================================================== --- pypy/dist/pypy/jit/timeshifter/hrtyper.py (original) +++ pypy/dist/pypy/jit/timeshifter/hrtyper.py Sun Mar 18 18:09:51 2007 @@ -53,8 +53,6 @@ py.log.setconsumer("timeshifter", ansi_log) def __init__(self, hannotator, rtyper, RGenOp): - import py; py.test.skip("PENDING MERGE FROM THE BRANCH") - RPythonTyper.__init__(self, hannotator, type_system=HintTypeSystem.instance) self.rtyper = rtyper From arigo at codespeak.net Sun Mar 18 19:05:57 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 18 Mar 2007 19:05:57 +0100 (CET) Subject: [pypy-svn] r40714 - pypy/dist/pypy/jit/codegen/llvm/test Message-ID: <20070318180557.B110E10086@code0.codespeak.net> Author: arigo Date: Sun Mar 18 19:05:55 2007 New Revision: 40714 Modified: pypy/dist/pypy/jit/codegen/llvm/test/test_genc_tl.py Log: Fix imports. Modified: pypy/dist/pypy/jit/codegen/llvm/test/test_genc_tl.py ============================================================================== --- pypy/dist/pypy/jit/codegen/llvm/test/test_genc_tl.py (original) +++ pypy/dist/pypy/jit/codegen/llvm/test/test_genc_tl.py Sun Mar 18 19:05:55 2007 @@ -1,12 +1,12 @@ import py -from pypy.jit.timeshifter.test import test_tl +from pypy.jit.timeshifter.test import test_1tl from pypy.jit.codegen.llvm.test.test_genc_ts import LLVMTimeshiftingTestMixin py.test.skip("WIP") class TestTL(LLVMTimeshiftingTestMixin, - test_tl.TestTL): + test_1tl.TestTL): # for the individual tests see # ====> ../../../timeshifter/test/test_tl.py From arigo at codespeak.net Sun Mar 18 19:17:34 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 18 Mar 2007 19:17:34 +0100 (CET) Subject: [pypy-svn] r40715 - pypy/dist/pypy/config Message-ID: <20070318181734.47BC31008A@code0.codespeak.net> Author: arigo Date: Sun Mar 18 19:17:31 2007 New Revision: 40715 Modified: pypy/dist/pypy/config/pypyoption.py Log: Remove from --faassen the option that don't give good speed-ups. Modified: pypy/dist/pypy/config/pypyoption.py ============================================================================== --- pypy/dist/pypy/config/pypyoption.py (original) +++ pypy/dist/pypy/config/pypyoption.py Sun Mar 18 19:17:31 2007 @@ -233,10 +233,10 @@ ("translation.profopt", "-c 'from richards import main;main(); from test import pystone; pystone.main()'"), ("objspace.std.withmultidict", True), - ("objspace.std.withstrjoin", True), +# ("objspace.std.withstrjoin", True), ("objspace.std.withshadowtracking", True), - ("objspace.std.withstrslice", True), - ("objspace.std.withsmallint", True), +# ("objspace.std.withstrslice", True), +# ("objspace.std.withsmallint", True), ("objspace.std.withrangelist", True), ("objspace.std.withmethodcache", True), # ("objspace.std.withfastslice", True), From fijal at codespeak.net Sun Mar 18 19:24:24 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 18 Mar 2007 19:24:24 +0100 (CET) Subject: [pypy-svn] r40716 - pypy/dist/pypy/lib/distributed/test Message-ID: <20070318182424.974781008D@code0.codespeak.net> Author: fijal Date: Sun Mar 18 19:24:16 2007 New Revision: 40716 Modified: pypy/dist/pypy/lib/distributed/test/test_greensock.py Log: Unskip tests, since we've got proper pylib version Modified: pypy/dist/pypy/lib/distributed/test/test_greensock.py ============================================================================== --- pypy/dist/pypy/lib/distributed/test/test_greensock.py (original) +++ pypy/dist/pypy/lib/distributed/test/test_greensock.py Sun Mar 18 19:24:16 2007 @@ -1,6 +1,5 @@ import py -py.test.skip("Skip this till pylib trunk->dist merge") from pypy.conftest import gettestobjspace class AppTestDistributedGreensock(object): From fijal at codespeak.net Sun Mar 18 19:25:23 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 18 Mar 2007 19:25:23 +0100 (CET) Subject: [pypy-svn] r40717 - pypy/dist/pypy/lib/distributed/test Message-ID: <20070318182523.EE8FB1008D@code0.codespeak.net> Author: fijal Date: Sun Mar 18 19:25:17 2007 New Revision: 40717 Modified: pypy/dist/pypy/lib/distributed/test/test_greensock.py Log: Fix imports Modified: pypy/dist/pypy/lib/distributed/test/test_greensock.py ============================================================================== --- pypy/dist/pypy/lib/distributed/test/test_greensock.py (original) +++ pypy/dist/pypy/lib/distributed/test/test_greensock.py Sun Mar 18 19:25:17 2007 @@ -37,7 +37,7 @@ def test_remote_call(self): from distributed import socklayer - from py.__.net.greenexecnet import PopenGateway + from py.__.green.greenexecnet import PopenGateway gw = PopenGateway() rp = socklayer.spawn_remote_side(self.remote_side_code, gw) a = rp.get_remote("a") @@ -45,8 +45,8 @@ def test_remote_counting(self): from distributed import socklayer - from py.__.net.greensock2 import allof - from py.__.net.greenexecnet import PopenGateway + from py.__.green.greensock2 import allof + from py.__.green.greenexecnet import PopenGateway gws = [PopenGateway() for i in range(3)] rps = [socklayer.spawn_remote_side(self.remote_side_code, gw) for gw in gws] From fijal at codespeak.net Sun Mar 18 19:28:15 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 18 Mar 2007 19:28:15 +0100 (CET) Subject: [pypy-svn] r40718 - in pypy/dist/pypy/translator/js/examples: . console console/test test Message-ID: <20070318182815.B95921008D@code0.codespeak.net> Author: fijal Date: Sun Mar 18 19:28:11 2007 New Revision: 40718 Modified: pypy/dist/pypy/translator/js/examples/console/console.py pypy/dist/pypy/translator/js/examples/console/session.py pypy/dist/pypy/translator/js/examples/console/test/test_console.py pypy/dist/pypy/translator/js/examples/console/test/test_session.py pypy/dist/pypy/translator/js/examples/overmind.py pypy/dist/pypy/translator/js/examples/test/test_examples.py Log: Fix imports and unskip tests 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 Sun Mar 18 19:28:11 2007 @@ -10,7 +10,7 @@ from pypy.translator.js.lib.support import callback from pypy.translator.js import commproxy from pypy.translator.js.examples.console.session import Interpreter -from py.__.net.server.httpserver import GreenHTTPServer +from py.__.green.server.httpserver import GreenHTTPServer commproxy.USE_MOCHIKIT = True Modified: pypy/dist/pypy/translator/js/examples/console/session.py ============================================================================== --- pypy/dist/pypy/translator/js/examples/console/session.py (original) +++ pypy/dist/pypy/translator/js/examples/console/session.py Sun Mar 18 19:28:11 2007 @@ -13,8 +13,8 @@ import py import subprocess from Queue import Queue -from py.__.net.greensock2 import autogreenlet, Timer, Interrupted -from py.__.net.pipe.fd import FDInput +from py.__.green.greensock2 import autogreenlet, Timer, Interrupted +from py.__.green.pipe.fd import FDInput class Interpreter(object): def __init__(self, python, timeout=TIMEOUT): Modified: pypy/dist/pypy/translator/js/examples/console/test/test_console.py ============================================================================== --- pypy/dist/pypy/translator/js/examples/console/test/test_console.py (original) +++ pypy/dist/pypy/translator/js/examples/console/test/test_console.py Sun Mar 18 19:28:11 2007 @@ -1,6 +1,5 @@ import py -py.test.skip("Skip this till pylib trunk->dist merge") def test_line_skip(): from pypy.translator.js.examples.console.console import line_split Modified: pypy/dist/pypy/translator/js/examples/console/test/test_session.py ============================================================================== --- pypy/dist/pypy/translator/js/examples/console/test/test_session.py (original) +++ pypy/dist/pypy/translator/js/examples/console/test/test_session.py Sun Mar 18 19:28:11 2007 @@ -3,10 +3,9 @@ """ import py -py.test.skip("Skip this till pylib trunk->dist merge") -from py.__.net.greensock2 import allof -from py.__.net.pipe.fd import FDInput +from py.__.green.greensock2 import allof +from py.__.green.pipe.fd import FDInput from pypy.translator.js.examples.console.session import Interpreter def test_greensock_reader_timeouter(): 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 Sun Mar 18 19:28:11 2007 @@ -57,7 +57,7 @@ if __name__ == '__main__': try: addr = ('', 8008) - from py.__.net.server.httpserver import GreenHTTPServer + from py.__.green.server.httpserver import GreenHTTPServer httpd = server.create_server(server_address=addr, handler=Handler, server=GreenHTTPServer) httpd.serve_forever() 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 Sun Mar 18 19:28:11 2007 @@ -2,7 +2,6 @@ """ Various build tests """ import py -py.test.skip("Skip this till pylib trunk->dist merge") from pypy.translator.js.main import rpython2javascript def test_console_build(): From fijal at codespeak.net Sun Mar 18 20:26:03 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 18 Mar 2007 20:26:03 +0100 (CET) Subject: [pypy-svn] r40721 - in pypy/dist/pypy/translator/js/examples: bnb/data console console/data Message-ID: <20070318192603.E93691008F@code0.codespeak.net> Author: fijal Date: Sun Mar 18 20:26:02 2007 New Revision: 40721 Modified: pypy/dist/pypy/translator/js/examples/bnb/data/bnb.html pypy/dist/pypy/translator/js/examples/console/console.py pypy/dist/pypy/translator/js/examples/console/data/console.html Log: Various style improvements Modified: pypy/dist/pypy/translator/js/examples/bnb/data/bnb.html ============================================================================== --- pypy/dist/pypy/translator/js/examples/bnb/data/bnb.html (original) +++ pypy/dist/pypy/translator/js/examples/bnb/data/bnb.html Sun Mar 18 20:26:02 2007 @@ -4,7 +4,7 @@ Bub'n'bros - + 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 Sun Mar 18 20:26:02 2007 @@ -113,8 +113,9 @@ class Root(server.Collection): exported_methods = exported_methods - #index = server.Static(static_dir.join("console.html")) index = server.FsFile(static_dir.join("console.html")) + style_css = server.FsFile(static_dir.dirpath().dirpath().join("data"). + join("style.css")) MochiKit = server.StaticDir('MochiKit') def source_js(self): Modified: pypy/dist/pypy/translator/js/examples/console/data/console.html ============================================================================== --- pypy/dist/pypy/translator/js/examples/console/data/console.html (original) +++ pypy/dist/pypy/translator/js/examples/console/data/console.html Sun Mar 18 20:26:02 2007 @@ -1,12 +1,13 @@ - + + + Console - + PyPy
    From mwh at codespeak.net Sun Mar 18 20:27:39 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Sun, 18 Mar 2007 20:27:39 +0100 (CET) Subject: [pypy-svn] r40722 - pypy/dist/pypy/jit/codegen/ppc Message-ID: <20070318192739.2C76310033@code0.codespeak.net> Author: mwh Date: Sun Mar 18 20:27:36 2007 New Revision: 40722 Modified: pypy/dist/pypy/jit/codegen/ppc/rgenop.py Log: make the ppc op_int_floordiv about 1e6 times simpler, and pass the tests. 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 Sun Mar 18 20:27:36 2007 @@ -841,28 +841,7 @@ commutative=True) def op_int_floordiv(self, gv_x, gv_y): - # grumble, the powerpc handles division when the signs of x - # and y differ the other way to how cpython wants it. this - # crawling horror is a branch-free way of computing the right - # remainder in all cases. it's probably not optimal. - - # we need to adjust the result iff the remainder is non-zero - # and the signs of x and y differ. in the standard-ish PPC - # way, we compute boolean values as either all-bits-0 or - # all-bits-1 and "and" them together, resulting in either - # adding 0 or -1 as needed in the final step. - - gv_dividend = self._arg_arg_op(gv_x, gv_y, _PPC.divw) - gv_remainder = self.op_int_sub(gv_x, self.op_int_mul(gv_dividend, gv_y)) - - gv_t = self._arg_arg_op(gv_y, gv_x, _PPC.xor) - gv_signs_differ = self._arg_simm_op(gv_t, self.rgenop.genconst(31), _PPC.srawi) - - gv_foo = self._arg_simm_op(gv_remainder, self.rgenop.genconst(0), _PPC.subfic) - gv_remainder_non_zero = self._arg_arg_op(gv_foo, gv_foo, _PPC.subfe) - - gv_b = self._arg_arg_op(gv_remainder_non_zero, gv_signs_differ, _PPC.and_) - return self._arg_arg_op(gv_dividend, gv_b, _PPC.add) + return self._arg_arg_op(gv_x, gv_y, _PPC.divw) ## def op_int_floordiv_zer(self, gv_x, gv_y): From mwh at codespeak.net Sun Mar 18 20:45:19 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Sun, 18 Mar 2007 20:45:19 +0100 (CET) Subject: [pypy-svn] r40723 - pypy/dist/pypy/translator/goal Message-ID: <20070318194519.7FEE91008F@code0.codespeak.net> Author: mwh Date: Sun Mar 18 20:45:15 2007 New Revision: 40723 Modified: pypy/dist/pypy/translator/goal/bench-cronjob.py Log: i've been carrying local changes to bench-cronjob.py around in pypytester's wc on tuatara since i set the benchmark runs up, don't know why. here they are, anyway. Modified: pypy/dist/pypy/translator/goal/bench-cronjob.py ============================================================================== --- pypy/dist/pypy/translator/goal/bench-cronjob.py (original) +++ pypy/dist/pypy/translator/goal/bench-cronjob.py Sun Mar 18 20:45:15 2007 @@ -1,15 +1,19 @@ #! /usr/bin/env python +import os +homedir = os.getenv('HOME') +os.environ['PATH'] += ':/usr/local/bin:/usr/local/llvm/cfrontend/ppc/llvm-gcc/bin:'+homedir+'/bin' + import autopath import py import time, os, sys, stat -from pypy.translator.llvm.buildllvm import optimizations +from pypy.translator.llvm.buildllvm import Builder os.umask(022) # allow everyone to read/execute the produced pypy-c's -homedir = os.getenv('HOME') + tmpdir = py.std.tempfile.gettempdir() + '/usession-' + os.environ['USER'] + '/' -cflags = "-mtune=pentium4 -O3 -fomit-frame-pointer" +cflags = "-O3" lflags = "-lgc -lm -lpthread" dry_run = False @@ -24,7 +28,7 @@ def update_pypy(): os.chdir(homedir + '/projects/pypy-dist') - run('svn up 2>&1') + run('/usr/local/bin/svn up 2>&1') def update_llvm(): os.chdir(homedir + '/projects/llvm') @@ -34,7 +38,7 @@ def compile_llvm_variants(revision, features): ll2bc(revision, features) bc2c_exe(revision, features, 'from richards import *;main(iterations=1)') - bc2x86_exe(revision, features, 'x86') + bc2x86_exe(revision, features, 'llvm') def ll2bc(revision, features): if features: @@ -42,7 +46,7 @@ cmd = 'cp %spypy.ll pypy/translator/goal/archive/pypy%s-%s.ll' % (tmpdir, features, revision) run(cmd) - opts = optimizations(simple=False, use_gcc=False) + opts = Builder(None).optimizations() cmd = '~/bin/llvm-as < %spypy.ll | ~/bin/opt %s -f -o %spypy.bc' % ( tmpdir, opts, tmpdir) run(cmd) @@ -153,7 +157,8 @@ os.chdir(homedir + '/projects/pypy-dist/pypy/translator/goal') uname = os.popen('uname -a', 'r').read() startload = get_load() - result = run('/usr/local/bin/withlock /tmp/cpu_cycles_lock /usr/local/bin/python bench-unix.py 2>&1 | tee benchmark.txt' % locals()) +# result = run('/usr/local/bin/withlock /tmp/cpu_cycles_lock /usr/local/bin/python bench-unix.py 2>&1 | tee benchmark.txt' % locals()) + result = run('/usr/local/bin/python bench-unix.py 2>&1 | tee benchmark.txt' % locals()) endload = get_load() if not dry_run and result == 0: f = open('benchmark.html', 'w') @@ -171,18 +176,16 @@ def main(backends=[]): if backends == []: #_ prefix means target specific option, # prefix to outcomment backends = [backend.strip() for backend in """ - llvm--_objspace-std-withmultidict - llvm--_objspace-opcodes-CALL_LIKELY_BUILTIN + llvm--_faassen c - c--gc=framework - 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-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-withmultidict--profopt='-c "from richards import *;main(iterations=1)"' - c--gc=framework--_objspace-std-withmultidict--profopt='-c "from richards import *;main(iterations=1)"' + c--stackless--_faassen + c--_faassen + c--thread + c--_objspace=taint + c--_allworkingmodules + c--_with-transparent-proxy--_faassen + c--gc=framework--_faassen + c--_objspace-std-withrope cli """.split('\n') if backend.strip() and not backend.strip().startswith('#')] print time.ctime() From arigo at codespeak.net Sun Mar 18 22:18:21 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 18 Mar 2007 22:18:21 +0100 (CET) Subject: [pypy-svn] r40726 - pypy/dist/pypy/tool Message-ID: <20070318211821.2C7611008F@code0.codespeak.net> Author: arigo Date: Sun Mar 18 22:18:19 2007 New Revision: 40726 Modified: pypy/dist/pypy/tool/ansi_print.py Log: (pedronis, arigo) Gray out the [hintannotate:stub] lines. Modified: pypy/dist/pypy/tool/ansi_print.py ============================================================================== --- pypy/dist/pypy/tool/ansi_print.py (original) +++ pypy/dist/pypy/tool/ansi_print.py Sun Mar 18 22:18:19 2007 @@ -17,6 +17,7 @@ 'event': ((1,), True), 'ERROR': ((1, 31), False), 'info': ((35,), False), + 'stub': ((1, 30), False), } def __init__(self, kw_to_color={}, file=None): From arigo at codespeak.net Sun Mar 18 22:19:55 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 18 Mar 2007 22:19:55 +0100 (CET) Subject: [pypy-svn] r40727 - pypy/dist/pypy/jit/goal Message-ID: <20070318211955.8766F1008F@code0.codespeak.net> Author: arigo Date: Sun Mar 18 22:19:53 2007 New Revision: 40727 Modified: pypy/dist/pypy/jit/goal/targetjit.py Log: don't override a goal specified on the command line. Modified: pypy/dist/pypy/jit/goal/targetjit.py ============================================================================== --- pypy/dist/pypy/jit/goal/targetjit.py (original) +++ pypy/dist/pypy/jit/goal/targetjit.py Sun Mar 18 22:19:53 2007 @@ -52,7 +52,7 @@ def handle_translate_config(self, translateconfig): super(PyPyJITTarget, self).handle_translate_config(translateconfig) - translateconfig.goals = ['timeshift'] + translateconfig.goals = translateconfig.goals or ['timeshift'] PyPyJITTarget().interface(globals()) From arigo at codespeak.net Sun Mar 18 22:20:42 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 18 Mar 2007 22:20:42 +0100 (CET) Subject: [pypy-svn] r40728 - pypy/dist/pypy/jit Message-ID: <20070318212042.2652E10092@code0.codespeak.net> Author: arigo Date: Sun Mar 18 22:20:32 2007 New Revision: 40728 Modified: pypy/dist/pypy/jit/TODO.txt Log: Another TODO item. Modified: pypy/dist/pypy/jit/TODO.txt ============================================================================== --- pypy/dist/pypy/jit/TODO.txt (original) +++ pypy/dist/pypy/jit/TODO.txt Sun Mar 18 22:20:32 2007 @@ -13,6 +13,8 @@ - basic docs and examples +- check that --jit works with --faassen + Longer-term ------------------ From arigo at codespeak.net Sun Mar 18 22:25:46 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 18 Mar 2007 22:25:46 +0100 (CET) Subject: [pypy-svn] r40729 - in pypy/dist/pypy: annotation rlib rpython rpython/lltypesystem rpython/lltypesystem/test Message-ID: <20070318212546.D841B1008F@code0.codespeak.net> Author: arigo Date: Sun Mar 18 22:25:41 2007 New Revision: 40729 Modified: pypy/dist/pypy/annotation/binaryop.py pypy/dist/pypy/annotation/bookkeeper.py pypy/dist/pypy/annotation/builtin.py pypy/dist/pypy/annotation/classdef.py pypy/dist/pypy/annotation/description.py pypy/dist/pypy/annotation/model.py pypy/dist/pypy/annotation/specialize.py pypy/dist/pypy/annotation/unaryop.py pypy/dist/pypy/rlib/objectmodel.py pypy/dist/pypy/rpython/lltypesystem/rclass.py pypy/dist/pypy/rpython/lltypesystem/rtagged.py pypy/dist/pypy/rpython/lltypesystem/rvirtualizable.py pypy/dist/pypy/rpython/lltypesystem/test/test_rvirtualizable.py pypy/dist/pypy/rpython/rbuiltin.py pypy/dist/pypy/rpython/rpbc.py Log: (pedronis, arigo) - added general support for flags on SomeInstance. - the access_directly flag on SomeInstance: used for virtualizables, to mean that it's safe to access the fields directly (i.e. at this point the virtualizable is not actually virtualized). - obscure specialization logic to make two copies of functions automatically: one in which at least one argument has the 'access_directly' flag, and one in which none has. Motivation: see next check-in. Modified: pypy/dist/pypy/annotation/binaryop.py ============================================================================== --- pypy/dist/pypy/annotation/binaryop.py (original) +++ pypy/dist/pypy/annotation/binaryop.py Sun Mar 18 22:25:41 2007 @@ -617,7 +617,15 @@ if basedef is None: # print warning? return SomeObject() - return SomeInstance(basedef, can_be_None=ins1.can_be_None or ins2.can_be_None) + flags = ins1.flags + if flags: + flags = flags.copy() + for key, value in flags.items(): + if key not in ins2.flags or ins2.flags[key] != value: + del flags[key] + return SomeInstance(basedef, + can_be_None=ins1.can_be_None or ins2.can_be_None, + flags=flags) def improve((ins1, ins2)): if ins1.classdef is None: Modified: pypy/dist/pypy/annotation/bookkeeper.py ============================================================================== --- pypy/dist/pypy/annotation/bookkeeper.py (original) +++ pypy/dist/pypy/annotation/bookkeeper.py Sun Mar 18 22:25:41 2007 @@ -519,13 +519,16 @@ self.pbctypes[cls] = True return result - def getmethoddesc(self, funcdesc, originclassdef, selfclassdef, name): - key = funcdesc, originclassdef, selfclassdef, name + def getmethoddesc(self, funcdesc, originclassdef, selfclassdef, name, + flags={}): + flagskey = flags.items() + flagskey.sort() + key = funcdesc, originclassdef, selfclassdef, name, tuple(flagskey) try: return self.methoddescs[key] except KeyError: result = description.MethodDesc(self, funcdesc, originclassdef, - selfclassdef, name) + selfclassdef, name, flags) self.methoddescs[key] = result return result Modified: pypy/dist/pypy/annotation/builtin.py ============================================================================== --- pypy/dist/pypy/annotation/builtin.py (original) +++ pypy/dist/pypy/annotation/builtin.py Sun Mar 18 22:25:41 2007 @@ -10,7 +10,7 @@ from pypy.annotation.model import SomePBC, SomeInstance, SomeDict from pypy.annotation.model import SomeExternalObject from pypy.annotation.model import annotation_to_lltype, lltype_to_annotation, ll_to_annotation -from pypy.annotation.model import add_knowntypedata, not_const +from pypy.annotation.model import add_knowntypedata from pypy.annotation.model import s_ImpossibleValue from pypy.annotation.bookkeeper import getbookkeeper from pypy.annotation import description @@ -319,9 +319,6 @@ def robjmodel_keepalive_until_here(*args_s): return immutablevalue(None) -def robjmodel_hint(s, **kwds_s): - return not_const(s) - def llmemory_cast_ptr_to_adr(s): return SomeAddress() @@ -383,7 +380,6 @@ BUILTIN_ANALYZERS[pypy.rlib.objectmodel.r_dict] = robjmodel_r_dict BUILTIN_ANALYZERS[pypy.rlib.objectmodel.hlinvoke] = robjmodel_hlinvoke BUILTIN_ANALYZERS[pypy.rlib.objectmodel.keepalive_until_here] = robjmodel_keepalive_until_here -BUILTIN_ANALYZERS[pypy.rlib.objectmodel.hint] = robjmodel_hint BUILTIN_ANALYZERS[pypy.rpython.lltypesystem.llmemory.cast_ptr_to_adr] = llmemory_cast_ptr_to_adr BUILTIN_ANALYZERS[pypy.rpython.lltypesystem.llmemory.cast_adr_to_ptr] = llmemory_cast_adr_to_ptr BUILTIN_ANALYZERS[pypy.rpython.lltypesystem.llmemory.cast_adr_to_int] = llmemory_cast_adr_to_int Modified: pypy/dist/pypy/annotation/classdef.py ============================================================================== --- pypy/dist/pypy/annotation/classdef.py (original) +++ pypy/dist/pypy/annotation/classdef.py Sun Mar 18 22:25:41 2007 @@ -333,7 +333,7 @@ return None return None - def lookup_filter(self, pbc, name=None): + def lookup_filter(self, pbc, name=None, flags={}): """Selects the methods in the pbc that could possibly be seen by a lookup performed on an instance of 'self', removing the ones that cannot appear. @@ -365,10 +365,10 @@ continue # not matching # bind the method by giving it a selfclassdef. Use the # more precise subclass that it's coming from. - desc = desc.bind_self(methclassdef) + desc = desc.bind_self(methclassdef, flags) d.append(desc) if uplookup is not None: - d.append(updesc.bind_self(self)) + d.append(updesc.bind_self(self, flags)) if d or pbc.can_be_None: return SomePBC(d, can_be_None=pbc.can_be_None) Modified: pypy/dist/pypy/annotation/description.py ============================================================================== --- pypy/dist/pypy/annotation/description.py (original) +++ pypy/dist/pypy/annotation/description.py Sun Mar 18 22:25:41 2007 @@ -676,12 +676,13 @@ knowntype = types.MethodType def __init__(self, bookkeeper, funcdesc, originclassdef, - selfclassdef, name): + selfclassdef, name, flags={}): super(MethodDesc, self).__init__(bookkeeper) self.funcdesc = funcdesc self.originclassdef = originclassdef self.selfclassdef = selfclassdef self.name = name + self.flags = flags def __repr__(self): if self.selfclassdef is None: @@ -696,7 +697,7 @@ from pypy.annotation.model import SomeInstance if self.selfclassdef is None: raise Exception("calling %r" % (self,)) - s_instance = SomeInstance(self.selfclassdef) + s_instance = SomeInstance(self.selfclassdef, flags = self.flags) args = args.prepend(s_instance) return self.funcdesc.pycall(schedule, args, s_previous_result) @@ -704,12 +705,13 @@ self.bookkeeper.warning("rebinding an already bound %r" % (self,)) return self.funcdesc.bind_under(classdef, name) - def bind_self(self, newselfclassdef): + def bind_self(self, newselfclassdef, flags={}): return self.bookkeeper.getmethoddesc(self.funcdesc, self.originclassdef, newselfclassdef, - self.name) - + self.name, + flags) + def consider_call_site(bookkeeper, family, descs, args, s_result): shape = rawshape(args, nextra=1) # account for the extra 'self' funcdescs = [methoddesc.funcdesc for methoddesc in descs] Modified: pypy/dist/pypy/annotation/model.py ============================================================================== --- pypy/dist/pypy/annotation/model.py (original) +++ pypy/dist/pypy/annotation/model.py Sun Mar 18 22:25:41 2007 @@ -297,10 +297,11 @@ class SomeInstance(SomeObject): "Stands for an instance of a (user-defined) class." - def __init__(self, classdef, can_be_None=False): + def __init__(self, classdef, can_be_None=False, flags={}): self.classdef = classdef self.knowntype = classdef or object self.can_be_None = can_be_None + self.flags = flags def fmt_knowntype(self, kt): return None @@ -309,6 +310,11 @@ return 'object' else: return cdef.name + def fmt_flags(self, flags): + if flags: + return repr(flags) + else: + return None def can_be_none(self): return self.can_be_None Modified: pypy/dist/pypy/annotation/specialize.py ============================================================================== --- pypy/dist/pypy/annotation/specialize.py (original) +++ pypy/dist/pypy/annotation/specialize.py Sun Mar 18 22:25:41 2007 @@ -6,12 +6,12 @@ from pypy.tool.algo.unionfind import UnionFind from pypy.objspace.flow.model import Block, Link, Variable, SpaceOperation from pypy.objspace.flow.model import Constant, checkgraph +from pypy.annotation import model as annmodel def default_specialize(funcdesc, args_s): argnames, vararg, kwarg = funcdesc.signature assert not kwarg, "functions with ** arguments are not supported" if vararg: - from pypy.annotation import model as annmodel # calls to *arg functions: create one version per number of args assert len(args_s) == len(argnames) + 1 s_tuple = args_s[-1] @@ -20,6 +20,8 @@ s_len = s_tuple.len() assert s_len.is_constant(), "calls require known number of args" nb_extra_args = s_len.const + flattened_s = list(args_s[:-1]) + flattened_s.extend(s_tuple.items) def builder(translator, func): # build a hacked graph that doesn't take a *arg any more, but @@ -46,13 +48,42 @@ graph.defaults = None # shouldn't be used in this case checkgraph(graph) return graph - - return funcdesc.cachedgraph(nb_extra_args, - alt_name='%s_star%d' % (funcdesc.name, - nb_extra_args), + + key, name_suffix = access_direct_key(nb_extra_args, flattened_s) + return funcdesc.cachedgraph(key, + alt_name='%s_star%d%s' % (funcdesc.name, + nb_extra_args, + name_suffix), builder=builder) else: - return funcdesc.cachedgraph(None) + key, name_suffix = access_direct_key(None, args_s) + if name_suffix: + alt_name = '%s%s' % (funcdesc.name, name_suffix) + else: + alt_name = None + return funcdesc.cachedgraph(key, alt_name=alt_name) + +def access_direct_key(key, args_s): + for s_obj in args_s: + if (isinstance(s_obj, annmodel.SomeInstance) and + 'access_directly' in s_obj.flags): + return (AccessDirect, key), '_AccessDirect' + return key, '' + +class AccessDirect(object): + """marker for specialization: set when any arguments is a SomeInstance + which has the 'access_directly' flag set.""" + +def getuniquenondirectgraph(desc): + result = [] + for key, graph in desc._cache.items(): + if (type(key) is tuple and len(key) == 2 and + key[0] is AccessDirect): + continue + result.append(graph) + assert len(result) == 1 + return result[0] + # ____________________________________________________________________________ # specializations Modified: pypy/dist/pypy/annotation/unaryop.py ============================================================================== --- pypy/dist/pypy/annotation/unaryop.py (original) +++ pypy/dist/pypy/annotation/unaryop.py Sun Mar 18 22:25:41 2007 @@ -524,7 +524,8 @@ # that can't possibly apply to an instance of ins.classdef. # XXX do it more nicely if isinstance(s_result, SomePBC): - s_result = ins.classdef.lookup_filter(s_result, attr) + s_result = ins.classdef.lookup_filter(s_result, attr, + ins.flags) elif isinstance(s_result, SomeImpossibleValue): ins.classdef.check_missing_attribute_update(attr) # blocking is harmless if the attribute is explicitly listed Modified: pypy/dist/pypy/rlib/objectmodel.py ============================================================================== --- pypy/dist/pypy/rlib/objectmodel.py (original) +++ pypy/dist/pypy/rlib/objectmodel.py Sun Mar 18 22:25:41 2007 @@ -192,6 +192,42 @@ def hint(x, **kwds): return x +class Entry(ExtRegistryEntry): + _about_ = hint + + def compute_result_annotation(self, s_x, **kwds_s): + from pypy.annotation import model as annmodel + s_x = annmodel.not_const(s_x) + if 's_access_directly' in kwds_s: + if isinstance(s_x, annmodel.SomeInstance): + from pypy.objspace.flow.model import Constant + classdesc = s_x.classdef.classdesc + virtualizable = classdesc.read_attribute('_virtualizable_', + Constant(False)).value + if virtualizable: + flags = s_x.flags.copy() + flags['access_directly'] = True + s_x = annmodel.SomeInstance(s_x.classdef, + s_x.can_be_None, + flags) + return s_x + + def specialize_call(self, hop, **kwds_i): + from pypy.rpython.lltypesystem import lltype + hints = {} + for key, index in kwds_i.items(): + s_value = hop.args_s[index] + if not s_value.is_constant(): + from pypy.rpython.error import TyperError + raise TyperError("hint %r is not constant" % (key,)) + assert key.startswith('i_') + hints[key[2:]] = s_value.const + v = hop.inputarg(hop.args_r[0], arg=0) + c_hint = hop.inputconst(lltype.Void, hints) + hop.exception_cannot_occur() + return hop.genop('hint', [v, c_hint], resulttype=v.concretetype) + + def we_are_jitted(): return False # timeshifts to True Modified: pypy/dist/pypy/rpython/lltypesystem/rclass.py ============================================================================== --- pypy/dist/pypy/rpython/lltypesystem/rclass.py (original) +++ pypy/dist/pypy/rpython/lltypesystem/rclass.py Sun Mar 18 22:25:41 2007 @@ -469,7 +469,7 @@ raise MissingRTypeAttribute(attr) return self.rbase.getfieldrepr(attr) - def getfield(self, vinst, attr, llops, force_cast=False): + def getfield(self, vinst, attr, llops, force_cast=False, flags={}): """Read the given attribute (or __class__ for the type) of 'vinst'.""" if attr in self.fields: mangled_name, r = self.fields[attr] @@ -480,9 +480,11 @@ else: if self.classdef is None: raise MissingRTypeAttribute(attr) - return self.rbase.getfield(vinst, attr, llops, force_cast=True) + return self.rbase.getfield(vinst, attr, llops, force_cast=True, + flags=flags) - def setfield(self, vinst, attr, vvalue, llops, force_cast=False, opname='setfield'): + def setfield(self, vinst, attr, vvalue, llops, force_cast=False, + opname='setfield', flags={}): """Write the given attribute (or __class__ for the type) of 'vinst'.""" if attr in self.fields: mangled_name, r = self.fields[attr] @@ -494,7 +496,8 @@ else: if self.classdef is None: raise MissingRTypeAttribute(attr) - self.rbase.setfield(vinst, attr, vvalue, llops, force_cast=True, opname=opname) + self.rbase.setfield(vinst, attr, vvalue, llops, force_cast=True, + opname=opname, flags=flags) def new_instance(self, llops, classcallhop=None, v_cpytype=None): """Build a new instance, without calling __init__.""" @@ -533,8 +536,8 @@ if value is not None: cvalue = inputconst(r.lowleveltype, r.convert_desc_or_const(value)) - self.setfield(vptr, fldname, cvalue, llops) - + self.setfield(vptr, fldname, cvalue, llops, + {'access_directly': True}) return vptr def rtype_type(self, hop): @@ -555,7 +558,8 @@ [desc] = hop.s_result.descriptions return hop.inputconst(Void, desc.pyobj) if attr in self.allinstancefields: - return self.getfield(vinst, attr, hop.llops) + return self.getfield(vinst, attr, hop.llops, + flags=hop.args_s[0].flags) elif attr in self.rclass.allmethods: # special case for methods: represented as their 'self' only # (see MethodsPBCRepr) @@ -569,7 +573,8 @@ attr = hop.args_s[1].const r_value = self.getfieldrepr(attr) vinst, vattr, vvalue = hop.inputargs(self, Void, r_value) - self.setfield(vinst, attr, vvalue, hop.llops) + self.setfield(vinst, attr, vvalue, hop.llops, + flags=hop.args_s[0].flags) def rtype_is_true(self, hop): vinst, = hop.inputargs(self) Modified: pypy/dist/pypy/rpython/lltypesystem/rtagged.py ============================================================================== --- pypy/dist/pypy/rpython/lltypesystem/rtagged.py (original) +++ pypy/dist/pypy/rpython/lltypesystem/rtagged.py Sun Mar 18 22:25:41 2007 @@ -90,7 +90,7 @@ else: return cunboxedcls - def getfield(self, vinst, attr, llops, force_cast=False): + def getfield(self, vinst, attr, llops, force_cast=False, flags={}): if not self.is_parent and attr == self.specialfieldname: return self.getvalue_from_unboxed(llops, vinst) elif attr == '__class__': Modified: pypy/dist/pypy/rpython/lltypesystem/rvirtualizable.py ============================================================================== --- pypy/dist/pypy/rpython/lltypesystem/rvirtualizable.py (original) +++ pypy/dist/pypy/rpython/lltypesystem/rvirtualizable.py Sun Mar 18 22:25:41 2007 @@ -126,9 +126,10 @@ return ll_setter - def getfield(self, vinst, attr, llops, force_cast=False): + def getfield(self, vinst, attr, llops, force_cast=False, flags={}): """Read the given attribute (or __class__ for the type) of 'vinst'.""" - if attr in self.my_redirected_fields: + if (attr in self.my_redirected_fields + and not flags.get('access_directly')): mangled_name, r = self.fields[attr] if force_cast: vinst = llops.genop('cast_pointer', [vinst], resulttype=self) @@ -137,9 +138,11 @@ else: return InstanceRepr.getfield(self, vinst, attr, llops, force_cast) - def setfield(self, vinst, attr, vvalue, llops, force_cast=False, opname='setfield'): + def setfield(self, vinst, attr, vvalue, llops, force_cast=False, + opname='setfield', flags={}): """Write the given attribute (or __class__ for the type) of 'vinst'.""" - if attr in self.my_redirected_fields: + if (attr in self.my_redirected_fields + and not flags.get('access_directly')): mangled_name, r = self.fields[attr] if force_cast: vinst = llops.genop('cast_pointer', [vinst], resulttype=self) Modified: pypy/dist/pypy/rpython/lltypesystem/test/test_rvirtualizable.py ============================================================================== --- pypy/dist/pypy/rpython/lltypesystem/test/test_rvirtualizable.py (original) +++ pypy/dist/pypy/rpython/lltypesystem/test/test_rvirtualizable.py Sun Mar 18 22:25:41 2007 @@ -1,6 +1,8 @@ import py +from pypy.objspace.flow.model import summary +from pypy.rlib.objectmodel import hint from pypy.rpython.lltypesystem import lltype, rclass -from pypy.rpython.test.test_llinterp import interpret +from pypy.rpython.test.test_llinterp import interpret, get_interpreter from pypy.rpython.annlowlevel import cast_instance_to_base_ptr from pypy.rpython.error import TyperError @@ -200,3 +202,95 @@ res = interpret(f, [42]) assert res.item1 == 42 + +def test_access_directly(): + def g(b): + return b.v0 + + def f(n): + b = B(n) + b = hint(b, access_directly=True) + return g(b) + + interp, graph = get_interpreter(f, [23]) + g_graph = interp.typer.annotator.translator._graphof(g) + assert summary(g_graph) == {'getfield': 1} + + res = interp.eval_graph(graph, [23]) + assert res == 23 + + +def test_access_directly_specialized(): + def g(b): + return b.v0 + + def f(n): + b = B(n) + x = g(b) + y = g(hint(b, access_directly=True)) + return x + y + + interp, graph = get_interpreter(f, [23]) + desc = interp.typer.annotator.bookkeeper.getdesc(g) + g_graphs = desc._cache.values() + assert len(g_graphs) == 2 + summaries = map(summary, g_graphs) + summaries.sort() + assert summaries == [{'direct_call': 1}, + {'getfield': 1}] + + res = interp.eval_graph(graph, [23]) + assert res == 46 + + +def test_access_directly_escape(): + class Global: + pass + glob = Global() + + def g(b): + glob.b = b + + def h(b): + return b.v0 + + def f(n): + b = B(n) + g(b) + g(hint(b, access_directly=True)) + return h(glob.b) + + interp, graph = get_interpreter(f, [23]) + desc = interp.typer.annotator.bookkeeper.getdesc(g) + g_graphs = desc._cache.values() + assert len(g_graphs) == 2 + summaries = map(summary, g_graphs) + summaries.sort() + assert summaries == [{'setfield': 1}, + {'setfield': 1}] + h_graph = interp.typer.annotator.translator._graphof(h) + assert summary(h_graph) == {'direct_call': 1} + + res = interp.eval_graph(graph, [23]) + assert res == 23 + + +def test_access_directly_method(): + class A(B): + def meth1(self, x): + return self.g(x+1) + + def g(self, y): + return self.v0 * y + + def f(n): + a = A(n) + a = hint(a, access_directly=True) + return a.meth1(100) + + interp, graph = get_interpreter(f, [23]) + g_graph = interp.typer.annotator.translator._graphof(A.g.im_func) + assert summary(g_graph) == {'getfield': 1, 'int_mul': 1} + + res = interp.eval_graph(graph, [23]) + assert res == 2323 Modified: pypy/dist/pypy/rpython/rbuiltin.py ============================================================================== --- pypy/dist/pypy/rpython/rbuiltin.py (original) +++ pypy/dist/pypy/rpython/rbuiltin.py Sun Mar 18 22:25:41 2007 @@ -616,23 +616,6 @@ BUILTIN_TYPER[objectmodel.keepalive_until_here] = rtype_keepalive_until_here -# hint - -def rtype_hint(hop, **kwds_i): - hints = {} - for key, index in kwds_i.items(): - s_value = hop.args_s[index] - if not s_value.is_constant(): - raise TyperError("hint %r is not constant" % (key,)) - assert key.startswith('i_') - hints[key[2:]] = s_value.const - v = hop.inputarg(hop.args_r[0], arg=0) - c_hint = hop.inputconst(lltype.Void, hints) - hop.exception_cannot_occur() - return hop.genop('hint', [v, c_hint], resulttype=v.concretetype) - -BUILTIN_TYPER[objectmodel.hint] = rtype_hint - def rtype_cast_ptr_to_adr(hop): vlist = hop.inputargs(hop.args_r[0]) assert isinstance(vlist[0].concretetype, lltype.Ptr) Modified: pypy/dist/pypy/rpython/rpbc.py ============================================================================== --- pypy/dist/pypy/rpython/rpbc.py (original) +++ pypy/dist/pypy/rpython/rpbc.py Sun Mar 18 22:25:41 2007 @@ -806,11 +806,15 @@ mdescs = s_pbc.descriptions.keys() methodname = mdescs[0].name classdef = mdescs[0].selfclassdef + flags = mdescs[0].flags for mdesc in mdescs[1:]: if mdesc.name != methodname: raise TyperError("cannot find a unique name under which the " "methods can be found: %r" % ( mdescs,)) + if mdesc.flags != flags: + raise TyperError("inconsistent 'flags': %r versus %r" % ( + mdesc.flags, flags)) classdef = classdef.commonbase(mdesc.selfclassdef) if classdef is None: raise TyperError("mixing methods coming from instances of " @@ -819,7 +823,7 @@ self.methodname = methodname self.classdef = classdef.locate_attribute(methodname) # the low-level representation is just the bound 'self' argument. - self.s_im_self = annmodel.SomeInstance(self.classdef) + self.s_im_self = annmodel.SomeInstance(self.classdef, flags=flags) self.r_im_self = rclass.getinstancerepr(rtyper, self.classdef) self.lowleveltype = self.r_im_self.lowleveltype From arigo at codespeak.net Sun Mar 18 22:29:30 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 18 Mar 2007 22:29:30 +0100 (CET) Subject: [pypy-svn] r40731 - in pypy/dist/pypy: interpreter jit/goal jit/hintannotator module/pypyjit Message-ID: <20070318212930.8FE9A1008F@code0.codespeak.net> Author: arigo Date: Sun Mar 18 22:29:27 2007 New Revision: 40731 Modified: pypy/dist/pypy/interpreter/pyframe.py pypy/dist/pypy/interpreter/pyopcode.py pypy/dist/pypy/jit/goal/jitstep.py pypy/dist/pypy/jit/hintannotator/model.py pypy/dist/pypy/module/pypyjit/interp_jit.py Log: (pedronis, arigo) Use the 'access_directly' hint in PyPy: - in PyFrame.__init__(), when initializing all the fields; - in PyFrame.dispatch(), the version which is *not* timeshifted. For this one the flag propagates through most of the code of pyopcode.py. The goal is that if a frame is run by the non-jitting copy of the main loop, we know that it is not a virtualized frame, so we can save all the checks and access the fields directly. Modified: pypy/dist/pypy/interpreter/pyframe.py ============================================================================== --- pypy/dist/pypy/interpreter/pyframe.py (original) +++ pypy/dist/pypy/interpreter/pyframe.py Sun Mar 18 22:29:27 2007 @@ -46,6 +46,7 @@ instr_prev = -1 def __init__(self, space, code, w_globals, closure): + self = hint(self, access_directly=True) assert isinstance(code, pycode.PyCode) self.pycode = code eval.Frame.__init__(self, space, w_globals, code.co_nlocals) @@ -320,8 +321,8 @@ return self.pycode.hidden_applevel def getcode(self): - return self.pycode - + return hint(hint(self.pycode, promote=True), deepfreeze=True) + def getfastscope(self): "Get the fast locals as a list." return self.fastlocals_w Modified: pypy/dist/pypy/interpreter/pyopcode.py ============================================================================== --- pypy/dist/pypy/interpreter/pyopcode.py (original) +++ pypy/dist/pypy/interpreter/pyopcode.py Sun Mar 18 22:29:27 2007 @@ -234,9 +234,6 @@ ### accessor functions ### - def getcode(self): - return hint(hint(self.pycode, promote=True), deepfreeze=True) - def getlocalvarname(self, index): return self.getcode().co_varnames[index] Modified: pypy/dist/pypy/jit/goal/jitstep.py ============================================================================== --- pypy/dist/pypy/jit/goal/jitstep.py (original) +++ pypy/dist/pypy/jit/goal/jitstep.py Sun Mar 18 22:29:27 2007 @@ -3,6 +3,7 @@ from pypy.objspace.flow.model import checkgraph from pypy.translator.translator import graphof +from pypy.annotation.specialize import getuniquenondirectgraph from pypy.jit.hintannotator.annotator import HintAnnotator, HintAnnotatorPolicy from pypy.jit.hintannotator.model import OriginFlags, SomeLLAbstractConstant @@ -26,6 +27,12 @@ mod = func.__module__ or '?' if mod.startswith('pypy.objspace'): return False + if mod.startswith('pypy._cache'): + return False + if mod.startswith('pypy.interpreter.astcompiler'): + return False + if mod.startswith('pypy.interpreter.pyparser'): + return False if mod.startswith('pypy.module.'): if not mod.startswith('pypy.module.pypyjit.'): return False @@ -87,19 +94,25 @@ targetgraphs.keys(),)) -def timeshift_graphs(t, portal_graph): +def timeshift_graphs(t, portal_graph, log): result_graphs = {} + bk = t.annotator.bookkeeper + def _graph(func): func = getattr(func, 'im_func', func) - return graphof(t, func) + desc = bk.getdesc(func) + return getuniquenondirectgraph(desc) def seefunc(fromfunc, *tofuncs): targetgraphs = {} for tofunc in tofuncs: targetgraphs[_graph(tofunc)] = True graphs = graphs_on_the_path_to(t, _graph(fromfunc), targetgraphs) - result_graphs.update(graphs) + for graph in graphs: + if graph not in result_graphs: + log('including graph %s' % (graph,)) + result_graphs[graph] = True def seepath(*path): for i in range(1, len(path)): @@ -173,14 +186,15 @@ t = drv.translator portal_graph = graphof(t, PORTAL) - POLICY = PyPyHintAnnotatorPolicy(timeshift_graphs(t, portal_graph)) + POLICY = PyPyHintAnnotatorPolicy(timeshift_graphs(t, portal_graph, + drv.log)) - graphnames = [str(_g) for _g in POLICY.timeshift_graphs] - graphnames.sort() - print '-' * 20 - for graphname in graphnames: - print graphname - print '-' * 20 +## graphnames = [str(_g) for _g in POLICY.timeshift_graphs] +## graphnames.sort() +## print '-' * 20 +## for graphname in graphnames: +## print graphname +## print '-' * 20 hannotator = HintAnnotator(base_translator=t, policy=POLICY) hs = hannotator.build_types(portal_graph, Modified: pypy/dist/pypy/jit/hintannotator/model.py ============================================================================== --- pypy/dist/pypy/jit/hintannotator/model.py (original) +++ pypy/dist/pypy/jit/hintannotator/model.py Sun Mar 18 22:29:27 2007 @@ -322,7 +322,8 @@ hs_clone = hs_v1.clone() hs_clone.deepfrozen = True return hs_clone - for name in ["reverse_split_queue", "global_merge_point"]: + for name in ["reverse_split_queue", "global_merge_point", + "access_directly"]: if hs_flags.const.get(name, False): return Modified: pypy/dist/pypy/module/pypyjit/interp_jit.py ============================================================================== --- pypy/dist/pypy/module/pypyjit/interp_jit.py (original) +++ pypy/dist/pypy/module/pypyjit/interp_jit.py Sun Mar 18 22:29:27 2007 @@ -29,6 +29,7 @@ if pycode.jit_enable: return self.dispatch_jit(pycode, next_instr, ec) else: + self = hint(self, access_directly=True) return super_dispatch(self, pycode, next_instr, ec) def dispatch_jit(self, pycode, next_instr, ec): From mwh at codespeak.net Sun Mar 18 22:53:23 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Sun, 18 Mar 2007 22:53:23 +0100 (CET) Subject: [pypy-svn] r40732 - pypy/dist/pypy/translator/llvm Message-ID: <20070318215323.C711D1008F@code0.codespeak.net> Author: mwh Date: Sun Mar 18 22:53:21 2007 New Revision: 40732 Modified: pypy/dist/pypy/translator/llvm/funcnode.py Log: fix all the LLVM tests that failed since the merge of the jit-virtual-world branch -- the changes to the exceptiontransformer meant genllvm's assumptions about exitcase ordering were no longer true. ps: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaargh Modified: pypy/dist/pypy/translator/llvm/funcnode.py ============================================================================== --- pypy/dist/pypy/translator/llvm/funcnode.py (original) +++ pypy/dist/pypy/translator/llvm/funcnode.py Sun Mar 18 22:53:21 2007 @@ -158,9 +158,18 @@ cond, condtype = self.db.repr_argwithtype(block.exitswitch) if block.exitswitch.concretetype == lltype.Bool: assert len(block.exits) == 2 + if block.exits[0].llexitcase == False: + assert block.exits[1].llexitcase == True + false_case = block.exits[0].target + true_case = block.exits[1].target + else: + assert block.exits[0].llexitcase == True + assert block.exits[1].llexitcase == False + false_case = block.exits[1].target + true_case = block.exits[0].target codewriter.br(cond, - self.block_to_name[block.exits[0].target], - self.block_to_name[block.exits[1].target]) + self.block_to_name[false_case], + self.block_to_name[true_case]) elif block.exitswitch.concretetype in \ (lltype.Signed, lltype.Unsigned, lltype.SignedLongLong, From arigo at codespeak.net Sun Mar 18 22:58:02 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 18 Mar 2007 22:58:02 +0100 (CET) Subject: [pypy-svn] r40733 - pypy/dist/pypy/module/pypyjit/test Message-ID: <20070318215802.3BB901008F@code0.codespeak.net> Author: arigo Date: Sun Mar 18 22:57:58 2007 New Revision: 40733 Modified: pypy/dist/pypy/module/pypyjit/test/test_pypy_c.py Log: (pedronis, arigo) Fix import. Modified: pypy/dist/pypy/module/pypyjit/test/test_pypy_c.py ============================================================================== --- pypy/dist/pypy/module/pypyjit/test/test_pypy_c.py (original) +++ pypy/dist/pypy/module/pypyjit/test/test_pypy_c.py Sun Mar 18 22:57:58 2007 @@ -103,7 +103,7 @@ def app_test_richards(): run_source(''' import sys; sys.path[:] = %r - import richards + from pypy.translator.goal import richards def main(): return richards.main(iterations = 1) From arigo at codespeak.net Sun Mar 18 23:07:57 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 18 Mar 2007 23:07:57 +0100 (CET) Subject: [pypy-svn] r40734 - pypy/dist/pypy/jit Message-ID: <20070318220757.34B6710092@code0.codespeak.net> Author: arigo Date: Sun Mar 18 23:07:53 2007 New Revision: 40734 Modified: pypy/dist/pypy/jit/TODO.txt Log: (pedronis, arigo) That was easy. Almost. Modified: pypy/dist/pypy/jit/TODO.txt ============================================================================== --- pypy/dist/pypy/jit/TODO.txt (original) +++ pypy/dist/pypy/jit/TODO.txt Sun Mar 18 23:07:53 2007 @@ -6,9 +6,6 @@ - improve is_true() -- make jit builds not horribly slower than regular builds - when running non-jitted code - - some --jit option for translate.py - basic docs and examples From arigo at codespeak.net Sun Mar 18 23:21:36 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 18 Mar 2007 23:21:36 +0100 (CET) Subject: [pypy-svn] r40735 - in pypy/dist/pypy/jit: goal hintannotator Message-ID: <20070318222136.3B55A10092@code0.codespeak.net> Author: arigo Date: Sun Mar 18 23:21:34 2007 New Revision: 40735 Modified: pypy/dist/pypy/jit/goal/jitstep.py pypy/dist/pypy/jit/hintannotator/bookkeeper.py Log: Count the stub and non-stub graphs separately. Modified: pypy/dist/pypy/jit/goal/jitstep.py ============================================================================== --- pypy/dist/pypy/jit/goal/jitstep.py (original) +++ pypy/dist/pypy/jit/goal/jitstep.py Sun Mar 18 23:21:34 2007 @@ -201,8 +201,9 @@ [SomeLLAbstractConstant(v.concretetype, {OriginFlags(): True}) for v in portal_graph.getargs()]) - drv.log.info('Hint-annotated %d graphs.' % ( - len(hannotator.translator.graphs),)) + count = hannotator.bookkeeper.nonstubgraphcount + drv.log.info('Hint-annotated %d graphs (plus %d stubs).' % ( + count, len(hannotator.translator.graphs) - count)) n = len(list(hannotator.translator.graphs[0].iterblocks())) drv.log.info("portal has %d blocks" % n) drv.hannotator = hannotator Modified: pypy/dist/pypy/jit/hintannotator/bookkeeper.py ============================================================================== --- pypy/dist/pypy/jit/hintannotator/bookkeeper.py (original) +++ pypy/dist/pypy/jit/hintannotator/bookkeeper.py Sun Mar 18 23:21:34 2007 @@ -49,6 +49,7 @@ bk = self.bookkeeper if bk.annotator.policy.look_inside_graph(self.origgraph): graph = copygraph(self.origgraph, varmap=TIMESHIFTMAP) + bk.nonstubgraphcount += 1 log(str(graph)) else: graph = self.build_callback_graph(self.origgraph) @@ -115,6 +116,7 @@ self.tsgraph_maximal_call_families = UnionFind(TsGraphCallFamily) self.annotator = hannotator self.tsgraphsigs = {} + self.nonstubgraphcount = 0 if hannotator is not None: # for tests t = hannotator.base_translator self.impurity_analyzer = ImpurityAnalyzer(t) From cfbolz at codespeak.net Sun Mar 18 23:24:22 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sun, 18 Mar 2007 23:24:22 +0100 (CET) Subject: [pypy-svn] r40736 - in pypy/dist/pypy/config: . test Message-ID: <20070318222422.AB23710092@code0.codespeak.net> Author: cfbolz Date: Sun Mar 18 23:24:19 2007 New Revision: 40736 Modified: pypy/dist/pypy/config/config.py pypy/dist/pypy/config/test/test_config.py Log: add a __delattr__ for debugging purposes Modified: pypy/dist/pypy/config/config.py ============================================================================== --- pypy/dist/pypy/config/config.py (original) +++ pypy/dist/pypy/config/config.py Sun Mar 18 23:24:19 2007 @@ -74,6 +74,18 @@ (self.__class__, name)) return self._cfgimpl_values[name] + def __delattr__(self, name): + # XXX if you use delattr you are responsible for all bad things + # happening + if name.startswith('_cfgimpl_'): + del self.__dict__[name] + return + self._cfgimpl_value_owners[name] = 'default' + opt = getattr(self._cfgimpl_descr, name) + if isinstance(opt, OptionDescription): + raise AttributeError("can't option subgroup") + self._cfgimpl_values[name] = getattr(opt, 'default', None) + def setoption(self, name, value, who): if name not in self._cfgimpl_values: raise AttributeError('unknown option %s' % (name,)) 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 Sun Mar 18 23:24:19 2007 @@ -471,3 +471,15 @@ assert c.opt assert not c.toplevel +def test_delattr(): + descr = OptionDescription("opt", "", [ + OptionDescription("s1", "", [ + BoolOption("a", "", default=False)]), + IntOption("int", "", default=42)]) + c = Config(descr) + c.int = 45 + assert c.int == 45 + del c.int + assert c.int == 42 + c.int = 45 + assert c.int == 45 From antocuni at codespeak.net Mon Mar 19 10:20:19 2007 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Mon, 19 Mar 2007 10:20:19 +0100 (CET) Subject: [pypy-svn] r40747 - pypy/dist/pypy/translator/cli Message-ID: <20070319092019.E1A131006F@code0.codespeak.net> Author: antocuni Date: Mon Mar 19 10:20:16 2007 New Revision: 40747 Modified: pypy/dist/pypy/translator/cli/ilgenerator.py Log: Fix cli translation Modified: pypy/dist/pypy/translator/cli/ilgenerator.py ============================================================================== --- pypy/dist/pypy/translator/cli/ilgenerator.py (original) +++ pypy/dist/pypy/translator/cli/ilgenerator.py Mon Mar 19 10:20:16 2007 @@ -262,7 +262,8 @@ def flush(self): pass -DEFINED_INT_SYMBOLICS = {'MALLOC_ZERO_FILLED':1} +DEFINED_INT_SYMBOLICS = {'MALLOC_ZERO_FILLED': 1, + '0 /* we are not jitted here */': 0} class CLIBaseGenerator(Generator): From mwh at codespeak.net Mon Mar 19 10:33:58 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Mon, 19 Mar 2007 10:33:58 +0100 (CET) Subject: [pypy-svn] r40748 - pypy/dist/pypy/jit/codegen/ppc Message-ID: <20070319093358.24AB41006F@code0.codespeak.net> Author: mwh Date: Mon Mar 19 10:33:52 2007 New Revision: 40748 Modified: pypy/dist/pypy/jit/codegen/ppc/rgenop.py Log: fixing the ppc jit tests step 1 of n: test_write_frame_place_direct (easy) 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 Mon Mar 19 10:33:52 2007 @@ -392,8 +392,10 @@ result.append(None) return result - def alloc_frame_place(self, kind, gv_initial_value): + def alloc_frame_place(self, kind, gv_initial_value=None): place = StackInfo() + if gv_initial_value is None: + gv_initial_value = AddrConst(llmemory.NULL) self.insns.append(insn.CopyIntoStack(place, gv_initial_value)) return place From afayolle at codespeak.net Mon Mar 19 11:00:02 2007 From: afayolle at codespeak.net (afayolle at codespeak.net) Date: Mon, 19 Mar 2007 11:00:02 +0100 (CET) Subject: [pypy-svn] r40750 - in pypy/dist/pypy: interpreter/test module/recparser/test Message-ID: <20070319100002.64CD510036@code0.codespeak.net> Author: afayolle Date: Mon Mar 19 11:00:00 2007 New Revision: 40750 Modified: pypy/dist/pypy/interpreter/test/test_compiler.py pypy/dist/pypy/module/recparser/test/test_compilehooks.py Log: fixed tests broken by last friday's commit (thanks arigo for the notice) 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 Mon Mar 19 11:00:00 2007 @@ -595,7 +595,7 @@ return parser.ASTConst(left.value + right.value) return node - def hook(ast, enc): + def hook(ast, enc, filename): return ast.mutate(Folder()) parser.install_compiler_hook(hook) Modified: pypy/dist/pypy/module/recparser/test/test_compilehooks.py ============================================================================== --- pypy/dist/pypy/module/recparser/test/test_compilehooks.py (original) +++ pypy/dist/pypy/module/recparser/test/test_compilehooks.py Mon Mar 19 11:00:00 2007 @@ -2,7 +2,7 @@ def test_basic_hook(self): # define the hook - def threebecomestwo(ast, enc): + def threebecomestwo(ast, enc, filename): class ChangeConstVisitor: def visitConst(self, node): if node.value == 3: @@ -28,14 +28,14 @@ assert d['a'] == 2 # well, yes ... def test_removal_of_broken_hooks(self): - def hook(ast, enc): + def hook(ast, enc, filename): 1/0 import parser parser.install_compiler_hook(hook) raises(ZeroDivisionError, "eval('1')") assert eval("1") == 1 - def hook2(ast, enc): + def hook2(ast, enc, filename): return 1 parser.install_compiler_hook(hook2) raises(TypeError, "eval('2')") @@ -46,7 +46,7 @@ class DISABLEDAppTest_GlobalsAsConsts: def test_ast_parser(self): # define the hook - def change_globals(ast, enc): + def change_globals(ast, enc, filename): class ChangeGlobalsVisitor: def visitConst(self, node): pass From mwh at codespeak.net Mon Mar 19 11:25:28 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Mon, 19 Mar 2007 11:25:28 +0100 (CET) Subject: [pypy-svn] r40751 - pypy/dist/pypy/jit/codegen/ppc Message-ID: <20070319102528.E47E410069@code0.codespeak.net> Author: mwh Date: Mon Mar 19 11:25:27 2007 New Revision: 40751 Modified: pypy/dist/pypy/jit/codegen/ppc/instruction.py pypy/dist/pypy/jit/codegen/ppc/rgenop.py Log: fixing the ppc jit tests step 2 of n: enough raising op support to pass the relevant tests in rgenop_tests. 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 Mon Mar 19 11:25:27 2007 @@ -239,6 +239,30 @@ self.result_reg.number, self.arg_reg.number) + +class Insn_GPR(Insn): + def __init__(self, methptr, result): + Insn.__init__(self) + self.methptr = methptr + + self.result = result + self.result_regclass = GP_REGISTER + self.reg_args = [] + self.reg_arg_regclasses = [] + self.result_reg = None + def allocate(self, allocator): + self.result_reg = allocator.loc_of(self.result) + def __repr__(self): + if self.result_reg: + r = "%s@%s"%(self.result, self.result_reg) + else: + r = str(self.result) + return "<%s-%d %s %s>" % (self.__class__.__name__, self._magic_index, + self.methptr.im_func.func_name, r) + def emit(self, asm): + self.methptr(asm, + self.result_reg.number) + class Insn_GPR__IMM(Insn): def __init__(self, methptr, result, args): Insn.__init__(self) @@ -327,6 +351,40 @@ self.reg2.number, self.reg3.number) +class Extrwi(Insn): + def __init__(self, result, source, size, bit): + Insn.__init__(self) + + self.result = result + self.result_regclass = GP_REGISTER + self.reg_args = [source] + self.reg_arg_regclasses = [GP_REGISTER] + self.result_reg = None + self.arg_reg = None + + self.size = size + self.bit = bit + def allocate(self, allocator): + self.result_reg = allocator.loc_of(self.result) + self.arg_reg = allocator.loc_of(self.reg_args[0]) + def __repr__(self): + if self.result_reg: + r = "%s@%s"%(self.result, self.result_reg) + else: + r = str(self.result) + if self.arg_reg: + a = "%s@%s"%(self.reg_args[0], self.arg_reg) + else: + a = str(self.reg_args[0]) + return "<%s-%d extrwi %s, %s, %s, %s>" % (self.__class__.__name__, self._magic_index, + r, a, self.size, self.bit) + + def emit(self, asm): + asm.extrwi(self.result_reg.number, + self.arg_reg.number, + self.size, self.bit) + + class CMPInsn(Insn): def __init__(self, info, result): 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 Mon Mar 19 11:25:27 2007 @@ -270,6 +270,18 @@ #print '->', id(r) return r + @specialize.arg(1) + def genraisingop2(self, opname, gv_arg1, gv_arg2): + genmethod = getattr(self, 'raisingop_' + opname) + r = genmethod(gv_arg1, gv_arg2) + return r + + @specialize.arg(1) + def genraisingop1(self, opname, gv_arg): + genmethod = getattr(self, 'raisingop_' + opname) + r = genmethod(gv_arg) + return r + def genop_ptr_iszero(self, kind, gv_ptr): return self.op_ptr_iszero(gv_ptr) @@ -810,6 +822,16 @@ return targetbuilder + def _ov(self): + # mfxer rFOO + # extrwi rBAR, rFOO, 1, 1 + gv_xer = Var() + self.insns.append( + insn.Insn_GPR(_PPC.mfxer, gv_xer)) + gv_ov = Var() + self.insns.append(insn.Extrwi(gv_ov, gv_xer, 1, 1)) + return gv_ov + def op_bool_not(self, gv_arg): return self._arg_uimm_op(gv_arg, self.rgenop.genconst(1), RPPCAssembler.xori) @@ -819,14 +841,21 @@ def op_int_neg(self, gv_arg): return self._arg_op(gv_arg, _PPC.neg) - ## op_int_neg_ovf(self, gv_arg) XXX + def raisingop_int_neg_ovf(self, gv_arg): + gv_result = self._arg_op(gv_arg, _PPC.nego) + gv_ov = self._ov() + return (gv_result, gv_ov) def op_int_abs(self, gv_arg): gv_sign = self._arg_uimm_op(gv_arg, self.rgenop.genconst(31), _PPC.srawi) gv_maybe_inverted = self._arg_arg_op(gv_arg, gv_sign, _PPC.xor) return self._arg_arg_op(gv_sign, gv_maybe_inverted, _PPC.subf) - ## op_int_abs_ovf(self, gv_arg): + def raisingop_int_abs_ovf(self, gv_arg): + gv_sign = self._arg_uimm_op(gv_arg, self.rgenop.genconst(31), _PPC.srawi) + gv_maybe_inverted = self._arg_arg_op(gv_arg, gv_sign, _PPC.xor) + gv_result = self._arg_arg_op(gv_sign, gv_maybe_inverted, _PPC.subfo) + return (gv_result, self._ov()) def op_int_invert(self, gv_arg): return self._arg_op(gv_arg, _PPC.not_) @@ -835,13 +864,28 @@ return self._arg_arg_op_with_simm(gv_x, gv_y, _PPC.add, _PPC.addi, commutative=True) + def raisingop_int_add_ovf(self, gv_x, gv_y): + gv_result = self._arg_arg_op(gv_x, gv_y, _PPC.addo) + gv_ov = self._ov() + return (gv_result, gv_ov) + def op_int_sub(self, gv_x, gv_y): return self._arg_arg_op_with_simm(gv_x, gv_y, _PPC.sub, _PPC.subi) + def raisingop_int_sub_ovf(self, gv_x, gv_y): + gv_result = self._arg_arg_op(gv_x, gv_y, _PPC.subo) + gv_ov = self._ov() + return (gv_result, gv_ov) + def op_int_mul(self, gv_x, gv_y): return self._arg_arg_op_with_simm(gv_x, gv_y, _PPC.mullw, _PPC.mulli, commutative=True) + def raisingop_int_mul_ovf(self, gv_x, gv_y): + gv_result = self._arg_arg_op(gv_x, gv_y, _PPC.mullwo) + gv_ov = self._ov() + return (gv_result, gv_ov) + def op_int_floordiv(self, gv_x, gv_y): return self._arg_arg_op(gv_x, gv_y, _PPC.divw) From mwh at codespeak.net Mon Mar 19 11:39:42 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Mon, 19 Mar 2007 11:39:42 +0100 (CET) Subject: [pypy-svn] r40752 - pypy/dist/pypy/jit/codegen/ppc Message-ID: <20070319103942.9B9FE1006F@code0.codespeak.net> Author: mwh Date: Mon Mar 19 11:39:38 2007 New Revision: 40752 Modified: pypy/dist/pypy/jit/codegen/ppc/instruction.py Log: so far unimportant, but funny, typo 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 Mon Mar 19 11:39:38 2007 @@ -67,7 +67,7 @@ Register.__init__(self) self.number = number -fprs = map(GPR, range(32)) +fprs = map(FPR, range(32)) class BaseCRF(Register): """ These represent condition registers; however, we never actually From mwh at codespeak.net Mon Mar 19 11:45:37 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Mon, 19 Mar 2007 11:45:37 +0100 (CET) Subject: [pypy-svn] r40754 - pypy/dist/pypy/jit/codegen/ppc Message-ID: <20070319104537.78E3710072@code0.codespeak.net> Author: mwh Date: Mon Mar 19 11:45:34 2007 New Revision: 40754 Modified: pypy/dist/pypy/jit/codegen/ppc/rgenop.py Log: last of the fixes for test_rgenop -k direct: a potentially nasty one about not propagating the amount of stack we're using through to builders created by FlexSwitches. 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 Mon Mar 19 11:45:34 2007 @@ -509,7 +509,8 @@ result = FlexSwitch(self.rgenop, switch_mc, allocator.loc_of(gv_exitswitch), allocator.loc_of(crresult), - allocator.var2loc) + allocator.var2loc, + allocator.spill_offset) return result, result.add_default() def start_writing(self): @@ -1300,11 +1301,12 @@ # a fair part of this code could likely be shared with the i386 # backend. - def __init__(self, rgenop, mc, switch_reg, crf, var2loc): + def __init__(self, rgenop, mc, switch_reg, crf, var2loc, initial_spill_offset): self.rgenop = rgenop self.crf = crf self.switch_reg = switch_reg self.var2loc = var2loc + self.initial_spill_offset = initial_spill_offset self.asm = RPPCAssembler() self.asm.mc = mc self.default_target_addr = 0 @@ -1313,6 +1315,7 @@ targetbuilder = self.rgenop.newbuilder() targetbuilder._open() targetbuilder.initial_var2loc = self.var2loc + targetbuilder.initial_spill_offset = self.initial_spill_offset target_addr = targetbuilder.asm.mc.tell() p = self.asm.mc.getpos() # that this works depends a bit on the fixed length of the @@ -1349,6 +1352,7 @@ targetbuilder = self.rgenop.newbuilder() targetbuilder._open() targetbuilder.initial_var2loc = self.var2loc + targetbuilder.initial_spill_offset = self.initial_spill_offset self.default_target_addr = targetbuilder.asm.mc.tell() self._write_default() return targetbuilder From arigo at codespeak.net Mon Mar 19 11:45:58 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 19 Mar 2007 11:45:58 +0100 (CET) Subject: [pypy-svn] r40755 - pypy/dist/pypy/jit/codegen/i386 Message-ID: <20070319104558.9308510077@code0.codespeak.net> Author: arigo Date: Mon Mar 19 11:45:56 2007 New Revision: 40755 Modified: pypy/dist/pypy/jit/codegen/i386/operation.py Log: - a simpler implementation of int_abs_ovf - bug fix Modified: pypy/dist/pypy/jit/codegen/i386/operation.py ============================================================================== --- pypy/dist/pypy/jit/codegen/i386/operation.py (original) +++ pypy/dist/pypy/jit/codegen/i386/operation.py Mon Mar 19 11:45:56 2007 @@ -59,8 +59,9 @@ emit = staticmethod(I386CodeBuilder.NOT) class OpIntAbs(Op1): - opname = 'int_abs' + opname = 'int_abs', 'int_abs_ovf' side_effects = False + ccexcflag = Conditions['L'] def mark_used_vars(self, allocator): allocator.using(self.x) def generate(self, allocator): @@ -77,14 +78,6 @@ mc.XOR(dstop, tmpop) allocator.end_clobber(tmpop) -class OpIntAbsOvf(OpIntAbs): - opname = 'int_abs_ovf' - ccexcflag = Conditions['E'] - def generate(self, allocator): - OpIntAbs.generate(self, allocator) - mc = allocator.mc - mc.CMP(allocator.var2loc[self], imm(-sys.maxint-1)) - class OpSameAs(Op1): clobbers_cc = False # special handling of the cc side_effects = False @@ -1015,7 +1008,7 @@ load_into_cc_ge = load_into_cc_eq ccflag_o = CCFLAG('O', load_into_cc_o) -ccflag_no = CCFLAG('O', load_into_cc_no) +ccflag_no = CCFLAG('NO', load_into_cc_no) ccflag_lt = CCFLAG('L', load_into_cc_lt) ccflag_le = CCFLAG('LE', load_into_cc_le) From fijal at codespeak.net Mon Mar 19 12:01:46 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 19 Mar 2007 12:01:46 +0100 (CET) Subject: [pypy-svn] r40757 - pypy/dist/pypy/lib/distributed/test Message-ID: <20070319110146.3B89B10063@code0.codespeak.net> Author: fijal Date: Mon Mar 19 12:01:43 2007 New Revision: 40757 Modified: pypy/dist/pypy/lib/distributed/test/test_greensock.py Log: Make this a bit aware of location of pylib Modified: pypy/dist/pypy/lib/distributed/test/test_greensock.py ============================================================================== --- pypy/dist/pypy/lib/distributed/test/test_greensock.py (original) +++ pypy/dist/pypy/lib/distributed/test/test_greensock.py Mon Mar 19 12:01:43 2007 @@ -7,36 +7,38 @@ cls.space = gettestobjspace(**{"objspace.std.withtproxy": True, "usemodules":("_stackless",)}) cls.w_remote_side_code = cls.space.appexec([], """(): - import py - remote_side_code = str(py.code.Source(''' - class A: - def __init__(self, x): - self.x = x + import sys + sys.path.insert(0, '%s') + remote_side_code = ''' +class A: + def __init__(self, x): + self.x = x - def __len__(self): - return self.x + 8 + def __len__(self): + return self.x + 8 - def raising(self): - 1/0 + def raising(self): + 1/0 - def method(self, x): - return x() + self.x + def method(self, x): + return x() + self.x - a = A(3) - - def count(): - x = 10 - # naive counting :) - result = 1 - for i in range(x): - result += 1 - return result - ''')) +a = A(3) + +def count(): + x = 10 + # naive counting :) + result = 1 + for i in range(x): + result += 1 + return result +''' return remote_side_code - """) + """ % str(py.path.local(__file__).dirpath().dirpath().dirpath().dirpath())) def test_remote_call(self): from distributed import socklayer + import sys from py.__.green.greenexecnet import PopenGateway gw = PopenGateway() rp = socklayer.spawn_remote_side(self.remote_side_code, gw) From arigo at codespeak.net Mon Mar 19 12:03:44 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 19 Mar 2007 12:03:44 +0100 (CET) Subject: [pypy-svn] r40758 - pypy/dist/pypy/jit/codegen/llvm Message-ID: <20070319110344.891F210063@code0.codespeak.net> Author: arigo Date: Mon Mar 19 12:03:41 2007 New Revision: 40758 Modified: pypy/dist/pypy/jit/codegen/llvm/conftest.py Log: Skip the jit.codegen.llvm tests again, for now. Modified: pypy/dist/pypy/jit/codegen/llvm/conftest.py ============================================================================== --- pypy/dist/pypy/jit/codegen/llvm/conftest.py (original) +++ pypy/dist/pypy/jit/codegen/llvm/conftest.py Mon Mar 19 12:03:41 2007 @@ -3,9 +3,10 @@ #XXX Should check here if llvm supports a JIT for this platform (perhaps using lli?) -#class Directory(py.test.collect.Directory): -# -# def run(self): +class Directory(py.test.collect.Directory): + + def run(self): + py.test.skip("skipping jit.codegen.llvm for now") # try: # processor = detect_cpu.autodetect() # except detect_cpu.ProcessorAutodetectError, e: @@ -13,8 +14,8 @@ # else: # if processor != 'i386': # py.test.skip('detected a %r CPU' % (processor,)) -# -# return super(Directory, self).run() + + return super(Directory, self).run() Option = py.test.config.Option From fijal at codespeak.net Mon Mar 19 12:07:05 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 19 Mar 2007 12:07:05 +0100 (CET) Subject: [pypy-svn] r40759 - pypy/dist/pypy/translator/js/test Message-ID: <20070319110705.DC0281007D@code0.codespeak.net> Author: fijal Date: Mon Mar 19 12:07:04 2007 New Revision: 40759 Modified: pypy/dist/pypy/translator/js/test/test_rfloat.py Log: Easy fix :) Modified: pypy/dist/pypy/translator/js/test/test_rfloat.py ============================================================================== --- pypy/dist/pypy/translator/js/test/test_rfloat.py (original) +++ pypy/dist/pypy/translator/js/test/test_rfloat.py Mon Mar 19 12:07:04 2007 @@ -2,7 +2,23 @@ import py from pypy.translator.js.test.runtest import JsTest from pypy.rpython.test.test_rfloat import BaseTestRfloat +from pypy.rlib.rarithmetic import r_uint, r_longlong class TestJsFloat(JsTest, BaseTestRfloat): def test_from_r_uint(self): py.test.skip("Not implemented") + + def test_longlong_conversion(self): + def fn(f): + return r_longlong(f) + + res = self.interpret(fn, [1.0]) + assert res == 1 + #assert self.is_of_type(res, r_longlong) + res = self.interpret(fn, [2.34]) + assert res == fn(2.34) + big = float(0x7fffffffffffffff) + x = big - 1.e10 + assert x != big + y = fn(x) + assert fn(x) == 9223372026854775808 From fijal at codespeak.net Mon Mar 19 12:08:12 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 19 Mar 2007 12:08:12 +0100 (CET) Subject: [pypy-svn] r40760 - pypy/dist/pypy/lib/distributed Message-ID: <20070319110812.1B34F10080@code0.codespeak.net> Author: fijal Date: Mon Mar 19 12:08:11 2007 New Revision: 40760 Modified: pypy/dist/pypy/lib/distributed/socklayer.py Log: Fix import Modified: pypy/dist/pypy/lib/distributed/socklayer.py ============================================================================== --- pypy/dist/pypy/lib/distributed/socklayer.py (original) +++ pypy/dist/pypy/lib/distributed/socklayer.py Mon Mar 19 12:08:11 2007 @@ -1,7 +1,7 @@ import py from socket import socket -from py.__.net.msgstruct import decodemessage, message +from py.__.green.msgstruct import decodemessage, message from socket import socket, AF_INET, SOCK_STREAM import marshal import sys From fijal at codespeak.net Mon Mar 19 12:12:45 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 19 Mar 2007 12:12:45 +0100 (CET) Subject: [pypy-svn] r40761 - pypy/dist/pypy/lib/distributed/test Message-ID: <20070319111245.3D55A10082@code0.codespeak.net> Author: fijal Date: Mon Mar 19 12:12:43 2007 New Revision: 40761 Modified: pypy/dist/pypy/lib/distributed/test/test_greensock.py Log: Skip those tests when not run -A Modified: pypy/dist/pypy/lib/distributed/test/test_greensock.py ============================================================================== --- pypy/dist/pypy/lib/distributed/test/test_greensock.py (original) +++ pypy/dist/pypy/lib/distributed/test/test_greensock.py Mon Mar 19 12:12:43 2007 @@ -1,9 +1,11 @@ import py -from pypy.conftest import gettestobjspace +from pypy.conftest import gettestobjspace, option class AppTestDistributedGreensock(object): def setup_class(cls): + if not option.runappdirect: + py.test.skip("Cannot run this on top of py.py because of PopenGateway") cls.space = gettestobjspace(**{"objspace.std.withtproxy": True, "usemodules":("_stackless",)}) cls.w_remote_side_code = cls.space.appexec([], """(): From mwh at codespeak.net Mon Mar 19 12:21:09 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Mon, 19 Mar 2007 12:21:09 +0100 (CET) Subject: [pypy-svn] r40762 - pypy/dist/pypy/jit/codegen/ppc Message-ID: <20070319112109.12DFB1006F@code0.codespeak.net> Author: mwh Date: Mon Mar 19 12:21:07 2007 New Revision: 40762 Modified: pypy/dist/pypy/jit/codegen/ppc/instruction.py Log: weaken a too-tight assert 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 Mon Mar 19 12:21:07 2007 @@ -734,7 +734,7 @@ self.reg = reg self.stack = stack if not isinstance(self.reg, GPR): - assert isinstance(self.reg, CRF) + assert isinstance(self.reg, CRF) or isinstance(self.reg, CTR) self.moveinsn = self.reg.move_from_gpr(None, 0) else: self.moveinsn = None From arigo at codespeak.net Mon Mar 19 13:04:32 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 19 Mar 2007 13:04:32 +0100 (CET) Subject: [pypy-svn] r40764 - pypy/dist/pypy/tool Message-ID: <20070319120432.EF7A31006F@code0.codespeak.net> Author: arigo Date: Mon Mar 19 13:04:30 2007 New Revision: 40764 Modified: pypy/dist/pypy/tool/ansi_print.py Log: Trying with navy blue instead of a dark gray that shows up as black on black on some terminal. Modified: pypy/dist/pypy/tool/ansi_print.py ============================================================================== --- pypy/dist/pypy/tool/ansi_print.py (original) +++ pypy/dist/pypy/tool/ansi_print.py Mon Mar 19 13:04:30 2007 @@ -17,7 +17,7 @@ 'event': ((1,), True), 'ERROR': ((1, 31), False), 'info': ((35,), False), - 'stub': ((1, 30), False), + 'stub': ((34,), False), } def __init__(self, kw_to_color={}, file=None): From guido at codespeak.net Mon Mar 19 13:23:49 2007 From: guido at codespeak.net (guido at codespeak.net) Date: Mon, 19 Mar 2007 13:23:49 +0100 (CET) Subject: [pypy-svn] r40765 - in pypy/dist/pypy/tool/build/testproject: . bin builds dist dist/test Message-ID: <20070319122349.EC1241006F@code0.codespeak.net> Author: guido Date: Mon Mar 19 13:23:44 2007 New Revision: 40765 Added: pypy/dist/pypy/tool/build/testproject/ pypy/dist/pypy/tool/build/testproject/__init__.py pypy/dist/pypy/tool/build/testproject/bin/ pypy/dist/pypy/tool/build/testproject/bin/autopath.py pypy/dist/pypy/tool/build/testproject/bin/buildserver.py (contents, props changed) pypy/dist/pypy/tool/build/testproject/bin/metaserver.py (contents, props changed) pypy/dist/pypy/tool/build/testproject/bin/startcompile.py (contents, props changed) pypy/dist/pypy/tool/build/testproject/builds/ pypy/dist/pypy/tool/build/testproject/compileoption.py pypy/dist/pypy/tool/build/testproject/config.py pypy/dist/pypy/tool/build/testproject/dist/ pypy/dist/pypy/tool/build/testproject/dist/test/ pypy/dist/pypy/tool/build/testproject/dist/test/test.c pypy/dist/pypy/tool/build/testproject/systemoption.py pypy/dist/pypy/tool/build/testproject/tooloption.py Log: Small test project to test the build tool with. Added: pypy/dist/pypy/tool/build/testproject/__init__.py ============================================================================== Added: pypy/dist/pypy/tool/build/testproject/bin/autopath.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/tool/build/testproject/bin/autopath.py Mon Mar 19 13:23:44 2007 @@ -0,0 +1,114 @@ +""" +self cloning, automatic path configuration + +copy this into any subdirectory of pypy from which scripts need +to be run, typically all of the test subdirs. +The idea is that any such script simply issues + + import autopath + +and this will make sure that the parent directory containing "pypy" +is in sys.path. + +If you modify the master "autopath.py" version (in pypy/tool/autopath.py) +you can directly run it which will copy itself on all autopath.py files +it finds under the pypy root directory. + +This module always provides these attributes: + + pypydir pypy root directory path + this_dir directory where this autopath.py resides + +""" + + +def __dirinfo(part): + """ return (partdir, this_dir) and insert parent of partdir + into sys.path. If the parent directories don't have the part + an EnvironmentError is raised.""" + + import sys, os + try: + head = this_dir = os.path.realpath(os.path.dirname(__file__)) + except NameError: + head = this_dir = os.path.realpath(os.path.dirname(sys.argv[0])) + + while head: + partdir = head + head, tail = os.path.split(head) + if tail == part: + break + else: + raise EnvironmentError, "'%s' missing in '%r'" % (partdir, this_dir) + + pypy_root = os.path.join(head, '') + try: + sys.path.remove(head) + except ValueError: + pass + sys.path.insert(0, head) + + munged = {} + for name, mod in sys.modules.items(): + if '.' in name: + continue + fn = getattr(mod, '__file__', None) + if not isinstance(fn, str): + continue + newname = os.path.splitext(os.path.basename(fn))[0] + if not newname.startswith(part + '.'): + continue + path = os.path.join(os.path.dirname(os.path.realpath(fn)), '') + if path.startswith(pypy_root) and newname != part: + modpaths = os.path.normpath(path[len(pypy_root):]).split(os.sep) + if newname != '__init__': + modpaths.append(newname) + modpath = '.'.join(modpaths) + if modpath not in sys.modules: + munged[modpath] = mod + + for name, mod in munged.iteritems(): + if name not in sys.modules: + sys.modules[name] = mod + if '.' in name: + prename = name[:name.rfind('.')] + postname = name[len(prename)+1:] + if prename not in sys.modules: + __import__(prename) + if not hasattr(sys.modules[prename], postname): + setattr(sys.modules[prename], postname, mod) + + return partdir, this_dir + +def __clone(): + """ clone master version of autopath.py into all subdirs """ + from os.path import join, walk + if not this_dir.endswith(join('pypy','tool')): + raise EnvironmentError("can only clone master version " + "'%s'" % join(pypydir, 'tool',_myname)) + + + def sync_walker(arg, dirname, fnames): + if _myname in fnames: + fn = join(dirname, _myname) + f = open(fn, 'rwb+') + try: + if f.read() == arg: + print "checkok", fn + else: + print "syncing", fn + f = open(fn, 'w') + f.write(arg) + finally: + f.close() + s = open(join(pypydir, 'tool', _myname), 'rb').read() + walk(pypydir, sync_walker, s) + +_myname = 'autopath.py' + +# set guaranteed attributes + +pypydir, this_dir = __dirinfo('pypy') + +if __name__ == '__main__': + __clone() Added: pypy/dist/pypy/tool/build/testproject/bin/buildserver.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/tool/build/testproject/bin/buildserver.py Mon Mar 19 13:23:44 2007 @@ -0,0 +1,51 @@ +#!/usr/bin/env python + +import autopath +import py +from py.execnet import PopenGateway +from pypy.tool.build import outputbuffer + +def compile(wc, compileinfo, buildpath): + code = """\ + import os + + import py + + # interpolating the path + wc = py.path.local(%r) + try: + os.chdir(str(wc)) + try: + output = py.process.cmdexec("gcc -o test test.c") + except Exception, e: + output = str(e) + upath = wc.join('test') + channel.send(output) + channel.send(str(upath)) + finally: + channel.close() + """ + gw = PopenGateway() + interpolated = py.code.Source(outputbuffer, + code % (str(wc), compileinfo, + str(buildpath))) + channel = gw.remote_exec(interpolated) + try: + upath = channel.receive() + output = channel.receive() + except channel.RemoteError, e: + print 'Remote exception:' + print str(e) + return (None, str(e)) + channel.close() + + return upath, output + +if __name__ == '__main__': + # main bit + from pypy.tool.build.bin import path + from pypy.tool.build.testproject import config + from pypy.tool.build.buildserver import main + + main(config, path, compile) + Added: pypy/dist/pypy/tool/build/testproject/bin/metaserver.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/tool/build/testproject/bin/metaserver.py Mon Mar 19 13:23:44 2007 @@ -0,0 +1,7 @@ +#!/usr/bin/env python + +from pypy.tool.build.testproject import config +from pypy.tool.build.metaserver import main + +main(config) + Added: pypy/dist/pypy/tool/build/testproject/bin/startcompile.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/tool/build/testproject/bin/startcompile.py Mon Mar 19 13:23:44 2007 @@ -0,0 +1,9 @@ +#!/usr/bin/env python + +import autopath +from pypy.tool.build.testproject import config +from pypy.tool.build.compile import main, getrequest +from py.execnet import SshGateway, PopenGateway + +request, foreground = getrequest(config) +main(config, request, foreground) Added: pypy/dist/pypy/tool/build/testproject/compileoption.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/tool/build/testproject/compileoption.py Mon Mar 19 13:23:44 2007 @@ -0,0 +1,9 @@ +import py +from pypy.config.config import OptionDescription, BoolOption, IntOption +from pypy.config.config import ChoiceOption, Config + +import sys +compile_optiondescription = OptionDescription('compile', '', [ + BoolOption('moo', 'moo while compiling', default=False), +]) + Added: pypy/dist/pypy/tool/build/testproject/config.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/tool/build/testproject/config.py Mon Mar 19 13:23:44 2007 @@ -0,0 +1,65 @@ +import py + +packageparent = py.magic.autopath().dirpath().dirpath().dirpath().dirpath().dirpath() + +# general settings, used by both server and client +server = 'localhost' +port = 23432 +testport = 43234 +path = [str(packageparent)] + +# options for webserver +webserver = '' +vhostroot = '' +webport = 8080 + +# configuration of options for client and startcompile +from pypy.config.config import Config + +# system config, on the client everything is set by scanning the system, when +# calling startcompile defaults are taken from the system, overrides are +# possible using cmdline args +from systemoption import system_optiondescription +system_config = Config(system_optiondescription) + +# compile option config, used by client to parse info, by startcompile for +# cmdline args, defaults are taken from the optiondescription +from compileoption import compile_optiondescription +compile_config = Config(compile_optiondescription) + +from tooloption import tool_optiondescription +tool_config = Config(tool_optiondescription) + +# settings for the server +projectname = 'testproject' +buildpath = packageparent.ensure('/pypy/tool/build/testproject/builds', + dir=True) +mailhost = 'localhost' +mailport = 25 +mailfrom = 'guido at codespeak.net' + +# this var is only used below +svnroot = 'http://codespeak.net/svn/pypy/dist/pypy/tool/build/testproject' + +# when considering a compile job, the checkers below will be called (with +# request as only arg), if one of them returns False the compilation will +# not be accepted +def check_svnroot(req): + if not req.svnurl.startswith(svnroot): + return False + return True + +client_checkers = [check_svnroot] + +# function to turn SVN paths into full URLs +def svnpath_to_url(p): + root = svnroot + if root.endswith('/'): + root = root[:-1] + return '%s/%s' % (root, p) + +# create an URL from a path, the URL is used in emails +def path_to_url(p): + return 'http://localhost/testproject/%s/data.zip' % ( + p.relto(py.magic.autopath().dirpath()),) + Added: pypy/dist/pypy/tool/build/testproject/dist/test/test.c ============================================================================== --- (empty file) +++ pypy/dist/pypy/tool/build/testproject/dist/test/test.c Mon Mar 19 13:23:44 2007 @@ -0,0 +1,6 @@ +#include + +int main(int argc, char *argv) { + printf("Hello, World!\n"); + return 0; +} Added: pypy/dist/pypy/tool/build/testproject/systemoption.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/tool/build/testproject/systemoption.py Mon Mar 19 13:23:44 2007 @@ -0,0 +1,13 @@ +import py +from pypy.config.config import OptionDescription, BoolOption, IntOption +from pypy.config.config import ChoiceOption, Config + +import sys +system_optiondescription = OptionDescription('system', '', [ + IntOption('maxint', 'maximum int value', default=sys.maxint), + ChoiceOption('byteorder', 'endianness, byte order (little/big)', + ['little', 'big'], default=sys.byteorder), + ChoiceOption('os', 'operating system', ['win32', 'linux2'], + default=sys.platform), +]) + Added: pypy/dist/pypy/tool/build/testproject/tooloption.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/tool/build/testproject/tooloption.py Mon Mar 19 13:23:44 2007 @@ -0,0 +1,13 @@ +import py +from pypy.config.config import StrOption, IntOption +from pypy.config.config import OptionDescription, Config + +import sys +tool_optiondescription = OptionDescription('tool', '', [ + IntOption('svnrev', 'Subversion revision', default='HEAD'), + StrOption('svnpath', 'Subversion path (relative to the project root)', + default='dist'), + StrOption('revrange', 'Revision range (max difference in revision between ' + 'requested build and result)', default=0), +]) + From afayolle at codespeak.net Mon Mar 19 13:37:34 2007 From: afayolle at codespeak.net (afayolle at codespeak.net) Date: Mon, 19 Mar 2007 13:37:34 +0100 (CET) Subject: [pypy-svn] r40766 - in pypy/dist/pypy/lib: . app_test Message-ID: <20070319123734.5D81E1006F@code0.codespeak.net> Author: afayolle Date: Mon Mar 19 13:37:24 2007 New Revision: 40766 Modified: pypy/dist/pypy/lib/aop.py pypy/dist/pypy/lib/app_test/test_aop.py Log: implementation of around call advice Modified: pypy/dist/pypy/lib/aop.py ============================================================================== --- pypy/dist/pypy/lib/aop.py (original) +++ pypy/dist/pypy/lib/aop.py Mon Mar 19 13:37:24 2007 @@ -97,14 +97,14 @@ def weave_at_execution(self, node, tjp): """weaving around a function execution moves the body of the function to an inner function called - __aoptarget__, and generate the following code: - return __aop__(id, __aoptarget__) + __aoptarget___, and generate the following code: + return __aop__(id, __aoptarget___) """ debug("WEAVE around execution") p = parser id = __aop__.register_joinpoint(self.woven_code, tjp) statement = node.code - newname = '__aoptarget_%s_%s__' % (node.name, id) + newname = '__aoptarget_%s__' % (id) newcode = p.ASTStmt([p.ASTFunction(node.decorators, newname, node.argnames, @@ -119,11 +119,21 @@ node.decorators = None node.code = newcode + debug('newnode: %s', node) return node def weave_at_call(self, node, tjp): - debug("WEAVE around execution") - raise NotImplementedError("abstract method") + debug("WEAVE around call") + p = parser + id = __aop__.register_joinpoint(self.woven_code, tjp) + newnode = make_aop_call_for_around_call(id, + node.node.varname, + node.args, + node.star_args, + node.dstar_args + ) + debug('newnode: %s', newnode) + return newnode def weave_at_initialization(self, node, tjp): raise NotImplementedError("abstract method") @@ -142,6 +152,7 @@ statement_list = node.code.nodes statement_list.insert(0, make_aop_call(id)) node.code.nodes = statement_list + debug('newnode: %s', node) return node @log_exc @@ -171,7 +182,7 @@ newnode = p.ASTSubscript(call, p.OP_APPLY, p.ASTConst(1)) - debug('%r', newnode) + debug('newnode: %s', newnode) return newnode def weave_at_initialization(self, node, tjp): @@ -192,6 +203,7 @@ statement = node.code tryfinally = parser.ASTTryFinally(statement, make_aop_call(id)) node.code = tryfinally + debug('newnode: %s', node) return node @log_exc @@ -222,6 +234,7 @@ def weave_at_static(self, node, tjp): debug("WEAVE introduce!!!") pass # XXX WRITEME + debug('newnode: %s', node) return node @@ -516,8 +529,10 @@ woven_code, (aspect, joinpoint, arguments) = self.joinpoints[id] joinpoint.func = target debug('target_locals = %s', target_locals) - if target_locals is not None: + if type(target_locals) is dict: joinpoint._arguments = (), dict([(n, target_locals[n]) for n in joinpoint._argnames or ()]) + elif type(target_locals) is tuple: + joinpoint._arguments = target_locals, {} if result is not _UndefinedResult: joinpoint._result = result args = (aspect, joinpoint,) + arguments @@ -548,7 +563,21 @@ # helper functions def make_aop_call(id, targetname=None, discard=True, resultcallfuncnode=None): """return an AST for a call to a woven function - id is the integer returned when the advice was stored in the registry""" + + id is the integer returned when the advice was stored in the + registry + + targetname is the name of the function that will be run when + jointpoint.proceed() is called by the advice + + if discard is True, the call is wrapped in an ASTDiscard node, + otherwise an ASTReturn node is used + + If resultcallfuncnode is not None, it is expected to be an + ASTCallFunc node which will be inserted as an argument in the aop + call, so that the function is called and its return value is + passed to the __aop__ instance. + """ p = parser arguments = [p.ASTConst(id),] if targetname is not None: @@ -573,6 +602,38 @@ None # *kwargs ) ) +def make_aop_call_for_around_call(id, targetname, target_args, target_starargs, target_dstar_args): + """return an AST for a call to a woven function + + id is the integer returned when the advice was stored in the + registry + + targetname is the name of the function that will be run when + jointpoint.proceed() is called by the advice + + target_args, target_starargs, target_dstar_args are the values of the original ASTCallFunc + """ + debug('make... %s %s %s %s %s', id, targetname, target_args, target_starargs, target_dstar_args) + p = parser + arguments = [p.ASTConst(id),] + if targetname is not None: + arguments.append(p.ASTName(targetname)) + else: + arguments.append(p.ASTName('None')) + + callargs = [p.ASTList(target_args)] + + + arguments.append(p.ASTTuple(callargs)) + + + debug('arguments: %s', arguments) + return p.ASTCallFunc(p.ASTName('__aop__'), + arguments, + None, # *args + None # *kwargs + ) + # debugging visitor class Debug(parser.ASTVisitor): Modified: pypy/dist/pypy/lib/app_test/test_aop.py ============================================================================== --- pypy/dist/pypy/lib/app_test/test_aop.py (original) +++ pypy/dist/pypy/lib/app_test/test_aop.py Mon Mar 19 13:37:24 2007 @@ -220,3 +220,34 @@ sample_aop_code.clean_module('aop_after_call') + def test_simple_aspect_around_call(self): + from aop import PointCut, Aspect, around + from app_test import sample_aop_code + __aop__._clear_all() + sample_aop_code.write_module('aop_around_call') + class AspectTest: + __metaclass__ = Aspect + def __init__(self): + self.executed_before = 0 + self.executed_after = 0 + @around(PointCut(func='bar').call()) + def advice_around_call(self, tjp): + print '>>>in', tjp.arguments() + self.executed_before += 1 + args, kwargs = tjp.arguments() + tjp.proceed(*args, **kwargs) + self.executed_after += 1 + self.result = tjp.result() + print '<< Author: guido Date: Mon Mar 19 13:50:33 2007 New Revision: 40767 Modified: pypy/dist/pypy/tool/build/testproject/ (props changed) pypy/dist/pypy/tool/build/testproject/__init__.py (props changed) pypy/dist/pypy/tool/build/testproject/bin/ (props changed) pypy/dist/pypy/tool/build/testproject/bin/autopath.py (props changed) pypy/dist/pypy/tool/build/testproject/bin/buildserver.py (contents, props changed) pypy/dist/pypy/tool/build/testproject/bin/metaserver.py (contents, props changed) pypy/dist/pypy/tool/build/testproject/bin/startcompile.py (props changed) pypy/dist/pypy/tool/build/testproject/compileoption.py (props changed) pypy/dist/pypy/tool/build/testproject/config.py (contents, props changed) pypy/dist/pypy/tool/build/testproject/systemoption.py (props changed) pypy/dist/pypy/tool/build/testproject/tooloption.py (props changed) Log: Test project is now working. Modified: pypy/dist/pypy/tool/build/testproject/bin/buildserver.py ============================================================================== --- pypy/dist/pypy/tool/build/testproject/bin/buildserver.py (original) +++ pypy/dist/pypy/tool/build/testproject/bin/buildserver.py Mon Mar 19 13:50:33 2007 @@ -8,27 +8,28 @@ def compile(wc, compileinfo, buildpath): code = """\ import os - import py - # interpolating the path - wc = py.path.local(%r) try: - os.chdir(str(wc)) + # interpolating the path + wc = py.path.local(%r) + os.chdir(str(wc.join('test'))) try: output = py.process.cmdexec("gcc -o test test.c") except Exception, e: output = str(e) - upath = wc.join('test') + channel.send(None) + else: + tempdir = py.test.ensuretemp('compile_testproject_result') + exe = wc.join('test/test') + exe.copy(tempdir) + channel.send(str(tempdir)) channel.send(output) - channel.send(str(upath)) finally: channel.close() """ gw = PopenGateway() - interpolated = py.code.Source(outputbuffer, - code % (str(wc), compileinfo, - str(buildpath))) + interpolated = py.code.Source(outputbuffer, code % (str(wc),)) channel = gw.remote_exec(interpolated) try: upath = channel.receive() Modified: pypy/dist/pypy/tool/build/testproject/bin/metaserver.py ============================================================================== --- pypy/dist/pypy/tool/build/testproject/bin/metaserver.py (original) +++ pypy/dist/pypy/tool/build/testproject/bin/metaserver.py Mon Mar 19 13:50:33 2007 @@ -3,5 +3,7 @@ from pypy.tool.build.testproject import config from pypy.tool.build.metaserver import main +print 'buildpath:', config.buildpath + main(config) Modified: pypy/dist/pypy/tool/build/testproject/config.py ============================================================================== --- pypy/dist/pypy/tool/build/testproject/config.py (original) +++ pypy/dist/pypy/tool/build/testproject/config.py Mon Mar 19 13:50:33 2007 @@ -63,3 +63,5 @@ return 'http://localhost/testproject/%s/data.zip' % ( p.relto(py.magic.autopath().dirpath()),) +configpath = 'pypy.tool.build.testproject.config' + From ac at codespeak.net Mon Mar 19 14:25:51 2007 From: ac at codespeak.net (ac at codespeak.net) Date: Mon, 19 Mar 2007 14:25:51 +0100 (CET) Subject: [pypy-svn] r40768 - in pypy/dist/pypy/translator: . goal test Message-ID: <20070319132551.2023710068@code0.codespeak.net> Author: ac Date: Mon Mar 19 14:25:49 2007 New Revision: 40768 Added: pypy/dist/pypy/translator/goal/targetportal.py (contents, props changed) Modified: pypy/dist/pypy/translator/driver.py pypy/dist/pypy/translator/goal/translate.py pypy/dist/pypy/translator/test/test_driver.py Log: (pedronis, arre) Add JIT-generation tasks to the driver and add a --jit option to translate.py See target_portal.py for a simple example. Modified: pypy/dist/pypy/translator/driver.py ============================================================================== --- pypy/dist/pypy/translator/driver.py (original) +++ pypy/dist/pypy/translator/driver.py Mon Mar 19 14:25:49 2007 @@ -1,6 +1,6 @@ import sys, os -from pypy.translator.translator import TranslationContext +from pypy.translator.translator import TranslationContext, graphof from pypy.translator.tool.taskengine import SimpleTaskEngine from pypy.translator.goal import query from pypy.annotation import model as annmodel @@ -78,7 +78,8 @@ class TranslationDriver(SimpleTaskEngine): - def __init__(self, setopts=None, default_goal=None, disable=[], + def __init__(self, setopts=None, default_goal=None, extra_goals=[], + disable=[], exe_name=None, extmod_name=None, config=None, overrides=None): SimpleTaskEngine.__init__(self) @@ -108,7 +109,7 @@ default_goal = None self.default_goal = default_goal - + self.extra_goals = extra_goals self.exposed = [] # expose tasks @@ -129,7 +130,9 @@ expose_task(task) else: task, postfix = parts - if task in ('rtype', 'backendopt', 'llinterpret'): + if task in ('rtype', 'backendopt', 'llinterpret', + 'prehannotatebackendopt', 'hintannotate', + 'timeshift'): if ts: if ts == postfix: expose_task(task, explicit_task) @@ -328,12 +331,75 @@ task_rtype_ootype = taskdef(task_rtype_ootype, ['annotate'], "ootyping") OOTYPE = 'rtype_ootype' + def task_prehannotatebackendopt_lltype(self): + from pypy.translator.backendopt.all import backend_optimizations + backend_optimizations(self.translator, + inline_threshold=0, + merge_if_blocks=False, + constfold=True, + remove_asserts=True) + # + task_prehannotatebackendopt_lltype = taskdef( + task_prehannotatebackendopt_lltype, + [RTYPE], + "Backendopt before Hint-annotate") + + def task_hintannotate_lltype(self): + from pypy.jit.hintannotator.annotator import HintAnnotator + from pypy.jit.hintannotator.model import OriginFlags + from pypy.jit.hintannotator.model import SomeLLAbstractConstant + + get_portal = self.extra['portal'] + PORTAL, POLICY = get_portal(self) + t = self.translator + self.portal_graph = graphof(t, PORTAL) + + hannotator = HintAnnotator(base_translator=t, policy=POLICY) + hs = hannotator.build_types(self.portal_graph, + [SomeLLAbstractConstant(v.concretetype, + {OriginFlags(): True}) + for v in self.portal_graph.getargs()]) + count = hannotator.bookkeeper.nonstubgraphcount + self.log.info('Hint-annotated %d graphs (plus %d stubs).' % ( + count, len(hannotator.translator.graphs) - count)) + n = len(list(hannotator.translator.graphs[0].iterblocks())) + self.log.info("portal has %d blocks" % n) + self.hannotator = hannotator + # + task_hintannotate_lltype = taskdef(task_hintannotate_lltype, + ['prehannotatebackendopt_lltype'], + "Hint-annotate") + + def task_timeshift_lltype(self): + from pypy.jit.timeshifter.hrtyper import HintRTyper + from pypy.jit.codegen import detect_cpu + cpu = detect_cpu.autodetect() + if cpu == 'i386': + from pypy.jit.codegen.i386.rgenop import RI386GenOp as RGenOp + RGenOp.MC_SIZE = 32 * 1024 * 1024 + elif cpu == 'ppc': + from pypy.jit.codegen.ppc.rgenop import RPPCGenOp as RGenOp + else: + raise Exception('Unsuported cpu %r'%cpu) + + ha = self.hannotator + t = self.translator + # make the timeshifted graphs + hrtyper = HintRTyper(ha, t.rtyper, RGenOp) + hrtyper.specialize(origportalgraph=self.portal_graph, view=False) + # + task_timeshift_lltype = taskdef(task_timeshift_lltype, + ["hintannotate_lltype"], + "Timeshift") + def task_backendopt_lltype(self): from pypy.translator.backendopt.all import backend_optimizations backend_optimizations(self.translator) # task_backendopt_lltype = taskdef(task_backendopt_lltype, - [RTYPE], "lltype back-end optimisations") + [RTYPE, + '??timeshift_lltype'], + "lltype back-end optimisations") BACKENDOPT = 'backendopt_lltype' def task_backendopt_ootype(self): @@ -630,18 +696,20 @@ return elif isinstance(goals, str): goals = [goals] + goals.extend(self.extra_goals) goals = self.backend_select_goals(goals) return self._execute(goals, task_skip = self._maybe_skip()) def from_targetspec(targetspec_dic, config=None, args=None, empty_translator=None, disable=[], - default_goal=None): + default_goal=None, + extra_goals=[]): if args is None: args = [] driver = TranslationDriver(config=config, default_goal=default_goal, - disable=disable) + extra_goals=extra_goals, disable=disable) # patch some attributes of the os module to make sure they # have the same value on every platform. backend, ts = driver.get_backend_and_type_system() Added: pypy/dist/pypy/translator/goal/targetportal.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/goal/targetportal.py Mon Mar 19 14:25:49 2007 @@ -0,0 +1,23 @@ +from pypy.rlib.objectmodel import hint + +def compute(x, y): + hint(x, concrete=True) + r = x + y + return r + +# __________ Entry point __________ + +def entry_point(argv): + if len(argv) <3: + return -2 + r = compute(int(argv[1]), int(argv[2])) + print r + return 0 + +# _____ Define and setup target ___ + +def target(*args): + return entry_point, None + +def portal(drv): + return compute, None Modified: pypy/dist/pypy/translator/goal/translate.py ============================================================================== --- pypy/dist/pypy/translator/goal/translate.py (original) +++ pypy/dist/pypy/translator/goal/translate.py Mon Mar 19 14:25:49 2007 @@ -17,21 +17,30 @@ GOALS= [ ("annotate", "do type inference", "-a --annotate", ""), ("rtype", "do rtyping", "-t --rtype", ""), + ("prehannotatebackendopt", "backend optimize before hint-annotating", + "--prehannotatebackendopt", ""), + ("hintannotate", "hint-annotate", "--hintannotate", ""), + ("timeshift", "timeshift (jit generation)", "--timeshift", ""), ("backendopt", "do backend optimizations", "--backendopt", ""), ("source", "create source", "-s --source", ""), ("compile", "compile", "-c --compile", " (default goal)"), + ("?jit", "generate JIT", "--jit", ""), ("run", "run the resulting binary", "--run", ""), ("llinterpret", "interpret the rtyped flow graphs", "--llinterpret", ""), ] - def goal_options(): result = [] for name, doc, cmdline, extra in GOALS: + optional = False + if name.startswith('?'): + optional = True + name = name[1:] yesdoc = doc[0].upper()+doc[1:]+extra result.append(BoolOption(name, yesdoc, default=False, cmdline=cmdline, negation=False)) - result.append(BoolOption("no_%s" % name, "Don't "+doc, default=False, - cmdline="--no-"+name, negation=False)) + if not optional: + result.append(BoolOption("no_%s" % name, "Don't "+doc, default=False, + cmdline="--no-"+name, negation=False)) return result translate_optiondescr = OptionDescription("translate", "XXX", [ @@ -116,6 +125,8 @@ # set goals and skipped_goals reset = False for name, _, _, _ in GOALS: + if name.startswith('?'): + continue if getattr(translateconfig.goal_options, name): if name not in translateconfig.goals: translateconfig.goals.append(name) @@ -250,12 +261,15 @@ pdb_plus_show.start(tb, server_setup, graphic=not translateconfig.text) log_config(translateconfig, "translate.py configuration") - + extra_goals = [] + if translateconfig.goal_options.jit: + extra_goals.append('timeshift') try: drv = driver.TranslationDriver.from_targetspec(targetspec_dic, config, args, empty_translator=t, disable=translateconfig.skipped_goals, - default_goal='compile') + default_goal='compile', + extra_goals=extra_goals) log_config(config.translation, "translation configuration") pdb_plus_show.expose({'drv': drv, 'prof': prof}) 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 Mon Mar 19 14:25:49 2007 @@ -12,9 +12,10 @@ def test_ctr(): td = TranslationDriver() - - assert cmpl(td.exposed, - ['annotate', 'backendopt', 'llinterpret', 'rtype', 'source', 'compile', 'run']) + expected = ['annotate', 'backendopt', 'llinterpret', 'rtype', 'source', + 'compile', 'run', 'prehannotatebackendopt', 'hintannotate', + 'timeshift'] + assert cmpl(td.exposed, expected) assert td.backend_select_goals(['compile_c']) == ['compile_c'] assert td.backend_select_goals(['compile']) == ['compile_c'] @@ -34,7 +35,7 @@ assert td.backend_select_goals(['backendopt_lltype']) == [ 'backendopt_lltype'] - assert cmpl(td.exposed, ['annotate', 'backendopt_lltype', + expected = ['annotate', 'backendopt_lltype', 'backendopt_ootype', 'llinterpret_lltype', 'rtype_ootype', 'rtype_lltype', 'source_cl', 'source_js', @@ -42,7 +43,10 @@ 'compile_cl', 'compile_cli', 'compile_c', 'compile_squeak', 'compile_llvm', 'compile_js', 'run_cl', 'run_squeak', 'run_llvm', 'run_c', 'run_js', 'run_cli', - 'compile_jvm', 'source_jvm', 'run_jvm']) + 'compile_jvm', 'source_jvm', 'run_jvm', + 'prehannotatebackendopt_lltype', 'hintannotate_lltype', + 'timeshift_lltype'] + assert cmpl(td.exposed, expected) td = TranslationDriver({'backend': None, 'type_system': 'lltype'}) @@ -55,7 +59,7 @@ 'backendopt_lltype'] expected = ['annotate', 'backendopt', 'llinterpret', 'rtype', 'source_c', - 'source_llvm', 'compile_c', 'compile_llvm', 'run_llvm', - 'run_c'] + 'source_llvm', 'compile_c', 'compile_llvm', 'run_llvm', + 'run_c', 'prehannotatebackendopt', 'hintannotate', 'timeshift'] assert cmpl(td.exposed, expected) From pedronis at codespeak.net Mon Mar 19 14:41:42 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Mon, 19 Mar 2007 14:41:42 +0100 (CET) Subject: [pypy-svn] r40769 - pypy/dist/pypy/translator/goal Message-ID: <20070319134142.A710A1006F@code0.codespeak.net> Author: pedronis Date: Mon Mar 19 14:41:39 2007 New Revision: 40769 Modified: pypy/dist/pypy/translator/goal/targetportal.py Log: add usage of we_are_jitted and stopping at info from the hint policy to the example. Modified: pypy/dist/pypy/translator/goal/targetportal.py ============================================================================== --- pypy/dist/pypy/translator/goal/targetportal.py (original) +++ pypy/dist/pypy/translator/goal/targetportal.py Mon Mar 19 14:41:39 2007 @@ -1,6 +1,11 @@ -from pypy.rlib.objectmodel import hint +from pypy.rlib.objectmodel import hint, we_are_jitted + +def jitted(): + print "jitted" def compute(x, y): + if we_are_jitted(): + jitted() hint(x, concrete=True) r = x + y return r @@ -20,4 +25,16 @@ return entry_point, None def portal(drv): - return compute, None + from pypy.jit.hintannotator.annotator import HintAnnotatorPolicy + class MyHintAnnotatorPolicy(HintAnnotatorPolicy): + + def __init__(self): + HintAnnotatorPolicy.__init__(self, oopspec=True, + novirtualcontainer=True) + + def look_inside_graph(self, graph): + if graph.func is jitted: + return False + return True + + return compute, MyHintAnnotatorPolicy() From arigo at codespeak.net Mon Mar 19 14:45:37 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 19 Mar 2007 14:45:37 +0100 (CET) Subject: [pypy-svn] r40770 - in pypy/dist/pypy/jit/timeshifter: . test Message-ID: <20070319134537.DF52910074@code0.codespeak.net> Author: arigo Date: Mon Mar 19 14:45:31 2007 New Revision: 40770 Modified: pypy/dist/pypy/jit/timeshifter/test/test_timeshift.py pypy/dist/pypy/jit/timeshifter/transform.py Log: Support for red switches, handled by turning them into a binary search tree. Modified: pypy/dist/pypy/jit/timeshifter/test/test_timeshift.py ============================================================================== --- pypy/dist/pypy/jit/timeshifter/test/test_timeshift.py (original) +++ pypy/dist/pypy/jit/timeshifter/test/test_timeshift.py Mon Mar 19 14:45:31 2007 @@ -1592,3 +1592,48 @@ res = self.timeshift(f, [42], policy=P_NOVIRTUAL) assert res == -7 + + def test_switch(self): + def g(n): + if n == 0: + return 12 + elif n == 1: + return 34 + elif n == 3: + return 56 + elif n == 7: + return 78 + else: + return 90 + def f(n, m): + x = g(n) # gives a red switch + y = g(hint(m, concrete=True)) # gives a green switch + return x - y + + res = self.timeshift(f, [7, 2], backendoptimize=True) + assert res == 78 - 90 + res = self.timeshift(f, [8, 1], backendoptimize=True) + assert res == 90 - 34 + + def test_switch_char(self): + def g(n): + n = chr(n) + if n == '\x00': + return 12 + elif n == '\x01': + return 34 + elif n == '\x02': + return 56 + elif n == '\x03': + return 78 + else: + return 90 + def f(n, m): + x = g(n) # gives a red switch + y = g(hint(m, concrete=True)) # gives a green switch + return x - y + + res = self.timeshift(f, [3, 0], backendoptimize=True) + assert res == 78 - 12 + res = self.timeshift(f, [2, 4], backendoptimize=True) + assert res == 56 - 90 Modified: pypy/dist/pypy/jit/timeshifter/transform.py ============================================================================== --- pypy/dist/pypy/jit/timeshifter/transform.py (original) +++ pypy/dist/pypy/jit/timeshifter/transform.py Mon Mar 19 14:45:31 2007 @@ -1,3 +1,4 @@ +import sys from pypy.objspace.flow.model import Variable, Constant, Block, Link from pypy.objspace.flow.model import SpaceOperation, mkentrymap from pypy.annotation import model as annmodel @@ -267,12 +268,19 @@ def insert_splits(self): hannotator = self.hannotator - for block in self.graph.iterblocks(): - if block.exitswitch is not None: - assert isinstance(block.exitswitch, Variable) - hs_switch = hannotator.binding(block.exitswitch) - if not hs_switch.is_green(): - self.insert_split_handling(block) + retry = True + while retry: + retry = False + for block in list(self.graph.iterblocks()): + if block.exitswitch is not None: + assert isinstance(block.exitswitch, Variable) + hs_switch = hannotator.binding(block.exitswitch) + if not hs_switch.is_green(): + if block.exitswitch.concretetype is lltype.Bool: + self.insert_split_handling(block) + else: + self.insert_switch_handling(block) + retry = True def trace_back_bool_var(self, block, v): """Return the (opname, arguments) that created the exitswitch of @@ -326,6 +334,117 @@ resulttype = lltype.Bool) block.exitswitch = v_flag + def insert_switch_handling(self, block): + v_redswitch = block.exitswitch + T = v_redswitch.concretetype + range_start = -sys.maxint-1 + range_stop = sys.maxint+1 + if T is not lltype.Signed: + if T is lltype.Char: + opcast = 'cast_char_to_int' + range_start = 0 + range_stop = 256 + elif T is lltype.UniChar: + opcast = 'cast_unichar_to_int' + range_start = 0 + elif T is lltype.Unsigned: + opcast = 'cast_uint_to_int' + else: + raise AssertionError(T) + v_redswitch = self.genop(block, opcast, [v_redswitch], + resulttype=lltype.Signed, red=True) + block.exitswitch = v_redswitch + # for now, we always turn the switch back into a chain of tests + # that perform a binary search + blockset = {block: True} # reachable from outside + cases = {} + defaultlink = None + for link in block.exits: + if link.exitcase == 'default': + defaultlink = link + blockset[link.target] = False # not reachable from outside + else: + assert lltype.typeOf(link.exitcase) == T + intval = lltype.cast_primitive(lltype.Signed, link.exitcase) + cases[intval] = link + link.exitcase = None + link.llexitcase = None + self.insert_integer_search(block, cases, defaultlink, blockset, + range_start, range_stop) + SSA_to_SSI(blockset, self.hannotator) + + def insert_integer_search(self, block, cases, defaultlink, blockset, + range_start, range_stop): + # fix the exit of the 'block' to check for the given remaining + # 'cases', knowing that if we get there then the value must + # be contained in range(range_start, range_stop). + if not cases: + assert defaultlink is not None + block.exitswitch = None + block.recloseblock(Link(defaultlink.args, defaultlink.target)) + elif len(cases) == 1 and (defaultlink is None or + range_start == range_stop-1): + block.exitswitch = None + block.recloseblock(cases.values()[0]) + else: + intvalues = cases.keys() + intvalues.sort() + if len(intvalues) <= 3: + # not much point in being clever with no more than 3 cases + intval = intvalues[-1] + remainingcases = cases.copy() + link = remainingcases.pop(intval) + c_intval = inputconst(lltype.Signed, intval) + v = self.genop(block, 'int_eq', [block.exitswitch, c_intval], + resulttype=lltype.Bool, red=True) + link.exitcase = True + link.llexitcase = True + falseblock = Block([]) + falseblock.exitswitch = block.exitswitch + blockset[falseblock] = False + falselink = Link([], falseblock) + falselink.exitcase = False + falselink.llexitcase = False + block.exitswitch = v + block.recloseblock(falselink, link) + if defaultlink is None or intval == range_stop-1: + range_stop = intval + self.insert_integer_search(falseblock, remainingcases, + defaultlink, blockset, + range_start, range_stop) + else: + intval = intvalues[len(intvalues) // 2] + c_intval = inputconst(lltype.Signed, intval) + v = self.genop(block, 'int_ge', [block.exitswitch, c_intval], + resulttype=lltype.Bool, red=True) + falseblock = Block([]) + falseblock.exitswitch = block.exitswitch + trueblock = Block([]) + trueblock.exitswitch = block.exitswitch + blockset[falseblock] = False + blockset[trueblock] = False + falselink = Link([], falseblock) + falselink.exitcase = False + falselink.llexitcase = False + truelink = Link([], trueblock) + truelink.exitcase = True + truelink.llexitcase = True + block.exitswitch = v + block.recloseblock(falselink, truelink) + falsecases = {} + truecases = {} + for intval1, link1 in cases.items(): + if intval1 < intval: + falsecases[intval1] = link1 + else: + truecases[intval1] = link1 + self.insert_integer_search(falseblock, falsecases, + defaultlink, blockset, + range_start, intval) + self.insert_integer_search(trueblock, truecases, + defaultlink, blockset, + intval, range_stop) + def get_resume_point_link(self, block): try: return self.resumepoints[block] From adim at codespeak.net Mon Mar 19 14:47:47 2007 From: adim at codespeak.net (adim at codespeak.net) Date: Mon, 19 Mar 2007 14:47:47 +0100 (CET) Subject: [pypy-svn] r40771 - in pypy/dist/pypy: interpreter/pyparser module/recparser Message-ID: <20070319134747.86CA610072@code0.codespeak.net> Author: adim Date: Mon Mar 19 14:47:40 2007 New Revision: 40771 Modified: pypy/dist/pypy/interpreter/pyparser/pythonparse.py pypy/dist/pypy/module/recparser/pyparser.py Log: modified recparser's unwrap_syntax_tree in order to make modified-2.4.1/test/test_parser.py pass again Modified: pypy/dist/pypy/interpreter/pyparser/pythonparse.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/pythonparse.py (original) +++ pypy/dist/pypy/interpreter/pyparser/pythonparse.py Mon Mar 19 14:47:40 2007 @@ -94,17 +94,15 @@ def __init__(self): # , predefined_symbols=None): grammar.Parser.__init__(self) pytoken.setup_tokens(self) + # remember how many tokens were loaded + self._basetokens_count = self._sym_count # if predefined_symbols: # self.load_symbols(predefined_symbols) self.keywords = [] - - # XXX (adim): this is trunk's keyword management - # self.with_grammar = None - # self.keywords = dict.fromkeys(grammar_builder.keywords) - # # Only when with_statement is enabled - # self.keywords.pop('with', None) - # self.keywords.pop('as', None) - + + def is_base_token(self, tokvalue): + return tokvalue < 0 or tokvalue >= self._basetokens_count + def parse_source(self, textsrc, mode, builder, flags=0): """Parse a python source according to goal""" goal = self.targets[mode] @@ -126,7 +124,6 @@ def parse_lines(self, lines, goal, builder, flags=0): - # XXX (adim): this is trunk's keyword management # builder.keywords = self.keywords.copy() # if flags & CO_FUTURE_WITH_STATEMENT: # builder.enable_with() Modified: pypy/dist/pypy/module/recparser/pyparser.py ============================================================================== --- pypy/dist/pypy/module/recparser/pyparser.py (original) +++ pypy/dist/pypy/module/recparser/pyparser.py Mon Mar 19 14:47:40 2007 @@ -183,11 +183,9 @@ def unwrap_syntax_tree( space, w_sequence ): items = space.unpackiterable( w_sequence ) + parser = space.default_compiler.parser nodetype = space.int_w( items[0] ) - is_syntax = True - if nodetype>=0 and nodetype < pytoken.N_TOKENS: - is_syntax = False - if is_syntax: + if parser.is_base_token(nodetype): nodes = [] for w_node in items[1:]: node = unwrap_syntax_tree( space, w_node ) From antocuni at codespeak.net Mon Mar 19 14:57:27 2007 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Mon, 19 Mar 2007 14:57:27 +0100 (CET) Subject: [pypy-svn] r40772 - in pypy/dist/pypy: rpython translator/oosupport translator/oosupport/test Message-ID: <20070319135727.178AE10072@code0.codespeak.net> Author: antocuni Date: Mon Mar 19 14:57:24 2007 New Revision: 40772 Added: pypy/dist/pypy/translator/oosupport/test/ pypy/dist/pypy/translator/oosupport/test/__init__.py (contents, props changed) pypy/dist/pypy/translator/oosupport/test/test_treebuilder.py (contents, props changed) pypy/dist/pypy/translator/oosupport/treebuilder.py (contents, props changed) Modified: pypy/dist/pypy/rpython/llinterp.py Log: Add a general way to transform SSI graphs in stack-based machine friendly form. Operations now accept three kinds of arguments: - variables - constants - sub-operation (recursively) The algorithm could be improved, because at the moment it simply ignores operations involving mutable objects instead of checking if they are effectively mutated. Modified: pypy/dist/pypy/rpython/llinterp.py ============================================================================== --- pypy/dist/pypy/rpython/llinterp.py (original) +++ pypy/dist/pypy/rpython/llinterp.py Mon Mar 19 14:57:24 2007 @@ -226,6 +226,16 @@ assert False, "type error: %r val from %r var/const" % (lltype.typeOf(val), varorconst.concretetype) return val + def getval_or_subop(self, varorsubop): + from pypy.translator.oosupport.treebuilder import SubOperation + if isinstance(varorsubop, SubOperation): + self.eval_operation(varorsubop.op) + resultval = self.getval(varorsubop.op.result) + del self.bindings[varorsubop.op.result] # XXX hack + return resultval + else: + return self.getval(varorsubop) + # _______________________________________________________ # other helpers def getoperationhandler(self, opname): @@ -365,7 +375,7 @@ if getattr(ophandler, 'specialform', False): retval = ophandler(*operation.args) else: - vals = [self.getval(x) for x in operation.args] + vals = [self.getval_or_subop(x) for x in operation.args] if getattr(ophandler, 'need_result_type', False): vals.insert(0, operation.result.concretetype) try: Added: pypy/dist/pypy/translator/oosupport/test/__init__.py ============================================================================== Added: pypy/dist/pypy/translator/oosupport/test/test_treebuilder.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/oosupport/test/test_treebuilder.py Mon Mar 19 14:57:24 2007 @@ -0,0 +1,89 @@ +from pypy.rpython.llinterp import LLInterpreter +from pypy.translator.translator import TranslationContext, graphof +from pypy.translator.oosupport.treebuilder import build_trees, SubOperation +from pypy.conftest import option +from pypy.rpython.test.test_rlist import BaseTestRlist +from pypy.rpython.test.tool import BaseRtypingTest, OORtypeMixin +from pypy.rpython.test.test_llinterp import get_interpreter + +def translate(func, argtypes): + t = TranslationContext() + t.buildannotator().build_types(func, argtypes) + t.buildrtyper(type_system='ootype').specialize() + return t + +def check_trees(func, argtypes): + t = translate(func, argtypes) + if option.view: + t.view() + graph = graphof(t, func) + build_trees(graph) + if option.view: + t.view() + interp = LLInterpreter(t.rtyper) + def eval_func(*args): + return interp.eval_graph(graph, args) + return graph, eval_func + +def test_simple(): + def fn(x): + x = x+1 + x = x+1 + return x + graph, eval_func = check_trees(fn, [int]) + block = graph.startblock + assert len(block.operations) == 1 + assert isinstance(block.operations[0].args[0], SubOperation) + assert eval_func(0) == 2 + +def test_function_call(): + def g(x): + return x+1 + def fn(x): + a = g(x) + b = g(x+1) + return a + b + graph, eval_func = check_trees(fn, [int]) + block = graph.startblock + assert len(block.operations) == 1 + assert isinstance(block.operations[0].args[0], SubOperation) + assert isinstance(block.operations[0].args[1], SubOperation) + assert eval_func(1) == 5 + +def test_count_exit_links(): + def g(x): + pass + def fn(x): + res = x+1 + g(res) + return res + graph, eval_func = check_trees(fn, [int]) + block = graph.startblock + assert len(block.operations) == 2 + v0 = block.operations[0].result + assert block.exits[0].args == [v0] + assert eval_func(0) == 1 + +def test_mutable_values(): + def fn(): + lst = [] + length = len(lst) + lst.append(42) + return length + 1 + graph, eval_func = check_trees(fn, []) + block = graph.startblock + assert not isinstance(block.operations[-1].args[0], SubOperation) + assert eval_func() == 1 + +class BuildTreeRtypingTest(BaseRtypingTest, OORtypeMixin): + def interpret(self, fn, args): + interp, graph = get_interpreter(fn, args, view=False, viewbefore=False, type_system=self.type_system) + if option.view: + interp.typer.annotator.translator.view() + build_trees(graph) + if option.view: + interp.typer.annotator.translator.view() + return interp.eval_graph(graph, args) + +class TestBuildTreeList(BuildTreeRtypingTest, BaseTestRlist): + pass Added: pypy/dist/pypy/translator/oosupport/treebuilder.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/oosupport/treebuilder.py Mon Mar 19 14:57:24 2007 @@ -0,0 +1,59 @@ +from pypy.rpython.ootypesystem import ootype +from pypy.objspace.flow import model as flowmodel + +class SubOperation(object): + def __init__(self, op): + self.op = op + self.concretetype = op.result.concretetype + + def __repr__(self): + return "[%s(%s)]" % (self.op.opname, + ", ".join(map(repr, self.op.args))) + +def is_mutable(TYPE): + return isinstance(TYPE, (ootype.Instance, + ootype.Record, + ootype.List, + ootype.Dict, + ootype.StringBuilder.__class__, + ootype.CustomDict, + ootype.DictItemsIterator)) + +def can_be_inlined(op): + for v in op.args: + if isinstance(v, flowmodel.Variable) and is_mutable(v.concretetype): + return False + return True + +def build_op_map(block): + var_count = {} + var_to_op = {} + def inc(v): + if isinstance(v, flowmodel.Variable): + var_count[v] = var_count.get(v, 0) + 1 + + for i, op in enumerate(block.operations): + var_to_op[op.result] = i, op + for v in op.args: + inc(v) + for link in block.exits: + for v in link.args: + inc(v) + return var_count, var_to_op + +def build_trees_for_block(block): + var_count, var_to_op = build_op_map(block) + for op in block.operations: + for i, v in enumerate(op.args): + if var_count.get(v, None) == 1 and v not in block.inputargs: # "inline" the operation + sub_i, sub_op = var_to_op[v] + if can_be_inlined(sub_op): + op.args[i] = SubOperation(sub_op) + block.operations[sub_i] = None + block.operations = [op for op in block.operations if op is not None] + +def build_trees(graph): + if not getattr(graph, 'tree_built', False): + for block in graph.iterblocks(): + build_trees_for_block(block) + graph.tree_built = True From guido at codespeak.net Mon Mar 19 15:12:00 2007 From: guido at codespeak.net (guido at codespeak.net) Date: Mon, 19 Mar 2007 15:12:00 +0100 (CET) Subject: [pypy-svn] r40773 - in pypy/dist/pypy: bin tool/build tool/build/bin tool/build/test tool/build/testproject tool/build/web/templates tool/build/web/test Message-ID: <20070319141200.B33A21006E@code0.codespeak.net> Author: guido Date: Mon Mar 19 15:11:56 2007 New Revision: 40773 Added: pypy/dist/pypy/tool/build/compile.py pypy/dist/pypy/tool/build/test/test_compile.py Modified: pypy/dist/pypy/bin/startcompile.py pypy/dist/pypy/tool/build/bin/metaserver pypy/dist/pypy/tool/build/config.py pypy/dist/pypy/tool/build/metaserver.py pypy/dist/pypy/tool/build/systemoption.py pypy/dist/pypy/tool/build/test/test_pypybuilder.py pypy/dist/pypy/tool/build/testproject/compileoption.py pypy/dist/pypy/tool/build/web/templates/buildersinfo.html pypy/dist/pypy/tool/build/web/test/test_app.py Log: Added --foreground switch to startcompile.py. In order to support this, and to be able to test it a little bit, I did some refactorings (like moving most of the startcompile to a seperate file and splitting it up a bit, moving some vars to config.py). Also fixed the busy_on links in buildersinfo.html, fixed a test in test_app.py, and did several small cleanups to more easily allow re-use of the project (issues that popped up while adding a test project) and fixed some issues in the metaserver queue handling. Modified: pypy/dist/pypy/bin/startcompile.py ============================================================================== --- pypy/dist/pypy/bin/startcompile.py (original) +++ pypy/dist/pypy/bin/startcompile.py Mon Mar 19 15:11:56 2007 @@ -1,95 +1,9 @@ #!/usr/bin/env python import autopath -from pypy.tool.build.bin import path -import sys -import random from pypy.tool.build import config -from pypy.tool.build import build -from pypy.tool.build.tooloption import tool_config - -def parse_options(config, tool_config): - # merge system + compile options into one optionparser - from py.compat.optparse import OptionParser, OptionGroup - from pypy.config.config import to_optparse - - optparser = to_optparse(config.system_config) - to_optparse(config.compile_config, parser=optparser) - to_optparse(tool_config, parser=optparser) - - (options, args) = optparser.parse_args() - - if not args or len(args) != 1: - optparser.error('please provide an email address') - - return optparser, options, args - -initcode = """ - import sys - sys.path += %r - - try: - from pypy.tool.build import metaserver_instance - from pypy.tool.build import build - ret = metaserver_instance.compile(%r) - 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 -""" -def init(gw, request, path, port=12321): - from pypy.tool.build import execnetconference - - conference = execnetconference.conference(gw, port, False) - channel = conference.remote_exec(initcode % (path, request)) - return channel - -if __name__ == '__main__': - from py.execnet import SshGateway, PopenGateway - from pypy.config.config import make_dict - - optparser, options, args = parse_options(config, tool_config) - - sysinfo = make_dict(config.system_config) - compileinfo = make_dict(config.compile_config) - - buildrequest = build.BuildRequest(args[0], sysinfo, compileinfo, - config.svnpath_to_url( - tool_config.svnpath), - tool_config.svnrev, - tool_config.revrange) - - print 'going to start compile job with info:' - for k, v in sysinfo.items(): - print '%s: %r' % (k, v) - print - print config.compile_config - - if config.server in ['localhost', '127.0.0.1']: - gw = PopenGateway() - else: - gw = SshGateway(config.server) - - channel = init(gw, buildrequest, config.path, port=config.port) - data = channel.receive() - if type(data) == str: - print data - for line in channel: - print line - elif type(data) != dict: - raise ValueError, 'invalid data returned: %r' % (data,) - else: - if data['path']: - print ('a suitable result is already available, you can find it ' - 'at "%s" on %s' % (data['path'], config.server)) - else: - print data['message'] - print 'you will be mailed once it\'s ready' - channel.close() - gw.exit() +from pypy.tool.build.compile import main, getrequest +from py.execnet import SshGateway, PopenGateway +request, foreground = getrequest(config) +main(config, request, foreground) Modified: pypy/dist/pypy/tool/build/bin/metaserver ============================================================================== --- pypy/dist/pypy/tool/build/bin/metaserver (original) +++ pypy/dist/pypy/tool/build/bin/metaserver Mon Mar 19 15:11:56 2007 @@ -3,22 +3,8 @@ import autopath import path from pypy.tool.build import config +from pypy.tool.build.metaserver import main if __name__ == '__main__': - from py.execnet import SshGateway, PopenGateway - from pypy.tool.build.metaserver import init - - if config.server in ['localhost', '127.0.0.1']: - gw = PopenGateway() - else: - gw = SshGateway(config.server) - channel = init(gw, config) - - try: - while 1: - data = channel.receive() - print data - finally: - channel.close() - gw.exit() + main(config) Added: pypy/dist/pypy/tool/build/compile.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/tool/build/compile.py Mon Mar 19 15:11:56 2007 @@ -0,0 +1,204 @@ +import sys +import random +import time +import py +from pypy.tool.build.bin import path +from pypy.tool.build import config +from pypy.tool.build import build +from pypy.tool.build import execnetconference + +POLLTIME = 5 # for --foreground polling + +def get_gateway(config): + if config.server in ['localhost', '127.0.0.1']: + gw = py.execnet.PopenGateway() + else: + gw = py.execnet.SshGateway(config.server) + return gw + +def parse_options(config, args=None): + # merge system + compile options into one optionparser + from py.compat.optparse import OptionParser, OptionGroup + from pypy.config.config import to_optparse + + optparser = to_optparse(config.system_config) + to_optparse(config.compile_config, parser=optparser) + to_optparse(config.tool_config, parser=optparser) + optparser.add_option('', '--foreground', action="store_true", + dest='foreground', default=False, + help='block until build is available and download it ' + 'immediately') + + (options, args) = optparser.parse_args() + + if not args or len(args) != 1: + optparser.error('please provide an email address') + + return optparser, options, args + +initcode = """ + import sys + import time + sys.path += %r + bufsize = 1024 + + try: + try: + from pypy.tool.build import metaserver_instance + from pypy.tool.build import build + ret = metaserver_instance.compile(%r) + channel.send(ret) + except Exception, e: + channel.send(str(e)) + finally: + channel.close() +""" +def init(gw, request, path, port): + conference = execnetconference.conference(gw, port, False) + channel = conference.remote_exec(initcode % (path, request)) + return channel + +checkcode = """ + import sys + sys.path += %r + bufsize = 1024 + try: + reqid = channel.receive() + from pypy.tool.build import metaserver_instance + from pypy.tool.build import build + for tb in metaserver_instance._done: + if tb.request.id() == reqid: + channel.send({'error': str(tb.error)}) + else: + channel.send(None) + finally: + channel.close() +""" +def check_server(config, id, path, port): + gw = get_gateway(config) + try: + conference = execnetconference.conference(gw, port, False) + channel = conference.remote_exec(checkcode % (path,)) + try: + channel.send(id) + ret = channel.receive() + finally: + channel.close() + finally: + gw.exit() + return ret + +zipcode = """ + import sys + sys.path += %r + bufsize = 1024 + try: + reqid = channel.receive() + from pypy.tool.build import metaserver_instance + from pypy.tool.build import build + for tb in metaserver_instance._done: + if tb.request.id() == reqid: + fp = tb.zipfile.open('rb') + try: + while 1: + data = fp.read(bufsize) + channel.send(data) + if len(data) < bufsize: + channel.send(None) + break + finally: + fp.close() + finally: + channel.close() +""" +def savezip(config, id, path, port, savepath): + gw = get_gateway(config) + savepath = py.path.local(savepath) + try: + conference = execnetconference.conference(gw, port, False) + channel = conference.remote_exec(zipcode % (path,)) + try: + channel.send(id) + fp = savepath.open('wb') + try: + while 1: + data = channel.receive() + if data is None: + break + fp.write(data) + finally: + fp.close() + finally: + channel.close() + finally: + gw.exit() + +def getrequest(config, args=None): + from pypy.config.config import make_dict + + optparser, options, args = parse_options(config, args=args) + + sysinfo = make_dict(config.system_config) + compileinfo = make_dict(config.compile_config) + + buildrequest = build.BuildRequest(args[0], sysinfo, compileinfo, + config.svnpath_to_url( + config.tool_config.svnpath), + config.tool_config.svnrev, + config.tool_config.revrange) + return buildrequest, options.foreground + +def main(config, request, foreground=False): + gateway = get_gateway(config) + + inprogress = False + try: + print 'going to start compile job with info:' + for k, v in request.sysinfo.items(): + print '%s: %r' % (k, v) + print + print config.compile_config + + channel = init(gateway, request, config.path, port=config.port) + try: + data = channel.receive() + if type(data) == str: + print data + for line in channel: + print line + elif type(data) != dict: + raise ValueError, 'invalid data returned: %r' % (data,) + else: + if data['path']: + print ('a suitable result is already available, you can ' + 'find it at "%s" on %s' % (data['path'], + config.server)) + else: + print data['message'] + print 'the id of this build request is: %s' % (data['id'],) + inprogress = True + finally: + channel.close() + finally: + gateway.exit() + + if foreground and inprogress: + print 'waiting until it\'s done' + error = None + while 1: + ret = check_server(config, request.id(), config.path, + config.port) + if ret is not None: + error = ret['error'] + break + time.sleep(POLLTIME) + if error and error != 'None': + print 'error:', error + else: + zipfile = py.path.local('data.zip') + savezip(config, request.id(), config.path, + config.port, zipfile) + print 'done, the result can be found in "data.zip"' + elif inprogress: + print 'you will be mailed once it\'s ready' + Modified: pypy/dist/pypy/tool/build/config.py ============================================================================== --- pypy/dist/pypy/tool/build/config.py (original) +++ pypy/dist/pypy/tool/build/config.py Mon Mar 19 15:11:56 2007 @@ -29,6 +29,10 @@ compile_config.override({'translation.backend': 'c', 'translation.gc': 'boehm'}) +# svn path and revision, etc. +from pypy.tool.build.tooloption import tool_optiondescription +tool_config = Config(tool_optiondescription) + # settings for the server projectname = 'pypy' buildpath = packageparent.ensure('/pypy/tool/build/builds', dir=True) @@ -64,3 +68,7 @@ return 'http://codespeak.net/pypy/%s/data.zip' % ( p.relto(py.magic.autopath().dirpath()),) +# this should contain the dotted name of the package where 'config' +# can be found on the metaserver (used for remote imports) +configpath = 'pypy.tool.build.config' + Modified: pypy/dist/pypy/tool/build/metaserver.py ============================================================================== --- pypy/dist/pypy/tool/build/metaserver.py (original) +++ pypy/dist/pypy/tool/build/metaserver.py Mon Mar 19 15:11:56 2007 @@ -85,18 +85,33 @@ for bp in self._done: if request.has_satisfying_data(bp.request): path = str(bp) - self._channel.send('already a build for this info available') - return {'path': path, 'id': requestid, 'isbuilding': True, + self._channel.send( + 'already a build for this info available as %s' % ( + bp.request.id(),)) + return {'path': path, 'id': bp.request.id(), + 'isbuilding': True, 'message': 'build is already available'} for builder in self._builders: - if builder.busy_on and request.has_satisfying_data(builder.busy_on): + if (builder.busy_on and + request.has_satisfying_data(builder.busy_on)): + id = builder.busy_on.id() self._channel.send( - "build for %s currently in progress on '%s'" % ( - request, builder.hostname)) + "build for %s currently in progress on '%s' as %s" % ( + request.id(), builder.hostname, id)) self._waiting.append(request) - return {'path': None, 'id': requestid, 'isbuilding': True, + return {'path': None, 'id': id, 'isbuilding': True, 'message': "this build is already in progress " "on '%s'" % (builder.hostname,)} + for br in self._waiting + self._queued: + if br.has_satisfying_data(request): + id = br.id() + self.channel.send( + 'build for %s already queued as %s' % ( + request.id(), id)) + return {'path': None, 'id': id, 'isbuilding': False, + 'message': ('no suitable server found, and a ' + 'similar request was already queued ' + 'as %s' % (id,))} # we don't have a build for this yet, find a builder to compile it hostname = self.run(request) if hostname is not None: @@ -247,9 +262,11 @@ if self.config.mailhost is not None: try: if buildpath.error: + excname = str(buildpath.error) + if hasattr(buildpath.error, '__class__'): + excname = buildpath.error.__class__.__name__ subject = '%s - %s during compilation' % ( - self.config.projectname, - buildpath.error.__class__.__name__) + self.config.projectname, excname) body = ('There was an error during the compilation you ' 'requested. The log can be found below.' '\n\n%s' % (buildpath.log,)) @@ -284,7 +301,7 @@ try: try: from pypy.tool.build.metaserver import MetaServer - from pypy.tool.build import config + import %s as config server = MetaServer(config, channel) # make the metaserver available to build servers as @@ -307,6 +324,25 @@ from pypy.tool.build import execnetconference conference = execnetconference.conference(gw, config.port, True) - channel = conference.remote_exec(initcode % (config.path,)) + channel = conference.remote_exec(initcode % (config.path, + config.configpath)) return channel +def main(config): + from py.execnet import SshGateway, PopenGateway + from pypy.tool.build.metaserver import init + + if config.server in ['localhost', '127.0.0.1']: + gw = PopenGateway() + else: + gw = SshGateway(config.server) + channel = init(gw, config) + + try: + while 1: + data = channel.receive() + print data + finally: + channel.close() + gw.exit() + Modified: pypy/dist/pypy/tool/build/systemoption.py ============================================================================== --- pypy/dist/pypy/tool/build/systemoption.py (original) +++ pypy/dist/pypy/tool/build/systemoption.py Mon Mar 19 15:11:56 2007 @@ -1,6 +1,6 @@ import py from pypy.config.config import OptionDescription, BoolOption, IntOption -from pypy.config.config import ChoiceOption, to_optparse, Config +from pypy.config.config import ChoiceOption, Config import sys system_optiondescription = OptionDescription('system', '', [ Added: pypy/dist/pypy/tool/build/test/test_compile.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/tool/build/test/test_compile.py Mon Mar 19 15:11:56 2007 @@ -0,0 +1,155 @@ +import py +import threading +from pypy.tool.build import execnetconference +from pypy.tool.build import config +from pypy.tool.build.compile import main +from pypy.tool.build.test import fake +from pypy.tool.build import build +from py.__.path.svn.testing import svntestbase +from pypy.tool.build.conftest import option + +here = py.magic.autopath().dirpath() +packageparent = here.dirpath().dirpath().dirpath() + +class FakeServer(object): + remote_code = """ + import sys + sys.path.append(%r) + + from pypy.tool import build + from pypy.tool.build.build import BuildPath + + class FakeMetaServer(object): + def __init__(self): + self._waiting = [] + self._done = [] + + def compile(self, request): + self._waiting.append(request) + return {'path': None, 'id': request.id(), 'isbuilding': True, + 'message': 'found server'} + + def waiting_ids(self): + ret = [] + for r in self._waiting: + ret.append(r.id()) + return ret + + def compilation_done(self, id, path, log): + for r in self._waiting: + if r.id() == id: + self._waiting.remove(r) + bp = BuildPath(path) + bp.log = log + bp.request = r + bp.zip = 'foo' + self._done.append(bp) + + try: + build.metaserver_instance = ms = FakeMetaServer() + + # notify we're done + channel.send(None) + + while 1: + command, data = channel.receive() + if command == 'quit': + break + elif command == 'compilation_done': + id, path, log = data + ms.compilation_done(id, path, log) + channel.send(None) + elif command == 'waiting_ids': + channel.send(ms.waiting_ids()) + finally: + channel.close() + """ % (str(packageparent),) + def __init__(self): + self.gw = gw = py.execnet.PopenGateway() + conference = execnetconference.conference(gw, config.testport, True) + self.channel = channel = conference.remote_exec(self.remote_code) + channel.receive() + + def close(self): + self.channel.send(('quit', None)) + self.channel.close() + self.gw.exit() + + def compilation_done(self, id, path, log): + self.channel.send(('compilation_done', (id, path, log))) + self.channel.receive() + + def waiting_ids(self): + self.channel.send(('waiting_ids', None)) + return self.channel.receive() + +def get_test_config(): + from pypy.config.config import OptionDescription, IntOption + from pypy.config.config import ChoiceOption, Config + sysconfig = Config(OptionDescription('system', '', [ + ChoiceOption('os', 'operating system', ['win32', 'linux2'], + default='linux'), + ])) + compileconfig = Config(OptionDescription('compileinfo', '', [ + IntOption('somevalue', 'some value', default=0), + ])) + return fake.Container( + server='localhost', + port=config.testport, + system_config=sysconfig, + compile_config=compileconfig, + path=[str(packageparent)], + check_svnroot=lambda r: True, + svnpath_to_url=lambda p: 'file://%s' % (p,), + ) + +def test_compile(): + # functional test, sorry :| + if not option.functional: + py.test.skip('skipping functional test, use --functional to run it') + + repo, wc = svntestbase.getrepowc('test_compile') + temp = py.test.ensuretemp('test_compile.buildpath') + wc.ensure('foo', dir=True) + wc.commit('added foo') + path = repo + '/foo' + gw = py.execnet.PopenGateway() + s = FakeServer() + try: + ids = s.waiting_ids() + assert len(ids) == 0 + + # first test a non-blocking compile + req = build.BuildRequest('foo at bar.com', {'foo': 'bar'}, {}, path, 1, 1) + reqid = req.id() + t = threading.Thread(target=main, args=(get_test_config(), req)) + t.start() + t.join(2) + assert not t.isAlive() + ids = s.waiting_ids() + assert ids == [reqid] + s.compilation_done(reqid, str(temp), 'no problems') + ids = s.waiting_ids() + assert len(ids) == 0 + + # now for a blocking one + req = build.BuildRequest('foo at baz.com', {'foo': 'bar'}, {}, path, 1, 1) + reqid = req.id() + t = threading.Thread(target=main, args=(get_test_config(), req, True)) + t.start() + t.join(5) + assert t.isAlive() # still blocking after 2 secs + ids = s.waiting_ids() + assert ids == [reqid] + s.compilation_done(reqid, str(temp), 'no problems') + t.join(15) + assert not t.isAlive() # should have stopped blocking now + ids = s.waiting_ids() + assert ids == [] + finally: + try: + s.close() + gw.exit() + except IOError: + pass + 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 Mar 19 15:11:56 2007 @@ -44,7 +44,7 @@ cfg = Container(projectname='pypytest', server='localhost', port=config.testport, path=config.testpath, buildpath=temppath, - mailhost=None) + mailhost=None, configpath='pypy.tool.build.config') mod.sc = sc = metaserver.init(sgw, cfg) Modified: pypy/dist/pypy/tool/build/testproject/compileoption.py ============================================================================== --- pypy/dist/pypy/tool/build/testproject/compileoption.py (original) +++ pypy/dist/pypy/tool/build/testproject/compileoption.py Mon Mar 19 15:11:56 2007 @@ -4,6 +4,6 @@ import sys compile_optiondescription = OptionDescription('compile', '', [ - BoolOption('moo', 'moo while compiling', default=False), + IntOption('moo', 'moo level', default=1), ]) Modified: pypy/dist/pypy/tool/build/web/templates/buildersinfo.html ============================================================================== --- pypy/dist/pypy/tool/build/web/templates/buildersinfo.html (original) +++ pypy/dist/pypy/tool/build/web/templates/buildersinfo.html Mon Mar 19 15:11:56 2007 @@ -35,7 +35,7 @@ %(not_busy)[c
    nothing
    %(not_busy)]c %(busy_on)[b
    - %(id)s + %(id)s
    request time: %(request_time)s Modified: pypy/dist/pypy/tool/build/web/test/test_app.py ============================================================================== --- pypy/dist/pypy/tool/build/web/test/test_app.py (original) +++ pypy/dist/pypy/tool/build/web/test/test_app.py Mon Mar 19 15:11:56 2007 @@ -137,7 +137,8 @@ binfo.update({'href': 'file:///foo', 'log': 'everything went well', 'error': None, - 'id': 'somebuild'}) + 'id': 'somebuild', + 'vhostroot': ''}) return [ {'hostname': 'host1', 'sysinfo': [{ From guido at codespeak.net Mon Mar 19 15:24:59 2007 From: guido at codespeak.net (guido at codespeak.net) Date: Mon, 19 Mar 2007 15:24:59 +0100 (CET) Subject: [pypy-svn] r40774 - pypy/dist/pypy/tool/build/web Message-ID: <20070319142459.1F29E1006F@code0.codespeak.net> Author: guido Date: Mon Mar 19 15:24:53 2007 New Revision: 40774 Modified: pypy/dist/pypy/tool/build/web/app.py Log: Added missing 'vhostroot' variable for template. Modified: pypy/dist/pypy/tool/build/web/app.py ============================================================================== --- pypy/dist/pypy/tool/build/web/app.py (original) +++ pypy/dist/pypy/tool/build/web/app.py Mon Mar 19 15:24:53 2007 @@ -244,6 +244,7 @@ if d[key]: d[key] = time.strftime('%Y/%m/%d %H:%M:%S', time.gmtime(d[key])) + d['vhostroot'] = config.vhostroot binfo['busy_on'] = [d] else: binfo['busy_on'] = [] From pedronis at codespeak.net Mon Mar 19 16:09:30 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Mon, 19 Mar 2007 16:09:30 +0100 (CET) Subject: [pypy-svn] r40775 - pypy/dist/demo/jit Message-ID: <20070319150930.4A53410069@code0.codespeak.net> Author: pedronis Date: Mon Mar 19 16:09:27 2007 New Revision: 40775 Added: pypy/dist/demo/jit/ - copied from r40768, pypy/dist/pypy/jit/goal/demo/ Log: move jit/goal/demo to demo/jit. jit/goal is going away with the --jit translate.py integration. From guido at codespeak.net Mon Mar 19 16:17:50 2007 From: guido at codespeak.net (guido at codespeak.net) Date: Mon, 19 Mar 2007 16:17:50 +0100 (CET) Subject: [pypy-svn] r40776 - in pypy/dist/pypy/tool/build/web: templates theme Message-ID: <20070319151750.DF84010069@code0.codespeak.net> Author: guido Date: Mon Mar 19 16:17:48 2007 New Revision: 40776 Modified: pypy/dist/pypy/tool/build/web/templates/build.html pypy/dist/pypy/tool/build/web/templates/buildersinfo.html pypy/dist/pypy/tool/build/web/templates/builds.html pypy/dist/pypy/tool/build/web/templates/metaserverstatus.html pypy/dist/pypy/tool/build/web/templates/nav.html pypy/dist/pypy/tool/build/web/theme/style.css Log: Applied some CSS and made some small changes in the HTML to be able to do so. Modified: pypy/dist/pypy/tool/build/web/templates/build.html ============================================================================== --- pypy/dist/pypy/tool/build/web/templates/build.html (original) +++ pypy/dist/pypy/tool/build/web/templates/build.html Mon Mar 19 16:17:48 2007 @@ -4,9 +4,12 @@ - %(nav)s +

    Build %(id)s

    -
    + %(nav)s +
    %(url)[c
    url: Modified: pypy/dist/pypy/tool/build/web/templates/buildersinfo.html ============================================================================== --- pypy/dist/pypy/tool/build/web/templates/buildersinfo.html (original) +++ pypy/dist/pypy/tool/build/web/templates/buildersinfo.html Mon Mar 19 16:17:48 2007 @@ -4,9 +4,12 @@ - %(nav)s +

    Connected build servers

    -
    + %(nav)s +
    %(builders)[b

    %(hostname)s

    Modified: pypy/dist/pypy/tool/build/web/templates/builds.html ============================================================================== --- pypy/dist/pypy/tool/build/web/templates/builds.html (original) +++ pypy/dist/pypy/tool/build/web/templates/builds.html Mon Mar 19 16:17:48 2007 @@ -4,35 +4,40 @@ - %(nav)s +

    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)[b + %(nav)s +
    +

    + 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. +

    +
    id (link)requestedstartedendedstatus
    + - - - - - + + + + + - %(builds)]b - -
    %(id)s%(request_time)s%(build_start_time)s%(build_end_time)s%(status)sid (link)requestedstartedendedstatus
    + + + %(builds)[b + + %(id)s + %(request_time)s + %(build_start_time)s + %(build_end_time)s + %(status)s + + %(builds)]b + + +
    Modified: pypy/dist/pypy/tool/build/web/templates/metaserverstatus.html ============================================================================== --- pypy/dist/pypy/tool/build/web/templates/metaserverstatus.html (original) +++ pypy/dist/pypy/tool/build/web/templates/metaserverstatus.html Mon Mar 19 16:17:48 2007 @@ -4,15 +4,20 @@ - %(nav)s +

    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
    • -
    + %(nav)s +
    +
      +
    • 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
    • +
    +
    Modified: pypy/dist/pypy/tool/build/web/templates/nav.html ============================================================================== --- pypy/dist/pypy/tool/build/web/templates/nav.html (original) +++ pypy/dist/pypy/tool/build/web/templates/nav.html Mon Mar 19 16:17:48 2007 @@ -1,6 +1,6 @@ Modified: pypy/dist/pypy/tool/build/web/theme/style.css ============================================================================== --- pypy/dist/pypy/tool/build/web/theme/style.css (original) +++ pypy/dist/pypy/tool/build/web/theme/style.css Mon Mar 19 16:17:48 2007 @@ -1,7 +1,22 @@ body { + font: Verdana, Helvetica, Arial, sans-serif; background-color: white; color: black; - font: Times New Roman; +} + +.sidebar { + width: 150px; + padding: 0px; + list-style-type: none; + position: absolute; +} + +.sidebar a { + text-decoration: none; +} + +#main { + padding-left: 170px; } .infoblock { @@ -18,7 +33,6 @@ .sub div { margin-left: 1em; - font-size: 0.8em; } td { From arigo at codespeak.net Mon Mar 19 16:22:17 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 19 Mar 2007 16:22:17 +0100 (CET) Subject: [pypy-svn] r40777 - in pypy/dist/pypy/translator: . tool Message-ID: <20070319152217.2A6B210069@code0.codespeak.net> Author: arigo Date: Mon Mar 19 16:22:16 2007 New Revision: 40777 Modified: pypy/dist/pypy/translator/driver.py pypy/dist/pypy/translator/tool/cbuild.py Log: Use the shell to expand a single string into multiple arguments. This fixes a bug causing profopt pypy translations to not do any profiling at all. Modified: pypy/dist/pypy/translator/driver.py ============================================================================== --- pypy/dist/pypy/translator/driver.py (original) +++ pypy/dist/pypy/translator/driver.py Mon Mar 19 16:22:16 2007 @@ -69,7 +69,7 @@ from py.compat import subprocess env = os.environ.copy() env['_INSTRUMENT_COUNTERS'] = str(self.datafile) - subprocess.call([exe, args], env=env) + subprocess.call("'%s' %s" % (exe, args), env=env, shell=True) def after(self): # xxx Modified: pypy/dist/pypy/translator/tool/cbuild.py ============================================================================== --- pypy/dist/pypy/translator/tool/cbuild.py (original) +++ pypy/dist/pypy/translator/tool/cbuild.py Mon Mar 19 16:22:16 2007 @@ -270,9 +270,10 @@ self.build('-fprofile-generate') def probe(self, exe, args): - from py.compat import subprocess - subprocess.call([exe, args]) - + # 'args' is a single string typically containing spaces + # and quotes, which represents several arguments. + os.system("'%s' %s" % (exe, args)) + def after(self): self.build('-fprofile-use') From mwh at codespeak.net Mon Mar 19 16:56:59 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Mon, 19 Mar 2007 16:56:59 +0100 (CET) Subject: [pypy-svn] r40778 - pypy/extradoc/planning/1.0 Message-ID: <20070319155659.9BF541006E@code0.codespeak.net> Author: mwh Date: Mon Mar 19 16:56:57 2007 New Revision: 40778 Modified: pypy/extradoc/planning/1.0/TODO.txt Log: note daily #pypy-sync meeting plans Modified: pypy/extradoc/planning/1.0/TODO.txt ============================================================================== --- pypy/extradoc/planning/1.0/TODO.txt (original) +++ pypy/extradoc/planning/1.0/TODO.txt Mon Mar 19 16:56:57 2007 @@ -4,12 +4,14 @@ current general timeline ----------------------------- +Note: meetings in #pypy-sync every weekday at 5pm + 18 (weekend) 19 build tool with servers -20 pypy-sync: release preps/tasks +20 release preps/tasks 21 wp10 documentation and features integrated (2.1, 3.1) 22 WP08 documentation and working examples integrated (12.1, 14.2, 10.1) -23 pypy-sync: release status / remaining tasks (14.5, 11.1) +23 release status / remaining tasks (14.5, 11.1) dist-trunk separation 24 (weekend) release candidates testing 25 (weekend) release candidates testing From ac at codespeak.net Mon Mar 19 17:18:09 2007 From: ac at codespeak.net (ac at codespeak.net) Date: Mon, 19 Mar 2007 17:18:09 +0100 (CET) Subject: [pypy-svn] r40779 - in pypy/dist/pypy: jit/goal module/pypyjit translator translator/goal Message-ID: <20070319161809.0A12310063@code0.codespeak.net> Author: ac Date: Mon Mar 19 17:18:07 2007 New Revision: 40779 Added: pypy/dist/pypy/module/pypyjit/portal.py - copied, changed from r40775, pypy/dist/pypy/jit/goal/jitstep.py Removed: pypy/dist/pypy/jit/goal/ Modified: pypy/dist/pypy/translator/driver.py pypy/dist/pypy/translator/goal/targetpypystandalone.py pypy/dist/pypy/translator/goal/translate.py Log: (pedronis, arre) Added support for --jit to targetpypystandalone.py Modified: pypy/dist/pypy/translator/driver.py ============================================================================== --- pypy/dist/pypy/translator/driver.py (original) +++ pypy/dist/pypy/translator/driver.py Mon Mar 19 17:18:07 2007 @@ -78,7 +78,7 @@ class TranslationDriver(SimpleTaskEngine): - def __init__(self, setopts=None, default_goal=None, extra_goals=[], + def __init__(self, setopts=None, default_goal=None, disable=[], exe_name=None, extmod_name=None, config=None, overrides=None): @@ -109,7 +109,7 @@ default_goal = None self.default_goal = default_goal - self.extra_goals = extra_goals + self.extra_goals = [] self.exposed = [] # expose tasks @@ -147,7 +147,10 @@ expose_task(explicit_task) else: expose_task(explicit_task) - + + def set_extra_goals(self, goals): + self.extra_goals = goals + def get_info(self): # XXX more? d = {'backend': self.config.translation.backend} return d @@ -703,13 +706,12 @@ def from_targetspec(targetspec_dic, config=None, args=None, empty_translator=None, disable=[], - default_goal=None, - extra_goals=[]): + default_goal=None): if args is None: args = [] driver = TranslationDriver(config=config, default_goal=default_goal, - extra_goals=extra_goals, disable=disable) + disable=disable) # patch some attributes of the os module to make sure they # have the same value on every platform. backend, ts = driver.get_backend_and_type_system() Modified: pypy/dist/pypy/translator/goal/targetpypystandalone.py ============================================================================== --- pypy/dist/pypy/translator/goal/targetpypystandalone.py (original) +++ pypy/dist/pypy/translator/goal/targetpypystandalone.py Mon Mar 19 17:18:07 2007 @@ -98,7 +98,7 @@ multimethod.Installer = multimethod.InstallerVersion1 def handle_translate_config(self, translateconfig): - pass + self.translateconfig = translateconfig def print_help(self, config): self.opt_parser(config).print_help() @@ -128,6 +128,11 @@ elif config.objspace.usemodules._stackless: config.translation.stackless = True + if self.translateconfig.goal_options.jit: + config.objspace.usemodules.pypyjit = True + elif config.objspace.usemodules.pypyjit: + self.translateconfig.goal_options.jit = True + config.objspace.nofaking = True config.objspace.compiler = "ast" config.translating = True @@ -143,6 +148,10 @@ return self.get_entry_point(config) + def portal(self, driver): + from pypy.module.pypyjit.portal import get_portal + return get_portal(driver) + def get_entry_point(self, config): space = make_objspace(config) @@ -164,7 +173,7 @@ def interface(self, ns): for name in ['take_options', 'handle_config', 'print_help', 'target', - 'handle_translate_config', + 'handle_translate_config', 'portal', 'get_additional_config_options']: ns[name] = getattr(self, name) Modified: pypy/dist/pypy/translator/goal/translate.py ============================================================================== --- pypy/dist/pypy/translator/goal/translate.py (original) +++ pypy/dist/pypy/translator/goal/translate.py Mon Mar 19 17:18:07 2007 @@ -260,16 +260,16 @@ pdb_plus_show.start(tb, server_setup, graphic=not translateconfig.text) - log_config(translateconfig, "translate.py configuration") - extra_goals = [] - if translateconfig.goal_options.jit: - extra_goals.append('timeshift') try: drv = driver.TranslationDriver.from_targetspec(targetspec_dic, config, args, empty_translator=t, disable=translateconfig.skipped_goals, - default_goal='compile', - extra_goals=extra_goals) + default_goal='compile') + log_config(translateconfig, "translate.py configuration") + if translateconfig.goal_options.jit: + if 'portal' not in targetspec_dic: + raise Exception('target has no portal defined.') + drv.set_extra_goals(['timeshift']) log_config(config.translation, "translation configuration") pdb_plus_show.expose({'drv': drv, 'prof': prof}) From tismer at codespeak.net Mon Mar 19 17:33:28 2007 From: tismer at codespeak.net (tismer at codespeak.net) Date: Mon, 19 Mar 2007 17:33:28 +0100 (CET) Subject: [pypy-svn] r40780 - pypy/extradoc/planning/1.0 Message-ID: <20070319163328.EE91D1006E@code0.codespeak.net> Author: tismer Date: Mon Mar 19 17:33:25 2007 New Revision: 40780 Modified: pypy/extradoc/planning/1.0/TODO.txt Log: time changed to 4pm for the rest of the week Modified: pypy/extradoc/planning/1.0/TODO.txt ============================================================================== --- pypy/extradoc/planning/1.0/TODO.txt (original) +++ pypy/extradoc/planning/1.0/TODO.txt Mon Mar 19 17:33:25 2007 @@ -4,7 +4,7 @@ current general timeline ----------------------------- -Note: meetings in #pypy-sync every weekday at 5pm +Note: meetings in #pypy-sync every weekday at 4pm 18 (weekend) 19 build tool with servers From mwh at codespeak.net Mon Mar 19 17:35:29 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Mon, 19 Mar 2007 17:35:29 +0100 (CET) Subject: [pypy-svn] r40781 - pypy/extradoc/planning/1.0 Message-ID: <20070319163529.E2B1D1006E@code0.codespeak.net> Author: mwh Date: Mon Mar 19 17:35:27 2007 New Revision: 40781 Modified: pypy/extradoc/planning/1.0/TODO.txt Log: notes from today's #pypy-sync planning session Modified: pypy/extradoc/planning/1.0/TODO.txt ============================================================================== --- pypy/extradoc/planning/1.0/TODO.txt (original) +++ pypy/extradoc/planning/1.0/TODO.txt Mon Mar 19 17:35:27 2007 @@ -4,9 +4,8 @@ current general timeline ----------------------------- -Note: meetings in #pypy-sync every weekday at 4pm +Note: meetings in #pypy-sync every weekday at 4pm (GMT+1) -18 (weekend) 19 build tool with servers 20 release preps/tasks 21 wp10 documentation and features integrated (2.1, 3.1) @@ -32,11 +31,17 @@ - pypy-c-stackless/tp/taint/jit/GC-framework/thunk - pypy-cli-tp/taint/thunk - make a matrix of possible combinations (wp13-report) + (cfbolz) + + - complete/debug jit on powerpc (mwh) + + - debug jit on intel (arigo/pedronis/arre) - integrate and test: - wp10 docs, examples and code - wp08 docs, examples and code - (wp09 docs, examples and code - maybe what we have is good enough?) + - wp10 docs, examples and code (hpk to chase) + - wp08 docs, examples and code (arigo/pedronis/arre, after debugging) + - wp09 docs, examples and code - maybe what we have is good enough? + (christian looking into this currently) - revisit entry level docs (architecture, mission, getting-started) - terminology clarifications: @@ -47,9 +52,11 @@ - so we have: - pypy standard interpreter (easy to understand/modify) - pypy VM translation framework (neccessarily more complex) + (hpk to start here) - describe particularly Javascript-related demos, refine them. (revisit play1.codespeak.net) + (fijal) - make transparent proxies more prominent (because they are a rather powerful feature) @@ -57,17 +64,19 @@ - write/review documentation - fix bugs if any - probably don't go for "transparent_proxy(type, ...)" :) + - update wp6 docs (object-optimizations.txt) and link - to them from getting-started + to them from getting-started (mwh to coordinate) - document build tool usages (getting-started?), connect servers with it + (guido_w) - - refactor and _document_ pypy special info/features to be in + - (maybe not) refactor and _document_ pypy special info/features to be in sys.pypy.version_info * sys.pypy.translation_options * - consider where/how to put special builtins ("pypymagic" + - consider where/how to put special builtins ("pypymagic" might not be a good name), suggestions: - names: pypybuiltin or maybe sys.pypy.* - document pypybuiltin module @@ -75,4 +84,4 @@ is enabled (e.g. method cache) - options only relating to py.py should not appear in translated version (unless they work :) - + (cfbolz) From fijal at codespeak.net Mon Mar 19 17:43:16 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 19 Mar 2007 17:43:16 +0100 (CET) Subject: [pypy-svn] r40782 - in pypy/dist/pypy/translator/js/examples: bnb/data console/data Message-ID: <20070319164316.386701006E@code0.codespeak.net> Author: fijal Date: Mon Mar 19 17:43:13 2007 New Revision: 40782 Modified: pypy/dist/pypy/translator/js/examples/bnb/data/bnb.html pypy/dist/pypy/translator/js/examples/console/data/console.html Log: Use global MochiKit.js, I still commit it... Modified: pypy/dist/pypy/translator/js/examples/bnb/data/bnb.html ============================================================================== --- pypy/dist/pypy/translator/js/examples/bnb/data/bnb.html (original) +++ pypy/dist/pypy/translator/js/examples/bnb/data/bnb.html Mon Mar 19 17:43:13 2007 @@ -4,7 +4,7 @@ Bub'n'bros - + Modified: pypy/dist/pypy/translator/js/examples/console/data/console.html ============================================================================== --- pypy/dist/pypy/translator/js/examples/console/data/console.html (original) +++ pypy/dist/pypy/translator/js/examples/console/data/console.html Mon Mar 19 17:43:13 2007 @@ -1,7 +1,7 @@ - + Console @@ -12,6 +12,7 @@
    From fijal at codespeak.net Mon Mar 19 17:44:21 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 19 Mar 2007 17:44:21 +0100 (CET) Subject: [pypy-svn] r40783 - pypy/dist/pypy/translator/js/examples/console/data Message-ID: <20070319164421.447D01006E@code0.codespeak.net> Author: fijal Date: Mon Mar 19 17:44:20 2007 New Revision: 40783 Modified: pypy/dist/pypy/translator/js/examples/console/data/console.html Log: Add additional pypy-c's Modified: pypy/dist/pypy/translator/js/examples/console/data/console.html ============================================================================== --- pypy/dist/pypy/translator/js/examples/console/data/console.html (original) +++ pypy/dist/pypy/translator/js/examples/console/data/console.html Mon Mar 19 17:44:20 2007 @@ -11,8 +11,9 @@ From arigo at codespeak.net Mon Mar 19 18:46:24 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 19 Mar 2007 18:46:24 +0100 (CET) Subject: [pypy-svn] r40787 - pypy/dist/pypy/module/_pickle_support Message-ID: <20070319174624.A3D991006E@code0.codespeak.net> Author: arigo Date: Mon Mar 19 18:46:24 2007 New Revision: 40787 Modified: pypy/dist/pypy/module/_pickle_support/maker.py Log: Unpickle the correct kind of interpreter-level frame. Modified: pypy/dist/pypy/module/_pickle_support/maker.py ============================================================================== --- pypy/dist/pypy/module/_pickle_support/maker.py (original) +++ pypy/dist/pypy/module/_pickle_support/maker.py Mon Mar 19 18:46:24 2007 @@ -61,7 +61,7 @@ w_pycode, = args_w pycode = space.interp_w(PyCode, w_pycode) w = space.wrap - new_frame = instantiate(PyFrame) + new_frame = instantiate(space.FrameClass) # XXX fish return space.wrap(new_frame) frame_new.unwrap_spec = [ObjSpace, Arguments] From arigo at codespeak.net Mon Mar 19 18:46:57 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 19 Mar 2007 18:46:57 +0100 (CET) Subject: [pypy-svn] r40788 - pypy/dist/pypy/jit Message-ID: <20070319174657.0D24B10070@code0.codespeak.net> Author: arigo Date: Mon Mar 19 18:46:56 2007 New Revision: 40788 Modified: pypy/dist/pypy/jit/TODO.txt Log: Complete the TODO. Modified: pypy/dist/pypy/jit/TODO.txt ============================================================================== --- pypy/dist/pypy/jit/TODO.txt (original) +++ pypy/dist/pypy/jit/TODO.txt Mon Mar 19 18:46:56 2007 @@ -10,7 +10,8 @@ - basic docs and examples -- check that --jit works with --faassen +- check that --jit works with --faassen; don't stop at + BINARY_ADD! Longer-term ------------------ From mwh at codespeak.net Mon Mar 19 19:00:33 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Mon, 19 Mar 2007 19:00:33 +0100 (CET) Subject: [pypy-svn] r40789 - pypy/dist/pypy/jit/codegen/test Message-ID: <20070319180033.B4EA010070@code0.codespeak.net> Author: mwh Date: Mon Mar 19 19:00:31 2007 New Revision: 40789 Modified: pypy/dist/pypy/jit/codegen/test/rgenop_tests.py Log: a test that uses large numbers of frame places (and passes dammit) 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 Mon Mar 19 19:00:31 2007 @@ -715,6 +715,53 @@ return res return write_frame_place_runner +class ManyFramePlaceWriter: + FUNC = lltype.Ptr(lltype.FuncType([llmemory.Address, lltype.Signed], + lltype.Void)) + def __init__(self, RGenOp): + def writer(base, value): + i = 0 + for p in self.places: + RGenOp.write_frame_place(lltype.Signed, base, p, value + i) + i += 1 + self.writer = writer + def get_writer(self, places): + self.places = places + return llhelper(self.FUNC, self.writer) + +def make_write_lots_of_frame_places(rgenop, get_writer): + signed_kind = rgenop.kindToken(lltype.Signed) + sigtoken = rgenop.sigToken(FUNC) + writertoken = rgenop.sigToken(FramePlaceWriter.FUNC.TO) + + builder, gv_f, [gv_x] = rgenop.newgraph(sigtoken, "f") + builder.start_writing() + + gv_base = builder.genop_get_frame_base() + places = [builder.alloc_frame_place(signed_kind) for i in range(100)] + gv_writer = rgenop.constPrebuiltGlobal(get_writer(places)) + builder.genop_call(writertoken, gv_writer, [gv_base, gv_x]) + gv_sum = rgenop.genconst(0) + for p in places: + gv_i = builder.genop_absorb_place(signed_kind, p) + gv_sum = builder.genop2("int_add", gv_sum, gv_i) + builder.finish_and_return(sigtoken, gv_sum) + builder.end() + + return gv_f + +def get_write_lots_of_frame_places_runner(RGenOp): + fvw = ManyFramePlaceWriter(RGenOp) + + def write_lots_of_frame_places_runner(x): + rgenop = RGenOp() + gv_f = make_write_lots_of_frame_places(rgenop, fvw.get_writer) + fn = gv_f.revealconst(lltype.Ptr(FUNC)) + res = fn(x) + keepalive_until_here(rgenop) # to keep the code blocks alive + return res + return write_lots_of_frame_places_runner + class FramePlaceReader: FUNC = lltype.Ptr(lltype.FuncType([llmemory.Address], lltype.Signed)) @@ -1387,6 +1434,21 @@ res = fn(606) assert res == 4242 - 6060 + def test_write_lots_of_frame_places_direct(self): + def get_writer(places): + fvw = ManyFramePlaceWriter(self.RGenOp) + fvw.places = places + writer_ptr = self.directtesthelper(fvw.FUNC, fvw.writer) + return writer_ptr + + rgenop = self.RGenOp() + gv_callable = make_write_lots_of_frame_places(rgenop, get_writer) + fnptr = self.cast(gv_callable, 1) + res = fnptr(3) + assert res == sum(range(3, 103)) + res = fnptr(6) + assert res == sum(range(6, 106)) + def test_read_frame_place_direct(self): def get_reader(place): fpr = FramePlaceReader(self.RGenOp) From pedronis at codespeak.net Mon Mar 19 19:03:09 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Mon, 19 Mar 2007 19:03:09 +0100 (CET) Subject: [pypy-svn] r40790 - in pypy/dist/pypy/jit: . timeshifter timeshifter/test Message-ID: <20070319180309.DDE2D10078@code0.codespeak.net> Author: pedronis Date: Mon Mar 19 19:03:09 2007 New Revision: 40790 Modified: pypy/dist/pypy/jit/TODO.txt pypy/dist/pypy/jit/timeshifter/rcontainer.py pypy/dist/pypy/jit/timeshifter/test/test_virtualizable.py Log: this one is done Modified: pypy/dist/pypy/jit/TODO.txt ============================================================================== --- pypy/dist/pypy/jit/TODO.txt (original) +++ pypy/dist/pypy/jit/TODO.txt Mon Mar 19 19:03:09 2007 @@ -6,8 +6,6 @@ - improve is_true() -- some --jit option for translate.py - - basic docs and examples - check that --jit works with --faassen; don't stop at Modified: pypy/dist/pypy/jit/timeshifter/rcontainer.py ============================================================================== --- pypy/dist/pypy/jit/timeshifter/rcontainer.py (original) +++ pypy/dist/pypy/jit/timeshifter/rcontainer.py Mon Mar 19 19:03:09 2007 @@ -200,12 +200,13 @@ VirtualStructCls = None # patched later with VirtualizableStruct _attrs_ = """redirected_fielddescs - base_desc rti_desc access_desc - gv_access - touch_update - gv_access_is_null_ptr access_is_null_token - get_rti set_rti - """.split() + redirected + base_desc rti_desc access_desc + gv_access + touch_update + gv_access_is_null_ptr access_is_null_token + get_rti set_rti + """.split() def __init__(self, hrtyper, TYPE): RGenOp = hrtyper.RGenOp @@ -213,10 +214,12 @@ ACCESS = self.TYPE.ACCESS redirected_fields = ACCESS.redirected_fields self.redirected_fielddescs = [] + self.redirected = {} i = 0 for fielddesc in self.fielddescs: if fielddesc.fieldname in redirected_fields: self.redirected_fielddescs.append((fielddesc, i)) + self.redirected[i] = None i += 1 self.base_desc = self.getfielddesc('vable_base') self.rti_desc = self.getfielddesc('vable_rti') @@ -804,6 +807,28 @@ continue boxes[i] = fielddesc.generate_get(jitstate, gv_outside) + def op_getfield(self, jitstate, fielddesc): + typedesc = self.typedesc + assert isinstance(typedesc, VirtualizableStructTypeDesc) + fieldindex = fielddesc.fieldindex + if fieldindex in typedesc.redirected: + return self.content_boxes[fielddesc.fieldindex] + else: + gv_ptr = self.getgenvar(jitstate) + box = fielddesc.generate_get(jitstate, gv_ptr) + return box + + def op_setfield(self, jitstate, fielddesc, valuebox): + typedesc = self.typedesc + assert isinstance(typedesc, VirtualizableStructTypeDesc) + fieldindex = fielddesc.fieldindex + if fieldindex in typedesc.redirected: + self.content_boxes[fielddesc.fieldindex] = valuebox + else: + gv_ptr = self.getgenvar(jitstate) + fielddesc.generate_set(jitstate, gv_ptr, + valuebox.getgenvar(jitstate)) + # patching VirtualStructCls StructTypeDesc.VirtualStructCls = VirtualStruct Modified: pypy/dist/pypy/jit/timeshifter/test/test_virtualizable.py ============================================================================== --- pypy/dist/pypy/jit/timeshifter/test/test_virtualizable.py (original) +++ pypy/dist/pypy/jit/timeshifter/test/test_virtualizable.py Mon Mar 19 19:03:09 2007 @@ -759,6 +759,43 @@ assert res == 42 self.check_insns(getfield=0) + def test_simple__class__(self): + class V(object): + _virtualizable_ = True + def __init__(self, a): + self.a = a + + class V1(V): + def __init__(self, b): + V.__init__(self, 1) + self.b = b + + class V2(V): + def __init__(self): + V.__init__(self, 2) + + def f(v): + hint(None, global_merge_point=True) + #V1(0).b + return v.__class__ + + def main(x, y): + if x: + v = V1(42) + else: + v = V2() + if y: + c = None + else: + c = f(v) + V2() + return c is not None + + res = self.timeshift_from_portal(main, f, [0, 1], policy=P_OOPSPEC) + assert not res + res = self.timeshift_from_portal(main, f, [1, 0], policy=P_OOPSPEC) + assert res + def test_simple_inheritance(self): class X(object): From mwh at codespeak.net Mon Mar 19 21:41:18 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Mon, 19 Mar 2007 21:41:18 +0100 (CET) Subject: [pypy-svn] r40793 - pypy/dist/pypy/jit/codegen/ppc Message-ID: <20070319204118.060C210069@code0.codespeak.net> Author: mwh Date: Mon Mar 19 21:41:17 2007 New Revision: 40793 Modified: pypy/dist/pypy/jit/codegen/ppc/rgenop.py Log: allow address cases in flexswitches 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 Mon Mar 19 21:41:17 2007 @@ -1142,10 +1142,10 @@ @specialize.genconst(1) def genconst(self, llvalue): T = lltype.typeOf(llvalue) - if isinstance(T, lltype.Primitive): - return IntConst(lltype.cast_primitive(lltype.Signed, llvalue)) - elif T is llmemory.Address: + if T is llmemory.Address: return AddrConst(llvalue) + elif isinstance(T, lltype.Primitive): + return IntConst(lltype.cast_primitive(lltype.Signed, llvalue)) elif isinstance(T, lltype.Ptr): lladdr = llmemory.cast_ptr_to_adr(llvalue) if T.TO._gckind == 'gc': @@ -1339,8 +1339,8 @@ def _add_case(self, gv_case, target_addr): asm = self.asm - assert isinstance(gv_case, IntConst) - asm.load_word(rSCRATCH, gv_case.value) + assert isinstance(gv_case, GenConst) + gv_case.load_now(asm, insn.gprs[0]) asm.cmpw(self.crf.number, rSCRATCH, self.switch_reg.number) asm.load_word(rSCRATCH, target_addr) asm.mtctr(rSCRATCH) From mwh at codespeak.net Mon Mar 19 22:08:17 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Mon, 19 Mar 2007 22:08:17 +0100 (CET) Subject: [pypy-svn] r40794 - in pypy/dist/pypy/jit/codegen: ppc test Message-ID: <20070319210817.0B4BD10077@code0.codespeak.net> Author: mwh Date: Mon Mar 19 22:08:16 2007 New Revision: 40794 Modified: pypy/dist/pypy/jit/codegen/ppc/instruction.py pypy/dist/pypy/jit/codegen/test/operation_tests.py Log: test + fix for a silly typo related to unsigned comparisons featuring constants. 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 Mon Mar 19 22:08:16 2007 @@ -464,7 +464,7 @@ #print "CMPWI", asm.mc.tell() asm.cmpwi(self.result_reg.number, self.arg_reg.number, self.imm.value) -class CMPWLI(CMPW): +class CMPWLI(CMPWI): def emit(self, asm): asm.cmplwi(self.result_reg.number, self.arg_reg.number, self.imm.value) Modified: pypy/dist/pypy/jit/codegen/test/operation_tests.py ============================================================================== --- pypy/dist/pypy/jit/codegen/test/operation_tests.py (original) +++ pypy/dist/pypy/jit/codegen/test/operation_tests.py Mon Mar 19 22:08:16 2007 @@ -148,6 +148,12 @@ ('int(x != y)', lambda x, y: int(x != y)), ('int(x > y)', lambda x, y: int(x > y)), ('int(x >= y)', lambda x, y: int(x >= y)), + ('int(12 < y)', lambda x, y: int(12 < y)), + ('int(12 <= y)', lambda x, y: int(12 <= y)), + ('int(12 == y)', lambda x, y: int(12 == y)), + ('int(12 != y)', lambda x, y: int(12 != y)), + ('int(12 > y)', lambda x, y: int(12 > y)), + ('int(12 >= y)', lambda x, y: int(12 >= y)), ]: fp = self.rgen(fn, [r_uint, r_uint]) print op From pedronis at codespeak.net Mon Mar 19 22:42:06 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Mon, 19 Mar 2007 22:42:06 +0100 (CET) Subject: [pypy-svn] r40795 - pypy/dist/pypy/jit/timeshifter Message-ID: <20070319214206.84E9810074@code0.codespeak.net> Author: pedronis Date: Mon Mar 19 22:42:05 2007 New Revision: 40795 Modified: pypy/dist/pypy/jit/timeshifter/rcontainer.py Log: (arre, pedronis) see alos previous checkin fixing issues related to access of non-redirected fields of virtualizables Modified: pypy/dist/pypy/jit/timeshifter/rcontainer.py ============================================================================== --- pypy/dist/pypy/jit/timeshifter/rcontainer.py (original) +++ pypy/dist/pypy/jit/timeshifter/rcontainer.py Mon Mar 19 22:42:05 2007 @@ -671,9 +671,19 @@ 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 - builder.genop_setfield(access_token, gv_outside, gv_access_null) + #access_token = typedesc.access_desc.fieldtoken + #gv_access_null = typedesc.access_desc.gv_default + #builder.genop_setfield(access_token, gv_outside, gv_access_null) + # write all non-redirected fields + boxes = self.content_boxes + fielddescs = typedesc.fielddescs + redirected = typedesc.redirected + for i in range(len(fielddescs)): + if i not in redirected: + fielddesc = fielddescs[i] + box = boxes[i] + fielddesc.generate_set(jitstate, gv_outside, + box.getgenvar(jitstate)) return gv_outside def store_back(self, jitstate): @@ -809,10 +819,12 @@ def op_getfield(self, jitstate, fielddesc): typedesc = self.typedesc - assert isinstance(typedesc, VirtualizableStructTypeDesc) + assert isinstance(typedesc, VirtualizableStructTypeDesc) + gv_outside = self.content_boxes[-1].genvar fieldindex = fielddesc.fieldindex - if fieldindex in typedesc.redirected: - return self.content_boxes[fielddesc.fieldindex] + if (gv_outside is typedesc.gv_null or + fieldindex in typedesc.redirected): + return self.content_boxes[fieldindex] else: gv_ptr = self.getgenvar(jitstate) box = fielddesc.generate_get(jitstate, gv_ptr) @@ -822,7 +834,9 @@ typedesc = self.typedesc assert isinstance(typedesc, VirtualizableStructTypeDesc) fieldindex = fielddesc.fieldindex - if fieldindex in typedesc.redirected: + gv_outside = self.content_boxes[-1].genvar + if (gv_outside is typedesc.gv_null or + fieldindex in typedesc.redirected): self.content_boxes[fielddesc.fieldindex] = valuebox else: gv_ptr = self.getgenvar(jitstate) From pedronis at codespeak.net Mon Mar 19 23:26:06 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Mon, 19 Mar 2007 23:26:06 +0100 (CET) Subject: [pypy-svn] r40796 - pypy/dist/pypy/translator Message-ID: <20070319222606.13A701006E@code0.codespeak.net> Author: pedronis Date: Mon Mar 19 23:26:04 2007 New Revision: 40796 Modified: pypy/dist/pypy/translator/interactive.py Log: interactive should default to verbose (for the benefit of translatorshell.py) Modified: pypy/dist/pypy/translator/interactive.py ============================================================================== --- pypy/dist/pypy/translator/interactive.py (original) +++ pypy/dist/pypy/translator/interactive.py Mon Mar 19 23:26:04 2007 @@ -7,6 +7,7 @@ DEFAULTS = { 'translation.backend': None, 'translation.type_system': None, + 'translation.verbose': True, } class Translation(object): From mwh at codespeak.net Mon Mar 19 23:53:34 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Mon, 19 Mar 2007 23:53:34 +0100 (CET) Subject: [pypy-svn] r40797 - pypy/dist/pypy/module/pypyjit/test Message-ID: <20070319225334.CB57E1006E@code0.codespeak.net> Author: mwh Date: Mon Mar 19 23:53:33 2007 New Revision: 40797 Added: pypy/dist/pypy/module/pypyjit/test/__init__.py pypy/dist/pypy/module/pypyjit/test/conftest.py pypy/dist/pypy/module/pypyjit/test/test_pypy_c2.py - copied, changed from r40763, pypy/dist/pypy/module/pypyjit/test/test_pypy_c.py Log: add another version of test_pypy_c that doesn't run as an apptest but instead relies on a --pypy-c option. Added: pypy/dist/pypy/module/pypyjit/test/__init__.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/pypyjit/test/__init__.py Mon Mar 19 23:53:33 2007 @@ -0,0 +1 @@ +# Added: pypy/dist/pypy/module/pypyjit/test/conftest.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/pypyjit/test/conftest.py Mon Mar 19 23:53:33 2007 @@ -0,0 +1,9 @@ +import py + + +Option = py.test.config.Option + +option = py.test.config.addoptions("ppc options", + Option('--pypy-c', action="store", default=None, + dest="pypy_c", + help="")) From xoraxax at codespeak.net Tue Mar 20 00:18:00 2007 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Tue, 20 Mar 2007 00:18:00 +0100 (CET) Subject: [pypy-svn] r40798 - pypy/dist/pypy/translator Message-ID: <20070319231800.93FA710068@code0.codespeak.net> Author: xoraxax Date: Tue Mar 20 00:17:58 2007 New Revision: 40798 Modified: pypy/dist/pypy/translator/interactive.py Log: Remove duplicate option line. Modified: pypy/dist/pypy/translator/interactive.py ============================================================================== --- pypy/dist/pypy/translator/interactive.py (original) +++ pypy/dist/pypy/translator/interactive.py Tue Mar 20 00:17:58 2007 @@ -32,8 +32,6 @@ graph = self.context.buildflowgraph(entry_point) self.context._prebuilt_graphs[entry_point] = graph - self.config.translation.verbose = True # enable messages - def view(self): self.context.view() From xoraxax at codespeak.net Tue Mar 20 00:46:31 2007 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Tue, 20 Mar 2007 00:46:31 +0100 (CET) Subject: [pypy-svn] r40799 - pypy/dist/pypy/translator Message-ID: <20070319234631.7569C10068@code0.codespeak.net> Author: xoraxax Date: Tue Mar 20 00:46:28 2007 New Revision: 40799 Modified: pypy/dist/pypy/translator/geninterplevel.py pypy/dist/pypy/translator/translator.py Log: Add mute_dot to build_flowgraph and let geninterp use it. Modified: pypy/dist/pypy/translator/geninterplevel.py ============================================================================== --- pypy/dist/pypy/translator/geninterplevel.py (original) +++ pypy/dist/pypy/translator/geninterplevel.py Tue Mar 20 00:46:28 2007 @@ -1152,7 +1152,7 @@ def gen_rpyfunction(self, func): try: - graph = self.translator.buildflowgraph(func) + graph = self.translator.buildflowgraph(func, True) except Exception, e: print 20*"*", e print func Modified: pypy/dist/pypy/translator/translator.py ============================================================================== --- pypy/dist/pypy/translator/translator.py (original) +++ pypy/dist/pypy/translator/translator.py Tue Mar 20 00:46:28 2007 @@ -57,7 +57,7 @@ pypy_optiondescription, self.config, translating=True) self.flowconfig.objspace.name = "flow" - def buildflowgraph(self, func): + def buildflowgraph(self, func, mute_dot=False): """Get the flow graph for a function.""" if not isinstance(func, types.FunctionType): raise TypeError("buildflowgraph() expects a function, " @@ -81,7 +81,7 @@ simplify.detect_list_comprehension(graph) if self.config.translation.verbose: log.done(func.__name__) - else: + elif not mute_dot: log.dot() self.graphs.append(graph) # store the graph in our list return graph From pedronis at codespeak.net Tue Mar 20 00:56:30 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Tue, 20 Mar 2007 00:56:30 +0100 (CET) Subject: [pypy-svn] r40801 - pypy/dist/pypy/jit Message-ID: <20070319235630.7CAEB10068@code0.codespeak.net> Author: pedronis Date: Tue Mar 20 00:56:29 2007 New Revision: 40801 Modified: pypy/dist/pypy/jit/TODO.txt Log: refine Modified: pypy/dist/pypy/jit/TODO.txt ============================================================================== --- pypy/dist/pypy/jit/TODO.txt (original) +++ pypy/dist/pypy/jit/TODO.txt Tue Mar 20 00:56:29 2007 @@ -3,6 +3,7 @@ ------------------ - see the inplace-version of the arithmetic operators + and some obvious unary ones: - ... - improve is_true() From santagada at codespeak.net Tue Mar 20 04:01:17 2007 From: santagada at codespeak.net (santagada at codespeak.net) Date: Tue, 20 Mar 2007 04:01:17 +0100 (CET) Subject: [pypy-svn] r40805 - in pypy/dist/pypy/lang/js: . test Message-ID: <20070320030117.8842B10063@code0.codespeak.net> Author: santagada Date: Tue Mar 20 04:01:15 2007 New Revision: 40805 Modified: pypy/dist/pypy/lang/js/jsobj.py pypy/dist/pypy/lang/js/operations.py pypy/dist/pypy/lang/js/test/test_interp.py pypy/dist/pypy/lang/js/test/test_parser.py Log: made arrays work a lot more like the javascript ones (but they can be optimzed a lot) Modified: pypy/dist/pypy/lang/js/jsobj.py ============================================================================== --- pypy/dist/pypy/lang/js/jsobj.py (original) +++ pypy/dist/pypy/lang/js/jsobj.py Tue Mar 20 04:01:15 2007 @@ -292,38 +292,42 @@ toString = W_Builtin(array_str_builtin) self.Put('toString', toString, de=True) self.Put('length', W_Number(0)) - self.array = [] + self.length = r_uint(0) self.set_builtin_call(arraycallbi) def Put(self, P, V, dd=False, ro=False, de=False, it=False): - try: - x = int(P) - # print "puting", V, 'in', x - if x > self.Get('length').ToNumber() - 1: - currsize = len(self.array) - self.propdict['length'].value = W_Number(x+1) - print x+1 - for i in range(x-(currsize-1)): - self.array.append(w_Undefined) - self.array[x]= V - - except ValueError: - W_Builtin.Put(self, P, V, dd=dd, ro=ro, de=de, it=it) + + if not self.CanPut(P): return + if P in self.propdict: + if P == 'length': + try: + res = V.ToUInt32() + if V.ToNumber() < 0: + raise RangeError() + self.propdict['length'].value = W_Number(res) + self.length = res + return + except ValueError: + raise RangeError('invalid array length') + else: + self.propdict[P].value = V + else: + self.propdict[P] = Property(P, V, + dd = dd, ro = ro, it = it) - def Get(self, P): try: - x = int(P) - if x > (len(self.array)-1): - return w_Undefined - else: - # print "returning", self.array[x], 'in', x - return self.array[x] + index = r_uint(float(P)) except ValueError: - return W_PrimitiveObject.Get(self, P) + return + if index < self.length: + return + self.length = index+1 + self.propdict['length'].value = W_Number(index+1) + return def ToString(self): - return ','.join([item.ToString() for item in self.array]) + return ','.join([self.Get(str(index)).ToString() for index in range(self.length)]) def array_str_builtin(ctx, args, this): return W_String(this.ToString()) @@ -439,6 +443,7 @@ self.scope = [] self.this = None self.variable = None + self.debug = False self.property = Property('',w_Undefined) #Attribute flags for new vars def assign(self, name, value): Modified: pypy/dist/pypy/lang/js/operations.py ============================================================================== --- pypy/dist/pypy/lang/js/operations.py (original) +++ pypy/dist/pypy/lang/js/operations.py Tue Mar 20 04:01:15 2007 @@ -968,6 +968,10 @@ def execute(self, ctx): for var in self.nodes: var.execute(ctx) + return W_String(self.nodes[-1].get_literal()) + + def eval(self, ctx): + return self.execute(ctx) class Void(UnaryOp): opcode = 'VOID' 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 Mar 20 04:01:15 2007 @@ -503,3 +503,9 @@ print(2 & 3) print(2 | 3) """, ['0', '2', '3']) + + def test_for_strange(self): + self.assert_prints(""" + for (var arg = "", i = 0; i < 2; i++) { print(i)} + """, ['0', '1']) + Modified: pypy/dist/pypy/lang/js/test/test_parser.py ============================================================================== --- pypy/dist/pypy/lang/js/test/test_parser.py (original) +++ pypy/dist/pypy/lang/js/test/test_parser.py Tue Mar 20 04:01:15 2007 @@ -6,5 +6,5 @@ def test_quoting(): - read_js_output('x = "\'"') + read_js_output("x = '\\''") read_js_output('x = "\\\\"') \ No newline at end of file From fijal at codespeak.net Tue Mar 20 10:26:01 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 20 Mar 2007 10:26:01 +0100 (CET) Subject: [pypy-svn] r40809 - pypy/dist/pypy/doc Message-ID: <20070320092601.D090D1005A@code0.codespeak.net> Author: fijal Date: Tue Mar 20 10:25:59 2007 New Revision: 40809 Added: pypy/dist/pypy/doc/parse_logs.py (contents, props changed) Log: Hmm. I've been keeping this script for a while in my wc, not sure if it's not commited somewhere else Added: pypy/dist/pypy/doc/parse_logs.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/doc/parse_logs.py Tue Mar 20 10:25:59 2007 @@ -0,0 +1,59 @@ +#!/usr/bin/env python +import log_reader + +def daily_date_hasher(date): + return ((date.year, date.month, date.day)) + +def read_log(filename, path_guesser, date_hasher=daily_date_hasher, + max_reads=None): + assert callable(path_guesser) + lr = log_reader.ApacheReader(filename) + ret = {} + keys = [] + for num, i in enumerate(lr): + if max_reads and num > max_reads: + return keys, ret + if 'path' in i: + if path_guesser(i['path']): + hash = date_hasher(i['time']) + if hash in ret: + ret[hash] += 1 + else: + ret[hash] = 1 + keys.append(hash) + return keys, ret + +def test_daily_date_hasher(): + from datetime import datetime + one = datetime(2007, 2, 25, 3, 10, 50) + two = datetime(2007, 2, 25, 7, 1, 5) + three = datetime(2007, 3, 25, 3, 10, 50) + assert daily_date_hasher(one) == daily_date_hasher(two) + assert daily_date_hasher(one) != daily_date_hasher(three) + +def test_read_log(): + def path_guesser(path): + return path.startswith("/viewvc") + keys, ret = read_log("code.log", path_guesser) + assert sum(ret.values()) == 51 + assert sorted(keys) == keys + assert ret[(2007, 2, 25)] == 51 + +if __name__ == "__main__": + import sys + import re + if len(sys.argv) == 3: + max_reads = int(sys.argv[2]) + elif len(sys.argv) != 2: + print "Usage ./parse_logs.py [max reads]" + sys.exit(1) + else: + max_reads = None + + def path_guesser(path): + return "pypy" in path + + keys, ret = read_log(sys.argv[1], path_guesser, max_reads=max_reads) + for key in keys: + year, month, day = key + print "%d-%d-%d, %d" % (year, month, day, ret[key]) From fijal at codespeak.net Tue Mar 20 10:26:27 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 20 Mar 2007 10:26:27 +0100 (CET) Subject: [pypy-svn] r40810 - pypy/dist/pypy/doc Message-ID: <20070320092627.9EC5710060@code0.codespeak.net> Author: fijal Date: Tue Mar 20 10:26:26 2007 New Revision: 40810 Modified: pypy/dist/pypy/doc/_ref.txt pypy/dist/pypy/doc/jit.txt Log: Fix jit reference Modified: pypy/dist/pypy/doc/_ref.txt ============================================================================== --- pypy/dist/pypy/doc/_ref.txt (original) +++ pypy/dist/pypy/doc/_ref.txt Tue Mar 20 10:26:26 2007 @@ -33,7 +33,6 @@ .. _`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 Modified: pypy/dist/pypy/doc/jit.txt ============================================================================== --- pypy/dist/pypy/doc/jit.txt (original) +++ pypy/dist/pypy/doc/jit.txt Tue Mar 20 10:26:26 2007 @@ -79,9 +79,9 @@ How to compile a pypy-c with a JIT ================================== -Go to ``pypy/jit/goal/`` and run:: +Go to ``pypy/translator/goal/`` and run:: - ../../translator/goal/translate.py targetjit.py + ./translate.py --jit targetpypystandalone Please first read the warning_ above. This only works for Intel 386-compatible machines yet. **This is not going to speed up your From hpk at codespeak.net Tue Mar 20 10:36:18 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Tue, 20 Mar 2007 10:36:18 +0100 (CET) Subject: [pypy-svn] r40811 - in pypy/dist/pypy/lang/js/test/ecma: . Array Boolean ExecutionContexts Expressions Message-ID: <20070320093618.4F1051005A@code0.codespeak.net> Author: hpk Date: Tue Mar 20 10:36:17 2007 New Revision: 40811 Modified: pypy/dist/pypy/lang/js/test/ecma/ (props changed) pypy/dist/pypy/lang/js/test/ecma/Array/ (props changed) pypy/dist/pypy/lang/js/test/ecma/Boolean/ (props changed) pypy/dist/pypy/lang/js/test/ecma/ExecutionContexts/ (props changed) pypy/dist/pypy/lang/js/test/ecma/Expressions/ (props changed) Log: ignore js-cache files From afayolle at codespeak.net Tue Mar 20 10:52:41 2007 From: afayolle at codespeak.net (afayolle at codespeak.net) Date: Tue, 20 Mar 2007 10:52:41 +0100 (CET) Subject: [pypy-svn] r40812 - in pypy/dist/pypy: doc lib lib/app_test Message-ID: <20070320095241.55FE41005A@code0.codespeak.net> Author: afayolle Date: Tue Mar 20 10:52:40 2007 New Revision: 40812 Added: pypy/dist/pypy/doc/aspect_oriented_programming.txt (contents, props changed) Modified: pypy/dist/pypy/lib/aop.py pypy/dist/pypy/lib/app_test/sample_aop_code.py Log: short documentation on the aop module Added: pypy/dist/pypy/doc/aspect_oriented_programming.txt ============================================================================== --- (empty file) +++ pypy/dist/pypy/doc/aspect_oriented_programming.txt Tue Mar 20 10:52:40 2007 @@ -0,0 +1,194 @@ +======================= +Documentation of aop.py +======================= + +.. contents:: +.. sectnum:: + +Prerequisites +============= + +The ``aop`` module for PyPy only requires PyPy. No special translation +options are required, and it should work with all the backends. For +the development of application using AOP, though, it is strongly +advised to use a PyPy interpreter translated with the +``--no-objspace-usepycfiles`` option, which tells the interpreter not +to use byte-compiled modules, otherwise, you will need to manually +remove all the ``.pyc`` files each time the aspects are modified. + +Concepts +======== + +Aspect +------ + +An aspect is a representation of a +software design concern which affects a large part of a +program. Cross-cutting aspects are those concerns which have to be +dealt with in a number of unrelated parts of a program, for instance, +logging, synchronisation, persistance, security, value sharing, etc. + +Advice +------ + +An advice is a piece of code that will be woven in a code base at +specific join points. An aspect is usually implemented as a set of +advices. + +Static advices deal with adding declarative statements in the code, +for instance, adding new methods to a class. Dynamic advices are about +modifying the behaviour of the code, by adding statements to a +method, or replacing the code of a method. + +Point cut +--------- + +A point cut is a set of join points. + +Join point +---------- + +A join point is a place in a code base where some advices are to be +woven. Common join points include class definition, method or +function definition and methode calls. + +Weaving +------- + +Weaving is the process of inserting an advices at a set of point +cuts. + +Implementation +============== + +Overview +-------- + +Importing the ``aop`` module has several side effects: + +* an instance of ``aop.Weaver`` is created and stored in + ``__builtin__.__aop__``, which makes it globally available in modules + which will be imported later +* this instance registers one of its methods with + ``parser.install_compiler_hook`` (see above) + +From then on, any module imported will be examined by the ``Weaver`` +instance. + +The code can define new aspects by using the ``Aspect`` metaclass in +the ``aop`` module. This metaclass can register methods decorated with +one of the advices of the ``aop`` module with the ``Weaver`` when the +``Aspect`` is instantiated. When a module is imported, the ``Weaver`` +looks for symbols (classes, functions and methods) which are targets +of registered aspects and weaves the aspect in the function. The +weaving is done by mutating the AST nodes of the module. The mutation +generally involves calling a method on the ``__aop__`` instance with a +unique identifier. The Weaver will use this identifier at run time to +find which advice it should execute. + +Aspects +~~~~~~~ + +Aspects are declared in classes using the ``aop.Aspect`` +metaclass. Such classes can have normal methods, and additionally +methods decorated with an advice decorator, and aspect instances will +be registered with the Weaver by the metaclass. These decorators take +a ``PointCut`` as an argument to describe the join points. + +Advices +------- + +The available advices are: + +* ``before``: the advice code will be woven before a dynamic join point +* ``after``: the advice code will be woven after a dynamic join point +* ``around``: the advice code will be woven in replacement of the + dynamic join point +* ``introduce``: the advice code will be added to a static join + point. + +Point cuts +---------- + +A static point cut is created by instantiating the ``aop.PointCut`` +class, passing one, two or three arguments. Each argument is a +regular expression which can match a package/module, a class or a +function/method. + +Point cuts can be combined using the python binary operators & and +|, which will produce a new PointCut representing respectively the +intersection and the union of the join points of the original point +cuts. + +A dynamic point cut can be obtained from a static point cut by calling +one of the following methods: + +=================== ====================================================== +method dynamic pointcut matching +------------------- ------------------------------------------------------ +pc.call() all the places where the method or + function matched by the static pointcut is called +------------------- ------------------------------------------------------ +pc.execution() the execution of the function or method matched by + the static point cut +------------------- ------------------------------------------------------ +pc.initialization() the initialization of the class matched by the + static point cut +------------------- ------------------------------------------------------ +pc.destruction() the destruction of the class matched by the + static point cut +=================== ====================================================== + +Example +======= + +The following code can be used to implement a logging aspect:: + +in file ``logging_aspect.py``:: + + from aop import Aspect, before, PointCut + + class LoggingAspect: + __metaclass__=Aspect + + # We weave in all methods and functions, except if the name of + # the method starts with an underscore + @before(PointCut(module='.*', klass='.*', func='[^_].*').execution()) + def logStartMethod(self, joinpoint): + print 'in', joinpoint.name() + + +In the startup code of the application, before all other imports:: + + from logging_aspect import LoggingAspect + log = LoggingAspect() + +References +========== + +AOP implementations exist for a wide variety of programming languages, +and many languages have several implementations available. A list can +be found on the `aosd.net`_ `tools for developers`_ wiki +page. `aosd.net`_ is also the main resource for AOP programming. + +Other AOP implementations for python include: + +* `lightweight aop for Python`_ +* `springpython.aop`_ +* `logilab.aspects`_ + +The apy of PyPy's ``aop`` module is strongly inspired by AspectJ_ and `AspectC++`_. + +.. _aosd.net: http://aosd.net/ + +.. _tools for developers: http://aosd.net/wiki/index.php?title=Tools_for_Developers + +.. _logilab.aspects: http://www.logilab.org/projects/aspects + +.. _lightweight aop for Python: http://www.cs.tut.fi/~ask/aspects/aspects.html + +.. _springpython.aop: http://springpython.python-hosting.com/wiki/AspectOrientedProgramming + +.. _AspectJ: http://www.eclipse.org/aspectj/ + +.. _AspectC++: http://www.aspectc.org/ Modified: pypy/dist/pypy/lib/aop.py ============================================================================== --- pypy/dist/pypy/lib/aop.py (original) +++ pypy/dist/pypy/lib/aop.py Tue Mar 20 10:52:40 2007 @@ -91,6 +91,7 @@ def weave_at_static(self, node, tjp): raise NotImplementedError("abstract method") + class around(Advice): """specify code to be run instead of the pointcut""" @log_exc Modified: pypy/dist/pypy/lib/app_test/sample_aop_code.py ============================================================================== --- pypy/dist/pypy/lib/app_test/sample_aop_code.py (original) +++ pypy/dist/pypy/lib/app_test/sample_aop_code.py Tue Mar 20 10:52:40 2007 @@ -1,5 +1,9 @@ code = """ -def foo(b,c): +def foo(b, c): + ''' + pre: + b < c + ''' print 'foo' a = 2 d = bar(a) From xoraxax at codespeak.net Tue Mar 20 10:52:46 2007 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Tue, 20 Mar 2007 10:52:46 +0100 (CET) Subject: [pypy-svn] r40813 - pypy/dist/pypy/translator/backendopt Message-ID: <20070320095246.4E3B710063@code0.codespeak.net> Author: xoraxax Date: Tue Mar 20 10:52:45 2007 New Revision: 40813 Modified: pypy/dist/pypy/translator/backendopt/removeassert.py Log: Only print counts for asserts in non-verbose mode. Modified: pypy/dist/pypy/translator/backendopt/removeassert.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/removeassert.py (original) +++ pypy/dist/pypy/translator/backendopt/removeassert.py Tue Mar 20 10:52:45 2007 @@ -12,6 +12,7 @@ clsdef = translator.annotator.bookkeeper.getuniqueclassdef(AssertionError) r_AssertionError = rclass.getclassrepr(rtyper, clsdef) ll_AssertionError = r_AssertionError.convert_const(AssertionError) + total_count = [0, 0] for graph in graphs: count = 0 @@ -29,14 +30,18 @@ morework = True break else: - log.removeassert("cannot remove an assert from %s" % (graph.name,)) + total_count[0] += 1 + if translator.config.translation.verbose: + log.removeassert("cannot remove an assert from %s" % (graph.name,)) if count: # now melt away the (hopefully) dead operation that compute # the condition + total_count[1] += count if translator.config.translation.verbose: log.removeassert("removed %d asserts in %s" % (count, graph.name)) checkgraph(graph) #transform_dead_op_vars(graph, translator) + log.removeassert("Could not remove %d asserts, but removed %d asserts." % tuple(total_count)) def kill_assertion_link(graph, link): From xoraxax at codespeak.net Tue Mar 20 10:53:36 2007 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Tue, 20 Mar 2007 10:53:36 +0100 (CET) Subject: [pypy-svn] r40814 - pypy/dist/pypy/jit/timeshifter Message-ID: <20070320095336.0D2EF10060@code0.codespeak.net> Author: xoraxax Date: Tue Mar 20 10:53:35 2007 New Revision: 40814 Modified: pypy/dist/pypy/jit/timeshifter/hrtyper.py Log: Only show the op timeshifter status every 5 %. Modified: pypy/dist/pypy/jit/timeshifter/hrtyper.py ============================================================================== --- pypy/dist/pypy/jit/timeshifter/hrtyper.py (original) +++ pypy/dist/pypy/jit/timeshifter/hrtyper.py Tue Mar 20 10:53:35 2007 @@ -65,6 +65,7 @@ self.timeshift_mapping = {} self.sigs = {} self.dispatchsubclasses = {} + self.old_percentage = 0 (self.s_JITState, self.r_JITState) = self.s_r_instanceof(rtimeshift.JITState) @@ -425,9 +426,12 @@ 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)) + percentage = 100 * self.graphcount / self.ngraphs + if percentage >= self.old_percentage + 5: + self.old_percentage = percentage + self.log.event("Timeshifted ops in %d blocks, %d/%d graphs (%d %%)" % + (self.blockcount, self.graphcount, + self.ngraphs, percentage)) self.graphcount += 1 # "normalize" the graphs by putting an explicit v_jitstate variable # everywhere From xoraxax at codespeak.net Tue Mar 20 10:54:11 2007 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Tue, 20 Mar 2007 10:54:11 +0100 (CET) Subject: [pypy-svn] r40815 - pypy/dist/pypy/jit/hintannotator Message-ID: <20070320095411.582991005A@code0.codespeak.net> Author: xoraxax Date: Tue Mar 20 10:54:10 2007 New Revision: 40815 Modified: pypy/dist/pypy/jit/hintannotator/bookkeeper.py Log: Show dots instead of graph names while hintannotating in non-verbose mode. Modified: pypy/dist/pypy/jit/hintannotator/bookkeeper.py ============================================================================== --- pypy/dist/pypy/jit/hintannotator/bookkeeper.py (original) +++ pypy/dist/pypy/jit/hintannotator/bookkeeper.py Tue Mar 20 10:54:10 2007 @@ -43,6 +43,7 @@ return graph def cachedgraph(self, key, alt_name=None): + verbose = self.bookkeeper.annotator.translator.config.translation.verbose try: return self._cache[key] except KeyError: @@ -50,10 +51,16 @@ if bk.annotator.policy.look_inside_graph(self.origgraph): graph = copygraph(self.origgraph, varmap=TIMESHIFTMAP) bk.nonstubgraphcount += 1 - log(str(graph)) + if verbose: + log(str(graph)) + else: + log.dot() else: graph = self.build_callback_graph(self.origgraph) - log.stub(str(graph)) + if verbose: + log.stub(str(graph)) + else: + log.dot() graph.tag = 'timeshifted' try: etrafo = bk.annotator.exceptiontransformer From fijal at codespeak.net Tue Mar 20 11:15:01 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 20 Mar 2007 11:15:01 +0100 (CET) Subject: [pypy-svn] r40816 - pypy/dist/pypy/translator/goal/test2 Message-ID: <20070320101501.ED84E10060@code0.codespeak.net> Author: fijal Date: Tue Mar 20 11:15:01 2007 New Revision: 40816 Modified: pypy/dist/pypy/translator/goal/test2/test_app_main.py Log: Failing test for -u option Modified: pypy/dist/pypy/translator/goal/test2/test_app_main.py ============================================================================== --- pypy/dist/pypy/translator/goal/test2/test_app_main.py (original) +++ pypy/dist/pypy/translator/goal/test2/test_app_main.py Tue Mar 20 11:15:01 2007 @@ -296,3 +296,24 @@ assert 'Name: __main__' in data assert ('File: ' + p) in data assert ('Argv: ' + repr([p, 'extra'])) in data + +def test_option_u(): + py.test.skip("Failing") + import subprocess + from py.__.green.greensock2 import autogreenlet, Timer, Interrupted + from py.__.green.pipe.fd import FDInput + python = "python" + pipe = subprocess.Popen([python, app_main, "-u", "-i"], + stdout=subprocess.PIPE, + stdin=subprocess.PIPE, stderr=subprocess.STDOUT, + bufsize=0, close_fds=True) + read_fd = FDInput(pipe.stdout.fileno(), close=False) + timeout = 5 + timer = Timer(timeout) + try: + data = read_fd.recv(10024) + except Interrupted: + py.test.fail("Timed out reading") + else: + timer.stop() + From afayolle at codespeak.net Tue Mar 20 11:16:32 2007 From: afayolle at codespeak.net (afayolle at codespeak.net) Date: Tue, 20 Mar 2007 11:16:32 +0100 (CET) Subject: [pypy-svn] r40817 - pypy/dist/pypy/doc Message-ID: <20070320101632.C0C9C10060@code0.codespeak.net> Author: afayolle Date: Tue Mar 20 11:16:31 2007 New Revision: 40817 Modified: pypy/dist/pypy/doc/getting-started.txt Log: getting started on aspect oriented programming Modified: pypy/dist/pypy/doc/getting-started.txt ============================================================================== --- pypy/dist/pypy/doc/getting-started.txt (original) +++ pypy/dist/pypy/doc/getting-started.txt Tue Mar 20 11:16:31 2007 @@ -324,6 +324,31 @@ .. _`Logic Object space features`: howto-logicobjspace-0.9.html +Aspect Oriented Programming ++++++++++++++++++++++++++++ + +PyPy provides some `Aspect Oriented Programming` facilities. + +Try it out:: + + cd pypy + python bin/py.py + + >>>> from aop import Aspect, before, PointCut + >>>> class DemoAspect: + .... __metaclass__ = Aspect + .... @before(PointCut(func="^open$").call()) + .... def before_open(self, joinpoint): + .... print "opening", joinpoint.arguments() + .... + >>>> aspect = DemoAspect() + >>>> f = open("/tmp/toto.txt", 'w') + +To read more about this, try the `aop module documentation`_. + +.. _`Aspect Oriented Programming`: http://aosd.net +.. _`aop module documentation`: aspect_oriented_programming.html + Running the tests +++++++++++++++++ From arigo at codespeak.net Tue Mar 20 11:35:47 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 20 Mar 2007 11:35:47 +0100 (CET) Subject: [pypy-svn] r40818 - in pypy/dist/pypy: config module/__builtin__ module/__builtin__/test Message-ID: <20070320103547.DC86210069@code0.codespeak.net> Author: arigo Date: Tue Mar 20 11:35:45 2007 New Revision: 40818 Modified: pypy/dist/pypy/config/pypyoption.py pypy/dist/pypy/module/__builtin__/importing.py pypy/dist/pypy/module/__builtin__/test/test_import.py Log: pyc files support for the versions of pypy-c that include new opcodes, with different magic numbers. The new test in test_import will fail if you add a new option in objspace.opcodes.* but forget to have it influence the magic number. Modified: pypy/dist/pypy/config/pypyoption.py ============================================================================== --- pypy/dist/pypy/config/pypyoption.py (original) +++ pypy/dist/pypy/config/pypyoption.py Tue Mar 20 11:35:45 2007 @@ -58,11 +58,9 @@ OptionDescription("opcodes", "opcodes to enable in the interpreter", [ BoolOption("CALL_LIKELY_BUILTIN", "emit a special bytecode for likely calls to builtin functions", default=False, - requires=[("objspace.usepycfiles", False), - ("objspace.std.withmultidict", True)]), + requires=[("objspace.std.withmultidict", True)]), BoolOption("CALL_METHOD", "emit a special bytecode for expr.name()", - default=False, - requires=[("objspace.usepycfiles", False)]), + default=False), ]), BoolOption("nofaking", "disallow faking in the object space", Modified: pypy/dist/pypy/module/__builtin__/importing.py ============================================================================== --- pypy/dist/pypy/module/__builtin__/importing.py (original) +++ pypy/dist/pypy/module/__builtin__/importing.py Tue Mar 20 11:35:45 2007 @@ -327,14 +327,27 @@ """ # we decided to use the magic of 2.4.1 +# +# In addition, for now, the presence of special bytecodes bumps the +# magic number: +# +# * CALL_LIKELY_BUILTIN +2 +# * CALL_METHOD +4 +# +# this is a bit of a hack waiting for a nicer general solution. +# Adding another bytecode is already a problem: if we bump the +# number by a total of +10 we collide with CPython's own magic +# number for 2.5a0. +# MAGIC = 62061 | (ord('\r')<<16) | (ord('\n')<<24) -"""Magic word as global; note that _PyImport_Init() can change the - value of this global to accommodate for alterations of how the - compiler works which are enabled by command line switches. -""" - -pyc_magic = MAGIC +def get_pyc_magic(space): + result = MAGIC + if space.config.objspace.opcodes.CALL_LIKELY_BUILTIN: + result += 2 + if space.config.objspace.opcodes.CALL_METHOD: + result += 4 + return result def parse_source_module(space, pathname, stream): @@ -408,7 +421,7 @@ stream = streamio.open_file_as_stream(cpathname, "rb") magic = _r_long(stream) try: - if magic != pyc_magic: + if magic != get_pyc_magic(space): # XXX what to do about Py_VerboseFlag ? # PySys_WriteStderr("# %s has bad magic\n", cpathname); return -1 @@ -441,7 +454,7 @@ """ w = space.wrap magic = _r_long(stream) - if magic != pyc_magic: + if magic != get_pyc_magic(space): raise OperationError(space.w_ImportError, w( "Bad magic number in %s" % cpathname)) _r_long(stream) # skip time stamp @@ -492,7 +505,7 @@ # should be ok (XXX or should call os.fsync() to be sure?) stream.seek(0, 0) - _w_long(stream, pyc_magic) + _w_long(stream, get_pyc_magic(space)) _w_long(stream, mtime) finally: stream.close() 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 Tue Mar 20 11:35:45 2007 @@ -4,6 +4,7 @@ import pypy.interpreter.pycode from pypy.tool.udir import udir from pypy.rlib import streamio +from pypy.conftest import gettestobjspace import sys, os import tempfile, marshal @@ -281,7 +282,7 @@ space = self.space pathname = "whatever" mtime = 12345 - cpathname = _testfile(importing.pyc_magic, mtime) + cpathname = _testfile(importing.get_pyc_magic(space), mtime) ret = importing.check_compiled_module(space, pathname, mtime, @@ -297,7 +298,7 @@ os.remove(cpathname) # check for wrong version - cpathname = _testfile(importing.pyc_magic+1, mtime) + cpathname = _testfile(importing.get_pyc_magic(space)+1, mtime) ret = importing.check_compiled_module(space, pathname, mtime, @@ -319,7 +320,7 @@ pathname = "whatever" mtime = 12345 co = compile('x = 42', '?', 'exec') - cpathname = _testfile(importing.pyc_magic, mtime, co) + cpathname = _testfile(importing.get_pyc_magic(space), mtime, co) stream = streamio.open_file_as_stream(cpathname, "r") try: stream.seek(8, 0) @@ -340,7 +341,7 @@ pathname = "whatever" mtime = 12345 co = compile('x = 42', '?', 'exec') - cpathname = _testfile(importing.pyc_magic, mtime, co) + cpathname = _testfile(importing.get_pyc_magic(space), mtime, co) w_modulename = space.wrap('somemodule') stream = streamio.open_file_as_stream(cpathname, "r") try: @@ -460,6 +461,37 @@ ret = space.int_w(w_ret) assert ret == 42 + def test_pyc_magic_changes(self): + # test that the pyc files produced by a space are not reimportable + # from another, if they differ in what opcodes they support + allspaces = [self.space] + for opcodename in self.space.config.objspace.opcodes.getpaths(): + key = 'objspace.opcodes.' + opcodename + space2 = gettestobjspace(**{key: True}) + allspaces.append(space2) + for space1 in allspaces: + for space2 in allspaces: + if space1 is space2: + continue + pathname = "whatever" + mtime = 12345 + co = compile('x = 42', '?', 'exec') + cpathname = _testfile(importing.get_pyc_magic(space1), + mtime, co) + w_modulename = space2.wrap('somemodule') + stream = streamio.open_file_as_stream(cpathname, "r") + try: + w_mod = space2.wrap(Module(space2, w_modulename)) + space2.raises_w(space2.w_ImportError, + importing.load_compiled_module, + space2, + w_modulename, + w_mod, + cpathname, + stream) + finally: + stream.close() + def test_PYTHONPATH_takes_precedence(space): if sys.platform == "win32": From arigo at codespeak.net Tue Mar 20 11:37:17 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 20 Mar 2007 11:37:17 +0100 (CET) Subject: [pypy-svn] r40819 - pypy/dist/pypy/jit Message-ID: <20070320103717.1A54710060@code0.codespeak.net> Author: arigo Date: Tue Mar 20 11:37:15 2007 New Revision: 40819 Modified: pypy/dist/pypy/jit/TODO.txt Log: add TODO item. Modified: pypy/dist/pypy/jit/TODO.txt ============================================================================== --- pypy/dist/pypy/jit/TODO.txt (original) +++ pypy/dist/pypy/jit/TODO.txt Tue Mar 20 11:37:15 2007 @@ -12,6 +12,9 @@ - check that --jit works with --faassen; don't stop at BINARY_ADD! +- why does the timeshifter finds very different number of + graphs every time we run it? + Longer-term ------------------ From mwh at codespeak.net Tue Mar 20 11:38:22 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Tue, 20 Mar 2007 11:38:22 +0100 (CET) Subject: [pypy-svn] r40820 - in pypy/dist/pypy/translator/llvm: . test Message-ID: <20070320103822.2EC9810063@code0.codespeak.net> Author: mwh Date: Tue Mar 20 11:38:22 2007 New Revision: 40820 Modified: pypy/dist/pypy/translator/llvm/database.py pypy/dist/pypy/translator/llvm/test/test_symbolic.py Log: add more explicit tests for CDefinedSymbolics in genllvm, redo support for same and add _we_are_jitted. should fix pypy-llvm builds. Modified: pypy/dist/pypy/translator/llvm/database.py ============================================================================== --- pypy/dist/pypy/translator/llvm/database.py (original) +++ pypy/dist/pypy/translator/llvm/database.py Tue Mar 20 11:38:22 2007 @@ -16,6 +16,7 @@ from pypy.rpython.memory.lladdress import NULL from pypy.rlib.objectmodel import Symbolic, ComputedIntSymbolic from pypy.rlib.objectmodel import CDefinedIntSymbolic +from pypy.rlib import objectmodel log = log.database @@ -505,7 +506,12 @@ # force the ComputedIntSymbolic to become a real integer value now repr = '%d' % value.compute_fn() elif isinstance(value, CDefinedIntSymbolic): - repr = CDEFINED_VALUE[value.expr] + if value is objectmodel.malloc_zero_filled: + repr = '1' + elif value is objectmodel._we_are_jitted: + repr = '0' + else: + raise NotImplementedError("CDefinedIntSymbolic: %r" % (value,)) else: raise NotImplementedError("symbolic: %r" % (value,)) @@ -556,8 +562,3 @@ raise Exception("unsupported offset") return from_, indices, to - -# reprs for specific CDefinedIntSymbolic constants -CDEFINED_VALUE = { - 'MALLOC_ZERO_FILLED': '1', - } Modified: pypy/dist/pypy/translator/llvm/test/test_symbolic.py ============================================================================== --- pypy/dist/pypy/translator/llvm/test/test_symbolic.py (original) +++ pypy/dist/pypy/translator/llvm/test/test_symbolic.py Tue Mar 20 11:38:22 2007 @@ -179,4 +179,19 @@ fn = compile_function(f, [int]) res = fn(5) assert res == 0 - + +def test_we_are_jitted(): + from pypy.rlib import objectmodel + def f(): + return objectmodel.we_are_jitted() + fn = compile_function(f, []) + res = fn() + assert res == False + +def test_malloc_zero_filled(): + from pypy.rlib import objectmodel + def f(): + return objectmodel.malloc_zero_filled + fn = compile_function(f, []) + res = fn() + assert res in [True, False] From pedronis at codespeak.net Tue Mar 20 12:15:30 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Tue, 20 Mar 2007 12:15:30 +0100 (CET) Subject: [pypy-svn] r40821 - pypy/dist/pypy/jit/timeshifter Message-ID: <20070320111530.5C24A1005A@code0.codespeak.net> Author: pedronis Date: Tue Mar 20 12:15:28 2007 New Revision: 40821 Modified: pypy/dist/pypy/jit/timeshifter/rtimeshift.py Log: XXX about fragile assumption Modified: pypy/dist/pypy/jit/timeshifter/rtimeshift.py ============================================================================== --- pypy/dist/pypy/jit/timeshifter/rtimeshift.py (original) +++ pypy/dist/pypy/jit/timeshifter/rtimeshift.py Tue Mar 20 12:15:28 2007 @@ -228,6 +228,8 @@ def ll_genptreq(jitstate, argbox0, argbox1, reverse): builder = jitstate.curbuilder + # XXX this assumption is not completely valid in the presence + # of virtualizable if argbox0.content is not None or argbox1.content is not None: equal = argbox0.content is argbox1.content return rvalue.ll_fromvalue(jitstate, equal ^ reverse) From arigo at codespeak.net Tue Mar 20 12:27:11 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 20 Mar 2007 12:27:11 +0100 (CET) Subject: [pypy-svn] r40823 - in pypy/dist/pypy/translator/goal: . test2 Message-ID: <20070320112711.55DB810061@code0.codespeak.net> Author: arigo Date: Tue Mar 20 12:27:09 2007 New Revision: 40823 Modified: pypy/dist/pypy/translator/goal/app_main.py pypy/dist/pypy/translator/goal/test2/test_app_main.py Log: Fix for the case of "-u -i" options. 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 Mar 20 12:27:09 2007 @@ -267,7 +267,7 @@ runpy.run_module(sys.argv[0], None, '__main__', True) success = run_toplevel(run_it) elif run_stdin: - if sys.stdin.isatty(): + if go_interactive or sys.stdin.isatty(): print_banner() python_startup = os.getenv('PYTHONSTARTUP') if python_startup: Modified: pypy/dist/pypy/translator/goal/test2/test_app_main.py ============================================================================== --- pypy/dist/pypy/translator/goal/test2/test_app_main.py (original) +++ pypy/dist/pypy/translator/goal/test2/test_app_main.py Tue Mar 20 12:27:09 2007 @@ -233,6 +233,19 @@ child.sendline('"pypy.translator.goal.test2.mymodule" in sys.modules') child.expect('False') + def test_options_u_i(self): + import subprocess, select, os + python = sys.executable + pipe = subprocess.Popen([python, app_main, "-u", "-i"], + stdout=subprocess.PIPE, + stdin=subprocess.PIPE, + stderr=subprocess.STDOUT, + bufsize=0, close_fds=True) + iwtd, owtd, ewtd = select.select([pipe.stdout], [], [], 5) + assert iwtd # else we timed out + data = os.read(pipe.stdout.fileno(), 1024) + assert data.startswith('Python') + class TestNonInteractive: @@ -296,24 +309,3 @@ assert 'Name: __main__' in data assert ('File: ' + p) in data assert ('Argv: ' + repr([p, 'extra'])) in data - -def test_option_u(): - py.test.skip("Failing") - import subprocess - from py.__.green.greensock2 import autogreenlet, Timer, Interrupted - from py.__.green.pipe.fd import FDInput - python = "python" - pipe = subprocess.Popen([python, app_main, "-u", "-i"], - stdout=subprocess.PIPE, - stdin=subprocess.PIPE, stderr=subprocess.STDOUT, - bufsize=0, close_fds=True) - read_fd = FDInput(pipe.stdout.fileno(), close=False) - timeout = 5 - timer = Timer(timeout) - try: - data = read_fd.recv(10024) - except Interrupted: - py.test.fail("Timed out reading") - else: - timer.stop() - From arigo at codespeak.net Tue Mar 20 12:38:26 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 20 Mar 2007 12:38:26 +0100 (CET) Subject: [pypy-svn] r40824 - in pypy/dist/pypy/translator/goal: . test2 Message-ID: <20070320113826.2680A1005A@code0.codespeak.net> Author: arigo Date: Tue Mar 20 12:38:25 2007 New Revision: 40824 Modified: pypy/dist/pypy/translator/goal/app_main.py pypy/dist/pypy/translator/goal/test2/test_app_main.py Log: Forgot to handle the case of the PYTHONINSPECT env var. 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 Mar 20 12:38:25 2007 @@ -253,6 +253,9 @@ if hasattr(signal, "SIGPIPE"): signal.signal(signal.SIGPIPE, signal.SIG_IGN) + def is_interactive(): + return go_interactive or os.getenv('PYTHONINSPECT') + success = True try: @@ -267,7 +270,7 @@ runpy.run_module(sys.argv[0], None, '__main__', True) success = run_toplevel(run_it) elif run_stdin: - if go_interactive or sys.stdin.isatty(): + if is_interactive() or sys.stdin.isatty(): print_banner() python_startup = os.getenv('PYTHONSTARTUP') if python_startup: @@ -295,7 +298,7 @@ sys.path.insert(0, scriptdir) success = run_toplevel(execfile, sys.argv[0], mainmodule.__dict__) - if go_interactive or os.getenv('PYTHONINSPECT'): + if is_interactive(): success = run_toplevel(interactive_console, mainmodule) except SystemExit, e: return e.code Modified: pypy/dist/pypy/translator/goal/test2/test_app_main.py ============================================================================== --- pypy/dist/pypy/translator/goal/test2/test_app_main.py (original) +++ pypy/dist/pypy/translator/goal/test2/test_app_main.py Tue Mar 20 12:38:25 2007 @@ -246,6 +246,20 @@ data = os.read(pipe.stdout.fileno(), 1024) assert data.startswith('Python') + def test_options_u_PYTHONINSPECT(self): + import subprocess, select, os + python = sys.executable + pipe = subprocess.Popen([python, app_main, "-u"], + stdout=subprocess.PIPE, + stdin=subprocess.PIPE, + stderr=subprocess.STDOUT, + bufsize=0, close_fds=True, + env={'PYTHONINSPECT': '1'}) + iwtd, owtd, ewtd = select.select([pipe.stdout], [], [], 5) + assert iwtd # else we timed out + data = os.read(pipe.stdout.fileno(), 1024) + assert data.startswith('Python') + class TestNonInteractive: From arigo at codespeak.net Tue Mar 20 12:48:01 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 20 Mar 2007 12:48:01 +0100 (CET) Subject: [pypy-svn] r40826 - pypy/dist/pypy/config Message-ID: <20070320114801.CB3571005A@code0.codespeak.net> Author: arigo Date: Tue Mar 20 12:48:00 2007 New Revision: 40826 Modified: pypy/dist/pypy/config/pypyoption.py Log: Remove optimized_int_add from faassen builds. Modified: pypy/dist/pypy/config/pypyoption.py ============================================================================== --- pypy/dist/pypy/config/pypyoption.py (original) +++ pypy/dist/pypy/config/pypyoption.py Tue Mar 20 12:48:00 2007 @@ -239,7 +239,7 @@ ("objspace.std.withmethodcache", True), # ("objspace.std.withfastslice", True), ("objspace.std.withprebuiltchar", True), - ("objspace.std.optimized_int_add", True), +# ("objspace.std.optimized_int_add", True), ], cmdline="--faassen", negation=False), From mwh at codespeak.net Tue Mar 20 12:51:44 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Tue, 20 Mar 2007 12:51:44 +0100 (CET) Subject: [pypy-svn] r40827 - pypy/dist/pypy/jit/codegen/ppc Message-ID: <20070320115144.8A0E61005A@code0.codespeak.net> Author: mwh Date: Tue Mar 20 12:51:43 2007 New Revision: 40827 Modified: pypy/dist/pypy/jit/codegen/ppc/instruction.py pypy/dist/pypy/jit/codegen/ppc/regalloc.py pypy/dist/pypy/jit/codegen/ppc/rgenop.py Log: remove some unused arguments 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 Tue Mar 20 12:51:43 2007 @@ -97,10 +97,10 @@ def make_loc(self): # should never call this on a CRF, only a BaseCRF raise NotImplementedError - def move_to_gpr(self, allocator, gpr): + def move_to_gpr(self, gpr): bit, negated = self.info return _CRF2GPR(gpr, self.alloc.number*4 + bit, negated) - def move_from_gpr(self, allocator, gpr): + def move_from_gpr(self, gpr): # cmp2info['ne'] self.set_info((2, 1)) return _GPR2CRF(self, gpr) @@ -109,7 +109,7 @@ class CTR(Register): regclass = CT_REGISTER - def move_from_gpr(self, allocator, gpr): + def move_from_gpr(self, gpr): return _GPR2CTR(gpr) ctr = CTR() @@ -552,7 +552,7 @@ allocator.freeregs[loc.regclass].append(loc.alloc) new_loc = allocator._allocate_reg(GP_REGISTER, gv) allocator.lru.append(gv) - allocator.insns.append(loc.move_to_gpr(allocator, new_loc.number)) + allocator.insns.append(loc.move_to_gpr(new_loc.number)) loc = new_loc self.label.arg_locations = [] for gv in self.label.args_gv: @@ -735,7 +735,7 @@ self.stack = stack if not isinstance(self.reg, GPR): assert isinstance(self.reg, CRF) or isinstance(self.reg, CTR) - self.moveinsn = self.reg.move_from_gpr(None, 0) + self.moveinsn = self.reg.move_from_gpr(0) else: self.moveinsn = None def __repr__(self): @@ -770,7 +770,7 @@ r = self.reg.number else: assert isinstance(self.reg, CRF) - self.reg.move_to_gpr(None, 0).emit(asm) + self.reg.move_to_gpr(0).emit(asm) r = 0 #print 'spilling to', self.stack.offset asm.stw(r, rFP, self.stack.offset) Modified: pypy/dist/pypy/jit/codegen/ppc/regalloc.py ============================================================================== --- pypy/dist/pypy/jit/codegen/ppc/regalloc.py (original) +++ pypy/dist/pypy/jit/codegen/ppc/regalloc.py Tue Mar 20 12:51:43 2007 @@ -68,7 +68,7 @@ self.forget(argtospill, reg) spillslot = self.spill_slot() if reg.regclass != GP_REGISTER: - self.insns.append(reg.move_to_gpr(self, 0)) + self.insns.append(reg.move_to_gpr(0)) reg = gprs[0] self.insns.append(Spill(argtospill, reg, spillslot)) self.set(argtospill, spillslot) @@ -181,13 +181,13 @@ else: gpr = rSCRATCH self.insns.append( - argloc.move_to_gpr(self, gpr)) + argloc.move_to_gpr(gpr)) else: gpr = argloc.number if argcls != GP_REGISTER: newargloc = self._allocate_reg(argcls, arg) self.insns.append( - newargloc.move_from_gpr(self, gpr)) + newargloc.move_from_gpr(gpr)) else: if DEBUG_PRINT: print "it was in ", argloc 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 Tue Mar 20 12:51:43 2007 @@ -146,7 +146,7 @@ emit(insn.Move(tarloc, srcloc)) else: assert isinstance(srcloc, insn.CRF) - emit(srcloc.move_to_gpr(self.allocator, tarloc.number)) + emit(srcloc.move_to_gpr(tarloc.number)) elif tarloc.is_register and not srcloc.is_register: emit(insn.Unspill(srcvar, tarloc, srcloc)) elif not tarloc.is_register and srcloc.is_register: @@ -174,9 +174,9 @@ targetlocs = target.arg_locations tarvars = [] - if DEBUG_PRINT: - print targetlocs - print allocator.var2loc +## if DEBUG_PRINT: +## print targetlocs +## print allocator.var2loc for i in range(len(targetlocs)): tloc = targetlocs[i] From pedronis at codespeak.net Tue Mar 20 12:55:04 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Tue, 20 Mar 2007 12:55:04 +0100 (CET) Subject: [pypy-svn] r40828 - in pypy/dist/pypy: jit/hintannotator translator Message-ID: <20070320115504.2F73B10060@code0.codespeak.net> Author: pedronis Date: Tue Mar 20 12:55:03 2007 New Revision: 40828 Modified: pypy/dist/pypy/jit/hintannotator/bookkeeper.py pypy/dist/pypy/translator/driver.py Log: print the number of seen graphs for hint-annotation (the number of specialized copies may vary depending on order issues) Modified: pypy/dist/pypy/jit/hintannotator/bookkeeper.py ============================================================================== --- pypy/dist/pypy/jit/hintannotator/bookkeeper.py (original) +++ pypy/dist/pypy/jit/hintannotator/bookkeeper.py Tue Mar 20 12:55:03 2007 @@ -50,13 +50,16 @@ bk = self.bookkeeper if bk.annotator.policy.look_inside_graph(self.origgraph): graph = copygraph(self.origgraph, varmap=TIMESHIFTMAP) - bk.nonstubgraphcount += 1 + if not self._cache: + bk.nonstuboriggraphcount += 1 if verbose: log(str(graph)) else: log.dot() else: graph = self.build_callback_graph(self.origgraph) + if not self._cache: + bk.stuboriggraphcount += 1 if verbose: log.stub(str(graph)) else: @@ -123,7 +126,8 @@ self.tsgraph_maximal_call_families = UnionFind(TsGraphCallFamily) self.annotator = hannotator self.tsgraphsigs = {} - self.nonstubgraphcount = 0 + self.nonstuboriggraphcount = 0 + self.stuboriggraphcount = 0 if hannotator is not None: # for tests t = hannotator.base_translator self.impurity_analyzer = ImpurityAnalyzer(t) Modified: pypy/dist/pypy/translator/driver.py ============================================================================== --- pypy/dist/pypy/translator/driver.py (original) +++ pypy/dist/pypy/translator/driver.py Tue Mar 20 12:55:03 2007 @@ -362,9 +362,10 @@ [SomeLLAbstractConstant(v.concretetype, {OriginFlags(): True}) for v in self.portal_graph.getargs()]) - count = hannotator.bookkeeper.nonstubgraphcount - self.log.info('Hint-annotated %d graphs (plus %d stubs).' % ( - count, len(hannotator.translator.graphs) - count)) + count = hannotator.bookkeeper.nonstuboriggraphcount + stubcount = hannotator.bookkeeper.stuboriggraphcount + self.log.info("The hint-annotator saw %d graphs" + " (and made stubs for %d graphs)." % (count, stubcount)) n = len(list(hannotator.translator.graphs[0].iterblocks())) self.log.info("portal has %d blocks" % n) self.hannotator = hannotator From mwh at codespeak.net Tue Mar 20 12:58:27 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Tue, 20 Mar 2007 12:58:27 +0100 (CET) Subject: [pypy-svn] r40829 - pypy/dist/pypy/jit/codegen/test Message-ID: <20070320115827.2C2EA10060@code0.codespeak.net> Author: mwh Date: Tue Mar 20 12:58:25 2007 New Revision: 40829 Modified: pypy/dist/pypy/jit/codegen/test/rgenop_tests.py Log: make test a bit more like what happens in practice. still passes :/ 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 Tue Mar 20 12:58:25 2007 @@ -738,7 +738,8 @@ builder.start_writing() gv_base = builder.genop_get_frame_base() - places = [builder.alloc_frame_place(signed_kind) for i in range(100)] + gv_sources = [builder.genop2('int_add', gv_x, rgenop.genconst(i)) for i in range(100)] + places = [builder.alloc_frame_place(signed_kind, gv_s) for gv_s in gv_sources] gv_writer = rgenop.constPrebuiltGlobal(get_writer(places)) builder.genop_call(writertoken, gv_writer, [gv_base, gv_x]) gv_sum = rgenop.genconst(0) From guido at codespeak.net Tue Mar 20 13:02:53 2007 From: guido at codespeak.net (guido at codespeak.net) Date: Tue, 20 Mar 2007 13:02:53 +0100 (CET) Subject: [pypy-svn] r40830 - in pypy/dist/pypy/tool/build: . test testproject Message-ID: <20070320120253.4CD9110053@code0.codespeak.net> Author: guido Date: Tue Mar 20 13:02:51 2007 New Revision: 40830 Modified: pypy/dist/pypy/tool/build/buildserver.py pypy/dist/pypy/tool/build/compile.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/testproject/ (props changed) Log: Improved cleanup of the build tool (fixed ctrl-c and made that builder channels get closed on shutdown), made that zips are streamed gradually over the network rather than sent to the server in full once they're available (hopefully reduces meta server mem usage), made that builds dir in testproject is ignored by svn. Modified: pypy/dist/pypy/tool/build/buildserver.py ============================================================================== --- pypy/dist/pypy/tool/build/buildserver.py (original) +++ pypy/dist/pypy/tool/build/buildserver.py Tue Mar 20 13:02:51 2007 @@ -53,6 +53,8 @@ # end of data is marked by sending a None if chunk is None: break + else: + self.channel.send(None) gotdata = True fp.write(chunk) finally: @@ -118,6 +120,7 @@ def write(self, data): self.loc += len(data) self.channel.send(data) + self.channel.receive() # to make sure stuff is only sent when required def close(self): self.channel.send(None) @@ -169,76 +172,73 @@ print 'connected' try: - try: - while 1: - # receive compile requests - request = channel.receive() - if not isinstance(request, str): - raise ValueError( - 'received wrong unexpected data of type %s' % ( - type(request),) - ) - try: - request = build.BuildRequest.fromstring(request) - except (KeyError, SyntaxError), e: - print ('exception occurred when trying to ' - 'interpret the following request:') - print request - print - print 'going to continue' - continue - accepting = True - for checker in config.client_checkers: - if not checker(request): - if hasattr(checker, 'im_func'): - name = '%s.%s' % (checker.im_class.__name__, - checker.im_func.func_name) - else: - name = checker.func_name - print 'request refused by checker', name - accepting = False - break - channel.send(accepting) - if not accepting: - print 'refusing compilation' - continue - - print 'compilation requested for %s' % (request,) - - # subversion checkout - print 'checking out %s@%s' % (request.svnurl, - request.normalized_rev) - temp = tempdir() - svnwc = py.path.svnwc(temp) - svnwc.checkout(request.svnurl) - svnwc.update(request.normalized_rev) - - try: - print 'starting compilation' - upath, log = compilefunc(svnwc, request.compileinfo, - temp) - except (SystemExit, KeyboardInterrupt): - print 'quitting...' + while 1: + # receive compile requests + request = channel.receive() + if not isinstance(request, str): + raise ValueError( + 'received wrong unexpected data of type %s' % ( + type(request),) + ) + try: + request = build.BuildRequest.fromstring(request) + except (KeyError, SyntaxError), e: + print ('exception occurred when trying to ' + 'interpret the following request:') + print request + print + print 'going to continue' + continue + accepting = True + for checker in config.client_checkers: + if not checker(request): + if hasattr(checker, 'im_func'): + name = '%s.%s' % (checker.im_class.__name__, + checker.im_func.func_name) + else: + name = checker.func_name + print 'request refused by checker', name + accepting = False break + channel.send(accepting) + if not accepting: + print 'refusing compilation' + continue + + print 'compilation requested for %s' % (request,) + + # subversion checkout + print 'checking out %s@%s' % (request.svnurl, + request.normalized_rev) + temp = tempdir() + svnwc = py.path.svnwc(temp) + svnwc.checkout(request.svnurl) + svnwc.update(request.normalized_rev) - if upath: - # send over zip data, end with a None - print 'compilation successful, sending to server' - wrapper = ChannelWrapper(channel) - zip_dir(py.path.local(upath), wrapper) - wrapper.close() - else: - print 'compilation failed, notifying server' - # just send the None - channel.send(None) - - # send over logs - print 'sending log' - channel.send(log) - - print 'done with compilation, waiting for next' - except EOFError: - py.std.sys.exit() + try: + print 'starting compilation' + upath, log = compilefunc(svnwc, request.compileinfo, + temp) + except (SystemExit, KeyboardInterrupt): + print 'quitting...' + break + + if upath: + # send over zip data, end with a None + print 'compilation successful, sending to server' + wrapper = ChannelWrapper(channel) + zip_dir(py.path.local(upath), wrapper) + wrapper.close() + else: + print 'compilation failed, notifying server' + # just send the None + channel.send(None) + + # send over logs + print 'sending log' + channel.send(log) + + print 'done with compilation, waiting for next' finally: channel.close() gw.exit() Modified: pypy/dist/pypy/tool/build/compile.py ============================================================================== --- pypy/dist/pypy/tool/build/compile.py (original) +++ pypy/dist/pypy/tool/build/compile.py Tue Mar 20 13:02:51 2007 @@ -103,6 +103,7 @@ while 1: data = fp.read(bufsize) channel.send(data) + channel.receive() if len(data) < bufsize: channel.send(None) break @@ -123,6 +124,7 @@ try: while 1: data = channel.receive() + channel.send(None) if data is None: break fp.write(data) Modified: pypy/dist/pypy/tool/build/metaserver.py ============================================================================== --- pypy/dist/pypy/tool/build/metaserver.py (original) +++ pypy/dist/pypy/tool/build/metaserver.py Tue Mar 20 13:02:51 2007 @@ -55,7 +55,7 @@ self._queuelock = thread.allocate_lock() self._namelock = thread.allocate_lock() - + def register(self, builder): """ register a builder (instance) """ self._builders.append(builder) @@ -161,10 +161,29 @@ """this keeps the script from dying, and re-tries jobs""" self._channel.send('going to serve') while 1: - time.sleep(self.retry_interval) - self._cleanup_builders() - self._test_waiting() - self._try_queued() + quit = False + try: + command = self._channel.receive() + except EOFError: + quit = True + else: + if command == 'quit': + quit = True + if quit: + self._cleanup() + break + else: + self._cleanup_builders() + self._test_waiting() + self._try_queued() + + def _cleanup(self): + for builder in self._builders: + try: + builder.channel.close() + except EOFError: + pass + self._channel.close() def get_new_buildpath(self, request): path = BuildPath(str(self._buildroot / self._create_filename())) @@ -338,10 +357,24 @@ gw = SshGateway(config.server) channel = init(gw, config) - try: + def main(): while 1: - data = channel.receive() - print data + try: + data = channel.receive() + except EOFError: + break + else: + print data + + thread.start_new_thread(main, ()) + + try: + try: + while 1: + channel.send(None) # ping + time.sleep(1) + except (SystemExit, KeyboardInterrupt): + channel.send('quit') finally: channel.close() gw.exit() 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 Tue Mar 20 13:02:51 2007 @@ -1,3 +1,4 @@ +import time from pypy.tool.build.build import BuildPath class FakeChannel(object): 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 Tue Mar 20 13:02:51 2007 @@ -59,10 +59,18 @@ def test_channelwrapper(): class FakeChannel(object): + i = 0 def __init__(self): self.buffer = [] def send(self, data): self.buffer.append(data) + def receive(self): + import time + while len(self.buffer) < self.i: + time.sleep(0.1) + ret = self.buffer[self.i] + self.i += 1 + return ret c = FakeChannel() cw = buildserver.ChannelWrapper(c) assert cw.tell() == 0 From mwh at codespeak.net Tue Mar 20 13:24:15 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Tue, 20 Mar 2007 13:24:15 +0100 (CET) Subject: [pypy-svn] r40836 - pypy/dist/pypy/doc Message-ID: <20070320122415.EF45110050@code0.codespeak.net> Author: mwh Date: Tue Mar 20 13:24:13 2007 New Revision: 40836 Modified: pypy/dist/pypy/doc/aspect_oriented_programming.txt Log: fix rest Modified: pypy/dist/pypy/doc/aspect_oriented_programming.txt ============================================================================== --- pypy/dist/pypy/doc/aspect_oriented_programming.txt (original) +++ pypy/dist/pypy/doc/aspect_oriented_programming.txt Tue Mar 20 13:24:13 2007 @@ -116,7 +116,7 @@ function/method. Point cuts can be combined using the python binary operators & and -|, which will produce a new PointCut representing respectively the +\|, which will produce a new PointCut representing respectively the intersection and the union of the join points of the original point cuts. @@ -144,18 +144,18 @@ The following code can be used to implement a logging aspect:: -in file ``logging_aspect.py``:: + in file ``logging_aspect.py``: - from aop import Aspect, before, PointCut + from aop import Aspect, before, PointCut - class LoggingAspect: - __metaclass__=Aspect + class LoggingAspect: + __metaclass__=Aspect - # We weave in all methods and functions, except if the name of - # the method starts with an underscore - @before(PointCut(module='.*', klass='.*', func='[^_].*').execution()) - def logStartMethod(self, joinpoint): - print 'in', joinpoint.name() + # We weave in all methods and functions, except if the name of + # the method starts with an underscore + @before(PointCut(module='.*', klass='.*', func='[^_].*').execution()) + def logStartMethod(self, joinpoint): + print 'in', joinpoint.name() In the startup code of the application, before all other imports:: From mwh at codespeak.net Tue Mar 20 14:12:04 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Tue, 20 Mar 2007 14:12:04 +0100 (CET) Subject: [pypy-svn] r40837 - pypy/dist/pypy/doc Message-ID: <20070320131204.0ECB41005A@code0.codespeak.net> Author: mwh Date: Tue Mar 20 14:12:03 2007 New Revision: 40837 Modified: pypy/dist/pypy/doc/index.txt Log: typo Modified: pypy/dist/pypy/doc/index.txt ============================================================================== --- pypy/dist/pypy/doc/index.txt (original) +++ pypy/dist/pypy/doc/index.txt Tue Mar 20 14:12:03 2007 @@ -93,7 +93,7 @@ `bytecode interpreter`_ explains the basic mechanisms of the bytecode interpreter and virtual machine. -`object optimizations`_ describer various alternative object implementations +`object optimizations`_ describes various alternative object implementations (for strings, dicts and lists) in the standard object space. `translation`_ is a detailed overview of our translation process. The From mwh at codespeak.net Tue Mar 20 14:13:26 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Tue, 20 Mar 2007 14:13:26 +0100 (CET) Subject: [pypy-svn] r40838 - pypy/dist/pypy/doc Message-ID: <20070320131326.98AB310061@code0.codespeak.net> Author: mwh Date: Tue Mar 20 14:13:25 2007 New Revision: 40838 Modified: pypy/dist/pypy/doc/index.txt Log: expand an abbreviation Modified: pypy/dist/pypy/doc/index.txt ============================================================================== --- pypy/dist/pypy/doc/index.txt (original) +++ pypy/dist/pypy/doc/index.txt Tue Mar 20 14:13:25 2007 @@ -94,7 +94,7 @@ of the bytecode interpreter and virtual machine. `object optimizations`_ describes various alternative object implementations -(for strings, dicts and lists) in the standard object space. +(for strings, dictionaries 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. From mwh at codespeak.net Tue Mar 20 14:19:13 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Tue, 20 Mar 2007 14:19:13 +0100 (CET) Subject: [pypy-svn] r40839 - pypy/dist/pypy/doc Message-ID: <20070320131913.1E37710069@code0.codespeak.net> Author: mwh Date: Tue Mar 20 14:19:12 2007 New Revision: 40839 Modified: pypy/dist/pypy/doc/index.txt Log: fix rest Modified: pypy/dist/pypy/doc/index.txt ============================================================================== --- pypy/dist/pypy/doc/index.txt (original) +++ pypy/dist/pypy/doc/index.txt Tue Mar 20 14:19:12 2007 @@ -197,8 +197,6 @@ `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 From pedronis at codespeak.net Tue Mar 20 14:56:06 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Tue, 20 Mar 2007 14:56:06 +0100 (CET) Subject: [pypy-svn] r40840 - in pypy/dist/pypy: module/pypyjit translator Message-ID: <20070320135606.3901910069@code0.codespeak.net> Author: pedronis Date: Tue Mar 20 14:56:05 2007 New Revision: 40840 Modified: pypy/dist/pypy/module/pypyjit/portal.py pypy/dist/pypy/translator/geninterplevel.py Log: (arre, pedronis) saner (?) and caching invariant way to skip geninterped graphs when timeshifting. Modified: pypy/dist/pypy/module/pypyjit/portal.py ============================================================================== --- pypy/dist/pypy/module/pypyjit/portal.py (original) +++ pypy/dist/pypy/module/pypyjit/portal.py Tue Mar 20 14:56:05 2007 @@ -20,7 +20,7 @@ mod = func.__module__ or '?' if mod.startswith('pypy.objspace'): return False - if mod.startswith('pypy._cache'): + if '_geninterp_' in func.func_globals # skip all geninterped stuff return False if mod.startswith('pypy.interpreter.astcompiler'): return False Modified: pypy/dist/pypy/translator/geninterplevel.py ============================================================================== --- pypy/dist/pypy/translator/geninterplevel.py (original) +++ pypy/dist/pypy/translator/geninterplevel.py Tue Mar 20 14:56:05 2007 @@ -72,7 +72,7 @@ log = py.log.Producer("geninterp") py.log.setconsumer("geninterp", ansi_log) -GI_VERSION = '1.1.22' # bump this for substantial changes +GI_VERSION = '1.1.23' # bump this for substantial changes # ____________________________________________________________ try: @@ -1399,6 +1399,8 @@ RPY_SEP = "#*************************************************************" RPY_INIT_HEADER = RPY_SEP + ''' +#__name__ = %(modname)r +_geninterp_ = True def init%(modname)s(space): """NOT_RPYTHON""" From hpk at codespeak.net Tue Mar 20 14:59:52 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Tue, 20 Mar 2007 14:59:52 +0100 (CET) Subject: [pypy-svn] r40841 - in pypy/dist: demo pypy/lib pypy/lib/test2 Message-ID: <20070320135952.DFBB410072@code0.codespeak.net> Author: hpk Date: Tue Mar 20 14:59:50 2007 New Revision: 40841 Added: pypy/dist/pypy/lib/test2/test_tputil.py (contents, props changed) pypy/dist/pypy/lib/tputil.py (contents, props changed) Modified: pypy/dist/demo/tp-persistence.py Log: initial draft for some support for transparent proxies, with tests. adapating the demo a bit. Modified: pypy/dist/demo/tp-persistence.py ============================================================================== --- pypy/dist/demo/tp-persistence.py (original) +++ pypy/dist/demo/tp-persistence.py Tue Mar 20 14:59:50 2007 @@ -5,39 +5,26 @@ """ from pypymagic import transparent_proxy, get_transparent_controller -from types import MethodType +from tputil import BaseDispatcher -class PersistentListController(object): +class PListDispatcher(BaseDispatcher): _changeops = ('__iadd__ __imul__ __delitem__ __setitem__ ' - '__delslice__ __setslice__ __init__ ' + '__delslice__ __setslice__ ' 'append extend insert pop remove reverse sort').split() - def __init__(self, obj, storage): - self._obj = obj + def __init__(self, realobj, storage): + parent = super(PListDispatcher, self) + parent.__init__(realobj, list) self._storage = storage - self.persist() - self.proxy = transparent_proxy(list, self.perform) - def persist(self): - self._storage.dump(self._obj) - - def perform(self, operation, *args, **kwargs): - result = getattr(self._obj, operation)(*args, **kwargs) - if operation in self._changeops: - # state was modified, do maximally eager checkpointing + def op_default(self, realmethod, *args, **kwargs): + res = realmethod(*args, **kwargs) + if realmethod.__name__ in self._changeops: self.persist() - if result is self._obj: - # If the result is the proxied list - # return the proxy instead. - result = self.proxy - elif (isinstance(result, MethodType) and - result.im_self is self._obj): - # Convert methods bound to the proxied list - # to methods bound to the proxy. - # This is to have calls to the method become calls - # to perform. - result = MethodType(result.im_func, self.proxy, result.im_class) - return result + return res + + def persist(self): + self._storage.dump(self.realobj) @classmethod def load(cls, storage): @@ -46,6 +33,7 @@ def work_with_list(mylist): assert isinstance(mylist, list) + assert mylist.__class__ is list mylist.append(4) mylist += [5,6,7] @@ -54,7 +42,7 @@ storage = py.path.local("/tmp/mystorage") somelist = [1,2,3] - newlist = PersistentListController(somelist, storage).proxy + newlist = PListDispatcher(somelist, storage).proxyobj # here we may call into application code which can # not detect easily that it is dealing with a persistent @@ -62,6 +50,12 @@ work_with_list(newlist) del somelist, newlist - restoredlist = PersistentListController.load(storage).proxy + restoredlist = PListDispatcher.load(storage).proxyobj print "restored list", restoredlist - print restoredlist == [1,2,3,4,5,6,7] + assert restoredlist == [1,2,3,4,5,6,7] + restoredlist *= 2 + del restoredlist + restoredlist = PListDispatcher.load(storage).proxyobj + print "restored list 2", restoredlist + assert restoredlist == [1,2,3,4,5,6,7] * 2 + Added: pypy/dist/pypy/lib/test2/test_tputil.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/lib/test2/test_tputil.py Tue Mar 20 14:59:50 2007 @@ -0,0 +1,36 @@ +from pypy.conftest import gettestobjspace + +class AppTestTPListproxy: + def setup_class(cls): + cls.space = gettestobjspace(**{"objspace.std.withtproxy": True}) + cls.w_BaseDispatcher = cls.space.appexec([],""" + (): + from tputil import BaseDispatcher + return BaseDispatcher + """) + + def test_listproxy_basic(self): + x = [] + wrapper = self.BaseDispatcher(x) + assert wrapper.realobj is x + l = wrapper.proxyobj + assert type(l) is list + l.append(1) + l.extend([2,3]) + assert l == [1,2,3] + assert x == l + + def test_listproxy_getattribute(self): + disp = self.BaseDispatcher([]) + meth = disp.proxyobj.append + assert meth.im_self == disp.proxyobj + meth = disp.proxyobj.__getattribute__ + assert meth.im_self == disp.proxyobj + + def test_listproxy_hook(self): + class MyBaseDispatcher(self.BaseDispatcher): + def op___getitem__(self, *args, **kwargs): + return 42 + l = MyBaseDispatcher([]).proxyobj + assert l[0] == 42 + assert l[-1] == 42 Added: pypy/dist/pypy/lib/tputil.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/lib/tputil.py Tue Mar 20 14:59:50 2007 @@ -0,0 +1,39 @@ +""" + +application level support module for transparent proxies. +This currently contains a BaseDispatcher class +whose subclasses may define "op_METH" where METH +is the original method operation name for +the proxied object. + +""" +from pypymagic import transparent_proxy +from types import MethodType + +class BaseDispatcher(object): + def __init__(self, realobj, typ=None): + self.realobj = realobj + if typ is None: + typ = type(realobj) + self.proxyobj = transparent_proxy(typ, self.invoke) + + def invoke(self, operation, *args, **kwargs): + """ return result from dispatching to proxied operation. """ + realmethod = getattr(self.realobj, operation) + print "operation", operation + dispmethod = getattr(self, "op_" + operation, None) + if dispmethod is None: + dispmethod = self.op_default + res = dispmethod(realmethod, *args, **kwargs) + return res + + def op___getattribute__(self, realmethod, *args, **kwargs): + res = realmethod(*args, **kwargs) + if (isinstance(res, MethodType) and + res.im_self is self.realobj): + res= MethodType(res.im_func, self.proxyobj, res.im_class) + return res + + def op_default(self, realmethod, *args, **kwargs): + return realmethod(*args, **kwargs) + From arigo at codespeak.net Tue Mar 20 14:59:52 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 20 Mar 2007 14:59:52 +0100 (CET) Subject: [pypy-svn] r40842 - pypy/dist/pypy/annotation Message-ID: <20070320135952.5DD761006F@code0.codespeak.net> Author: arigo Date: Tue Mar 20 14:59:50 2007 New Revision: 40842 Modified: pypy/dist/pypy/annotation/description.py Log: Found a fix for the annotation 'contains' crash in some --jit translations. Modified: pypy/dist/pypy/annotation/description.py ============================================================================== --- pypy/dist/pypy/annotation/description.py (original) +++ pypy/dist/pypy/annotation/description.py Tue Mar 20 14:59:50 2007 @@ -726,10 +726,34 @@ return self.funcdesc def simplify_desc_set(descs): - # if two MethodDescs in the set differ only in their selfclassdefs, - # and if one of the selfclassdefs is a subclass of the other, then - # we can remove the former. This is not just an optimization but - # needed to make contains() happy on SomePBC. + # Some hacking needed to make contains() happy on SomePBC: if the + # set of MethodDescs contains some "redundant" ones, i.e. ones that + # are less general than others already in the set, then kill them. + # This ensures that if 'a' is less general than 'b', then + # SomePBC({a}) union SomePBC({b}) is again SomePBC({b}). + # + # Two cases: + # 1. if two MethodDescs differ in their selfclassdefs, and if one + # of the selfclassdefs is a subclass of the other; + # 2. if two MethodDescs differ in their flags, take the intersection. + + # --- case 2 --- + # only keep the intersection of all the flags, that's good enough + lst = list(descs) + commonflags = lst[0].flags.copy() + for key, value in commonflags.items(): + for desc in lst[1:]: + if key not in desc.flags or desc.flags[key] != value: + del commonflags[key] + break + for desc in lst: + if desc.flags != commonflags: + desc.bookkeeper.getmethoddesc(desc.funcdesc, + desc.originclassdef, + desc.selfclassdefs, + desc.name, + flags) + # --- case 1 --- groups = {} for desc in descs: if desc.selfclassdef is not None: From pedronis at codespeak.net Tue Mar 20 15:07:12 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Tue, 20 Mar 2007 15:07:12 +0100 (CET) Subject: [pypy-svn] r40843 - pypy/dist/pypy/annotation Message-ID: <20070320140712.D3DFF10072@code0.codespeak.net> Author: pedronis Date: Tue Mar 20 15:07:12 2007 New Revision: 40843 Modified: pypy/dist/pypy/annotation/description.py Log: show flags in bound MethodDesc repr. Modified: pypy/dist/pypy/annotation/description.py ============================================================================== --- pypy/dist/pypy/annotation/description.py (original) +++ pypy/dist/pypy/annotation/description.py Tue Mar 20 15:07:12 2007 @@ -689,9 +689,10 @@ return '' % (self.name, self.originclassdef) else: - return '' % (self.name, + return '' % (self.name, self.originclassdef, - self.selfclassdef) + self.selfclassdef, + self.flags) def pycall(self, schedule, args, s_previous_result): from pypy.annotation.model import SomeInstance From arigo at codespeak.net Tue Mar 20 15:10:57 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 20 Mar 2007 15:10:57 +0100 (CET) Subject: [pypy-svn] r40844 - pypy/dist/pypy/annotation Message-ID: <20070320141057.75EE010074@code0.codespeak.net> Author: arigo Date: Tue Mar 20 15:10:56 2007 New Revision: 40844 Modified: pypy/dist/pypy/annotation/description.py Log: Argh. Good spot pedronis. Of course there is no test for this; I need to write one even if it's a mess :-( Modified: pypy/dist/pypy/annotation/description.py ============================================================================== --- pypy/dist/pypy/annotation/description.py (original) +++ pypy/dist/pypy/annotation/description.py Tue Mar 20 15:10:56 2007 @@ -749,11 +749,14 @@ break for desc in lst: if desc.flags != commonflags: - desc.bookkeeper.getmethoddesc(desc.funcdesc, - desc.originclassdef, - desc.selfclassdefs, - desc.name, - flags) + newdesc = desc.bookkeeper.getmethoddesc(desc.funcdesc, + desc.originclassdef, + desc.selfclassdefs, + desc.name, + flags) + del descs[desc] + descs[newdesc] = True + # --- case 1 --- groups = {} for desc in descs: From santagada at codespeak.net Tue Mar 20 16:08:56 2007 From: santagada at codespeak.net (santagada at codespeak.net) Date: Tue, 20 Mar 2007 16:08:56 +0100 (CET) Subject: [pypy-svn] r40845 - pypy/dist/pypy/lang/js Message-ID: <20070320150856.3368710060@code0.codespeak.net> Author: santagada Date: Tue Mar 20 16:08:55 2007 New Revision: 40845 Modified: pypy/dist/pypy/lang/js/interpreter.py Log: global functions Modified: pypy/dist/pypy/lang/js/interpreter.py ============================================================================== --- pypy/dist/pypy/lang/js/interpreter.py (original) +++ pypy/dist/pypy/lang/js/interpreter.py Tue Mar 20 16:08:55 2007 @@ -39,7 +39,10 @@ def evaljs(ctx, args, this): if len(args) >= 1: - code = args[0] + if isinstance(args[0],W_String): + code = args[0] + else: + return args[0] else: code = W_String('') return load_source(code.ToString()).execute(ctx) @@ -59,6 +62,36 @@ print functioncode return evaljs(ctx, [W_String(functioncode),], this) +def parseIntjs(ctx, args, this): + if len(args) < 1: + return W_Number(NaN) + s = args[0].ToString().strip() + if len(args) > 1: + radix = args[1].ToInt32() + else: + radix = 10 + if len(s) >= 2 and (s.startswith('0x') or s.startswith('0X')) : + radix = 16 + s = s[2:] + if s == '' or radix < 2 or radix > 36: + return W_Number(NaN) + try: + n = int(s, radix) + except ValueError: + n = NaN + return W_Number(n) + +def parseFloatjs(ctx, args, this): + if len(args) < 1: + return W_Number(NaN) + s = args[0].ToString().strip() + try: + n = float(s) + except ValueError: + n = NaN + return W_Number(n) + + def printjs(ctx, args, this): writer(",".join([i.GetValue().ToString() for i in args])) return w_Undefined @@ -67,8 +100,19 @@ return W_Object() def isnanjs(ctx, args, this): + if len(args) < 1: + return W_Boolean(True) return W_Boolean(args[0].ToNumber() == NaN) +def isfinitejs(ctx, args, this): + if len(args) < 1: + return W_Boolean(True) + n = args[0].ToNumber() + if n == Infinity or n == -Infinity or n == NaN: + return W_Boolean(False) + else: + return W_Boolean(True) + def booleanjs(ctx, args, this): if len(args) > 0: return W_Boolean(args[0].ToBoolean()) @@ -140,16 +184,16 @@ w_Number.Put('NaN', W_Number(NaN)) w_Number.Put('POSITIVE_INFINITY', W_Number(Infinity)) w_Number.Put('NEGATIVE_INFINITY', W_Number(-Infinity)) - w_Global.Put('Number', w_Number) - w_Global.Put('eval', W_Builtin(evaljs)) - w_Global.Put('print', W_Builtin(printjs)) - w_Global.Put('isNaN', W_Builtin(isnanjs)) - w_Boolean = W_Builtin(booleanjs, Class="Boolean") w_Global.Put('Boolean', W_Builtin(booleanjs, Class="Boolean")) - + w_Global.Put('eval', W_Builtin(evaljs)) + w_Global.Put('print', W_Builtin(printjs)) + w_Global.Put('isNaN', W_Builtin(isnanjs)) + w_Global.Put('isFinite', W_Builtin(isnanjs)) + w_Global.Put('parseFloat', W_Builtin(parseFloatjs)) + w_Global.Put('parseInt', W_Builtin(parseIntjs)) w_Global.Put('NaN', W_Number(NaN)) w_Global.Put('Infinity', W_Number(Infinity)) w_Global.Put('undefined', w_Undefined) From arigo at codespeak.net Tue Mar 20 16:11:11 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 20 Mar 2007 16:11:11 +0100 (CET) Subject: [pypy-svn] r40846 - pypy/dist/pypy/module/pypyjit Message-ID: <20070320151111.8536C10060@code0.codespeak.net> Author: arigo Date: Tue Mar 20 16:11:10 2007 New Revision: 40846 Modified: pypy/dist/pypy/module/pypyjit/portal.py Log: typo Modified: pypy/dist/pypy/module/pypyjit/portal.py ============================================================================== --- pypy/dist/pypy/module/pypyjit/portal.py (original) +++ pypy/dist/pypy/module/pypyjit/portal.py Tue Mar 20 16:11:10 2007 @@ -20,7 +20,7 @@ mod = func.__module__ or '?' if mod.startswith('pypy.objspace'): return False - if '_geninterp_' in func.func_globals # skip all geninterped stuff + if '_geninterp_' in func.func_globals: # skip all geninterped stuff return False if mod.startswith('pypy.interpreter.astcompiler'): return False From hpk at codespeak.net Tue Mar 20 16:39:00 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Tue, 20 Mar 2007 16:39:00 +0100 (CET) Subject: [pypy-svn] r40847 - pypy/extradoc/planning/1.0 Message-ID: <20070320153900.2E5D410053@code0.codespeak.net> Author: hpk Date: Tue Mar 20 16:38:59 2007 New Revision: 40847 Modified: pypy/extradoc/planning/1.0/TODO.txt Log: update after today's sync meeting Modified: pypy/extradoc/planning/1.0/TODO.txt ============================================================================== --- pypy/extradoc/planning/1.0/TODO.txt (original) +++ pypy/extradoc/planning/1.0/TODO.txt Tue Mar 20 16:38:59 2007 @@ -6,8 +6,6 @@ Note: meetings in #pypy-sync every weekday at 4pm (GMT+1) -19 build tool with servers -20 release preps/tasks 21 wp10 documentation and features integrated (2.1, 3.1) 22 WP08 documentation and working examples integrated (12.1, 14.2, 10.1) 23 release status / remaining tasks (14.5, 11.1) @@ -25,20 +23,23 @@ pending issues ----------------------------- -XXX the below are yet-undiscussed suggestions from cfbolz/hpk: - - ensure working Interpreter translation combinations: - pypy-c-stackless/tp/taint/jit/GC-framework/thunk - pypy-cli-tp/taint/thunk + - make a matrix of possible combinations (wp13-report) - (cfbolz) + (cfbolz) - complete/debug jit on powerpc (mwh) - debug jit on intel (arigo/pedronis/arre) + in progress, fixing bugs and improving "is_true" jitting + - integrate and test: - - wp10 docs, examples and code (hpk to chase) + - wp10 + - docs, examples (done) + - fixing "weaver" bugs (agurney) - wp08 docs, examples and code (arigo/pedronis/arre, after debugging) - wp09 docs, examples and code - maybe what we have is good enough? (christian looking into this currently) @@ -55,7 +56,7 @@ (hpk to start here) - describe particularly Javascript-related demos, refine them. - (revisit play1.codespeak.net) + (in-progress, adding more console variations currently, nicer entry page) (fijal) - make transparent proxies more prominent @@ -64,7 +65,7 @@ - write/review documentation - fix bugs if any - probably don't go for "transparent_proxy(type, ...)" :) - + (hpk) - update wp6 docs (object-optimizations.txt) and link to them from getting-started (mwh to coordinate) @@ -72,16 +73,16 @@ - document build tool usages (getting-started?), connect servers with it (guido_w) - - (maybe not) refactor and _document_ pypy special info/features to be in - sys.pypy.version_info * - sys.pypy.translation_options * - - consider where/how to put special builtins ("pypymagic" might not be a good name), suggestions: - - names: pypybuiltin or maybe sys.pypy.* - - document pypybuiltin module + - names: pypybuiltin? decide about name at pypy-sync wednesday + - document pypybuiltin module (add docstrings) - functions should only be there if the according option is enabled (e.g. method cache) - options only relating to py.py should not appear in translated version (unless they work :) (cfbolz) + + - include documentation/entry point for + the JS interpreter (santagada, fijal) + From arigo at codespeak.net Tue Mar 20 16:39:48 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 20 Mar 2007 16:39:48 +0100 (CET) Subject: [pypy-svn] r40848 - in pypy/dist/pypy/annotation: . test Message-ID: <20070320153948.3CF4010063@code0.codespeak.net> Author: arigo Date: Tue Mar 20 16:39:47 2007 New Revision: 40848 Modified: pypy/dist/pypy/annotation/description.py pypy/dist/pypy/annotation/test/test_annrpython.py Log: test, typo, typo. Modified: pypy/dist/pypy/annotation/description.py ============================================================================== --- pypy/dist/pypy/annotation/description.py (original) +++ pypy/dist/pypy/annotation/description.py Tue Mar 20 16:39:47 2007 @@ -751,9 +751,9 @@ if desc.flags != commonflags: newdesc = desc.bookkeeper.getmethoddesc(desc.funcdesc, desc.originclassdef, - desc.selfclassdefs, + desc.selfclassdef, desc.name, - flags) + commonflags) del descs[desc] descs[newdesc] = True 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 Tue Mar 20 16:39:47 2007 @@ -2696,6 +2696,46 @@ s = a.build_types(f, [bool]) assert isinstance(s, annmodel.SomeExternalBuiltin) + def test_instance_with_flags(self): + from pypy.rlib.objectmodel import hint + + class A: + _virtualizable_ = True + class B(A): + def meth(self): + return self + class C(A): + def meth(self): + return self + + def f(n): + x = B() + x = hint(x, access_directly=True) + m = x.meth + for i in range(n): + x = C() + m = x.meth + return x, m, m() + + a = self.RPythonAnnotator() + s = a.build_types(f, [a.bookkeeper.immutablevalue(0)]) + assert isinstance(s.items[0], annmodel.SomeInstance) + assert s.items[0].flags == {'access_directly': True} + assert isinstance(s.items[1], annmodel.SomePBC) + assert len(s.items[1].descriptions) == 1 + assert s.items[1].descriptions.keys()[0].flags == {'access_directly': + True} + assert isinstance(s.items[2], annmodel.SomeInstance) + assert s.items[2].flags == {'access_directly': True} + + a = self.RPythonAnnotator() + s = a.build_types(f, [int]) + assert isinstance(s.items[0], annmodel.SomeInstance) + assert s.items[0].flags == {} + assert isinstance(s.items[1], annmodel.SomePBC) + assert isinstance(s.items[2], annmodel.SomeInstance) + assert s.items[2].flags == {} + def g(n): return [0,1,2,n] From cfbolz at codespeak.net Tue Mar 20 18:21:10 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Tue, 20 Mar 2007 18:21:10 +0100 (CET) Subject: [pypy-svn] r40851 - pypy/dist/pypy/module/pypymagic Message-ID: <20070320172110.BDCFE10061@code0.codespeak.net> Author: cfbolz Date: Tue Mar 20 18:21:09 2007 New Revision: 40851 Modified: pypy/dist/pypy/module/pypymagic/interp_magic.py Log: docstrings Modified: pypy/dist/pypy/module/pypymagic/interp_magic.py ============================================================================== --- pypy/dist/pypy/module/pypymagic/interp_magic.py (original) +++ pypy/dist/pypy/module/pypymagic/interp_magic.py Tue Mar 20 18:21:09 2007 @@ -6,6 +6,8 @@ return space.wrap('%r' % (w_object,)) def isfake(space, w_obj): + """Return whether the argument is faked (stolen from CPython). This is + always False after translation.""" if we_are_translated(): return space.w_False return space.wrap(bool(w_obj.typedef.fakedcpytype)) @@ -19,6 +21,8 @@ pdb.set_trace() def method_cache_counter(space, name): + """Return a tuple (method_cache_hits, method_cache_misses) for calls to + methods with the name.""" assert space.config.objspace.std.withmethodcachecounter ec = space.getexecutioncontext() return space.newtuple([space.newint(ec.method_cache_hits.get(name, 0)), @@ -26,6 +30,7 @@ method_cache_counter.unwrap_spec = [ObjSpace, str] def reset_method_cache_counter(space): + """Reset the method cache counter to zero for all method names.""" assert space.config.objspace.std.withmethodcachecounter ec = space.getexecutioncontext() ec.method_cache_misses = {} From hpk at codespeak.net Tue Mar 20 18:49:50 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Tue, 20 Mar 2007 18:49:50 +0100 (CET) Subject: [pypy-svn] r40853 - in pypy/dist: demo pypy/lib pypy/lib/test2 Message-ID: <20070320174950.3D06E10061@code0.codespeak.net> Author: hpk Date: Tue Mar 20 18:49:49 2007 New Revision: 40853 Modified: pypy/dist/demo/tp-persistence.py pypy/dist/pypy/lib/test2/test_tputil.py pypy/dist/pypy/lib/tputil.py Log: simplified tputil support to provide a "make_proxy" helper that will pass a somewhat nice Invocation object to the provided callback. Thus got rid of having to subclass etc. Adapated demo and added another test. Modified: pypy/dist/demo/tp-persistence.py ============================================================================== --- pypy/dist/demo/tp-persistence.py (original) +++ pypy/dist/demo/tp-persistence.py Tue Mar 20 18:49:49 2007 @@ -5,32 +5,24 @@ """ from pypymagic import transparent_proxy, get_transparent_controller -from tputil import BaseDispatcher +from tputil import make_proxy -class PListDispatcher(BaseDispatcher): - _changeops = ('__iadd__ __imul__ __delitem__ __setitem__ ' +list_changeops = ('__iadd__ __imul__ __delitem__ __setitem__ ' '__delslice__ __setslice__ ' 'append extend insert pop remove reverse sort').split() - def __init__(self, realobj, storage): - parent = super(PListDispatcher, self) - parent.__init__(realobj, list) - self._storage = storage - - def op_default(self, realmethod, *args, **kwargs): - res = realmethod(*args, **kwargs) - if realmethod.__name__ in self._changeops: - self.persist() - return res - - def persist(self): - self._storage.dump(self.realobj) - - @classmethod - def load(cls, storage): - obj = storage.load() - return cls(obj, storage) - +def make_plist(instance, storage): + def perform(invocation): + res = invocation.perform() + if invocation.opname in list_changeops: + storage.dump(instance) + return res + return make_proxy(instance, perform, typ=list) + +def get_plist(storage): + obj = storage.load() + return make_plist(obj, storage) + def work_with_list(mylist): assert isinstance(mylist, list) assert mylist.__class__ is list @@ -41,21 +33,19 @@ import py storage = py.path.local("/tmp/mystorage") - somelist = [1,2,3] - newlist = PListDispatcher(somelist, storage).proxyobj - + plist = make_plist([1,2,3], storage) # here we may call into application code which can - # not detect easily that it is dealing with a persistent - # object - work_with_list(newlist) - del somelist, newlist + # not detect easily that it is dealing with a + # transparently persistent list + work_with_list(plist) + del plist - restoredlist = PListDispatcher.load(storage).proxyobj + restoredlist = get_plist(storage) print "restored list", restoredlist assert restoredlist == [1,2,3,4,5,6,7] restoredlist *= 2 del restoredlist - restoredlist = PListDispatcher.load(storage).proxyobj + restoredlist = get_plist(storage) print "restored list 2", restoredlist assert restoredlist == [1,2,3,4,5,6,7] * 2 Modified: pypy/dist/pypy/lib/test2/test_tputil.py ============================================================================== --- pypy/dist/pypy/lib/test2/test_tputil.py (original) +++ pypy/dist/pypy/lib/test2/test_tputil.py Tue Mar 20 18:49:49 2007 @@ -3,34 +3,39 @@ class AppTestTPListproxy: def setup_class(cls): cls.space = gettestobjspace(**{"objspace.std.withtproxy": True}) - cls.w_BaseDispatcher = cls.space.appexec([],""" - (): - from tputil import BaseDispatcher - return BaseDispatcher - """) def test_listproxy_basic(self): - x = [] - wrapper = self.BaseDispatcher(x) - assert wrapper.realobj is x - l = wrapper.proxyobj - assert type(l) is list + from tputil import make_proxy + record = [] + def func(invocation): + record.append(invocation) + return invocation.perform() + l = make_proxy([], func) l.append(1) - l.extend([2,3]) - assert l == [1,2,3] - assert x == l - - def test_listproxy_getattribute(self): - disp = self.BaseDispatcher([]) - meth = disp.proxyobj.append - assert meth.im_self == disp.proxyobj - meth = disp.proxyobj.__getattribute__ - assert meth.im_self == disp.proxyobj + assert len(record) == 2 + i1, i2 = record + assert i1.opname == '__getattribute__' + assert i2.opname == 'append' - def test_listproxy_hook(self): - class MyBaseDispatcher(self.BaseDispatcher): - def op___getitem__(self, *args, **kwargs): - return 42 - l = MyBaseDispatcher([]).proxyobj - assert l[0] == 42 - assert l[-1] == 42 + def test_proxy_double(self): + from tputil import make_proxy + r1 = [] + r2 = [] + def func1(invocation): + r1.append(invocation) + return invocation.perform() + def func2(invocation): + r2.append(invocation) + return invocation.perform() + + l = make_proxy([], func1) + l2 = make_proxy(l, func2) + assert not r1 and not r2 + l2.append + assert len(r2) == 1 + assert r2[0].opname == '__getattribute__' + assert len(r1) == 2 + assert r1[0].opname == '__getattribute__' + assert r1[0].args[0] == '__getattribute__' + assert r1[1].opname == '__getattribute__' + assert r1[1].args[0] == 'append' Modified: pypy/dist/pypy/lib/tputil.py ============================================================================== --- pypy/dist/pypy/lib/tputil.py (original) +++ pypy/dist/pypy/lib/tputil.py Tue Mar 20 18:49:49 2007 @@ -10,30 +10,32 @@ from pypymagic import transparent_proxy from types import MethodType -class BaseDispatcher(object): - def __init__(self, realobj, typ=None): - self.realobj = realobj - if typ is None: - typ = type(realobj) - self.proxyobj = transparent_proxy(typ, self.invoke) +def make_proxy(instance, invokefunc=None, typ=None): + if typ is None: + typ = type(instance) + def perform(opname, *args, **kwargs): + invocation = Invocation(tp, instance, opname, args, kwargs) + return invokefunc(invocation) + tp = transparent_proxy(typ, perform) + return tp - def invoke(self, operation, *args, **kwargs): - """ return result from dispatching to proxied operation. """ - realmethod = getattr(self.realobj, operation) - print "operation", operation - dispmethod = getattr(self, "op_" + operation, None) - if dispmethod is None: - dispmethod = self.op_default - res = dispmethod(realmethod, *args, **kwargs) - return res +class Invocation(object): + def __init__(self, proxyobj, realobj, opname, args, kwargs): + self.proxyobj = proxyobj + self.realobj = realobj + self.opname = opname + self.args = args + self.kwargs = kwargs + self.realmethod = getattr(realobj, opname) - def op___getattribute__(self, realmethod, *args, **kwargs): - res = realmethod(*args, **kwargs) - if (isinstance(res, MethodType) and - res.im_self is self.realobj): - res= MethodType(res.im_func, self.proxyobj, res.im_class) - return res - - def op_default(self, realmethod, *args, **kwargs): - return realmethod(*args, **kwargs) + def perform(self): + res = self.realmethod(*self.args, **self.kwargs) + if self.opname == "__getattribute__": + if (isinstance(res, MethodType) and + res.im_self is self.realobj): + res = MethodType(res.im_func, self.proxyobj, res.im_class) + return res + def __repr__(self): + return " Author: ac Date: Tue Mar 20 19:25:01 2007 New Revision: 40856 Modified: pypy/dist/pypy/module/pypyjit/portal.py pypy/dist/pypy/module/pypyjit/test/test_pypy_c.py Log: (pedronis, arre) Add support for more operators (and don't timeshift unsusefull parts). Add a test. Modified: pypy/dist/pypy/module/pypyjit/portal.py ============================================================================== --- pypy/dist/pypy/module/pypyjit/portal.py (original) +++ pypy/dist/pypy/module/pypyjit/portal.py Tue Mar 20 19:25:01 2007 @@ -88,6 +88,7 @@ def timeshift_graphs(t, portal_graph, log): + import pypy result_graphs = {} bk = t.annotator.bookkeeper @@ -114,59 +115,62 @@ def dontsee(func): result_graphs[_graph(func)] = False + def seebinary(opname): + name2 = name1 = opname[:3].lower() + if name1 in ('and', 'or'): + name1 += '_' + descr_impl = getattr(pypy.objspace.descroperation.DescrOperation, name1) + obj_impl = getattr(pypy.objspace.std.intobject, name2 + '__Int_Int') + seepath(getattr(pypy.interpreter.pyframe.PyFrame, 'BINARY_'+ opname), + descr_impl, + obj_impl) + seepath(descr_impl, + pypy.objspace.std.typeobject.W_TypeObject.is_heaptype) + descr_impl = getattr(pypy.objspace.descroperation.DescrOperation, + 'inplace_' + name2) + seepath(getattr(pypy.interpreter.pyframe.PyFrame, 'INPLACE_'+ opname), + descr_impl, + obj_impl) + seepath(descr_impl, + pypy.objspace.std.typeobject.W_TypeObject.is_heaptype) + + def seeunary(opname, name=None): + if name is None: + name = opname.lower() + descr_impl = getattr(pypy.objspace.descroperation.DescrOperation, name) + seepath(getattr(pypy.interpreter.pyframe.PyFrame, 'UNARY_' + opname), + descr_impl, + getattr(pypy.objspace.std.intobject, name + '__Int')) + seepath(descr_impl, + pypy.objspace.std.typeobject.W_TypeObject.is_heaptype) + + def seecmp(name): + descr_impl = getattr(pypy.objspace.descroperation.DescrOperation, name) + seepath(pypy.interpreter.pyframe.PyFrame.COMPARE_OP, + descr_impl, + getattr(pypy.objspace.std.intobject, name +'__Int_Int')) + seepath(descr_impl, + pypy.objspace.std.typeobject.W_TypeObject.is_heaptype) + # -------------------- - import pypy - seepath(pypy.interpreter.pyframe.PyFrame.BINARY_ADD, - pypy.objspace.descroperation.DescrOperation.add, - pypy.objspace.std.intobject.add__Int_Int, - pypy.objspace.std.inttype.wrapint, - pypy.objspace.std.intobject.W_IntObject.__init__) - seepath(pypy.interpreter.pyframe.PyFrame.BINARY_SUBTRACT, - pypy.objspace.descroperation.DescrOperation.sub, - pypy.objspace.std.intobject.sub__Int_Int) - seepath(pypy.interpreter.pyframe.PyFrame.BINARY_MULTIPLY, - pypy.objspace.descroperation.DescrOperation.mul, - pypy.objspace.std.intobject.mul__Int_Int) - seepath(pypy.interpreter.pyframe.PyFrame.BINARY_AND, - pypy.objspace.descroperation.DescrOperation.and_, - pypy.objspace.std.intobject.and__Int_Int) - seepath(pypy.interpreter.pyframe.PyFrame.BINARY_OR, - pypy.objspace.descroperation.DescrOperation.or_, - pypy.objspace.std.intobject.or__Int_Int) - seepath(pypy.interpreter.pyframe.PyFrame.BINARY_XOR, - pypy.objspace.descroperation.DescrOperation.xor, - pypy.objspace.std.intobject.xor__Int_Int) - seepath(pypy.interpreter.pyframe.PyFrame.COMPARE_OP, - pypy.objspace.descroperation.DescrOperation.lt, - pypy.objspace.std.intobject.lt__Int_Int) - seepath(pypy.interpreter.pyframe.PyFrame.COMPARE_OP, - pypy.objspace.descroperation.DescrOperation.le, - pypy.objspace.std.intobject.le__Int_Int) - seepath(pypy.interpreter.pyframe.PyFrame.COMPARE_OP, - pypy.objspace.descroperation.DescrOperation.eq, - pypy.objspace.std.intobject.eq__Int_Int) - seepath(pypy.interpreter.pyframe.PyFrame.COMPARE_OP, - pypy.objspace.descroperation.DescrOperation.ne, - pypy.objspace.std.intobject.ne__Int_Int) - seepath(pypy.interpreter.pyframe.PyFrame.COMPARE_OP, - pypy.objspace.descroperation.DescrOperation.gt, - pypy.objspace.std.intobject.gt__Int_Int) - seepath(pypy.interpreter.pyframe.PyFrame.COMPARE_OP, - pypy.objspace.descroperation.DescrOperation.ge, - pypy.objspace.std.intobject.ge__Int_Int) + for binop in 'ADD SUBTRACT MULTIPLY AND OR XOR'.split(): + seebinary(binop) + for cmpname in 'lt le eq ne ge gt'.split(): + seecmp(cmpname) + seepath(pypy.interpreter.pyframe.PyFrame.UNARY_NOT, + pypy.objspace.std.Space.not_) + seeunary('INVERT') + seeunary('POSITIVE', 'pos') + seeunary('NEGATIVE', 'neg') + seepath(pypy.objspace.descroperation._invoke_binop, pypy.objspace.descroperation._check_notimplemented) + seepath(pypy.objspace.std.intobject.add__Int_Int, + pypy.objspace.std.inttype.wrapint, + pypy.objspace.std.intobject.W_IntObject.__init__) seepath(pypy.objspace.descroperation.DescrOperation.add, pypy.objspace.std.Space.type, pypy.objspace.std.Space.gettypeobject) - #seepath(pypy.objspace.descroperation.DescrOperation.xxx, - # pypy.objspace.std.typeobject.W_TypeObject.lookup, - # pypy.objspace.std.typeobject.W_TypeObject.getdictvalue_w) - seepath(pypy.objspace.descroperation.DescrOperation.add, - pypy.objspace.std.typeobject.W_TypeObject.lookup_where, - pypy.objspace.std.typeobject.W_TypeObject.getdictvalue_w) - seepath(pypy.objspace.std.typeobject.W_TypeObject.lookup_where, - pypy.objspace.std.typeobject.W_TypeObject.is_heaptype) seepath(pypy.objspace.descroperation.DescrOperation.add, pypy.objspace.std.Space.is_w) dontsee(pypy.interpreter.pyframe.PyFrame.execute_frame) Modified: pypy/dist/pypy/module/pypyjit/test/test_pypy_c.py ============================================================================== --- pypy/dist/pypy/module/pypyjit/test/test_pypy_c.py (original) +++ pypy/dist/pypy/module/pypyjit/test/test_pypy_c.py Tue Mar 20 19:25:01 2007 @@ -109,3 +109,15 @@ return richards.main(iterations = 1) ''' % (sys.path,), [([], 42)]) + +def app_test_inplace_op(): + run_source(''' + def main(x, y): + r = 5 + r += x + r += -y + return r + ''', [([17, 3], 19), + ([sys.maxint-3, 5], long(sys.maxint - 3)), + ([17, -sys.maxint - 1], sys.maxint + 23) + ]) From ac at codespeak.net Tue Mar 20 19:28:49 2007 From: ac at codespeak.net (ac at codespeak.net) Date: Tue, 20 Mar 2007 19:28:49 +0100 (CET) Subject: [pypy-svn] r40857 - pypy/dist/pypy/module/pypyjit/test Message-ID: <20070320182849.37C3110072@code0.codespeak.net> Author: ac Date: Tue Mar 20 19:28:48 2007 New Revision: 40857 Modified: pypy/dist/pypy/module/pypyjit/test/test_pypy_c2.py Log: Fix typo. Modified: pypy/dist/pypy/module/pypyjit/test/test_pypy_c2.py ============================================================================== --- pypy/dist/pypy/module/pypyjit/test/test_pypy_c2.py (original) +++ pypy/dist/pypy/module/pypyjit/test/test_pypy_c2.py Tue Mar 20 19:28:48 2007 @@ -5,7 +5,7 @@ def setup_module(mod): if option.pypy_c is None: - py.test.skip("pass --pypy_c!") + py.test.skip("pass --pypy-c!") mod.tmpdir = udir.join('pypy-jit') mod.tmpdir.ensure(dir=1) mod.counter = 0 From arigo at codespeak.net Tue Mar 20 19:33:01 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 20 Mar 2007 19:33:01 +0100 (CET) Subject: [pypy-svn] r40858 - in pypy/dist/pypy/rpython: lltypesystem test Message-ID: <20070320183301.A1A4E10078@code0.codespeak.net> Author: arigo Date: Tue Mar 20 19:33:00 2007 New Revision: 40858 Modified: pypy/dist/pypy/rpython/lltypesystem/rdict.py pypy/dist/pypy/rpython/test/test_rdict.py Log: The rdict logic was too clever. Unfortunately some tests check the details of the cleverness, so here is an attempt to fix the clever bit. Added stress-tests for more combinations. Modified: pypy/dist/pypy/rpython/lltypesystem/rdict.py ============================================================================== --- pypy/dist/pypy/rpython/lltypesystem/rdict.py (original) +++ pypy/dist/pypy/rpython/lltypesystem/rdict.py Tue Mar 20 19:33:00 2007 @@ -92,30 +92,47 @@ s_value = self.dictvalue.s_value nullkeymarker = not self.key_repr.can_ll_be_null(s_key) nullvaluemarker = not self.value_repr.can_ll_be_null(s_value) + dummykeyobj = self.key_repr.get_ll_dummyval_obj(self.rtyper, + s_key) + dummyvalueobj = self.value_repr.get_ll_dummyval_obj(self.rtyper, + s_value) - if nullkeymarker: + # * the state of the entry - trying to encode it as dummy objects + if nullkeymarker and dummykeyobj: + # all the state can be encoded in the key entrymeths['everused'] = ll_everused_from_key - elif nullvaluemarker: - entrymeths['everused'] = ll_everused_from_value - else: - entryfields.append(("f_everused", lltype.Bool)) - entrymeths['everused'] = ll_everused_from_flag - - # * if the key or the value can also contain a "dummy" non-null - # marker, we use it for deleted entries. - rtyper = self.rtyper - dummy_obj = self.key_repr.get_ll_dummyval_obj(rtyper, s_key) - if dummy_obj: - entrymeths['dummy_obj'] = dummy_obj + entrymeths['dummy_obj'] = dummykeyobj entrymeths['valid'] = ll_valid_from_key entrymeths['mark_deleted'] = ll_mark_deleted_in_key # the key is overwritten by 'dummy' when the entry is deleted entrymeths['must_clear_key'] = False + + elif nullvaluemarker and dummyvalueobj: + # all the state can be encoded in the value + entrymeths['everused'] = ll_everused_from_value + entrymeths['dummy_obj'] = dummyvalueobj + entrymeths['valid'] = ll_valid_from_value + entrymeths['mark_deleted'] = ll_mark_deleted_in_value + # value is overwritten by 'dummy' when entry is deleted + entrymeths['must_clear_value'] = False + else: - dummy_obj = self.value_repr.get_ll_dummyval_obj(rtyper, - s_value) - if dummy_obj: - entrymeths['dummy_obj'] = dummy_obj + # we need a flag to know if the entry was ever used + # (we cannot use a NULL as a marker for this, because + # the key and value will be reset to NULL to clear their + # reference) + entryfields.append(("f_everused", lltype.Bool)) + entrymeths['everused'] = ll_everused_from_flag + + # can we still rely on a dummy obj to mark deleted entries? + if dummykeyobj: + entrymeths['dummy_obj'] = dummykeyobj + entrymeths['valid'] = ll_valid_from_key + entrymeths['mark_deleted'] = ll_mark_deleted_in_key + # key is overwritten by 'dummy' when entry is deleted + entrymeths['must_clear_key'] = False + elif dummyvalueobj: + entrymeths['dummy_obj'] = dummyvalueobj entrymeths['valid'] = ll_valid_from_value entrymeths['mark_deleted'] = ll_mark_deleted_in_value # value is overwritten by 'dummy' when entry is deleted Modified: pypy/dist/pypy/rpython/test/test_rdict.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_rdict.py (original) +++ pypy/dist/pypy/rpython/test/test_rdict.py Tue Mar 20 19:33:00 2007 @@ -602,55 +602,6 @@ # ____________________________________________________________ - def test_stress(self): - from pypy.annotation.dictdef import DictKey, DictValue - from pypy.annotation import model as annmodel - dictrepr = rdict.DictRepr(None, rint.signed_repr, rint.signed_repr, - DictKey(None, annmodel.SomeInteger()), - DictValue(None, annmodel.SomeInteger())) - dictrepr.setup() - l_dict = rdict.ll_newdict(dictrepr.DICT) - referencetable = [None] * 400 - referencelength = 0 - value = 0 - - def complete_check(): - for n, refvalue in zip(range(len(referencetable)), referencetable): - try: - gotvalue = rdict.ll_dict_getitem(l_dict, n) - except KeyError: - assert refvalue is None - else: - assert gotvalue == refvalue - - for x in not_really_random(): - n = int(x*100.0) # 0 <= x < 400 - op = repr(x)[-1] - if op <= '2' and referencetable[n] is not None: - rdict.ll_dict_delitem(l_dict, n) - referencetable[n] = None - referencelength -= 1 - elif op <= '6': - rdict.ll_dict_setitem(l_dict, n, value) - if referencetable[n] is None: - referencelength += 1 - referencetable[n] = value - value += 1 - else: - try: - gotvalue = rdict.ll_dict_getitem(l_dict, n) - except KeyError: - assert referencetable[n] is None - else: - assert gotvalue == referencetable[n] - if 1.38 <= x <= 1.39: - complete_check() - print 'current dict length:', referencelength - assert l_dict.num_items == referencelength - complete_check() - - # ____________________________________________________________ - def test_opt_nullkeymarker(self): def f(): d = {"hello": None} @@ -759,3 +710,120 @@ except RuntimeError: return False assert self.interpret(func, []) == False + + # ____________________________________________________________ + +class TestStress: + + def test_stress(self): + from pypy.annotation.dictdef import DictKey, DictValue + from pypy.annotation import model as annmodel + dictrepr = rdict.DictRepr(None, rint.signed_repr, rint.signed_repr, + DictKey(None, annmodel.SomeInteger()), + DictValue(None, annmodel.SomeInteger())) + dictrepr.setup() + l_dict = rdict.ll_newdict(dictrepr.DICT) + referencetable = [None] * 400 + referencelength = 0 + value = 0 + + def complete_check(): + for n, refvalue in zip(range(len(referencetable)), referencetable): + try: + gotvalue = rdict.ll_dict_getitem(l_dict, n) + except KeyError: + assert refvalue is None + else: + assert gotvalue == refvalue + + for x in not_really_random(): + n = int(x*100.0) # 0 <= x < 400 + op = repr(x)[-1] + if op <= '2' and referencetable[n] is not None: + rdict.ll_dict_delitem(l_dict, n) + referencetable[n] = None + referencelength -= 1 + elif op <= '6': + rdict.ll_dict_setitem(l_dict, n, value) + if referencetable[n] is None: + referencelength += 1 + referencetable[n] = value + value += 1 + else: + try: + gotvalue = rdict.ll_dict_getitem(l_dict, n) + except KeyError: + assert referencetable[n] is None + else: + assert gotvalue == referencetable[n] + if 1.38 <= x <= 1.39: + complete_check() + print 'current dict length:', referencelength + assert l_dict.num_items == referencelength + complete_check() + + def test_stress_2(self): + yield self.stress_combination, True, False + yield self.stress_combination, False, True + yield self.stress_combination, False, False + yield self.stress_combination, True, True + + def stress_combination(self, key_can_be_none, value_can_be_none): + from pypy.rpython.lltypesystem.rstr import string_repr + from pypy.annotation.dictdef import DictKey, DictValue + from pypy.annotation import model as annmodel + + print + print "Testing combination with can_be_None: keys %s, values %s" % ( + key_can_be_none, value_can_be_none) + + class PseudoRTyper: + cache_dummy_values = {} + dictrepr = rdict.DictRepr(PseudoRTyper(), string_repr, string_repr, + DictKey(None, annmodel.SomeString(key_can_be_none)), + DictValue(None, annmodel.SomeString(value_can_be_none))) + dictrepr.setup() + print dictrepr.lowleveltype + for key, value in dictrepr.DICTENTRY._adtmeths.items(): + print ' %s = %s' % (key, value) + l_dict = rdict.ll_newdict(dictrepr.DICT) + referencetable = [None] * 400 + referencelength = 0 + values = not_really_random() + keytable = [string_repr.convert_const("foo%d" % n) + for n in range(len(referencetable))] + + def complete_check(): + for n, refvalue in zip(range(len(referencetable)), referencetable): + try: + gotvalue = rdict.ll_dict_getitem(l_dict, keytable[n]) + except KeyError: + assert refvalue is None + else: + assert gotvalue == refvalue + + for x in not_really_random(): + n = int(x*100.0) # 0 <= x < 400 + op = repr(x)[-1] + if op <= '2' and referencetable[n] is not None: + rdict.ll_dict_delitem(l_dict, keytable[n]) + referencetable[n] = None + referencelength -= 1 + elif op <= '6': + ll_value = string_repr.convert_const(str(values.next())) + rdict.ll_dict_setitem(l_dict, keytable[n], ll_value) + if referencetable[n] is None: + referencelength += 1 + referencetable[n] = ll_value + else: + try: + gotvalue = rdict.ll_dict_getitem(l_dict, keytable[n]) + except KeyError: + assert referencetable[n] is None + else: + assert gotvalue == referencetable[n] + if 1.38 <= x <= 1.39: + complete_check() + print 'current dict length:', referencelength + assert l_dict.num_items == referencelength + complete_check() From ac at codespeak.net Tue Mar 20 19:42:30 2007 From: ac at codespeak.net (ac at codespeak.net) Date: Tue, 20 Mar 2007 19:42:30 +0100 (CET) Subject: [pypy-svn] r40859 - pypy/dist/pypy/module/pypyjit/test Message-ID: <20070320184230.646E410078@code0.codespeak.net> Author: ac Date: Tue Mar 20 19:42:29 2007 New Revision: 40859 Removed: pypy/dist/pypy/module/pypyjit/test/test_pypy_c2.py Modified: pypy/dist/pypy/module/pypyjit/test/test_pypy_c.py Log: (pedronis, arre) Refactor tests. Modified: pypy/dist/pypy/module/pypyjit/test/test_pypy_c.py ============================================================================== --- pypy/dist/pypy/module/pypyjit/test/test_pypy_c.py (original) +++ pypy/dist/pypy/module/pypyjit/test/test_pypy_c.py Tue Mar 20 19:42:29 2007 @@ -3,121 +3,134 @@ import py import sys, os -def setup_module(mod): - if not option.runappdirect: - py.test.skip("meant only for pypy-c") - mod.space = gettestobjspace(usemodules=['pypyjit']) - mod.tmpdir = udir.join('pypy-jit') - mod.tmpdir.ensure(dir=1) - mod.counter = 0 - - -def run_source(source, testcases): - global counter - source = py.code.Source(source) - filepath = tmpdir.join('case%d.py' % counter) - logfilepath = filepath.new(ext='.log') - counter += 1 - f = filepath.open('w') - print >> f, source - # some support code... - print >> f, py.code.Source(""" - import sys, pypyjit - pypyjit.enable(main.func_code) - - def check(args, expected): - print >> sys.stderr, 'trying:', args - result = main(*args) - print >> sys.stderr, 'got:', repr(result) - assert result == expected - assert type(result) is type(expected) - """) - for testcase in testcases * 2: - print >> f, "check(%r, %r)" % testcase - print >> f, "print 'OK :-)'" - f.close() - - # we don't have os.popen() yet on pypy-c... - if sys.platform.startswith('win'): - py.test.skip("XXX this is not Windows-friendly") - child_stdin, child_stdout = os.popen2('PYPYJITLOG="%s" "%s" "%s"' % ( - logfilepath, sys.executable, filepath)) - child_stdin.close() - result = child_stdout.read() - child_stdout.close() - assert result - assert result.splitlines()[-1].strip() == 'OK :-)' - assert logfilepath.check() - - -def app_test_f(): - run_source(""" - def main(n): - return (n+5)+6 - """, - [([100], 111), - ([-5], 6), - ([sys.maxint], sys.maxint+11), - ([-sys.maxint-5], long(-sys.maxint+6)), - ]) - -def app_test_f1(): - run_source(''' - def main(n): - "Arbitrary test function." - i = 0 - x = 1 - while i 1: - r *= n - n -= 1 - return r - ''', - [([5], 120), - ([20], 2432902008176640000L)]) - -def app_test_factorialrec(): - run_source(''' - def main(n): - if n > 1: - return n * main(n-1) - else: - return 1 - ''', - [([5], 120), - ([20], 2432902008176640000L)]) - -def app_test_richards(): - run_source(''' - import sys; sys.path[:] = %r - from pypy.translator.goal import richards - - def main(): - return richards.main(iterations = 1) - ''' % (sys.path,), - [([], 42)]) - -def app_test_inplace_op(): - run_source(''' - def main(x, y): - r = 5 - r += x - r += -y - return r - ''', [([17, 3], 19), - ([sys.maxint-3, 5], long(sys.maxint - 3)), - ([17, -sys.maxint - 1], sys.maxint + 23) - ]) +class PyPyCJITTests(object): + def run_source(self, source, testcases): + source = py.code.Source(source) + filepath = self.tmpdir.join('case%d.py' % self.counter) + logfilepath = filepath.new(ext='.log') + self.counter += 1 + f = filepath.open('w') + print >> f, source + # some support code... + print >> f, py.code.Source(""" + import sys, pypyjit + pypyjit.enable(main.func_code) + + def check(args, expected): + print >> sys.stderr, 'trying:', args + result = main(*args) + print >> sys.stderr, 'got:', repr(result) + assert result == expected + assert type(result) is type(expected) + """) + for testcase in testcases * 2: + print >> f, "check(%r, %r)" % testcase + print >> f, "print 'OK :-)'" + f.close() + + # we don't have os.popen() yet on pypy-c... + if sys.platform.startswith('win'): + py.test.skip("XXX this is not Windows-friendly") + child_stdin, child_stdout = os.popen2('PYPYJITLOG="%s" "%s" "%s"' % ( + logfilepath, self.pypy_c, filepath)) + child_stdin.close() + result = child_stdout.read() + child_stdout.close() + assert result + assert result.splitlines()[-1].strip() == 'OK :-)' + assert logfilepath.check() + + + def test_f(self): + self.run_source(""" + def main(n): + return (n+5)+6 + """, + [([100], 111), + ([-5], 6), + ([sys.maxint], sys.maxint+11), + ([-sys.maxint-5], long(-sys.maxint+6)), + ]) + + def test_f1(self): + self.run_source(''' + def main(n): + "Arbitrary test function." + i = 0 + x = 1 + while i 1: + r *= n + n -= 1 + return r + ''', + [([5], 120), + ([20], 2432902008176640000L)]) + + def test_factorialrec(self): + self.run_source(''' + def main(n): + if n > 1: + return n * main(n-1) + else: + return 1 + ''', + [([5], 120), + ([20], 2432902008176640000L)]) + + def test_richards(self): + self.run_source(''' + import sys; sys.path[:] = %r + from pypy.translator.goal import richards + + def main(): + return richards.main(iterations = 1) + ''' % (sys.path,), + [([], 42)]) + + def test_inplace_op(self): + self.run_source(''' + def main(x, y): + r = 5 + r += x + r += -y + return r + ''', [([17, 3], 19), + ([sys.maxint-3, 5], long(sys.maxint - 3)), + ([17, -sys.maxint - 1], sys.maxint + 23) + ]) + +class AppTestJIT(PyPyCJITTests): + def setup_class(cls): + if not option.runappdirect: + py.test.skip("meant only for pypy-c") + cls.space = gettestobjspace(usemodules=['pypyjit']) + cls.tmpdir = udir.join('pypy-jit') + cls.tmpdir.ensure(dir=1) + cls.counter = 0 + cls.pypy_c = sys.executable + +class TestJIT(PyPyCJITTests): + def setup_class(cls): + if option.pypy_c is None: + py.test.skip("pass --pypy-c!") + cls.tmpdir = udir.join('pypy-jit') + cls.tmpdir.ensure(dir=1) + cls.counter = 0 + cls.pypy_c = option.pypy_c + + + From pedronis at codespeak.net Tue Mar 20 19:45:21 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Tue, 20 Mar 2007 19:45:21 +0100 (CET) Subject: [pypy-svn] r40860 - pypy/dist/pypy/jit Message-ID: <20070320184521.4B73710079@code0.codespeak.net> Author: pedronis Date: Tue Mar 20 19:45:20 2007 New Revision: 40860 Modified: pypy/dist/pypy/jit/TODO.txt Log: (arre, pedronis) these two have been taken care of. The last portal.py changes also reduced the amount of graphs we timeshift. We were timeshifting graphs that at the moment are not really helpful. Modified: pypy/dist/pypy/jit/TODO.txt ============================================================================== --- pypy/dist/pypy/jit/TODO.txt (original) +++ pypy/dist/pypy/jit/TODO.txt Tue Mar 20 19:45:20 2007 @@ -2,9 +2,6 @@ To Do Right Now ------------------ -- see the inplace-version of the arithmetic operators - and some obvious unary ones: - ... - - improve is_true() - basic docs and examples @@ -12,9 +9,6 @@ - check that --jit works with --faassen; don't stop at BINARY_ADD! -- why does the timeshifter finds very different number of - graphs every time we run it? - Longer-term ------------------ From arigo at codespeak.net Tue Mar 20 20:24:09 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 20 Mar 2007 20:24:09 +0100 (CET) Subject: [pypy-svn] r40862 - in pypy/dist/pypy/module/posix: . test Message-ID: <20070320192409.7EF7C10063@code0.codespeak.net> Author: arigo Date: Tue Mar 20 20:24:06 2007 New Revision: 40862 Modified: pypy/dist/pypy/module/posix/__init__.py pypy/dist/pypy/module/posix/app_posix.py pypy/dist/pypy/module/posix/test/test_posix_libfile.py Log: An app-level version of posix.popen(). It returns a subclass of 'file' with its close() method overridden to wait on the child process. Modified: pypy/dist/pypy/module/posix/__init__.py ============================================================================== --- pypy/dist/pypy/module/posix/__init__.py (original) +++ pypy/dist/pypy/module/posix/__init__.py Tue Mar 20 20:24:06 2007 @@ -70,6 +70,7 @@ interpleveldefs['readlink'] = 'interp_posix.readlink' if hasattr(os, 'fork'): interpleveldefs['fork'] = 'interp_posix.fork' + appleveldefs['popen'] = 'app_posix.popen' if hasattr(os, 'waitpid'): interpleveldefs['waitpid'] = 'interp_posix.waitpid' if hasattr(os, 'execv'): 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 Tue Mar 20 20:24:06 2007 @@ -1,5 +1,6 @@ # NOT_RPYTHON +import os from _structseq import structseqtype, structseqfield error = OSError @@ -28,3 +29,65 @@ return file.fdopen(fd, mode, buffering) + +# __________ only if we have os.fork() __________ + +class popenfile(file): + _childpid = None + + def close(self): + file.close(self) + pid = self._childpid + if pid is not None: + self._childpid = None + os.waitpid(pid, 0) + __del__ = close # as in CPython, __del__ may call os.waitpid() + +def try_close(fd): + try: + os.close(fd) + except OSError: + pass + +def popen(command, mode='r', bufsize=-1): + """popen(command [, mode='r' [, bufsize]]) -> pipe + + Open a pipe to/from a command returning a file object.""" + + from popen2 import MAXFD + + if not mode.startswith('r') and not mode.startswith('w'): + raise ValueError("invalid mode %r" % (mode,)) + read_end, write_end = os.pipe() + try: + childpid = os.fork() + if childpid == 0: + # in the child + try: + if mode.startswith('r'): + os.dup2(write_end, 1) + os.close(read_end) + else: + os.dup2(read_end, 0) + os.close(write_end) + for i in range(3, MAXFD): + try_close(i) + cmd = ['/bin/sh', '-c', command] + os.execvp(cmd[0], cmd) + finally: + os._exit(1) + + if mode.startswith('r'): + os.close(write_end) + fd = read_end + else: + os.close(read_end) + fd = write_end + g = popenfile.fdopen(fd, mode, bufsize) + g._childpid = childpid + return g + + except Exception, e: + try_close(write_end) + try_close(read_end) + raise Exception, e # bare 'raise' does not work here :-( Modified: pypy/dist/pypy/module/posix/test/test_posix_libfile.py ============================================================================== --- pypy/dist/pypy/module/posix/test/test_posix_libfile.py (original) +++ pypy/dist/pypy/module/posix/test/test_posix_libfile.py Tue Mar 20 20:24:06 2007 @@ -23,3 +23,30 @@ f = posix.fdopen(fd, "r") result = f.read() assert result == "this is a test" + + def test_popen(self): + import sys + if sys.platform.startswith('win'): + skip("unix specific") + path2 = self.path + '2' + posix = self.posix + + f = posix.popen("echo hello") + data = f.read() + f.close() + assert data == 'hello\n' + + f = posix.popen("cat > '%s'" % (path2,), 'w') + f.write('123\n') + f.close() + f = open(path2, 'r') + data = f.read() + f.close() + assert data == '123\n' + + import time + start_time = time.time() + f = posix.popen("sleep 2") + f.close() # should wait here + end_time = time.time() + assert end_time - start_time >= 1.9 From guido at codespeak.net Tue Mar 20 22:15:43 2007 From: guido at codespeak.net (guido at codespeak.net) Date: Tue, 20 Mar 2007 22:15:43 +0100 (CET) Subject: [pypy-svn] r40864 - in pypy/dist/pypy/tool/build: . test testproject/builds Message-ID: <20070320211543.47C3F10063@code0.codespeak.net> Author: guido Date: Tue Mar 20 22:15:41 2007 New Revision: 40864 Removed: pypy/dist/pypy/tool/build/testproject/builds/ Modified: pypy/dist/pypy/tool/build/compile.py pypy/dist/pypy/tool/build/metaserver.py pypy/dist/pypy/tool/build/test/test_compile.py Log: Refactored and cleaned up compile.py, added retry mechanism to compile.py, typo, removed 'builds' dir in the test project. Modified: pypy/dist/pypy/tool/build/compile.py ============================================================================== --- pypy/dist/pypy/tool/build/compile.py (original) +++ pypy/dist/pypy/tool/build/compile.py Tue Mar 20 22:15:41 2007 @@ -9,12 +9,121 @@ POLLTIME = 5 # for --foreground polling -def get_gateway(config): - if config.server in ['localhost', '127.0.0.1']: - gw = py.execnet.PopenGateway() - else: - gw = py.execnet.SshGateway(config.server) - return gw +class ServerAccessor(object): + remote_code = """ + import sys + sys.path += %r + + from pypy.tool.build import metaserver_instance + from pypy.tool.build.build import BuildRequest + + def getbp(ms, id): + for bp in ms._done: + if bp.request.id() == id: + return bp + + chunksize = 1024 + + try: + while 1: + cmd, data = channel.receive() + if cmd == 'compile': + ret = metaserver_instance.compile( + BuildRequest.fromstring(data)) + elif cmd == 'check': + ret = False + bp = getbp(metaserver_instance, data) + if bp: + ret = str(bp.error) + elif cmd == 'zip': + bp = getbp(metaserver_instance, data) + zipfp = bp.zipfile.open('rb') + try: + while 1: + chunk = zipfp.read(chunksize) + channel.send(chunk) + channel.receive() + if len(chunk) < chunksize: + channel.send(None) + break + finally: + zipfp.close() + channel.send(ret) + finally: + channel.close() + """ + def __init__(self, config): + self.config = config + self.requestid = None + self._connect() + + def _send_twice(self, data): + try: + self.channel.send(data) + except EOFError: + print 'error during send: %s, retrying' % (e,) + self.close() + self._connect() + self.channel.send(data) + + def _receive_twice(self): + try: + ret = self.channel.receive() + except EOFError, e: + print 'error during receive: %s, retrying' % (e,) + self.close() + self._connect() + ret = self.channel.receive() + if isinstance(ret, Exception): + raise ret.__class__, ret # tb? + return ret + + def _try_twice(self, command, data): + self._send_twice((command, data)) + return self._receive_twice() + + def start_compile(self, request): + req = request.serialize() + ret = self._try_twice('compile', req) + if isinstance(ret, dict): + self.requestid = ret['id'] + return ret + + def check_in_progress(self): + return self._try_twice('check', self.requestid) + + def save_zip(self, path): + self._send_twice(('zip', self.requestid)) + fp = path.open('w') + try: + while 1: + chunk = self.channel.receive() + if chunk is None: + break + fp.write(chunk) + self.channel.send(None) + finally: + fp.close() + + def close(self): + try: + self.channel.close() + except EOFError: + pass + self.gateway.exit() + + def _connect(self): + self.gateway = gw = self._get_gateway() + conference = execnetconference.conference(gw, self.config.port, False) + self.channel = conference.remote_exec(self.remote_code % ( + self.config.path,)) + + def _get_gateway(self): + if self.config.server in ['localhost', '127.0.0.1']: + gw = py.execnet.PopenGateway() + else: + gw = py.execnet.SshGateway(config.server) + return gw def parse_options(config, args=None): # merge system + compile options into one optionparser @@ -36,105 +145,6 @@ return optparser, options, args -initcode = """ - import sys - import time - sys.path += %r - bufsize = 1024 - - try: - try: - from pypy.tool.build import metaserver_instance - from pypy.tool.build import build - ret = metaserver_instance.compile(%r) - channel.send(ret) - except Exception, e: - channel.send(str(e)) - finally: - channel.close() -""" -def init(gw, request, path, port): - conference = execnetconference.conference(gw, port, False) - channel = conference.remote_exec(initcode % (path, request)) - return channel - -checkcode = """ - import sys - sys.path += %r - bufsize = 1024 - try: - reqid = channel.receive() - from pypy.tool.build import metaserver_instance - from pypy.tool.build import build - for tb in metaserver_instance._done: - if tb.request.id() == reqid: - channel.send({'error': str(tb.error)}) - else: - channel.send(None) - finally: - channel.close() -""" -def check_server(config, id, path, port): - gw = get_gateway(config) - try: - conference = execnetconference.conference(gw, port, False) - channel = conference.remote_exec(checkcode % (path,)) - try: - channel.send(id) - ret = channel.receive() - finally: - channel.close() - finally: - gw.exit() - return ret - -zipcode = """ - import sys - sys.path += %r - bufsize = 1024 - try: - reqid = channel.receive() - from pypy.tool.build import metaserver_instance - from pypy.tool.build import build - for tb in metaserver_instance._done: - if tb.request.id() == reqid: - fp = tb.zipfile.open('rb') - try: - while 1: - data = fp.read(bufsize) - channel.send(data) - channel.receive() - if len(data) < bufsize: - channel.send(None) - break - finally: - fp.close() - finally: - channel.close() -""" -def savezip(config, id, path, port, savepath): - gw = get_gateway(config) - savepath = py.path.local(savepath) - try: - conference = execnetconference.conference(gw, port, False) - channel = conference.remote_exec(zipcode % (path,)) - try: - channel.send(id) - fp = savepath.open('wb') - try: - while 1: - data = channel.receive() - channel.send(None) - if data is None: - break - fp.write(data) - finally: - fp.close() - finally: - channel.close() - finally: - gw.exit() - def getrequest(config, args=None): from pypy.config.config import make_dict @@ -151,55 +161,40 @@ return buildrequest, options.foreground def main(config, request, foreground=False): - gateway = get_gateway(config) - inprogress = False - try: - print 'going to start compile job with info:' - for k, v in request.sysinfo.items(): - print '%s: %r' % (k, v) - print - print config.compile_config - channel = init(gateway, request, config.path, port=config.port) - try: - data = channel.receive() - if type(data) == str: - print data - for line in channel: - print line - elif type(data) != dict: - raise ValueError, 'invalid data returned: %r' % (data,) - else: - if data['path']: - print ('a suitable result is already available, you can ' - 'find it at "%s" on %s' % (data['path'], - config.server)) - else: - print data['message'] - print 'the id of this build request is: %s' % (data['id'],) - inprogress = True - finally: - channel.close() - finally: - gateway.exit() + print 'going to start compile job with info:' + for k, v in request.sysinfo.items(): + print '%s: %r' % (k, v) + print + print config.compile_config + + msa = ServerAccessor(config) + print 'going to start compile' + ret = msa.start_compile(request) + if ret['path']: + print ('a suitable result is already available, you can ' + 'find it at "%s" on %s' % (ret['path'], + config.server)) + else: + print ret['message'] + print 'the id of this build request is: %s' % (ret['id'],) + inprogress = True if foreground and inprogress: print 'waiting until it\'s done' error = None while 1: - ret = check_server(config, request.id(), config.path, - config.port) - if ret is not None: - error = ret['error'] + ret = msa.check_in_progress() + if ret is not False: + error = ret break time.sleep(POLLTIME) if error and error != 'None': print 'error:', error else: zipfile = py.path.local('data.zip') - savezip(config, request.id(), config.path, - config.port, zipfile) + msa.save_zip(zipfile) print 'done, the result can be found in "data.zip"' elif inprogress: print 'you will be mailed once it\'s ready' Modified: pypy/dist/pypy/tool/build/metaserver.py ============================================================================== --- pypy/dist/pypy/tool/build/metaserver.py (original) +++ pypy/dist/pypy/tool/build/metaserver.py Tue Mar 20 22:15:41 2007 @@ -105,7 +105,7 @@ for br in self._waiting + self._queued: if br.has_satisfying_data(request): id = br.id() - self.channel.send( + self._channel.send( 'build for %s already queued as %s' % ( request.id(), id)) return {'path': None, 'id': id, 'isbuilding': False, Modified: pypy/dist/pypy/tool/build/test/test_compile.py ============================================================================== --- pypy/dist/pypy/tool/build/test/test_compile.py (original) +++ pypy/dist/pypy/tool/build/test/test_compile.py Tue Mar 20 22:15:41 2007 @@ -2,7 +2,7 @@ import threading from pypy.tool.build import execnetconference from pypy.tool.build import config -from pypy.tool.build.compile import main +from pypy.tool.build.compile import main, ServerAccessor from pypy.tool.build.test import fake from pypy.tool.build import build from py.__.path.svn.testing import svntestbase @@ -103,16 +103,20 @@ svnpath_to_url=lambda p: 'file://%s' % (p,), ) -def test_compile(): - # functional test, sorry :| - if not option.functional: - py.test.skip('skipping functional test, use --functional to run it') - +def create_test_repo_file(name): repo, wc = svntestbase.getrepowc('test_compile') - temp = py.test.ensuretemp('test_compile.buildpath') + temp = py.test.ensuretemp('test_compile.%s' % (name,)) wc.ensure('foo', dir=True) wc.commit('added foo') path = repo + '/foo' + return path + +def test_blocking(): + # functional test, sorry :| + if not option.functional: + py.test.skip('skipping functional test, use --functional to run it') + path = create_test_repo_file('test_blocking') + gw = py.execnet.PopenGateway() s = FakeServer() try: @@ -153,3 +157,101 @@ except IOError: pass +class TestServerAccessor(object): + initcode = """ + import sys + sys.path += %r + + import py + from pypy.tool.build.build import BuildPath, BuildRequest + + class FakeMetaServer(object): + def __init__(self): + self._done = [] + self._compilation_requested = [] + + def compile(self, request): + self._compilation_requested.append(request) + return {'id': request.id(), 'path': None, + 'message': 'compilation started'} + + ms = FakeMetaServer() + from pypy.tool import build + old_metaserver_instance = getattr(build, 'metaserver_instance', None) + build.metaserver_instance = ms + try: + while 1: + command, data = channel.receive() + if command == 'quit': + break + elif command == 'compilation_done': + for req in ms._compilation_requested: + if req.id() == data: + temp = py.test.ensuretemp( + 'test_compile.TestServerAccessor').join(data) + ms._compilation_requested.remove(req) + bp = BuildPath(temp.join(data)) + bp.request = req + bp.zipfile = 'foo' + ms._done.append(bp) + break + channel.send(None) + elif command == 'done': + channel.send([bp.request.id() for bp in ms._done]) + elif command == 'requesting': + channel.send([br.id() for br in ms._compilation_requested]) + finally: + channel.close() + build.metaserver_instance = old_metaserver_instance + """ + + def setup(self, method): + self.gw = gw = py.execnet.PopenGateway() + conference = execnetconference.conference(gw, config.testport, True) + self.channel = conference.remote_exec(self.initcode % (config.path,)) + + def teardown_method(self, method): + self.channel.close() + self.gw.exit() + + def test_compilation(self): + # another functional one, although not too bad because it uses + # a mock meta server + if not option.functional: + py.test.skip('skipping functional test, use --functional to run it') + path = create_test_repo_file('TestServerAccessor.start_compile') + req = build.BuildRequest('foo at bar.com', {'foo': 'bar'}, {}, path, 1, 1) + reqid = req.id() + self.channel.send(('requesting', None)) + ret = self.channel.receive() + assert ret == [] + + sa = ServerAccessor(fake.Container(server='localhost', + port=config.testport, + path=config.testpath)) + sa.start_compile(req) + self.channel.send(('requesting', None)) + ret = self.channel.receive() + assert ret == [req.id()] + + ret = sa.check_in_progress() + assert not ret + + self.channel.send(('done', None)) + ret = self.channel.receive() + assert ret == [] + + self.channel.send(('compilation_done', req.id())) + assert self.channel.receive() is None + self.channel.send(('done', None)) + ret = self.channel.receive() + assert ret == [req.id()] + self.channel.send(('requesting', None)) + ret = self.channel.receive() + assert ret == [] + + temppath = py.test.ensuretemp('test_compile.TestServerAccessor.zip') + zippath = temppath.join('data.zip') + sa.save_zip(zippath) + assert zippath.read() == 'foo' + From pedronis at codespeak.net Tue Mar 20 23:14:53 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Tue, 20 Mar 2007 23:14:53 +0100 (CET) Subject: [pypy-svn] r40865 - pypy/dist/pypy/jit Message-ID: <20070320221453.185CE1005A@code0.codespeak.net> Author: pedronis Date: Tue Mar 20 23:14:53 2007 New Revision: 40865 Modified: pypy/dist/pypy/jit/TODO.txt Log: status of --jit --faassen Modified: pypy/dist/pypy/jit/TODO.txt ============================================================================== --- pypy/dist/pypy/jit/TODO.txt (original) +++ pypy/dist/pypy/jit/TODO.txt Tue Mar 20 23:14:53 2007 @@ -8,6 +8,7 @@ - check that --jit works with --faassen; don't stop at BINARY_ADD! + we explode in reg alloc for f(sys.maxint) (of test_pypy_c) ...! Longer-term ------------------ From pedronis at codespeak.net Wed Mar 21 00:16:50 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Wed, 21 Mar 2007 00:16:50 +0100 (CET) Subject: [pypy-svn] r40869 - pypy/dist/pypy/jit Message-ID: <20070320231650.4506B10036@code0.codespeak.net> Author: pedronis Date: Wed Mar 21 00:16:49 2007 New Revision: 40869 Modified: pypy/dist/pypy/jit/TODO.txt Log: some more info Modified: pypy/dist/pypy/jit/TODO.txt ============================================================================== --- pypy/dist/pypy/jit/TODO.txt (original) +++ pypy/dist/pypy/jit/TODO.txt Wed Mar 21 00:16:49 2007 @@ -13,6 +13,7 @@ BINARY_ADD! - we explode in reg alloc for f(sys.maxint) (of test_pypy_c) ...! it seems we are in a flexswitch after a promote to be precise + adding a bunch of printf to the c code: it seems that the inputlocatios to the reg alloc contain the same register twice - CALL_LIKELY_BUILTIN uses call_valuestack => bad Longer-term From afayolle at codespeak.net Wed Mar 21 00:33:32 2007 From: afayolle at codespeak.net (afayolle at codespeak.net) Date: Wed, 21 Mar 2007 00:33:32 +0100 (CET) Subject: [pypy-svn] r40870 - in pypy/dist/pypy/lib: . app_test Message-ID: <20070320233332.01AB110053@code0.codespeak.net> Author: afayolle Date: Wed Mar 21 00:33:30 2007 New Revision: 40870 Modified: pypy/dist/pypy/lib/aop.py pypy/dist/pypy/lib/app_test/sample_aop_code.py pypy/dist/pypy/lib/app_test/test_aop.py Log: added compound point cuts and introduce advice Modified: pypy/dist/pypy/lib/aop.py ============================================================================== --- pypy/dist/pypy/lib/aop.py (original) +++ pypy/dist/pypy/lib/aop.py Wed Mar 21 00:33:30 2007 @@ -2,6 +2,7 @@ heavily influenced by Aspect++""" + __all__ = ('around', 'before', 'after', 'introduce', 'PointCut', 'Aspect') ########################### # API @@ -49,8 +50,13 @@ PointCut: self.weave_at_static, } self.weave_at = dispatch[pointcut.__class__] + self.woven_code = None + def __repr__(self): + return '<%s: %s at %s>' % (self.__class__.__name__, + self.woven_code, + self.pointcut) def __call__(self, function): debug('wrapping advice %s on %s', self.pointcut, function.__name__) @@ -58,7 +64,6 @@ return self def weave(self, ast, enc, modulename): - debug("modulename = %s", modulename) self.curr_encoding = enc if self.pointcut.match_module(modulename): return ast.mutate(self) @@ -68,14 +73,9 @@ def default(self, node): if self.pointcut.match(node): node = self.weave_at(node, - self.pointcut.joinpoint(node)) + self.pointcut.joinpoint(node)) return node -## def visitClass(self, node): -## if self.pointcut.match(node): -## print("found match", node.name) -## return node - def weave_at_execution(self, node, tjp): raise NotImplementedError("abstract method") @@ -234,7 +234,37 @@ requires_dynamic_pointcut=False def weave_at_static(self, node, tjp): debug("WEAVE introduce!!!") - pass # XXX WRITEME + p = parser + id = __aop__.register_joinpoint(self.woven_code, tjp) + if node.code.__class__ == p.ASTPass: + node.code = p.ASTStmt([]) + + methods = node.code.nodes + + newmethod = p.ASTFunction(None, + self.woven_code.func_name, + [p.ASTAssName('self', 0), + p.ASTAssName('args', 0), + ], + [], + p.CO_VARARGS, + self.woven_code.func_doc, + p.ASTStmt([p.ASTPrintnl([p.ASTName('self')], None), + p.ASTPrintnl([p.ASTName('args')], None), + p.ASTReturn(p.ASTCallFunc(p.ASTGetattr(p.ASTName('__aop__'), 'call_introduced'), + [p.ASTConst(id), + p.ASTAdd(p.ASTTuple([p.ASTName('self')]), p.ASTName('args')), + ], None, None) + ) + ] + ), + node.lineno + ) + + + + methods.append(newmethod) + node.code.nodes = methods debug('newnode: %s', node) return node @@ -242,7 +272,6 @@ # JoinPoint # -------- - class JoinPoint: # API for use within advices def signature(self): @@ -250,6 +279,9 @@ point""" return self._signature + def name(self): + return self._name + def that(self): """return: a reference on the object initiating the call, or None if it is a static method or a global function""" @@ -287,6 +319,7 @@ self._arguments = arguments self._argnames = None self.func = func + self._name = None # PointCut @@ -307,7 +340,7 @@ The created point cut is static. The pointcut argument can also be a pointcut instance""" - info('%r %r %r %s', module, klass, func, pointcut) + ##debug('%s %s %s %s', module, klass, func, pointcut) if pointcut is None: self.func_re = re.compile(func) self.module_re = re.compile(module) @@ -316,20 +349,28 @@ self.func_re = pointcut.func_re self.module_re = pointcut.module_re self.class_re = pointcut.class_re + ##debug('*** %s %s %s', self.func_re, self.module_re, self.class_re) else: raise TypeError(type(pointcut)) self.isdynamic = False + def __repr__(self): + return '<%s on %s:%s:%s>' % (self.__class__.__name__, + self.module_re.pattern, + self.class_re.pattern, + self.func_re.pattern) + def __and__(self, other): """return: new pointcut, intersection of the join points in the self and other""" - if other.__class__ != self.__class__: + if not isinstance(other, PointCut): raise TypeError(other.__class__.__name__) - pass + return _AndPC(self, other) + def __or__(self, other): """return: new pointcut, union of the join points in the self and other""" - if other.__class__ != self.__class__: + if not isinstance(other, PointCut): raise TypeError(other.__class__.__name__) - pass + return _OrPC(self, other) ## def __not__(self): ## """return: new pointcut, exclusion of the join points in self""" @@ -358,16 +399,64 @@ def match_module(self, modulename): return self.module_re.match(modulename) - def match(self, astnode): + def find_classname(self, node): + while node is not None: + node = node.parent + if isinstance(node, parser.ASTClass): + return node.name + return '' + + def match(self, node): "a static point cut only matches classes: the function part is not used" assert self.func_re.pattern == '.*' - return self.class_re.match(astnode.name) + return isinstance(node, parser.ASTClass) and \ + self.class_re.match(node.name) def joinpoint(self, node): """returns a join point instance for the node""" # assert self.match(node) return JoinPoint() +class _CompoundPC(PointCut): + def __init__(self, pc1, pc2): + self.pc1 = pc1 + self.pc2 = pc2 + + def __repr__(self): + return "<%s(%r, %r)>" % (self.__class__.__name__, self.pc1, self.pc2) + def call(self): + """return a dynamic pointcut representing places where the pointcut is called""" + return self.__class__(self.pc1.call(), self.pc2.call()) + + def execution(self): + """return a dynamic pointcut representing places where the pointcut is executed""" + return self.__class__(self.pc1.execution(), self.pc2.execution()) + + def initialization(self): + """return a dynamic pointcut representing places where the pointcut is instantiated""" + return self.__class__(self.pc1.initialization(), self.pc2.initialization()) + + def destruction(self): + """return a dynamic pointcut representing places where the pointcut is destroyed""" + return self.__class__(self.pc1.destruction(), self.pc2.destruction()) + +class _AndPC(_CompoundPC): + def match_module(self, modulename): + return self.pc1.match_module(modulename) and self.pc2.match_module(modulename) + + def match(self, node): + return self.pc1.match(node) and self.pc2.match(node) + +class _OrPC(_CompoundPC): + def __init__(self, pc1, pc2): + self.pc1 = pc1 + self.pc2 = pc2 + + def match_module(self, modulename): + return self.pc1.match_module(modulename) or self.pc2.match_module(modulename) + + def match(self, node): + return self.pc1.match(node) or self.pc2.match(node) class AbstractDynamicPointCut(PointCut): def __init__(self, pointcut): @@ -393,15 +482,18 @@ matching func_re, defined within a class matching class_re written in a module matching module_re""" - def match(self, astnode): - # FIXME: class_re - return isinstance(astnode, parser.ASTFunction) and \ - self.func_re.match(astnode.name) + def match(self, node): + if not isinstance(node, parser.ASTFunction): + return False + classname = self.find_classname(node) + return self.class_re.match(classname) and \ + self.func_re.match(node.name) def joinpoint(self, node): """returns a join point instance for the node""" # assert self.match(node) jp = JoinPoint() + jp._name = node.name jp._flags = node.flags jp._argnames = [a.name for a in node.argnames] jp._defaultargvalues = [d.value for d in node.defaults] @@ -414,9 +506,12 @@ module matching module_re""" def match(self, node): - # FIXME: class_re + if not isinstance(node, parser.ASTCallFunc): + return False + classname = self.find_classname(node) return isinstance(node, parser.ASTCallFunc) and \ isinstance(node.node, parser.ASTName) and \ + self.class_re.match(classname) and \ self.func_re.match(node.node.varname) @@ -426,7 +521,7 @@ method in a class matching class_re in a module matching module_re""" def __init__(self, pointcut): ExecutionPointCut.__init__(self, pointcut=pointcut) - self.func_re='^__del__$' + self.func_re = re.compile('^__del__$') ### XXX: won't match anything if no __init__ method exists (or only on a parent class) class InitializationPointCut(ExecutionPointCut): @@ -435,29 +530,7 @@ module_re""" def __init__(self, pointcut): ExecutionPointCut.__init__(self, pointcut=pointcut) - self.func_re='^__init__$' - - -### make these class methods of PointCut ? -def within(pointcutstring): - """return point cut filtering joinpoints on lexical scope""" - pass - -def base(pointcutstring): - """return class pointcuts based on the class hierarchy""" - pass -def derived(pointcutstring): - """return class pointcuts based on the class hierarchy""" - pass - -def that(typepattern): - pass -def target(typepattern): - pass -def result(typepattern): - pass -def args(typepattern): - pass + self.func_re = re.compile('^__init__$') class _UndefinedResult: """used to denote that the result of a call to a aspectised @@ -496,8 +569,8 @@ if not self.advices: return ast try: - info('Weaving on %s %s', filename, sys.path) modulename = self._guessmodule(filename) + info('Looking for something to weave on %s', modulename) for aspect, advice in self.advices: self._curr_aspect = aspect ast = advice.weave(ast, enc, modulename) @@ -539,6 +612,13 @@ args = (aspect, joinpoint,) + arguments return woven_code(*args) + def call_introduced(self, id, args): + info('call to __aop__.call_introduced(%d, *%s)', id, args) + woven_code, (aspect, joinpoint, arguments) = self.joinpoints[id] + debug('woven_code: %s', woven_code) + return woven_code(aspect, *args) + + import __builtin__ __builtin__.__aop__ = Weaver() del __builtin__ @@ -556,7 +636,7 @@ instance = super(Aspect, cls).__call__(*args, **kwargs) for name, advice in cls.__dict__.iteritems(): if isinstance(advice, Advice): - info("registering advice %s.%s", instance.__class__.__name__, name) + info("registering advice %s", advice) __aop__.register_advice(instance, advice) return instance Modified: pypy/dist/pypy/lib/app_test/sample_aop_code.py ============================================================================== --- pypy/dist/pypy/lib/app_test/sample_aop_code.py (original) +++ pypy/dist/pypy/lib/app_test/sample_aop_code.py Wed Mar 21 00:33:30 2007 @@ -24,10 +24,16 @@ class Mumble: def __init__(self, param): self.p = param - def frobble(self): - return 3 * self.p + def frobble(self, b): + return 3 * self.p + b def __del__(self): - print 'poof' + print 'Mumble goes poof' + +def truc(): + m = Mumble(2) + r = m.frobble(1) + print 'truc', r, 'expected 7' + return r """ import os import os.path as osp @@ -38,10 +44,15 @@ return osp.join(osp.dirname(__file__), name) def write_module(name): + clean_module(name) f = open(_make_filename(name), 'w') f.write(code) f.close() def clean_module(name): - os.unlink(_make_filename(name)) + name = _make_filename(name) + if os.path.isfile(name): + os.unlink(name) + if os.path.isfile(name+'c'): + os.unlink(name+'c') Modified: pypy/dist/pypy/lib/app_test/test_aop.py ============================================================================== --- pypy/dist/pypy/lib/app_test/test_aop.py (original) +++ pypy/dist/pypy/lib/app_test/test_aop.py Wed Mar 21 00:33:30 2007 @@ -60,11 +60,93 @@ assert pc.match_module('logilab.common') assert not pc.match_module('logilab') assert not pc.match_module('common.logilab') + + def test_static_pointcut_match(self): + from aop import PointCut + from parser import ASTClass, ASTPass, ASTFunction + pc = PointCut(klass="Mumble") + assert pc.match(ASTClass('Mumble', [], None, ASTPass())) + assert pc.match(ASTClass('MumblesALot', [], None, ASTPass())) + f = ASTFunction(None, 'MumblesALot', [], [], 0, '', ASTPass()) + f.parent = ASTClass('MumblesALot', [], None, ASTPass()) + assert not pc.match(f) + + def test_exec_pointcut_match(self): + from aop import PointCut + from parser import ASTClass, ASTPass, ASTFunction + pc = PointCut(klass="Mumble", func='frobble').execution() + f = ASTFunction(None, 'frobble', [], [], 0, '', ASTPass()) + f.parent = ASTClass('MumblesALot', [], None, ASTPass()) + assert pc.match(f) + f.parent.name = 'Babble' + assert not pc.match(f) + c = ASTClass('frobbles_a_bit', [], None, ASTPass()) + c.parent = ASTClass('MumblesALot', [], None, ASTPass()) + assert not pc.match(c) + + def test_call_pointcut_match(self): + from aop import PointCut + from parser import ASTClass, ASTPass, ASTFunction, ASTName, ASTCallFunc + pc = PointCut(klass="Mumble", func='frobble').call() + cf = ASTCallFunc( ASTName('frobble'), [], None, None) + c = ASTClass('MumblesALot', [], None, ASTPass()) + cf.parent = c + assert pc.match(cf) + f = ASTFunction(None, 'frobble', [], [], 0, '', ASTPass()) + f.parent = c + assert not pc.match(f) + c2 = ASTClass('frobbles_a_bit', [], None, ASTPass()) + c2.parent = c + assert not pc.match(c2) + c.name = 'Babble' + assert not pc.match(cf) + + def test_init_pointcut_match(self): + from aop import PointCut + from parser import ASTClass, ASTPass, ASTFunction + pc = PointCut(klass="Mumble").initialization() + init = ASTFunction(None, '__init__', [], [], 0, '', ASTPass()) + c = ASTClass('MumblesALot', [], None, ASTPass()) + init.parent = c + assert pc.match(init) + c2 = ASTClass('__init__', [], None, ASTPass()) + c2.parent = c + assert not pc.match(c2) + init.name = 'frobble' + assert not pc.match(init) + + def test_destruction_pointcut_match(self): + from aop import PointCut + from parser import ASTClass, ASTPass, ASTFunction, ASTCallFunc, ASTName + pc = PointCut(klass="Mumble").destruction() + delete = ASTFunction(None, '__del__', [], [], 0, '', ASTPass()) + c = ASTClass('MumblesALot', [], None, ASTPass()) + delete.parent = c + assert pc.match(delete) + c2 = ASTClass('__del__', [], None, ASTPass()) + c2.parent = c + assert not pc.match(c2) + delete.name = 'frobble' + assert not pc.match(delete) + + + def test_and_compound_pointcut_match(self): + from aop import PointCut + from parser import ASTClass, ASTPass, ASTFunction, ASTCallFunc, ASTName + pc1 = PointCut(klass="Mumble") + pc2 = PointCut(func="frobble") + pc = (pc1 & pc2).execution() + f = ASTFunction(None, 'frobble', [], [], 0, '', ASTPass()) + f.parent = ASTClass('MumblesALot', [], None, ASTPass()) + assert pc.match(f) + f.parent.name = 'Babble' + assert not pc.match(f) + c = ASTClass('frobbles_a_bit', [], None, ASTPass()) + c.parent = ASTClass('MumblesALot', [], None, ASTPass()) + assert not pc.match(c) + class AppTestWeavingAtExecution(object): - def setup_class(cls): - cls.space = gettestobjspace(**{'objspace.usepycfiles':False}) - def test_simple_aspect_before_execution(self): from aop import PointCut, Aspect, before from app_test import sample_aop_code @@ -95,6 +177,36 @@ assert answ == 47 sample_aop_code.clean_module('aop_before_execution') + def test_aspect_before_meth_execution(self): + from aop import PointCut, Aspect, before + from app_test import sample_aop_code + __aop__._clear_all() + sample_aop_code.write_module('aop_before_meth_execution') + + class AspectTest: + __metaclass__ = Aspect + def __init__(self): + self.executed = False + @before(PointCut(func='frobble', klass='Mumble').execution()) + def advice_before_meth_execution(self, tjp): + self.executed = True + self.argnames = tjp._argnames + self.flags = tjp._flags + + assert __aop__.advices == [] + aspect = AspectTest() + assert __aop__.advices == [(aspect, AspectTest.advice_before_meth_execution)] + assert not aspect.executed + + from app_test import aop_before_meth_execution + assert aspect.executed == 0 + answ = aop_before_meth_execution.truc() + assert aspect.executed == 1 + assert aspect.argnames == ['self', 'b'] + assert aspect.flags == 0 + assert answ == 7 + sample_aop_code.clean_module('aop_before_meth_execution') + def test_simple_aspect_after_execution(self): from aop import PointCut, Aspect, after from app_test import sample_aop_code @@ -153,9 +265,6 @@ class AppTestWeavingAtCall(object): - def setup_class(cls): - cls.space = gettestobjspace(**{'objspace.usepycfiles':False}) - def test_simple_aspect_before_call(self): from aop import PointCut, Aspect, before from app_test import sample_aop_code @@ -251,3 +360,27 @@ assert aspect.result == 42 assert answ == 47 sample_aop_code.clean_module('aop_around_call') + + + +class AppTestWeavingIntroduce(object): + def test_introduce(self): + from aop import PointCut, Aspect, introduce + from app_test import sample_aop_code + __aop__._clear_all() + sample_aop_code.write_module('aop_introduce') + class AspectTest: + __metaclass__ = Aspect + @introduce(PointCut(klass='Mumble')) + def newmethod(self, it, a, b): + return it.p*a+b + + aspect = AspectTest() + from app_test import aop_introduce + c = aop_introduce.Mumble(2) + try: + answ = c.newmethod(1,3) + except Exception, exc: + print exc.__class__.__name__, exc + assert False + assert answ == 5 From pedronis at codespeak.net Wed Mar 21 01:03:49 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Wed, 21 Mar 2007 01:03:49 +0100 (CET) Subject: [pypy-svn] r40871 - pypy/dist/pypy/jit Message-ID: <20070321000349.8162A1005A@code0.codespeak.net> Author: pedronis Date: Wed Mar 21 01:03:47 2007 New Revision: 40871 Modified: pypy/dist/pypy/jit/TODO.txt Log: twice same reg because twice same var :( Modified: pypy/dist/pypy/jit/TODO.txt ============================================================================== --- pypy/dist/pypy/jit/TODO.txt (original) +++ pypy/dist/pypy/jit/TODO.txt Wed Mar 21 01:03:47 2007 @@ -14,7 +14,8 @@ - we explode in reg alloc for f(sys.maxint) (of test_pypy_c) ...! it seems we are in a flexswitch after a promote to be precise adding a bunch of printf to the c code: it seems that the inputlocatios to the reg alloc contain the same register twice - - CALL_LIKELY_BUILTIN uses call_valuestack => bad + mmh, because we have the same variable twice (this is an invariant broken) +- CALL_LIKELY_BUILTIN uses call_valuestack => bad Longer-term ------------------ From hpk at codespeak.net Wed Mar 21 08:34:43 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Wed, 21 Mar 2007 08:34:43 +0100 (CET) Subject: [pypy-svn] r40872 - pypy/dist/pypy/doc Message-ID: <20070321073443.196801006E@code0.codespeak.net> Author: hpk Date: Wed Mar 21 08:34:41 2007 New Revision: 40872 Modified: pypy/dist/pypy/doc/objspace-proxies.txt Log: first go at refactoring/streamlining Tproxies docs (and code) Modified: pypy/dist/pypy/doc/objspace-proxies.txt ============================================================================== --- pypy/dist/pypy/doc/objspace-proxies.txt (original) +++ pypy/dist/pypy/doc/objspace-proxies.txt Wed Mar 21 08:34:41 2007 @@ -452,18 +452,19 @@ Transparent Proxy Implementation ================================ -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, see the document -about `alternative object implementations`_. - -Transparent proxies are implementation of types which sends every performed -operation on an object to a provided callable. From an application level -it looks like an instance of arbitrary type, but all operations are directly -calling a provided callable with an apropriate arguments. +PyPy's Transparent Proxies allow to route operations to objects +to a callable. Application level code can customize e.g. list +and dictionary objects without interfering with the type system, +for example ``type(proxy_list) is list`` can be true but you +you have full control on all operations that are performed on the +``proxy_list``. -Suppose we have a need of having a list instance which added to anything -will provide 42. Than we create transparent proxy for int:: + +Example of the core mechanism +------------------------------------------- + +The following example proxies a list and will +return ``42`` on any add operation to the list:: $ py.py --with-transparent-proxy >>>> from pypymagic import transparent_proxy @@ -473,65 +474,40 @@ >>>> raise AttributeError >>>> >>>> i = transparent_proxy(list, f) - -And now:: - - >>> type(i) + >>>> type(i) list - >>> i + 3 + >>>> i + 3 42 .. _`alternative object implementations`: object-optimizations.html -More sophisticated example: ---------------------------- + +Example of recording all operations on builtins +---------------------------------------------------- + +XXX describe tputil.py's "Invocation" object somewhere +XXX this is work in progress Suppose we want to have list which stores all operations performed on -it for later analysis. So we create an apropriate controller:: +it for later analysis. We use a small `tputil.py`_ module that helps +with transparently proxying builtin instances:: - from pypymagic import transparent_proxy, get_transparent_controller - from types import MethodType + from tputil import make_proxy - class ListController(object): - def __init__(self, l): - assert isinstance(l, list) - self.l = l - self.history = [] - self.proxy = transparent_proxy(list, self.perform) - - def perform(self, operation, *args, **kwargs): - self.history.append(operation) # remember the operation performed - # perform the operation on the proxied object - result = getattr(self.l, operation)(*args, **kwargs) - if result is self.l: - # If the result is the proxied list - # return the proxy instead. - result = self.proxy - elif (isinstance(result, MethodType) and - result.im_self is self.l): - # Convert methods bound to the proxied list - # to methods bound to the proxy. - # This is to have calls to the method become calls - # to perform. - result = MethodType(result.im_func, self.proxy, result.im_class) - return result - - >>>> l = [] - >>>> c = Controller(l) - >>>> lst = c.proxy - -Now we can perform:: - - >>>> lst.append(3) - >>>> len(lst) - 1 - >>>> l - [3] - >>>> c.history - [__getattribute__, append, __len__] - >>>> type(lst) is type(l) - True + history = [] + def recorder(invocation): + history.append(invocation) + return invocation.perform() + >>>> l = make_proxy([], recorder) + >>>> type(l) + list + >>>> l.append(3) + >>>> len(l) + 1 + >>>> len(history) + 4 + So what happened: * We've create transparent proxy of type list with controller c.perform @@ -548,10 +524,13 @@ 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. +Basic and tputil.py API +----------------------------- + +XXX (hpk) refactor/amend/refine + +Transparent proxy provides two functions in the pypymagic module. * `transparent_proxy` - a basic function to create proxy object. @@ -576,23 +555,34 @@ 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: -------------- +Implementation Note +----------------------------- -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 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. +PyPy's standard object space allows to internally have multiple +implementations of a type and change the implementation at run +time while application level code consistently sees the exact +same type and object. Multiple performance optimisations using +this features are already implemented, see the document +about `alternative object implementations`_. Transparent +Proxies use the architecture to provide control back +to application level code. + +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 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. .. _`standard object space`: objspace.html#the-standard-object-space .. _`proxy_helpers.py`: ../../pypy/objspace/std/proxy_helpers.py .. _`proxyobject.py`: ../../pypy/objspace/std/proxyobject.py .. _`transparent.py`: ../../pypy/objspace/std/transparent.py +.. _`tputil.py`: ../../pypy/lib/tputil.py .. include:: _ref.txt From hpk at codespeak.net Wed Mar 21 08:35:51 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Wed, 21 Mar 2007 08:35:51 +0100 (CET) Subject: [pypy-svn] r40873 - pypy/extradoc/planning/1.0 Message-ID: <20070321073551.624D01006E@code0.codespeak.net> Author: hpk Date: Wed Mar 21 08:35:49 2007 New Revision: 40873 Modified: pypy/extradoc/planning/1.0/TODO.txt Log: some updates from my side Modified: pypy/extradoc/planning/1.0/TODO.txt ============================================================================== --- pypy/extradoc/planning/1.0/TODO.txt (original) +++ pypy/extradoc/planning/1.0/TODO.txt Wed Mar 21 08:35:49 2007 @@ -56,13 +56,14 @@ (hpk to start here) - describe particularly Javascript-related demos, refine them. + bring play1.codespeak.net online (in-progress) (in-progress, adding more console variations currently, nicer entry page) (fijal) - make transparent proxies more prominent (because they are a rather powerful feature) - - write a nice support module - - write/review documentation + - write a nice support module (pypy/lib/tputil.py - in progress) + - write/review documentation (in-progress) - fix bugs if any - probably don't go for "transparent_proxy(type, ...)" :) (hpk) From fijal at codespeak.net Wed Mar 21 09:25:25 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 21 Mar 2007 09:25:25 +0100 (CET) Subject: [pypy-svn] r40874 - pypy/dist/pypy/doc Message-ID: <20070321082525.9765D1006E@code0.codespeak.net> Author: fijal Date: Wed Mar 21 09:25:24 2007 New Revision: 40874 Modified: pypy/dist/pypy/doc/summer-of-pypy.txt Log: Fix links Modified: pypy/dist/pypy/doc/summer-of-pypy.txt ============================================================================== --- pypy/dist/pypy/doc/summer-of-pypy.txt (original) +++ pypy/dist/pypy/doc/summer-of-pypy.txt Wed Mar 21 09:25:24 2007 @@ -92,10 +92,10 @@ .. _PSF: http://code.google.com/soc/psf/about.html -.. _`Ajax in python based on PyPy's JavaScript backend`: http://code.google.com/soc/psf/appinfo.html?csaid=12134111E3C90670 +.. _`Ajax in python based on PyPy's JavaScript backend`: http://code.google.com/soc/2006/psf/appinfo.html?csaid=12134111E3C90670 .. _`Write and port modules from CPython with ctypes`: http://codespeak.net/svn/user/rhymes/proposal_abstract.txt -.. _`Complete gencli, the PyPy CLI backend`: http://code.google.com/soc/psf/appinfo.html?csaid=CB4EC4BA30BDDBCD +.. _`Complete gencli, the PyPy CLI backend`: http://code.google.com/soc/2006/psf/appinfo.html?csaid=CB4EC4BA30BDDBCD .. _`JavaScript interpreter`: http://codespeak.net/svn/user/santagada/javascript_interpreter_sop.txt From mwh at codespeak.net Wed Mar 21 09:47:51 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Wed, 21 Mar 2007 09:47:51 +0100 (CET) Subject: [pypy-svn] r40875 - in pypy/dist/pypy: jit/codegen/ppc translator Message-ID: <20070321084751.4AE631007D@code0.codespeak.net> Author: mwh Date: Wed Mar 21 09:47:49 2007 New Revision: 40875 Modified: pypy/dist/pypy/jit/codegen/ppc/rgenop.py pypy/dist/pypy/translator/driver.py Log: hack on ppc the same way as intel to make the code blocks bigger in pypy-c-jit 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 Wed Mar 21 09:47:49 2007 @@ -25,6 +25,7 @@ _PPC = RPPCAssembler + NSAVEDREGISTERS = 19 DEBUG_TRAP = option.trap @@ -1123,6 +1124,7 @@ insn.CR_FIELD:insn.crfs, insn.CT_REGISTER:[insn.ctr]} DEBUG_SCRIBBLE = option.debug_scribble + MC_SIZE = 65536 def __init__(self): self.mcs = [] # machine code blocks where no-one is currently writing @@ -1273,7 +1275,7 @@ if self.mcs: return self.mcs.pop() else: - return self.MachineCodeBlock(65536) # XXX supposed infinite for now + return self.MachineCodeBlock(self.MC_SIZE) # XXX supposed infinite for now def close_mc(self, mc): ## from pypy.jit.codegen.ppc.ppcgen.asmfunc import get_ppcgen Modified: pypy/dist/pypy/translator/driver.py ============================================================================== --- pypy/dist/pypy/translator/driver.py (original) +++ pypy/dist/pypy/translator/driver.py Wed Mar 21 09:47:49 2007 @@ -383,6 +383,7 @@ RGenOp.MC_SIZE = 32 * 1024 * 1024 elif cpu == 'ppc': from pypy.jit.codegen.ppc.rgenop import RPPCGenOp as RGenOp + RGenOp.MC_SIZE = 32 * 1024 * 1024 else: raise Exception('Unsuported cpu %r'%cpu) From mwh at codespeak.net Wed Mar 21 09:50:30 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Wed, 21 Mar 2007 09:50:30 +0100 (CET) Subject: [pypy-svn] r40877 - pypy/dist/pypy/jit/codegen/ppc Message-ID: <20070321085030.7460E1007D@code0.codespeak.net> Author: mwh Date: Wed Mar 21 09:50:29 2007 New Revision: 40877 Modified: pypy/dist/pypy/jit/codegen/ppc/regalloc.py Log: add even more spew to debug_print Modified: pypy/dist/pypy/jit/codegen/ppc/regalloc.py ============================================================================== --- pypy/dist/pypy/jit/codegen/ppc/regalloc.py (original) +++ pypy/dist/pypy/jit/codegen/ppc/regalloc.py Wed Mar 21 09:50:29 2007 @@ -142,6 +142,7 @@ print "Processing instruction" print insn print "LRU list was:", self.lru + print 'located at', [self.loc_of(a) for a in self.lru] # put things into the lru for arg in insn.reg_args: @@ -150,6 +151,7 @@ self._promote(insn.result) if DEBUG_PRINT: print "LRU list is now:", self.lru + print 'located at', [self.loc_of(a) for a in self.lru if a is not insn.result] # We need to allocate a register for each used # argument that is not already in one From stephan at codespeak.net Wed Mar 21 09:53:44 2007 From: stephan at codespeak.net (stephan at codespeak.net) Date: Wed, 21 Mar 2007 09:53:44 +0100 (CET) Subject: [pypy-svn] r40878 - in pypy/dist/pypy/lib: . app_test Message-ID: <20070321085344.BDFAC1007D@code0.codespeak.net> Author: stephan Date: Wed Mar 21 09:53:43 2007 New Revision: 40878 Modified: pypy/dist/pypy/lib/app_test/test_stackless.py pypy/dist/pypy/lib/stackless.py Log: one more test in test_stackless.py. The 'coroutine' interface is now embedded into stackless.py when used from CPython. Modified: pypy/dist/pypy/lib/app_test/test_stackless.py ============================================================================== --- pypy/dist/pypy/lib/app_test/test_stackless.py (original) +++ pypy/dist/pypy/lib/app_test/test_stackless.py Wed Mar 21 09:53:43 2007 @@ -544,5 +544,15 @@ assert value == (2, 42) + def test_schedule_return_value(self): + + def task(val): + value = stackless.schedule(val) + assert value == val + + stackless.tasklet(task)(10) + stackless.tasklet(task)(5) + + stackless.run() Modified: pypy/dist/pypy/lib/stackless.py ============================================================================== --- pypy/dist/pypy/lib/stackless.py (original) +++ pypy/dist/pypy/lib/stackless.py Wed Mar 21 09:53:43 2007 @@ -9,12 +9,96 @@ try: from _stackless import coroutine, greenlet except ImportError: # we are running from CPython - # you must have coroutine from - # http://codespeak.net/svn/user/stephan/hacks/coroutine/ - # in your path in order to get the following to work - from py.magic import greenlet - from coroutine import coroutine + try: + from functools import partial + except ImportError: # we are not running python 2.5 + class partial(object): + # just enough of 'partial' to be usefull + def __init__(self, func, *argl, **argd): + self.func = func + self.argl = argl + self.argd = argd + + def __call__(self): + return self.func(*self.argl, **self.argd) + + class GWrap(greenlet): + """This is just a wrapper around greenlets to allow + to stick additional attributes to a greenlet. + To be more concrete, we need a backreference to + the coroutine object""" + + class MWrap(object): + def __init__(self,something): + self.something = something + + def __getattr__(self, attr): + return getattr(self.something, attr) + + class coroutine(object): + "we can't have greenlet as a base, because greenlets can't be rebound" + + def __init__(self): + self._frame = None + self.is_zombie = False + + def __getattr__(self, attr): + return getattr(self._frame, attr) + + def __del__(self): + self.is_zombie = True + del self._frame + self._frame = None + + def bind(self, func, *argl, **argd): + """coro.bind(f, *argl, **argd) -> None. + binds function f to coro. f will be called with + arguments *argl, **argd + """ + if self._frame is None or self._frame.dead: + self._frame = frame = GWrap() + frame.coro = self + if hasattr(self._frame, 'run') and self._frame.run: + raise ValueError("cannot bind a bound coroutine") + self._frame.run = partial(func, *argl, **argd) + + def switch(self): + """coro.switch() -> returnvalue + switches to coroutine coro. If the bound function + f finishes, the returnvalue is that of f, otherwise + None is returned + """ + try: + return greenlet.switch(self._frame) + except TypeError: # self._frame is the main coroutine + return greenlet.switch(self._frame.something) + + def kill(self): + """coro.kill() : kill coroutine coro""" + self._frame.throw() + + def _is_alive(self): + if self._frame is None: + return False + return not self._frame.dead + is_alive = property(_is_alive) + del _is_alive + + def getcurrent(): + """coroutine.getcurrent() -> the currently running coroutine""" + try: + return greenlet.getcurrent().coro + except AttributeError: + return _maincoro + getcurrent = staticmethod(getcurrent) + + _maincoro = coroutine() + maingreenlet = greenlet.getcurrent() + _maincoro._frame = frame = MWrap(maingreenlet) + frame.coro = _maincoro + del frame + del maingreenlet from collections import deque From fijal at codespeak.net Wed Mar 21 10:32:51 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 21 Mar 2007 10:32:51 +0100 (CET) Subject: [pypy-svn] r40880 - pypy/dist/pypy/translator/js/examples/data Message-ID: <20070321093251.BBAAC10077@code0.codespeak.net> Author: fijal Date: Wed Mar 21 10:32:43 2007 New Revision: 40880 Modified: pypy/dist/pypy/translator/js/examples/data/index.html Log: Fix redirect 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 Mar 21 10:32:43 2007 @@ -10,7 +10,7 @@ From antocuni at codespeak.net Wed Mar 21 11:15:27 2007 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Wed, 21 Mar 2007 11:15:27 +0100 (CET) Subject: [pypy-svn] r40884 - pypy/dist/pypy/doc Message-ID: <20070321101527.E7FA610079@code0.codespeak.net> Author: antocuni Date: Wed Mar 21 11:15:27 2007 New Revision: 40884 Modified: pypy/dist/pypy/doc/getting-started.txt Log: Some infos on the clr module. Modified: pypy/dist/pypy/doc/getting-started.txt ============================================================================== --- pypy/dist/pypy/doc/getting-started.txt (original) +++ pypy/dist/pypy/doc/getting-started.txt Wed Mar 21 11:15:27 2007 @@ -712,6 +712,40 @@ fine. Once assembled, you can run the produced executable with the Microsoft Runtime. +Trying the experimental .NET integration +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +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_class`` 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 = 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`: From cfbolz at codespeak.net Wed Mar 21 11:23:44 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 21 Mar 2007 11:23:44 +0100 (CET) Subject: [pypy-svn] r40885 - pypy/dist/pypy/translator/goal Message-ID: <20070321102344.87B3A10079@code0.codespeak.net> Author: cfbolz Date: Wed Mar 21 11:23:42 2007 New Revision: 40885 Modified: pypy/dist/pypy/translator/goal/targetpypystandalone.py Log: enable clr module when translating with gencli and the other way round Modified: pypy/dist/pypy/translator/goal/targetpypystandalone.py ============================================================================== --- pypy/dist/pypy/translator/goal/targetpypystandalone.py (original) +++ pypy/dist/pypy/translator/goal/targetpypystandalone.py Wed Mar 21 11:23:42 2007 @@ -133,6 +133,11 @@ elif config.objspace.usemodules.pypyjit: self.translateconfig.goal_options.jit = True + if config.translation.backend == "cli": + config.objspace.usemodules.clr = True + elif config.objspace.usemodules.clr: + config.translation.backend == "clr" + config.objspace.nofaking = True config.objspace.compiler = "ast" config.translating = True From antocuni at codespeak.net Wed Mar 21 11:26:08 2007 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Wed, 21 Mar 2007 11:26:08 +0100 (CET) Subject: [pypy-svn] r40886 - pypy/dist/pypy/doc Message-ID: <20070321102608.C705C1007C@code0.codespeak.net> Author: antocuni Date: Wed Mar 21 11:26:07 2007 New Revision: 40886 Modified: pypy/dist/pypy/doc/getting-started.txt Log: You don't longer need to enable the clr module explicitly Modified: pypy/dist/pypy/doc/getting-started.txt ============================================================================== --- pypy/dist/pypy/doc/getting-started.txt (original) +++ pypy/dist/pypy/doc/getting-started.txt Wed Mar 21 11:26:07 2007 @@ -716,16 +716,12 @@ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 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:: +enables integration with the surrounding .NET environment. - ./translate.py --text --batch --backend=cli targetpypystandalone.py --withmod-clr - -Then, you can dynamically load .NET classes using the -``clr.load_cli_class`` 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:: +You can dynamically load .NET classes using the ``clr.load_cli_class`` +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') From auc at codespeak.net Wed Mar 21 12:14:49 2007 From: auc at codespeak.net (auc at codespeak.net) Date: Wed, 21 Mar 2007 12:14:49 +0100 (CET) Subject: [pypy-svn] r40889 - pypy/dist/pypy/rlib/cslib Message-ID: <20070321111449.94D3A10074@code0.codespeak.net> Author: auc Date: Wed Mar 21 12:14:48 2007 New Revision: 40889 Modified: pypy/dist/pypy/rlib/cslib/rdistributor.py pypy/dist/pypy/rlib/cslib/rdomain.py pypy/dist/pypy/rlib/cslib/rpropagation.py Log: cleanup & one helper for c.space distributors Modified: pypy/dist/pypy/rlib/cslib/rdistributor.py ============================================================================== --- pypy/dist/pypy/rlib/cslib/rdistributor.py (original) +++ pypy/dist/pypy/rlib/cslib/rdistributor.py Wed Mar 21 12:14:48 2007 @@ -45,7 +45,7 @@ doms1 = make_new_domains(domains) doms2 = make_new_domains(domains) for modified_domain in self._distribute(doms1,doms2): - modified_domain._changed = False + modified_domain._changed = False return [doms1,doms2] class AllOrNothingDistributor(AbstractDistributor): @@ -53,25 +53,39 @@ The first new domain has a size of one, and the second has all the other values""" + def _distribute_on_choice(self, dom, choice): + if choice == 1: + dom.remove_values(dom.get_values()[1:]) + else: + dom.remove_value(dom.get_values()[0]) + 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]) + self._distribute_on_choice(doms1[variable], 1) + self._distribute_on_choice(doms2[variable], 2) 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_on_choice(self, dom, choice): + values = dom.get_values() + middle = len(values)/2 + if choice == 1: + dom.remove_values(values[:middle]) + else: + dom.remove_values(values[middle:]) + 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:]) + self._distribute_on_choice(doms1[variable], 1) + self._distribute_on_choice(doms2[variable], 2) return [doms1[variable], doms2[variable]] DefaultDistributor = DichotomyDistributor Modified: pypy/dist/pypy/rlib/cslib/rdomain.py ============================================================================== --- pypy/dist/pypy/rlib/cslib/rdomain.py (original) +++ pypy/dist/pypy/rlib/cslib/rdomain.py Wed Mar 21 12:14:48 2007 @@ -30,7 +30,6 @@ self._value_removed() def remove_values(self, values): - assert isinstance(values, list) if len(values) > 0: for val in values: del self._values[val] @@ -43,50 +42,7 @@ 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() Modified: pypy/dist/pypy/rlib/cslib/rpropagation.py ============================================================================== --- pypy/dist/pypy/rlib/cslib/rpropagation.py (original) +++ pypy/dist/pypy/rlib/cslib/rpropagation.py Wed Mar 21 12:14:48 2007 @@ -10,9 +10,9 @@ 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 = {} + self._varconst = {} for var in self._variables: - self._variableListeners[var] = [] + self._varconst[var] = [] for constr in constraints: self.add_constraint( constr ) @@ -30,17 +30,17 @@ else: self._constraints.append(constraint) for var in constraint._variables: - self._variableListeners[var].append(constraint) + self._varconst[var].append(constraint) def _remove_constraint(self, constraint): self._constraints.remove(constraint) for var in constraint._variables: try: - self._variableListeners[var].remove(constraint) + self._varconst[var].remove(constraint) except ValueError: raise ValueError('Error removing constraint from listener', var, - self._variableListeners[var], + self._varconst[var], constraint) def get_domains(self): @@ -82,7 +82,7 @@ dom = self._domains[var] if not dom._changed: # XXX continue - for constr in self._variableListeners[var]: + for constr in self._varconst[var]: if constr is not constraint: _affected_constraints[constr] = True dom._changed = False From auc at codespeak.net Wed Mar 21 12:17:20 2007 From: auc at codespeak.net (auc at codespeak.net) Date: Wed, 21 Mar 2007 12:17:20 +0100 (CET) Subject: [pypy-svn] r40890 - pypy/dist/pypy/module/_cslib Message-ID: <20070321111720.9A7DE10074@code0.codespeak.net> Author: auc Date: Wed Mar 21 12:17:19 2007 New Revision: 40890 Modified: pypy/dist/pypy/module/_cslib/constraint.py pypy/dist/pypy/module/_cslib/fd.py pypy/dist/pypy/module/_cslib/propagation.py Log: small adaptations Modified: pypy/dist/pypy/module/_cslib/constraint.py ============================================================================== --- pypy/dist/pypy/module/_cslib/constraint.py (original) +++ pypy/dist/pypy/module/_cslib/constraint.py Wed Mar 21 12:17:19 2007 @@ -48,8 +48,6 @@ W_AbstractConstraint.typedef = typedef.TypeDef( "W_AbstractConstraint") - - class _Expression(rc.Expression): """A constraint represented as a python expression.""" @@ -74,8 +72,7 @@ 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_val = dom.vlist[value] w_kwargs.content[space.wrap(var)] = w_val return space.is_true(space.call(self.w_filter_func, space.newlist([]), @@ -85,7 +82,6 @@ def __repr__(self): return '<%s>' % self.formula - class _BinaryExpression(rc.BinaryExpression): """A constraint represented as a python expression.""" @@ -117,11 +113,11 @@ w_kwargs = space.newdict() dom = self.doms[var1] - w_val = space.getitem( dom.w_values, space.wrap(arg1) ) + w_val = dom.vlist[arg1] w_kwargs.content[space.wrap(var1)] = w_val dom = self.doms[var2] - w_val = space.getitem( dom.w_values, space.wrap(arg2) ) + w_val = dom.vlist[arg2] w_kwargs.content[space.wrap(var2)] = w_val res = space.is_true(space.call(self.w_filter_func, @@ -179,7 +175,6 @@ 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)) Modified: pypy/dist/pypy/module/_cslib/fd.py ============================================================================== --- pypy/dist/pypy/module/_cslib/fd.py (original) +++ pypy/dist/pypy/module/_cslib/fd.py Wed Mar 21 12:17:19 2007 @@ -13,30 +13,43 @@ 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 + def __init__(self, vlist, values): + """vlist is a list of values in the domain + values is a dictionnary to make sure that there are no duplicate values""" - assert isinstance(w_values, W_ListObject) - self.w_values = w_values + #assert isinstance(w_values, W_ListObject) + self.vlist = vlist self._values = {} if values is None: - for k in range(len(w_values.wrappeditems)): + for k in range(len(vlist)): self._values[k] = True else: self._values = values.copy() self._changed = False + def get_wvalues_in_rlist(self): + w_vals = self.vlist + return [w_vals[idx] for idx in self._values] + def copy(self): - return _FiniteDomain(self.w_values, self._values) + return _FiniteDomain(self.vlist, self._values) + + def intersect(self, other): + v1 = self.get_wvalues_in_rlist() + v2 = other.get_wvalues_in_rlist() + inter = [v for v in v1 + if v in v2] + return _FiniteDomain(inter, None) + class W_FiniteDomain(baseobjspace.Wrappable): def __init__(self, w_values, values): assert isinstance(w_values, W_ListObject) - self.domain = _FiniteDomain( w_values, values ) + self.domain = _FiniteDomain(w_values.wrappeditems, values) + def make_fd(space, w_values): if not isinstance(w_values, W_ListObject): Modified: pypy/dist/pypy/module/_cslib/propagation.py ============================================================================== --- pypy/dist/pypy/module/_cslib/propagation.py (original) +++ pypy/dist/pypy/module/_cslib/propagation.py Wed Mar 21 12:17:19 2007 @@ -72,7 +72,7 @@ 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) ) + w_value = domain.vlist[value] space.setitem( w_dict, w_var, w_value ) sols_w.append( w_dict ) return space.newlist(sols_w) From auc at codespeak.net Wed Mar 21 12:19:51 2007 From: auc at codespeak.net (auc at codespeak.net) Date: Wed, 21 Mar 2007 12:19:51 +0100 (CET) Subject: [pypy-svn] r40891 - in pypy/dist/pypy/module/cclp: . constraint Message-ID: <20070321111951.6B5D010074@code0.codespeak.net> Author: auc Date: Wed Mar 21 12:19:50 2007 New Revision: 40891 Added: pypy/dist/pypy/module/cclp/app.py (contents, props changed) Modified: pypy/dist/pypy/module/cclp/__init__.py pypy/dist/pypy/module/cclp/constraint/__init__.py pypy/dist/pypy/module/cclp/constraint/constraint.py pypy/dist/pypy/module/cclp/constraint/domain.py pypy/dist/pypy/module/cclp/constraint/variable.py pypy/dist/pypy/module/cclp/cspace.py pypy/dist/pypy/module/cclp/interp_var.py pypy/dist/pypy/module/cclp/scheduler.py pypy/dist/pypy/module/cclp/thunk.py pypy/dist/pypy/module/cclp/types.py pypy/dist/pypy/module/cclp/variable.py Log: big cleanup Modified: pypy/dist/pypy/module/cclp/__init__.py ============================================================================== --- pypy/dist/pypy/module/cclp/__init__.py (original) +++ pypy/dist/pypy/module/cclp/__init__.py Wed Mar 21 12:19:50 2007 @@ -7,6 +7,7 @@ """ appleveldefs = { + 'make_expression':'app.make_expression' } interpleveldefs = { @@ -21,12 +22,13 @@ 'reset_scheduler':'scheduler.reset_scheduler', 'newspace':'cspace.newspace', + 'dorkspace':'cspace.dorkspace', 'choose':'cspace.choose', 'tell':'cspace.tell', - 'distribute':'constraint.distributor.distribute', + 'distribute':'cspace.distribute', - 'make_expression':'constraint.constraint.make_expression', + '_make_expression':'constraint.constraint._make_expression', 'all_diff': 'constraint.constraint.make_alldistinct' } Added: pypy/dist/pypy/module/cclp/app.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/cclp/app.py Wed Mar 21 12:19:50 2007 @@ -0,0 +1,7 @@ +from cclp import _make_expression + +def make_expression(variables, formula): + func = 'lambda %s:%s' % (','.join([name_of(var) + for var in variables]), + formula) + return _make_expression(variables, formula, eval(func)) Modified: pypy/dist/pypy/module/cclp/constraint/__init__.py ============================================================================== --- pypy/dist/pypy/module/cclp/constraint/__init__.py (original) +++ pypy/dist/pypy/module/cclp/constraint/__init__.py Wed Mar 21 12:19:50 2007 @@ -1 +1 @@ -# pass +# Modified: pypy/dist/pypy/module/cclp/constraint/constraint.py ============================================================================== --- pypy/dist/pypy/module/cclp/constraint/constraint.py (original) +++ pypy/dist/pypy/module/cclp/constraint/constraint.py Wed Mar 21 12:19:50 2007 @@ -1,320 +1,55 @@ -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 import baseobjspace from pypy.interpreter.function import Function +from pypy.interpreter.error import OperationError + 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_Var, 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: - assert isinstance(var, W_Var) - 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 +from pypy.module.cclp.types import W_CVar - 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""" +def check_variables(space, w_variables, min_nb): + if not isinstance(w_variables, W_ListObject): + raise OperationError(space.w_TypeError, + space.wrap("variables must be in a list or tuple.")) assert isinstance(w_variables, W_ListObject) - assert isinstance(w_formula, W_StringObject) - items = object_space.unpackiterable(w_variables) - lst = [] - for it in items: - assert isinstance(it, W_Variable) - lst.append(it.name_w()) - var_ids = ','.join(lst) #[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) - self._space.setitem(result_cache, 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 + if len(w_variables.wrappeditems) < min_nb: + raise OperationError(space.w_RuntimeError, + space.wrap("there must be at least %s variables." % min_nb)) + return w_variables + +def cvars_to_names(cvars): + variables = [] + for w_var in cvars: + assert isinstance(w_var, W_CVar) + variables.append(w_var.w_nam) + return variables - 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) +from pypy.module._cslib.constraint import interp_make_expression, \ + make_alldistinct as mkalldiff - 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): +def _make_expression(space, w_variables, w_formula, w_filter_func): """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)) + w_variables = check_variables(space, w_variables, 1) + assert isinstance(w_filter_func, Function) + if not isinstance(w_formula, W_StringObject): + raise OperationError(space.w_TypeError, + space.wrap("formula must be a string.")) + variables = cvars_to_names(w_variables.wrappeditems) + return interp_make_expression(space, space.newlist(variables), + w_formula, w_filter_func) + +_make_expression.unwrap_spec = [baseobjspace.ObjSpace, + baseobjspace.W_Root, + baseobjspace.W_Root, + baseobjspace.W_Root] + +def make_alldistinct(space, w_variables): + w_variables = check_variables(space, w_variables, 2) + variables = cvars_to_names(w_variables.wrappeditems) + return mkalldiff(space, space.newlist(variables)) -#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] + baseobjspace.W_Root] Modified: pypy/dist/pypy/module/cclp/constraint/domain.py ============================================================================== --- pypy/dist/pypy/module/cclp/constraint/domain.py (original) +++ pypy/dist/pypy/module/cclp/constraint/domain.py Wed Mar 21 12:19:50 2007 @@ -1,165 +1,31 @@ -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.types import W_Var from pypy.module.cclp.interp_var import interp_bind, interp_free -all_mms = {} +from pypy.module._cslib import fd -class W_FiniteDomain(W_AbstractDomain): +class _DorkFiniteDomain(fd._FiniteDomain): """ - Variable Domain with a finite set of possible values + this variant accomodates synchronization needs + of the dorkspace """ - 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 __init__(self, space, w_values, values): + fd._FiniteDomain.__init__(self, w_values, values) + self.space = space + self._changevar = W_Var(space) 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 + assert not interp_free(self._changevar) + self._changevar = W_Var(self.space) + def one_shot_watcher(self): + return self._changevar + def _value_removed(self): - "The implementation of remove_value should call this method" - #atomic - interp_bind(self._changed, self._space.w_True) + fd._FiniteDomain._value_removed(self) + interp_bind(self._changevar, 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) - self._space.delitem(self._values, 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: - self._space.delitem(self._values,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._space.unpackiterable(self._values)] - - 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 = space.unpackiterable(w_fd1._values) - res = [w_v for w_v in space.unpackiterable(w_fd2._values) - 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)) Modified: pypy/dist/pypy/module/cclp/constraint/variable.py ============================================================================== --- pypy/dist/pypy/module/cclp/constraint/variable.py (original) +++ pypy/dist/pypy/module/cclp/constraint/variable.py Wed Mar 21 12:19:50 2007 @@ -2,21 +2,22 @@ from pypy.objspace.std.listobject import W_ListObject from pypy.objspace.std.stringobject import W_StringObject -from pypy.module.cclp.constraint.domain import W_FiniteDomain - from pypy.module.cclp.types import deref, W_Var, W_CVar from pypy.module.cclp.variable import bind_mm, raise_unification_failure, _alias, \ _assign_aliases, bind__Var_Root, bind__Var_Var from pypy.module.cclp.misc import w +from pypy.module._cslib import fd + + W_Root = baseobjspace.W_Root def domain(space, w_values, w_name): assert isinstance(w_values, W_ListObject) assert isinstance(w_name, W_StringObject) - w_dom = W_FiniteDomain(space, w_values) + w_dom = fd.W_FiniteDomain(w_values, None) w_var = W_CVar(space, w_dom, w_name) - #w("CVAR", str(w_var)) + w("CVAR", str(w_var)) return w_var app_domain = gateway.interp2app(domain) @@ -24,20 +25,24 @@ def bind__CVar_Root(space, w_cvar, w_obj): #XXX we should (want to) be able to test membership # in a wrapped against wrappeds into a non-wrapped dict - if [True for elt in space.unpackiterable(w_cvar.w_dom._values) + if [True for elt in w_cvar.w_dom.domain.get_wvalues_in_rlist() if space.is_true(space.eq(w_obj, elt))]: return bind__Var_Root(space, w_cvar, w_obj) raise_unification_failure(space, "value not in variable domain") def bind__CVar_CVar(space, w_cvar1, w_cvar2): - w_inter_dom = space.intersection(w_cvar1.w_dom, w_cvar2.w_dom) - if w_inter_dom.__len__() > 0: - if w_inter_dom.__len__() == 1: - w_value = w_inter_dom.get_values()[0] + d1 = w_cvar1.w_dom.domain + d2 = w_cvar2.w_dom.domain + dinter = d1.intersect(d2) + if dinter.size() > 0: + if dinter.size() == 1: + w_value = dinter.get_wvalues_in_rlist()[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 + w_interdom = fd.W_FiniteDomain(space.newlist([]), None) + w_interdom.domain = dinter + w_cvar1.w_dom = w_cvar2.w_dom = w_interdom _alias(space, w_cvar1, w_cvar2) else: raise_unification_failure(space, "incompatible domains") Modified: pypy/dist/pypy/module/cclp/cspace.py ============================================================================== --- pypy/dist/pypy/module/cclp/cspace.py (original) +++ pypy/dist/pypy/module/cclp/cspace.py Wed Mar 21 12:19:50 2007 @@ -1,51 +1,82 @@ 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.objspace.std.stringobject import W_StringObject -from pypy.module._stackless.interp_coroutine import AbstractThunk - -from pypy.module.cclp.misc import get_current_cspace, w +from pypy.module.cclp.misc import get_current_cspace, w, v 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.types import FailedSpace, ConsistencyError, W_Var, W_CVar 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 - +from pypy.module._cslib import fd +from pypy.rlib.cslib import rdistributor as rd +from pypy.module._stackless.coroutine import AppCoroutine +import pypy.rlib.rgc as rgc +def gc_swap_pool(pool): + if we_are_translated(): + return rgc.gc_swap_pool(pool) + +def gc_clone(data, pool): + if we_are_translated(): + return rgc.gc_clone(data, pool) + def newspace(space, w_callable, __args__): "application level creation of a new computation space" args = __args__.normalize() - dist_thread = SpaceCoroutine(space) + # allocate in a new pool + saved_pool = gc_swap_pool(None) + dist_thread = AppCoroutine(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() + w_space = W_CSpace(space, dist_thread, saved_pool) + w_space.goodbye_local_pool() + # /allocate if not we_are_translated(): - w("NEWSPACE, (distributor) thread", - str(id(dist_thread)), "for", str(w_callable.name)) + w("NEWSPACE, (distributor) thread %d for %s" % + ( id(dist_thread), str(w_callable.name) ) ) return w_space + newspace.unwrap_spec=[baseobjspace.ObjSpace, baseobjspace.W_Root, argument.Arguments] + +def dorkspace(space, w_callable, __args__): + "application level creation of a new complicated computation space" + args = __args__.normalize() + dist_thread = AppCoroutine(space) + thunk = CSpaceThunk(space, w_callable, args, dist_thread) + dist_thread.bind(thunk) + + saved_pool = gc_swap_pool(None) + try: + w_space = W_ComplicatedSpace(space, dist_thread, saved_pool) + w_space.goodbye_local_pool() + except: + gc_swap_pool(saved_pool) + raise OperationError(space.w_RuntimeError, + space.wrap("Unknown error in newspace")) + if not we_are_translated(): + w("NEWSPACE, (distributor) thread %d for %s" % + ( id(dist_thread), str(w_callable.name) ) ) + return w_space + +dorkspace.unwrap_spec=[baseobjspace.ObjSpace, + baseobjspace.W_Root, + argument.Arguments] + + def choose(space, w_n): + "non deterministic choice from within a c.space" if not isinstance(w_n, W_IntObject): raise OperationError(space.w_TypeError, space.wrap('choose only accepts an integer.')) @@ -64,33 +95,94 @@ space.wrap("this space is finished")) try: return cspace.choose(n) - except ConsistencyError: - raise OperationError(space.w_ConsistencyError, - space.wrap("this space is failed")) + except Exception, e: + if not we_are_translated(): + import traceback + traceback.print_exc() + w('whack whack whack') + raise OperationError(space.w_RuntimeError, + space.wrap("something wacky happened %s" % e)) choose.unwrap_spec = [baseobjspace.ObjSpace, baseobjspace.W_Root] -from pypy.module.cclp.constraint import constraint +from pypy.module._cslib.constraint import W_AbstractConstraint def tell(space, w_constraint): - if not isinstance(w_constraint, constraint.W_AbstractConstraint): + "adding a constraint to a c.space (from within)" + if not isinstance(w_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) + get_current_cspace(space).tell(w_constraint.constraint) tell.unwrap_spec = [baseobjspace.ObjSpace, baseobjspace.W_Root] +def distribute(space, w_strategy): + assert isinstance(w_strategy, W_StringObject) + strat = space.str_w(w_strategy) + cspace = get_current_cspace(space) + # constraint distributor thread main loop + cspace.distribute(strat) +distribute.unwrap_spec = [baseobjspace.ObjSpace, + baseobjspace.W_Root] + + +# base space +# non concurrent propagators +# hence much less weird synchronization stuff +# a specific pool object +# XXX maybe use a descr_method__new__ to create the pool before allocation class W_CSpace(W_ThreadGroupScheduler): + local_pool = None - def __init__(self, space, dist_thread): + def dump(self): + w('-- DUMPing C.Space data --') + w(':local pool %s' % id(self.local_pool)) + w(':saved pool %s' % id(self.saved_pool)) + v(':threads :') + curr = stop = self._head + while 1: + v('%s ' % id(curr)) + curr = curr._next + if curr == stop: + break + w('') + v(':blocked :') + for th in self._blocked.keys(): + v('%s ' % id(th)) + w('') + w(':blocked_on') + for var, thl in self._blocked_on.items(): + v(' var %s : ' % id(var)) + for th in thl: + v('%s ' % id(th)) + w('') + w(':blocked_byneed') + for var, thl in self._blocked_byneed.items(): + v(' var %s : ' % id(var)) + for th in thl: + v('%s ' % id(th)) + w('') + w(':traced vars') + for th, varl in self._traced.items(): + v(' thread %s : ' % id(th)) + for var in varl: + v('%s ' % id(var)) + w('') + w('-- /DUMP --') + + def __init__(self, space, dist_thread, saved_pool): W_ThreadGroupScheduler.__init__(self, space) + # pool + self.local_pool = None + self.saved_pool = saved_pool + # /pool + # thread ring dist_thread._cspace = self self._init_head(dist_thread) - self.main_thread = dist_thread + # /ring sched.uler.add_new_group(self) - self.distributor = None # dist instance != thread # choice mgmt self._choices = newvar(space) self._committed = newvar(space) @@ -100,89 +192,277 @@ 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 + self._constraints = [] + self._domains = {} # varname -> domain + self._variables = [] # varnames + self._varconst = {} # varname -> constraints + self._cqueue = [] # constraint queue to be processed + + #-- POOL & cloning stuff + + def hello_local_pool(self): + if we_are_translated(): + self.saved_pool = gc_swap_pool(self.local_pool) + + def goodbye_local_pool(self): + if we_are_translated(): + self.local_pool = gc_swap_pool(self.saved_pool) + self.saved_pool = None 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) + # all this stuff is created in the local pool so that + # gc_clone can clone it. every object we want to clone + # must be reachable through objects allocated in this + # local pool via the data tuple. + self.report_bad_condition_to_applevel() + head = curr = self._head + new_shells = [] + # within new POOL + self.hello_local_pool() + coroutines_to_clone = [] + while 1: + coroutines_to_clone.append((curr, curr.frame, curr.subctx)) + self.goodbye_local_pool() + # outside new POOL, build new fresh coro shells + new = AppCoroutine(self.space, state = curr.costate) + new.parent = curr.parent + new_shells.append(new) + self.hello_local_pool() + # /outside + curr = curr._next + if curr == head: + break + data = (self, coroutines_to_clone) + # /within new POOL + self.goodbye_local_pool() + + (copy, copied_coros), copypool = gc_clone(data, self.local_pool) + copy.local_pool = copypool + copy.finalize_cloning(copied_coros, new_shells) + sched.uler.add_new_group(copy) + self.dump() + copy.dump() + return self.space.wrap(copy) - def finalize_cloning(self, orig_cspace, cl_thread ): + def finalize_cloning(self, copied_coros, new_shells): # 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 ) + # 1. our cloned thread gets a new thread ID + w('finalize cloning in c.space %s' % id(self)) + self._head = None + for i in range(len(copied_coros)): + coro, cloned_frame, cloned_subctx = copied_coros[i] + # bolt cloned stuff on new coro shells + cloned_coro = new_shells[i] + cloned_coro.frame = cloned_frame + cloned_coro.subctx = cloned_subctx + cloned_coro._cspace = self + cloned_coro.thunk = coro.thunk + self.replace_thread(coro, cloned_coro) + + def replace_thread(self, old, new): + # walk the list of _blocked threads: + if old in self._blocked.keys(): + w('blocked : %s replaced %s' % (id(new), id(old))) + del self._blocked[old] + self._blocked[new] = 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] is old: + w('blocked_on : %s replaced %s' % (id(new), id(old))) + threads[k] = new + + for w_var in self._blocked_byneed: + threads = self._blocked_byneed[w_var] + for k in range(len(threads)): + if threads[k] is old: + w('blocked_byneed : %s replaced %s' % (id(new), id(old))) + threads[k] = new + + # handled traced thread + for th in self._traced.keys(): + if th is old: + lvars = self._traced[th] + del self._traced[th] + self._traced[new] = lvars + + # insert the thread in the linked list + if self._head is None: + w('head was initialized with %s' % id(new)) + self._head = new._next = new._prev = new + else: + w('%s was inserted in the runqueue' % id(new)) + r = self._head + l = r._prev + l._next = new + r._prev = new + new._prev = l + new._next = r + assert new._next is not new + assert new._prev is not new + + def _newvar(self): + """ + ensure a new space-local variable is allocated + in the right space/pool + """ + self.hello_local_pool() + var = newvar(self.space) + self.goodbye_local_pool() + return var - def report_bad_state_to_applevel(self): + #-- / POOL + + def register_var(self, cvar): + name = cvar.name + dom = cvar.w_dom.domain + self._domains[name] = dom + self._varconst[name] = [] + + def tell(self, rconst): + w('telling %s' % rconst) + self._constraints.append(rconst) + for var in rconst._variables: + self._varconst[var].append(rconst) + + def untell(self, constraint): + "entailed constraint are allowed to go away" + self._constraints.remove(constraint) + for var in constraint._variables: + self._varconst[var].remove(constraint) + + def distributable(self): + for dom in self._domains.values(): + if dom.size() > 1: + return True + return False + + def distribute(self, strat): + w('SP:start constraint propagation & distribution loop') + space = self.space + if strat == 'dichotomy': + dist = rd.DichotomyDistributor() + elif strat == 'allornothing': + dist = rd.AllOrNothingDistributor() + else: + raise OperationError(space.w_RuntimeError, + space.wrap("please pick a strategy in " + "(allornothing, dichotomy).")) + # initialize constraint queue + self._cqueue = [(constr.estimate_cost(self._domains), constr) + for constr in self._constraints] + self.wait_stable() # hmm + self.propagate() + while self.distributable(): + w('SP:distribute loop') + w_choice = self.choose(2) # yes, two, always, all the time + choice = space.int_w(w_choice) + small_dom_var = dist.find_smallest_domain(self._domains) + dom = self._domains[small_dom_var] + dist._distribute_on_choice(dom, choice) + for constraint in self._varconst[small_dom_var]: + self._cqueue.append((0, constraint)) # *uck the cost + dom._changed = False + self.propagate() + + def propagate(self): # XXX pasted from rlib.cslib.rpropagation, mixin me + """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""" + + # XXX : _queue.sort() + w('SP:propagating') + _queue = self._cqueue + _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._varconst[var]: + if constr is not constraint: + _affected_constraints[constr] = True + dom._changed = False + if entailed: + self.untell(constraint) + if constraint in _affected_constraints: + del _affected_constraints[constraint] + + for domain in self._domains.values(): + if domain.size() != 1: + return 0 + return 1 + + #-- Public ops + + def report_bad_condition_to_applevel(self): + """ + a couple of checks for methods on spaces + but forbidden within + """ + currspace = get_current_cspace(self.space) + if currspace is self: + raise OperationError(self.space.w_RuntimeError, + self.space.wrap("you can't do this operation" + "on the current computation space")) 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() + self.report_bad_condition_to_applevel() except: # we're dead, let's avoid wait_stable ... - return self._choices + return self.space.wrap(self._last_choice) 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() + self._choices = self._newvar() 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._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) + # type requirements (logic variables only accept W_Roots) interp_bind(self._choices, self.space.wrap(n)) # unblock the solver # now we wait on a solver commit - self.space.wait(self._committed) + 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 + self.report_bad_condition_to_applevel() + if not isinstance(w_n, W_IntObject): + raise OperationError(self.space.w_TypeError, + self.space.wrap('commit accepts only ints.')) + n = self.space.int_w(w_n) assert interp_free(self._committed) if n < 1 or n > self._last_choice: raise OperationError(self.space.w_ValueError, - self.space.wrap("need 0 var + self._domains = {} # varname -> domain + + + def register_var(self, cvar): + name = cvar.name + self._store[name] = cvar + # let's switch to dork-style finite domains + basic_dom = cvar.w_dom.domain + dom = _DorkFiniteDomain(self.space, + basic_dom.vlist, + basic_dom._values) + cvar.w_dom.domain = dom + self._domains[name] = dom + + def distribute(self, strat): + space = self.space + if strat == 'dichotomy': + dist = rd.DichotomyDistributor() + elif strat == 'allornothing': + dist = rd.AllOrNothingDistributor() + else: + raise OperationError(space.w_RuntimeError, + space.wrap("please pick a strategy in " + "(allornothing, dichotomy).")) + self.wait_stable() + while self.distributable(): + w_choice = self.choose(2) + choice = space.int_w(w_choice) + small_dom_var = dist.find_smallest_domain(self._domains) + dom = self._domains[small_dom_var] + w('ABOUT TO DISTRIBUTE') + dist._distribute_on_choice(dom, choice) + self.wait_stable() + + def tell(self, constraint): + space = self.space + w_coro = AppCoroutine(space) + w_coro._next = w_coro._prev = w_coro + w_coro._cspace = self + thunk = PropagatorThunk(space, constraint, w_coro) + w_coro.bind(thunk) + self.add_new_thread(w_coro) + + + def _bind_solution_variables(self, solution): + if contains_cvar(solution): # was a constraint script + for var in solution: + assert isinstance(var, W_CVar) + realvar = self._store[var.name] + dom = realvar.w_dom.domain + assert isinstance(dom, fd._FiniteDomain) + assert dom.size() == 1 + interp_bind(var, dom.get_wvalues_in_rlist()[0]) Modified: pypy/dist/pypy/module/cclp/interp_var.py ============================================================================== --- pypy/dist/pypy/module/cclp/interp_var.py (original) +++ pypy/dist/pypy/module/cclp/interp_var.py Wed Mar 21 12:19:50 2007 @@ -69,7 +69,7 @@ def _assign(w_var, w_val): assert isinstance(w_var, W_Var) if isinstance(w_var, W_CVar): - if not w_var.w_dom.contains(w_val): + if not w_val in w_var.w_dom.domain.vlist: raise ValueError, "assignment out of domain" w_var.w_bound_to = w_val Modified: pypy/dist/pypy/module/cclp/scheduler.py ============================================================================== --- pypy/dist/pypy/module/cclp/scheduler.py (original) +++ pypy/dist/pypy/module/cclp/scheduler.py Wed Mar 21 12:19:50 2007 @@ -9,7 +9,6 @@ #-- Singleton scheduler ------------------------------------------------ -AppCoroutine.tid = 0 AppCoroutine._cspace = None class TopLevelScheduler(object): @@ -26,25 +25,6 @@ # asking for stability self._asking = {} # cspace -> 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" @@ -61,14 +41,11 @@ 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() + running.goodbye_local_pool() + to_be_run.hello_local_pool() to_be_run.schedule() def _select_next(self): @@ -79,7 +56,6 @@ 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") @@ -245,12 +221,13 @@ 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 + # head thread self._head = None + # thread group ring self._next = self self._prev = self # accounting for blocked stuff @@ -260,40 +237,9 @@ 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 - + w("HEAD (main) THREAD = ", str(id(self._head))) def _chain_insert(self, thread): assert isinstance(thread, AppCoroutine), "type error" @@ -305,12 +251,11 @@ r._prev = thread thread._prev = l thread._next = r - sched.uler.register_thread( thread ) - def hello(self): + def hello_local_pool(self): pass - def goodbye(self): + def goodbye_local_pool(self): pass def register_var(self, var): @@ -352,9 +297,7 @@ 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() @@ -449,14 +392,15 @@ 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))) + v(str(id(th))) del th._cspace._blocked[th] th._cspace.blocked_count -= 1 w('') sched.uler._asking[home] = {} - + def distribute(self, dist): + raise OperationError(self.space.w_RuntimeError, + self.space.wrap("You can't distribute a top-level space.")) def add_new_thread(self, thread): "insert 'thread' at end of running queue" @@ -493,7 +437,6 @@ 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): Modified: pypy/dist/pypy/module/cclp/thunk.py ============================================================================== --- pypy/dist/pypy/module/cclp/thunk.py (original) +++ pypy/dist/pypy/module/cclp/thunk.py Wed Mar 21 12:19:50 2007 @@ -1,12 +1,11 @@ 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.misc import w, get_current_cspace 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 + ConsistencyError, FailedSpace, Solution +from pypy.module.cclp.interp_var import interp_bind, interp_free, interp_wait_or from pypy.objspace.std.listobject import W_ListObject from pypy.objspace.std.listobject import W_TupleObject @@ -40,6 +39,9 @@ _AppThunk.call(self) except Exception, exc: w(".! exceptional EXIT of procedure", str(id(self._coro)), "with", str(exc)) + if not we_are_translated(): + import traceback + traceback.print_exc() sched.uler.dirty_traced_vars(self._coro, W_FailedValue(exc)) else: w(".! clean EXIT of procedure", str(id(self._coro))) @@ -83,7 +85,7 @@ def call(self): space = self.space coro = AppCoroutine.w_getcurrent(space) - assert isinstance(coro, SpaceCoroutine) + assert isinstance(coro, AppCoroutine) cspace = coro._cspace w("-- initial DISTRIBUTOR thunk CALL in", str(id(coro))) sched.uler.trace_vars(coro, logic_args(self.args.unpack())) @@ -93,15 +95,20 @@ _AppThunk.call(self) finally: coro = AppCoroutine.w_getcurrent(space) - assert isinstance(coro, SpaceCoroutine) + assert isinstance(coro, AppCoroutine) cspace = coro._cspace - except ConsistencyError, exc: - w("-- EXIT of DISTRIBUTOR, space is FAILED", str(id(coro)), "with", str(exc)) + except FailedSpace, exc: + w("-- EXIT of DISTRIBUTOR %s, space is FAILED with %s" % (id(coro), + 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)) + w("-- exceptional EXIT of DISTRIBUTOR %s with %s" % (id(coro), + str(exc))) + if not we_are_translated(): + import traceback + traceback.print_exc() failed_value = W_FailedValue(exc) sched.uler.dirty_traced_vars(coro, failed_value) interp_bind(cspace._solution, failed_value) @@ -125,7 +132,6 @@ sched.uler.remove_thread(coro) sched.uler.schedule() - class PropagatorThunk(AbstractThunk): def __init__(self, space, w_constraint, coro): self.space = space @@ -135,26 +141,27 @@ def call(self): #coro = AppCoroutine.w_getcurrent(self.space) try: + space = self.space cspace = self.coro._cspace + const = self.const try: while 1: - entailed = self.const.revise() + if not interp_free(cspace._finished): + break + entailed = const.revise(cspace._domains) 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()) + _doms = [cspace._domains[var] + for var in const._variables] + for dom in _doms: + #assert isinstance(dom, W_AbstractDomain) + wait_list.append(dom.one_shot_watcher()) #or the cspace being dead wait_list.append(cspace._finished) - interp_wait_or(self.space, wait_list) - if not interp_free(cspace._finished): - break + interp_wait_or(space, wait_list) + cspace = get_current_cspace(space) # might have been cloned except ConsistencyError: cspace.fail() except Exception: # rpython doesn't like just except:\n ... Modified: pypy/dist/pypy/module/cclp/types.py ============================================================================== --- pypy/dist/pypy/module/cclp/types.py (original) +++ pypy/dist/pypy/module/cclp/types.py Wed Mar 21 12:19:50 2007 @@ -40,9 +40,11 @@ w("FUT", str(w_self)) +from pypy.module._cslib import fd + class W_CVar(W_Var): def __init__(self, space, w_dom, w_name): - assert isinstance(w_dom, W_AbstractDomain) + assert isinstance(w_dom, fd.W_FiniteDomain) W_Var.__init__(self, space) self.w_dom = w_dom self.name = space.str_w(w_name) @@ -58,6 +60,12 @@ def w_name(self): return self.w_nam + def assign(self, w_var): + if not w_var.w_dom.contains(w_val): + raise ValueError, "assignment out of domain" + w_var.w_bound_to = w_val + + def domain_of(space, w_v): if not isinstance(w_v, W_CVar): raise OperationError(space.w_TypeError, @@ -85,95 +93,42 @@ class Solution(Exception): pass -#-- Constraint --------------------------------------------- +class FailedSpace(Exception): pass -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) +#-- Ring (used by scheduling entities) +class RingMixin(object): + _mixin_ = True + """ + useless till we can give a type parameter + """ + + def init_head(self, head): + self._head = head + head._next = head._prev = head + self._count = 1 + + def chain_insert(self, obj): + r = self._head + l = r._prev + l._next = obj + r._prev = obj + obj._prev = l + obj._next = r + + def remove(self, obj): + l = obj._prev + r = obj._next + l._next = r + r._prev = l + if self._head == obj: + self._head = r + if r == obj: + # that means obj was the last one + # the group is about to die + self._head = None + obj._next = obj._prev = None + #-- Misc --------------------------------------------------- Modified: pypy/dist/pypy/module/cclp/variable.py ============================================================================== --- pypy/dist/pypy/module/cclp/variable.py (original) +++ pypy/dist/pypy/module/cclp/variable.py Wed Mar 21 12:19:50 2007 @@ -289,7 +289,7 @@ def _assign(space, w_var, w_val): assert isinstance(w_var, W_Var) if isinstance(w_var, W_CVar): - if not w_val in space.unpackiterable(w_var.w_dom._values): + if not w_val in w_var.w_dom.domain.get_wvalues_in_rlist(): raise_unification_failure(space, "assignment out of domain") w_var.w_bound_to = w_val From auc at codespeak.net Wed Mar 21 12:20:45 2007 From: auc at codespeak.net (auc at codespeak.net) Date: Wed, 21 Mar 2007 12:20:45 +0100 (CET) Subject: [pypy-svn] r40892 - pypy/dist/pypy/objspace Message-ID: <20070321112045.09BC210074@code0.codespeak.net> Author: auc Date: Wed Mar 21 12:20:44 2007 New Revision: 40892 Modified: pypy/dist/pypy/objspace/logic.py Log: simplify, according to recent changes Modified: pypy/dist/pypy/objspace/logic.py ============================================================================== --- pypy/dist/pypy/objspace/logic.py (original) +++ pypy/dist/pypy/objspace/logic.py Wed Mar 21 12:20:44 2007 @@ -27,25 +27,12 @@ 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.module.cclp.constraint.variable import app_domain +from pypy.module.cclp.constraint.variable import app_domain from pypy.module.cclp.types import app_domain_of, app_name_of, AppCoroutine all_mms.update(variable_mms) -#-- CONSTRAINTS ---------------------------------------------- - -## #------ domains ------------------ -from pypy.module.cclp.constraint import domain -all_mms.update(domain.all_mms) - -W_FiniteDomain = domain.W_FiniteDomain - -## # ---- constraints ---------------- -from pypy.module.cclp.constraint import constraint -all_mms.update(constraint.all_mms) - - #-- SPACE HELPERS ------------------------------------- @@ -182,10 +169,10 @@ 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_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 = ( @@ -231,23 +218,10 @@ 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() From auc at codespeak.net Wed Mar 21 12:21:32 2007 From: auc at codespeak.net (auc at codespeak.net) Date: Wed, 21 Mar 2007 12:21:32 +0100 (CET) Subject: [pypy-svn] r40893 - pypy/dist/pypy/objspace/test Message-ID: <20070321112132.9D21710079@code0.codespeak.net> Author: auc Date: Wed Mar 21 12:21:30 2007 New Revision: 40893 Added: pypy/dist/pypy/objspace/test/test_logiccloning.py (contents, props changed) Modified: pypy/dist/pypy/objspace/test/_test_logic_build.py pypy/dist/pypy/objspace/test/test_logicobjspace.py Log: split tests Modified: pypy/dist/pypy/objspace/test/_test_logic_build.py ============================================================================== --- pypy/dist/pypy/objspace/test/_test_logic_build.py (original) +++ pypy/dist/pypy/objspace/test/_test_logic_build.py Wed Mar 21 12:21:30 2007 @@ -1,4 +1,6 @@ import inspect +import os +from cclp import switch_debug_info def raises(exception, call, *args): try: @@ -12,8 +14,10 @@ class Skip(Exception): pass def skip(desc): - print "skipping because", desc - raise Skip + raise Skip, desc + +def out(obj): + os.write(1, str(obj)) def get_test_classes(): return [obj for name, obj in inspect.getmembers(tm) @@ -41,14 +45,16 @@ continue try: meth() - except Skip: -## import traceback -## traceback.print_exc() - skipped.append(name) + except Skip, s: + skipped.append((name, s.args[0])) + out('s') except Exception, e: failures.append((name, meth, e)) + out('F') else: successes.append(name) + out('.') + out('\n') if successes: print "Successes :" @@ -61,7 +67,9 @@ print if skipped: print "Skipped" - print '', '\n '.join(skipped) + for name, cause in skipped: + print '', name, "skipped because", cause + print # replay failures with more info switch_debug_info() Added: pypy/dist/pypy/objspace/test/test_logiccloning.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/objspace/test/test_logiccloning.py Wed Mar 21 12:21:30 2007 @@ -0,0 +1,132 @@ +try: + from pypy.conftest import gettestobjspace, option + from py.test import skip +except ImportError: + pass + +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_full_logic_program(self): + # this used to work at some point + from constraint.solver import solve + from cclp import newspace, choose, switch_debug_info + + 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) + from pprint import pprint + sols = set() + for sol in solve(s): + sols.add(sol) + + pprint(list(sols)) + assert sols == set([('beige', 'mauve', 'coral'), + ('beige', 'ochre', 'coral'), + ('coral', 'mauve', 'beige'), + ('coral', 'ochre', 'beige'), + ('mauve', 'beige', 'ochre'), + ('mauve', 'coral', 'ochre'), + ('ochre', 'beige', 'mauve'), + ('ochre', 'coral', 'mauve')]) + + + + def test_relational_append(self): + skip('next, ensure this works') + from cclp import newspace, choose + from constraint.solver import solve + + def append(A, B, C): + choice = choose(2) + try: + if choice == 1: + unify(A, None) + unify(B, C) + return A, B + else: + Atail, Ctail, X = newvar(), newvar(), newvar() + unify(A, (X, Atail)) + unify(C, (X, Ctail)) + return append(Atail, B, Ctail) + return A, B + except: + import traceback + traceback.print_exc() + + def in_space(): + X, Y = newvar(), newvar() + return append(X, Y, (1, (2, (3, None)))) + + s = newspace(in_space) + + for sol in solve(s): + print "SOL", sol +## assert sol in ((None, (1,(2,(3,None)))), +## ((1,None), (2,(3,None))), +## ((1,(2,None)), (3,None)), +## ((1,(2,(3,None))), None)) + + + def test_cloning_queens(self): + skip('next, ensure this works') + from constraint.solver import solve + from constraint.examples import queens1, queens2 + from cclp import newspace + + for queen in (queens1, queens2): + sols = set() + s = newspace(queen, 8) + for sol in solve(s): + sols.add(sol) + print sol + #assert len(sols) == 2 + + + def test_recomputing_solver(self): + skip('next, ensure this works') + from constraint.examples import conference_scheduling + from constraint import solver + from cclp import newspace, switch_debug_info + + switch_debug_info() + s = newspace(conference_scheduling) + + sols = set() + for sol in solver.solve_recomputing(s): + sols.add(tuple(sol)) + print sol + assert len(sols) == 64 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 Mar 21 12:21:30 2007 @@ -6,11 +6,6 @@ # we might be called from _test_logic_build # if not, check your paths -try: - is_interpreted() -except: - def is_interpreted(): return True - class AppTest_Logic(object): @@ -700,7 +695,7 @@ raises(UnificationError, unify, d1, d3) unify(d1, d2) assert alias_of(d1, d2) - assert domain_of(d1) == domain_of(d2) == FiniteDomain([2, 3]) + assert domain_of(d1) == domain_of(d2) d1 = domain([1, 2, 3], '') d4 = domain([3, 4], '') @@ -726,6 +721,7 @@ return [] X = newvar() + newspace(in_space, X) wait(X) @@ -774,7 +770,7 @@ def test_tell_ask_choose_commit(self): from constraint.examples import conference_scheduling - from cclp import stacklet, newspace, choose, switch_debug_info + from cclp import stacklet, newspace, dorkspace, choose def solve(spc, commitment, Sol): while 1: @@ -789,18 +785,19 @@ else: unify(Sol, False) - for commit_to in (1, 2): - s = newspace(conference_scheduling) - Solution = newvar() - stacklet(solve, s, commit_to, Solution) - - # well, depending on dict key linear order, we get different - # results -- possibly failed spaces - assert len(Solution) == 10 + for somespace in (dorkspace, newspace): + for commit_to in (1, 2): + s = somespace(conference_scheduling) + Solution = newvar() + stacklet(solve, s, commit_to, Solution) + + # well, depending on dict key linear order, we get different + # results -- possibly failed spaces + assert len(Solution) == 10 def test_logic_program(self): - from cclp import newspace, choose + from cclp import newspace, dorkspace, choose def soft(): choice = choose(2) @@ -848,16 +845,18 @@ for e in lst: yield e - for commit_to in (lazily([1, 1, 1, 1, 1, 1]), - lazily([1, 1, 1, 2, 1, 2])): - s = newspace(suit) - Solution = newvar() - solve(s, commit_to, Solution) - assert Solution in (False, ('beige', 'mauve', 'coral')) + for somespace in (dorkspace, newspace): + for commit_to in (lazily([1, 1, 1, 1, 1, 1]), + lazily([1, 1, 1, 2, 1, 2])): + s = somespace(suit) + Solution = newvar() + solve(s, commit_to, Solution) + assert Solution in (False, ('beige', 'mauve', 'coral')) def test_queens(self): skip("success depends on dict order") from constraint.examples import queens1, queens2 + from cclp import newspace def solve(spc, commitment, Sol): while 1: @@ -897,101 +896,3 @@ 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): - from constraint.examples import queens1, queens2 - from constraint.solver import solve - - #switch_debug_info() - for queen in (queens1,):# queens2): - sols = set() - s = newspace(queens1, {'size':8}) - for sol in solve(s): - sols.add(sol) - 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)) From auc at codespeak.net Wed Mar 21 12:29:07 2007 From: auc at codespeak.net (auc at codespeak.net) Date: Wed, 21 Mar 2007 12:29:07 +0100 (CET) Subject: [pypy-svn] r40895 - pypy/dist/pypy/module/cclp/constraint Message-ID: <20070321112907.9C43F10074@code0.codespeak.net> Author: auc Date: Wed Mar 21 12:29:05 2007 New Revision: 40895 Removed: pypy/dist/pypy/module/cclp/constraint/distributor.py Log: unneeded now From auc at codespeak.net Wed Mar 21 12:29:33 2007 From: auc at codespeak.net (auc at codespeak.net) Date: Wed, 21 Mar 2007 12:29:33 +0100 (CET) Subject: [pypy-svn] r40896 - pypy/dist/pypy/module/cclp/constraint Message-ID: <20070321112933.D82D51007D@code0.codespeak.net> Author: auc Date: Wed Mar 21 12:29:32 2007 New Revision: 40896 Removed: pypy/dist/pypy/module/cclp/constraint/btree.py Log: this one too From fijal at codespeak.net Wed Mar 21 12:44:22 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 21 Mar 2007 12:44:22 +0100 (CET) Subject: [pypy-svn] r40899 - in pypy/dist/pypy/doc: . js Message-ID: <20070321114422.A8EE210074@code0.codespeak.net> Author: fijal Date: Wed Mar 21 12:44:21 2007 New Revision: 40899 Modified: pypy/dist/pypy/doc/js/whatis.txt pypy/dist/pypy/doc/release-0.99.0.txt Log: Fix play1 links, add a link to js/whatis.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 Mar 21 12:44:21 2007 @@ -52,7 +52,10 @@ 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`_ +Several `demos`_ are available online, to take a glimpse at features. + .. _`using`: using.html .. _`b'n'b demo`: http://play1.codespeak.net:7070 .. _`testing`: testing.html +.. _`demos`: http://play1.codespeak.net/ 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 Wed Mar 21 12:44:21 2007 @@ -92,7 +92,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: - http://play1.codespeak.net:8008/ + http://play1.codespeak.net/ * new configuration system: There is a new comprehensive configuration system that allows From fijal at codespeak.net Wed Mar 21 12:45:31 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 21 Mar 2007 12:45:31 +0100 (CET) Subject: [pypy-svn] r40900 - in pypy/dist/pypy/translator/js/examples: console/data data Message-ID: <20070321114531.223FA10074@code0.codespeak.net> Author: fijal Date: Wed Mar 21 12:45:30 2007 New Revision: 40900 Modified: pypy/dist/pypy/translator/js/examples/console/data/console.html pypy/dist/pypy/translator/js/examples/data/style.css Log: Various style fixes, added help box Modified: pypy/dist/pypy/translator/js/examples/console/data/console.html ============================================================================== --- pypy/dist/pypy/translator/js/examples/console/data/console.html (original) +++ pypy/dist/pypy/translator/js/examples/console/data/console.html Wed Mar 21 12:45:30 2007 @@ -7,26 +7,35 @@ Console - PyPy - Modified: pypy/dist/pypy/translator/js/examples/data/style.css ============================================================================== --- pypy/dist/pypy/translator/js/examples/data/style.css (original) +++ pypy/dist/pypy/translator/js/examples/data/style.css Wed Mar 21 12:45:30 2007 @@ -11,6 +11,19 @@ margin-right: 5px; } +div#contents { + float: left; + width: 160px; +} + +#inp { + font: 90% fixed; +} + +#help { + background: #EEE; +} + .menubar { font-weight: bold; float: left; From fijal at codespeak.net Wed Mar 21 13:09:14 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 21 Mar 2007 13:09:14 +0100 (CET) Subject: [pypy-svn] r40901 - pypy/dist/pypy/translator/js/examples/bnb Message-ID: <20070321120914.D2C1B1007B@code0.codespeak.net> Author: fijal Date: Wed Mar 21 13:09:07 2007 New Revision: 40901 Modified: pypy/dist/pypy/translator/js/examples/bnb/start_bnb.py Log: Revive logging pane to display help 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 Mar 21 13:09:07 2007 @@ -267,7 +267,7 @@ bnb_dispatcher) def bnb(): - #createLoggingPane(True) + createLoggingPane(True) log("keys: [0-9] to select player, [wsad] to walk around") exported_methods.initialize_session(session_dispatcher) From fijal at codespeak.net Wed Mar 21 13:13:55 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 21 Mar 2007 13:13:55 +0100 (CET) Subject: [pypy-svn] r40903 - in pypy/dist/pypy/translator/js/examples: console console/data data Message-ID: <20070321121355.24ED01007D@code0.codespeak.net> Author: fijal Date: Wed Mar 21 13:13:53 2007 New Revision: 40903 Modified: pypy/dist/pypy/translator/js/examples/console/client.py pypy/dist/pypy/translator/js/examples/console/console.py pypy/dist/pypy/translator/js/examples/console/data/console.html pypy/dist/pypy/translator/js/examples/data/style.css Log: Minor style updates, help box 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 Wed Mar 21 13:13:53 2007 @@ -31,14 +31,16 @@ if msg[0] == "refresh": inp_elem.scrollIntoView() data = msg[1] - log(data) 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): +def set_sessid(data): + sessid = int(data[0]) + help_msg = data[1] glob.sess_id = sessid + dom.document.getElementById("helpcontents").innerHTML = help_msg exported_methods.refresh_empty(sessid, refresh_console) def empty_callback(msg): 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 Wed Mar 21 13:13:53 2007 @@ -15,6 +15,24 @@ commproxy.USE_MOCHIKIT = True FUNCTION_LIST = ["load_console", "console_onload"] +HELP = {'python':"just python, play as you like :)", + 'pypy-c': +''' +This is the PyPy standart interpreter translated to C with following features: +
      +
    • Stackless - You can use full stackless features including + tasklets, channels, coroutines and greenlets, full list of examples + and niceties can be found on a stackless docs +
    • +
    • Transparent proxy - This is a unique PyPy interpreter feature, + which allows you to provide application-level controller for every possible + object. Details and snippets can be found on a transparent proxy doc
    • +
    +''', + 'pypy-c-thunk':'''the PyPy standart interpreter compiled to C with + a thunk object space''', + 'pypy-c-taint':'''the PyPy standart interpreter compiled to C with + a taint object space'''} class Ignore(Exception): pass @@ -78,10 +96,10 @@ sessions = Sessions() class ExportedMethods(server.ExportedMethods): - @callback(args=[str], retval=int) + @callback(args=[str], retval=[str]) def get_console(self, python="python"): retval = sessions.new_session(python) - return retval + return [str(retval), HELP[python]] @callback(retval=[str]) def refresh(self, pid=0, to_write=""): Modified: pypy/dist/pypy/translator/js/examples/console/data/console.html ============================================================================== --- pypy/dist/pypy/translator/js/examples/console/data/console.html (original) +++ pypy/dist/pypy/translator/js/examples/console/data/console.html Wed Mar 21 13:13:53 2007 @@ -31,7 +31,7 @@ >>>
    - Help box + Help box

    Modified: pypy/dist/pypy/translator/js/examples/data/style.css ============================================================================== --- pypy/dist/pypy/translator/js/examples/data/style.css (original) +++ pypy/dist/pypy/translator/js/examples/data/style.css Wed Mar 21 13:13:53 2007 @@ -43,7 +43,7 @@ div#metaspace { position: absolute; - top: 40px; + top: 20px; left: 170px; } From fijal at codespeak.net Wed Mar 21 13:19:38 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 21 Mar 2007 13:19:38 +0100 (CET) Subject: [pypy-svn] r40904 - pypy/extradoc/planning/1.0 Message-ID: <20070321121938.AFD8B1007D@code0.codespeak.net> Author: fijal Date: Wed Mar 21 13:19:37 2007 New Revision: 40904 Modified: pypy/extradoc/planning/1.0/TODO.txt Log: Update from my POV Modified: pypy/extradoc/planning/1.0/TODO.txt ============================================================================== --- pypy/extradoc/planning/1.0/TODO.txt (original) +++ pypy/extradoc/planning/1.0/TODO.txt Wed Mar 21 13:19:37 2007 @@ -56,8 +56,13 @@ (hpk to start here) - describe particularly Javascript-related demos, refine them. - bring play1.codespeak.net online (in-progress) - (in-progress, adding more console variations currently, nicer entry page) + (in-progress, adding more console variations currently, nicer entry page) + It's all more or less done. What needs to be done (play1): + - more examples with autopaste feature + - source code of web page under the button? + - refined help + - make nice 404 and 500 pages, also for apache + - make pypy-cli work there (fijal) - make transparent proxies more prominent From cfbolz at codespeak.net Wed Mar 21 13:33:32 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 21 Mar 2007 13:33:32 +0100 (CET) Subject: [pypy-svn] r40907 - pypy/extradoc/eu-report Message-ID: <20070321123332.0552210069@code0.codespeak.net> Author: cfbolz Date: Wed Mar 21 13:33:29 2007 New Revision: 40907 Added: pypy/extradoc/eu-report/D03.1_Extension_Compiler-2007-03-21.pdf (contents, props changed) Removed: pypy/extradoc/eu-report/D03.1_Extension_Compiler-interim-2007-02-28.pdf Log: add final version Added: pypy/extradoc/eu-report/D03.1_Extension_Compiler-2007-03-21.pdf ============================================================================== Binary file. No diff available. From cfbolz at codespeak.net Wed Mar 21 13:34:42 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 21 Mar 2007 13:34:42 +0100 (CET) Subject: [pypy-svn] r40908 - pypy/dist/pypy/doc Message-ID: <20070321123442.2DF6C1007F@code0.codespeak.net> Author: cfbolz Date: Wed Mar 21 13:34:36 2007 New Revision: 40908 Modified: pypy/dist/pypy/doc/index-report.txt Log: fix link Modified: pypy/dist/pypy/doc/index-report.txt ============================================================================== --- pypy/dist/pypy/doc/index-report.txt (original) +++ pypy/dist/pypy/doc/index-report.txt Wed Mar 21 13:34:36 2007 @@ -117,7 +117,7 @@ .. _`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 +.. _`D03.1 Extension Compiler`: http://codespeak.net/pypy/extradoc/eu-report/D03.1_Extension_Compiler-2007-03-21.pdf .. _`Interim D02.3 Testing Tool`: http://codespeak.net/pypy/extradoc/eu-report/D02.3_Testing_Framework-interim-2007-03-12.pdf .. _`Interim D01.2-4 Project Organization`: http://codespeak.net/pypy/extradoc/eu-report/D01.2-4_Project_Organization-interim-2007-03-12.pdf .. _`Interim D02.1 Development Tools and Website`: http://codespeak.net/pypy/extradoc/eu-report/D02.1_Development_Tools_and_Website-interim-2007-03-12.pdf From cfbolz at codespeak.net Wed Mar 21 13:36:41 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 21 Mar 2007 13:36:41 +0100 (CET) Subject: [pypy-svn] r40909 - pypy/dist/pypy/doc Message-ID: <20070321123641.5156E10087@code0.codespeak.net> Author: cfbolz Date: Wed Mar 21 13:36:25 2007 New Revision: 40909 Modified: pypy/dist/pypy/doc/index-report.txt Log: move to top, stop saying that it is only interim, fix date Modified: pypy/dist/pypy/doc/index-report.txt ============================================================================== --- pypy/dist/pypy/doc/index-report.txt (original) +++ pypy/dist/pypy/doc/index-report.txt Wed Mar 21 13:36:25 2007 @@ -12,6 +12,11 @@ Reports of 2007 =============== +`D03.1 Extension Compiler`_ is a report about +PyPy's extension compiler and RCTypes, as well as the effort to keep up with +CPython's changes. *(2007-03-21)* + + `Interim D12.1 High-Level-Backends and Feature Prototypes`_ is an interim version of a report about our high-level backends and our several validation prototypes: an information flow security prototype, @@ -46,10 +51,6 @@ 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. From cfbolz at codespeak.net Wed Mar 21 13:51:28 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 21 Mar 2007 13:51:28 +0100 (CET) Subject: [pypy-svn] r40911 - pypy/extradoc/eu-report Message-ID: <20070321125128.F1E3810069@code0.codespeak.net> Author: cfbolz Date: Wed Mar 21 13:51:27 2007 New Revision: 40911 Modified: pypy/extradoc/eu-report/D03.1_Extension_Compiler-2007-03-21.pdf Log: update Modified: pypy/extradoc/eu-report/D03.1_Extension_Compiler-2007-03-21.pdf ============================================================================== Binary files. No diff available. From afayolle at codespeak.net Wed Mar 21 14:01:26 2007 From: afayolle at codespeak.net (afayolle at codespeak.net) Date: Wed, 21 Mar 2007 14:01:26 +0100 (CET) Subject: [pypy-svn] r40914 - pypy/dist/pypy/lib Message-ID: <20070321130126.5C56210084@code0.codespeak.net> Author: afayolle Date: Wed Mar 21 14:01:25 2007 New Revision: 40914 Modified: pypy/dist/pypy/lib/aop.py Log: no use of stdlib's logging module Modified: pypy/dist/pypy/lib/aop.py ============================================================================== --- pypy/dist/pypy/lib/aop.py (original) +++ pypy/dist/pypy/lib/aop.py Wed Mar 21 14:01:25 2007 @@ -12,28 +12,6 @@ import sys import os import os.path as osp -from logging import error, debug, warning, info - -import logging -logging.basicConfig(level=logging.DEBUG, - format='%(asctime)s %(levelname)-8s: %(message)s', - datefmt='%H:%M:%S') - - - -def log_exc(func): - """Logs entering the function at debug level. - Logs any exception during function execution at error level""" - - def wrapped(*args, **kwargs): - try: - return func(*args, **kwargs) - except Exception, exc: - error('Unhandled exception in %s', func.func_name) - error('Exception %s: %s', exc.__class__.__name__, exc)#, exc_info=True) - raise - wrapped.__doc__ == func.__doc__ - return wrapped # advices # ------- @@ -59,7 +37,6 @@ self.pointcut) def __call__(self, function): - debug('wrapping advice %s on %s', self.pointcut, function.__name__) self.woven_code = function return self @@ -94,14 +71,12 @@ class around(Advice): """specify code to be run instead of the pointcut""" - @log_exc def weave_at_execution(self, node, tjp): """weaving around a function execution moves the body of the function to an inner function called __aoptarget___, and generate the following code: return __aop__(id, __aoptarget___) """ - debug("WEAVE around execution") p = parser id = __aop__.register_joinpoint(self.woven_code, tjp) statement = node.code @@ -120,11 +95,9 @@ node.decorators = None node.code = newcode - debug('newnode: %s', node) return node def weave_at_call(self, node, tjp): - debug("WEAVE around call") p = parser id = __aop__.register_joinpoint(self.woven_code, tjp) newnode = make_aop_call_for_around_call(id, @@ -133,7 +106,6 @@ node.star_args, node.dstar_args ) - debug('newnode: %s', newnode) return newnode def weave_at_initialization(self, node, tjp): @@ -144,25 +116,20 @@ class before(Advice): """specify code to be run before the pointcut""" - @log_exc def weave_at_execution(self, node, tjp): """weaving before execution inserts a call to __aop__(id) at the beginning of the wrapped function definition""" - debug("WEAVE before execution") id = __aop__.register_joinpoint(self.woven_code, tjp) statement_list = node.code.nodes statement_list.insert(0, make_aop_call(id)) node.code.nodes = statement_list - debug('newnode: %s', node) return node - @log_exc def weave_at_call(self, node, tjp): """weaving before call replaces a call to foo(bar) with the following code: (lambda *args,**kwargs: (__aop__(id), foo(*args,**kwargs)))(bar)[1] """ - debug("WEAVE before call") id = __aop__.register_joinpoint(self.woven_code, tjp) p = parser lambda_ret = p.ASTTuple((make_aop_call(id).expr, # we don't want the ASTDiscard @@ -183,7 +150,6 @@ newnode = p.ASTSubscript(call, p.OP_APPLY, p.ASTConst(1)) - debug('newnode: %s', newnode) return newnode def weave_at_initialization(self, node, tjp): @@ -194,31 +160,24 @@ class after(Advice): """specify code to be run after the pointcut""" - @log_exc def weave_at_execution(self, node, tjp): """weaving after execution wraps the code of the function in a try...finally block, and calls __aop__(id) in the finally block""" - debug("WEAVE after execution") id = __aop__.register_joinpoint(self.woven_code, tjp) statement = node.code tryfinally = parser.ASTTryFinally(statement, make_aop_call(id)) node.code = tryfinally - debug('newnode: %s', node) return node - @log_exc def weave_at_call(self, node, tjp): """weaving before call replaces a call to foo(bar) with the following code: __aop__(id, result=foo(bar)) """ - debug("WEAVE after call") id = __aop__.register_joinpoint(self.woven_code, tjp) p = parser - debug('old node: %s', node) newnode = make_aop_call(id, resultcallfuncnode=node).expr # we don't want the ASTDiscard - debug('newnode: %s', newnode) return newnode @@ -233,7 +192,6 @@ this is the only advice available on static point cuts""" requires_dynamic_pointcut=False def weave_at_static(self, node, tjp): - debug("WEAVE introduce!!!") p = parser id = __aop__.register_joinpoint(self.woven_code, tjp) if node.code.__class__ == p.ASTPass: @@ -265,7 +223,6 @@ methods.append(newmethod) node.code.nodes = methods - debug('newnode: %s', node) return node @@ -340,7 +297,6 @@ The created point cut is static. The pointcut argument can also be a pointcut instance""" - ##debug('%s %s %s %s', module, klass, func, pointcut) if pointcut is None: self.func_re = re.compile(func) self.module_re = re.compile(module) @@ -349,7 +305,6 @@ self.func_re = pointcut.func_re self.module_re = pointcut.module_re self.class_re = pointcut.class_re - ##debug('*** %s %s %s', self.func_re, self.module_re, self.class_re) else: raise TypeError(type(pointcut)) self.isdynamic = False @@ -570,7 +525,6 @@ return ast try: modulename = self._guessmodule(filename) - info('Looking for something to weave on %s', modulename) for aspect, advice in self.advices: self._curr_aspect = aspect ast = advice.weave(ast, enc, modulename) @@ -592,19 +546,17 @@ def register_joinpoint(self, woven_code, joinpoint, *args): # FIXME: do we need *args ? assert self._curr_aspect is not None id = self._next_id() - info("register joinpoint with id %d", id) arguments = self._curr_aspect, joinpoint, args self.joinpoints[id] = woven_code, arguments return id def __call__(self, id, target=None, target_locals = None, result=_UndefinedResult): - info('call to __aop__(%d)', id) - debug('arguments: id=%d, target=%s, target_locals=%s, result=%s', id, target, target_locals, result) woven_code, (aspect, joinpoint, arguments) = self.joinpoints[id] joinpoint.func = target - debug('target_locals = %s', target_locals) if type(target_locals) is dict: - joinpoint._arguments = (), dict([(n, target_locals[n]) for n in joinpoint._argnames or ()]) + joinpoint._arguments = (), dict([(n, target_locals[n]) for n in joinpoint._argnames or () if n != 'self']) + if 'self' in target_locals: + joinpoint._target = target_locals['self'] elif type(target_locals) is tuple: joinpoint._arguments = target_locals, {} if result is not _UndefinedResult: @@ -613,9 +565,7 @@ return woven_code(*args) def call_introduced(self, id, args): - info('call to __aop__.call_introduced(%d, *%s)', id, args) woven_code, (aspect, joinpoint, arguments) = self.joinpoints[id] - debug('woven_code: %s', woven_code) return woven_code(aspect, *args) @@ -636,7 +586,6 @@ instance = super(Aspect, cls).__call__(*args, **kwargs) for name, advice in cls.__dict__.iteritems(): if isinstance(advice, Advice): - info("registering advice %s", advice) __aop__.register_advice(instance, advice) return instance @@ -694,7 +643,6 @@ target_args, target_starargs, target_dstar_args are the values of the original ASTCallFunc """ - debug('make... %s %s %s %s %s', id, targetname, target_args, target_starargs, target_dstar_args) p = parser arguments = [p.ASTConst(id),] if targetname is not None: @@ -702,13 +650,10 @@ else: arguments.append(p.ASTName('None')) - callargs = [p.ASTList(target_args)] - + callargs = [p.ASTList(target_args)] arguments.append(p.ASTTuple(callargs)) - - - debug('arguments: %s', arguments) + return p.ASTCallFunc(p.ASTName('__aop__'), arguments, None, # *args From arigo at codespeak.net Wed Mar 21 14:20:41 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 21 Mar 2007 14:20:41 +0100 (CET) Subject: [pypy-svn] r40916 - in pypy/dist/pypy/jit/codegen: . test Message-ID: <20070321132041.A07601007B@code0.codespeak.net> Author: arigo Date: Wed Mar 21 14:20:39 2007 New Revision: 40916 Modified: pypy/dist/pypy/jit/codegen/model.py pypy/dist/pypy/jit/codegen/test/rgenop_tests.py Log: Tests and documentation about the fact that the backends shouldn't assume that the lists of live variables contain no duplicates. Modified: pypy/dist/pypy/jit/codegen/model.py ============================================================================== --- pypy/dist/pypy/jit/codegen/model.py (original) +++ pypy/dist/pypy/jit/codegen/model.py Wed Mar 21 14:20:39 2007 @@ -118,7 +118,12 @@ The current builder stays open. To make the backend\'s life easier it must be closed before the fresh builder is used at all, and the first thing to call on the latter is - start_writing().''' + start_writing(). + + args_for_jump_gv lists the variables that need to be live + after the jump is taken. The list can contain duplicates + (which the backend should ignore) but no constants. + ''' raise NotImplementedError def jump_if_true(self, gv_condition, args_for_jump_gv): @@ -151,7 +156,9 @@ few times. args_gv is the list of live variables. It\'s the list of - variables that can be used in each switch case. + variables that can be used in each switch case. The list can + contain duplicates (which the backend should ignore) but no + constants. Returns a tuple: - an instance of CodeGenSwitch (see below) @@ -177,7 +184,10 @@ while. This allows the builder to be freed. The pause_writing() method returns the next builder, on which you will have to call start_writing() before you continue. - ''' + + args_gv lists the variables that need to stay live. The list can + contain duplicates (which the backend should ignore) but no + constants.''' return self def start_writing(self): 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 Wed Mar 21 14:20:39 2007 @@ -414,9 +414,10 @@ gv_cond = builder.genop2("int_gt", gv_x, rgenop.genconst(0)) - targetbuilder = builder.jump_if_false(gv_cond, [gv_x]) + # this also tests duplicates in the lists of live vars + targetbuilder = builder.jump_if_false(gv_cond, [gv_x, gv_x]) - builder = builder.pause_writing([gv_x]) + builder = builder.pause_writing([gv_x, gv_x, gv_x]) targetbuilder.start_writing() gv_negated = targetbuilder.genop1("int_neg", gv_x) @@ -1490,7 +1491,8 @@ 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]) + # test duplicates in live vars while we're at it + flexswitch0, builder2 = builder1.flexswitch(v12, [v9, v10, v12, v10]) v13 = builder2.genop2("int_add", v9, v10) v14 = builder2.genop2("int_add", v13, v12) builder2.finish_and_return(sigtoken, v14) From ac at codespeak.net Wed Mar 21 14:30:34 2007 From: ac at codespeak.net (ac at codespeak.net) Date: Wed, 21 Mar 2007 14:30:34 +0100 (CET) Subject: [pypy-svn] r40917 - pypy/dist/pypy/objspace/std Message-ID: <20070321133034.4B3C710082@code0.codespeak.net> Author: ac Date: Wed Mar 21 14:30:32 2007 New Revision: 40917 Modified: pypy/dist/pypy/objspace/std/objspace.py Log: Have CALL_LIKELY_BUILTIN not use call_valuestack in the jitted case. Modified: pypy/dist/pypy/objspace/std/objspace.py ============================================================================== --- pypy/dist/pypy/objspace/std/objspace.py (original) +++ pypy/dist/pypy/objspace/std/objspace.py Wed Mar 21 14:30:32 2007 @@ -2,6 +2,7 @@ from pypy.interpreter.baseobjspace import ObjSpace, Wrappable from pypy.interpreter.error import OperationError, debug_print from pypy.interpreter.typedef import get_unique_interplevel_subclass +from pypy.interpreter.argument import Arguments from pypy.interpreter import pyframe from pypy.rlib.objectmodel import instantiate from pypy.interpreter.gateway import PyPyCacheDir @@ -13,7 +14,7 @@ from pypy.objspace.descroperation import DescrOperation from pypy.objspace.std import stdtypedef from pypy.rlib.rarithmetic import base_int -from pypy.rlib.objectmodel import we_are_translated, hint +from pypy.rlib.objectmodel import we_are_translated, hint, we_are_jitted import sys import os import __builtin__ @@ -109,12 +110,16 @@ f.space.wrap(message)) nargs = oparg & 0xff w_function = w_value - try: - w_result = f.space.call_valuestack(w_function, nargs, f) - # XXX XXX fix the problem of resume points! - #rstack.resume_point("CALL_FUNCTION", f, nargs, returns=w_result) - finally: - f.dropvalues(nargs) + if we_are_jitted(): + args = Arguments(f.space, f.popvalues(nargs)) + w_result = f.space.call_args(w_function, args) + else: + try: + w_result = f.space.call_valuestack(w_function, nargs, f) + # XXX XXX fix the problem of resume points! + #rstack.resume_point("CALL_FUNCTION", f, nargs, returns=w_result) + finally: + f.dropvalues(nargs) f.pushvalue(w_result) self.FrameClass = StdObjSpaceFrame From arigo at codespeak.net Wed Mar 21 14:35:30 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 21 Mar 2007 14:35:30 +0100 (CET) Subject: [pypy-svn] r40918 - pypy/dist/pypy/jit Message-ID: <20070321133530.6398010086@code0.codespeak.net> Author: arigo Date: Wed Mar 21 14:35:28 2007 New Revision: 40918 Modified: pypy/dist/pypy/jit/TODO.txt Log: Pending issue... Modified: pypy/dist/pypy/jit/TODO.txt ============================================================================== --- pypy/dist/pypy/jit/TODO.txt (original) +++ pypy/dist/pypy/jit/TODO.txt Wed Mar 21 14:35:28 2007 @@ -17,6 +17,9 @@ mmh, because we have the same variable twice (this is an invariant broken) - CALL_LIKELY_BUILTIN uses call_valuestack => bad +- 386 regalloc bug: release(gv) might release it too early if gv is + used several times by the same operation :-( + Longer-term ------------------ From arigo at codespeak.net Wed Mar 21 14:37:18 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 21 Mar 2007 14:37:18 +0100 (CET) Subject: [pypy-svn] r40919 - pypy/dist/pypy/jit Message-ID: <20070321133718.D91A21008B@code0.codespeak.net> Author: arigo Date: Wed Mar 21 14:37:17 2007 New Revision: 40919 Modified: pypy/dist/pypy/jit/TODO.txt Log: done that Modified: pypy/dist/pypy/jit/TODO.txt ============================================================================== --- pypy/dist/pypy/jit/TODO.txt (original) +++ pypy/dist/pypy/jit/TODO.txt Wed Mar 21 14:37:17 2007 @@ -9,8 +9,8 @@ - we are promoting inside space.type, there are other uses of it beyond dispatching, it may not be the best idea in general -- check that --jit works with --faassen; don't stop at - BINARY_ADD! +- check that --jit works with --faassen + - we explode in reg alloc for f(sys.maxint) (of test_pypy_c) ...! it seems we are in a flexswitch after a promote to be precise adding a bunch of printf to the c code: it seems that the inputlocatios to the reg alloc contain the same register twice From arigo at codespeak.net Wed Mar 21 14:37:45 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 21 Mar 2007 14:37:45 +0100 (CET) Subject: [pypy-svn] r40920 - pypy/dist/pypy/jit/codegen/i386 Message-ID: <20070321133745.E35781008F@code0.codespeak.net> Author: arigo Date: Wed Mar 21 14:37:44 2007 New Revision: 40920 Modified: pypy/dist/pypy/jit/codegen/i386/regalloc.py Log: Two fixes for the 386 backend. Modified: pypy/dist/pypy/jit/codegen/i386/regalloc.py ============================================================================== --- pypy/dist/pypy/jit/codegen/i386/regalloc.py (original) +++ pypy/dist/pypy/jit/codegen/i386/regalloc.py Wed Mar 21 14:37:44 2007 @@ -158,9 +158,12 @@ 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 v in self.var2loc: # duplicate inputvars_gv, which is ok + assert self.var2loc[v] == loc + else: + 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)) @@ -564,7 +567,15 @@ allocator._created(self, loc) if self.x is not None: srcop = allocator.get_operand(self.x) - allocator.mc.MOV(loc, srcop) + try: + allocator.mc.MOV(loc, srcop) + except FailedToImplement: + # loc and srcop are both in the stack - need a temporary reg + tmpop = allocator.create_scratch_reg(srcop) + # loc and srcop still valid, as they are already in the stack + # so cannot have been spilled by create_scratch_reg() + allocator.mc.MOV(loc, tmpop) + allocator.end_clobber(tmpop) allocator.release(self.x) self.x = None # hack to avoid that the Place keeps a lot of # memory around From arigo at codespeak.net Wed Mar 21 14:39:54 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 21 Mar 2007 14:39:54 +0100 (CET) Subject: [pypy-svn] r40921 - pypy/dist/pypy/translator Message-ID: <20070321133954.0ADF110093@code0.codespeak.net> Author: arigo Date: Wed Mar 21 14:39:54 2007 New Revision: 40921 Modified: pypy/dist/pypy/translator/driver.py Log: The timeshifter now supports switches, so we can do merge_if_blocks. Modified: pypy/dist/pypy/translator/driver.py ============================================================================== --- pypy/dist/pypy/translator/driver.py (original) +++ pypy/dist/pypy/translator/driver.py Wed Mar 21 14:39:54 2007 @@ -338,7 +338,7 @@ from pypy.translator.backendopt.all import backend_optimizations backend_optimizations(self.translator, inline_threshold=0, - merge_if_blocks=False, + merge_if_blocks=True, constfold=True, remove_asserts=True) # From cfbolz at codespeak.net Wed Mar 21 14:40:13 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 21 Mar 2007 14:40:13 +0100 (CET) Subject: [pypy-svn] r40922 - pypy/dist/pypy/doc/statistic Message-ID: <20070321134013.3D9F710095@code0.codespeak.net> Author: cfbolz Date: Wed Mar 21 14:40:11 2007 New Revision: 40922 Added: pypy/dist/pypy/doc/statistic/confrest.py - copied unchanged from r40884, pypy/dist/pypy/doc/weekly/confrest.py pypy/dist/pypy/doc/statistic/loc.csv - copied unchanged from r40884, pypy/dist/pypy/doc/statistic/loc.txt pypy/dist/pypy/doc/statistic/loc.png (contents, props changed) pypy/dist/pypy/doc/statistic/number_files.csv - copied unchanged from r40884, pypy/dist/pypy/doc/statistic/number_files.txt pypy/dist/pypy/doc/statistic/number_files.png (contents, props changed) pypy/dist/pypy/doc/statistic/post.csv - copied unchanged from r40884, pypy/dist/pypy/doc/statistic/post.txt pypy/dist/pypy/doc/statistic/post.png (contents, props changed) pypy/dist/pypy/doc/statistic/python-list.csv - copied unchanged from r40884, pypy/dist/pypy/doc/statistic/python-list.txt pypy/dist/pypy/doc/statistic/python-list.png (contents, props changed) pypy/dist/pypy/doc/statistic/release_dates.dat - copied unchanged from r40884, pypy/dist/pypy/doc/statistic/release_dates.csv pypy/dist/pypy/doc/statistic/sprint_dates.dat - copied unchanged from r40884, pypy/dist/pypy/doc/statistic/sprint_dates.csv pypy/dist/pypy/doc/statistic/statistic_irc_log.csv - copied unchanged from r40884, pypy/dist/pypy/doc/statistic/statistic_irc_log.txt pypy/dist/pypy/doc/statistic/statistic_irc_log.png (contents, props changed) pypy/dist/pypy/doc/statistic/style.css - copied unchanged from r40884, pypy/dist/pypy/doc/weekly/style.css pypy/dist/pypy/doc/statistic/subscribers.csv - copied unchanged from r40884, pypy/dist/pypy/doc/statistic/subscribers.txt pypy/dist/pypy/doc/statistic/subscribers.png (contents, props changed) pypy/dist/pypy/doc/statistic/webaccess.csv - copied unchanged from r40884, pypy/dist/pypy/doc/statistic/webaccess.txt pypy/dist/pypy/doc/statistic/webaccess.png (contents, props changed) Removed: pypy/dist/pypy/doc/statistic/conftest.py pypy/dist/pypy/doc/statistic/loc.txt pypy/dist/pypy/doc/statistic/number_files.txt pypy/dist/pypy/doc/statistic/post.txt pypy/dist/pypy/doc/statistic/python-list.txt pypy/dist/pypy/doc/statistic/release_dates.csv pypy/dist/pypy/doc/statistic/sprint_dates.csv pypy/dist/pypy/doc/statistic/statistic_irc_log.txt pypy/dist/pypy/doc/statistic/subscribers.txt pypy/dist/pypy/doc/statistic/webaccess.txt Modified: pypy/dist/pypy/doc/statistic/format.py Log: reorder stuff to be able to create a page showing all the graphs Modified: pypy/dist/pypy/doc/statistic/format.py ============================================================================== --- pypy/dist/pypy/doc/statistic/format.py (original) +++ pypy/dist/pypy/doc/statistic/format.py Wed Mar 21 14:40:11 2007 @@ -46,15 +46,15 @@ else: colors = "brg" -def txt2png(p): +def csv2png(p): print p title, axis, data = get_data(p) dates = data[0] - release_title, release_axis, release_data = get_data( py.path.local("release_dates.csv") ) + release_title, release_axis, release_data = get_data( py.path.local("release_dates.dat") ) release_dates, release_names = release_data - sprint_title, sprint_axis, sprint_data = get_data( py.path.local("sprint_dates.csv") ) + sprint_title, sprint_axis, sprint_data = get_data( py.path.local("sprint_dates.dat") ) sprint_locations, sprint_begin_dates, sprint_end_dates = sprint_data ax = pylab.subplot(111) @@ -111,7 +111,7 @@ py.std.sys.exit() for arg in args[1:]: if arg == "--all": - for p in py.path.local().listdir("*.txt"): + for p in py.path.local().listdir("*.csv"): py.std.os.system("python %s %s" % (args[0], p.basename)) else: - txt2png(py.path.local(arg)) + csv2png(py.path.local(arg)) Added: pypy/dist/pypy/doc/statistic/loc.png ============================================================================== Binary file. No diff available. Added: pypy/dist/pypy/doc/statistic/number_files.png ============================================================================== Binary file. No diff available. Added: pypy/dist/pypy/doc/statistic/post.png ============================================================================== Binary file. No diff available. Added: pypy/dist/pypy/doc/statistic/python-list.png ============================================================================== Binary file. No diff available. Added: pypy/dist/pypy/doc/statistic/statistic_irc_log.png ============================================================================== Binary file. No diff available. Added: pypy/dist/pypy/doc/statistic/subscribers.png ============================================================================== Binary file. No diff available. Added: pypy/dist/pypy/doc/statistic/webaccess.png ============================================================================== Binary file. No diff available. From pedronis at codespeak.net Wed Mar 21 14:42:44 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Wed, 21 Mar 2007 14:42:44 +0100 (CET) Subject: [pypy-svn] r40923 - pypy/dist/pypy/jit Message-ID: <20070321134244.573961009A@code0.codespeak.net> Author: pedronis Date: Wed Mar 21 14:42:42 2007 New Revision: 40923 Modified: pypy/dist/pypy/jit/TODO.txt Log: - one task done - postpone another after 1.0 Modified: pypy/dist/pypy/jit/TODO.txt ============================================================================== --- pypy/dist/pypy/jit/TODO.txt (original) +++ pypy/dist/pypy/jit/TODO.txt Wed Mar 21 14:42:42 2007 @@ -6,16 +6,12 @@ - basic docs and examples -- we are promoting inside space.type, there are other uses of it - beyond dispatching, it may not be the best idea in general - - check that --jit works with --faassen - we explode in reg alloc for f(sys.maxint) (of test_pypy_c) ...! it seems we are in a flexswitch after a promote to be precise adding a bunch of printf to the c code: it seems that the inputlocatios to the reg alloc contain the same register twice mmh, because we have the same variable twice (this is an invariant broken) -- CALL_LIKELY_BUILTIN uses call_valuestack => bad - 386 regalloc bug: release(gv) might release it too early if gv is used several times by the same operation :-( @@ -23,6 +19,9 @@ Longer-term ------------------ +- we are promoting inside space.type, there are other uses of it + beyond dispatching, it may not be the best idea in general + - don't follow eagerly the exception path of 'int_xxx_ovf'. - global merge point and portal should delegate their cache impl. From arigo at codespeak.net Wed Mar 21 14:43:56 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 21 Mar 2007 14:43:56 +0100 (CET) Subject: [pypy-svn] r40924 - pypy/dist/pypy/jit/codegen/llgraph Message-ID: <20070321134356.BB0701009C@code0.codespeak.net> Author: arigo Date: Wed Mar 21 14:43:55 2007 New Revision: 40924 Modified: pypy/dist/pypy/jit/codegen/llgraph/llimpl.py Log: Fix the llgraph backend for the change in codegen/model. Modified: pypy/dist/pypy/jit/codegen/llgraph/llimpl.py ============================================================================== --- pypy/dist/pypy/jit/codegen/llgraph/llimpl.py (original) +++ pypy/dist/pypy/jit/codegen/llgraph/llimpl.py Wed Mar 21 14:43:55 2007 @@ -393,6 +393,7 @@ inputvars = prevblockvars else: inputvars = _inputvars(inputargs) + inputvars = dict.fromkeys(inputvars).keys() # the link's arguments are the same as the inputvars, except # if otherlink is specified, in which case they are copied from otherlink if otherlink is None: From hpk at codespeak.net Wed Mar 21 14:44:51 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Wed, 21 Mar 2007 14:44:51 +0100 (CET) Subject: [pypy-svn] r40925 - pypy/dist/pypy/doc Message-ID: <20070321134451.3E5A110050@code0.codespeak.net> Author: hpk Date: Wed Mar 21 14:44:50 2007 New Revision: 40925 Modified: pypy/dist/pypy/doc/objspace-proxies.txt Log: fix tproxy description Modified: pypy/dist/pypy/doc/objspace-proxies.txt ============================================================================== --- pypy/dist/pypy/doc/objspace-proxies.txt (original) +++ pypy/dist/pypy/doc/objspace-proxies.txt Wed Mar 21 14:44:50 2007 @@ -28,9 +28,10 @@ * *Dump Object Space*: dumps all operations performed on all the objects into a large log file. For debugging your applications. -* *Transparent Proxies Object Space*: adds new objects that behave like - regular built-in objects (list objects, traceback objects, etc.), but - completely under the control of the application. +* *Transparent Proxies Extension*: adds new proxy objects to + the Standard Object Space that enable applications to + control operations on application and builtin objects, + e.g lists, dictionaries, tracebacks. Which object space to use can be chosen with :config:`objspace.name` option. From hpk at codespeak.net Wed Mar 21 14:45:43 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Wed, 21 Mar 2007 14:45:43 +0100 (CET) Subject: [pypy-svn] r40926 - pypy/dist/demo Message-ID: <20070321134543.DE0671009A@code0.codespeak.net> Author: hpk Date: Wed Mar 21 14:45:41 2007 New Revision: 40926 Modified: pypy/dist/demo/tp-persistence.py Log: use sets (pypy always has them) Modified: pypy/dist/demo/tp-persistence.py ============================================================================== --- pypy/dist/demo/tp-persistence.py (original) +++ pypy/dist/demo/tp-persistence.py Wed Mar 21 14:45:41 2007 @@ -7,9 +7,9 @@ from pypymagic import transparent_proxy, get_transparent_controller from tputil import make_proxy -list_changeops = ('__iadd__ __imul__ __delitem__ __setitem__ ' - '__delslice__ __setslice__ ' - 'append extend insert pop remove reverse sort').split() +list_changeops = set('__iadd__ __imul__ __delitem__ __setitem__ ' + '__delslice__ __setslice__ ' + 'append extend insert pop remove reverse sort'.split()) def make_plist(instance, storage): def perform(invocation): @@ -48,4 +48,3 @@ restoredlist = get_plist(storage) print "restored list 2", restoredlist assert restoredlist == [1,2,3,4,5,6,7] * 2 - From pedronis at codespeak.net Wed Mar 21 14:58:01 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Wed, 21 Mar 2007 14:58:01 +0100 (CET) Subject: [pypy-svn] r40930 - pypy/dist/pypy/jit/codegen/test Message-ID: <20070321135801.2E86C100A0@code0.codespeak.net> Author: pedronis Date: Wed Mar 21 14:57:59 2007 New Revision: 40930 Modified: pypy/dist/pypy/jit/codegen/test/rgenop_tests.py Log: change the test to not use a 'for', to odd a setup for the llgraph case to catch the StopIteration. 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 Wed Mar 21 14:57:59 2007 @@ -722,7 +722,10 @@ def __init__(self, RGenOp): def writer(base, value): i = 0 - for p in self.places: + places = self.places + n = len(places) + while i < n: + p = places[i] RGenOp.write_frame_place(lltype.Signed, base, p, value + i) i += 1 self.writer = writer From hpk at codespeak.net Wed Mar 21 15:05:45 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Wed, 21 Mar 2007 15:05:45 +0100 (CET) Subject: [pypy-svn] r40932 - in pypy/dist: demo pypy/doc pypy/lib pypy/lib/distributed pypy/lib/test2 pypy/objspace/std pypy/objspace/std/test Message-ID: <20070321140545.06F5610093@code0.codespeak.net> Author: hpk Date: Wed Mar 21 15:05:42 2007 New Revision: 40932 Modified: pypy/dist/demo/tp-persistence.py pypy/dist/pypy/doc/objspace-proxies.txt pypy/dist/pypy/lib/distributed/protocol.py pypy/dist/pypy/lib/test2/test_tputil.py pypy/dist/pypy/lib/tputil.py pypy/dist/pypy/objspace/std/objspace.py pypy/dist/pypy/objspace/std/test/test_proxy.py pypy/dist/pypy/objspace/std/test/test_proxy_function.py pypy/dist/pypy/objspace/std/test/test_proxy_internals.py pypy/dist/pypy/objspace/std/test/test_proxy_object.py Log: consistently rename transparent_proxy to tproxy and get_transparent_controller to get_tproxy_controller and make_proxy to make_instance_proxy (not completely sure about the last one but i'd like to distinguish the name a bit from the more "virtual" tproxy operating on types whereas make_instance_proxy helps to proxy an existing object (you can still provide a type if you wish)) Modified: pypy/dist/demo/tp-persistence.py ============================================================================== --- pypy/dist/demo/tp-persistence.py (original) +++ pypy/dist/demo/tp-persistence.py Wed Mar 21 15:05:42 2007 @@ -4,8 +4,8 @@ mechanism on top of PyPy's transparent proxies. """ -from pypymagic import transparent_proxy, get_transparent_controller -from tputil import make_proxy +from pypymagic import tproxy, get_tproxy_controller +from tputil import make_instance_proxy list_changeops = set('__iadd__ __imul__ __delitem__ __setitem__ ' '__delslice__ __setslice__ ' @@ -17,7 +17,7 @@ if invocation.opname in list_changeops: storage.dump(instance) return res - return make_proxy(instance, perform, typ=list) + return make_instance_proxy(instance, perform, typ=list) def get_plist(storage): obj = storage.load() Modified: pypy/dist/pypy/doc/objspace-proxies.txt ============================================================================== --- pypy/dist/pypy/doc/objspace-proxies.txt (original) +++ pypy/dist/pypy/doc/objspace-proxies.txt Wed Mar 21 15:05:42 2007 @@ -468,13 +468,13 @@ return ``42`` on any add operation to the list:: $ py.py --with-transparent-proxy - >>>> from pypymagic import transparent_proxy + >>>> from pypymagic import tproxy >>>> def f(operation, *args, **kwargs): >>>> if operation == '__add__': >>>> return 42 >>>> raise AttributeError >>>> - >>>> i = transparent_proxy(list, f) + >>>> i = tproxy(list, f) >>>> type(i) list >>>> i + 3 @@ -493,14 +493,14 @@ it for later analysis. We use a small `tputil.py`_ module that helps with transparently proxying builtin instances:: - from tputil import make_proxy + from tputil import make_instance_proxy history = [] def recorder(invocation): history.append(invocation) return invocation.perform() - >>>> l = make_proxy([], recorder) + >>>> l = make_instance_proxy([], recorder) >>>> type(l) list >>>> l.append(3) @@ -533,9 +533,9 @@ Transparent proxy provides two functions in the pypymagic module. -* `transparent_proxy` - a basic function to create proxy object. +* `tproxy` - a basic function to create proxy object. -* `get_transparent_controller` - for some use-cases there is need to know +* `get_tproxy_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. Modified: pypy/dist/pypy/lib/distributed/protocol.py ============================================================================== --- pypy/dist/pypy/lib/distributed/protocol.py (original) +++ pypy/dist/pypy/lib/distributed/protocol.py Wed Mar 21 15:05:42 2007 @@ -36,8 +36,8 @@ """ try: - from pypymagic import transparent_proxy as proxy - from pypymagic import get_transparent_controller + from pypymagic import tproxy as proxy + from pypymagic import get_tproxy_controller except ImportError: raise ImportError("Cannot work without transparent proxy functionality") @@ -112,7 +112,7 @@ return False tp = type(obj) - ctrl = get_transparent_controller(obj) + ctrl = get_tproxy_controller(obj) if ctrl: return "tp", self.keeper.get_remote_object(ctrl) elif obj is None: Modified: pypy/dist/pypy/lib/test2/test_tputil.py ============================================================================== --- pypy/dist/pypy/lib/test2/test_tputil.py (original) +++ pypy/dist/pypy/lib/test2/test_tputil.py Wed Mar 21 15:05:42 2007 @@ -5,12 +5,12 @@ cls.space = gettestobjspace(**{"objspace.std.withtproxy": True}) def test_listproxy_basic(self): - from tputil import make_proxy + from tputil import make_instance_proxy record = [] def func(invocation): record.append(invocation) return invocation.perform() - l = make_proxy([], func) + l = make_instance_proxy([], func) l.append(1) assert len(record) == 2 i1, i2 = record @@ -18,7 +18,7 @@ assert i2.opname == 'append' def test_proxy_double(self): - from tputil import make_proxy + from tputil import make_instance_proxy r1 = [] r2 = [] def func1(invocation): @@ -28,8 +28,8 @@ r2.append(invocation) return invocation.perform() - l = make_proxy([], func1) - l2 = make_proxy(l, func2) + l = make_instance_proxy([], func1) + l2 = make_instance_proxy(l, func2) assert not r1 and not r2 l2.append assert len(r2) == 1 Modified: pypy/dist/pypy/lib/tputil.py ============================================================================== --- pypy/dist/pypy/lib/tputil.py (original) +++ pypy/dist/pypy/lib/tputil.py Wed Mar 21 15:05:42 2007 @@ -7,16 +7,16 @@ the proxied object. """ -from pypymagic import transparent_proxy +from pypymagic import tproxy from types import MethodType -def make_proxy(instance, invokefunc=None, typ=None): +def make_instance_proxy(instance, invokefunc=None, typ=None): if typ is None: typ = type(instance) def perform(opname, *args, **kwargs): invocation = Invocation(tp, instance, opname, args, kwargs) return invokefunc(invocation) - tp = transparent_proxy(typ, perform) + tp = tproxy(typ, perform) return tp class Invocation(object): Modified: pypy/dist/pypy/objspace/std/objspace.py ============================================================================== --- pypy/dist/pypy/objspace/std/objspace.py (original) +++ pypy/dist/pypy/objspace/std/objspace.py Wed Mar 21 15:05:42 2007 @@ -215,9 +215,9 @@ w_pypymagic = self.getbuiltinmodule("pypymagic") from pypy.objspace.std.transparent import app_proxy, app_proxy_controller - self.setattr(w_pypymagic, self.wrap('transparent_proxy'), + self.setattr(w_pypymagic, self.wrap('tproxy'), self.wrap(app_proxy)) - self.setattr(w_pypymagic, self.wrap('get_transparent_controller'), + self.setattr(w_pypymagic, self.wrap('get_tproxy_controller'), self.wrap(app_proxy_controller)) def enable_old_style_classes_as_default_metaclass(self): Modified: pypy/dist/pypy/objspace/std/test/test_proxy.py ============================================================================== --- pypy/dist/pypy/objspace/std/test/test_proxy.py (original) +++ pypy/dist/pypy/objspace/std/test/test_proxy.py Wed Mar 21 15:05:42 2007 @@ -19,8 +19,8 @@ return Controller """) self.w_proxy = self.space.appexec([], """(): - from pypymagic import transparent_proxy - return transparent_proxy + from pypymagic import tproxy + return tproxy """) class AppTestListProxy(AppProxyBasic): Modified: pypy/dist/pypy/objspace/std/test/test_proxy_function.py ============================================================================== --- pypy/dist/pypy/objspace/std/test/test_proxy_function.py (original) +++ pypy/dist/pypy/objspace/std/test/test_proxy_function.py Wed Mar 21 15:05:42 2007 @@ -19,7 +19,7 @@ return getattr(self.obj, name)(*args, **kwargs) def get_proxy(f): import types - from pypymagic import transparent_proxy as proxy + from pypymagic import tproxy as proxy return proxy(types.FunctionType, Controller(f).perform) return get_proxy """) @@ -90,7 +90,7 @@ class AA: pass - from pypymagic import transparent_proxy as proxy + from pypymagic import tproxy as proxy a = A() class X: def __init__(self, x): Modified: pypy/dist/pypy/objspace/std/test/test_proxy_internals.py ============================================================================== --- pypy/dist/pypy/objspace/std/test/test_proxy_internals.py (original) +++ pypy/dist/pypy/objspace/std/test/test_proxy_internals.py Wed Mar 21 15:05:42 2007 @@ -16,7 +16,7 @@ def perform(self, name, *args, **kwargs): return getattr(self.obj, name)(*args, **kwargs) def get_proxy(f): - from pypymagic import transparent_proxy as proxy + from pypymagic import tproxy as proxy return proxy(type(f), Controller(f).perform) return get_proxy """) @@ -71,7 +71,7 @@ import traceback def get_proxy(f): - from pypymagic import transparent_proxy as proxy + from pypymagic import tproxy as proxy return proxy(type(f), Controller(f).perform) class FakeTb(object): @@ -115,12 +115,12 @@ assert traceback.format_tb(last_tb) == traceback.format_tb(e[2]) def test_proxy_get(self): - from pypymagic import transparent_proxy, get_transparent_controller + from pypymagic import tproxy, get_tproxy_controller l = [1,2,3] def f(name, *args, **kwargs): return getattr(l, name)(*args, **kwargs) - lst = transparent_proxy(list, f) - assert get_transparent_controller(lst) is f + lst = tproxy(list, f) + assert get_tproxy_controller(lst) is f class DONTAppTestProxyType(AppProxy): def test_filetype(self): Modified: pypy/dist/pypy/objspace/std/test/test_proxy_object.py ============================================================================== --- pypy/dist/pypy/objspace/std/test/test_proxy_object.py (original) +++ pypy/dist/pypy/objspace/std/test/test_proxy_object.py Wed Mar 21 15:05:42 2007 @@ -13,8 +13,8 @@ return A """) self.w_proxy = self.space.appexec([], """(): - from pypymagic import transparent_proxy - return transparent_proxy + from pypymagic import tproxy + return tproxy """) def test_write_dict(self): @@ -106,8 +106,8 @@ return A """) self.w_proxy = self.space.appexec([], """(): - from pypymagic import transparent_proxy - return transparent_proxy + from pypymagic import tproxy + return tproxy """) From cfbolz at codespeak.net Wed Mar 21 15:07:21 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 21 Mar 2007 15:07:21 +0100 (CET) Subject: [pypy-svn] r40933 - pypy/dist/pypy/doc/statistic Message-ID: <20070321140721.137DF10095@code0.codespeak.net> Author: cfbolz Date: Wed Mar 21 15:07:19 2007 New Revision: 40933 Added: pypy/dist/pypy/doc/statistic/index.txt (contents, props changed) Log: add index.txt containing all the images Added: pypy/dist/pypy/doc/statistic/index.txt ============================================================================== --- (empty file) +++ pypy/dist/pypy/doc/statistic/index.txt Wed Mar 21 15:07:19 2007 @@ -0,0 +1,67 @@ +======================= +PyPy Project Statistics +======================= + +This page collects some statistics (updated in irregular intervals) about the +PyPy project. + +Lines of Code +============= + +Lines of code and lines of test code below +the ``pypy/dist/pypy`` tree: + +.. image:: loc.png + + +Number of Files +=============== + +Number of non-test files and the number of test +files below the ``pypy/dist/pypy`` tree: + +.. image:: number_files.png + + +Subscribers to mailing lists +============================ + +Number of people subscribed to the `pypy-dev`_ and `pypy-svn`_ mailing lists: + +.. image:: subscribers.png + + +Posts to mailing lists +====================== + +Number of posts to the `pypy-dev`_ and `pypy-svn`_ mailing lists: + +.. image:: post.png + + +IRC channel activity +==================== + +Written lines in the #pypy irc channel: + +.. image:: statistic_irc_log.png + + +comp.lang.python +================ + +Mentions of the terms "pypy" and "py.test" on comp.lang.python: + +.. image:: python-list.png + + +Web access +========== + +Page hits to http://codespeak.net/pypy/: + + +.. image:: webaccess.png + +.. _`pypy-dev`: http://codespeak.net/mailman/listinfo/pypy-svn +.. _`pypy-svn`: http://codespeak.net/mailman/listinfo/pypy-dev From afayolle at codespeak.net Wed Mar 21 15:09:31 2007 From: afayolle at codespeak.net (afayolle at codespeak.net) Date: Wed, 21 Mar 2007 15:09:31 +0100 (CET) Subject: [pypy-svn] r40934 - in pypy/dist: demo pypy/lib Message-ID: <20070321140931.4523310093@code0.codespeak.net> Author: afayolle Date: Wed Mar 21 15:09:30 2007 New Revision: 40934 Added: pypy/dist/demo/contract_stack.py (contents, props changed) pypy/dist/demo/contracts.py (contents, props changed) pypy/dist/pypy/lib/dbc.py (contents, props changed) Log: simple design by contract module built on top of aop.py, and demo Added: pypy/dist/demo/contract_stack.py ============================================================================== --- (empty file) +++ pypy/dist/demo/contract_stack.py Wed Mar 21 15:09:30 2007 @@ -0,0 +1,50 @@ + +class Stack: + """A very simple stack interface + (not very useful in Python) + """ + + def __init__(self, max_size = 10): + self.max_size = max_size + self.elements = [] + + def _pre_pop(self): + return not self.is_empty() + def _post_pop(self, old, ret): + return ret == old.top() and \ + self.size() == old.size() - 1 + def pop(self): + return self.elements.pop() + + + def _pre_push(self, obj): + return obj is not None and not self.is_full() + def _post_push(self, old, ret, obj): + return not self.is_empty() and (self.top() == obj) + def push(self, obj): + self.elements.append(obj) + + + def top(self): + """Returns the top element of the stack + """ + return self.elements[-1] + + def is_empty(self): + """Tells whether or not the stack is empty + """ + return not bool(self.elements) + + + def is_full(self): + """Tells whether or not the stack is full + """ + return len(self.elements) == self.max_size + + def size(self): + """Returns the current size of the stack + """ + return len(self.elements) + + def __str__(self): + return "elements = %s, max_size = %s" % (self.elements, self.max_size) Added: pypy/dist/demo/contracts.py ============================================================================== --- (empty file) +++ pypy/dist/demo/contracts.py Wed Mar 21 15:09:30 2007 @@ -0,0 +1,41 @@ +from dbc import ContractAspect, ContractError +ContractAspect() +from contract_stack import Stack + +def run(): + """This is an example of how contracts work + """ + print "*"*30 + print "Creating an empty stack (max_size = 3)" + stack = Stack(3) + + try: + print "Empty stack, pop() should fail" + stack.pop() + except ContractError, excpt: + print "\t failed with %s, (OK)" % excpt + else: + print "\t did not failed, (XXX)" + + print "\n\n\n" + stack.push(1) + print "push 1 done" + stack.push(2) + print "push 2 done" + stack.push(3) + print "push 3 done" + + try: + print "The stack is full, push() should fail" + stack.push(4) + except ContractError, excpt: + print "\t failed with %s, (OK)" % excpt + else: + print "\t did not failed, (XXX)" + + print "\n\n\n" + + + +if __name__ == '__main__': + run() Added: pypy/dist/pypy/lib/dbc.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/lib/dbc.py Wed Mar 21 15:09:30 2007 @@ -0,0 +1,42 @@ +__all__ = ['ContractAspect', 'ContractError', 'PreconditionError', 'PostConditionError'] +from aop import * +from copy import deepcopy +class ContractAspect: + __metaclass__ = Aspect + def __init__(self): + self.initial_state = {} + + @around(PointCut(func='[^_].*', klass='.+').execution()) + def contract_check(self, tjp): + target = tjp.target() + args, kwargs = tjp.arguments() + try: + prefunc = getattr(target, '_pre_%s' % tjp.name()) + except AttributeError: + prefunc = None + try: + postfunc = getattr(target, '_post_%s' % tjp.name()) + except AttributeError: + postfunc = None + else: + oldtarget = deepcopy(target) + + if prefunc is not None: + status = prefunc(*args, **kwargs) + if not status: + raise PreconditionError(tjp.name()) + tjp.proceed(target, *args, **kwargs) + if postfunc is not None: + if not postfunc(oldtarget, tjp.result(), *args, **kwargs): + raise PostconditionError(tjp.name()) + return tjp.result() + + +class ContractError(StandardError): + pass + +class PreconditionError(ContractError): + pass + +class PostconditionError(ContractError): + pass From cfbolz at codespeak.net Wed Mar 21 15:10:32 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 21 Mar 2007 15:10:32 +0100 (CET) Subject: [pypy-svn] r40935 - pypy/dist/pypy/doc Message-ID: <20070321141032.D77F810093@code0.codespeak.net> Author: cfbolz Date: Wed Mar 21 15:10:30 2007 New Revision: 40935 Modified: pypy/dist/pypy/doc/index.txt Log: link to statistics page Modified: pypy/dist/pypy/doc/index.txt ============================================================================== --- pypy/dist/pypy/doc/index.txt (original) +++ pypy/dist/pypy/doc/index.txt Wed Mar 21 15:10:30 2007 @@ -81,7 +81,9 @@ `compliance test status`_ shows outcomes of compliance test runs against PyPy on top of CPython. -`PyPy statistics`_ shows LOC statistics about PyPy. +`PyPy LOC statistics`_ shows LOC statistics about PyPy. + +`PyPy statistics`_ is a page with various statistics about the PyPy project. Source Code Documentation @@ -138,7 +140,8 @@ .. _`license`: ../../LICENSE .. _`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/ +.. _`PyPy LOC statistics`: http://codespeak.net/~hpk/pypy-stat/ +.. _`PyPy statistics`: http://codespeak.net/pypy/dist/pypy/doc/statistic .. _`object spaces`: objspace.html .. _`object optimizations`: object-optimizations.html .. _`translation`: translation.html From cfbolz at codespeak.net Wed Mar 21 15:12:55 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 21 Mar 2007 15:12:55 +0100 (CET) Subject: [pypy-svn] r40936 - pypy/dist/pypy/doc/statistic Message-ID: <20070321141255.41E4C10093@code0.codespeak.net> Author: cfbolz Date: Wed Mar 21 15:12:53 2007 New Revision: 40936 Modified: pypy/dist/pypy/doc/statistic/ (props changed) Log: ignore pdf and eps files From antocuni at codespeak.net Wed Mar 21 15:30:43 2007 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Wed, 21 Mar 2007 15:30:43 +0100 (CET) Subject: [pypy-svn] r40939 - pypy/dist/pypy/translator/cli Message-ID: <20070321143043.E90AD1009F@code0.codespeak.net> Author: antocuni Date: Wed Mar 21 15:30:42 2007 New Revision: 40939 Modified: pypy/dist/pypy/translator/cli/rte.py pypy/dist/pypy/translator/cli/sdk.py Log: When on windows, try to find if mono is installed and in that case use its ilasm2 for assembling files, because the one shipped with Microsoft CLR can't compile pypy-cli. Modified: pypy/dist/pypy/translator/cli/rte.py ============================================================================== --- pypy/dist/pypy/translator/cli/rte.py (original) +++ pypy/dist/pypy/translator/cli/rte.py Wed Mar 21 15:30:42 2007 @@ -5,7 +5,6 @@ import os import os.path -import platform import shutil import py Modified: pypy/dist/pypy/translator/cli/sdk.py ============================================================================== --- pypy/dist/pypy/translator/cli/sdk.py (original) +++ pypy/dist/pypy/translator/cli/sdk.py Wed Mar 21 15:30:42 2007 @@ -1,3 +1,4 @@ +import os.path import platform import py @@ -39,7 +40,48 @@ CSC = 'gmcs' PEVERIFY = 'peverify' # it's not part of mono, but we get a meaningful skip message -if platform.system() == 'Windows': - SDK = MicrosoftSDK -else: - SDK = MonoSDK +def key_as_dict(handle): + import _winreg + i = 0 + res = {} + while True: + try: + name, value, type_ = _winreg.EnumValue(handle, i) + res[name] = value + i += 1 + except WindowsError: + break + return res + +def find_mono_on_windows(): + if platform.system() != 'Windows': + return None + import _winreg + try: + hMono = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, "Software\\Novell\\Mono") + except WindowsError: # mono seems not installed + return None + + mono = key_as_dict(hMono) + mono_version = mono.get('DefaultCLR', None) + if mono_version is None: + return None + hMono.Close() + + hMono_data = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, "Software\\Novell\\Mono\\%s" % mono_version) + mono_data = key_as_dict(hMono_data) + mono_dir = str(mono_data['SdkInstallRoot']) + return os.path.join(mono_dir, 'bin') + +def get_default_SDK(): + if platform.system() == 'Windows': + SDK = MicrosoftSDK + # if present, use mono ilasm2 instead of MS ilasm + mono_bin = find_mono_on_windows() + if mono_bin is not None: + SDK.ILASM = os.path.join(mono_bin, 'ilasm2.bat') + else: + SDK = MonoSDK + return SDK + +SDK = get_default_SDK() From mwh at codespeak.net Wed Mar 21 15:46:29 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Wed, 21 Mar 2007 15:46:29 +0100 (CET) Subject: [pypy-svn] r40940 - in pypy/dist/pypy: jit/codegen/ppc rpython translator/c translator/c/src Message-ID: <20070321144629.9F67210090@code0.codespeak.net> Author: mwh Date: Wed Mar 21 15:46:27 2007 New Revision: 40940 Added: pypy/dist/pypy/jit/codegen/ppc/_flush_icache.c Modified: pypy/dist/pypy/jit/codegen/ppc/rgenop.py pypy/dist/pypy/rpython/extfuncregistry.py pypy/dist/pypy/translator/c/extfunc.py pypy/dist/pypy/translator/c/src/g_include.h Log: flush the icache after we generate code Added: pypy/dist/pypy/jit/codegen/ppc/_flush_icache.c ============================================================================== --- (empty file) +++ pypy/dist/pypy/jit/codegen/ppc/_flush_icache.c Wed Mar 21 15:46:27 2007 @@ -0,0 +1,20 @@ +#include +#include "../../../translator/c/src/asm_ppc.h" + +static PyObject* +_flush_icache(PyObject *self, PyObject *args) +{ + Py_INCREF(Py_None); + return Py_None; +} + +PyMethodDef _flush_icache_methods[] = { + {"_flush_icache", _flush_icache, METH_VARARGS, ""}, + {0, 0} +}; + +PyMODINIT_FUNC +init_flush_icache(void) +{ + Py_InitModule("_flush_icache", _flush_icache_methods); +} 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 Wed Mar 21 15:46:27 2007 @@ -6,7 +6,7 @@ from pypy.rpython.lltypesystem import lloperation from pypy.rlib.objectmodel import specialize, we_are_translated from pypy.jit.codegen.conftest import option -from ctypes import POINTER, cast, c_void_p, c_int +from ctypes import POINTER, cast, c_void_p, c_int, CFUNCTYPE from pypy.jit.codegen.ppc import codebuf from pypy.jit.codegen.ppc.instruction import rSP, rFP, rSCRATCH, gprs @@ -18,6 +18,7 @@ from pypy.jit.codegen.ppc.ppcgen.ppc_assembler import MyPPCAssembler from pypy.jit.codegen.i386.rgenop import gc_malloc_fnaddr +from pypy.rpython.annlowlevel import llhelper class RPPCAssembler(make_rassembler(MyPPCAssembler)): def emit(self, value): @@ -26,6 +27,14 @@ _PPC = RPPCAssembler +_flush_icache = None +def flush_icache(base, size): + global _flush_icache + if _flush_icache == None: + cpath = py.magic.autopath().dirpath().join('_flush_icache.c') + _flush_icache = cpath._getpymodule()._flush_icache + _flush_icache(base, size) + NSAVEDREGISTERS = 19 DEBUG_TRAP = option.trap @@ -652,9 +661,13 @@ def _open(self): self.asm.mc = self.rgenop.open_mc() + self._code_start = self.asm.mc.tell() self.closed = False def _close(self): + _code_stop = self.asm.mc.tell() + code_size = self._code_start - _code_stop + flush_icache(self._code_start, code_size) self.rgenop.close_mc(self.asm.mc) self.asm.mc = None Modified: pypy/dist/pypy/rpython/extfuncregistry.py ============================================================================== --- pypy/dist/pypy/rpython/extfuncregistry.py (original) +++ pypy/dist/pypy/rpython/extfuncregistry.py Wed Mar 21 15:46:27 2007 @@ -51,6 +51,12 @@ annotation_hook = hook) # ___________________________ +# bit of magic for the ppc jit +from pypy.jit.codegen.ppc.rgenop import flush_icache +register_external(flush_icache, [int, int], None, "LL_flush_icache") + + +# ___________________________ # os.path functions from pypy.tool.sourcetools import func_with_new_name Modified: pypy/dist/pypy/translator/c/extfunc.py ============================================================================== --- pypy/dist/pypy/translator/c/extfunc.py (original) +++ pypy/dist/pypy/translator/c/extfunc.py Wed Mar 21 15:46:27 2007 @@ -99,6 +99,7 @@ for name in math_functions: EXTERNALS['ll_math.ll_math_%s' % name] = 'LL_math_%s' % name +EXTERNALS['LL_flush_icache'] = 'LL_flush_icache' #______________________________________________________ Modified: pypy/dist/pypy/translator/c/src/g_include.h ============================================================================== --- pypy/dist/pypy/translator/c/src/g_include.h (original) +++ pypy/dist/pypy/translator/c/src/g_include.h Wed Mar 21 15:46:27 2007 @@ -43,6 +43,11 @@ # include "src/asm_gcc_x86.h" #endif +#if defined(__GNUC__) && defined(__ppc__) +# include "src/asm_ppc.h" +#endif + + /*** modules ***/ #ifdef HAVE_RTYPER /* only if we have an RTyper */ # include "src/rtyper.h" From hpk at codespeak.net Wed Mar 21 15:47:06 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Wed, 21 Mar 2007 15:47:06 +0100 (CET) Subject: [pypy-svn] r40941 - pypy/dist/pypy/doc Message-ID: <20070321144706.8082010093@code0.codespeak.net> Author: hpk Date: Wed Mar 21 15:47:05 2007 New Revision: 40941 Modified: pypy/dist/pypy/doc/objspace-proxies.txt Log: some progress/review of documentation on tproxies Modified: pypy/dist/pypy/doc/objspace-proxies.txt ============================================================================== --- pypy/dist/pypy/doc/objspace-proxies.txt (original) +++ pypy/dist/pypy/doc/objspace-proxies.txt Wed Mar 21 15:47:05 2007 @@ -450,16 +450,15 @@ .. _tproxy: -Transparent Proxy Implementation +Transparent Proxies ================================ PyPy's Transparent Proxies allow to route operations to objects to a callable. Application level code can customize e.g. list and dictionary objects without interfering with the type system, -for example ``type(proxy_list) is list`` can be true but you -you have full control on all operations that are performed on the -``proxy_list``. - +i.e. ``type(proxied_list) is list`` holds true while still +giving you full control on all operations that are performed on the +``proxied_list``. Example of the core mechanism ------------------------------------------- @@ -486,11 +485,8 @@ Example of recording all operations on builtins ---------------------------------------------------- -XXX describe tputil.py's "Invocation" object somewhere -XXX this is work in progress - Suppose we want to have list which stores all operations performed on -it for later analysis. We use a small `tputil.py`_ module that helps +it for later analysis. We use a small `tputil`_ module that helps with transparently proxying builtin instances:: from tputil import make_instance_proxy @@ -509,7 +505,7 @@ >>>> len(history) 4 -So what happened: +So what happened (XXX): * We've create transparent proxy of type list with controller c.perform @@ -525,22 +521,38 @@ does not show up at all (indeed the type is the only aspect of the instance that the controller cannot change). +.. _`transparent proxy builtins`: -Basic and tputil.py API ------------------------------ +Transparent Proxy PyPy Builtins +-------------------------------------- + +If you are using the `--with-transparent-proxies` option +the `pypymagic`_ module provides the following builtins: + +* ``tproxy(type, controller)``: returns a proxy object + representing the given type and forwarding all operations + on this type to the controller. On each such operation + ``controller(opname, *args, **kwargs)`` is invoked. + +* ``get_tproxy_controller(obj)``: returns the responsible + controller for a given object. For non-proxied objects + ``None`` is returned. + +.. _pypymagic: -XXX (hpk) refactor/amend/refine +.. _tputil: -Transparent proxy provides two functions in the pypymagic module. +tputil help module +---------------------------- -* `tproxy` - a basic function to create proxy object. +The `tputil.py`_ module helps writing programs that +make use of transparent proxies. Apart from the +`transparent proxy builtins`_ it provides +the following functionality: -* `get_tproxy_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. +XXX -Further points of interest: +Further points of interest --------------------------- A lot of tasks could be performed using transparent proxies. Including, @@ -556,7 +568,7 @@ objects. (Of course some operations on them could raise exceptions, but it's purely done in application level, so it's not real problem) -Implementation Note +Implementation Notes ----------------------------- PyPy's standard object space allows to internally have multiple From antocuni at codespeak.net Wed Mar 21 15:47:53 2007 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Wed, 21 Mar 2007 15:47:53 +0100 (CET) Subject: [pypy-svn] r40942 - pypy/dist/pypy/doc Message-ID: <20070321144753.D591E10090@code0.codespeak.net> Author: antocuni Date: Wed Mar 21 15:47:52 2007 New Revision: 40942 Modified: pypy/dist/pypy/doc/cli-backend.txt pypy/dist/pypy/doc/getting-started.txt Log: update some infos about gencli Modified: pypy/dist/pypy/doc/cli-backend.txt ============================================================================== --- pypy/dist/pypy/doc/cli-backend.txt (original) +++ pypy/dist/pypy/doc/cli-backend.txt Wed Mar 21 15:47:52 2007 @@ -85,9 +85,15 @@ =============== ======== ====== 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. +module: it defines an abstract class which exposes some methods +returning the name of the helpers and one subclass for each of the two +supported platforms. + +Since Microfost ``ilasm`` is not capable of compiling the PyPy +standard interpreter due to its size, on Windows machines we also look +for an existing Mono installation: if present, we use CLR for +everything except the assembling phase, for which we use Mono's +``ilasm2``. Targeting the CLI Virtual Machine Modified: pypy/dist/pypy/doc/getting-started.txt ============================================================================== --- pypy/dist/pypy/doc/getting-started.txt (original) +++ pypy/dist/pypy/doc/getting-started.txt Wed Mar 21 15:47:52 2007 @@ -701,16 +701,17 @@ 2 >>>> -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; +Unfortunately, at the moment it's not possible to do the full +translation using only the tools provided by the Microsoft .NET SDK, +since ``ilasm`` crashes when trying to assemble the pypy-cli code due +to its size. 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 -Microsoft Runtime. +Windows users that want to compile their own pypy-cli can install +Mono_: if a Mono installation is detected the translation toolchain +will automatically use its ``ilasm2`` tool to assemble the +executables. Trying the experimental .NET integration ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ From mwh at codespeak.net Wed Mar 21 15:51:07 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Wed, 21 Mar 2007 15:51:07 +0100 (CET) Subject: [pypy-svn] r40944 - pypy/dist/pypy/translator/c/src Message-ID: <20070321145107.4AC201009F@code0.codespeak.net> Author: mwh Date: Wed Mar 21 15:51:05 2007 New Revision: 40944 Added: pypy/dist/pypy/translator/c/src/asm_ppc.h Log: forgot this, thanks cfbolz! Added: pypy/dist/pypy/translator/c/src/asm_ppc.h ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/c/src/asm_ppc.h Wed Mar 21 15:51:05 2007 @@ -0,0 +1,29 @@ + +void LL_flush_icache(long base, long size); + +#ifndef PYPY_NOT_MAIN_FILE + +#define __dcbst(base, index) \ + __asm__ ("dcbst %0, %1" : /*no result*/ : "b%" (index), "r" (base) : "memory") +#define __icbi(base, index) \ + __asm__ ("icbi %0, %1" : /*no result*/ : "b%" (index), "r" (base) : "memory") +#define __sync() __asm__ volatile ("sync") +#define __isync() \ + __asm__ volatile ("isync") + +void +LL_flush_icache(long base, long size) +{ + long i; + + for (i = 0; i < size; i += 32){ + __dcbst(base, i); + } + __sync(); + for (i = 0; i < size; i += 32){ + __icbi(base, i); + } + __isync(); +} + +#endif From santagada at codespeak.net Wed Mar 21 17:00:25 2007 From: santagada at codespeak.net (santagada at codespeak.net) Date: Wed, 21 Mar 2007 17:00:25 +0100 (CET) Subject: [pypy-svn] r40947 - pypy/dist/pypy/lang/js/test Message-ID: <20070321160025.1E4AC10074@code0.codespeak.net> Author: santagada Date: Wed Mar 21 17:00:23 2007 New Revision: 40947 Modified: pypy/dist/pypy/lang/js/test/test_interp.py Log: new tests sugested by fijal and guido_w 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 Wed Mar 21 17:00:23 2007 @@ -509,3 +509,34 @@ for (var arg = "", i = 0; i < 2; i++) { print(i)} """, ['0', '1']) + def test_recursive_call(self): + py.test.skip() + self.assert_prints(""" + function f(x) { if (x == 0) { return 1; } else { return f(x-1)*x; }} + print(f(3)) + """, ['6',]) + + def test_recursive_call(self): + py.test.skip() + self.assert_prints(""" + function f(x) { if (x == 0) { return 1; } else { return f(x-1)*x; }} + print(f(3)) + """, ['6',]) + + def test_function_prototype(self): + py.test.skip() + self.assert_prints(""" + function foo() {}; foo.prototype.bar = function() {} + """, ['',]) + + def test_function_prototype(self): + py.test.skip() + self.assert_prints(""" + function foo() {}; foo.prototype.bar = function() {} + """, ['',]) + + def test_function_this(self): + py.test.skip() + self.assert_prints(""" + function foo() {this.bar = function() {}}; var f = new foo(); f.bar(); + """, ['',]) From cfbolz at codespeak.net Wed Mar 21 17:06:32 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 21 Mar 2007 17:06:32 +0100 (CET) Subject: [pypy-svn] r40948 - pypy/dist/pypy/doc/image Message-ID: <20070321160632.357F110074@code0.codespeak.net> Author: cfbolz Date: Wed Mar 21 17:06:30 2007 New Revision: 40948 Added: pypy/dist/pypy/doc/image/compat-matrix.png (contents, props changed) pypy/dist/pypy/doc/image/compat-matrix.sxc (contents, props changed) Log: compatibility matrix Added: pypy/dist/pypy/doc/image/compat-matrix.png ============================================================================== Binary file. No diff available. Added: pypy/dist/pypy/doc/image/compat-matrix.sxc ============================================================================== Binary file. No diff available. From mwh at codespeak.net Wed Mar 21 17:06:46 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Wed, 21 Mar 2007 17:06:46 +0100 (CET) Subject: [pypy-svn] r40949 - pypy/dist/pypy/doc/config Message-ID: <20070321160646.7428310082@code0.codespeak.net> Author: mwh Date: Wed Mar 21 17:06:44 2007 New Revision: 40949 Modified: pypy/dist/pypy/doc/config/translation.backend.txt Log: make this actually a link Modified: pypy/dist/pypy/doc/config/translation.backend.txt ============================================================================== --- pypy/dist/pypy/doc/config/translation.backend.txt (original) +++ pypy/dist/pypy/doc/config/translation.backend.txt Wed Mar 21 17:06:44 2007 @@ -1,3 +1,3 @@ -Which backend to use when translating, see `translation documentation`. +Which backend to use when translating, see `translation documentation`_. .. _`translation documentation`: ../translation.html From guido at codespeak.net Wed Mar 21 17:09:50 2007 From: guido at codespeak.net (guido at codespeak.net) Date: Wed, 21 Mar 2007 17:09:50 +0100 (CET) Subject: [pypy-svn] r40950 - in pypy/dist/pypy/translator/js/examples: console data Message-ID: <20070321160950.A20FC1007E@code0.codespeak.net> Author: guido Date: Wed Mar 21 17:09:47 2007 New Revision: 40950 Modified: pypy/dist/pypy/translator/js/examples/console/console.py pypy/dist/pypy/translator/js/examples/data/index.html Log: Some language improvements. 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 Wed Mar 21 17:09:47 2007 @@ -15,24 +15,26 @@ commproxy.USE_MOCHIKIT = True FUNCTION_LIST = ["load_console", "console_onload"] -HELP = {'python':"just python, play as you like :)", +HELP = {'python':"just Python, play as you like :)", 'pypy-c': ''' -This is the PyPy standart interpreter translated to C with following features: +This is the PyPy standard interpreter translated to C with the following features:
      -
    • Stackless - You can use full stackless features including - tasklets, channels, coroutines and greenlets, full list of examples - and niceties can be found on a stackless docs +
    • Stackless - You can use all stackless features including + tasklets, channels, coroutines and greenlets, more information and some + examples can be found in the + PyPy stackless documentation.
    • Transparent proxy - This is a unique PyPy interpreter feature, - which allows you to provide application-level controller for every possible - object. Details and snippets can be found on a transparent proxy doc
    • + which allows you to provide application-level controller for any kind of + object. Details and snippets can be found in the + transparent proxy documentation.
    ''', - 'pypy-c-thunk':'''the PyPy standart interpreter compiled to C with - a thunk object space''', - 'pypy-c-taint':'''the PyPy standart interpreter compiled to C with - a taint object space'''} + 'pypy-c-thunk':'''the PyPy standard interpreter compiled to C using + the thunk object space''', + 'pypy-c-taint':'''the PyPy standard interpreter compiled to C using + the taint object space'''} class Ignore(Exception): pass 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 Mar 21 17:09:47 2007 @@ -10,24 +10,25 @@
    -

    This site presents various demos created using +

    This site presents various demos created with PyPy's compiler toolchain - to generate a JavaScript code out of an - RPython code.

    + to generate JavaScript code out of + RPython.

    -

    You can also play a bit with PyPy's unique features on consoles, - which run underlaying process of pypy standard interpreter translated - to C or CLI. On each console there is a little help to try out features +

    It also allows you to play with PyPy's unique features on consoles + presenting a PyPy standard interpreter translated to C or + CLI (forwarded from the server). On each console there is + a little help box which explains the features.

    -

    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

    +

    Note: these demos are set up on a replicable Xen instance, but + please do not vandalise the machine, otherwise we will be forced to + take it down.

    From pedronis at codespeak.net Wed Mar 21 17:16:24 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Wed, 21 Mar 2007 17:16:24 +0100 (CET) Subject: [pypy-svn] r40951 - pypy/dist/pypy/jit Message-ID: <20070321161624.51CD31007E@code0.codespeak.net> Author: pedronis Date: Wed Mar 21 17:16:23 2007 New Revision: 40951 Modified: pypy/dist/pypy/jit/TODO.txt Log: --jit and --faasen now work together. Modified: pypy/dist/pypy/jit/TODO.txt ============================================================================== --- pypy/dist/pypy/jit/TODO.txt (original) +++ pypy/dist/pypy/jit/TODO.txt Wed Mar 21 17:16:23 2007 @@ -6,13 +6,6 @@ - basic docs and examples -- check that --jit works with --faassen - - - we explode in reg alloc for f(sys.maxint) (of test_pypy_c) ...! - it seems we are in a flexswitch after a promote to be precise - adding a bunch of printf to the c code: it seems that the inputlocatios to the reg alloc contain the same register twice - mmh, because we have the same variable twice (this is an invariant broken) - - 386 regalloc bug: release(gv) might release it too early if gv is used several times by the same operation :-( From fijal at codespeak.net Wed Mar 21 17:21:37 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 21 Mar 2007 17:21:37 +0100 (CET) Subject: [pypy-svn] r40953 - in pypy/dist/pypy/lib: . test2 Message-ID: <20070321162137.C675B10087@code0.codespeak.net> Author: fijal Date: Wed Mar 21 17:21:35 2007 New Revision: 40953 Modified: pypy/dist/pypy/lib/test2/test_tputil.py pypy/dist/pypy/lib/tputil.py Log: Fix to tputil and a test for that Modified: pypy/dist/pypy/lib/test2/test_tputil.py ============================================================================== --- pypy/dist/pypy/lib/test2/test_tputil.py (original) +++ pypy/dist/pypy/lib/test2/test_tputil.py Wed Mar 21 17:21:35 2007 @@ -39,3 +39,15 @@ assert r1[0].args[0] == '__getattribute__' assert r1[1].opname == '__getattribute__' assert r1[1].args[0] == 'append' + + def test_proxy_inplace_add(self): + r = [] + from tputil import make_instance_proxy + def func1(invocation): + r.append(invocation) + return invocation.perform() + + l2 = make_instance_proxy([], func1) + l = l2 + l += [3] + assert l is l2 Modified: pypy/dist/pypy/lib/tputil.py ============================================================================== --- pypy/dist/pypy/lib/tputil.py (original) +++ pypy/dist/pypy/lib/tputil.py Wed Mar 21 17:21:35 2007 @@ -34,6 +34,8 @@ if (isinstance(res, MethodType) and res.im_self is self.realobj): res = MethodType(res.im_func, self.proxyobj, res.im_class) + if res is self.realobj: + return self.proxyobj return res def __repr__(self): From fijal at codespeak.net Wed Mar 21 17:27:12 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 21 Mar 2007 17:27:12 +0100 (CET) Subject: [pypy-svn] r40954 - pypy/dist/pypy/translator/js/examples/console Message-ID: <20070321162712.26D3B10087@code0.codespeak.net> Author: fijal Date: Wed Mar 21 17:27:10 2007 New Revision: 40954 Modified: pypy/dist/pypy/translator/js/examples/console/console.py Log: Capitalize first letter 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 Wed Mar 21 17:27:10 2007 @@ -31,10 +31,11 @@ transparent proxy documentation. ''', - 'pypy-c-thunk':'''the PyPy standard interpreter compiled to C using + 'pypy-c-thunk':'''The PyPy standard interpreter compiled to C using the thunk object space''', - 'pypy-c-taint':'''the PyPy standard interpreter compiled to C using - the taint object space'''} + 'pypy-c-taint':'''The PyPy standard interpreter compiled to C using + the taint object space''', + 'pypy-cli':'''The PyPy standard interpreter compiled to CLI'''} class Ignore(Exception): pass From cfbolz at codespeak.net Wed Mar 21 17:31:09 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 21 Mar 2007 17:31:09 +0100 (CET) Subject: [pypy-svn] r40955 - pypy/dist/pypy/doc/image Message-ID: <20070321163109.9D8E510087@code0.codespeak.net> Author: cfbolz Date: Wed Mar 21 17:30:58 2007 New Revision: 40955 Modified: pypy/dist/pypy/doc/image/compat-matrix.png pypy/dist/pypy/doc/image/compat-matrix.sxc Log: fix some things, thanks michael Modified: pypy/dist/pypy/doc/image/compat-matrix.png ============================================================================== Binary files. No diff available. Modified: pypy/dist/pypy/doc/image/compat-matrix.sxc ============================================================================== Binary files. No diff available. From ac at codespeak.net Wed Mar 21 17:32:15 2007 From: ac at codespeak.net (ac at codespeak.net) Date: Wed, 21 Mar 2007 17:32:15 +0100 (CET) Subject: [pypy-svn] r40956 - pypy/dist/pypy/interpreter Message-ID: <20070321163215.28A2510077@code0.codespeak.net> Author: ac Date: Wed Mar 21 17:32:11 2007 New Revision: 40956 Modified: pypy/dist/pypy/interpreter/callmethod.py Log: Have CALL_METHOD not use call_valuestack in the jitted case. Modified: pypy/dist/pypy/interpreter/callmethod.py ============================================================================== --- pypy/dist/pypy/interpreter/callmethod.py (original) +++ pypy/dist/pypy/interpreter/callmethod.py Wed Mar 21 17:32:11 2007 @@ -11,6 +11,8 @@ """ from pypy.interpreter import pyframe, function +from pypy.rlib.objectmodel import we_are_jitted +from pypy.interpreter.argument import Arguments def object_getattribute(space): @@ -58,11 +60,20 @@ 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: + w_self = f.peekvalue(nargs) + if we_are_jitted(): + if w_self is None: + args = f.popvalues(nargs) + f.popvalue() # w_self + else: + args = f.popvalues(nargs + 1) + w_callable = f.popvalue() + w_result = f.space.call_args(w_callable, Arguments(f.space, args)) + else: + w_callable = f.peekvalue(nargs + 1) n = nargs + (w_self is not None) - w_result = f.space.call_valuestack(w_callable, n, f) - finally: - f.dropvalues(nargs + 2) + try: + w_result = f.space.call_valuestack(w_callable, n, f) + finally: + f.dropvalues(nargs + 2) f.pushvalue(w_result) From cfbolz at codespeak.net Wed Mar 21 17:56:32 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 21 Mar 2007 17:56:32 +0100 (CET) Subject: [pypy-svn] r40957 - pypy/dist/pypy/doc/image Message-ID: <20070321165632.3B41C10034@code0.codespeak.net> Author: cfbolz Date: Wed Mar 21 17:56:30 2007 New Revision: 40957 Modified: pypy/dist/pypy/doc/image/compat-matrix.png Log: try to get better fonts back Modified: pypy/dist/pypy/doc/image/compat-matrix.png ============================================================================== Binary files. No diff available. From cfbolz at codespeak.net Wed Mar 21 18:34:22 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 21 Mar 2007 18:34:22 +0100 (CET) Subject: [pypy-svn] r40958 - in pypy/dist/pypy/doc: . config Message-ID: <20070321173422.1B7531007A@code0.codespeak.net> Author: cfbolz Date: Wed Mar 21 18:34:20 2007 New Revision: 40958 Modified: pypy/dist/pypy/doc/config/index.txt pypy/dist/pypy/doc/index.txt Log: add link a link to the compat matrix, embed it into config/index.txt Modified: pypy/dist/pypy/doc/config/index.txt ============================================================================== --- pypy/dist/pypy/doc/config/index.txt (original) +++ pypy/dist/pypy/doc/config/index.txt Wed Mar 21 18:34:20 2007 @@ -39,6 +39,11 @@ barely be imagined in CPython, which are documented in `What PyPy can do for your objects`_. +The following diagram gives some hints about which PyPy features work together +with which other PyPy features: + +.. image:: ../image/compat-matrix.png + .. _`configuration`: ../configuration.html .. _`objspace options`: commandline.html#overwiew-of-command-line-options-for-objspace .. _`object space options`: commandline.html#overwiew-of-command-line-options-for-objspace Modified: pypy/dist/pypy/doc/index.txt ============================================================================== --- pypy/dist/pypy/doc/index.txt (original) +++ pypy/dist/pypy/doc/index.txt Wed Mar 21 18:34:20 2007 @@ -85,6 +85,9 @@ `PyPy statistics`_ is a page with various statistics about the PyPy project. +`compatibility matrix`_ is a diagram that shows which of the various features +of the PyPy interpreter work together with which other features. + Source Code Documentation =============================================== @@ -342,6 +345,7 @@ .. _Mono: http://www.mono-project.com/ .. _`"standard library"`: rlib.html .. _`graph viewer`: getting-started.html#try-out-the-translator +.. _`compatibility matrix`: image/compat-matrix.png .. include:: _ref.txt From mwh at codespeak.net Wed Mar 21 18:36:25 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Wed, 21 Mar 2007 18:36:25 +0100 (CET) Subject: [pypy-svn] r40959 - pypy/extradoc/planning/1.0 Message-ID: <20070321173625.339C71007B@code0.codespeak.net> Author: mwh Date: Wed Mar 21 18:36:23 2007 New Revision: 40959 Modified: pypy/extradoc/planning/1.0/TODO.txt Log: TODO from today's meeting Modified: pypy/extradoc/planning/1.0/TODO.txt ============================================================================== --- pypy/extradoc/planning/1.0/TODO.txt (original) +++ pypy/extradoc/planning/1.0/TODO.txt Wed Mar 21 18:36:23 2007 @@ -26,23 +26,20 @@ - ensure working Interpreter translation combinations: - pypy-c-stackless/tp/taint/jit/GC-framework/thunk - pypy-cli-tp/taint/thunk - - make a matrix of possible combinations (wp13-report) - (cfbolz) + (cfbolz will check in soon) - complete/debug jit on powerpc (mwh) + somewhat working, debugging in progress - debug jit on intel (arigo/pedronis/arre) - in progress, fixing bugs and improving "is_true" jitting - + in progress, --jit --faassen works now, "is_true" issue still open - integrate and test: - - wp10 - - docs, examples (done) - - fixing "weaver" bugs (agurney) + - wp10 - basically complete, pending issues brought up in review - wp08 docs, examples and code (arigo/pedronis/arre, after debugging) - wp09 docs, examples and code - maybe what we have is good enough? - (christian looking into this currently) + (christian looking into this currently) no real progress here - revisit entry level docs (architecture, mission, getting-started) - terminology clarifications: @@ -53,7 +50,7 @@ - so we have: - pypy standard interpreter (easy to understand/modify) - pypy VM translation framework (neccessarily more complex) - (hpk to start here) + (hpk to start here, have something done by friday) - describe particularly Javascript-related demos, refine them. (in-progress, adding more console variations currently, nicer entry page) @@ -70,7 +67,6 @@ - write a nice support module (pypy/lib/tputil.py - in progress) - write/review documentation (in-progress) - fix bugs if any - - probably don't go for "transparent_proxy(type, ...)" :) (hpk) - update wp6 docs (object-optimizations.txt) and link @@ -78,11 +74,12 @@ - document build tool usages (getting-started?), connect servers with it (guido_w) + targetpypystandalone changes caused some problems. - consider where/how to put special builtins ("pypymagic" might not be a good name), suggestions: - names: pypybuiltin? decide about name at pypy-sync wednesday - - document pypybuiltin module (add docstrings) + - document pypybuiltin module (add docstrings) (done) - functions should only be there if the according option is enabled (e.g. method cache) - options only relating to py.py should not appear in From cfbolz at codespeak.net Wed Mar 21 18:38:52 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 21 Mar 2007 18:38:52 +0100 (CET) Subject: [pypy-svn] r40960 - pypy/extradoc/planning/1.0 Message-ID: <20070321173852.A273210072@code0.codespeak.net> Author: cfbolz Date: Wed Mar 21 18:38:49 2007 New Revision: 40960 Modified: pypy/extradoc/planning/1.0/TODO.txt Log: some updates Modified: pypy/extradoc/planning/1.0/TODO.txt ============================================================================== --- pypy/extradoc/planning/1.0/TODO.txt (original) +++ pypy/extradoc/planning/1.0/TODO.txt Wed Mar 21 18:38:49 2007 @@ -27,7 +27,7 @@ - pypy-c-stackless/tp/taint/jit/GC-framework/thunk - pypy-cli-tp/taint/thunk - make a matrix of possible combinations (wp13-report) - (cfbolz will check in soon) + (cfbolz) done - complete/debug jit on powerpc (mwh) somewhat working, debugging in progress @@ -78,12 +78,12 @@ - consider where/how to put special builtins ("pypymagic" might not be a good name), suggestions: - - names: pypybuiltin? decide about name at pypy-sync wednesday + - names: not pypymagic, not pypybuiltin, holger and cf to propose - document pypybuiltin module (add docstrings) (done) - functions should only be there if the according option - is enabled (e.g. method cache) - - options only relating to py.py should not appear in - translated version (unless they work :) + is enabled (e.g. method cache) (done) + - functions only relating to py.py should not appear in + translated version (unless they work :) (done) (cfbolz) - include documentation/entry point for From ac at codespeak.net Wed Mar 21 18:39:34 2007 From: ac at codespeak.net (ac at codespeak.net) Date: Wed, 21 Mar 2007 18:39:34 +0100 (CET) Subject: [pypy-svn] r40961 - pypy/dist/pypy/module/posix Message-ID: <20070321173934.E01AD1007E@code0.codespeak.net> Author: ac Date: Wed Mar 21 18:39:33 2007 New Revision: 40961 Modified: pypy/dist/pypy/module/posix/app_posix.py Log: Fix recursive import of posix. 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 Wed Mar 21 18:39:33 2007 @@ -1,6 +1,5 @@ # NOT_RPYTHON -import os from _structseq import structseqtype, structseqfield error = OSError @@ -36,6 +35,7 @@ _childpid = None def close(self): + import os file.close(self) pid = self._childpid if pid is not None: @@ -43,18 +43,19 @@ os.waitpid(pid, 0) __del__ = close # as in CPython, __del__ may call os.waitpid() -def try_close(fd): - try: - os.close(fd) - except OSError: - pass - def popen(command, mode='r', bufsize=-1): """popen(command [, mode='r' [, bufsize]]) -> pipe Open a pipe to/from a command returning a file object.""" from popen2 import MAXFD + import os + + def try_close(fd): + try: + os.close(fd) + except OSError: + pass if not mode.startswith('r') and not mode.startswith('w'): raise ValueError("invalid mode %r" % (mode,)) From cfbolz at codespeak.net Wed Mar 21 19:04:07 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 21 Mar 2007 19:04:07 +0100 (CET) Subject: [pypy-svn] r40963 - pypy/dist/pypy/doc Message-ID: <20070321180407.171861007B@code0.codespeak.net> Author: cfbolz Date: Wed Mar 21 19:04:05 2007 New Revision: 40963 Modified: pypy/dist/pypy/doc/object-optimizations.txt Log: a small section about ropes Modified: pypy/dist/pypy/doc/object-optimizations.txt ============================================================================== --- pypy/dist/pypy/doc/object-optimizations.txt (original) +++ pypy/dist/pypy/doc/object-optimizations.txt Wed Mar 21 19:04:05 2007 @@ -48,7 +48,36 @@ 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. +You can enable this feature with the :config:`objspace.std.withstrslice` option. + + +Ropes +----- + +Ropes are a general flexible string implementation, following the paper `"Ropes: +An alternative to Strings."`_ by Boehm, Atkinson and Plass. Strings are +represented as balanced concatenation trees, which makes slicing and +concatenation of huge strings efficient. + +Using ropes is usually not a huge benefit for normal Python programs that use +the typical pattern of appending substrings to a list and doing a +``"".join(l)`` at the end. If ropes are used, there is no need to do that. +A somewhat silly example of things you can do with them is this:: + + $ bin/py.py --objspace-std-withrope + faking + PyPy 0.99.0 in StdObjSpace on top of Python 2.4.4c1 (startuptime: 17.24 secs) + >>>> import sys + >>>> sys.maxint + 2147483647 + >>>> s = "a" * sys.maxint + >>>> s[10:20] + 'aaaaaaaaaa' + + +You can enable this feature with the :config:`objspace.std.withrope` option. + +.. _`"Ropes: An alternative to Strings."`: http://www.cs.ubc.ca/local/reading/proceedings/spe91-95/spe/vol25/issue12/spe986.pdf Integer optimizations ===================== From cfbolz at codespeak.net Wed Mar 21 19:36:17 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 21 Mar 2007 19:36:17 +0100 (CET) Subject: [pypy-svn] r40964 - pypy/dist/pypy/objspace Message-ID: <20070321183617.D9C0910074@code0.codespeak.net> Author: cfbolz Date: Wed Mar 21 19:36:15 2007 New Revision: 40964 Modified: pypy/dist/pypy/objspace/taint.py Log: docstrings for taint functions in pypymagic Modified: pypy/dist/pypy/objspace/taint.py ============================================================================== --- pypy/dist/pypy/objspace/taint.py (original) +++ pypy/dist/pypy/objspace/taint.py Wed Mar 21 19:36:15 2007 @@ -66,6 +66,7 @@ def taint(w_obj): + """Return a tainted version of the argument.""" if w_obj is None or isinstance(w_obj, W_Tainted): return w_obj else: @@ -74,11 +75,15 @@ app_taint = gateway.interp2app(taint) def is_tainted(space, w_obj): + """Return whether the argument is 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_expectedtype, w_obj): + """untaint(expectedtype, tainted_obj) -> obj +Untaint untainted_obj and return it. If the result is not of expectedtype, +raise a type error.""" if (isinstance(w_expectedtype, W_Tainted) or isinstance(w_expectedtype, W_TaintBomb)): raise OperationError(space.w_TypeError, @@ -129,6 +134,10 @@ unwrap_spec=[gateway.ObjSpace, gateway.W_Root, 'args_w']) def taint_atomic(space, w_callable): + """decorator to make a callable "taint-atomic": if the function is called +with tainted arguments, those are untainted. The result of the function is +tainted again. All exceptions that the callable raises are turned into +taint bombs.""" meth = Method(space, space.w_fn_taint_atomic_function, w_callable, space.type(w_callable)) return space.wrap(meth) @@ -139,11 +148,16 @@ executioncontext.ExecutionContext.taint_debug = 0 def taint_debug(space, level): + """Set the debug level. If the debug level is greater than 0, the creation +of taint bombs will print debug information. For debugging purposes +only!""" space.getexecutioncontext().taint_debug = level app_taint_debug = gateway.interp2app(taint_debug, unwrap_spec=[gateway.ObjSpace, int]) def taint_look(space, w_obj): + """Print some info about the taintedness of an object. For debugging +purposes only!""" 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)) @@ -182,11 +196,16 @@ def __init__(self, *args, **kwds): StdObjSpace.__init__(self, *args, **kwds) + w_dict = self.newdict() + self.setitem(w_dict, self.wrap("__doc__"), self.wrap("""\ +Exception that is raised when an operation revealing information on a tainted +object is performed.""")) self.w_TaintError = self.call_function( self.w_type, self.wrap("TaintError"), self.newtuple([self.w_Exception]), - self.newdict()) + w_dict + ) w_pypymagic = self.getbuiltinmodule("pypymagic") self.setattr(w_pypymagic, self.wrap('taint'), self.wrap(app_taint)) From arigo at codespeak.net Wed Mar 21 19:39:53 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 21 Mar 2007 19:39:53 +0100 (CET) Subject: [pypy-svn] r40965 - in pypy/dist/pypy/jit: hintannotator timeshifter timeshifter/test Message-ID: <20070321183953.7129F10079@code0.codespeak.net> Author: arigo Date: Wed Mar 21 19:39:51 2007 New Revision: 40965 Modified: pypy/dist/pypy/jit/hintannotator/annotator.py pypy/dist/pypy/jit/hintannotator/bookkeeper.py pypy/dist/pypy/jit/timeshifter/hrtyper.py pypy/dist/pypy/jit/timeshifter/test/test_timeshift.py Log: (pedronis, arigo, arre) Advanced (but easy (but obscure)) support for taking complete control from the RPython program over the timeshifted version of a function. Modified: pypy/dist/pypy/jit/hintannotator/annotator.py ============================================================================== --- pypy/dist/pypy/jit/hintannotator/annotator.py (original) +++ pypy/dist/pypy/jit/hintannotator/annotator.py Wed Mar 21 19:39:51 2007 @@ -90,6 +90,10 @@ def consider_op_resume_point(self, hs_v, *args_hs): pass + def consider_op_ts_metacall(self, hs_metafunc, *args_hs): + RESTYPE = self.bookkeeper.current_op_concretetype() + return hintmodel.variableoftype(RESTYPE) + def simplify(self): RPythonAnnotator.simplify(self, extra_passes=[]) Modified: pypy/dist/pypy/jit/hintannotator/bookkeeper.py ============================================================================== --- pypy/dist/pypy/jit/hintannotator/bookkeeper.py (original) +++ pypy/dist/pypy/jit/hintannotator/bookkeeper.py Wed Mar 21 19:39:51 2007 @@ -48,8 +48,13 @@ return self._cache[key] except KeyError: bk = self.bookkeeper - if bk.annotator.policy.look_inside_graph(self.origgraph): - graph = copygraph(self.origgraph, varmap=TIMESHIFTMAP) + look = bk.annotator.policy.look_inside_graph(self.origgraph) + if look: + if callable(look): + graph = self.build_metacall_graph(self.origgraph, look) + else: + # normal case + graph = copygraph(self.origgraph, varmap=TIMESHIFTMAP) if not self._cache: bk.nonstuboriggraphcount += 1 if verbose: @@ -87,7 +92,20 @@ newstartblock = Block(args_v) newstartblock.operations.append( SpaceOperation('direct_call', [v_ptr] + args_v, v_res)) - newgraph = FunctionGraph(graph.name, newstartblock) + newgraph = FunctionGraph('%s_ts_stub' % (graph.name,), newstartblock) + newgraph.getreturnvar().concretetype = v_res.concretetype + newstartblock.closeblock(Link([v_res], newgraph.returnblock)) + return newgraph + + def build_metacall_graph(self, origgraph, metafunc): + args_v = [copyvar(None, v) for v in origgraph.getargs()] + v_res = copyvar(None, origgraph.getreturnvar()) + v_metafunc = Constant(metafunc, lltype.Void) + newstartblock = Block(args_v) + newstartblock.operations.append( + SpaceOperation('ts_metacall', [v_metafunc] + args_v, v_res)) + newgraph = FunctionGraph('%s_ts_metacall' % (origgraph.name,), + newstartblock) newgraph.getreturnvar().concretetype = v_res.concretetype newstartblock.closeblock(Link([v_res], newgraph.returnblock)) return newgraph Modified: pypy/dist/pypy/jit/timeshifter/hrtyper.py ============================================================================== --- pypy/dist/pypy/jit/timeshifter/hrtyper.py (original) +++ pypy/dist/pypy/jit/timeshifter/hrtyper.py Wed Mar 21 19:39:51 2007 @@ -680,6 +680,18 @@ [v] = hop.inputargs(hop.r_result) return v + def translate_op_ts_metacall(self, hop): + nb_args = hop.nb_args - 1 + args_r = [self.getredrepr(originalconcretetype(hs)) + for hs in hop.args_s[1:]] + vlist = hop.inputargs(lltype.Void, *args_r) + metafunc = vlist[0].value + v_jitstate = hop.llops.getjitstate() + return hop.llops.genmixlevelhelpercall(metafunc, + [self.s_JITState] + [self.s_RedBox] * nb_args, + [v_jitstate] + vlist[1:], + self.s_RedBox) + def translate_op_getfield(self, hop): if isinstance(hop.args_r[0], BlueRepr): return hop.args_r[0].timeshift_getfield(hop) Modified: pypy/dist/pypy/jit/timeshifter/test/test_timeshift.py ============================================================================== --- pypy/dist/pypy/jit/timeshifter/test/test_timeshift.py (original) +++ pypy/dist/pypy/jit/timeshifter/test/test_timeshift.py Wed Mar 21 19:39:51 2007 @@ -1637,3 +1637,28 @@ assert res == 78 - 12 res = self.timeshift(f, [2, 4], backendoptimize=True) assert res == 56 - 90 + + def test_substitute_graph(self): + + def h(jitstate, mbox): + from pypy.jit.timeshifter.rvalue import IntRedBox + builder = jitstate.curbuilder + gv_result = builder.genop1("int_neg", mbox.getgenvar(jitstate)) + return IntRedBox(mbox.kind, gv_result) + + def g(m): + return m + 17 + + def f(n): + return g(n) + + class MyPolicy(HintAnnotatorPolicy): + def look_inside_graph(self, graph): + if graph.func is g: + return h # replaces g with a meta-call to h... + else: + return True + + res = self.timeshift(f, [3], policy=MyPolicy()) + assert res == -3 + self.check_insns({'int_neg': 1}) From hpk at codespeak.net Wed Mar 21 20:02:35 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Wed, 21 Mar 2007 20:02:35 +0100 (CET) Subject: [pypy-svn] r40966 - in pypy/dist: demo pypy/lib pypy/lib/test2 Message-ID: <20070321190235.959EF10072@code0.codespeak.net> Author: hpk Date: Wed Mar 21 20:02:34 2007 New Revision: 40966 Modified: pypy/dist/demo/tp-persistence.py pypy/dist/pypy/lib/test2/test_tputil.py pypy/dist/pypy/lib/tputil.py Log: settling the tputil API to handle both virtual and concrete proxies (the latter are instantiated through providing an instance 'obj' and there is convenient help to delegate operations to it, see the tests and docstring for details) Modified: pypy/dist/demo/tp-persistence.py ============================================================================== --- pypy/dist/demo/tp-persistence.py (original) +++ pypy/dist/demo/tp-persistence.py Wed Mar 21 20:02:34 2007 @@ -5,7 +5,7 @@ """ from pypymagic import tproxy, get_tproxy_controller -from tputil import make_instance_proxy +from tputil import make_proxy list_changeops = set('__iadd__ __imul__ __delitem__ __setitem__ ' '__delslice__ __setslice__ ' @@ -13,11 +13,11 @@ def make_plist(instance, storage): def perform(invocation): - res = invocation.perform() + res = invocation.delegate() if invocation.opname in list_changeops: storage.dump(instance) return res - return make_instance_proxy(instance, perform, typ=list) + return make_proxy(perform, type=list, obj=instance) def get_plist(storage): obj = storage.load() Modified: pypy/dist/pypy/lib/test2/test_tputil.py ============================================================================== --- pypy/dist/pypy/lib/test2/test_tputil.py (original) +++ pypy/dist/pypy/lib/test2/test_tputil.py Wed Mar 21 20:02:34 2007 @@ -1,35 +1,59 @@ from pypy.conftest import gettestobjspace -class AppTestTPListproxy: +class AppTest_make_proxy: def setup_class(cls): cls.space = gettestobjspace(**{"objspace.std.withtproxy": True}) + + def test_errors(self): + from tputil import make_proxy + raises(TypeError, "make_proxy(None)") + raises(TypeError, "make_proxy(None, None)") + def f(): pass + raises(TypeError, "make_proxy(f)") + raises(TypeError, "make_proxy(f, None, None)") + + def test_virtual_proxy(self): + from tputil import make_proxy + l = [] + tp = make_proxy(l.append, type=list) + x = len(tp) + assert len(l) == 1 + assert l[0].opname == '__len__' - def test_listproxy_basic(self): - from tputil import make_instance_proxy + def test_simple(self): + from tputil import make_proxy record = [] - def func(invocation): - record.append(invocation) - return invocation.perform() - l = make_instance_proxy([], func) + def func(operation): + record.append(operation) + return operation.delegate() + l = make_proxy(func, obj=[]) l.append(1) assert len(record) == 2 i1, i2 = record assert i1.opname == '__getattribute__' assert i2.opname == 'append' + def test_missing_attr(self): + from tputil import make_proxy + def func(operation): + return operation.delegate() + l = make_proxy(func, obj=[]) + excinfo = raises(AttributeError, "l.asdasd") + assert str(excinfo).find("asdasd") != -1 + def test_proxy_double(self): - from tputil import make_instance_proxy + from tputil import make_proxy r1 = [] r2 = [] - def func1(invocation): - r1.append(invocation) - return invocation.perform() - def func2(invocation): - r2.append(invocation) - return invocation.perform() + def func1(operation): + r1.append(operation) + return operation.delegate() + def func2(operation): + r2.append(operation) + return operation.delegate() - l = make_instance_proxy([], func1) - l2 = make_instance_proxy(l, func2) + l = make_proxy(func1, obj=[]) + l2 = make_proxy(func2, obj=l) assert not r1 and not r2 l2.append assert len(r2) == 1 @@ -42,12 +66,12 @@ def test_proxy_inplace_add(self): r = [] - from tputil import make_instance_proxy - def func1(invocation): - r.append(invocation) - return invocation.perform() + from tputil import make_proxy + def func1(operation): + r.append(operation) + return operation.delegate() - l2 = make_instance_proxy([], func1) + l2 = make_proxy(func1, obj=[]) l = l2 l += [3] assert l is l2 Modified: pypy/dist/pypy/lib/tputil.py ============================================================================== --- pypy/dist/pypy/lib/tputil.py (original) +++ pypy/dist/pypy/lib/tputil.py Wed Mar 21 20:02:34 2007 @@ -10,34 +10,59 @@ from pypymagic import tproxy from types import MethodType -def make_instance_proxy(instance, invokefunc=None, typ=None): - if typ is None: - typ = type(instance) +_dummy = object() +origtype = type + +def make_proxy(controller, type=_dummy, obj=_dummy): + """ return a tranparent proxy controlled by the given + 'controller' callable. The proxy will appear + as a completely regular instance of the given + type but all operations on it are send to the + specified controller - which receices on + ProxyOperation instance on each such call. A non-specified + type will default to type(obj) if obj is specified. + """ + if type is _dummy: + if obj is _dummy: + raise TypeError("you must specify a type or an instance obj") + type = origtype(obj) def perform(opname, *args, **kwargs): - invocation = Invocation(tp, instance, opname, args, kwargs) - return invokefunc(invocation) - tp = tproxy(typ, perform) + operation = ProxyOperation(tp, type, obj, opname, args, kwargs) + return controller(operation) + tp = tproxy(type, perform) return tp -class Invocation(object): - def __init__(self, proxyobj, realobj, opname, args, kwargs): +class ProxyOperation(object): + def __init__(self, proxyobj, type, obj, opname, args, kwargs): self.proxyobj = proxyobj - self.realobj = realobj self.opname = opname self.args = args self.kwargs = kwargs - self.realmethod = getattr(realobj, opname) + self.type = type + if obj is not _dummy: + self.obj = obj - def perform(self): - res = self.realmethod(*self.args, **self.kwargs) + def delegate(self): + """ return result from delegating this operation to the + underyling self.obj - which must exist and is usually + provided through the initial make_proxy(..., obj=...) + creation. + """ + try: + obj = getattr(self, 'obj') + except AttributeError: + raise TypeError("proxy does not have an underlying 'obj', " + "cannot delegate") + objattr = getattr(obj, self.opname) + res = objattr(*self.args, **self.kwargs) if self.opname == "__getattribute__": if (isinstance(res, MethodType) and - res.im_self is self.realobj): + res.im_self is self.instance): res = MethodType(res.im_func, self.proxyobj, res.im_class) - if res is self.realobj: - return self.proxyobj + if res is self.obj: + res = self.proxyobj return res def __repr__(self): - return "" %( + self.opname, self.args, self.kwargs, id(self)) From cfbolz at codespeak.net Wed Mar 21 20:04:54 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 21 Mar 2007 20:04:54 +0100 (CET) Subject: [pypy-svn] r40967 - pypy/dist/pypy/doc/config Message-ID: <20070321190454.0E66A10072@code0.codespeak.net> Author: cfbolz Date: Wed Mar 21 20:04:52 2007 New Revision: 40967 Modified: pypy/dist/pypy/doc/config/objspace.std.withrope.txt Log: link to object-optimizations Modified: pypy/dist/pypy/doc/config/objspace.std.withrope.txt ============================================================================== --- pypy/dist/pypy/doc/config/objspace.std.withrope.txt (original) +++ pypy/dist/pypy/doc/config/objspace.std.withrope.txt Wed Mar 21 20:04:52 2007 @@ -1,3 +1,7 @@ -Implement the Python ``str`` types using *ropes*, described in the paper -"Ropes: an Alternative to Strings" by Hans-J. Boehm, Russ Atkinson and Michael -Plass. +Enable ropes to be the default string implementation. + +See the page about `object optimizations`_ for more details. + +.. _`object optimizations`: ../object-optimizations.html + + From mwh at codespeak.net Wed Mar 21 20:21:05 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Wed, 21 Mar 2007 20:21:05 +0100 (CET) Subject: [pypy-svn] r40969 - pypy/dist/pypy/jit/codegen/ppc Message-ID: <20070321192105.5171610077@code0.codespeak.net> Author: mwh Date: Wed Mar 21 20:21:03 2007 New Revision: 40969 Modified: pypy/dist/pypy/jit/codegen/ppc/_flush_icache.c Log: actually have the _flush_icache extension module do something (thanks xorAxAx for the spot) Modified: pypy/dist/pypy/jit/codegen/ppc/_flush_icache.c ============================================================================== --- pypy/dist/pypy/jit/codegen/ppc/_flush_icache.c (original) +++ pypy/dist/pypy/jit/codegen/ppc/_flush_icache.c Wed Mar 21 20:21:03 2007 @@ -4,6 +4,12 @@ static PyObject* _flush_icache(PyObject *self, PyObject *args) { + long base, size; + + if (!PyArg_ParseTuple(args, "ii:_flush_icache", &base, &size)) + return NULL; + + LL_flush_icache(base, size); Py_INCREF(Py_None); return Py_None; } From hpk at codespeak.net Wed Mar 21 20:26:02 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Wed, 21 Mar 2007 20:26:02 +0100 (CET) Subject: [pypy-svn] r40970 - pypy/dist/pypy/doc Message-ID: <20070321192602.5C66A10077@code0.codespeak.net> Author: hpk Date: Wed Mar 21 20:26:01 2007 New Revision: 40970 Modified: pypy/dist/pypy/doc/objspace-proxies.txt Log: explain what make_proxy and ProxyOperation's provide. Modified: pypy/dist/pypy/doc/objspace-proxies.txt ============================================================================== --- pypy/dist/pypy/doc/objspace-proxies.txt (original) +++ pypy/dist/pypy/doc/objspace-proxies.txt Wed Mar 21 20:26:01 2007 @@ -489,14 +489,14 @@ it for later analysis. We use a small `tputil`_ module that helps with transparently proxying builtin instances:: - from tputil import make_instance_proxy + from tputil import make_proxy history = [] - def recorder(invocation): - history.append(invocation) - return invocation.perform() + def recorder(operation): + history.append(operation) + return operation.delegate() - >>>> l = make_instance_proxy([], recorder) + >>>> l = make_proxy(recorder, obj=[]) >>>> type(l) list >>>> l.append(3) @@ -545,12 +545,31 @@ tputil help module ---------------------------- -The `tputil.py`_ module helps writing programs that -make use of transparent proxies. Apart from the -`transparent proxy builtins`_ it provides -the following functionality: +The `tputil.py`_ module provides: -XXX +* ``make_proxy(controller, type, obj)`` function which + creates a tranparent proxy controlled by the given + 'controller' callable. The proxy will appear + as a completely regular instance of the given + type but all operations on it are send to the + specified controller - which receices on + ProxyOperation instance on each such operation. + A non-specified type will default to type(obj) if + `obj` was specified. + + ProxyOperation instances have the following attributes: + + `proxyobj`: the transparent proxy object of this operation. + `type`: the apparent type of the transparent proxy + `opname`: the operation name of this operation + `args`: positional arguments for this operation + `kwargs`: keyword arguments for this operation + `obj`: (if provided to `make_proxy`: an concrete object) + + If you have specified a concrete object instance `obj` + to your `make_proxy` invocation, you may call + ``proxyoperation.delegate()`` to delegate the operation + to this object instance. Further points of interest --------------------------- From cfbolz at codespeak.net Wed Mar 21 21:07:11 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 21 Mar 2007 21:07:11 +0100 (CET) Subject: [pypy-svn] r40974 - pypy/extradoc/eu-report Message-ID: <20070321200711.24F3310033@code0.codespeak.net> Author: cfbolz Date: Wed Mar 21 21:07:07 2007 New Revision: 40974 Modified: pypy/extradoc/eu-report/D03.1_Extension_Compiler-2007-03-21.pdf Log: update. hrumpf3 Modified: pypy/extradoc/eu-report/D03.1_Extension_Compiler-2007-03-21.pdf ============================================================================== Binary files. No diff available. From fijal at codespeak.net Wed Mar 21 21:50:19 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 21 Mar 2007 21:50:19 +0100 (CET) Subject: [pypy-svn] r40976 - in pypy/dist/pypy/translator/js/examples/console: . test Message-ID: <20070321205019.EE1331006E@code0.codespeak.net> Author: fijal Date: Wed Mar 21 21:50:18 2007 New Revision: 40976 Modified: pypy/dist/pypy/translator/js/examples/console/client.py pypy/dist/pypy/translator/js/examples/console/console.py pypy/dist/pypy/translator/js/examples/console/session.py pypy/dist/pypy/translator/js/examples/console/test/test_session.py Log: Improve console a bit. Unfortunately huge amount of logic which I've written didn't make it's way here, because it was completely useless. 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 Wed Mar 21 21:50:18 2007 @@ -30,6 +30,7 @@ #inp_elem.disabled = False if msg[0] == "refresh": inp_elem.scrollIntoView() + inp_elem.focus() data = msg[1] exported_methods.refresh_empty(glob.sess_id, refresh_console) add_text(data) @@ -63,11 +64,14 @@ def nothing(msg): pass +def nothing2(msg): + pass + def cleanup_console(): inp_elem = dom.document.getElementById("inp") inp_elem.disabled = True set_text("") - exported_methods.kill_console(glob.sess_id, nothing) + exported_methods.kill_console(glob.sess_id, nothing2) def load_console(python="python"): if glob.console_running: @@ -80,6 +84,13 @@ glob.console_running = True exported_methods.get_console(python, set_sessid) +def add_snippet(snippet): + add_text(snippet) + exported_methods.refresh(glob.sess_id, snippet, refresh_console) + +def execute_snippet(number=3): + exported_methods.execute_snippet(number, add_snippet) + def console_onload(): #createLoggingPane(True) #inp_elem = dom.document.getElementById("inp") 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 Wed Mar 21 21:50:18 2007 @@ -14,7 +14,17 @@ commproxy.USE_MOCHIKIT = True -FUNCTION_LIST = ["load_console", "console_onload"] +SNIPPETS = [ + """from tputil import make_instance_proxy +history = [] +def recorder(invocation): + history.append(invocation) + return invocation.perform() + +l = make_instance_proxy([], recorder) +"""] + +FUNCTION_LIST = ["load_console", "console_onload", "execute_snippet"] HELP = {'python':"just Python, play as you like :)", 'pypy-c': ''' @@ -28,9 +38,11 @@
  • Transparent proxy - This is a unique PyPy interpreter feature, which allows you to provide application-level controller for any kind of object. Details and snippets can be found in the - transparent proxy documentation.
  • + transparent proxy documentation. Example (execute): +
    %s
    + -''', +''' % (SNIPPETS[0],), 'pypy-c-thunk':'''The PyPy standard interpreter compiled to C using the thunk object space''', 'pypy-c-taint':'''The PyPy standard interpreter compiled to C using @@ -99,7 +111,7 @@ sessions = Sessions() class ExportedMethods(server.ExportedMethods): - @callback(args=[str], retval=[str]) + @callback(retval=[str]) def get_console(self, python="python"): retval = sessions.new_session(python) return [str(retval), HELP[python]] @@ -124,6 +136,10 @@ except Ignore: return ["ignore"] + @callback(retval=str) + def execute_snippet(self, number=3): + return SNIPPETS[int(number)] + @callback() def kill_console(self, pid=0): sessions.kill_session(int(pid)) Modified: pypy/dist/pypy/translator/js/examples/console/session.py ============================================================================== --- pypy/dist/pypy/translator/js/examples/console/session.py (original) +++ pypy/dist/pypy/translator/js/examples/console/session.py Wed Mar 21 21:50:18 2007 @@ -37,12 +37,11 @@ return data def write_only(self, to_write): - if to_write: + if to_write is not None: self.pipe.stdin.write(to_write) def interact(self, to_write=None): - if to_write is not None: - self.pipe.stdin.write(to_write) + self.write_only(to_write) return self.timeout_read(self.read_fd, self.timeout) def close(self): Modified: pypy/dist/pypy/translator/js/examples/console/test/test_session.py ============================================================================== --- pypy/dist/pypy/translator/js/examples/console/test/test_session.py (original) +++ pypy/dist/pypy/translator/js/examples/console/test/test_session.py Wed Mar 21 21:50:18 2007 @@ -31,3 +31,15 @@ one, two = allof(g, f) assert two.startswith(">>") assert one.startswith("Traceback") + +def test_multiline_command(): + i = Interpreter("python", timeout=3) + while not i.interact().endswith(">>> "): + pass + val = i.interact("def f(x):\n y = x + 3\n return y\n\nf(8)\n") + while val is not None: + assert 'Traceback' not in val + assert 'Syntax' not in val + print val + val = i.interact() + From pedronis at codespeak.net Wed Mar 21 22:19:55 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Wed, 21 Mar 2007 22:19:55 +0100 (CET) Subject: [pypy-svn] r40980 - pypy/dist/pypy/interpreter Message-ID: <20070321211955.603E910069@code0.codespeak.net> Author: pedronis Date: Wed Mar 21 22:19:54 2007 New Revision: 40980 Modified: pypy/dist/pypy/interpreter/gateway.py Log: use the appropriate module name for not geinterped app level parts of mixed modules Modified: pypy/dist/pypy/interpreter/gateway.py ============================================================================== --- pypy/dist/pypy/interpreter/gateway.py (original) +++ pypy/dist/pypy/interpreter/gateway.py Wed Mar 21 22:19:54 2007 @@ -828,7 +828,7 @@ "NOT_RPYTHON" from pypy.interpreter.pycode import PyCode w_glob = space.newdict() - space.setitem(w_glob, space.wrap('__name__'), space.wrap('__builtin__')) + space.setitem(w_glob, space.wrap('__name__'), space.wrap(self.modname)) space.exec_(self.code, w_glob, w_glob, hidden_applevel=self.hidden_applevel) return w_glob From fijal at codespeak.net Wed Mar 21 22:21:12 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 21 Mar 2007 22:21:12 +0100 (CET) Subject: [pypy-svn] r40981 - in pypy/dist/pypy/translator/js: examples/console lib Message-ID: <20070321212112.2453C10069@code0.codespeak.net> Author: fijal Date: Wed Mar 21 22:21:10 2007 New Revision: 40981 Modified: pypy/dist/pypy/translator/js/examples/console/console.py pypy/dist/pypy/translator/js/lib/support.py Log: Minor fixes. 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 Wed Mar 21 22:21:10 2007 @@ -15,13 +15,13 @@ commproxy.USE_MOCHIKIT = True SNIPPETS = [ - """from tputil import make_instance_proxy + """from tputil import make_proxy history = [] -def recorder(invocation): - history.append(invocation) - return invocation.perform() +def recorder(operation): + history.append(operation) + return operation.delegate() -l = make_instance_proxy([], recorder) +l = make_proxy(recorder, obj=[]) """] FUNCTION_LIST = ["load_console", "console_onload", "execute_snippet"] Modified: pypy/dist/pypy/translator/js/lib/support.py ============================================================================== --- pypy/dist/pypy/translator/js/lib/support.py (original) +++ pypy/dist/pypy/translator/js/lib/support.py Wed Mar 21 22:21:10 2007 @@ -17,7 +17,10 @@ if defs is None: defs = () vars = func.func_code.co_varnames[:func.func_code.co_argcount] - arg_list = load_dict_args(vars, defs, args) + if isinstance(args, dict): + arg_list = load_dict_args(vars, defs, args) + else: + arg_list = args arg_list.append(("callback", _callable(args=[retval]))) func._method = (func.__name__, MethodDesc(arg_list, retval)) return func From pedronis at codespeak.net Wed Mar 21 22:23:02 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Wed, 21 Mar 2007 22:23:02 +0100 (CET) Subject: [pypy-svn] r40983 - pypy/dist/pypy/tool Message-ID: <20070321212302.F092B10074@code0.codespeak.net> Author: pedronis Date: Wed Mar 21 22:23:02 2007 New Revision: 40983 Modified: pypy/dist/pypy/tool/cache.py Log: sanity checking code that we don't end up with recursive invocation of the cache building code for the same entry. The problem fixed by 40961 would have exploded more cleanly and clearly with this. Modified: pypy/dist/pypy/tool/cache.py ============================================================================== --- pypy/dist/pypy/tool/cache.py (original) +++ pypy/dist/pypy/tool/cache.py Wed Mar 21 22:23:02 2007 @@ -29,13 +29,21 @@ class Cache(object): def __init__(self): self.content = {} + self._building = {} def getorbuild(self, key): try: return self.content[key] except KeyError: - result = self._build(key) - self.content[key] = result + if key in self._building: + raise Exception, "%s recursive building of %r" % ( + self, key) + self._building[key] = True + try: + result = self._build(key) + self.content[key] = result + finally: + del self._building[key] self._ready(result) return result getorbuild._annspecialcase_ = "specialize:memo" From arigo at codespeak.net Wed Mar 21 22:30:33 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 21 Mar 2007 22:30:33 +0100 (CET) Subject: [pypy-svn] r40985 - in pypy/dist/pypy: jit/codegen/dump/test jit/codegen/i386/test jit/hintannotator jit/timeshifter jit/timeshifter/test module/pypyjit module/pypyjit/test objspace/std Message-ID: <20070321213033.CBF8310072@code0.codespeak.net> Author: arigo Date: Wed Mar 21 22:30:31 2007 New Revision: 40985 Added: pypy/dist/pypy/module/pypyjit/newbool.py (contents, props changed) pypy/dist/pypy/module/pypyjit/test/test_newbool.py (contents, props changed) Modified: pypy/dist/pypy/jit/codegen/dump/test/test_rgenop.py pypy/dist/pypy/jit/codegen/i386/test/test_interp_ts.py pypy/dist/pypy/jit/hintannotator/annotator.py pypy/dist/pypy/jit/hintannotator/bookkeeper.py pypy/dist/pypy/jit/timeshifter/hrtyper.py pypy/dist/pypy/jit/timeshifter/rcontainer.py pypy/dist/pypy/jit/timeshifter/rtimeshift.py pypy/dist/pypy/jit/timeshifter/test/test_timeshift.py pypy/dist/pypy/jit/timeshifter/vdict.py pypy/dist/pypy/objspace/std/boolobject.py pypy/dist/pypy/objspace/std/noneobject.py pypy/dist/pypy/objspace/std/objspace.py Log: (the jit band) Special support for newbool(), linked from pypyjit with the timeshifter. Returns a VirtualBool which simply stores the boolean value. Not integrated with "translate --jit" yet. Modified: pypy/dist/pypy/jit/codegen/dump/test/test_rgenop.py ============================================================================== --- pypy/dist/pypy/jit/codegen/dump/test/test_rgenop.py (original) +++ pypy/dist/pypy/jit/codegen/dump/test/test_rgenop.py Wed Mar 21 22:30:31 2007 @@ -1,5 +1,6 @@ import py from pypy.jit.codegen.dump.rgenop import RDumpGenOp +from pypy.jit.timeshifter.test.test_timeshift import Whatever from pypy.rpython.lltypesystem import lltype from pypy.jit.codegen.test.rgenop_tests import AbstractRGenOpTests, FUNC, FUNC2 from ctypes import cast, c_int, c_void_p, CFUNCTYPE @@ -17,12 +18,3 @@ # for the individual tests see # ====> ../../test/rgenop_tests.py - - -class Whatever(object): - def __eq__(self, other): - return True - def __ne__(self, other): - return False - def __and__(self, other): - return Whatever() # for test_ovfcheck_adder_direct Modified: pypy/dist/pypy/jit/codegen/i386/test/test_interp_ts.py ============================================================================== --- pypy/dist/pypy/jit/codegen/i386/test/test_interp_ts.py (original) +++ pypy/dist/pypy/jit/codegen/i386/test/test_interp_ts.py Wed Mar 21 22:30:31 2007 @@ -1,6 +1,7 @@ import os, py from pypy.annotation import model as annmodel from pypy.jit.timeshifter.test import test_timeshift +from pypy.jit.timeshifter.test.test_timeshift import Whatever from pypy.jit.codegen.i386.rgenop import RI386GenOp, IntConst from pypy.jit.codegen.i386.test.test_operation import RGenOpPacked from pypy.jit.codegen.i386.conftest import option @@ -9,10 +10,6 @@ if not option.interp: py.test.skip("these tests take ages and are not really useful") -class Whatever(object): - def __eq__(self, other): - return True - class I386LLInterpTimeshiftingTestMixin(object): class RGenOp(RGenOpPacked): from pypy.jit.codegen.i386.codebuf import LLTypeMachineCodeBlock \ Modified: pypy/dist/pypy/jit/hintannotator/annotator.py ============================================================================== --- pypy/dist/pypy/jit/hintannotator/annotator.py (original) +++ pypy/dist/pypy/jit/hintannotator/annotator.py Wed Mar 21 22:30:31 2007 @@ -9,13 +9,19 @@ class HintAnnotatorPolicy(policy.AnnotatorPolicy): - - def __init__(self, novirtualcontainer = False, - oopspec = False, - entrypoint_returns_red = True): - self.novirtualcontainer = novirtualcontainer - self.oopspec = oopspec - self.entrypoint_returns_red = entrypoint_returns_red + novirtualcontainer = False + oopspec = False + entrypoint_returns_red = True + + def __init__(self, novirtualcontainer = None, + oopspec = None, + entrypoint_returns_red = None): + if novirtualcontainer is not None: + self.novirtualcontainer = novirtualcontainer + if oopspec is not None: + self.oopspec = oopspec + if entrypoint_returns_red is not None: + self.entrypoint_returns_red = entrypoint_returns_red def look_inside_graph(self, graph): return True @@ -23,10 +29,10 @@ class StopAtXPolicy(HintAnnotatorPolicy): """Useful for tests.""" + novirtualcontainer = True + oopspec = True def __init__(self, *funcs): - HintAnnotatorPolicy.__init__(self, novirtualcontainer=True, - oopspec=True) self.funcs = funcs def look_inside_graph(self, graph): Modified: pypy/dist/pypy/jit/hintannotator/bookkeeper.py ============================================================================== --- pypy/dist/pypy/jit/hintannotator/bookkeeper.py (original) +++ pypy/dist/pypy/jit/hintannotator/bookkeeper.py Wed Mar 21 22:30:31 2007 @@ -97,13 +97,13 @@ newstartblock.closeblock(Link([v_res], newgraph.returnblock)) return newgraph - def build_metacall_graph(self, origgraph, metafunc): + def build_metacall_graph(self, origgraph, metadesccls): args_v = [copyvar(None, v) for v in origgraph.getargs()] v_res = copyvar(None, origgraph.getreturnvar()) - v_metafunc = Constant(metafunc, lltype.Void) + v_metadesccls = Constant(metadesccls, lltype.Void) newstartblock = Block(args_v) newstartblock.operations.append( - SpaceOperation('ts_metacall', [v_metafunc] + args_v, v_res)) + SpaceOperation('ts_metacall', [v_metadesccls] + args_v, v_res)) newgraph = FunctionGraph('%s_ts_metacall' % (origgraph.name,), newstartblock) newgraph.getreturnvar().concretetype = v_res.concretetype Modified: pypy/dist/pypy/jit/timeshifter/hrtyper.py ============================================================================== --- pypy/dist/pypy/jit/timeshifter/hrtyper.py (original) +++ pypy/dist/pypy/jit/timeshifter/hrtyper.py Wed Mar 21 22:30:31 2007 @@ -685,7 +685,9 @@ args_r = [self.getredrepr(originalconcretetype(hs)) for hs in hop.args_s[1:]] vlist = hop.inputargs(lltype.Void, *args_r) - metafunc = vlist[0].value + metadesccls = vlist[0].value + metadesc = metadesccls(self) + metafunc = metadesc.metafunc v_jitstate = hop.llops.getjitstate() return hop.llops.genmixlevelhelpercall(metafunc, [self.s_JITState] + [self.s_RedBox] * nb_args, Modified: pypy/dist/pypy/jit/timeshifter/rcontainer.py ============================================================================== --- pypy/dist/pypy/jit/timeshifter/rcontainer.py (original) +++ pypy/dist/pypy/jit/timeshifter/rcontainer.py Wed Mar 21 22:30:31 2007 @@ -26,13 +26,17 @@ class VirtualContainer(AbstractContainer): - _attrs_ = [] + _attrs_ = ('ownbox',) allowed_in_virtualizable = False def setforced(self, _): raise NotImplementedError + def op_ptreq(self, jitstate, otherbox, reverse): + equal = self is otherbox.content + return rvalue.ll_fromvalue(jitstate, equal ^ reverse) + class FrozenContainer(AbstractContainer): _attrs_ = [] @@ -465,7 +469,7 @@ #self.fz_content_boxes initialized later def exactmatch(self, vstruct, outgoingvarboxes, memo): - assert isinstance(vstruct, VirtualStruct) + assert isinstance(vstruct, VirtualContainer) contmemo = memo.containers if self in contmemo: ok = vstruct is contmemo[self] @@ -476,7 +480,8 @@ assert contmemo[vstruct] is not self outgoingvarboxes.append(vstruct.ownbox) return False - if self.typedesc is not vstruct.typedesc: + if (not isinstance(vstruct, VirtualStruct) + or self.typedesc is not vstruct.typedesc): if not memo.force_merge: raise rvalue.DontMerge outgoingvarboxes.append(vstruct.ownbox) @@ -511,7 +516,7 @@ class VirtualStruct(VirtualContainer): - _attrs_ = "typedesc content_boxes ownbox".split() + _attrs_ = "typedesc content_boxes".split() allowed_in_virtualizable = True @@ -842,7 +847,17 @@ gv_ptr = self.getgenvar(jitstate) fielddesc.generate_set(jitstate, gv_ptr, valuebox.getgenvar(jitstate)) - + + def op_ptreq(self, jitstate, otherbox, reverse): + if self is otherbox.content: + answer = True + else: + gv_outside = self.content_boxes[-1].genvar + if gv_outside is self.typedesc.gv_null: + answer = False + else: + return None # fall-back + return rvalue.ll_fromvalue(jitstate, answer ^ reverse) # patching VirtualStructCls StructTypeDesc.VirtualStructCls = VirtualStruct Modified: pypy/dist/pypy/jit/timeshifter/rtimeshift.py ============================================================================== --- pypy/dist/pypy/jit/timeshifter/rtimeshift.py (original) +++ pypy/dist/pypy/jit/timeshifter/rtimeshift.py Wed Mar 21 22:30:31 2007 @@ -228,15 +228,18 @@ def ll_genptreq(jitstate, argbox0, argbox1, reverse): builder = jitstate.curbuilder - # XXX this assumption is not completely valid in the presence - # of virtualizable - if argbox0.content is not None or argbox1.content is not None: - equal = argbox0.content is argbox1.content - return rvalue.ll_fromvalue(jitstate, equal ^ reverse) - elif argbox0.is_constant() and argbox1.is_constant(): + if argbox0.is_constant() and argbox1.is_constant(): addr0 = rvalue.ll_getvalue(argbox0, llmemory.Address) addr1 = rvalue.ll_getvalue(argbox1, llmemory.Address) return rvalue.ll_fromvalue(jitstate, (addr0 == addr1) ^ reverse) + if argbox0.content is not None: + resultbox = argbox0.content.op_ptreq(jitstate, argbox1, reverse) + if resultbox is not None: + return resultbox + if argbox1.content is not None: + resultbox = argbox1.content.op_ptreq(jitstate, argbox0, reverse) + if resultbox is not None: + return resultbox gv_addr0 = argbox0.getgenvar(jitstate) gv_addr1 = argbox1.getgenvar(jitstate) if reverse: Modified: pypy/dist/pypy/jit/timeshifter/test/test_timeshift.py ============================================================================== --- pypy/dist/pypy/jit/timeshifter/test/test_timeshift.py (original) +++ pypy/dist/pypy/jit/timeshifter/test/test_timeshift.py Wed Mar 21 22:30:31 2007 @@ -12,7 +12,7 @@ from pypy.rlib.objectmodel import hint, keepalive_until_here, debug_assert from pypy.rlib.unroll import unrolling_iterable from pypy.rlib.rarithmetic import ovfcheck -from pypy.rpython.annlowlevel import PseudoHighLevelCallable +from pypy.rpython.annlowlevel import PseudoHighLevelCallable, cachedtype from pypy.rpython.module.support import LLSupport from pypy.annotation import model as annmodel from pypy.rpython.llinterp import LLInterpreter, LLException @@ -23,6 +23,17 @@ P_NOVIRTUAL = HintAnnotatorPolicy(novirtualcontainer=True) + +class Whatever(object): + """To cheat in the tests that have no way to do the right thing.""" + def __eq__(self, other): + return True + def __ne__(self, other): + return False + def __and__(self, other): + return Whatever() # for test_ovfcheck_adder_direct in codegen.dump + + def getargtypes(annotator, values): return [annotation(annotator, x) for x in values] @@ -1640,11 +1651,20 @@ def test_substitute_graph(self): - def h(jitstate, mbox): - from pypy.jit.timeshifter.rvalue import IntRedBox - builder = jitstate.curbuilder - gv_result = builder.genop1("int_neg", mbox.getgenvar(jitstate)) - return IntRedBox(mbox.kind, gv_result) + class MetaG: + __metaclass__ = cachedtype + + def __init__(self, hrtyper): + pass + + def _freeze_(self): + return True + + def metafunc(self, jitstate, mbox): + from pypy.jit.timeshifter.rvalue import IntRedBox + builder = jitstate.curbuilder + gv_result = builder.genop1("int_neg", mbox.getgenvar(jitstate)) + return IntRedBox(mbox.kind, gv_result) def g(m): return m + 17 @@ -1655,7 +1675,7 @@ class MyPolicy(HintAnnotatorPolicy): def look_inside_graph(self, graph): if graph.func is g: - return h # replaces g with a meta-call to h... + return MetaG # replaces g with a meta-call to metafunc() else: return True Modified: pypy/dist/pypy/jit/timeshifter/vdict.py ============================================================================== --- pypy/dist/pypy/jit/timeshifter/vdict.py (original) +++ pypy/dist/pypy/jit/timeshifter/vdict.py Wed Mar 21 22:30:31 2007 @@ -183,7 +183,7 @@ class AbstractVirtualDict(VirtualContainer): - _attrs_ = ('typedesc', 'ownbox') # and no item_boxes + _attrs_ = ('typedesc',) # and no item_boxes FrozenVirtualDict = AbstractFrozenVirtualDict # overridden in subclasses Added: pypy/dist/pypy/module/pypyjit/newbool.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/pypyjit/newbool.py Wed Mar 21 22:30:31 2007 @@ -0,0 +1,204 @@ +from pypy.rpython.lltypesystem import lltype, llmemory +from pypy.rpython.annlowlevel import cachedtype +from pypy.annotation import model as annmodel +from pypy.jit.timeshifter import rvalue, rcontainer +from pypy.objspace.std.boolobject import W_BoolObject + + +class NewBoolDesc: + __metaclass__ = cachedtype + + def __init__(self, hrtyper): + self.hrtyper = hrtyper + RGenOp = hrtyper.RGenOp + rtyper = hrtyper.rtyper + bk = rtyper.annotator.bookkeeper + s_w_bool = annmodel.unionof(bk.immutablevalue(W_BoolObject.w_False), + bk.immutablevalue(W_BoolObject.w_True)) + r_w_bool = rtyper.getrepr(s_w_bool) + self.ll_False = r_w_bool.convert_const(W_BoolObject.w_False) + self.ll_True = r_w_bool.convert_const(W_BoolObject.w_True) + + A = lltype.FixedSizeArray(lltype.typeOf(self.ll_False), 2) + self.ll_bools = lltype.malloc(A, immortal=True) + self.ll_bools[0] = self.ll_False + self.ll_bools[1] = self.ll_True + self.gv_bools = RGenOp.constPrebuiltGlobal(self.ll_bools) + self.boolsToken = RGenOp.arrayToken(A) + + self.bools_gv = [RGenOp.constPrebuiltGlobal(self.ll_False), + RGenOp.constPrebuiltGlobal(self.ll_True)] + + self.ptrkind = RGenOp.kindToken(r_w_bool.lowleveltype) + self.boolkind = RGenOp.kindToken(lltype.Bool) + + ll_BoolObject = r_w_bool.rclass.getvtable() + self.BoolObjectBox = rvalue.redbox_from_prebuilt_value(RGenOp, + ll_BoolObject) + + self.Falsebox = rvalue.redbox_from_prebuilt_value(RGenOp, False) + self.Truebox = rvalue.redbox_from_prebuilt_value(RGenOp, True) + self.boolboxes = [self.Falsebox, self.Truebox] + + def _freeze_(self): + return True + + def vboolfactory(self): + vbool = VirtualBool(self) + box = rvalue.PtrRedBox(self.ptrkind, known_nonzero=True) + box.content = vbool + vbool.ownbox = box + return vbool + + def metafunc(self, jitstate, valuebox): + vbool = self.vboolfactory() + vbool.valuebox = valuebox + return vbool.ownbox + + def getboolbox(self, jitstate, gv_bool, reverse=False): + if gv_bool.is_const: + flag = gv_bool.revealconst(lltype.Bool) + return self.boolboxes[flag ^ reverse] + else: + if reverse: + gv_bool = jitstate.curbuilder.genop1("bool_not", gv_bool) + return rvalue.IntRedBox(self.boolkind, gv_bool) + + def genbooleq(self, jitstate, gv_bool1, gv_bool2, reverse=False): + if gv_bool1.is_const: + reverse ^= not gv_bool1.revealconst(lltype.Bool) + return self.getboolbox(jitstate, gv_bool2, reverse) + elif gv_bool2.is_const: + reverse ^= not gv_bool2.revealconst(lltype.Bool) + return self.getboolbox(jitstate, gv_bool1, reverse) + else: + # XXX maybe gv_bool1 == gv_bool2 :-) + curbuilder = jitstate.curbuilder + gv_int1 = curbuilder.genop1("cast_bool_to_int", gv_bool1) + gv_int2 = curbuilder.genop1("cast_bool_to_int", gv_bool2) + if reverse: + gv_res = curbuilder.genop2("int_ne", gv_int1, gv_int2) + else: + gv_res = curbuilder.genop2("int_eq", gv_int1, gv_int2) + return rvalue.IntRedBox(self.boolkind, gv_res) + + +class VirtualBool(rcontainer.VirtualContainer): + + def __init__(self, newbooldesc): + self.newbooldesc = newbooldesc + #self.valuebox = ... set independently + + def enter_block(self, incoming, memo): + contmemo = memo.containers + if self not in contmemo: + contmemo[self] = None + self.valuebox.enter_block(incoming, memo) + + def force_runtime_container(self, jitstate): + desc = self.newbooldesc + valuebox = self.valuebox + if valuebox.is_constant(): + value = valuebox.genvar.revealconst(lltype.Bool) + genvar = desc.bools_gv[value] + else: + gv_index = valuebox.getgenvar(jitstate) + gv_index = jitstate.curbuilder.genop1("cast_bool_to_int", gv_index) + genvar = jitstate.curbuilder.genop_getarrayitem( + desc.boolsToken, + desc.gv_bools, + gv_index) + self.ownbox.setgenvar_hint(genvar, known_nonzero=True) + self.ownbox.content = None + + def freeze(self, memo): + contmemo = memo.containers + assert self not in contmemo # contmemo no longer used + result = contmemo[self] = FrozenBool(self.newbooldesc) + frozenbox = self.valuebox.freeze(memo) + result.fz_valuebox = frozenbox + return result + + def copy(self, memo): + contmemo = memo.containers + assert self not in contmemo # contmemo no longer used + result = contmemo[self] = VirtualBool(self.newbooldesc) + result.valuebox = self.valuebox.copy(memo) + result.ownbox = self.ownbox.copy(memo) + return result + + def replace(self, memo): + contmemo = memo.containers + assert self not in contmemo # contmemo no longer used + contmemo[self] = None + self.valuebox = self.valuebox.replace(memo) + self.ownbox = self.ownbox.replace(memo) + + def op_getfield(self, jitstate, fielddesc): + if fielddesc.fieldindex == 0: # the __class__ field + return self.newbooldesc.BoolObjectBox + else: + # assume it is the 'boolval' field + return self.valuebox + + def op_ptreq(self, jitstate, otherbox, reverse): + desc = self.newbooldesc + if otherbox.is_constant(): + addr = otherbox.genvar.revealconst(llmemory.Address) + if addr == llmemory.cast_ptr_to_adr(desc.ll_False): + return desc.getboolbox(jitstate, self.valuebox.genvar, + not reverse) + elif addr == llmemory.cast_ptr_to_adr(desc.ll_True): + return desc.getboolbox(jitstate, self.valuebox.genvar, + reverse) + else: + return desc.boolboxes[False ^ reverse] + + othercontent = otherbox.content + if not isinstance(othercontent, VirtualBool): + return None # no clue + + return desc.genbooleq(jitstate, + self.valuebox.genvar, + othercontent.valuebox.genvar, + reverse) + + +class FrozenBool(rcontainer.FrozenContainer): + + def __init__(self, newbooldesc): + self.newbooldesc = newbooldesc + #self.fz_valuebox initialized later + + def exactmatch(self, vstruct, outgoingvarboxes, memo): + # XXX code duplication with rcontainer... + contmemo = memo.containers + if self in contmemo: + ok = vstruct is contmemo[self] + if not ok: + outgoingvarboxes.append(vstruct.ownbox) + return ok + if vstruct in contmemo: + assert contmemo[vstruct] is not self + outgoingvarboxes.append(vstruct.ownbox) + return False + if not isinstance(vstruct, VirtualBool): + if not memo.force_merge: + raise rvalue.DontMerge + outgoingvarboxes.append(vstruct.ownbox) + return False + contmemo[self] = vstruct + contmemo[vstruct] = self + return self.fz_valuebox.exactmatch(vstruct.valuebox, + outgoingvarboxes, + memo) + + def unfreeze(self, incomingvarboxes, memo): + contmemo = memo.containers + if self in contmemo: + return contmemo[self] + vbool = self.newbooldesc.vboolfactory() + ownbox = vbool.ownbox + contmemo[self] = ownbox + vbool.valuebox = self.fz_valuebox.unfreeze(incomingvarboxes, memo) + return ownbox Added: pypy/dist/pypy/module/pypyjit/test/test_newbool.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/pypyjit/test/test_newbool.py Wed Mar 21 22:30:31 2007 @@ -0,0 +1,214 @@ +from pypy.rpython.lltypesystem import lltype +from pypy.jit.hintannotator.annotator import HintAnnotatorPolicy +from pypy.jit.timeshifter import rvalue +from pypy.jit.timeshifter.test.test_timeshift import Whatever +from pypy.jit.timeshifter.test.test_timeshift import TimeshiftingTests +from pypy.jit.codegen.model import GenVar +from pypy.jit.codegen.llgraph.rgenop import rgenop +from pypy.module.pypyjit.newbool import NewBoolDesc + + +class DummyDesc(NewBoolDesc): + def __init__(self): + self.boolkind = rgenop.kindToken(lltype.Bool) + self.boolboxes = [rvalue.redbox_from_prebuilt_value(rgenop, False), + rvalue.redbox_from_prebuilt_value(rgenop, True)] + +desc = DummyDesc() + + +class DummyJITState: + def __init__(self): + self.curbuilder = DummyBuilder() + + +class DummyBuilder: + def __init__(self): + self.operations = [] + + def genop1(self, opname, gv_arg): + gv_res = GenVar() + self.operations.append((opname, gv_arg, gv_res)) + return gv_res + + def genop2(self, opname, gv_arg1, gv_arg2): + gv_res = GenVar() + self.operations.append((opname, gv_arg1, gv_arg2, gv_res)) + return gv_res + + +def test_getboolbox(): + for b1 in [False, True]: + for b2 in [False, True]: + jitstate = DummyJITState() + box = desc.getboolbox(jitstate, rgenop.genconst(b1), b2) + assert box.genvar.revealconst(lltype.Bool) == b1 ^ b2 + assert not jitstate.curbuilder.operations + + gv1 = GenVar() + jitstate = DummyJITState() + box = desc.getboolbox(jitstate, gv1, False) + assert box.genvar == gv1 + assert not jitstate.curbuilder.operations + + jitstate = DummyJITState() + box = desc.getboolbox(jitstate, gv1, True) + assert jitstate.curbuilder.operations == [ + ("bool_not", gv1, box.genvar), + ] + +def test_genbooleq(): + gv1 = GenVar() + gv2 = GenVar() + gf = rgenop.genconst(False) + gt = rgenop.genconst(True) + + for b1 in [False, True]: + for b2 in [False, True]: + for rev in [False, True]: + jitstate = DummyJITState() + box = desc.genbooleq(jitstate, + rgenop.genconst(b1), + rgenop.genconst(b2), + rev) + assert box.genvar.revealconst(lltype.Bool) == (b1 == b2) ^ rev + assert not jitstate.curbuilder.operations + + for b2 in [False, True]: + for rev in [False, True]: + for flip in [False, True]: + jitstate = DummyJITState() + args = [gv1, rgenop.genconst(b2), rev] + if flip: + args[0], args[1] = args[1], args[0] + box = desc.genbooleq(jitstate, *args) + + should_neg = (b2 == rev) + if should_neg: + assert jitstate.curbuilder.operations == [ + ("bool_not", gv1, box.genvar), + ] + else: + assert box.genvar == gv1 + assert not jitstate.curbuilder.operations + + for rev in [False, True]: + jitstate = DummyJITState() + box = desc.genbooleq(jitstate, gv1, gv2, rev) + ops = jitstate.curbuilder.operations + _, _, gvi1 = ops[0] + _, _, gvi2 = ops[1] + assert ops == [ + ("cast_bool_to_int", gv1, gvi1), + ("cast_bool_to_int", gv2, gvi2), + (["int_eq", "int_ne"][rev], gvi1, gvi2, box.genvar), + ] + +# ____________________________________________________________ + +from pypy.objspace.std.boolobject import W_BoolObject +from pypy.interpreter.baseobjspace import W_Root + +def newbool(flag): + if flag: + return W_BoolObject.w_True + else: + return W_BoolObject.w_False + +class MyPolicy(HintAnnotatorPolicy): + novirtualcontainer = True + def look_inside_graph(self, graph): + if graph.func is newbool: + return NewBoolDesc + else: + return True + + +class TestNewBool(TimeshiftingTests): + + def test_simple(self): + def f(n): + w_res = newbool(n > 5) + return int(w_res.boolval) + + res = self.timeshift(f, [7], policy=MyPolicy()) + assert res == 1 + self.check_insns({'int_gt': 1, 'cast_bool_to_int': 1}) + + def test_ptreq1(self): + def f(n): + w_res = newbool(n > 5) + return int(w_res is W_BoolObject.w_True) + + res = self.timeshift(f, [3], policy=MyPolicy()) + assert res == 0 + self.check_insns({'int_gt': 1, 'cast_bool_to_int': 1}) + + def test_ptreq2(self): + def f(n): + w_res = newbool(n > 5) + return int(w_res is W_BoolObject.w_False) + + res = self.timeshift(f, [3], policy=MyPolicy()) + assert res == 1 + self.check_insns({'int_gt': 1, 'bool_not': 1, 'cast_bool_to_int': 1}) + + def test_force(self): + def f(n): + w_res = newbool(n > 5) + return w_res + f.convert_result = lambda res: 'foo' + + res = self.timeshift(f, [3], policy=MyPolicy()) + self.check_insns({'int_gt': 1, + 'cast_bool_to_int': 1, 'getarrayitem': 1, + 'cast_pointer': Whatever()}) + + def test_merge_bools(self): + def f(n): + if n > 5: + w_res = newbool(n >= 10) + else: + w_res = newbool(n < -10) + return int(w_res.boolval) + + res = self.timeshift(f, [-3], policy=MyPolicy()) + assert res == 0 + self.check_insns({'int_gt': 1, 'int_ge': 1, 'int_lt': 1, + 'cast_bool_to_int': 1}) + + def test_merge_with_virtual_root(self): + def f(n): + if n > 5: + w_res = newbool(n >= 10) + else: + w_res = W_Root() + return w_res + f.convert_result = lambda res: 'foo' + + res = self.timeshift(f, [-3], policy=MyPolicy()) + self.check_insns({'int_gt': 1, 'int_ge': 1, + 'cast_bool_to_int': 1, 'getarrayitem': 1, + 'malloc': 1, 'setfield': 1, + 'cast_pointer': Whatever()}) + + def test_ptreq3(self): + def f(n): + w1 = newbool(n >= 10) + w2 = W_Root() + return int(w1 is w2) + int(w2 is w1) + + res = self.timeshift(f, [123], policy=MyPolicy()) + assert res == 0 + self.check_insns({'int_ge': 1}) + + def test_ptreq4(self): + w2 = W_Root() + + def f(n): + w1 = newbool(n >= 10) + return int(w1 is w2) + int(w2 is w1) + + res = self.timeshift(f, [123], policy=MyPolicy()) + assert res == 0 + self.check_insns({'int_ge': 1}) Modified: pypy/dist/pypy/objspace/std/boolobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/boolobject.py (original) +++ pypy/dist/pypy/objspace/std/boolobject.py Wed Mar 21 22:30:31 2007 @@ -20,6 +20,9 @@ registerimplementation(W_BoolObject) +W_BoolObject.w_False = W_BoolObject(False) +W_BoolObject.w_True = W_BoolObject(True) + # bool-to-int delegation requires translating the .boolvar attribute # to an .intval one def delegate_Bool2IntObject(space, w_bool): Modified: pypy/dist/pypy/objspace/std/noneobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/noneobject.py (original) +++ pypy/dist/pypy/objspace/std/noneobject.py Wed Mar 21 22:30:31 2007 @@ -14,6 +14,8 @@ registerimplementation(W_NoneObject) +W_NoneObject.w_None = W_NoneObject() + def nonzero__None(space, w_none): return space.w_False Modified: pypy/dist/pypy/objspace/std/objspace.py ============================================================================== --- pypy/dist/pypy/objspace/std/objspace.py (original) +++ pypy/dist/pypy/objspace/std/objspace.py Wed Mar 21 22:30:31 2007 @@ -166,9 +166,9 @@ globals()[cls.__name__] = cls # singletons - self.w_None = W_NoneObject() - self.w_False = W_BoolObject(False) - self.w_True = W_BoolObject(True) + self.w_None = W_NoneObject.w_None + self.w_False = W_BoolObject.w_False + self.w_True = W_BoolObject.w_True from pypy.interpreter.special import NotImplemented, Ellipsis self.w_NotImplemented = self.wrap(NotImplemented(self)) self.w_Ellipsis = self.wrap(Ellipsis(self)) From cfbolz at codespeak.net Wed Mar 21 22:42:47 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 21 Mar 2007 22:42:47 +0100 (CET) Subject: [pypy-svn] r40988 - pypy/extradoc/eu-report Message-ID: <20070321214247.0C55310069@code0.codespeak.net> Author: cfbolz Date: Wed Mar 21 22:42:46 2007 New Revision: 40988 Added: pypy/extradoc/eu-report/D02.1_Development_Tools_and_Website-2007-03-21.pdf - copied unchanged from r40987, pypy/eu-tracking/deliverable/D02_1_Development_Tools_and_Website/D02.1-deliverablereport.pdf Log: add D02.1 final pdf From cfbolz at codespeak.net Wed Mar 21 22:45:23 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 21 Mar 2007 22:45:23 +0100 (CET) Subject: [pypy-svn] r40989 - pypy/dist/pypy/doc Message-ID: <20070321214523.699EC10072@code0.codespeak.net> Author: cfbolz Date: Wed Mar 21 22:45:22 2007 New Revision: 40989 Modified: pypy/dist/pypy/doc/index-report.txt Log: fix link, declare report final Modified: pypy/dist/pypy/doc/index-report.txt ============================================================================== --- pypy/dist/pypy/doc/index-report.txt (original) +++ pypy/dist/pypy/doc/index-report.txt Wed Mar 21 22:45:22 2007 @@ -12,6 +12,10 @@ Reports of 2007 =============== +`D02.1 Development Tools and Website`_ is a report +about the codespeak_ development environment and aditional tool support for the +PyPy development process. *(2007-03-21)* + `D03.1 Extension Compiler`_ is a report about PyPy's extension compiler and RCTypes, as well as the effort to keep up with CPython's changes. *(2007-03-21)* @@ -29,10 +33,6 @@ PyPy development process. The report is still non-final, all feedback for it is welcome. *(2007-03-12)* -`Interim D02.1 Development Tools and Website`_ is an interim version of a report -about the codespeak_ development environment and aditional tool support for the -PyPy development process. The report is still non-final, all feedback for it is welcome. *(2007-03-12)* - `Interim 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 non-final, all feedback for it is welcome. *(2007-03-12)* @@ -121,7 +121,7 @@ .. _`D03.1 Extension Compiler`: http://codespeak.net/pypy/extradoc/eu-report/D03.1_Extension_Compiler-2007-03-21.pdf .. _`Interim D02.3 Testing Tool`: http://codespeak.net/pypy/extradoc/eu-report/D02.3_Testing_Framework-interim-2007-03-12.pdf .. _`Interim D01.2-4 Project Organization`: http://codespeak.net/pypy/extradoc/eu-report/D01.2-4_Project_Organization-interim-2007-03-12.pdf -.. _`Interim D02.1 Development Tools and Website`: http://codespeak.net/pypy/extradoc/eu-report/D02.1_Development_Tools_and_Website-interim-2007-03-12.pdf +.. _`D02.1 Development Tools and Website`: http://codespeak.net/pypy/extradoc/eu-report/D02.1_Development_Tools_and_Website-2007-03-21.pdf .. _`Draft D08.2 JIT Compiler Architecture`: http://codespeak.net/pypy/extradoc/eu-report/D08.2_JIT_Compiler_Architecture-interim-2007-01-28.pdf .. _`Interim D12.1 High-Level-Backends and Feature Prototypes`: http://codespeak.net/pypy/extradoc/eu-report/D12.1_H-L-Backends_and_Feature_Prototypes-interim-2007-03-12.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 Wed Mar 21 22:45:55 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 21 Mar 2007 22:45:55 +0100 (CET) Subject: [pypy-svn] r40990 - pypy/extradoc/eu-report Message-ID: <20070321214555.04B7010075@code0.codespeak.net> Author: cfbolz Date: Wed Mar 21 22:45:54 2007 New Revision: 40990 Removed: pypy/extradoc/eu-report/D02.1_Development_Tools_and_Website-interim-2007-03-12.pdf Log: remove interim version From cfbolz at codespeak.net Wed Mar 21 23:37:47 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 21 Mar 2007 23:37:47 +0100 (CET) Subject: [pypy-svn] r40991 - in pypy/dist/pypy: config doc/config lib lib/distributed module/__pypy__ module/__pypy__/test module/pypymagic module/rsocket/test objspace objspace/std objspace/std/benchmark objspace/std/test objspace/test Message-ID: <20070321223747.14A1E1006F@code0.codespeak.net> Author: cfbolz Date: Wed Mar 21 23:37:46 2007 New Revision: 40991 Added: pypy/dist/pypy/doc/config/objspace.usemodules.__pypy__.txt - copied, changed from r40974, pypy/dist/pypy/doc/config/objspace.usemodules.pypymagic.txt pypy/dist/pypy/module/__pypy__/ - copied from r40974, pypy/dist/pypy/module/pypymagic/ Removed: pypy/dist/pypy/doc/config/objspace.usemodules.pypymagic.txt pypy/dist/pypy/module/pypymagic/ Modified: pypy/dist/pypy/config/pypyoption.py pypy/dist/pypy/lib/distributed/protocol.py pypy/dist/pypy/lib/tputil.py pypy/dist/pypy/module/__pypy__/test/test_special.py pypy/dist/pypy/module/rsocket/test/test_sock_app.py pypy/dist/pypy/objspace/std/benchmark/bench_dict.py pypy/dist/pypy/objspace/std/objspace.py pypy/dist/pypy/objspace/std/test/test_listmultiobject.py pypy/dist/pypy/objspace/std/test/test_proxy.py pypy/dist/pypy/objspace/std/test/test_proxy_function.py pypy/dist/pypy/objspace/std/test/test_proxy_internals.py pypy/dist/pypy/objspace/std/test/test_proxy_object.py pypy/dist/pypy/objspace/std/test/test_rangeobject.py pypy/dist/pypy/objspace/std/test/test_shadowtracking.py pypy/dist/pypy/objspace/std/test/test_strjoinobject.py pypy/dist/pypy/objspace/std/test/test_strsliceobject.py pypy/dist/pypy/objspace/taint.py pypy/dist/pypy/objspace/test/test_taintobjspace.py pypy/dist/pypy/objspace/test/test_thunkobjspace.py pypy/dist/pypy/objspace/thunk.py Log: rename pypymagic -> __pypy__, step 1 Modified: pypy/dist/pypy/config/pypyoption.py ============================================================================== --- pypy/dist/pypy/config/pypyoption.py (original) +++ pypy/dist/pypy/config/pypyoption.py Wed Mar 21 23:37:46 2007 @@ -18,7 +18,7 @@ default_modules.update(dict.fromkeys( ["_codecs", "gc", "_weakref", "array", "marshal", "errno", "math", "_sre", "_pickle_support", "operator", - "recparser", "symbol", "_random", "pypymagic"])) + "recparser", "symbol", "_random", "__pypy__"])) working_modules = default_modules.copy() @@ -189,7 +189,7 @@ default=False, requires=[("objspace.std.withtypeversion", True)]), BoolOption("withmethodcachecounter", - "try to cache methods and provide a counter in pypymagic. " + "try to cache methods and provide a counter in __pypy__. " "for testing purposes only.", default=False, requires=[("objspace.std.withmethodcache", True)]), Modified: pypy/dist/pypy/lib/distributed/protocol.py ============================================================================== --- pypy/dist/pypy/lib/distributed/protocol.py (original) +++ pypy/dist/pypy/lib/distributed/protocol.py Wed Mar 21 23:37:46 2007 @@ -36,8 +36,8 @@ """ try: - from pypymagic import tproxy as proxy - from pypymagic import get_tproxy_controller + from __pypy__ import tproxy as proxy + from __pypy__ import get_tproxy_controller except ImportError: raise ImportError("Cannot work without transparent proxy functionality") @@ -56,7 +56,7 @@ 3. Support inheritance and recursive types """ -from pypymagic import pypy_repr +from __pypy__ import pypy_repr import types from marshal import dumps Modified: pypy/dist/pypy/lib/tputil.py ============================================================================== --- pypy/dist/pypy/lib/tputil.py (original) +++ pypy/dist/pypy/lib/tputil.py Wed Mar 21 23:37:46 2007 @@ -7,7 +7,7 @@ the proxied object. """ -from pypymagic import tproxy +from __pypy__ import tproxy from types import MethodType _dummy = object() Modified: pypy/dist/pypy/module/__pypy__/test/test_special.py ============================================================================== --- pypy/dist/pypy/module/pypymagic/test/test_special.py (original) +++ pypy/dist/pypy/module/__pypy__/test/test_special.py Wed Mar 21 23:37:46 2007 @@ -8,12 +8,12 @@ cls.space = gettestobjspace(**{"objspace.usemodules.select": False}) def test__isfake(self): - from pypymagic import isfake + from __pypy__ import isfake assert not isfake(map) assert not isfake(object) assert not isfake(isfake) def test__isfake_currently_true(self): - from pypymagic import isfake + from __pypy__ import isfake import select assert isfake(select) 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 Wed Mar 21 23:37:46 2007 @@ -448,8 +448,8 @@ import errno try: s = socket(AF_INET, SOCK_STREAM) - import pypymagic - print pypymagic.pypy_repr(s) + import __pypy__ + print __pypy__.pypy_repr(s) s.accept() except Exception, e: assert len(e.args) == 2 Modified: pypy/dist/pypy/objspace/std/benchmark/bench_dict.py ============================================================================== --- pypy/dist/pypy/objspace/std/benchmark/bench_dict.py (original) +++ pypy/dist/pypy/objspace/std/benchmark/bench_dict.py Wed Mar 21 23:37:46 2007 @@ -47,6 +47,6 @@ if __name__ == '__main__': test_d = bench_simple_dict() - import pypymagic - print pypymagic.pypy_repr(test_d) - print pypymagic.pypy_repr(test_d.iterkeys()) + import __pypy__ + print __pypy__.pypy_repr(test_d) + print __pypy__.pypy_repr(test_d.iterkeys()) Modified: pypy/dist/pypy/objspace/std/objspace.py ============================================================================== --- pypy/dist/pypy/objspace/std/objspace.py (original) +++ pypy/dist/pypy/objspace/std/objspace.py Wed Mar 21 23:37:46 2007 @@ -212,12 +212,12 @@ self.setup_builtin_modules() # Adding transparent proxy call if self.config.objspace.std.withtproxy: - w_pypymagic = self.getbuiltinmodule("pypymagic") + w___pypy__ = self.getbuiltinmodule("__pypy__") from pypy.objspace.std.transparent import app_proxy, app_proxy_controller - self.setattr(w_pypymagic, self.wrap('tproxy'), + self.setattr(w___pypy__, self.wrap('tproxy'), self.wrap(app_proxy)) - self.setattr(w_pypymagic, self.wrap('get_tproxy_controller'), + self.setattr(w___pypy__, self.wrap('get_tproxy_controller'), self.wrap(app_proxy_controller)) def enable_old_style_classes_as_default_metaclass(self): 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 Wed Mar 21 23:37:46 2007 @@ -17,9 +17,9 @@ assert l2 == range(1, 19, 2) def test_strlist_literal(self): - import pypymagic + import __pypy__ l = ["1", "2", "3", "4", "5"] - assert "StrListImplementation" in pypymagic.pypy_repr(l) + assert "StrListImplementation" in __pypy__.pypy_repr(l) def test_strlist_delitem(self): l = ["1", "2"] @@ -27,24 +27,24 @@ assert l == ["2"] def test_strlist_append(self): - import pypymagic + import __pypy__ l = [] l.append("a") - assert "StrListImplementation" in pypymagic.pypy_repr(l) + assert "StrListImplementation" in __pypy__.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) + assert "StrListImplementation" in __pypy__.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 + import __pypy__ def f(r): return (isinstance(r, list) and - "RangeImplementation" in pypymagic.pypy_repr(r)) + "RangeImplementation" in __pypy__.pypy_repr(r)) return f """) @@ -57,34 +57,34 @@ cls.space = gettestobjspace(**{"objspace.std.withfastslice": True}) def test_lazy_slice(self): - import pypymagic + import __pypy__ 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) + assert "SliceTrackingListImplementation" in __pypy__.pypy_repr(l) + assert "SliceListImplementation" in __pypy__.pypy_repr(l2) result = 0 for i in l2: result += i # didn't force l2 - assert "SliceListImplementation" in pypymagic.pypy_repr(l2) + assert "SliceListImplementation" in __pypy__.pypy_repr(l2) # force l2: l2.append(10) assert l2 == range(1, 99) + [10] def test_append_extend_dont_force(self): - import pypymagic + import __pypy__ 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) + assert "SliceTrackingListImplementation" in __pypy__.pypy_repr(l) + assert "SliceListImplementation" in __pypy__.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) + assert "SliceTrackingListImplementation" in __pypy__.pypy_repr(l) + assert "SliceListImplementation" in __pypy__.pypy_repr(l2) def test_slice_of_slice(self): - import pypymagic + import __pypy__ l = [i for i in range(100)] # force it to not be a range impl l2 = l[1:-1] l3 = l2[1:-1] @@ -92,17 +92,17 @@ assert l2 == range(1, 99) assert l3 == range(2, 98) assert l4 == range(3, 97) - assert "SliceListImplementation" in pypymagic.pypy_repr(l4) + assert "SliceListImplementation" in __pypy__.pypy_repr(l4) l2[3] = 4 - assert "SliceListImplementation" not in pypymagic.pypy_repr(l2) - assert "SliceListImplementation" in pypymagic.pypy_repr(l4) + assert "SliceListImplementation" not in __pypy__.pypy_repr(l2) + assert "SliceListImplementation" in __pypy__.pypy_repr(l4) def test_delitem_to_empty(self): - import pypymagic + import __pypy__ 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) + assert "EmptyListImplementation" in __pypy__.pypy_repr(l1) class TestSliceListImplementation(object): def setup_method(self,method): Modified: pypy/dist/pypy/objspace/std/test/test_proxy.py ============================================================================== --- pypy/dist/pypy/objspace/std/test/test_proxy.py (original) +++ pypy/dist/pypy/objspace/std/test/test_proxy.py Wed Mar 21 23:37:46 2007 @@ -19,7 +19,7 @@ return Controller """) self.w_proxy = self.space.appexec([], """(): - from pypymagic import tproxy + from __pypy__ import tproxy return tproxy """) Modified: pypy/dist/pypy/objspace/std/test/test_proxy_function.py ============================================================================== --- pypy/dist/pypy/objspace/std/test/test_proxy_function.py (original) +++ pypy/dist/pypy/objspace/std/test/test_proxy_function.py Wed Mar 21 23:37:46 2007 @@ -19,7 +19,7 @@ return getattr(self.obj, name)(*args, **kwargs) def get_proxy(f): import types - from pypymagic import tproxy as proxy + from __pypy__ import tproxy as proxy return proxy(types.FunctionType, Controller(f).perform) return get_proxy """) @@ -90,7 +90,7 @@ class AA: pass - from pypymagic import tproxy as proxy + from __pypy__ import tproxy as proxy a = A() class X: def __init__(self, x): Modified: pypy/dist/pypy/objspace/std/test/test_proxy_internals.py ============================================================================== --- pypy/dist/pypy/objspace/std/test/test_proxy_internals.py (original) +++ pypy/dist/pypy/objspace/std/test/test_proxy_internals.py Wed Mar 21 23:37:46 2007 @@ -16,7 +16,7 @@ def perform(self, name, *args, **kwargs): return getattr(self.obj, name)(*args, **kwargs) def get_proxy(f): - from pypymagic import tproxy as proxy + from __pypy__ import tproxy as proxy return proxy(type(f), Controller(f).perform) return get_proxy """) @@ -71,7 +71,7 @@ import traceback def get_proxy(f): - from pypymagic import tproxy as proxy + from __pypy__ import tproxy as proxy return proxy(type(f), Controller(f).perform) class FakeTb(object): @@ -115,7 +115,7 @@ assert traceback.format_tb(last_tb) == traceback.format_tb(e[2]) def test_proxy_get(self): - from pypymagic import tproxy, get_tproxy_controller + from __pypy__ import tproxy, get_tproxy_controller l = [1,2,3] def f(name, *args, **kwargs): return getattr(l, name)(*args, **kwargs) Modified: pypy/dist/pypy/objspace/std/test/test_proxy_object.py ============================================================================== --- pypy/dist/pypy/objspace/std/test/test_proxy_object.py (original) +++ pypy/dist/pypy/objspace/std/test/test_proxy_object.py Wed Mar 21 23:37:46 2007 @@ -13,7 +13,7 @@ return A """) self.w_proxy = self.space.appexec([], """(): - from pypymagic import tproxy + from __pypy__ import tproxy return tproxy """) @@ -106,7 +106,7 @@ return A """) self.w_proxy = self.space.appexec([], """(): - from pypymagic import tproxy + from __pypy__ import tproxy return tproxy """) 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 Wed Mar 21 23:37:46 2007 @@ -7,10 +7,10 @@ def setup_class(cls): cls.space = gettestobjspace(**{"objspace.std.withrangelist": True}) cls.w_not_forced = cls.space.appexec([], """(): - import pypymagic + import __pypy__ def f(r): return (isinstance(r, list) and - "W_ListObject" not in pypymagic.pypy_repr(r)) + "W_ListObject" not in __pypy__.pypy_repr(r)) return f """) 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 Wed Mar 21 23:37:46 2007 @@ -111,7 +111,7 @@ **{"objspace.std.withmethodcachecounter": True}) def test_mix_classes(self): - import pypymagic + import __pypy__ class A(object): def f(self): return 42 @@ -122,16 +122,16 @@ def f(self): return 44 l = [A(), B(), C()] * 10 - pypymagic.reset_method_cache_counter() + __pypy__.reset_method_cache_counter() for i, a in enumerate(l): assert a.f() == 42 + i % 3 - cache_counter = pypymagic.method_cache_counter("f") + cache_counter = __pypy__.method_cache_counter("f") assert cache_counter[0] >= 15 assert cache_counter[1] >= 3 # should be (27, 3) assert sum(cache_counter) == 30 def test_class_that_cannot_be_cached(self): - import pypymagic + import __pypy__ class metatype(type): pass class A(object): @@ -146,29 +146,29 @@ def f(self): return 44 l = [A(), B(), C()] * 10 - pypymagic.reset_method_cache_counter() + __pypy__.reset_method_cache_counter() for i, a in enumerate(l): assert a.f() == 42 + i % 3 - cache_counter = pypymagic.method_cache_counter("f") + cache_counter = __pypy__.method_cache_counter("f") assert cache_counter[0] >= 9 assert cache_counter[1] >= 2 # should be (18, 2) assert sum(cache_counter) == 20 def test_change_methods(self): - import pypymagic + import __pypy__ class A(object): def f(self): return 42 l = [A()] * 10 - pypymagic.reset_method_cache_counter() + __pypy__.reset_method_cache_counter() for i, a in enumerate(l): assert a.f() == 42 + i A.f = eval("lambda self: %s" % (42 + i + 1, )) - cache_counter = pypymagic.method_cache_counter("f") + cache_counter = __pypy__.method_cache_counter("f") assert cache_counter == (0, 10) def test_subclasses(self): - import pypymagic + import __pypy__ class A(object): def f(self): return 42 @@ -178,16 +178,16 @@ class C(A): pass l = [A(), B(), C()] * 10 - pypymagic.reset_method_cache_counter() + __pypy__.reset_method_cache_counter() for i, a in enumerate(l): assert a.f() == 42 + (i % 3 == 1) - cache_counter = pypymagic.method_cache_counter("f") + cache_counter = __pypy__.method_cache_counter("f") assert cache_counter[0] >= 15 assert cache_counter[1] >= 3 # should be (27, 3) assert sum(cache_counter) == 30 def test_many_names(self): - import pypymagic + import __pypy__ class A(object): foo = 5 bar = 6 @@ -202,11 +202,11 @@ if not name.startswith('_')] names_repeated = names * 10 result = [] - pypymagic.reset_method_cache_counter() + __pypy__.reset_method_cache_counter() for name in names_repeated: result.append(getattr(a, name)) - append_counter = pypymagic.method_cache_counter("append") - names_counters = [pypymagic.method_cache_counter(name) + append_counter = __pypy__.method_cache_counter("append") + names_counters = [__pypy__.method_cache_counter(name) for name in names] assert append_counter[0] >= 5 * len(names) for name, count in zip(names, names_counters): 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 Wed Mar 21 23:37:46 2007 @@ -9,10 +9,10 @@ cls.space = gettestobjspace(**{"objspace.std.withstrjoin": True}) def test_basic(self): - import pypymagic + import __pypy__ s = "Hello, " + "World!" assert type(s) is str - assert 'W_StringJoinObject' in pypymagic.pypy_repr(s) + assert 'W_StringJoinObject' in __pypy__.pypy_repr(s) def test_add_twice(self): x = "a" + "" @@ -21,20 +21,20 @@ assert c == "ab" def test_add(self): - import pypymagic + import __pypy__ all = "" for i in range(20): all += str(i) - assert 'W_StringJoinObject' in pypymagic.pypy_repr(all) + assert 'W_StringJoinObject' in __pypy__.pypy_repr(all) def test_hash(self): - import pypymagic + import __pypy__ # check that we have the same hash as CPython for at least 31 bits # (but don't go checking CPython's special case -1) # disabled: assert hash('') == 0 --- different special case def join(s): return s[:len(s) // 2] + s[len(s) // 2:] s = join('a' * 101) - assert 'W_StringJoinObject' in pypymagic.pypy_repr(s) + assert 'W_StringJoinObject' in __pypy__.pypy_repr(s) assert hash(s) & 0x7fffffff == 0x7e0bce58 def test_len(self): Modified: pypy/dist/pypy/objspace/std/test/test_strsliceobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/test/test_strsliceobject.py (original) +++ pypy/dist/pypy/objspace/std/test/test_strsliceobject.py Wed Mar 21 23:37:46 2007 @@ -15,7 +15,7 @@ cls.w_not_forced = cls.space.wrap(gateway.interp2app(not_forced)) def test_basic(self): - import pypymagic + import __pypy__ def slice(s): return (s*3)[len(s):-len(s)] s = slice('0123456789' * 20) assert len(s) == 200 @@ -23,17 +23,17 @@ assert s[5] == '5' assert s[-2] == '8' assert s[3:7] == '3456' - assert 'W_StringSliceObject' in pypymagic.pypy_repr(s) + assert 'W_StringSliceObject' in __pypy__.pypy_repr(s) # when the slice is too short, don't use the slice string object - assert 'W_StringObject' in pypymagic.pypy_repr("abcdefgh"[3:7]) + assert 'W_StringObject' in __pypy__.pypy_repr("abcdefgh"[3:7]) s2 = s.upper() assert not self.not_forced(s) def test_find(self): - import pypymagic + import __pypy__ def slice(s): return (s*3)[len(s):-len(s)] s = slice('abcdefghiabc' + "X" * 100) - assert 'W_StringSliceObject' in pypymagic.pypy_repr(s) + assert 'W_StringSliceObject' in __pypy__.pypy_repr(s) assert slice('abcdefghiabc' + 'X' * 100) == 'abcdefghiabc' + 'X' * 100 res = s.find('abc') assert res == 0 @@ -41,11 +41,11 @@ assert s.find('def', 4) == -1 def test_index(self): - import pypymagic, sys + import __pypy__, sys m = sys.maxint def slice(s): return (s*3)[len(s):-len(s)] s = slice('abcdefghiabc' * 20) - assert 'W_StringSliceObject' in pypymagic.pypy_repr(s) + assert 'W_StringSliceObject' in __pypy__.pypy_repr(s) assert s.index('') == 0 assert s.index('def') == 3 assert s.index('abc') == 0 @@ -59,21 +59,21 @@ raises(TypeError, slice('abcdefghijklmn' * 20).index, 'abc', -10.0, 30) def test_rfind(self): - import pypymagic + import __pypy__ def slice(s): return (s*3)[len(s):-len(s)] s = slice('abcdefghiabc' + "X" * 100) - assert 'W_StringSliceObject' in pypymagic.pypy_repr(s) + assert 'W_StringSliceObject' in __pypy__.pypy_repr(s) assert s.rfind('abc') == 9 assert s.rfind('') == 112 assert s.rfind('abcd') == 0 assert s.rfind('abcz') == -1 def test_rindex(self): - import pypymagic + import __pypy__ from sys import maxint def slice(s): return (s*3)[len(s):-len(s)] s = slice("X" * 100 + 'abcdefghiabc') - assert 'W_StringSliceObject' in pypymagic.pypy_repr(s) + assert 'W_StringSliceObject' in __pypy__.pypy_repr(s) assert s.rindex('') == 112 assert s.rindex('def') == 103 assert s.rindex('abc') == 109 @@ -90,10 +90,10 @@ 'abc', -10.0, 30) def test_contains(self): - import pypymagic + import __pypy__ def slice(s): return (s*3)[len(s):-len(s)] s = slice("abc" + "X" * 100) - assert 'W_StringSliceObject' in pypymagic.pypy_repr(s) + assert 'W_StringSliceObject' in __pypy__.pypy_repr(s) assert '' in s assert 'a' in s assert 'ab' in s @@ -101,31 +101,31 @@ raises(TypeError, slice('a' * 100).__contains__, 1) def test_hash(self): - import pypymagic + import __pypy__ # check that we have the same hash as CPython for at least 31 bits # (but don't go checking CPython's special case -1) # disabled: assert hash('') == 0 --- different special case def slice(s): return (s*3)[len(s):-len(s)] s = slice('a' * 101) - assert 'W_StringSliceObject' in pypymagic.pypy_repr(s) + assert 'W_StringSliceObject' in __pypy__.pypy_repr(s) assert hash(s) & 0x7fffffff == 0x7e0bce58 def test_split_produces_strslices(self): - import pypymagic + import __pypy__ l = ("X" * 100 + "," + "Y" * 100).split(",") - assert "W_StringSliceObject" in pypymagic.pypy_repr(l[0]) - assert "W_StringSliceObject" in pypymagic.pypy_repr(l[1]) + assert "W_StringSliceObject" in __pypy__.pypy_repr(l[0]) + assert "W_StringSliceObject" in __pypy__.pypy_repr(l[1]) def test_strip_produces_strslices(self): - import pypymagic + import __pypy__ s = ("abc" + "X" * 100 + "," + "Y" * 100 + "abc").strip("abc") - assert "W_StringSliceObject" in pypymagic.pypy_repr(s) + assert "W_StringSliceObject" in __pypy__.pypy_repr(s) def test_splitlines_produces_strslices(self): - import pypymagic + import __pypy__ l = ("X" * 100 + "\n" + "Y" * 100).splitlines() - assert "W_StringSliceObject" in pypymagic.pypy_repr(l[0]) - assert "W_StringSliceObject" in pypymagic.pypy_repr(l[1]) + assert "W_StringSliceObject" in __pypy__.pypy_repr(l[0]) + assert "W_StringSliceObject" in __pypy__.pypy_repr(l[1]) def test_count_does_not_force(self): def slice(s): return (s*3)[len(s):-len(s)] Modified: pypy/dist/pypy/objspace/taint.py ============================================================================== --- pypy/dist/pypy/objspace/taint.py (original) +++ pypy/dist/pypy/objspace/taint.py Wed Mar 21 23:37:46 2007 @@ -206,21 +206,21 @@ self.newtuple([self.w_Exception]), w_dict ) - w_pypymagic = self.getbuiltinmodule("pypymagic") - self.setattr(w_pypymagic, self.wrap('taint'), + w___pypy__ = self.getbuiltinmodule("__pypy__") + self.setattr(w___pypy__, self.wrap('taint'), self.wrap(app_taint)) - self.setattr(w_pypymagic, self.wrap('is_tainted'), + self.setattr(w___pypy__, self.wrap('is_tainted'), self.wrap(app_is_tainted)) - self.setattr(w_pypymagic, self.wrap('untaint'), + self.setattr(w___pypy__, 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.setattr(w___pypy__, self.wrap('taint_atomic'), self.wrap(app_taint_atomic)) - self.setattr(w_pypymagic, self.wrap('TaintError'), + self.setattr(w___pypy__, self.wrap('TaintError'), self.w_TaintError) - self.setattr(w_pypymagic, self.wrap('_taint_debug'), + self.setattr(w___pypy__, self.wrap('_taint_debug'), self.wrap(app_taint_debug)) - self.setattr(w_pypymagic, self.wrap('_taint_look'), + self.setattr(w___pypy__, self.wrap('_taint_look'), self.wrap(app_taint_look)) patch_space_in_place(self, 'taint', proxymaker) 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 Wed Mar 21 23:37:46 2007 @@ -6,7 +6,7 @@ cls.space = gettestobjspace('taint') def test_simple(self): - from pypymagic import taint, untaint, TaintError + from __pypy__ import taint, untaint, TaintError x = taint(6) x = x * 7 raises(TaintError, "if x: y = 1") @@ -16,7 +16,7 @@ raises(TaintError, "untaint(float, x)") def test_bomb(self): - from pypymagic import taint, untaint, TaintError + from __pypy__ import taint, untaint, TaintError x = taint(6) x = x / 0 raises(TaintError, "if x: y = 1") @@ -26,7 +26,7 @@ raises(TaintError, "untaint(float, x)") def test_taint_atomic(self): - from pypymagic import taint, untaint, TaintError, taint_atomic + from __pypy__ import taint, untaint, TaintError, taint_atomic x = taint(6) x *= 7 @@ -42,7 +42,7 @@ assert untaint(int, y) == 5 def test_taint_atomic_exception(self): - from pypymagic import taint, untaint, TaintError, taint_atomic + from __pypy__ import taint, untaint, TaintError, taint_atomic x = taint(6) x *= 7 @@ -58,7 +58,7 @@ raises(TaintError, "untaint(int, y)") def test_taint_atomic_incoming_bomb(self): - from pypymagic import taint, untaint, TaintError, taint_atomic + from __pypy__ import taint, untaint, TaintError, taint_atomic x = taint(6) x /= 0 lst = [] 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 Wed Mar 21 23:37:46 2007 @@ -6,7 +6,7 @@ cls.space = gettestobjspace('thunk') def test_simple(self): - from pypymagic import thunk, become + from __pypy__ import thunk, become computed = [] def f(): computed.append(True) @@ -21,7 +21,7 @@ assert computed == [True] def test_setitem(self): - from pypymagic import thunk, become + from __pypy__ import thunk, become computed = [] def f(a): computed.append(True) @@ -39,7 +39,7 @@ assert d[7] == [43] def test_become(self): - from pypymagic import thunk, become + from __pypy__ import thunk, become x = [] y = [] assert x is not y @@ -47,7 +47,7 @@ assert x is y def test_id(self): - from pypymagic import thunk, become + from __pypy__ import thunk, become # these are the Smalltalk semantics of become(). x = []; idx = id(x) y = []; idy = id(y) @@ -56,7 +56,7 @@ assert id(x) == id(y) == idy def test_double_become(self): - from pypymagic import thunk, become + from __pypy__ import thunk, become x = [] y = [] z = [] @@ -65,28 +65,28 @@ assert x is y is z def test_thunk_forcing_while_forcing(self): - from pypymagic import thunk, become + from __pypy__ import thunk, become def f(): return x+1 x = thunk(f) raises(RuntimeError, 'x+1') def INPROGRESS_test_thunk_forcing_while_forcing_2(self): - from pypymagic import thunk, become + from __pypy__ import thunk, become def f(): return x x = thunk(f) raises(RuntimeError, 'x+1') def test_is_thunk(self): - from pypymagic import thunk, become, is_thunk + from __pypy__ import thunk, become, is_thunk def f(): pass assert is_thunk(thunk(f)) assert not is_thunk(42) def test_lazy(self): - from pypymagic import lazy + from __pypy__ import lazy lst = [] def f(x): lst.append(x) Modified: pypy/dist/pypy/objspace/thunk.py ============================================================================== --- pypy/dist/pypy/objspace/thunk.py (original) +++ pypy/dist/pypy/objspace/thunk.py Wed Mar 21 23:37:46 2007 @@ -1,7 +1,7 @@ """Example usage: $ py.py -o thunk - >>> from pypymagic import thunk, lazy, become + >>> from __pypy__ import thunk, lazy, become >>> def f(): ... print 'computing...' ... return 6*7 @@ -172,14 +172,14 @@ from pypy.objspace import std space = std.Space(*args, **kwds) patch_space_in_place(space, 'thunk', proxymaker) - w_pypymagic = space.getbuiltinmodule("pypymagic") + w___pypy__ = space.getbuiltinmodule("__pypy__") space.w_fn_thunk = space.wrap(app_thunk) - space.setattr(w_pypymagic, space.wrap('thunk'), + space.setattr(w___pypy__, space.wrap('thunk'), space.w_fn_thunk) - space.setattr(w_pypymagic, space.wrap('is_thunk'), + space.setattr(w___pypy__, space.wrap('is_thunk'), space.wrap(app_is_thunk)) - space.setattr(w_pypymagic, space.wrap('become'), + space.setattr(w___pypy__, space.wrap('become'), space.wrap(app_become)) - space.setattr(w_pypymagic, space.wrap('lazy'), + space.setattr(w___pypy__, space.wrap('lazy'), space.wrap(app_lazy)) return space From cfbolz at codespeak.net Wed Mar 21 23:41:23 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 21 Mar 2007 23:41:23 +0100 (CET) Subject: [pypy-svn] r40992 - pypy/dist/pypy/doc Message-ID: <20070321224123.B6AD91006F@code0.codespeak.net> Author: cfbolz Date: Wed Mar 21 23:41:21 2007 New Revision: 40992 Modified: pypy/dist/pypy/doc/getting-started.txt pypy/dist/pypy/doc/objspace-proxies.txt Log: fix docs Modified: pypy/dist/pypy/doc/getting-started.txt ============================================================================== --- pypy/dist/pypy/doc/getting-started.txt (original) +++ pypy/dist/pypy/doc/getting-started.txt Wed Mar 21 23:41:21 2007 @@ -261,7 +261,7 @@ cd pypy python bin/py.py -o thunk - >>>> from pypymagic import thunk + >>>> from __pypy__ import thunk >>>> def longcomputation(lst): .... print "computing..." .... return sum(lst) Modified: pypy/dist/pypy/doc/objspace-proxies.txt ============================================================================== --- pypy/dist/pypy/doc/objspace-proxies.txt (original) +++ pypy/dist/pypy/doc/objspace-proxies.txt Wed Mar 21 23:41:21 2007 @@ -50,7 +50,7 @@ Example usage:: $ py.py -o thunk - >>>> from pypymagic import thunk + >>>> from __pypy__ import thunk >>>> def f(): .... print 'computing...' .... return 6*7 @@ -70,7 +70,7 @@ and globally replaced with another:: $ py.py -o thunk - >>>> from pypymagic import become + >>>> from __pypy__ import become >>>> x = object() >>>> lst = [1, 2, x, 4] >>>> become(x, 3) @@ -82,7 +82,7 @@ invoked before the result is used, if at all):: $ py.py -o thunk - >>>> from pypymagic import lazy + >>>> from __pypy__ import lazy >>>> @lazy .... def f(x): .... print 'computing...' @@ -194,7 +194,7 @@ Start a py.py with the Taint Object Space and try the following example:: $ py.py -o taint - >>>> from pypymagic import taint + >>>> from __pypy__ import taint >>>> x = taint(6) # x is hidden from now on. We can pass it around and @@ -231,7 +231,7 @@ ``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 + >>>> from __pypy__ import taint >>>> untaint(int, x) 6 >>>> untaint(int, z) @@ -286,7 +286,7 @@ 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 way to peek in a Taint -Box or Bomb, ``pypymagic._taint_look(x)``, and a "debug mode" that +Box or Bomb, ``__pypy__._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 @@ -303,7 +303,7 @@ There is a built-in decorator that does exactly that:: - >>>> @pypymagic.taint_atomic + >>>> @__pypy__.taint_atomic >>>> def myop(x, y): .... while x > 0: .... x -= y @@ -385,7 +385,7 @@ 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: +the ``__pypy__`` module exposes the following interface: * ``taint(obj)`` @@ -467,7 +467,7 @@ return ``42`` on any add operation to the list:: $ py.py --with-transparent-proxy - >>>> from pypymagic import tproxy + >>>> from __pypy__ import tproxy >>>> def f(operation, *args, **kwargs): >>>> if operation == '__add__': >>>> return 42 @@ -527,7 +527,7 @@ -------------------------------------- If you are using the `--with-transparent-proxies` option -the `pypymagic`_ module provides the following builtins: +the `__pypy__`_ module provides the following builtins: * ``tproxy(type, controller)``: returns a proxy object representing the given type and forwarding all operations @@ -538,7 +538,7 @@ controller for a given object. For non-proxied objects ``None`` is returned. -.. _pypymagic: +.. ___pypy__: .. _tputil: From cfbolz at codespeak.net Wed Mar 21 23:59:41 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 21 Mar 2007 23:59:41 +0100 (CET) Subject: [pypy-svn] r40996 - in pypy/dist/pypy: doc/discussion lib/distributed module/__pypy__ module/rsocket/test objspace/std/benchmark objspace/std/test translator/js/examples/console Message-ID: <20070321225941.239E61006F@code0.codespeak.net> Author: cfbolz Date: Wed Mar 21 23:59:40 2007 New Revision: 40996 Modified: pypy/dist/pypy/doc/discussion/distribution-newattempt.txt pypy/dist/pypy/lib/distributed/protocol.py pypy/dist/pypy/module/__pypy__/__init__.py pypy/dist/pypy/module/__pypy__/interp_magic.py pypy/dist/pypy/module/rsocket/test/test_sock_app.py pypy/dist/pypy/objspace/std/benchmark/bench_dict.py pypy/dist/pypy/objspace/std/test/test_listmultiobject.py pypy/dist/pypy/objspace/std/test/test_rangeobject.py pypy/dist/pypy/objspace/std/test/test_strjoinobject.py pypy/dist/pypy/objspace/std/test/test_strsliceobject.py pypy/dist/pypy/translator/js/examples/console/ideas.txt Log: rename pypy_repr to internal_repr Modified: pypy/dist/pypy/doc/discussion/distribution-newattempt.txt ============================================================================== --- pypy/dist/pypy/doc/discussion/distribution-newattempt.txt (original) +++ pypy/dist/pypy/doc/discussion/distribution-newattempt.txt Wed Mar 21 23:59:40 2007 @@ -14,7 +14,7 @@ What we want to achieve is to have a transparent enough layer on local side, which does not allow user to tell the objects local and remote apart -(despit sys.pypy_repr, which I would consider cheating). +(despite __pypy__.internal_repr, which I would consider cheating). Because in pypy we have possibility to have different implementations for types (even builtin ones), we can use that mechanism to implement Modified: pypy/dist/pypy/lib/distributed/protocol.py ============================================================================== --- pypy/dist/pypy/lib/distributed/protocol.py (original) +++ pypy/dist/pypy/lib/distributed/protocol.py Wed Mar 21 23:59:40 2007 @@ -56,7 +56,7 @@ 3. Support inheritance and recursive types """ -from __pypy__ import pypy_repr +from __pypy__ import internal_repr import types from marshal import dumps Modified: pypy/dist/pypy/module/__pypy__/__init__.py ============================================================================== --- pypy/dist/pypy/module/__pypy__/__init__.py (original) +++ pypy/dist/pypy/module/__pypy__/__init__.py Wed Mar 21 23:59:40 2007 @@ -7,7 +7,7 @@ } interpleveldefs = { - 'pypy_repr' : 'interp_magic.pypy_repr', + 'internal_repr' : 'interp_magic.internal_repr', } def setup_after_space_initialization(self): Modified: pypy/dist/pypy/module/__pypy__/interp_magic.py ============================================================================== --- pypy/dist/pypy/module/__pypy__/interp_magic.py (original) +++ pypy/dist/pypy/module/__pypy__/interp_magic.py Wed Mar 21 23:59:40 2007 @@ -2,7 +2,7 @@ from pypy.interpreter.gateway import ObjSpace from pypy.rlib.objectmodel import we_are_translated -def pypy_repr(space, w_object): +def internal_repr(space, w_object): return space.wrap('%r' % (w_object,)) def isfake(space, w_obj): 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 Wed Mar 21 23:59:40 2007 @@ -449,7 +449,7 @@ try: s = socket(AF_INET, SOCK_STREAM) import __pypy__ - print __pypy__.pypy_repr(s) + print __pypy__.internal_repr(s) s.accept() except Exception, e: assert len(e.args) == 2 Modified: pypy/dist/pypy/objspace/std/benchmark/bench_dict.py ============================================================================== --- pypy/dist/pypy/objspace/std/benchmark/bench_dict.py (original) +++ pypy/dist/pypy/objspace/std/benchmark/bench_dict.py Wed Mar 21 23:59:40 2007 @@ -48,5 +48,5 @@ if __name__ == '__main__': test_d = bench_simple_dict() import __pypy__ - print __pypy__.pypy_repr(test_d) - print __pypy__.pypy_repr(test_d.iterkeys()) + print __pypy__.internal_repr(test_d) + print __pypy__.internal_repr(test_d.iterkeys()) 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 Wed Mar 21 23:59:40 2007 @@ -19,7 +19,7 @@ def test_strlist_literal(self): import __pypy__ l = ["1", "2", "3", "4", "5"] - assert "StrListImplementation" in __pypy__.pypy_repr(l) + assert "StrListImplementation" in __pypy__.internal_repr(l) def test_strlist_delitem(self): l = ["1", "2"] @@ -30,11 +30,11 @@ import __pypy__ l = [] l.append("a") - assert "StrListImplementation" in __pypy__.pypy_repr(l) + assert "StrListImplementation" in __pypy__.internal_repr(l) l.extend(["b", "c", "d"]) l += ["e", "f"] assert l == ["a", "b", "c", "d", "e", "f"] - assert "StrListImplementation" in __pypy__.pypy_repr(l) + assert "StrListImplementation" in __pypy__.internal_repr(l) class AppTestRangeImplementation(AppTestRangeListObject): @@ -44,7 +44,7 @@ import __pypy__ def f(r): return (isinstance(r, list) and - "RangeImplementation" in __pypy__.pypy_repr(r)) + "RangeImplementation" in __pypy__.internal_repr(r)) return f """) @@ -60,13 +60,13 @@ import __pypy__ l = [i for i in range(100)] # force it to not be a range impl l2 = l[1:-1] - assert "SliceTrackingListImplementation" in __pypy__.pypy_repr(l) - assert "SliceListImplementation" in __pypy__.pypy_repr(l2) + assert "SliceTrackingListImplementation" in __pypy__.internal_repr(l) + assert "SliceListImplementation" in __pypy__.internal_repr(l2) result = 0 for i in l2: result += i # didn't force l2 - assert "SliceListImplementation" in __pypy__.pypy_repr(l2) + assert "SliceListImplementation" in __pypy__.internal_repr(l2) # force l2: l2.append(10) assert l2 == range(1, 99) + [10] @@ -75,13 +75,13 @@ import __pypy__ l = [i for i in range(100)] # force it to not be a range impl l2 = l[1:-1] - assert "SliceTrackingListImplementation" in __pypy__.pypy_repr(l) - assert "SliceListImplementation" in __pypy__.pypy_repr(l2) + assert "SliceTrackingListImplementation" in __pypy__.internal_repr(l) + assert "SliceListImplementation" in __pypy__.internal_repr(l2) l.append(100) l.extend(range(101, 110)) assert l == range(110) - assert "SliceTrackingListImplementation" in __pypy__.pypy_repr(l) - assert "SliceListImplementation" in __pypy__.pypy_repr(l2) + assert "SliceTrackingListImplementation" in __pypy__.internal_repr(l) + assert "SliceListImplementation" in __pypy__.internal_repr(l2) def test_slice_of_slice(self): import __pypy__ @@ -92,17 +92,17 @@ assert l2 == range(1, 99) assert l3 == range(2, 98) assert l4 == range(3, 97) - assert "SliceListImplementation" in __pypy__.pypy_repr(l4) + assert "SliceListImplementation" in __pypy__.internal_repr(l4) l2[3] = 4 - assert "SliceListImplementation" not in __pypy__.pypy_repr(l2) - assert "SliceListImplementation" in __pypy__.pypy_repr(l4) + assert "SliceListImplementation" not in __pypy__.internal_repr(l2) + assert "SliceListImplementation" in __pypy__.internal_repr(l4) def test_delitem_to_empty(self): import __pypy__ l = [i for i in range(100)] # force it to not be a range impl l1 = l[1:-1] del l1[:] - assert "EmptyListImplementation" in __pypy__.pypy_repr(l1) + assert "EmptyListImplementation" in __pypy__.internal_repr(l1) class TestSliceListImplementation(object): def setup_method(self,method): 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 Wed Mar 21 23:59:40 2007 @@ -10,7 +10,7 @@ import __pypy__ def f(r): return (isinstance(r, list) and - "W_ListObject" not in __pypy__.pypy_repr(r)) + "W_ListObject" not in __pypy__.internal_repr(r)) return f """) 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 Wed Mar 21 23:59:40 2007 @@ -12,7 +12,7 @@ import __pypy__ s = "Hello, " + "World!" assert type(s) is str - assert 'W_StringJoinObject' in __pypy__.pypy_repr(s) + assert 'W_StringJoinObject' in __pypy__.internal_repr(s) def test_add_twice(self): x = "a" + "" @@ -25,7 +25,7 @@ all = "" for i in range(20): all += str(i) - assert 'W_StringJoinObject' in __pypy__.pypy_repr(all) + assert 'W_StringJoinObject' in __pypy__.internal_repr(all) def test_hash(self): import __pypy__ @@ -34,7 +34,7 @@ # disabled: assert hash('') == 0 --- different special case def join(s): return s[:len(s) // 2] + s[len(s) // 2:] s = join('a' * 101) - assert 'W_StringJoinObject' in __pypy__.pypy_repr(s) + assert 'W_StringJoinObject' in __pypy__.internal_repr(s) assert hash(s) & 0x7fffffff == 0x7e0bce58 def test_len(self): Modified: pypy/dist/pypy/objspace/std/test/test_strsliceobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/test/test_strsliceobject.py (original) +++ pypy/dist/pypy/objspace/std/test/test_strsliceobject.py Wed Mar 21 23:59:40 2007 @@ -23,9 +23,9 @@ assert s[5] == '5' assert s[-2] == '8' assert s[3:7] == '3456' - assert 'W_StringSliceObject' in __pypy__.pypy_repr(s) + assert 'W_StringSliceObject' in __pypy__.internal_repr(s) # when the slice is too short, don't use the slice string object - assert 'W_StringObject' in __pypy__.pypy_repr("abcdefgh"[3:7]) + assert 'W_StringObject' in __pypy__.internal_repr("abcdefgh"[3:7]) s2 = s.upper() assert not self.not_forced(s) @@ -33,7 +33,7 @@ import __pypy__ def slice(s): return (s*3)[len(s):-len(s)] s = slice('abcdefghiabc' + "X" * 100) - assert 'W_StringSliceObject' in __pypy__.pypy_repr(s) + assert 'W_StringSliceObject' in __pypy__.internal_repr(s) assert slice('abcdefghiabc' + 'X' * 100) == 'abcdefghiabc' + 'X' * 100 res = s.find('abc') assert res == 0 @@ -45,7 +45,7 @@ m = sys.maxint def slice(s): return (s*3)[len(s):-len(s)] s = slice('abcdefghiabc' * 20) - assert 'W_StringSliceObject' in __pypy__.pypy_repr(s) + assert 'W_StringSliceObject' in __pypy__.internal_repr(s) assert s.index('') == 0 assert s.index('def') == 3 assert s.index('abc') == 0 @@ -62,7 +62,7 @@ import __pypy__ def slice(s): return (s*3)[len(s):-len(s)] s = slice('abcdefghiabc' + "X" * 100) - assert 'W_StringSliceObject' in __pypy__.pypy_repr(s) + assert 'W_StringSliceObject' in __pypy__.internal_repr(s) assert s.rfind('abc') == 9 assert s.rfind('') == 112 assert s.rfind('abcd') == 0 @@ -73,7 +73,7 @@ from sys import maxint def slice(s): return (s*3)[len(s):-len(s)] s = slice("X" * 100 + 'abcdefghiabc') - assert 'W_StringSliceObject' in __pypy__.pypy_repr(s) + assert 'W_StringSliceObject' in __pypy__.internal_repr(s) assert s.rindex('') == 112 assert s.rindex('def') == 103 assert s.rindex('abc') == 109 @@ -93,7 +93,7 @@ import __pypy__ def slice(s): return (s*3)[len(s):-len(s)] s = slice("abc" + "X" * 100) - assert 'W_StringSliceObject' in __pypy__.pypy_repr(s) + assert 'W_StringSliceObject' in __pypy__.internal_repr(s) assert '' in s assert 'a' in s assert 'ab' in s @@ -107,25 +107,25 @@ # disabled: assert hash('') == 0 --- different special case def slice(s): return (s*3)[len(s):-len(s)] s = slice('a' * 101) - assert 'W_StringSliceObject' in __pypy__.pypy_repr(s) + assert 'W_StringSliceObject' in __pypy__.internal_repr(s) assert hash(s) & 0x7fffffff == 0x7e0bce58 def test_split_produces_strslices(self): import __pypy__ l = ("X" * 100 + "," + "Y" * 100).split(",") - assert "W_StringSliceObject" in __pypy__.pypy_repr(l[0]) - assert "W_StringSliceObject" in __pypy__.pypy_repr(l[1]) + assert "W_StringSliceObject" in __pypy__.internal_repr(l[0]) + assert "W_StringSliceObject" in __pypy__.internal_repr(l[1]) def test_strip_produces_strslices(self): import __pypy__ s = ("abc" + "X" * 100 + "," + "Y" * 100 + "abc").strip("abc") - assert "W_StringSliceObject" in __pypy__.pypy_repr(s) + assert "W_StringSliceObject" in __pypy__.internal_repr(s) def test_splitlines_produces_strslices(self): import __pypy__ l = ("X" * 100 + "\n" + "Y" * 100).splitlines() - assert "W_StringSliceObject" in __pypy__.pypy_repr(l[0]) - assert "W_StringSliceObject" in __pypy__.pypy_repr(l[1]) + assert "W_StringSliceObject" in __pypy__.internal_repr(l[0]) + assert "W_StringSliceObject" in __pypy__.internal_repr(l[1]) def test_count_does_not_force(self): def slice(s): return (s*3)[len(s):-len(s)] Modified: pypy/dist/pypy/translator/js/examples/console/ideas.txt ============================================================================== --- pypy/dist/pypy/translator/js/examples/console/ideas.txt (original) +++ pypy/dist/pypy/translator/js/examples/console/ideas.txt Wed Mar 21 23:59:40 2007 @@ -6,6 +6,6 @@ * Stackless - examples in a docs of stackless/WP7 -* pypymagic.pypy_repr - --faassen, ropes +* __pypy__.internal_repr - --faassen, ropes * changing grammar at the runtime From hpk at codespeak.net Thu Mar 22 00:06:41 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Thu, 22 Mar 2007 00:06:41 +0100 (CET) Subject: [pypy-svn] r40998 - in pypy/dist/pypy/lib: . test2 Message-ID: <20070321230641.05E8F1006F@code0.codespeak.net> Author: hpk Date: Thu Mar 22 00:06:40 2007 New Revision: 40998 Modified: pypy/dist/pypy/lib/test2/test_tputil.py pypy/dist/pypy/lib/tputil.py Log: remove type attribute from operation (get it with type(operation.proxyobj)) Modified: pypy/dist/pypy/lib/test2/test_tputil.py ============================================================================== --- pypy/dist/pypy/lib/test2/test_tputil.py (original) +++ pypy/dist/pypy/lib/test2/test_tputil.py Thu Mar 22 00:06:40 2007 @@ -12,6 +12,18 @@ raises(TypeError, "make_proxy(f)") raises(TypeError, "make_proxy(f, None, None)") + def test_repr(self): + from tputil import make_proxy + l = [] + def func(operation): + l.append(repr(operation)) + return operation.delegate() + tp = make_proxy(func, obj=[]) + tp.append(3) + for rep in l: + assert isinstance(rep, str) + assert rep.find("list") != -1 + def test_virtual_proxy(self): from tputil import make_proxy l = [] @@ -38,8 +50,7 @@ def func(operation): return operation.delegate() l = make_proxy(func, obj=[]) - excinfo = raises(AttributeError, "l.asdasd") - assert str(excinfo).find("asdasd") != -1 + raises(AttributeError, "l.asdasd") def test_proxy_double(self): from tputil import make_proxy Modified: pypy/dist/pypy/lib/tputil.py ============================================================================== --- pypy/dist/pypy/lib/tputil.py (original) +++ pypy/dist/pypy/lib/tputil.py Thu Mar 22 00:06:40 2007 @@ -18,27 +18,27 @@ 'controller' callable. The proxy will appear as a completely regular instance of the given type but all operations on it are send to the - specified controller - which receices on - ProxyOperation instance on each such call. A non-specified - type will default to type(obj) if obj is specified. + specified controller - which receives on + ProxyOperation instance on each such call. + A non-specified type will default to type(obj) + if obj is specified. """ if type is _dummy: if obj is _dummy: - raise TypeError("you must specify a type or an instance obj") + raise TypeError("you must specify a type or an instance obj of it") type = origtype(obj) def perform(opname, *args, **kwargs): - operation = ProxyOperation(tp, type, obj, opname, args, kwargs) + operation = ProxyOperation(tp, obj, opname, args, kwargs) return controller(operation) tp = tproxy(type, perform) return tp class ProxyOperation(object): - def __init__(self, proxyobj, type, obj, opname, args, kwargs): + def __init__(self, proxyobj, obj, opname, args, kwargs): self.proxyobj = proxyobj self.opname = opname self.args = args self.kwargs = kwargs - self.type = type if obj is not _dummy: self.obj = obj @@ -64,5 +64,6 @@ return res def __repr__(self): - return "" %( - self.opname, self.args, self.kwargs, id(self)) + return "" %( + type(self.proxyobj).__name__, self.opname, + self.args, self.kwargs, id(self.proxyobj)) From hpk at codespeak.net Thu Mar 22 00:14:55 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Thu, 22 Mar 2007 00:14:55 +0100 (CET) Subject: [pypy-svn] r41001 - pypy/dist/pypy/lib Message-ID: <20070321231455.B01A710069@code0.codespeak.net> Author: hpk Date: Thu Mar 22 00:14:54 2007 New Revision: 41001 Modified: pypy/dist/pypy/lib/tputil.py Log: fix module docstring Modified: pypy/dist/pypy/lib/tputil.py ============================================================================== --- pypy/dist/pypy/lib/tputil.py (original) +++ pypy/dist/pypy/lib/tputil.py Thu Mar 22 00:14:54 2007 @@ -1,10 +1,6 @@ """ application level support module for transparent proxies. -This currently contains a BaseDispatcher class -whose subclasses may define "op_METH" where METH -is the original method operation name for -the proxied object. """ from __pypy__ import tproxy From cfbolz at codespeak.net Thu Mar 22 00:30:53 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 22 Mar 2007 00:30:53 +0100 (CET) Subject: [pypy-svn] r41002 - in pypy/dist/pypy/objspace: . std Message-ID: <20070321233053.472BD10070@code0.codespeak.net> Author: cfbolz Date: Thu Mar 22 00:30:52 2007 New Revision: 41002 Modified: pypy/dist/pypy/objspace/std/transparent.py pypy/dist/pypy/objspace/thunk.py Log: some more doc strings Modified: pypy/dist/pypy/objspace/std/transparent.py ============================================================================== --- pypy/dist/pypy/objspace/std/transparent.py (original) +++ pypy/dist/pypy/objspace/std/transparent.py Thu Mar 22 00:30:52 2007 @@ -9,6 +9,9 @@ from pypy.objspace.std.typeobject import W_TypeObject def proxy(space, w_type, w_controller): + """tproxy(typ, controller) -> obj +Return something that looks like it is of type typ. It's behaviour is +completely controlled by the controller.""" from pypy.interpreter.typedef import Function, PyTraceback, PyFrame, \ PyCode, GeneratorIterator @@ -39,6 +42,9 @@ "be wrapped (YET)" % w_type.getname(space, "?"))) def proxy_controller(space, w_object): + """get_tproxy_controller(obj) -> controller +If obj is really a transparent proxy, return its controller. Otherwise return +None.""" if isinstance(w_object, W_Transparent): return w_object.w_controller if isinstance(w_object, W_TransparentObject): Modified: pypy/dist/pypy/objspace/thunk.py ============================================================================== --- pypy/dist/pypy/objspace/thunk.py (original) +++ pypy/dist/pypy/objspace/thunk.py Thu Mar 22 00:30:52 2007 @@ -97,6 +97,7 @@ app_become = gateway.interp2app(become) def lazy(space, w_callable): + """Decorator to make a callable return its results wrapped in a thunk.""" meth = Method(space, space.w_fn_thunk, w_callable, space.type(w_callable)) return space.wrap(meth) From cfbolz at codespeak.net Thu Mar 22 00:32:10 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 22 Mar 2007 00:32:10 +0100 (CET) Subject: [pypy-svn] r41003 - pypy/dist/pypy/objspace/std Message-ID: <20070321233210.ED48610070@code0.codespeak.net> Author: cfbolz Date: Thu Mar 22 00:32:09 2007 New Revision: 41003 Modified: pypy/dist/pypy/objspace/std/transparent.py Log: heute ist Ichkannkeinenglischtag Modified: pypy/dist/pypy/objspace/std/transparent.py ============================================================================== --- pypy/dist/pypy/objspace/std/transparent.py (original) +++ pypy/dist/pypy/objspace/std/transparent.py Thu Mar 22 00:32:09 2007 @@ -10,7 +10,7 @@ def proxy(space, w_type, w_controller): """tproxy(typ, controller) -> obj -Return something that looks like it is of type typ. It's behaviour is +Return something that looks like it is of type typ. Its behaviour is completely controlled by the controller.""" from pypy.interpreter.typedef import Function, PyTraceback, PyFrame, \ PyCode, GeneratorIterator From hpk at codespeak.net Thu Mar 22 00:33:10 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Thu, 22 Mar 2007 00:33:10 +0100 (CET) Subject: [pypy-svn] r41004 - pypy/dist/pypy Message-ID: <20070321233310.D640210070@code0.codespeak.net> Author: hpk Date: Thu Mar 22 00:33:09 2007 New Revision: 41004 Modified: pypy/dist/pypy/conftest.py Log: make the check for app_test's a bit less specific (but i am not sure it's worth it at all) Modified: pypy/dist/pypy/conftest.py ============================================================================== --- pypy/dist/pypy/conftest.py (original) +++ pypy/dist/pypy/conftest.py Thu Mar 22 00:33:09 2007 @@ -160,7 +160,7 @@ 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' + return "app_test" in self.listnames() else: return True From hpk at codespeak.net Thu Mar 22 00:33:36 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Thu, 22 Mar 2007 00:33:36 +0100 (CET) Subject: [pypy-svn] r41005 - pypy/dist/pypy/doc Message-ID: <20070321233336.0BFE710074@code0.codespeak.net> Author: hpk Date: Thu Mar 22 00:33:35 2007 New Revision: 41005 Modified: pypy/dist/pypy/doc/objspace-proxies.txt Log: remove mention of 'type' from doc Modified: pypy/dist/pypy/doc/objspace-proxies.txt ============================================================================== --- pypy/dist/pypy/doc/objspace-proxies.txt (original) +++ pypy/dist/pypy/doc/objspace-proxies.txt Thu Mar 22 00:33:35 2007 @@ -560,7 +560,6 @@ ProxyOperation instances have the following attributes: `proxyobj`: the transparent proxy object of this operation. - `type`: the apparent type of the transparent proxy `opname`: the operation name of this operation `args`: positional arguments for this operation `kwargs`: keyword arguments for this operation From cfbolz at codespeak.net Thu Mar 22 00:43:29 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 22 Mar 2007 00:43:29 +0100 (CET) Subject: [pypy-svn] r41006 - in pypy/dist/pypy/doc: . config Message-ID: <20070321234329.A060410070@code0.codespeak.net> Author: cfbolz Date: Thu Mar 22 00:43:28 2007 New Revision: 41006 Added: pypy/dist/pypy/doc/__pypy__-module.txt (contents, props changed) Modified: pypy/dist/pypy/doc/config/objspace.usemodules.__pypy__.txt Log: add docs about __pypy__ module Added: pypy/dist/pypy/doc/__pypy__-module.txt ============================================================================== --- (empty file) +++ pypy/dist/pypy/doc/__pypy__-module.txt Thu Mar 22 00:43:28 2007 @@ -0,0 +1,61 @@ +======================= +The ``__pypy__`` module +======================= + +The ``__pypy__`` module contains special PyPy-specific functionality. Its +contents varies greatly, depending on which `configuration options`_ are used. + +.. _`configuration options`: config/index.html + + +Generally available functionality +================================= + + - ``internal_repr(obj)``: return the interpreter-level representation of an + object. + +Functionality available on py.py +================================ + + - ``isfake(obj)``: returns True if ``obj`` is faked. + + - ``interp_pdb()``: start a pdb at interpreter-level. + + +Thunk Object Space Functionality +================================ + +When the thunk object space is used (choose with :config:`objspace.name`), +the following functions are put into ``__pypy__``: + + - ``thunk(f, *args, **kwargs)``: returns something that behaves like the result + of the call ``f(*args, **kwargs)`` but the call is done lazily. + + - ``is_thunk(obj)``: return True if ``obj`` is a thunk that is not computed + yet. + + - ``become(obj1, obj2)``: globally replace ``obj1`` with ``obj2``. + + - ``lazy(callable)``: Should be used as a function decorator. The decorated + function behaves lazily: all calls to it return a thunk object. + +For explanations and examples see the `thunk object space docs`_. + +.. _`thunk object space docs`: objspace-proxies.html#thunk + +Transparent Proxy Functionality +=============================== + +If `transparent proxies`_ are enabled (with :config:`objspace.std.withtproxy`) +the following functions are put into ``__pypy__``: + + - ``tproxy(typ, controller)``: Return something that looks like it is of type + typ. Its behaviour is completely controlled by the controller. See the docs + about `transparent proxies`_ for detail. + + - ``get_tproxy_controller(obj)``: If obj is really a transparent proxy, return + its controller. Otherwise return None. + +.. _`transparent proxies`: objspace-proxies.html#tproxy + +XXX missing taint obj space docs Modified: pypy/dist/pypy/doc/config/objspace.usemodules.__pypy__.txt ============================================================================== --- pypy/dist/pypy/doc/config/objspace.usemodules.__pypy__.txt (original) +++ pypy/dist/pypy/doc/config/objspace.usemodules.__pypy__.txt Thu Mar 22 00:43:28 2007 @@ -3,5 +3,7 @@ It contains special PyPy-specific functionality. For example most of the special functions described in the `object space proxies` document are in the module. +See the `__pypy__ module documentation`_ for more details. .. _`object space proxy`: ../objspace-proxies.html +.. _`__pypy__ module documentation`: __pypy__-module.html From hpk at codespeak.net Thu Mar 22 07:44:03 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Thu, 22 Mar 2007 07:44:03 +0100 (CET) Subject: [pypy-svn] r41007 - pypy/dist/pypy/doc Message-ID: <20070322064403.6231710069@code0.codespeak.net> Author: hpk Date: Thu Mar 22 07:44:00 2007 New Revision: 41007 Modified: pypy/dist/pypy/doc/__pypy__-module.txt Log: some rewording at the beginning and reshuffling (py.py special functionality last IMO) Modified: pypy/dist/pypy/doc/__pypy__-module.txt ============================================================================== --- pypy/dist/pypy/doc/__pypy__-module.txt (original) +++ pypy/dist/pypy/doc/__pypy__-module.txt Thu Mar 22 07:44:00 2007 @@ -2,26 +2,19 @@ The ``__pypy__`` module ======================= -The ``__pypy__`` module contains special PyPy-specific functionality. Its -contents varies greatly, depending on which `configuration options`_ are used. +The ``__pypy__`` module is the main entry point to special features provided +by PyPy's standard interpreter. Its content depends on `configuration options`_ +which may add new functionality and functions whose existence or non-existence +indicates the presence of such features. .. _`configuration options`: config/index.html - Generally available functionality ================================= - ``internal_repr(obj)``: return the interpreter-level representation of an object. -Functionality available on py.py -================================ - - - ``isfake(obj)``: returns True if ``obj`` is faked. - - - ``interp_pdb()``: start a pdb at interpreter-level. - - Thunk Object Space Functionality ================================ @@ -58,4 +51,14 @@ .. _`transparent proxies`: objspace-proxies.html#tproxy + +Functionality available on py.py +================================ + + - ``isfake(obj)``: returns True if ``obj`` is faked. + + - ``interp_pdb()``: start a pdb at interpreter-level. + + + XXX missing taint obj space docs From hpk at codespeak.net Thu Mar 22 08:44:14 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Thu, 22 Mar 2007 08:44:14 +0100 (CET) Subject: [pypy-svn] r41010 - pypy/dist/demo Message-ID: <20070322074414.54F751006F@code0.codespeak.net> Author: hpk Date: Thu Mar 22 08:44:12 2007 New Revision: 41010 Added: pypy/dist/demo/tp-print-builtin-operation.py (contents, props changed) Log: add a quick demo that prints operations on builtins Added: pypy/dist/demo/tp-print-builtin-operation.py ============================================================================== --- (empty file) +++ pypy/dist/demo/tp-print-builtin-operation.py Thu Mar 22 08:44:12 2007 @@ -0,0 +1,27 @@ +""" + +This example transparently intercepts and shows operations on +builtin objects. It requires the "--with-transparent-proxy" option. + +""" + +from tputil import make_proxy +from __pypy__ import become + +def make_show_proxy(instance): + def controller(operation): + res = operation.delegate() + print "proxy sees:", operation, "result=%s" %(res,) + return res + tproxy = make_proxy(controller, obj=instance) + return tproxy + +mydict = make_show_proxy({}) + +assert type(mydict) is dict # this looks exactly like a dict +mydict['hello'] = 'world' # will print __ +mydict[42] = 23 +assert mydict.pop('hello') == 'world' +assert mydict.popitem() == (42,23) + + From hpk at codespeak.net Thu Mar 22 09:08:04 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Thu, 22 Mar 2007 09:08:04 +0100 (CET) Subject: [pypy-svn] r41011 - pypy/dist/demo Message-ID: <20070322080804.D4D6510036@code0.codespeak.net> Author: hpk Date: Thu Mar 22 09:08:02 2007 New Revision: 41011 Modified: pypy/dist/demo/tp-persistence.py Log: make nested lists/dicts get persisted all to the same file, us tputil. Modified: pypy/dist/demo/tp-persistence.py ============================================================================== --- pypy/dist/demo/tp-persistence.py (original) +++ pypy/dist/demo/tp-persistence.py Thu Mar 22 09:08:02 2007 @@ -4,47 +4,59 @@ mechanism on top of PyPy's transparent proxies. """ -from pypymagic import tproxy, get_tproxy_controller -from tputil import make_proxy +from tputil import make_proxy -list_changeops = set('__iadd__ __imul__ __delitem__ __setitem__ ' +list_changeops = set('__iadd__ __imul__ __delitem__ __setitem__ __setattr__' '__delslice__ __setslice__ ' 'append extend insert pop remove reverse sort'.split()) -def make_plist(instance, storage): - def perform(invocation): - res = invocation.delegate() - if invocation.opname in list_changeops: - storage.dump(instance) +dict_changeops = set('__delitem__ __setitem__ __setattr__' + 'clear pop popitem setdefault update'.split()) + +def ischangeop(operation): + """ return True if this operation is a changing operation + on known builtins (dicts, lists). + """ + if isinstance(operation.obj, list): + changeops = list_changeops + elif isinstance(operation.obj, dict): + changeops = dict_changeops + else: + return False + return operation.opname in changeops + +def make_persistent_proxy(instance, storage): + def perform(operation): + res = operation.delegate() + if ischangeop(operation): + print "persisting after:", operation + storage.dump(instance) + if res is not operation.proxyobj and isinstance(res, (dict, list)): + res = make_proxy(perform, obj=res) return res - return make_proxy(perform, type=list, obj=instance) + return make_proxy(perform, obj=instance) -def get_plist(storage): +def load(storage): obj = storage.load() - return make_plist(obj, storage) + return make_persistent_proxy(obj, storage) -def work_with_list(mylist): - assert isinstance(mylist, list) - assert mylist.__class__ is list - mylist.append(4) - mylist += [5,6,7] - if __name__ == '__main__': import py - storage = py.path.local("/tmp/mystorage") - - plist = make_plist([1,2,3], storage) - # here we may call into application code which can - # not detect easily that it is dealing with a - # transparently persistent list - work_with_list(plist) - del plist - - restoredlist = get_plist(storage) - print "restored list", restoredlist - assert restoredlist == [1,2,3,4,5,6,7] - restoredlist *= 2 - del restoredlist - restoredlist = get_plist(storage) - print "restored list 2", restoredlist - assert restoredlist == [1,2,3,4,5,6,7] * 2 + storage = py.path.local("/tmp/dictpickle") + pdict = make_persistent_proxy({}, storage) + + # the below is not aware of using the proxy + assert type(pdict) is dict + pdict['hello'] = 'world' + pdict['somelist'] = [] + del pdict + + newdict = load(storage) + assert newdict == {'hello': 'world', 'somelist': []} + l = newdict['somelist'] + l.append(1) # this triggers persisting the whole dict + l.extend([2,3]) # this triggers persisting the whole dict + del newdict, l + + newdict = load(storage) + print newdict['somelist'] # will show [1,2,3] From hpk at codespeak.net Thu Mar 22 09:21:40 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Thu, 22 Mar 2007 09:21:40 +0100 (CET) Subject: [pypy-svn] r41012 - pypy/dist/pypy/lib Message-ID: <20070322082140.207C510036@code0.codespeak.net> Author: hpk Date: Thu Mar 22 09:21:39 2007 New Revision: 41012 Modified: pypy/dist/pypy/lib/tputil.py Log: niceifying repr of ProxyOperations Modified: pypy/dist/pypy/lib/tputil.py ============================================================================== --- pypy/dist/pypy/lib/tputil.py (original) +++ pypy/dist/pypy/lib/tputil.py Thu Mar 22 09:21:39 2007 @@ -5,6 +5,7 @@ """ from __pypy__ import tproxy from types import MethodType +import inspect _dummy = object() origtype = type @@ -60,6 +61,10 @@ return res def __repr__(self): - return "" %( - type(self.proxyobj).__name__, self.opname, - self.args, self.kwargs, id(self.proxyobj)) + args = ", ".join([repr(x) for x in self.args]) + args = "<0x%x>, " % id(self.proxyobj) + args + if self.kwargs: + args += ", ".join(["%s=%r" % item + for item in self.kwargs.items()]) + return "" %( + type(self.proxyobj).__name__, self.opname, args) From hpk at codespeak.net Thu Mar 22 09:25:28 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Thu, 22 Mar 2007 09:25:28 +0100 (CET) Subject: [pypy-svn] r41013 - pypy/dist/demo Message-ID: <20070322082528.95D811005A@code0.codespeak.net> Author: hpk Date: Thu Mar 22 09:25:27 2007 New Revision: 41013 Modified: pypy/dist/demo/tp-print-builtin-operation.py Log: remove unused import Modified: pypy/dist/demo/tp-print-builtin-operation.py ============================================================================== --- pypy/dist/demo/tp-print-builtin-operation.py (original) +++ pypy/dist/demo/tp-print-builtin-operation.py Thu Mar 22 09:25:27 2007 @@ -6,7 +6,6 @@ """ from tputil import make_proxy -from __pypy__ import become def make_show_proxy(instance): def controller(operation): From cfbolz at codespeak.net Thu Mar 22 11:35:20 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 22 Mar 2007 11:35:20 +0100 (CET) Subject: [pypy-svn] r41015 - pypy/dist/pypy/config Message-ID: <20070322103520.E061C10069@code0.codespeak.net> Author: cfbolz Date: Thu Mar 22 11:35:19 2007 New Revision: 41015 Modified: pypy/dist/pypy/config/pypyoption.py Log: use the more regular option name again Modified: pypy/dist/pypy/config/pypyoption.py ============================================================================== --- pypy/dist/pypy/config/pypyoption.py (original) +++ pypy/dist/pypy/config/pypyoption.py Thu Mar 22 11:35:19 2007 @@ -103,7 +103,7 @@ OptionDescription("std", "Standard Object Space Options", [ BoolOption("withtproxy", "support transparent proxies", - default=False, cmdline='--with-transparent-proxy'), + default=False), BoolOption("withsmallint", "use tagged integers", default=False, From ac at codespeak.net Thu Mar 22 11:37:57 2007 From: ac at codespeak.net (ac at codespeak.net) Date: Thu, 22 Mar 2007 11:37:57 +0100 (CET) Subject: [pypy-svn] r41016 - pypy/dist/pypy/doc Message-ID: <20070322103757.7A02610070@code0.codespeak.net> Author: ac Date: Thu Mar 22 11:37:55 2007 New Revision: 41016 Modified: pypy/dist/pypy/doc/objspace-proxies.txt Log: Fix typo. Modified: pypy/dist/pypy/doc/objspace-proxies.txt ============================================================================== --- pypy/dist/pypy/doc/objspace-proxies.txt (original) +++ pypy/dist/pypy/doc/objspace-proxies.txt Thu Mar 22 11:37:55 2007 @@ -552,7 +552,7 @@ 'controller' callable. The proxy will appear as a completely regular instance of the given type but all operations on it are send to the - specified controller - which receices on + specified controller - which receives a ProxyOperation instance on each such operation. A non-specified type will default to type(obj) if `obj` was specified. From guido at codespeak.net Thu Mar 22 11:54:17 2007 From: guido at codespeak.net (guido at codespeak.net) Date: Thu, 22 Mar 2007 11:54:17 +0100 (CET) Subject: [pypy-svn] r41018 - pypy/dist/pypy/tool/build/test Message-ID: <20070322105417.B598B10074@code0.codespeak.net> Author: guido Date: Thu Mar 22 11:54:16 2007 New Revision: 41018 Modified: pypy/dist/pypy/tool/build/test/test_compile.py Log: Fixed wrong method name. Modified: pypy/dist/pypy/tool/build/test/test_compile.py ============================================================================== --- pypy/dist/pypy/tool/build/test/test_compile.py (original) +++ pypy/dist/pypy/tool/build/test/test_compile.py Thu Mar 22 11:54:16 2007 @@ -205,7 +205,7 @@ build.metaserver_instance = old_metaserver_instance """ - def setup(self, method): + def setup_method(self, method): self.gw = gw = py.execnet.PopenGateway() conference = execnetconference.conference(gw, config.testport, True) self.channel = conference.remote_exec(self.initcode % (config.path,)) From mwh at codespeak.net Thu Mar 22 12:46:52 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Thu, 22 Mar 2007 12:46:52 +0100 (CET) Subject: [pypy-svn] r41023 - pypy/dist/pypy/rpython/lltypesystem Message-ID: <20070322114652.808F110070@code0.codespeak.net> Author: mwh Date: Thu Mar 22 12:46:51 2007 New Revision: 41023 Modified: pypy/dist/pypy/rpython/lltypesystem/opimpl.py Log: use the explicit floordiv operator in the floordiv opimpl Modified: pypy/dist/pypy/rpython/lltypesystem/opimpl.py ============================================================================== --- pypy/dist/pypy/rpython/lltypesystem/opimpl.py (original) +++ pypy/dist/pypy/rpython/lltypesystem/opimpl.py Thu Mar 22 12:46:51 2007 @@ -155,7 +155,7 @@ def op_int_floordiv(x, y): assert isinstance(x, int) assert isinstance(y, int) - r = x/y + r = x//y if x^y < 0 and x%y != 0: r += 1 return r @@ -171,7 +171,7 @@ def op_llong_floordiv(x, y): assert isinstance(x, r_longlong) assert isinstance(y, r_longlong) - r = x/y + r = x//y if x^y < 0 and x%y != 0: r += 1 return r From mwh at codespeak.net Thu Mar 22 12:51:40 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Thu, 22 Mar 2007 12:51:40 +0100 (CET) Subject: [pypy-svn] r41025 - in pypy/dist/pypy/rpython: . test Message-ID: <20070322115140.EA32C10070@code0.codespeak.net> Author: mwh Date: Thu Mar 22 12:51:38 2007 New Revision: 41025 Modified: pypy/dist/pypy/rpython/llinterp.py pypy/dist/pypy/rpython/rint.py pypy/dist/pypy/rpython/test/test_rint.py Log: issue 300 testing the root problem was that the '_zer' variants of the division and modulo operations weren't getting their results adjusted, so be cleaner and more comprehensive there. the fix was held up for a while finding out that the llinterp's implementation of op_int_floordiv_ovf and so on didn't get updated when they should have (in rev 40556), but that's fixed now. add (hopefully) comprehensive tests. Modified: pypy/dist/pypy/rpython/llinterp.py ============================================================================== --- pypy/dist/pypy/rpython/llinterp.py (original) +++ pypy/dist/pypy/rpython/llinterp.py Thu Mar 22 12:51:38 2007 @@ -841,12 +841,26 @@ checkfn = 'intmask' else: checkfn = '' + if operator == '//': + code = '''r = %(checkfn)s(x // y) + if x^y < 0 and x%%y != 0: + r += 1 + return r + '''%locals() + elif operator == '%': + code = '''r = %(checkfn)s(x %% y) + if x^y < 0 and x%%y != 0: + r -= y + return r + '''%locals() + else: + code = 'return %(checkfn)s(x %(operator)s y)'%locals() exec py.code.Source(""" def %(fn)s(self, x, y): assert isinstance(x, %(xtype)s) assert isinstance(y, %(ytype)s) try: - return %(checkfn)s(x %(operator)s y) + %(code)s except (OverflowError, ValueError, ZeroDivisionError): self.make_llexception() """ % locals()).compile() in globals(), d Modified: pypy/dist/pypy/rpython/rint.py ============================================================================== --- pypy/dist/pypy/rpython/rint.py (original) +++ pypy/dist/pypy/rpython/rint.py Thu Mar 22 12:51:38 2007 @@ -208,7 +208,9 @@ assert isinstance(repr.lowleveltype, Number) c_zero = inputconst(repr.lowleveltype, repr.lowleveltype._default) - if func in ('floordiv', 'floordiv_ovf'): + op = func.split('_', 1)[0] + + if op == 'floordiv': # return (x/y) - (((x^y)<0)&((x%y)!=0)); v_xor = hop.genop(prefix + 'xor', vlist, resulttype=repr) @@ -224,7 +226,7 @@ resulttype=repr) v_res = hop.genop(prefix + 'sub', [v_res, v_corr], resulttype=repr) - elif func in ('mod', 'mod_ovf'): + elif op == 'mod': # return r + y*(((x^y)<0)&(r!=0)); v_xor = hop.genop(prefix + 'xor', vlist, resulttype=repr) 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 Thu Mar 22 12:51:38 2007 @@ -245,6 +245,68 @@ res = self.interpret(m, [x, y]) assert res == m(x, y) + def test_protected_div_mod(self): + def div_unpro(x, y): + return x//y + def div_ovf(x, y): + try: + return ovfcheck(x//y) + except OverflowError: + return 42 + def div_zer(x, y): + try: + return x//y + except ZeroDivisionError: + return 84 + def div_ovf_zer(x, y): + try: + return ovfcheck(x//y) + except OverflowError: + return 42 + except ZeroDivisionError: + return 84 + + def mod_unpro(x, y): + return x%y + def mod_ovf(x, y): + try: + return ovfcheck(x%y) + except OverflowError: + return 42 + def mod_zer(x, y): + try: + return x%y + except ZeroDivisionError: + return 84 + def mod_ovf_zer(x, y): + try: + return ovfcheck(x%y) + except OverflowError: + return 42 + except ZeroDivisionError: + return 84 + + for inttype in (int, r_longlong): + + args = [( 5, 2), (-5, 2), ( 5,-2), (-5,-2), + ( 6, 2), (-6, 2), ( 6,-2), (-6,-2), + (-sys.maxint, -1), (4, 0)] + + funcs = [div_unpro, div_ovf, div_zer, div_ovf_zer, + mod_unpro, mod_ovf, mod_zer, mod_ovf_zer] + + for func in funcs: + print func + if 'ovf' in func.func_name and inttype is r_longlong: + continue # don't have many llong_*_ovf operations... + for x, y in args: + x, y = inttype(x), inttype(y) + try: + res1 = ovfcheck(func(x, y)) + except (OverflowError, ZeroDivisionError): + continue + res2 = self.interpret(func, [x, y]) + assert res1 == res2 class TestLLtype(BaseTestRint, LLRtypeMixin): pass From ac at codespeak.net Thu Mar 22 12:54:20 2007 From: ac at codespeak.net (ac at codespeak.net) Date: Thu, 22 Mar 2007 12:54:20 +0100 (CET) Subject: [pypy-svn] r41026 - pypy/dist/demo Message-ID: <20070322115420.86B0610072@code0.codespeak.net> Author: ac Date: Thu Mar 22 12:54:19 2007 New Revision: 41026 Modified: pypy/dist/demo/tp-persistence.py pypy/dist/demo/tp-print-builtin-operation.py Log: Minor editing of demos. Modified: pypy/dist/demo/tp-persistence.py ============================================================================== --- pypy/dist/demo/tp-persistence.py (original) +++ pypy/dist/demo/tp-persistence.py Thu Mar 22 12:54:19 2007 @@ -45,7 +45,7 @@ storage = py.path.local("/tmp/dictpickle") pdict = make_persistent_proxy({}, storage) - # the below is not aware of using the proxy + # the code below is not aware of pdict being a proxy assert type(pdict) is dict pdict['hello'] = 'world' pdict['somelist'] = [] Modified: pypy/dist/demo/tp-print-builtin-operation.py ============================================================================== --- pypy/dist/demo/tp-print-builtin-operation.py (original) +++ pypy/dist/demo/tp-print-builtin-operation.py Thu Mar 22 12:54:19 2007 @@ -15,12 +15,13 @@ tproxy = make_proxy(controller, obj=instance) return tproxy -mydict = make_show_proxy({}) +if __name__ == '__main__': + mydict = make_show_proxy({}) -assert type(mydict) is dict # this looks exactly like a dict -mydict['hello'] = 'world' # will print __ -mydict[42] = 23 -assert mydict.pop('hello') == 'world' -assert mydict.popitem() == (42,23) + assert type(mydict) is dict # this looks exactly like a dict + mydict['hello'] = 'world' # will print __setitem__ + mydict[42] = 23 # will print __setitem__ + assert mydict.pop('hello') == 'world' # will print pop + assert mydict.popitem() == (42,23) # will print popitem From guido at codespeak.net Thu Mar 22 13:07:20 2007 From: guido at codespeak.net (guido at codespeak.net) Date: Thu, 22 Mar 2007 13:07:20 +0100 (CET) Subject: [pypy-svn] r41030 - in pypy/dist/pypy: bin tool/build tool/build/test Message-ID: <20070322120720.02D7510069@code0.codespeak.net> Author: guido Date: Thu Mar 22 13:07:19 2007 New Revision: 41030 Added: pypy/dist/pypy/tool/build/compileoption.py pypy/dist/pypy/tool/build/test/test_compileoption.py Modified: pypy/dist/pypy/bin/buildserver.py pypy/dist/pypy/tool/build/config.py Log: Combining compile config and translate config into and using that on the build server both for compilation and translation options. This seems to work, but for some reasons compilations fail with strange annotation errors when ran. Still, it works a bit more than before. :| (I hope someone who knows more about PyPy can figure out what the problem is...) Modified: pypy/dist/pypy/bin/buildserver.py ============================================================================== --- pypy/dist/pypy/bin/buildserver.py (original) +++ pypy/dist/pypy/bin/buildserver.py Thu Mar 22 13:07:19 2007 @@ -34,9 +34,19 @@ from pypy.config import pypyoption from pypy.tool.udir import udir - config = pypyoption.get_pypy_config() + from pypy.config.pypyoption import get_pypy_config + from pypy.translator.goal.translate import translate_optiondescr + from pypy.tool.build.compileoption import combine_config + from pypy.config.config import Config + pypy_config = get_pypy_config() + translate_config = Config(translate_optiondescr) + config = combine_config(pypy_config, translate_config, 'pypy', + 'pypy options') + open('/tmp/compileinfo', 'w').write(repr(compileinfo)) config.override(compileinfo) + targetpypystandalone.PyPyTarget.translateconfig = config + driver = TranslationDriver.from_targetspec( targetpypystandalone.__dict__, config=config, default_goal='compile') Added: pypy/dist/pypy/tool/build/compileoption.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/tool/build/compileoption.py Thu Mar 22 13:07:19 2007 @@ -0,0 +1,19 @@ +from pypy.config.config import OptionDescription, Config + +def combine_config(c1, c2, name, desc='', overrides=None, translating=False): + if overrides is None: + overrides = {} + children = c1._cfgimpl_descr._children + c2._cfgimpl_descr._children + children = [c for c in children if c._name != 'help'] + odescr = OptionDescription(name, desc, children) + config = Config(odescr, **overrides) + if translating: + config.translating = True + for c in c1, c2: + for child in c._cfgimpl_descr._children: + if child._name == 'help': + continue + value = getattr(c, child._name) + config._cfgimpl_values[child._name] = value + return config + Modified: pypy/dist/pypy/tool/build/config.py ============================================================================== --- pypy/dist/pypy/tool/build/config.py (original) +++ pypy/dist/pypy/tool/build/config.py Thu Mar 22 13:07:19 2007 @@ -25,9 +25,15 @@ # compile option config, used by client to parse info, by startcompile for # cmdline args, defaults are taken from the optiondescription from pypy.config.pypyoption import get_pypy_config -compile_config = get_pypy_config() -compile_config.override({'translation.backend': 'c', - 'translation.gc': 'boehm'}) +from pypy.translator.goal.translate import translate_optiondescr +from pypy.tool.build.compileoption import combine_config +pypy_config = get_pypy_config() +pypy_config.override({'translation.backend': 'c', + 'translation.gc': 'boehm'}) +translate_config = Config(translate_optiondescr) +translate_config.override({'graphserve': 0}) +compile_config = combine_config(pypy_config, translate_config, 'pypy', + 'pypy options') # svn path and revision, etc. from pypy.tool.build.tooloption import tool_optiondescription Added: pypy/dist/pypy/tool/build/test/test_compileoption.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/tool/build/test/test_compileoption.py Thu Mar 22 13:07:19 2007 @@ -0,0 +1,16 @@ +from pypy.tool.build.compileoption import combine_config +from pypy.config.config import OptionDescription, BoolOption, IntOption, \ + ArbitraryOption, FloatOption, ChoiceOption, \ + StrOption, to_optparse, Config + +def test_combine_config(): + c1 = Config(OptionDescription('c1', 'c1', + [BoolOption('foo', 'foo option', + default=False)])) + c2 = Config(OptionDescription('c2', 'c2', + [BoolOption('bar', 'bar option', + default=False)])) + combined = combine_config(c1, c2, 'combined', 'combined config') + assert isinstance(combined, Config) + assert combined.foo == False + assert combined.bar == False From guido at codespeak.net Thu Mar 22 13:16:41 2007 From: guido at codespeak.net (guido at codespeak.net) Date: Thu, 22 Mar 2007 13:16:41 +0100 (CET) Subject: [pypy-svn] r41033 - pypy/dist/pypy/tool/build/test Message-ID: <20070322121641.64B7310069@code0.codespeak.net> Author: guido Date: Thu Mar 22 13:16:39 2007 New Revision: 41033 Modified: pypy/dist/pypy/tool/build/test/test_compileoption.py Log: Added test that uses a combined config in an actual translation. Modified: pypy/dist/pypy/tool/build/test/test_compileoption.py ============================================================================== --- pypy/dist/pypy/tool/build/test/test_compileoption.py (original) +++ pypy/dist/pypy/tool/build/test/test_compileoption.py Thu Mar 22 13:16:39 2007 @@ -1,3 +1,4 @@ +import py from pypy.tool.build.compileoption import combine_config from pypy.config.config import OptionDescription, BoolOption, IntOption, \ ArbitraryOption, FloatOption, ChoiceOption, \ @@ -14,3 +15,38 @@ assert isinstance(combined, Config) assert combined.foo == False assert combined.bar == False + +def test_annotator_folding(): + from pypy.translator.interactive import Translation + + gcoption = ChoiceOption('name', 'GC name', ['ref', 'framework'], 'ref') + gcgroup = OptionDescription('gc', '', [gcoption]) + descr1 = OptionDescription('pypy', '', [gcgroup]) + c1 = Config(descr1) + + foooption = IntOption('foo', 'foo', default=0) + descr2 = OptionDescription('foo', '', [foooption]) + c2 = Config(descr2) + + config = combine_config(c1, c2, 'pypy') + + def f(x): + if config.gc.name == 'ref': + return x + 1 + else: + return 'foo' + + t = Translation(f) + t.rtype([int]) + + block = t.context.graphs[0].startblock + assert len(block.exits[0].target.operations) == 0 + assert len(block.operations) == 1 + assert len(block.exits) == 1 + assert block.operations[0].opname == 'int_add' + + assert config._freeze_() + # does not raise, since it does not change the attribute + config.gc.name = "ref" + py.test.raises(TypeError, 'config.gc.name = "framework"') + From cfbolz at codespeak.net Thu Mar 22 13:25:10 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 22 Mar 2007 13:25:10 +0100 (CET) Subject: [pypy-svn] r41034 - pypy/dist/pypy/bin Message-ID: <20070322122510.3348110072@code0.codespeak.net> Author: cfbolz Date: Thu Mar 22 13:24:54 2007 New Revision: 41034 Modified: pypy/dist/pypy/bin/buildserver.py Log: hrmpf. care is needed here, not whacking Modified: pypy/dist/pypy/bin/buildserver.py ============================================================================== --- pypy/dist/pypy/bin/buildserver.py (original) +++ pypy/dist/pypy/bin/buildserver.py Thu Mar 22 13:24:54 2007 @@ -48,7 +48,8 @@ targetpypystandalone.PyPyTarget.translateconfig = config driver = TranslationDriver.from_targetspec( - targetpypystandalone.__dict__, config=config, + targetpypystandalone.__dict__, + config=pypy_config, default_goal='compile') driver.proceed(['compile']) except Exception, e: From ac at codespeak.net Thu Mar 22 13:28:28 2007 From: ac at codespeak.net (ac at codespeak.net) Date: Thu, 22 Mar 2007 13:28:28 +0100 (CET) Subject: [pypy-svn] r41035 - pypy/dist/pypy/annotation Message-ID: <20070322122828.6CE8810074@code0.codespeak.net> Author: ac Date: Thu Mar 22 13:28:23 2007 New Revision: 41035 Modified: pypy/dist/pypy/annotation/description.py Log: Oops, typo! Modified: pypy/dist/pypy/annotation/description.py ============================================================================== --- pypy/dist/pypy/annotation/description.py (original) +++ pypy/dist/pypy/annotation/description.py Thu Mar 22 13:28:23 2007 @@ -755,7 +755,7 @@ desc.name, commonflags) del descs[desc] - descs[newdesc] = True + descs[newdesc] = None # --- case 1 --- groups = {} From hpk at codespeak.net Thu Mar 22 13:49:34 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Thu, 22 Mar 2007 13:49:34 +0100 (CET) Subject: [pypy-svn] r41036 - in pypy/dist/pypy/doc: . config Message-ID: <20070322124934.349191006E@code0.codespeak.net> Author: hpk Date: Thu Mar 22 13:49:31 2007 New Revision: 41036 Modified: pypy/dist/pypy/doc/config/objspace.usemodules.__pypy__.txt pypy/dist/pypy/doc/objspace-proxies.txt Log: fix option name and add references, improve tp docs a bit. Modified: pypy/dist/pypy/doc/config/objspace.usemodules.__pypy__.txt ============================================================================== --- pypy/dist/pypy/doc/config/objspace.usemodules.__pypy__.txt (original) +++ pypy/dist/pypy/doc/config/objspace.usemodules.__pypy__.txt Thu Mar 22 13:49:31 2007 @@ -6,4 +6,4 @@ See the `__pypy__ module documentation`_ for more details. .. _`object space proxy`: ../objspace-proxies.html -.. _`__pypy__ module documentation`: __pypy__-module.html +.. _`__pypy__ module documentation`: ../__pypy__-module.html Modified: pypy/dist/pypy/doc/objspace-proxies.txt ============================================================================== --- pypy/dist/pypy/doc/objspace-proxies.txt (original) +++ pypy/dist/pypy/doc/objspace-proxies.txt Thu Mar 22 13:49:31 2007 @@ -466,7 +466,7 @@ The following example proxies a list and will return ``42`` on any add operation to the list:: - $ py.py --with-transparent-proxy + $ py.py --objspace-std-withtproxy >>>> from __pypy__ import tproxy >>>> def f(operation, *args, **kwargs): >>>> if operation == '__add__': @@ -496,37 +496,29 @@ history.append(operation) return operation.delegate() - >>>> l = make_proxy(recorder, obj=[]) + >>>> l = make_proxy(recorder, obj=[]) >>>> type(l) list >>>> l.append(3) >>>> len(l) 1 >>>> len(history) - 4 + 2 -So what happened (XXX): +``make_proxy(recorder, obj=[])`` creates a transparent list +proxy where we can delegate operations to in the ``recorder`` function. +Calling ``type(l)`` does not lead to any operation at all. -* We've create transparent proxy of type list with controller c.perform - -* When performing lst.append, it calls lst.__getattribute__ which returns - bound method append of l (so append did not show up) - -* we call len - -* we call type, which does not show up at all (indeed the type is the only - aspect of the instance that the controller cannot change). - -Note that ``append`` shows up as ``__getattribute__`` and that the ``type(lst)`` +XXX 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). .. _`transparent proxy builtins`: -Transparent Proxy PyPy Builtins --------------------------------------- +Transparent Proxy PyPy Builtins and support +----------------------------------------------------------- -If you are using the `--with-transparent-proxies` option +If you are using the `--objspace-std-withtproxy`_ option the `__pypy__`_ module provides the following builtins: * ``tproxy(type, controller)``: returns a proxy object @@ -538,7 +530,8 @@ controller for a given object. For non-proxied objects ``None`` is returned. -.. ___pypy__: +.. _`__pypy__`: __pypy__-module.html +.. _`--objspace-std-withtproxy`: config/objspace.std.withtproxy.html .. _tputil: @@ -560,9 +553,13 @@ ProxyOperation instances have the following attributes: `proxyobj`: the transparent proxy object of this operation. + `opname`: the operation name of this operation + `args`: positional arguments for this operation + `kwargs`: keyword arguments for this operation + `obj`: (if provided to `make_proxy`: an concrete object) If you have specified a concrete object instance `obj` @@ -601,7 +598,7 @@ 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 +`--objspace-std-withtproxy`_ 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 From guido at codespeak.net Thu Mar 22 14:11:57 2007 From: guido at codespeak.net (guido at codespeak.net) Date: Thu, 22 Mar 2007 14:11:57 +0100 (CET) Subject: [pypy-svn] r41037 - pypy/dist/pypy/doc/discussion Message-ID: <20070322131157.677AE1006F@code0.codespeak.net> Author: guido Date: Thu Mar 22 14:11:55 2007 New Revision: 41037 Modified: pypy/dist/pypy/doc/discussion/build-tool-description.txt Log: Updated the text a bit and added some info about the web server. Modified: pypy/dist/pypy/doc/discussion/build-tool-description.txt ============================================================================== --- pypy/dist/pypy/doc/discussion/build-tool-description.txt (original) +++ pypy/dist/pypy/doc/discussion/build-tool-description.txt Thu Mar 22 14:11:55 2007 @@ -2,10 +2,6 @@ PyPyBuilder ============ -NOTE: this package is under construction, it does not contain all the -functionality described below. Also described functionality may differ from -the actual (test) implementation. - What is this? ============= @@ -18,28 +14,49 @@ your machine to create it. If enough people participate, with diverse enough machines, a 'build farm' is created. +Quick usage instructions +======================== + +For the impatient, that just want to get started, some quick instructions. To +start a compilation, run (from the pypy root directory):: + + $ ./bin/startcompile.py [options] + +where the options can be found by using --help, and the email address will be +used to send mail to once the compilation is finished. + +To start a build server, to participate in the build farm, do:: + + $ ./bin/buildserver.py + +That's it for the compilation script and build server, if you have your own +project and want to set up your own meta server, you'll have to be a bit more +patient and read the details below... + Components ========== -The application consists of 3 main components: a server component, a client -component that handles compilations (let's call this a 'participating client') +The application consists of 3 main components: a meta server component, a +client component that handles compilations (let's call this a 'build server') and a small client component to start compile jobs (which we'll call 'requesting clients' for now). -The server waits for participating clients to register, and for compile job +The server waits for build server to register, and for compile job requests. When participating clients register, they pass the server information -about what compilations the system can handle (system info). +about what compilations the system can handle (system info), and a set of +options to use for compilation (compile info). When now a requesting client requests a compilation job, the server checks -whether a suitable binary is already available, and if so returns that. If -there isn't one, the server walks through a list of connected participating -clients to see if one of them can handle the job, and if so dispatches the -compilation. If there's no participating client to handle the job, it gets -queued until there is. If a client crashes during compilation, the build is -restarted, or error information is sent to the logs and requesting client, -depending on the type of error. As long as no compilation error occurs (read: -on disconnects, system errors, etc.) compilation will be retried until a -build is available. +whether a suitable binary is already available based on the system and compile +info, and if so returns that. If there isn't one, the server walks through a +list of connected participating clients to see if one of them can handle the +job, and if so dispatches the compilation. If there's no participating client +to handle the job, it gets queued until there is. + +If a client crashes during compilation, the build is restarted, or error +information is sent to the logs and requesting client, depending on the type of +error. As long as no compilation error occurs (read: on disconnects, system +errors, etc.) compilation will be retried until a build is available. Once a build is available, the server will send an email to all clients waiting for the build (it could be that more than one person asked for some build at @@ -49,11 +66,11 @@ ============= There are several aspects to configuration on this system. Of course, for the -server, client and startcompile components there is configuration for the host -and port to connect to, and there is some additional configuration for things -like which mailhost to use (only applies to the server), but also there is -configuration data passed around to determine what client is picked, and what -the client needs to compile exactly. +meta server, build server and startcompile components there is configuration +for the host and port to connect to, and there is some additional configuration +for things like which mailhost to use (only applies to the server), but also +there is configuration data passed around to determine what client is picked, +and what the client needs to compile exactly. Config file ----------- @@ -87,42 +104,48 @@ The third form of configuration is that of the to-be-built application itself, its compilation arguments. This configuration is only provided by the -requesting clients, participating clients can examine the information and -refuse a compilation based on this configuration (just like with the system -config, see 'client_checkers' in 'config.py'). Compilation configuration can be -controlled using command-line arguments (use 'bin/startcompile --help' for an +requesting clients, build servers can examine the information and refuse a +compilation based on this configuration (just like with the system config, see +'client_checkers' in 'config.py'). Compilation configuration can be controlled +using command-line arguments (use 'bin/startcompile.py --help' for an overview). Build tool options ------------------ -Yet another part of the configuration are the options that can be passed to -the 'request a build' script, the requesting client can specify what SVN path -(relative to a certain base path) and what Subversion revision is desired. -The revision can either be specified exactly, or as a range of versions. +Yet another part of the configuration are the options that are used by the +startcompile.py script itself: the user can specify what SVN path (relative to +a certain base path) and what Subversion revision is desired. The revision can +either be specified exactly, or as a range of versions. Installation ============ -Client ------- +Build Server +------------ + +Installing the system should not be required: just run './bin/buildserver' to +start. Note that it depends on the `py lib`_ (as does the rest of PyPy). -Installing the system should not be required: just run './bin/client' to start -the client. Note that it depends on the `py lib`_ (as does the rest of PyPy). +When starting a build server with PyPy's default configuration, it will connect +to a meta server we have running in codespeak.net. -Server ------- +Meta Server +----------- Also for the server there's no real setup required, and again there's a -dependency on the `py lib`_. Starting it is done by running './bin/server'. +dependency on the `py lib`_. Starting it is done by running +'./tool/build/bin/metaserver'. Running a compile job --------------------- -Again installation is not required, just run './bin/startcompile [options] +Again installation is not required, just run './bin/startcompile.py [options] ' (see --help for the options) to start. Again, you need to have the `py lib`_ installed. +Normally the codespeak.net meta server will be used when this script is issued. + .. _`py lib`: http://codespeak.net/py Using the build tool for other projects @@ -133,6 +156,9 @@ just change the configuration, and implement a build client script (probably highly resembling bin/client). +Note that there is a test project in 'tool/build/testproject' that can serve +as an example. + Prerequisities -------------- @@ -144,7 +170,8 @@ be built from Python; it's just a matter of integrating it into the tool properly... A project that can entirely be built from Python code (like PyPy) is easier to integrate than something that is built from the command - line, though (although implementing that won't be very hard either). + line, though (although implementing that won't be very hard either, see + the test project for instance). * it is located in Subversion @@ -171,6 +198,43 @@ Python a bit, it shouldn't be too hard to get things going (note that more documentation about this subject will follow in the future). +Web Front-End +============= + +To examine the status of the meta server, connected build servers and build +requests, there is a web server available. This can be started using +'./tool/build/bin/webserver' and uses port 8080 by default (override in +config.py). + +The web server presents a number of different pages: + + * / and /metaserverstatus - meta server status + + this displays a small list of information about the meta server, such + as the amount of connected build servers, the amount of builds available, + the amount of waiting clients, etc. + + * /buildservers - connected build servers + + this page contains a list of all connected build servers, system + information and what build they're currently working on (if any) + + * /builds - a list of builds + + here you'll find a list of all builds, both done and in-progress and + queued ones, with links to the details pages, the date they were + requested and their status + + * /build/ - build details + + the 'build' (virtual) directory contains pages of information for each + build - each of those pages displays status information, time requested, + time started and finished (if appropriate), links to the zip and logs, + and system and compile information + +There's a build tool status web server for the meta server on codespeak.net +available at http://codespeak.net/pypy/buildstatus/. + More info ========= From hpk at codespeak.net Thu Mar 22 14:14:08 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Thu, 22 Mar 2007 14:14:08 +0100 (CET) Subject: [pypy-svn] r41038 - pypy/dist/pypy/doc Message-ID: <20070322131408.8B1D91006F@code0.codespeak.net> Author: hpk Date: Thu Mar 22 14:14:06 2007 New Revision: 41038 Modified: pypy/dist/pypy/doc/conftest.py Log: i think the statistic directory is not meant for rest-generation, correct me if i am wrong (this fixes a few weird errors, there might be another fix) Modified: pypy/dist/pypy/doc/conftest.py ============================================================================== --- pypy/dist/pypy/doc/conftest.py (original) +++ pypy/dist/pypy/doc/conftest.py Thu Mar 22 14:14:06 2007 @@ -44,6 +44,11 @@ class Directory(Directory): ReSTChecker = PyPyReSTChecker + def run(self): + l = super(Directory, self).run() + if 'statistic' in l: + l.remove('statistic') + return l try: from docutils.parsers.rst import directives, states, roles From guido at codespeak.net Thu Mar 22 14:14:29 2007 From: guido at codespeak.net (guido at codespeak.net) Date: Thu, 22 Mar 2007 14:14:29 +0100 (CET) Subject: [pypy-svn] r41040 - in pypy/dist/pypy/doc: . discussion Message-ID: <20070322131429.200FE10072@code0.codespeak.net> Author: guido Date: Thu Mar 22 14:14:28 2007 New Revision: 41040 Added: pypy/dist/pypy/doc/buildtool.txt - copied unchanged from r41037, pypy/dist/pypy/doc/discussion/build-tool-description.txt Removed: pypy/dist/pypy/doc/discussion/build-tool-description.txt Log: Moved build tool doc out of discussion (and changed the name, likely this will be the only doc about the build tool). Leaving the web front-end doc in discussion as this does not yet exist (config front-end). From pedronis at codespeak.net Thu Mar 22 14:18:10 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Thu, 22 Mar 2007 14:18:10 +0100 (CET) Subject: [pypy-svn] r41042 - pypy/dist/pypy/jit/timeshifter Message-ID: <20070322131810.A8E561006F@code0.codespeak.net> Author: pedronis Date: Thu Mar 22 14:18:08 2007 New Revision: 41042 Modified: pypy/dist/pypy/jit/timeshifter/hrtyper.py Log: fix void args to metacalls Modified: pypy/dist/pypy/jit/timeshifter/hrtyper.py ============================================================================== --- pypy/dist/pypy/jit/timeshifter/hrtyper.py (original) +++ pypy/dist/pypy/jit/timeshifter/hrtyper.py Thu Mar 22 14:18:08 2007 @@ -682,8 +682,13 @@ def translate_op_ts_metacall(self, hop): nb_args = hop.nb_args - 1 - args_r = [self.getredrepr(originalconcretetype(hs)) - for hs in hop.args_s[1:]] + def normalize(hs): + T = originalconcretetype(hs) + if T is lltype.Void: + return lltype.Void + else: + return self.getredrepr(T) + args_r = [normalize(hs) for hs in hop.args_s[1:]] vlist = hop.inputargs(lltype.Void, *args_r) metadesccls = vlist[0].value metadesc = metadesccls(self) From fijal at codespeak.net Thu Mar 22 14:25:39 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 22 Mar 2007 14:25:39 +0100 (CET) Subject: [pypy-svn] r41044 - pypy/dist/pypy/translator/js/examples/console Message-ID: <20070322132539.6CE5910075@code0.codespeak.net> Author: fijal Date: Thu Mar 22 14:25:37 2007 New Revision: 41044 Modified: pypy/dist/pypy/translator/js/examples/console/console.py Log: Minor update to play1, mostly adding code snippets from docs. 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 Mar 22 14:25:37 2007 @@ -22,6 +22,16 @@ return operation.delegate() l = make_proxy(recorder, obj=[]) +""", + """from __pypy__ import thunk +def f(): + print 'computing...' + return 6*7 + +x = thunk(f) +""", + """from __pypy__ import taint +x = taint(6) """] FUNCTION_LIST = ["load_console", "console_onload", "execute_snippet"] @@ -44,9 +54,15 @@ ''' % (SNIPPETS[0],), 'pypy-c-thunk':'''The PyPy standard interpreter compiled to C using - the thunk object space''', + the thunk object space. Example (execute): +
    %s
    + And try x. +''' % (SNIPPETS[1],), 'pypy-c-taint':'''The PyPy standard interpreter compiled to C using - the taint object space''', + the taint object space. Example (execute): +
    %s
    + Now try hard getting to value of x :-) + ''' % (SNIPPETS[2],), 'pypy-cli':'''The PyPy standard interpreter compiled to CLI'''} class Ignore(Exception): From arigo at codespeak.net Thu Mar 22 14:26:41 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 22 Mar 2007 14:26:41 +0100 (CET) Subject: [pypy-svn] r41045 - in pypy/dist/pypy/jit: hintannotator hintannotator/test timeshifter timeshifter/test Message-ID: <20070322132641.C9B8E10075@code0.codespeak.net> Author: arigo Date: Thu Mar 22 14:26:40 2007 New Revision: 41045 Modified: pypy/dist/pypy/jit/hintannotator/annotator.py pypy/dist/pypy/jit/hintannotator/bookkeeper.py pypy/dist/pypy/jit/hintannotator/model.py pypy/dist/pypy/jit/hintannotator/test/test_annotator.py pypy/dist/pypy/jit/timeshifter/hrtyper.py pypy/dist/pypy/jit/timeshifter/test/test_timeshift.py Log: (arigo, arre, pedronis) Support for pure ts_metacalls, with fixing across them. If they are green, the original graph just gets called at compile-time. Modified: pypy/dist/pypy/jit/hintannotator/annotator.py ============================================================================== --- pypy/dist/pypy/jit/hintannotator/annotator.py (original) +++ pypy/dist/pypy/jit/hintannotator/annotator.py Thu Mar 22 14:26:40 2007 @@ -96,9 +96,11 @@ def consider_op_resume_point(self, hs_v, *args_hs): pass - def consider_op_ts_metacall(self, hs_metafunc, *args_hs): - RESTYPE = self.bookkeeper.current_op_concretetype() - return hintmodel.variableoftype(RESTYPE) + def consider_op_ts_metacall(self, hs_f1, hs_metadesccls, *args_hs): + bookkeeper = self.bookkeeper + fnobj = hs_f1.const._obj + return hintmodel.cannot_follow_call(bookkeeper, fnobj.graph, args_hs, + lltype.typeOf(fnobj).RESULT) def simplify(self): RPythonAnnotator.simplify(self, extra_passes=[]) Modified: pypy/dist/pypy/jit/hintannotator/bookkeeper.py ============================================================================== --- pypy/dist/pypy/jit/hintannotator/bookkeeper.py (original) +++ pypy/dist/pypy/jit/hintannotator/bookkeeper.py Thu Mar 22 14:26:40 2007 @@ -49,12 +49,9 @@ except KeyError: bk = self.bookkeeper look = bk.annotator.policy.look_inside_graph(self.origgraph) - if look: - if callable(look): - graph = self.build_metacall_graph(self.origgraph, look) - else: - # normal case - graph = copygraph(self.origgraph, varmap=TIMESHIFTMAP) + if look and not callable(look): + # normal case + graph = copygraph(self.origgraph, varmap=TIMESHIFTMAP) if not self._cache: bk.nonstuboriggraphcount += 1 if verbose: @@ -62,7 +59,7 @@ else: log.dot() else: - graph = self.build_callback_graph(self.origgraph) + graph = self.build_callback_graph(self.origgraph, look) if not self._cache: bk.stuboriggraphcount += 1 if verbose: @@ -83,29 +80,24 @@ self.bookkeeper.annotator.translator.graphs.append(graph) return graph - def build_callback_graph(self, graph): + def build_callback_graph(self, graph, metadesccls=False): args_v = [copyvar(None, v) for v in graph.getargs()] v_res = copyvar(None, graph.getreturnvar()) rtyper = self.bookkeeper.annotator.base_translator.rtyper # fish fnptr = rtyper.getcallable(graph) v_ptr = Constant(fnptr, lltype.typeOf(fnptr)) newstartblock = Block(args_v) + if metadesccls: + v_metadesccls = Constant(metadesccls, lltype.Void) + args_v = [v_metadesccls] + args_v + opname = 'ts_metacall' + suffix = 'ts_metacall' + else: + opname = 'direct_call' + suffix = 'ts_stub' newstartblock.operations.append( - SpaceOperation('direct_call', [v_ptr] + args_v, v_res)) - newgraph = FunctionGraph('%s_ts_stub' % (graph.name,), newstartblock) - newgraph.getreturnvar().concretetype = v_res.concretetype - newstartblock.closeblock(Link([v_res], newgraph.returnblock)) - return newgraph - - def build_metacall_graph(self, origgraph, metadesccls): - args_v = [copyvar(None, v) for v in origgraph.getargs()] - v_res = copyvar(None, origgraph.getreturnvar()) - v_metadesccls = Constant(metadesccls, lltype.Void) - newstartblock = Block(args_v) - newstartblock.operations.append( - SpaceOperation('ts_metacall', [v_metadesccls] + args_v, v_res)) - newgraph = FunctionGraph('%s_ts_metacall' % (origgraph.name,), - newstartblock) + SpaceOperation(opname, [v_ptr] + args_v, v_res)) + newgraph = FunctionGraph('%s_%s' % (graph.name, suffix), newstartblock) newgraph.getreturnvar().concretetype = v_res.concretetype newstartblock.closeblock(Link([v_res], newgraph.returnblock)) return newgraph Modified: pypy/dist/pypy/jit/hintannotator/model.py ============================================================================== --- pypy/dist/pypy/jit/hintannotator/model.py (original) +++ pypy/dist/pypy/jit/hintannotator/model.py Thu Mar 22 14:26:40 2007 @@ -83,7 +83,7 @@ def record_dependencies(self, greenorigindependencies, callreturndependencies): bk = self.bookkeeper - if self.spaceop.opname == 'direct_call': + if self.spaceop.opname in ('direct_call', 'ts_metacall'): args = self.spaceop.args[1:] elif self.spaceop.opname == 'indirect_call': args = self.spaceop.args[1:-1] Modified: pypy/dist/pypy/jit/hintannotator/test/test_annotator.py ============================================================================== --- pypy/dist/pypy/jit/hintannotator/test/test_annotator.py (original) +++ pypy/dist/pypy/jit/hintannotator/test/test_annotator.py Thu Mar 22 14:26:40 2007 @@ -881,3 +881,31 @@ return 5 hs = hannotate(g, [int], backendoptimize=True) assert hs.is_green() + + +def test_substitute_graph(): + class MetaG: + pass # the details are only used by the timeshifter + + def g(m): + return m * 17 + + def f(n, m): + x = g(n) + y = g(m) + hint(y, concrete=True) + return g(m) + + class MyPolicy(HintAnnotatorPolicy): + entrypoint_returns_red = False + def look_inside_graph(self, graph): + if graph.func is g: + return MetaG # replaces g with a meta-call to metafunc() + else: + return True + + hs, hannotator = hannotate(f, [int, int], policy=MyPolicy(), + annotator=True) + assert hs.is_green() + for graph in hannotator.translator.graphs: + assert 'int_mul' not in flowmodel.summary(graph) Modified: pypy/dist/pypy/jit/timeshifter/hrtyper.py ============================================================================== --- pypy/dist/pypy/jit/timeshifter/hrtyper.py (original) +++ pypy/dist/pypy/jit/timeshifter/hrtyper.py Thu Mar 22 14:26:40 2007 @@ -681,22 +681,25 @@ return v def translate_op_ts_metacall(self, hop): - nb_args = hop.nb_args - 1 + # note that if the ts_metacall operation is pure and green, then + # we don't even get there because the original graph in which + # it is will just be green_call'ed by the caller. + nb_args = hop.nb_args - 2 def normalize(hs): T = originalconcretetype(hs) if T is lltype.Void: return lltype.Void else: return self.getredrepr(T) - args_r = [normalize(hs) for hs in hop.args_s[1:]] - vlist = hop.inputargs(lltype.Void, *args_r) - metadesccls = vlist[0].value + args_r = [normalize(hs) for hs in hop.args_s[2:]] + vlist = hop.inputargs(lltype.Void, lltype.Void, *args_r) + metadesccls = vlist[1].value metadesc = metadesccls(self) metafunc = metadesc.metafunc v_jitstate = hop.llops.getjitstate() return hop.llops.genmixlevelhelpercall(metafunc, [self.s_JITState] + [self.s_RedBox] * nb_args, - [v_jitstate] + vlist[1:], + [v_jitstate] + vlist[2:], self.s_RedBox) def translate_op_getfield(self, hop): @@ -1527,6 +1530,7 @@ args_v = [v_self] + args_v function = function.im_func + assert len(args_s) == len(args_v) graph = self.hrtyper.annhelper.getgraph(function, args_s, s_result) self.record_extra_call(graph) # xxx Modified: pypy/dist/pypy/jit/timeshifter/test/test_timeshift.py ============================================================================== --- pypy/dist/pypy/jit/timeshifter/test/test_timeshift.py (original) +++ pypy/dist/pypy/jit/timeshifter/test/test_timeshift.py Thu Mar 22 14:26:40 2007 @@ -1667,10 +1667,13 @@ return IntRedBox(mbox.kind, gv_result) def g(m): - return m + 17 + return m * 10 - def f(n): - return g(n) + def f(n, m): + x = g(n) + y = g(m) + hint(y, concrete=True) + return x + g(y) class MyPolicy(HintAnnotatorPolicy): def look_inside_graph(self, graph): @@ -1679,6 +1682,6 @@ else: return True - res = self.timeshift(f, [3], policy=MyPolicy()) - assert res == -3 - self.check_insns({'int_neg': 1}) + res = self.timeshift(f, [3, 6], policy=MyPolicy()) + assert res == -3 + 600 + self.check_insns({'int_neg': 1, 'int_add': 1}) From fijal at codespeak.net Thu Mar 22 14:29:50 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 22 Mar 2007 14:29:50 +0100 (CET) Subject: [pypy-svn] r41048 - pypy/dist/pypy/translator/js/examples/console Message-ID: <20070322132950.9A33010079@code0.codespeak.net> Author: fijal Date: Thu Mar 22 14:29:48 2007 New Revision: 41048 Modified: pypy/dist/pypy/translator/js/examples/console/client.py Log: minor updatex 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 Thu Mar 22 14:29:48 2007 @@ -29,9 +29,10 @@ inp_elem = dom.document.getElementById("inp") #inp_elem.disabled = False if msg[0] == "refresh": - inp_elem.scrollIntoView() - inp_elem.focus() data = msg[1] + if data: + inp_elem.scrollIntoView() + inp_elem.focus() exported_methods.refresh_empty(glob.sess_id, refresh_console) add_text(data) elif msg[0] == 'disconnect': From guido at codespeak.net Thu Mar 22 14:38:11 2007 From: guido at codespeak.net (guido at codespeak.net) Date: Thu, 22 Mar 2007 14:38:11 +0100 (CET) Subject: [pypy-svn] r41051 - pypy/dist/pypy/tool/build Message-ID: <20070322133811.876121007A@code0.codespeak.net> Author: guido Date: Thu Mar 22 14:38:08 2007 New Revision: 41051 Modified: pypy/dist/pypy/tool/build/systemoption.py Log: Allowing 'darwin' as os... :) Modified: pypy/dist/pypy/tool/build/systemoption.py ============================================================================== --- pypy/dist/pypy/tool/build/systemoption.py (original) +++ pypy/dist/pypy/tool/build/systemoption.py Thu Mar 22 14:38:08 2007 @@ -7,7 +7,7 @@ IntOption('maxint', 'maximum int value', default=sys.maxint), ChoiceOption('byteorder', 'endianness, byte order (little/big)', ['little', 'big'], default=sys.byteorder), - ChoiceOption('os', 'operating system', ['win32', 'linux2'], + ChoiceOption('os', 'operating system', ['win32', 'linux2', 'darwin'], default=sys.platform), ]) From mwh at codespeak.net Thu Mar 22 14:43:40 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Thu, 22 Mar 2007 14:43:40 +0100 (CET) Subject: [pypy-svn] r41053 - pypy/dist/pypy/jit/codegen/ppc Message-ID: <20070322134340.2CE281007A@code0.codespeak.net> Author: mwh Date: Thu Mar 22 14:43:38 2007 New Revision: 41053 Modified: pypy/dist/pypy/jit/codegen/ppc/rgenop.py Log: stupid 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 Thu Mar 22 14:43:38 2007 @@ -666,7 +666,7 @@ def _close(self): _code_stop = self.asm.mc.tell() - code_size = self._code_start - _code_stop + code_size = _code_stop - self._code_start flush_icache(self._code_start, code_size) self.rgenop.close_mc(self.asm.mc) self.asm.mc = None From fijal at codespeak.net Thu Mar 22 14:47:25 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 22 Mar 2007 14:47:25 +0100 (CET) Subject: [pypy-svn] r41054 - in pypy/dist/pypy/translator/js/examples/console: . test Message-ID: <20070322134725.3D24C1007A@code0.codespeak.net> Author: fijal Date: Thu Mar 22 14:47:24 2007 New Revision: 41054 Modified: pypy/dist/pypy/translator/js/examples/console/session.py pypy/dist/pypy/translator/js/examples/console/test/test_session.py Log: A new feature and a test Modified: pypy/dist/pypy/translator/js/examples/console/session.py ============================================================================== --- pypy/dist/pypy/translator/js/examples/console/session.py (original) +++ pypy/dist/pypy/translator/js/examples/console/session.py Thu Mar 22 14:47:24 2007 @@ -3,6 +3,7 @@ build around subprocess to run python console in it """ +KILL_TIMEOUT = 300 TIMEOUT = 10 """ The idea behind is that we create xmlhttprequest immediataly @@ -15,9 +16,13 @@ from Queue import Queue from py.__.green.greensock2 import autogreenlet, Timer, Interrupted from py.__.green.pipe.fd import FDInput - +import time + +class Killed(Exception): + pass + class Interpreter(object): - def __init__(self, python, timeout=TIMEOUT): + def __init__(self, python, timeout=TIMEOUT, kill_timeout=KILL_TIMEOUT): pipe = subprocess.Popen([python, "-u", "-i"], stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.STDOUT, close_fds=True, bufsize=0) @@ -25,6 +30,8 @@ self.read_fd = FDInput(self.pipe.stdout.fileno(), close=False) self.pid = pipe.pid self.timeout = timeout + self.kill_timeout = kill_timeout + self.last_activity = time.time() def timeout_read(self, fd, timeout): timer = Timer(timeout) @@ -38,10 +45,14 @@ def write_only(self, to_write): if to_write is not None: + self.last_activity = time.time() self.pipe.stdin.write(to_write) def interact(self, to_write=None): self.write_only(to_write) + if time.time() - self.last_activity > self.kill_timeout: + self.close() + raise Killed() return self.timeout_read(self.read_fd, self.timeout) def close(self): Modified: pypy/dist/pypy/translator/js/examples/console/test/test_session.py ============================================================================== --- pypy/dist/pypy/translator/js/examples/console/test/test_session.py (original) +++ pypy/dist/pypy/translator/js/examples/console/test/test_session.py Thu Mar 22 14:47:24 2007 @@ -6,7 +6,7 @@ from py.__.green.greensock2 import allof from py.__.green.pipe.fd import FDInput -from pypy.translator.js.examples.console.session import Interpreter +from pypy.translator.js.examples.console.session import Interpreter, Killed def test_greensock_reader_timeouter(): i = Interpreter("python", timeout=3) @@ -43,3 +43,9 @@ print val val = i.interact() +def test_kill_timeout(): + i = Interpreter("python", kill_timeout=1, timeout=3) + while not i.interact().endswith(">>> "): + pass + i.interact() + py.test.raises(Killed, "i.interact()") From pedronis at codespeak.net Thu Mar 22 14:51:12 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Thu, 22 Mar 2007 14:51:12 +0100 (CET) Subject: [pypy-svn] r41056 - in pypy/dist/pypy: module/pypyjit objspace/std Message-ID: <20070322135112.49C5A1007A@code0.codespeak.net> Author: pedronis Date: Thu Mar 22 14:51:10 2007 New Revision: 41056 Modified: pypy/dist/pypy/module/pypyjit/newbool.py pypy/dist/pypy/module/pypyjit/portal.py pypy/dist/pypy/objspace/std/objspace.py Log: (pedronis, arigo and arre around) see is_true, use the logic in newbool.py for the timeshifting of space.newbool(flag). Modified: pypy/dist/pypy/module/pypyjit/newbool.py ============================================================================== --- pypy/dist/pypy/module/pypyjit/newbool.py (original) +++ pypy/dist/pypy/module/pypyjit/newbool.py Thu Mar 22 14:51:10 2007 @@ -50,7 +50,7 @@ vbool.ownbox = box return vbool - def metafunc(self, jitstate, valuebox): + def metafunc(self, jitstate, spacevoid, valuebox): vbool = self.vboolfactory() vbool.valuebox = valuebox return vbool.ownbox @@ -172,6 +172,7 @@ def exactmatch(self, vstruct, outgoingvarboxes, memo): # XXX code duplication with rcontainer... + assert isinstance(vstruct, rcontainer.VirtualContainer) contmemo = memo.containers if self in contmemo: ok = vstruct is contmemo[self] Modified: pypy/dist/pypy/module/pypyjit/portal.py ============================================================================== --- pypy/dist/pypy/module/pypyjit/portal.py (original) +++ pypy/dist/pypy/module/pypyjit/portal.py Thu Mar 22 14:51:10 2007 @@ -1,13 +1,14 @@ from pypy.module.pypyjit.interp_jit import PORTAL +from pypy.module.pypyjit.newbool import NewBoolDesc from pypy.translator.translator import graphof from pypy.annotation.specialize import getuniquenondirectgraph from pypy.jit.hintannotator.annotator import HintAnnotatorPolicy class PyPyHintAnnotatorPolicy(HintAnnotatorPolicy): + novirtualcontainer = True + oopspec = True def __init__(self, timeshift_graphs): - HintAnnotatorPolicy.__init__(self, novirtualcontainer = True, - oopspec = True) self.timeshift_graphs = timeshift_graphs def look_inside_graph(self, graph): @@ -112,8 +113,16 @@ for i in range(1, len(path)): seefunc(path[i-1], path[i]) - def dontsee(func): - result_graphs[_graph(func)] = False + def seegraph(func, look=True): + graph = _graph(func) + if look: + extra = "" + if look != True: + extra = " substituted with %s" % look + log('including graph %s%s' % (graph, extra)) + else: + log('excluding graph %s' % (graph,)) + result_graphs[graph] = look def seebinary(opname): name2 = name1 = opname[:3].lower() @@ -148,7 +157,8 @@ descr_impl = getattr(pypy.objspace.descroperation.DescrOperation, name) seepath(pypy.interpreter.pyframe.PyFrame.COMPARE_OP, descr_impl, - getattr(pypy.objspace.std.intobject, name +'__Int_Int')) + getattr(pypy.objspace.std.intobject, name +'__Int_Int'), + pypy.objspace.std.Space.newbool) seepath(descr_impl, pypy.objspace.std.typeobject.W_TypeObject.is_heaptype) @@ -173,9 +183,15 @@ pypy.objspace.std.Space.gettypeobject) seepath(pypy.objspace.descroperation.DescrOperation.add, pypy.objspace.std.Space.is_w) - dontsee(pypy.interpreter.pyframe.PyFrame.execute_frame) + seegraph(pypy.interpreter.pyframe.PyFrame.execute_frame, False) # -------------------- - + # special timeshifting logic for newbool + seegraph(pypy.objspace.std.Space.newbool, NewBoolDesc) + seepath(pypy.interpreter.pyframe.PyFrame.JUMP_IF_TRUE, + pypy.objspace.std.Space.is_true) + seepath(pypy.interpreter.pyframe.PyFrame.JUMP_IF_FALSE, + pypy.objspace.std.Space.is_true) + return result_graphs Modified: pypy/dist/pypy/objspace/std/objspace.py ============================================================================== --- pypy/dist/pypy/objspace/std/objspace.py (original) +++ pypy/dist/pypy/objspace/std/objspace.py Thu Mar 22 14:51:10 2007 @@ -549,6 +549,8 @@ return w_one is w_two def is_true(self, w_obj): + if isinstance(w_obj, W_BoolObject): + return w_obj.boolval if type(w_obj) is self.DictObjectCls: return w_obj.len() != 0 else: From cfbolz at codespeak.net Thu Mar 22 14:51:30 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 22 Mar 2007 14:51:30 +0100 (CET) Subject: [pypy-svn] r41058 - pypy/extradoc/eu-report Message-ID: <20070322135130.0ECC910082@code0.codespeak.net> Author: cfbolz Date: Thu Mar 22 14:51:24 2007 New Revision: 41058 Added: pypy/extradoc/eu-report/D10.1_Aspect_Oriented_Programming_in_PyPy-2007-03-21.pdf (contents, props changed) Log: add final version of D10.1 Added: pypy/extradoc/eu-report/D10.1_Aspect_Oriented_Programming_in_PyPy-2007-03-21.pdf ============================================================================== Binary file. No diff available. From fijal at codespeak.net Thu Mar 22 14:55:06 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 22 Mar 2007 14:55:06 +0100 (CET) Subject: [pypy-svn] r41061 - in pypy/dist/pypy/translator/js/examples/console: . data Message-ID: <20070322135506.B7B8E10063@code0.codespeak.net> Author: fijal Date: Thu Mar 22 14:55:05 2007 New Revision: 41061 Modified: pypy/dist/pypy/translator/js/examples/console/client.py pypy/dist/pypy/translator/js/examples/console/console.py pypy/dist/pypy/translator/js/examples/console/data/console.html pypy/dist/pypy/translator/js/examples/console/session.py Log: Add a logic for killing consoles. Needed on limited-memory machine. 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 Thu Mar 22 14:55:05 2007 @@ -19,6 +19,9 @@ data_elem.removeChild(data_elem.childNodes[0]) data_elem.appendChild(dom.document.createTextNode(data)) +def create_text(txt): + return dom.document.createTextNode(txt) + def set_text(txt): data_elem = dom.document.getElementById("data") while data_elem.childNodes: @@ -35,8 +38,13 @@ inp_elem.focus() exported_methods.refresh_empty(glob.sess_id, refresh_console) add_text(data) - elif msg[0] == 'disconnect': - dom.document.getElementById("error").innerHTML = "ERROR! disconnected" + elif msg[0] == 'disconnected': + inp_elem.disabled = True + name_bar = dom.document.getElementById("namebar") + name_bar.style.color = "red" + text = name_bar.lastChild.nodeValue + name_bar.removeChild(name_bar.lastChild) + name_bar.appendChild(create_text(text + " [DEFUNCT]")) def set_sessid(data): sessid = int(data[0]) 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 Mar 22 14:55:05 2007 @@ -9,7 +9,7 @@ from pypy.translator.js.main import rpython2javascript from pypy.translator.js.lib.support import callback from pypy.translator.js import commproxy -from pypy.translator.js.examples.console.session import Interpreter +from pypy.translator.js.examples.console.session import Interpreter, Killed from py.__.green.server.httpserver import GreenHTTPServer commproxy.USE_MOCHIKIT = True @@ -137,7 +137,7 @@ #print "Refresh %s %d" % (to_write, int(pid)) try: return ["refresh", sessions.update_session(int(pid), to_write)] - except (KeyError, IOError): + except (KeyError, IOError, Killed): return ["disconnected"] except Ignore: return ["ignore"] @@ -147,7 +147,7 @@ #print "Empty refresh %d" % int(pid) try: return ["refresh", sessions.update_session(int(pid), None)] - except (KeyError, IOError): + except (KeyError, IOError, Killed): return ["disconnected"] except Ignore: return ["ignore"] Modified: pypy/dist/pypy/translator/js/examples/console/data/console.html ============================================================================== --- pypy/dist/pypy/translator/js/examples/console/data/console.html (original) +++ pypy/dist/pypy/translator/js/examples/console/data/console.html Thu Mar 22 14:55:05 2007 @@ -26,7 +26,7 @@
    From mwh at codespeak.net Fri Mar 23 11:42:05 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 23 Mar 2007 11:42:05 +0100 (CET) Subject: [pypy-svn] r41153 - in pypy/dist/pypy: rpython/raisingops translator/backendopt translator/backendopt/test Message-ID: <20070323104205.B555E10091@code0.codespeak.net> Author: mwh Date: Fri Mar 23 11:42:04 2007 New Revision: 41153 Added: pypy/dist/pypy/translator/backendopt/test/test_raisingop2direct_call.py (contents, props changed) Modified: pypy/dist/pypy/rpython/raisingops/raisingops.py pypy/dist/pypy/translator/backendopt/raisingop2direct_call.py Log: issue300 testing still more div/mod fallout: the way raisingop2direct_call worked meant that after it, the result of a division or modulo could end up getting adjusted twice. fix that, and add some tests that test raisingop2direct_call specifically. Modified: pypy/dist/pypy/rpython/raisingops/raisingops.py ============================================================================== --- pypy/dist/pypy/rpython/raisingops/raisingops.py (original) +++ pypy/dist/pypy/rpython/raisingops/raisingops.py Fri Mar 23 11:42:04 2007 @@ -1,5 +1,7 @@ import sys from pypy.rlib.rarithmetic import r_longlong, r_uint, intmask +from pypy.rpython.lltypesystem.lloperation import llop +from pypy.rpython.lltypesystem.lltype import Signed #XXX original SIGNED_RIGHT_SHIFT_ZERO_FILLS not taken into account #XXX assuming HAVE_LONG_LONG (int_mul_ovf) @@ -17,7 +19,7 @@ else FAIL_ZER(err, "integer division") ''' if y: - return int_floordiv(x, y) + return llop.int_floordiv(Signed, x, y) else: raise ZeroDivisionError("integer division") @@ -132,7 +134,7 @@ if y == -1 and x < 0 and (r_uint(x) << 1) == 0: raise OverflowError("integer division") else: - return int_floordiv(x, y) + return llop.int_floordiv(Signed, x, y) def int_floordiv_ovf_zer(x, y): '''#define OP_INT_FLOORDIV_OVF_ZER(x,y,r,err) \ @@ -153,7 +155,7 @@ if y == -1 and x < 0 and (r_uint(x) << 1) == 0: raise OverflowError("integer modulo") else: - return int_mod(x, y) + return llop.int_mod(Signed, x, y) def int_mod_zer(x, y): '''#define OP_INT_MOD_ZER(x,y,r,err) \ @@ -161,7 +163,7 @@ else FAIL_ZER(err, "integer modulo") ''' if y: - return int_mod(x, y) + return llop.int_mod(Signed, x, y) else: raise ZeroDivisionError("integer modulo") @@ -187,42 +189,6 @@ # Helpers... -def int_floordiv(x, y): - return x / y - -#def int_floordiv(x, y): -# xdivy = r_longlong(x / y) -# xmody = r_longlong(x - xdivy * y) -# -# # If the signs of x and y differ, and the remainder is non-0, -# # C89 doesn't define whether xdivy is now the floor or the -# # ceiling of the infinitely precise quotient. We want the floor, -# # and we have it iff the remainder's sign matches y's. -# if xmody and ((y ^ xmody) < 0): -# xmody += y -# xdivy -= 1 -# assert xmody and ((y ^ xmody) >= 0) -# -# return xdivy - -def int_mod(x, y): - return x % y - -#def int_mod(x, y): -# xdivy = r_longlong(x / y) -# xmody = r_longlong(x - xdivy * y) -# -# # If the signs of x and y differ, and the remainder is non-0, -# # C89 doesn't define whether xdivy is now the floor or the -# # ceiling of the infinitely precise quotient. We want the floor, -# # and we have it iff the remainder's sign matches y's. -# if xmody and ((y ^ xmody) < 0): -# xmody += y -# xdivy -= 1 -# assert xmody and ((y ^ xmody) >= 0) -# -# return xmody - def _Py_ARITHMETIC_RIGHT_SHIFT(i, j): ''' // Py_ARITHMETIC_RIGHT_SHIFT Modified: pypy/dist/pypy/translator/backendopt/raisingop2direct_call.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/raisingop2direct_call.py (original) +++ pypy/dist/pypy/translator/backendopt/raisingop2direct_call.py Fri Mar 23 11:42:04 2007 @@ -2,6 +2,15 @@ import pypy.rpython.raisingops.raisingops log = log.raisingop2directcall +def is_raisingop(op): + s = op.opname + if (not s.startswith('int_') and not s.startswith('uint_') and + not s.startswith('float_') and not s.startswith('llong_')): + return False + if not s.endswith('_zer') and not s.endswith('_ovf') and not s.endswith('_val'): #not s in special_operations: + return False + return True + def raisingop2direct_call(translator, graphs=None): """search for operations that could raise an exception and change that operation into a direct_call to a function from the raisingops directory. @@ -14,14 +23,6 @@ if graphs is None: graphs = translator.graphs - def is_raisingop(op): - s = op.opname - if (not s.startswith('int_') and not s.startswith('uint_') and - not s.startswith('float_') and not s.startswith('llong_')): - return False - if not s.endswith('_zer') and not s.endswith('_ovf') and not s.endswith('_val'): #not s in special_operations: - return False - return True log('starting') seen = {} Added: pypy/dist/pypy/translator/backendopt/test/test_raisingop2direct_call.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/backendopt/test/test_raisingop2direct_call.py Fri Mar 23 11:42:04 2007 @@ -0,0 +1,119 @@ +from pypy.translator.backendopt import raisingop2direct_call, support +from pypy.rpython.test.test_llinterp import get_interpreter +from pypy.rlib.rarithmetic import ovfcheck + +import sys + +import py + + +def get_runner(f, exceptedop, types): + values = [t() for t in types] + interp, graph = get_interpreter(f, values) + for op in support.graph_operations(graph): + if op.opname == exceptedop: + break + else: + assert False, "op %r not found!"%(exceptedop,) + t = interp.typer.annotator.translator # FIIISH! + raisingop2direct_call.raisingop2direct_call(t, [graph]) + def ret(*args): + assert map(type, args) == types + return interp.eval_graph(graph, args) + return ret + +def test_test_machinery(): + def f(x, y): + try: + return x + y + except OverflowError: + return 123 + py.test.raises(AssertionError, "get_runner(f, 'int_add_ovf', [int, int])") + def f(x, y): + try: + return ovfcheck(x + y) + except OverflowError: + return 123 + fn = get_runner(f, 'int_add_ovf', [int, int]) + res = fn(0, 0) + assert res == 0 + + +def test_division(): + def f(x, y): + try: + return x//y + except ZeroDivisionError: + return 123 + fn = get_runner(f, 'int_floordiv_zer', [int, int]) + res = fn(1, 0) + assert res == 123 + res = fn(-5, 2) + assert res == -3 + + # this becomes an int_floordiv_ovf_zer already? +## def g(x, y): +## try: +## return ovfcheck(x//y) +## except OverflowError: +## return 123 +## gn = get_runner(g, 'int_floordiv_ovf', [int, int]) +## res = gn(-sys.maxint-1, -1) +## assert res == 123 +## res = gn(-5, 2) +## assert res == -3 + + def h(x, y): + try: + return ovfcheck(x//y) + except OverflowError: + return 123 + except ZeroDivisionError: + return 246 + hn = get_runner(h, 'int_floordiv_ovf_zer', [int, int]) + res = hn(-sys.maxint-1, -1) + assert res == 123 + res = hn(1, 0) + assert res == 246 + res = hn(-5, 2) + assert res == -3 + +def test_modulo(): + def f(x, y): + try: + return x%y + except ZeroDivisionError: + return 123 + fn = get_runner(f, 'int_mod_zer', [int, int]) + res = fn(0, 0) + assert res == 123 + res = fn(-5, 2) + assert res == 1 + + + # this becomes an int_mod_ovf_zer already? +## def g(x, y): +## try: +## return ovfcheck(x%y) +## except OverflowError: +## return 123 +## gn = get_runner(g, 'int_mod_ovf', [int, int]) +## res = gn(-sys.maxint-1, -1) +## assert res == 123 +## res = gn(-5, 2) +## assert res == -3 + + def h(x, y): + try: + return ovfcheck(x%y) + except OverflowError: + return 123 + except ZeroDivisionError: + return 246 + hn = get_runner(h, 'int_mod_ovf_zer', [int, int]) + res = hn(-sys.maxint-1, -1) + assert res == 123 + res = hn(1, 0) + assert res == 246 + res = hn(-5, 2) + assert res == 1 From antocuni at codespeak.net Fri Mar 23 11:51:37 2007 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Fri, 23 Mar 2007 11:51:37 +0100 (CET) Subject: [pypy-svn] r41154 - in pypy/dist/pypy/module/clr: . test Message-ID: <20070323105137.5D87B10095@code0.codespeak.net> Author: antocuni Date: Fri Mar 23 11:51:36 2007 New Revision: 41154 Modified: pypy/dist/pypy/module/clr/interp_clr.py pypy/dist/pypy/module/clr/test/test_clr.py Log: test&fix a last-minute bug in the clr module 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 Fri Mar 23 11:51:36 2007 @@ -15,10 +15,14 @@ def get_method(space, b_type, name, b_paramtypes): try: - return b_type.GetMethod(name, b_paramtypes) + method = b_type.GetMethod(name, b_paramtypes) except AmbiguousMatchException: msg = 'Multiple overloads for %s could match' % name raise OperationError(space.w_TypeError, space.wrap(msg)) + if method is None: + msg = 'No overloads for %s could match' % name + raise OperationError(space.w_TypeError, space.wrap(msg)) + return method def get_constructor(space, b_type, b_paramtypes): try: 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 Fri Mar 23 11:51:36 2007 @@ -78,6 +78,11 @@ assert obj.IndexOf(7) == 7 assert obj.IndexOf(7, 0, 5) == -1 + def test_wrong_overload(self): + import clr + Math = clr.load_cli_class('System', 'Math') + raises(TypeError, Math.Abs, "foo") + def test_staticmethod(self): import clr Math = clr.load_cli_class('System', 'Math') From mwh at codespeak.net Fri Mar 23 11:56:00 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 23 Mar 2007 11:56:00 +0100 (CET) Subject: [pypy-svn] r41155 - pypy/dist/pypy/jit/codegen/ppc Message-ID: <20070323105600.66ED9100A7@code0.codespeak.net> Author: mwh Date: Fri Mar 23 11:55:59 2007 New Revision: 41155 Modified: pypy/dist/pypy/jit/codegen/ppc/rgenop.py Log: be about 300% more careful about flushing the icache when needed. 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 Mar 23 11:55:59 2007 @@ -539,6 +539,8 @@ self.asm.mc = self.rgenop.ExistingCodeBlock( self.final_jump_addr, self.final_jump_addr+8) self.asm.load_word(rSCRATCH, target) + _flush_icache(self.final_jump_addr, 8) + self._code_start = mc.tell() self.asm.mc = mc self.final_jump_addr = 0 self.closed = False @@ -554,6 +556,7 @@ self.asm.mc = self.rgenop.ExistingCodeBlock( self.patch_start_here, self.patch_start_here+8) self.asm.load_word(rSCRATCH, mc.tell()) + _flush_icache(self.patch_start_here, 8) self.asm.mc = mc self.patch_start_here = 0 @@ -1344,6 +1347,7 @@ self._add_case(gv_case, target_addr) except codebuf.CodeBlockOverflow: self.asm.mc.setpos(p) + base = self.asm.mc.tell() mc = self.rgenop.open_mc() newmc = mc.reserve(7 * 5 + 4) self.rgenop.close_mc(mc) @@ -1351,12 +1355,15 @@ self.asm.load_word(rSCRATCH, new_addr) self.asm.mtctr(rSCRATCH) self.asm.bctr() + size = self.asm.mc.tell() - base + flush_icache(base, size) self.asm.mc = newmc self._add_case(gv_case, target_addr) return targetbuilder def _add_case(self, gv_case, target_addr): asm = self.asm + base = self.asm.mc.tell() assert isinstance(gv_case, GenConst) gv_case.load_now(asm, insn.gprs[0]) asm.cmpw(self.crf.number, rSCRATCH, self.switch_reg.number) @@ -1365,14 +1372,19 @@ asm.bcctr(12, self.crf.number*4 + 2) if self.default_target_addr: self._write_default() + size = self.asm.mc.tell() - base + flush_icache(base, size) def add_default(self): targetbuilder = self.rgenop.newbuilder() targetbuilder._open() targetbuilder.initial_var2loc = self.var2loc targetbuilder.initial_spill_offset = self.initial_spill_offset + base = self.asm.mc.tell() self.default_target_addr = targetbuilder.asm.mc.tell() self._write_default() + size = self.asm.mc.tell() - base + flush_icache(base, size) return targetbuilder def _write_default(self): From hpk at codespeak.net Fri Mar 23 12:14:14 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Fri, 23 Mar 2007 12:14:14 +0100 (CET) Subject: [pypy-svn] r41156 - pypy/extradoc/planning/1.0 Message-ID: <20070323111414.09823100AC@code0.codespeak.net> Author: hpk Date: Fri Mar 23 12:14:11 2007 New Revision: 41156 Modified: pypy/extradoc/planning/1.0/TODO.txt Log: after considering (and drafting a bit) i think we need to seriously consider architecture.txt refinements if we want to be clearer about our communication regarding what PyPy is. Modified: pypy/extradoc/planning/1.0/TODO.txt ============================================================================== --- pypy/extradoc/planning/1.0/TODO.txt (original) +++ pypy/extradoc/planning/1.0/TODO.txt Fri Mar 23 12:14:11 2007 @@ -58,6 +58,26 @@ - review entry points from the play1 demos. + - review/refactor architecture.txt: + - mission statement should emphasize VM + framework/translation and not mention project results + - always clearly separate the talk about the VM translation + framework and the Python implementation (and its features) + for example "PyPy - implementation of python in python" + as the first title is misleading. maybe something like: + a) PyPy is a VM/VHLL translation framework (or whatever we settle on) + b) already contains a full Python implementation + part of which is re-used from the translation framework + to analyse RPython programs (abstract interpretation ...) + - make the descriptions more "future" proof, i.e. + not reflecting the current state, possibly shortening + + rationale for looking in more depth at architecture.txt: + this document and getting-started.txt document are + the most viewed (arch: 1500 times in march, getting-started: + around 2200 times) ones and people expect archictecture.txt + to reflect our view on the project. + - describe particularly Javascript-related demos, refine them. (mostly done, apart from 404/500 pages and possible JIT demo) It's all more or less done. What needs to be done (play1): From hpk at codespeak.net Fri Mar 23 12:16:02 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Fri, 23 Mar 2007 12:16:02 +0100 (CET) Subject: [pypy-svn] r41157 - pypy/extradoc/planning/1.0 Message-ID: <20070323111602.CC6E8100B5@code0.codespeak.net> Author: hpk Date: Fri Mar 23 12:16:00 2007 New Revision: 41157 Modified: pypy/extradoc/planning/1.0/TODO.txt Log: remove redundancy Modified: pypy/extradoc/planning/1.0/TODO.txt ============================================================================== --- pypy/extradoc/planning/1.0/TODO.txt (original) +++ pypy/extradoc/planning/1.0/TODO.txt Fri Mar 23 12:16:00 2007 @@ -46,16 +46,6 @@ but no feedback/interaction with DFKI/Danish yet. - revisit entry level docs (architecture, mission, getting-started) - - terminology clarifications: - - use "translating PYPY interpreters" or "translating - standard interpreter" instead of talking about - e.g. "translating the whole of pypy" - - VM translation framework - - so we have: - - pypy standard interpreter (easy to understand/modify) - - pypy VM translation framework (neccessarily more complex) - (hpk to start here, have something done by friday) - - review entry points from the play1 demos. - review/refactor architecture.txt: @@ -71,6 +61,8 @@ to analyse RPython programs (abstract interpretation ...) - make the descriptions more "future" proof, i.e. not reflecting the current state, possibly shortening + - check other entry level docs (also FAQ) for keeping to this + updated view rationale for looking in more depth at architecture.txt: this document and getting-started.txt document are From mwh at codespeak.net Fri Mar 23 12:30:05 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 23 Mar 2007 12:30:05 +0100 (CET) Subject: [pypy-svn] r41159 - pypy/dist/pypy/jit/codegen/ppc Message-ID: <20070323113005.D1E12100A9@code0.codespeak.net> Author: mwh Date: Fri Mar 23 12:30:04 2007 New Revision: 41159 Modified: pypy/dist/pypy/jit/codegen/ppc/rgenop.py Log: can someone please turn the stupid ray off? 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 Mar 23 12:30:04 2007 @@ -539,7 +539,7 @@ self.asm.mc = self.rgenop.ExistingCodeBlock( self.final_jump_addr, self.final_jump_addr+8) self.asm.load_word(rSCRATCH, target) - _flush_icache(self.final_jump_addr, 8) + flush_icache(self.final_jump_addr, 8) self._code_start = mc.tell() self.asm.mc = mc self.final_jump_addr = 0 @@ -556,7 +556,7 @@ self.asm.mc = self.rgenop.ExistingCodeBlock( self.patch_start_here, self.patch_start_here+8) self.asm.load_word(rSCRATCH, mc.tell()) - _flush_icache(self.patch_start_here, 8) + flush_icache(self.patch_start_here, 8) self.asm.mc = mc self.patch_start_here = 0 From arigo at codespeak.net Fri Mar 23 13:07:38 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 23 Mar 2007 13:07:38 +0100 (CET) Subject: [pypy-svn] r41160 - pypy/dist/pypy/jit Message-ID: <20070323120738.CBC04100AC@code0.codespeak.net> Author: arigo Date: Fri Mar 23 13:07:37 2007 New Revision: 41160 Modified: pypy/dist/pypy/jit/TODO.txt Log: Update the TODO. Modified: pypy/dist/pypy/jit/TODO.txt ============================================================================== --- pypy/dist/pypy/jit/TODO.txt (original) +++ pypy/dist/pypy/jit/TODO.txt Fri Mar 23 13:07:37 2007 @@ -4,14 +4,12 @@ - basic docs and examples -- (maybe) make W_IntObject immutable - -- (maybe) try to replace the bool genvar with two constant bools in - the two paths exiting a conditional jump - Longer-term ------------------ +- make W_IntObject immutable (done, but gives bad code with + unexpected merges - try to understand why) + - we should be able to timeshift call_valuestack with sane results - we are promoting inside space.type, there are other uses of it From pedronis at codespeak.net Fri Mar 23 13:11:27 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Fri, 23 Mar 2007 13:11:27 +0100 (CET) Subject: [pypy-svn] r41162 - pypy/dist/pypy/jit Message-ID: <20070323121127.9180E100B4@code0.codespeak.net> Author: pedronis Date: Fri Mar 23 13:11:25 2007 New Revision: 41162 Modified: pypy/dist/pypy/jit/TODO.txt Log: now call_valuestack is timeshifted with somewhat nice results, although you need the right kind of benchmark to see them. The produced code for calls like f(x,y) is kind of nice. Modified: pypy/dist/pypy/jit/TODO.txt ============================================================================== --- pypy/dist/pypy/jit/TODO.txt (original) +++ pypy/dist/pypy/jit/TODO.txt Fri Mar 23 13:11:25 2007 @@ -10,7 +10,7 @@ - make W_IntObject immutable (done, but gives bad code with unexpected merges - try to understand why) -- we should be able to timeshift call_valuestack with sane results +- do something even better for calls (and LOOKUP_METHOD) - we are promoting inside space.type, there are other uses of it beyond dispatching, it may not be the best idea in general From hpk at codespeak.net Fri Mar 23 13:19:48 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Fri, 23 Mar 2007 13:19:48 +0100 (CET) Subject: [pypy-svn] r41163 - in pypy/dist: demo pypy/lib Message-ID: <20070323121948.7A9F1100B3@code0.codespeak.net> Author: hpk Date: Fri Mar 23 13:19:47 2007 New Revision: 41163 Modified: pypy/dist/demo/tp-print-builtin-operation.py pypy/dist/pypy/lib/tputil.py Log: fix imports, option name Modified: pypy/dist/demo/tp-print-builtin-operation.py ============================================================================== --- pypy/dist/demo/tp-print-builtin-operation.py (original) +++ pypy/dist/demo/tp-print-builtin-operation.py Fri Mar 23 13:19:47 2007 @@ -1,7 +1,7 @@ """ This example transparently intercepts and shows operations on -builtin objects. It requires the "--with-transparent-proxy" option. +builtin objects. Requires the "--objspace-std-withtproxy" option. """ @@ -9,15 +9,14 @@ def make_show_proxy(instance): def controller(operation): + print "proxy sees:", operation res = operation.delegate() - print "proxy sees:", operation, "result=%s" %(res,) return res tproxy = make_proxy(controller, obj=instance) return tproxy if __name__ == '__main__': mydict = make_show_proxy({}) - assert type(mydict) is dict # this looks exactly like a dict mydict['hello'] = 'world' # will print __setitem__ mydict[42] = 23 # will print __setitem__ Modified: pypy/dist/pypy/lib/tputil.py ============================================================================== --- pypy/dist/pypy/lib/tputil.py (original) +++ pypy/dist/pypy/lib/tputil.py Fri Mar 23 13:19:47 2007 @@ -5,7 +5,6 @@ """ from __pypy__ import tproxy from types import MethodType -import inspect _dummy = object() origtype = type From ac at codespeak.net Fri Mar 23 13:39:55 2007 From: ac at codespeak.net (ac at codespeak.net) Date: Fri, 23 Mar 2007 13:39:55 +0100 (CET) Subject: [pypy-svn] r41164 - in pypy/dist/pypy: lib objspace/std/test Message-ID: <20070323123955.8BAC5100B3@code0.codespeak.net> Author: ac Date: Fri Mar 23 13:39:54 2007 New Revision: 41164 Modified: pypy/dist/pypy/lib/_classobj.py pypy/dist/pypy/objspace/std/test/test_index.py Log: Add test abount non-existing __index__ method. Fix tests to really test oldstyle classes. Fix a bug in oldstyle classes Modified: pypy/dist/pypy/lib/_classobj.py ============================================================================== --- pypy/dist/pypy/lib/_classobj.py (original) +++ pypy/dist/pypy/lib/_classobj.py Fri Mar 23 13:39:54 2007 @@ -404,7 +404,7 @@ if func: return func() else: - raise AttributeError('object cannot be interpreted as an index') + raise TypeError('object cannot be interpreted as an index') # coerce Modified: pypy/dist/pypy/objspace/std/test/test_index.py ============================================================================== --- pypy/dist/pypy/objspace/std/test/test_index.py (original) +++ pypy/dist/pypy/objspace/std/test/test_index.py Fri Mar 23 13:39:54 2007 @@ -1,7 +1,9 @@ from py.test import raises +from pypy.conftest import gettestobjspace class AppTest_IndexProtocol: def setup_class(self): + self.space = gettestobjspace(oldstyle=True) w_oldstyle = self.space.appexec([], """(): class oldstyle: def __index__(self): @@ -14,6 +16,16 @@ return self.ind return newstyle""") + w_oldstyle_no_index = self.space.appexec([], """(): + class oldstyle_no_index: + pass + return oldstyle_no_index""") + + w_newstyle_no_index = self.space.appexec([], """(): + class newstyle_no_index(object): + pass + return newstyle_no_index""") + w_TrapInt = self.space.appexec([], """(): class TrapInt(int): def __index__(self): @@ -28,8 +40,10 @@ self.w_oldstyle = w_oldstyle self.w_o = self.space.call_function(w_oldstyle) + self.w_o_no_index = self.space.call_function(w_oldstyle_no_index) self.w_newstyle = w_newstyle self.w_n = self.space.call_function(w_newstyle) + self.w_n_no_index = self.space.call_function(w_newstyle_no_index) self.w_TrapInt = w_TrapInt self.w_TrapLong = w_TrapLong @@ -40,6 +54,8 @@ import operator assert operator.index(self.o) == -2 assert operator.index(self.n) == 2 + raises(TypeError, operator.index, self.o_no_index) + raises(TypeError, operator.index, self.n_no_index) def test_slice(self): self.o.ind = 1 From arigo at codespeak.net Fri Mar 23 13:40:40 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 23 Mar 2007 13:40:40 +0100 (CET) Subject: [pypy-svn] r41166 - in pypy/dist/pypy/jit/codegen: . i386 Message-ID: <20070323124040.90420100BE@code0.codespeak.net> Author: arigo Date: Fri Mar 23 13:40:39 2007 New Revision: 41166 Modified: pypy/dist/pypy/jit/codegen/detect_cpu.py pypy/dist/pypy/jit/codegen/i386/codebuf_nt.py Log: (afa on pypy-dev): * platform.machine() is empty on some Windows machine * the codebuf_nt module is expected to export a type called PTR Modified: pypy/dist/pypy/jit/codegen/detect_cpu.py ============================================================================== --- pypy/dist/pypy/jit/codegen/detect_cpu.py (original) +++ pypy/dist/pypy/jit/codegen/detect_cpu.py Fri Mar 23 13:40:39 2007 @@ -8,10 +8,13 @@ pass def autodetect(): + mach = None try: import platform mach = platform.machine() except ImportError: + pass + if not mach: platform = sys.platform.lower() if platform.startswith('win'): # assume an Intel Windows return 'i386' Modified: pypy/dist/pypy/jit/codegen/i386/codebuf_nt.py ============================================================================== --- pypy/dist/pypy/jit/codegen/i386/codebuf_nt.py (original) +++ pypy/dist/pypy/jit/codegen/i386/codebuf_nt.py Fri Mar 23 13:40:39 2007 @@ -19,24 +19,24 @@ globals().update(ctypes_platform.configure(CConfig)) # cannot use c_void_p as return value of functions :-( -LPVOID = ctypes.POINTER(ctypes.c_char) +PTR = ctypes.POINTER(ctypes.c_char) VirtualAlloc = ctypes.windll.kernel32.VirtualAlloc -VirtualAlloc.argtypes = [LPVOID, SIZE_T, DWORD, DWORD] -VirtualAlloc.restype = LPVOID +VirtualAlloc.argtypes = [PTR, SIZE_T, DWORD, DWORD] +VirtualAlloc.restype = PTR VirtualProtect = ctypes.windll.kernel32.VirtualProtect -VirtualProtect.argtypes = [LPVOID, SIZE_T, DWORD, ctypes.POINTER(DWORD)] +VirtualProtect.argtypes = [PTR, SIZE_T, DWORD, ctypes.POINTER(DWORD)] VirtualProtect.restype = BOOL VirtualFree = ctypes.windll.kernel32.VirtualFree -VirtualFree.argtypes = [LPVOID, SIZE_T, DWORD] +VirtualFree.argtypes = [PTR, SIZE_T, DWORD] VirtualFree.restype = BOOL # ____________________________________________________________ def alloc(map_size): - res = VirtualAlloc(LPVOID(), map_size, MEM_COMMIT|MEM_RESERVE, + res = VirtualAlloc(PTR(), map_size, MEM_COMMIT|MEM_RESERVE, PAGE_EXECUTE_READWRITE) if not res: raise MemoryError From pedronis at codespeak.net Fri Mar 23 14:11:52 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Fri, 23 Mar 2007 14:11:52 +0100 (CET) Subject: [pypy-svn] r41172 - pypy/dist/pypy/doc Message-ID: <20070323131152.DDA6D100C0@code0.codespeak.net> Author: pedronis Date: Fri Mar 23 14:11:51 2007 New Revision: 41172 Modified: pypy/dist/pypy/doc/cleanup-todo.txt Log: a clarification, another todo Modified: pypy/dist/pypy/doc/cleanup-todo.txt ============================================================================== --- pypy/dist/pypy/doc/cleanup-todo.txt (original) +++ pypy/dist/pypy/doc/cleanup-todo.txt Fri Mar 23 14:11:51 2007 @@ -19,7 +19,10 @@ and the gctransfomers, which varies depending on the GC :(, exploit better the removal of zeroing assumption - clean up the tangle of including headers in the C backend - - make approach for loading modules more sane + - make approach for loading modules more sane, mixedmodule capture + too many platform dependecies especially for pypy-cli + - review pdbplus, especially the graph commands, also in the light of + https://codespeak.net/issue/pypy-dev/issue303 interpreter ----------- From pedronis at codespeak.net Fri Mar 23 14:13:03 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Fri, 23 Mar 2007 14:13:03 +0100 (CET) Subject: [pypy-svn] r41174 - pypy/dist/pypy/doc Message-ID: <20070323131303.ECBE6100C0@code0.codespeak.net> Author: pedronis Date: Fri Mar 23 14:13:02 2007 New Revision: 41174 Modified: pypy/dist/pypy/doc/cleanup-todo.txt Log: some more details Modified: pypy/dist/pypy/doc/cleanup-todo.txt ============================================================================== --- pypy/dist/pypy/doc/cleanup-todo.txt (original) +++ pypy/dist/pypy/doc/cleanup-todo.txt Fri Mar 23 14:13:02 2007 @@ -22,7 +22,9 @@ - make approach for loading modules more sane, mixedmodule capture too many platform dependecies especially for pypy-cli - review pdbplus, especially the graph commands, also in the light of - https://codespeak.net/issue/pypy-dev/issue303 + https://codespeak.net/issue/pypy-dev/issue303 and the fact that + we can have more than one translator/annotator around (with the + timeshfiter) interpreter ----------- From pedronis at codespeak.net Fri Mar 23 14:13:54 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Fri, 23 Mar 2007 14:13:54 +0100 (CET) Subject: [pypy-svn] r41175 - pypy/dist/pypy/jit Message-ID: <20070323131354.3B8FA100C0@code0.codespeak.net> Author: pedronis Date: Fri Mar 23 14:13:52 2007 New Revision: 41175 Modified: pypy/dist/pypy/jit/TODO.txt Log: jit todo Modified: pypy/dist/pypy/jit/TODO.txt ============================================================================== --- pypy/dist/pypy/jit/TODO.txt (original) +++ pypy/dist/pypy/jit/TODO.txt Fri Mar 23 14:13:52 2007 @@ -12,6 +12,8 @@ - do something even better for calls (and LOOKUP_METHOD) +- redirect only the relevant fields in the virtualized frames + - we are promoting inside space.type, there are other uses of it beyond dispatching, it may not be the best idea in general From pedronis at codespeak.net Fri Mar 23 14:16:48 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Fri, 23 Mar 2007 14:16:48 +0100 (CET) Subject: [pypy-svn] r41176 - pypy/dist/pypy/doc Message-ID: <20070323131648.80639100C3@code0.codespeak.net> Author: pedronis Date: Fri Mar 23 14:16:46 2007 New Revision: 41176 Modified: pypy/dist/pypy/doc/cleanup-todo.txt Log: typo Modified: pypy/dist/pypy/doc/cleanup-todo.txt ============================================================================== --- pypy/dist/pypy/doc/cleanup-todo.txt (original) +++ pypy/dist/pypy/doc/cleanup-todo.txt Fri Mar 23 14:16:46 2007 @@ -24,7 +24,7 @@ - review pdbplus, especially the graph commands, also in the light of https://codespeak.net/issue/pypy-dev/issue303 and the fact that we can have more than one translator/annotator around (with the - timeshfiter) + timeshifter) interpreter ----------- From pedronis at codespeak.net Fri Mar 23 14:28:13 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Fri, 23 Mar 2007 14:28:13 +0100 (CET) Subject: [pypy-svn] r41180 - pypy/dist/pypy/objspace/flow Message-ID: <20070323132813.4A402100C3@code0.codespeak.net> Author: pedronis Date: Fri Mar 23 14:28:12 2007 New Revision: 41180 Modified: pypy/dist/pypy/objspace/flow/model.py Log: let optionally pass a translator to graph.show(), stop-gap to see colors of variables etc at a pdb prompt. Modified: pypy/dist/pypy/objspace/flow/model.py ============================================================================== --- pypy/dist/pypy/objspace/flow/model.py (original) +++ pypy/dist/pypy/objspace/flow/model.py Fri Mar 23 14:28:12 2007 @@ -120,9 +120,9 @@ for op in block.operations: yield block, op - def show(self): - from pypy.translator.tool.graphpage import SingleGraphPage - SingleGraphPage(self).display() + def show(self, t=None): + from pypy.translator.tool.graphpage import FlowGraphPage + FlowGraphPage(t, [self]).display() class Link(object): From hpk at codespeak.net Fri Mar 23 15:23:11 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Fri, 23 Mar 2007 15:23:11 +0100 (CET) Subject: [pypy-svn] r41186 - pypy/extradoc/planning/1.0 Message-ID: <20070323142311.007D2100E7@code0.codespeak.net> Author: hpk Date: Fri Mar 23 15:23:10 2007 New Revision: 41186 Modified: pypy/extradoc/planning/1.0/TODO.txt Log: looked a bit at play1, still needs some fix up Modified: pypy/extradoc/planning/1.0/TODO.txt ============================================================================== --- pypy/extradoc/planning/1.0/TODO.txt (original) +++ pypy/extradoc/planning/1.0/TODO.txt Fri Mar 23 15:23:10 2007 @@ -72,12 +72,11 @@ - describe particularly Javascript-related demos, refine them. (mostly done, apart from 404/500 pages and possible JIT demo) - It's all more or less done. What needs to be done (play1): - - more examples with autopaste feature + - fix play1 issues: - source code of web page under the button? - - refined help + - review/refine help (add examples where necessary) - make nice 404 and 500 pages, also for apache - - make pypy-cli work there + - fix linking (it gets easily confused if you click around) - discuss/do a JIT demo (fijal) @@ -87,7 +86,7 @@ - write a nice support module (pypy/lib/tputil.py - in progress) - write/review documentation (in-progress) - fix bugs if any - (hpk, still a bit of doc's/demo refinements) + (hpk) - update wp6 docs (object-optimizations.txt) and link to them from getting-started (mwh to coordinate) From mwh at codespeak.net Fri Mar 23 16:43:40 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 23 Mar 2007 16:43:40 +0100 (CET) Subject: [pypy-svn] r41190 - pypy/extradoc/planning/1.0 Message-ID: <20070323154340.856B1100F2@code0.codespeak.net> Author: mwh Date: Fri Mar 23 16:43:39 2007 New Revision: 41190 Added: pypy/extradoc/planning/1.0/docs-refactoring.txt Modified: pypy/extradoc/planning/1.0/TODO.txt Log: updates from today's meeting Modified: pypy/extradoc/planning/1.0/TODO.txt ============================================================================== --- pypy/extradoc/planning/1.0/TODO.txt (original) +++ pypy/extradoc/planning/1.0/TODO.txt Fri Mar 23 16:43:39 2007 @@ -4,7 +4,8 @@ current general timeline ----------------------------- -Note: meetings in #pypy-sync every weekday at 4pm (GMT+1) +Note: meetings in #pypy-sync every day at 4pm (GMT+1) +(weekend attendance optional :-) published final reports: 3.1, 2.1, 10.1, 12.1, 14.2 @@ -14,8 +15,8 @@ permissions for release candidates) 24 (weekend) release candidates testing 25 (weekend) release candidates testing -26 RELEASE (9.1, 2.3) -27 (1.2-4, 13.1) +26 testing testing testing (9.1, 2.3) +27 RELEASE (1.2-4, 13.1) 28 29 30 @@ -26,50 +27,19 @@ ----------------------------- - ensure working Interpreter translation combinations: - - pypy-c-stackless/tp/taint/jit/GC-framework/thunk - - pypy-cli-tp/taint/thunk - - - (done) make a matrix of possible combinations (wp13-report) (cfbolz) - - - complete/debug jit on powerpc (mwh) - (basically done) somewhat working, debugging in progress - - - (mostly done) debug jit on intel (arigo/pedronis/arre) - in progress, --jit --faassen works now, "is_true" issue fixed + - test various config option configurations -- use build tool? (guido) + - test windows situation (antocuni, fijal) -- seems generally good - integrate and test: - - (done) wp10 - basically complete, pending issues brought up in review - - (almost done) wp08 code - - (arigo,pedronis,arre): docs & examples, getting-started + - (arigo,pedronis,arre): wp08 docs & examples, getting-started - wp09 docs, examples and code - maybe what we have is good enough? (christian looking into this currently) a bit of progress, but no feedback/interaction with DFKI/Danish yet. - revisit entry level docs (architecture, mission, getting-started) - - review entry points from the play1 demos. - - - review/refactor architecture.txt: - - mission statement should emphasize VM - framework/translation and not mention project results - - always clearly separate the talk about the VM translation - framework and the Python implementation (and its features) - for example "PyPy - implementation of python in python" - as the first title is misleading. maybe something like: - a) PyPy is a VM/VHLL translation framework (or whatever we settle on) - b) already contains a full Python implementation - part of which is re-used from the translation framework - to analyse RPython programs (abstract interpretation ...) - - make the descriptions more "future" proof, i.e. - not reflecting the current state, possibly shortening - - check other entry level docs (also FAQ) for keeping to this - updated view - - rationale for looking in more depth at architecture.txt: - this document and getting-started.txt document are - the most viewed (arch: 1500 times in march, getting-started: - around 2200 times) ones and people expect archictecture.txt - to reflect our view on the project. - + - (guido,hpk) review entry points from the play1 demos. + - (hpk, ...) review/refactor architecture.txt -- see docs-refactoring.txt + - describe particularly Javascript-related demos, refine them. (mostly done, apart from 404/500 pages and possible JIT demo) - fix play1 issues: @@ -80,22 +50,25 @@ - discuss/do a JIT demo (fijal) - - (done, still a bit of doc's/demo refinements maybe) - make transparent proxies more prominent - because they are a rather powerful feature) - - write a nice support module (pypy/lib/tputil.py - in progress) - - write/review documentation (in-progress) - - fix bugs if any - (hpk) - - update wp6 docs (object-optimizations.txt) and link to them from getting-started (mwh to coordinate) ropes docs added - - (done) document build tool usages (getting-started?), connect servers with it + - (guido) connect more servers to buildtool if possible - stress-test/use buildtool for translation tests (multicompile) (guido_w) + - (no news ) include documentation/entry point for + the JS interpreter (santagada, fijal) + + - include documentation/entry point for + the prolog interpreter (cfbolz, maybe) + + + +NOTES AND DONE TASKS +----------------------------- + - (DONE) consider where/how to put special builtins ("pypymagic" might not be a good name), suggestions: - names: not pypymagic, not pypybuiltin, holger and cf to propose @@ -107,8 +80,23 @@ translated version (unless they work :) (done) (cfbolz) - - (no news ) include documentation/entry point for - the JS interpreter (santagada, fijal) + - (done, still a bit of doc's/demo refinements maybe) + make transparent proxies more prominent + because they are a rather powerful feature) + - write a nice support module (pypy/lib/tputil.py - in progress) + - write/review documentation (in-progress) + - fix bugs if any + (hpk) - - include documentation/entry point for - the prolog interpreter (cfbolz, maybe) + - (done) wp10 - basically complete, pending issues brought up in review + - (done) wp08 code + + - (done) make a matrix of possible combinations (wp13-report) (cfbolz) + + - complete/debug jit on powerpc + (basically done) somewhat working + + - (done for release) debug jit on intel (arigo/pedronis/arre) + appears to work well, gives nice speedups on suitably contrived examples + + - (done) document build tool usages (getting-started?) Added: pypy/extradoc/planning/1.0/docs-refactoring.txt ============================================================================== --- (empty file) +++ pypy/extradoc/planning/1.0/docs-refactoring.txt Fri Mar 23 16:43:39 2007 @@ -0,0 +1,21 @@ + - mission statement should emphasize VM + framework/translation and not mention project results + - always clearly separate the talk about the VM translation + framework and the Python implementation (and its features) + for example "PyPy - implementation of python in python" + as the first title is misleading. maybe something like: + a) PyPy is a VM/VHLL translation framework (or whatever we settle on) + b) already contains a full Python implementation + part of which is re-used from the translation framework + to analyse RPython programs (abstract interpretation ...) + - make the descriptions more "future" proof, i.e. + not reflecting the current state, possibly shortening + - check other entry level docs (also FAQ) for keeping to this + updated view + + rationale for looking in more depth at architecture.txt: + this document and getting-started.txt document are + the most viewed (arch: 1500 times in march, getting-started: + around 2200 times) ones and people expect archictecture.txt + to reflect our view on the project. + From cfbolz at codespeak.net Fri Mar 23 16:49:55 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 23 Mar 2007 16:49:55 +0100 (CET) Subject: [pypy-svn] r41192 - pypy/extradoc/eu-report Message-ID: <20070323154955.2FDB2100FB@code0.codespeak.net> Author: cfbolz Date: Fri Mar 23 16:49:54 2007 New Revision: 41192 Modified: pypy/extradoc/eu-report/D03.1_Extension_Compiler-2007-03-21.pdf Log: fix small typo Modified: pypy/extradoc/eu-report/D03.1_Extension_Compiler-2007-03-21.pdf ============================================================================== Binary files. No diff available. From guido at codespeak.net Fri Mar 23 16:51:17 2007 From: guido at codespeak.net (guido at codespeak.net) Date: Fri, 23 Mar 2007 16:51:17 +0100 (CET) Subject: [pypy-svn] r41194 - pypy/dist/pypy/tool/build Message-ID: <20070323155117.A5A1D100FC@code0.codespeak.net> Author: guido Date: Fri Mar 23 16:51:15 2007 New Revision: 41194 Added: pypy/dist/pypy/tool/build/multibuild.py Modified: pypy/dist/pypy/tool/build/buildserver.py pypy/dist/pypy/tool/build/compile.py Log: Added multibuild.py script that mimics translator/goal/multibuild.py, but instead of building locally it uses the build tool, rolling back some change that applied some (useless) blocking while loading the zip from the build server, fixed some logic in reconnecting code. Modified: pypy/dist/pypy/tool/build/buildserver.py ============================================================================== --- pypy/dist/pypy/tool/build/buildserver.py (original) +++ pypy/dist/pypy/tool/build/buildserver.py Fri Mar 23 16:51:15 2007 @@ -53,8 +53,6 @@ # end of data is marked by sending a None if chunk is None: break - else: - self.channel.send(None) gotdata = True fp.write(chunk) finally: @@ -120,7 +118,6 @@ def write(self, data): self.loc += len(data) self.channel.send(data) - self.channel.receive() # to make sure stuff is only sent when required def close(self): self.channel.send(None) Modified: pypy/dist/pypy/tool/build/compile.py ============================================================================== --- pypy/dist/pypy/tool/build/compile.py (original) +++ pypy/dist/pypy/tool/build/compile.py Fri Mar 23 16:51:15 2007 @@ -66,21 +66,19 @@ self._connect() self.channel.send(data) - def _receive_twice(self): - try: - ret = self.channel.receive() - except EOFError, e: - print 'error during receive: %s, retrying' % (e,) - self.close() - self._connect() - ret = self.channel.receive() + def _receive(self): + ret = self.channel.receive() if isinstance(ret, Exception): raise ret.__class__, ret # tb? return ret def _try_twice(self, command, data): - self._send_twice((command, data)) - return self._receive_twice() + try: + self._send_twice((command, data)) + return self._receive() + except EOFError: + self._send_twice((command, data)) + return self._receive() def start_compile(self, request): req = request.serialize() @@ -94,6 +92,8 @@ def save_zip(self, path): self._send_twice(('zip', self.requestid)) + # XXX let's not try to fiddle about with re-sending the zip on + # failures, people can always go to the web page fp = path.open('w') try: while 1: @@ -138,7 +138,7 @@ help='block until build is available and download it ' 'immediately') - (options, args) = optparser.parse_args() + (options, args) = optparser.parse_args(args) if not args or len(args) != 1: optparser.error('please provide an email address') @@ -172,6 +172,7 @@ msa = ServerAccessor(config) print 'going to start compile' ret = msa.start_compile(request) + reqid = ret['id'] if ret['path']: print ('a suitable result is already available, you can ' 'find it at "%s" on %s' % (ret['path'], @@ -192,10 +193,14 @@ time.sleep(POLLTIME) if error and error != 'None': print 'error:', error + return (False, error) else: - zipfile = py.path.local('data.zip') + zipfile = py.path.local('pypy-%s.zip' % (retid,)) msa.save_zip(zipfile) - print 'done, the result can be found in "data.zip"' - elif inprogress: + print 'done, the result can be found in %s' % (zipfile,) + return (True, ret['message']) + elif not foreground and inprogress and not ret['path']: print 'you will be mailed once it\'s ready' + elif foreground: + return (False, ret['message']) Added: pypy/dist/pypy/tool/build/multibuild.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/tool/build/multibuild.py Fri Mar 23 16:51:15 2007 @@ -0,0 +1,93 @@ +""" multibuild.py variant that uses startcompile to run the builds + + see pypy/translator/goal/multibuild.py for the original version (by mwh) + that builds on the local host +""" + +import autopath +import sys +import random +import os +import threading +from pypy.translator.goal.multibuild import get_options, exe_name_from_options +from pypy.tool.build import config +from pypy.tool.build.compile import getrequest, main + +class ConfigWrapper(object): + def __init__(self, orgconfig): + self.__dict__.update(orgconfig.__dict__) + +def setconfig(conf, overrides): + for name, value in overrides.iteritems(): + try: + homeconfig, name = conf._cfgimpl_get_home_by_path(name) + homeconfig.setoption(name, value, 'default') + except AttributeError: + pass + +def override_conf(config, opts): + for k, v in opts.items(): + for c in (config.system_config, config.compile_config, + config.tool_config): + try: + c.set(**{k: v}) + except AttributeError: + pass + +def startcompile(exe_name, config, opts): + try: + override_conf(config, opts) + except: + return exe_name_from_options(newconfig.compile_config, opts), \ + "didn't configure" + request, foreground = getrequest(config, sys.argv[3:]) + hasbuilt, message = main(config, request, True) + hasbuilt, message = (True, 'foo') + return hasbuilt and 'successfully built' or 'not built: %s' % (message,) + +def wait_until_done(): + while 1: + for t in threading.enumerate(): + if t != threading.currentThread() and t.isAlive(): + t.join() + else: + break + +results = [] +def build_pypy_with_options(basedir, opts): + """ start blocking (--foreground) startcompile with opts + """ + newconfig = ConfigWrapper(config) + newconfig.system_config = config.system_config.copy() + newconfig.compile_config = config.compile_config.copy() + newconfig.tool_config = config.tool_config.copy() + + exe_name = os.path.join(basedir, exe_name_from_options( + newconfig.compile_config, opts)) + + print 'starting: %s' % (exe_name,) + sys.stdout.flush() + + status = startcompile(exe_name, newconfig, opts) + + results.append((exe_name, status)) + + print '%s: %s' % (exe_name, status) + +if __name__ == '__main__': + basedir = sys.argv[1] + optionsfile = sys.argv[2] + results = [] + options = list(get_options(optionsfile)) + random.shuffle(options) + for opts in options: + t = threading.Thread(target=build_pypy_with_options, + args=(basedir, opts)) + t.start() + wait_until_done() + print 'done' + + out = open(os.path.join(basedir, 'results'), 'w') + for exe, r in results: + print >>out, exe, r + From cfbolz at codespeak.net Fri Mar 23 16:56:23 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 23 Mar 2007 16:56:23 +0100 (CET) Subject: [pypy-svn] r41197 - pypy/extradoc/eu-report Message-ID: <20070323155623.972D61010A@code0.codespeak.net> Author: cfbolz Date: Fri Mar 23 16:56:22 2007 New Revision: 41197 Modified: pypy/extradoc/eu-report/D12.1_H-L-Backends_and_Feature_Prototypes-2007-03-22.pdf Log: fix D13.1 title Modified: pypy/extradoc/eu-report/D12.1_H-L-Backends_and_Feature_Prototypes-2007-03-22.pdf ============================================================================== Binary files. No diff available. From mwh at codespeak.net Fri Mar 23 17:09:56 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 23 Mar 2007 17:09:56 +0100 (CET) Subject: [pypy-svn] r41198 - pypy/dist/pypy/doc Message-ID: <20070323160956.05F471010C@code0.codespeak.net> Author: mwh Date: Fri Mar 23 17:09:55 2007 New Revision: 41198 Modified: pypy/dist/pypy/doc/object-optimizations.txt Log: add a table of contents, a few content tweaks Modified: pypy/dist/pypy/doc/object-optimizations.txt ============================================================================== --- pypy/dist/pypy/doc/object-optimizations.txt (original) +++ pypy/dist/pypy/doc/object-optimizations.txt Fri Mar 23 17:09:55 2007 @@ -2,6 +2,11 @@ Alternative object implementations in the PyPy standard interpreter =================================================================== +.. contents:: Contents + +Introduction +============ + 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 @@ -17,7 +22,6 @@ since you have to know only a rather small part of PyPy to do them. And they are fun too! - String optimizations ==================== @@ -50,7 +54,6 @@ You can enable this feature with the :config:`objspace.std.withstrslice` option. - Ropes ----- @@ -85,10 +88,10 @@ 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. +Similar to CPython, 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. You can enable this feature with the :config:`objspace.std.withsmallint` option. @@ -111,18 +114,18 @@ Multi-dicts are a special implementation of dictionaries. It became clear that it is very useful to *change* the internal representation of an object during -its lifetime. Multi-Dicts are a general way to do that for dictionaries: they +its lifetime. Multi-dicts are a general way to do that for dictionaries: they provide generic support for the switching of internal 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 -general representation that can store arbitrary keys). In addition there are -more specialized dictionary implementations for various purposes (see below). +for string-keyed dictionaries. 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. +.. XXX chunked dicts, small dicts sharing dicts ------------- @@ -144,7 +147,6 @@ You can enable this feature with the :config:`objspace.std.withsharingdict` option. - builtin-shadowing ----------------- @@ -257,3 +259,5 @@ You can enable this feature with the :config:`objspace.std.withmethodcache` option. + +.. CALL_METHOD? From guido at codespeak.net Fri Mar 23 17:42:17 2007 From: guido at codespeak.net (guido at codespeak.net) Date: Fri, 23 Mar 2007 17:42:17 +0100 (CET) Subject: [pypy-svn] r41202 - in pypy/dist/pypy/tool/build: . test Message-ID: <20070323164217.84C821008D@code0.codespeak.net> Author: guido Date: Fri Mar 23 17:42:15 2007 New Revision: 41202 Modified: pypy/dist/pypy/tool/build/compile.py pypy/dist/pypy/tool/build/metaserver.py pypy/dist/pypy/tool/build/test/test_compile.py pypy/dist/pypy/tool/build/test/test_metaserver.py Log: Fixed a threading bug in metaserver which made that build requests could end up on the same build server at the same time, blocking each other (and the rest of the system), improved logging of the meta server a bit, fixed functional test. Modified: pypy/dist/pypy/tool/build/compile.py ============================================================================== Modified: pypy/dist/pypy/tool/build/metaserver.py ============================================================================== --- pypy/dist/pypy/tool/build/metaserver.py (original) +++ pypy/dist/pypy/tool/build/metaserver.py Fri Mar 23 17:42:15 2007 @@ -53,14 +53,14 @@ self._queued = [] # no builders available self._waiting = [] # compilation already in progress for someone else + self._requestlock = thread.allocate_lock() self._queuelock = thread.allocate_lock() self._namelock = thread.allocate_lock() def register(self, builder): """ register a builder (instance) """ self._builders.append(builder) - self._channel.send('registered %s with info %r' % ( - builder, builder.sysinfo)) + self._channel.send('registered build server %s' % (builder.hostname,)) def compile(self, request): """start a compilation @@ -79,53 +79,61 @@ in any case, if the first item of the tuple returned is False, an email will be sent once the build is available """ - # store the request, if there's already a build available the - # storage will return that path - requestid = request.id() - for bp in self._done: - if request.has_satisfying_data(bp.request): - path = str(bp) - self._channel.send( - 'already a build for this info available as %s' % ( - bp.request.id(),)) - return {'path': path, 'id': bp.request.id(), - 'isbuilding': True, - 'message': 'build is already available'} - for builder in self._builders: - if (builder.busy_on and - request.has_satisfying_data(builder.busy_on)): - id = builder.busy_on.id() - self._channel.send( - "build for %s currently in progress on '%s' as %s" % ( - request.id(), builder.hostname, id)) - self._waiting.append(request) - return {'path': None, 'id': id, 'isbuilding': True, - 'message': "this build is already in progress " - "on '%s'" % (builder.hostname,)} - for br in self._waiting + self._queued: - if br.has_satisfying_data(request): - id = br.id() - self._channel.send( - 'build for %s already queued as %s' % ( - request.id(), id)) - return {'path': None, 'id': id, 'isbuilding': False, - 'message': ('no suitable server found, and a ' - 'similar request was already queued ' - 'as %s' % (id,))} - # we don't have a build for this yet, find a builder to compile it - hostname = self.run(request) - if hostname is not None: - return {'path': None, 'id': requestid, 'isbuilding': True, - 'message': "found a suitable server, going to build " - "on '%s'" % (hostname, )} - self._queuelock.acquire() + self._requestlock.acquire() try: - self._queued.append(request) + # store the request, if there's already a build available the + # storage will return that path + requestid = request.id() + for bp in self._done: + if request.has_satisfying_data(bp.request): + path = str(bp) + self._channel.send( + 'already a build for this info available as %s' % ( + bp.request.id(),)) + return {'path': path, 'id': bp.request.id(), + 'isbuilding': True, + 'message': 'build is already available'} + for builder in self._builders: + if (builder.busy_on and + request.has_satisfying_data(builder.busy_on)): + id = builder.busy_on.id() + self._channel.send( + "build for %s currently in progress on '%s' as %s" % ( + request.id(), builder.hostname, id)) + self._waiting.append(request) + return {'path': None, 'id': id, 'isbuilding': True, + 'message': "this build is already in progress " + "on '%s'" % (builder.hostname,)} + for br in self._waiting + self._queued: + if br.has_satisfying_data(request): + id = br.id() + self._channel.send( + 'build for %s already queued as %s' % ( + request.id(), id)) + return {'path': None, 'id': id, 'isbuilding': False, + 'message': ('no suitable server found, and a ' + 'similar request was already queued ' + 'as %s' % (id,))} + # we don't have a build for this yet, find a builder to compile it + hostname = self.run(request) + if hostname is not None: + self._channel.send('going to send compile job for request %s' + 'to %s' % (request.id(), builder.hostname)) + return {'path': None, 'id': requestid, 'isbuilding': True, + 'message': "found a suitable server, going to build " + "on '%s'" % (hostname, )} + self._channel.send('no suitable build server available for ' + 'compilation of %s' % (request.id(),)) + self._queuelock.acquire() + try: + self._queued.append(request) + finally: + self._queuelock.release() + return {'path': None, 'id': requestid, 'isbuilding': False, + 'message': 'no suitable build server found; your request ' + 'is queued'} finally: - self._queuelock.release() - return {'path': None, 'id': requestid, 'isbuilding': False, - 'message': 'no suitable build server found; your request ' - 'is queued'} + self._requestlock.release() def run(self, request): """find a suitable build server and run the job if possible""" @@ -140,22 +148,9 @@ request in builder.refused): continue else: - self._channel.send( - 'going to send compile job for request %s to %s' % ( - request, builder.hostname - ) - ) accepted = builder.compile(request) if accepted: - self._channel.send('compile job accepted') return builder.hostname - else: - self._channel.send('compile job denied') - self._channel.send( - 'no suitable build server available for compilation of %s' % ( - request, - ) - ) def serve_forever(self): """this keeps the script from dying, and re-tries jobs""" @@ -177,14 +172,6 @@ self._test_waiting() self._try_queued() - def _cleanup(self): - for builder in self._builders: - try: - builder.channel.close() - except EOFError: - pass - self._channel.close() - def get_new_buildpath(self, request): path = BuildPath(str(self._buildroot / self._create_filename())) path.request = request @@ -195,7 +182,8 @@ self._queuelock.acquire() try: self._channel.send('compilation done for %s, written to %s' % ( - buildpath.request, buildpath)) + buildpath.request.id(), + buildpath)) emails = [buildpath.request.email] self._done.append(buildpath) waiting = self._waiting[:] @@ -216,13 +204,21 @@ for builder in builders: if builder.channel.isclosed(): self._channel.send('build server %s disconnected' % ( - builder,)) + builder.hostname,)) if builder.busy_on: self._queued.append(builder.busy_on) self._builders.remove(builder) finally: self._queuelock.release() + def _cleanup(self): + for builder in self._builders: + try: + builder.channel.close() + except EOFError: + pass + self._channel.close() + def _test_waiting(self): """ for each waiting request, see if the compilation is still alive Modified: pypy/dist/pypy/tool/build/test/test_compile.py ============================================================================== --- pypy/dist/pypy/tool/build/test/test_compile.py (original) +++ pypy/dist/pypy/tool/build/test/test_compile.py Fri Mar 23 17:42:15 2007 @@ -105,7 +105,6 @@ def create_test_repo_file(name): repo, wc = svntestbase.getrepowc('test_compile') - temp = py.test.ensuretemp('test_compile.%s' % (name,)) wc.ensure('foo', dir=True) wc.commit('added foo') path = repo + '/foo' @@ -115,6 +114,7 @@ # functional test, sorry :| if not option.functional: py.test.skip('skipping functional test, use --functional to run it') + temp = py.test.ensuretemp('test_compile.test_blocking') path = create_test_repo_file('test_blocking') gw = py.execnet.PopenGateway() 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 Fri Mar 23 17:42:15 2007 @@ -60,8 +60,6 @@ assert "fake" in ret['message'] # hostname ret = svr._channel.receive() assert ret.find('going to send compile job') > -1 - acceptedmsg = svr._channel.receive() - assert acceptedmsg == 'compile job accepted' ret = c1.channel.receive() assert ret == br.serialize() none = c1.channel.receive() @@ -79,8 +77,6 @@ svr.compile(br3) ret = svr._channel.receive() assert ret.find('going to send') > -1 - acceptedmsg = svr._channel.receive() - assert acceptedmsg == 'compile job accepted' assert c2.channel.receive() == br3.serialize() assert c2.channel.receive() is None py.test.raises(IndexError, "c1.channel.receive()") From mwh at codespeak.net Fri Mar 23 18:03:20 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 23 Mar 2007 18:03:20 +0100 (CET) Subject: [pypy-svn] r41203 - in pypy/dist/pypy/doc: . config Message-ID: <20070323170320.B5F681007F@code0.codespeak.net> Author: mwh Date: Fri Mar 23 18:03:18 2007 New Revision: 41203 Added: pypy/dist/pypy/doc/interpreter-optimizations.txt - copied, changed from r41198, pypy/dist/pypy/doc/object-optimizations.txt Removed: pypy/dist/pypy/doc/object-optimizations.txt Modified: pypy/dist/pypy/doc/config/index.txt pypy/dist/pypy/doc/config/objspace.std.withfastslice.txt pypy/dist/pypy/doc/config/objspace.std.withmethodcache.txt pypy/dist/pypy/doc/config/objspace.std.withmultidict.txt pypy/dist/pypy/doc/config/objspace.std.withmultilist.txt pypy/dist/pypy/doc/config/objspace.std.withrangelist.txt pypy/dist/pypy/doc/config/objspace.std.withrope.txt pypy/dist/pypy/doc/config/objspace.std.withsharingdict.txt pypy/dist/pypy/doc/config/objspace.std.withstrjoin.txt pypy/dist/pypy/doc/config/objspace.std.withstrslice.txt pypy/dist/pypy/doc/index.txt pypy/dist/pypy/doc/objspace-proxies.txt pypy/dist/pypy/doc/objspace.txt Log: svn mv object-optimizations.txt interpreter-optimizations.txt and lots of associated changes, but not much in the way of generalizing the content of the document yet. Modified: pypy/dist/pypy/doc/config/index.txt ============================================================================== --- pypy/dist/pypy/doc/config/index.txt (original) +++ pypy/dist/pypy/doc/config/index.txt Fri Mar 23 18:03:18 2007 @@ -34,10 +34,9 @@ passed in either position. Many of the more interesting object space options enable optimzations, -which are described in `Alternative object implementations in the PyPy -standard interpreter`_, or allow the creation of objects that can -barely be imagined in CPython, which are documented in `What PyPy can -do for your objects`_. +which are described in `Standard Interpreter Optimizations`_, or allow +the creation of objects that can barely be imagined in CPython, which +are documented in `What PyPy can do for your objects`_. The following diagram gives some hints about which PyPy features work together with which other PyPy features: @@ -49,5 +48,5 @@ .. _`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 +.. _`Standard Interpreter Optimizations`: ../interpreter-optimizations.html .. _`What PyPy can do for your objects`: ../objspace-proxies.html Modified: pypy/dist/pypy/doc/config/objspace.std.withfastslice.txt ============================================================================== --- pypy/dist/pypy/doc/config/objspace.std.withfastslice.txt (original) +++ pypy/dist/pypy/doc/config/objspace.std.withfastslice.txt Fri Mar 23 18:03:18 2007 @@ -2,6 +2,6 @@ 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. +See the description in `Standard Interpreter Optimizations`_ for more details. -.. _`object reimplementations`: ../object-optimizations.html +.. _`Standard Interpreter Optimizations`: ../interpreter-optimizations.html#fast-list-slicing Modified: pypy/dist/pypy/doc/config/objspace.std.withmethodcache.txt ============================================================================== --- pypy/dist/pypy/doc/config/objspace.std.withmethodcache.txt (original) +++ pypy/dist/pypy/doc/config/objspace.std.withmethodcache.txt Fri Mar 23 18:03:18 2007 @@ -1,3 +1,2 @@ -Enable method caching. See the section "Method Caching" in `Alternative object -implementations in the PyPy standard interpreter -<../object-optimizations.html#method-caching>`__. +Enable method caching. See the section "Method Caching" in `Standard +Interpreter Optimizations <../interpreter-optimizations.html#method-caching>`__. 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 Fri Mar 23 18:03:18 2007 @@ -3,6 +3,6 @@ the normal implementation is not used at all). 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. +See the description in `Standard Interpreter Optimizations`_ for more details. -.. _`object reimplementations`: ../object-optimizations.html +.. _`Standard Interpreter Optimizations`: ../interpreter-optimizations.html#multi-dicts Modified: pypy/dist/pypy/doc/config/objspace.std.withmultilist.txt ============================================================================== --- pypy/dist/pypy/doc/config/objspace.std.withmultilist.txt (original) +++ pypy/dist/pypy/doc/config/objspace.std.withmultilist.txt Fri Mar 23 18:03:18 2007 @@ -2,7 +2,7 @@ ``list`` type, indistinguishable for the normal user (when using multilists, the normal implementation is not used at all). -See the page about `object reimplementations`_ for more details. +See the section in `Standard Interpreter Optimizations`_ for more details. -.. _`object reimplementations`: ../object-optimizations.html +.. _`Standard Interpreter Optimizations`: ../interpreter-optimizations.html#multi-lists 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 Fri Mar 23 18:03:18 2007 @@ -5,7 +5,7 @@ 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. +See the section in `Standard Interpreter Optimizations`_ for more details. -.. _`object reimplementations`: ../object-optimizations.html +.. _`Standard Interpreter Optimizations`: ../interpreter-optimizations.html#range-lists Modified: pypy/dist/pypy/doc/config/objspace.std.withrope.txt ============================================================================== --- pypy/dist/pypy/doc/config/objspace.std.withrope.txt (original) +++ pypy/dist/pypy/doc/config/objspace.std.withrope.txt Fri Mar 23 18:03:18 2007 @@ -1,7 +1,7 @@ Enable ropes to be the default string implementation. -See the page about `object optimizations`_ for more details. +See the section in `Standard Interpreter Optimizations`_ for more details. -.. _`object optimizations`: ../object-optimizations.html +.. _`Standard Interpreter Optimizations`: ../interpreter-optimizations.html#ropes 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 Fri Mar 23 18:03:18 2007 @@ -1,6 +1,6 @@ Enable "sharing dictionaries". -See the page about `object optimizations`_ for more details. +See the section in `Standard Interpreter Optimizations`_ for more details. -.. _`object optimizations`: ../object-optimizations.html +.. _`Standard Interpreter Optimizations`: ../interpreter-optimizations.html#sharing-dicts 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 Fri Mar 23 18:03:18 2007 @@ -1,7 +1,7 @@ Enable "string join" objects. -See the page about `object optimizations`_ for more details. +See the page about `Standard Interpreter Optimizations`_ for more details. -.. _`object optimizations`: ../object-optimizations.html +.. _`Standard Interpreter Optimizations`: ../interpreter-optimizations.html#string-join-objects 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 Fri Mar 23 18:03:18 2007 @@ -1,7 +1,7 @@ Enable "string slice" objects. -See the page about `object optimizations`_ for more details. +See the page about `Standard Interpreter Optimizations`_ for more details. -.. _`object optimizations`: ../object-optimizations.html +.. _`Standard Interpreter Optimizations`: ../interpreter-optimizations.html#string-slice-objects Modified: pypy/dist/pypy/doc/index.txt ============================================================================== --- pypy/dist/pypy/doc/index.txt (original) +++ pypy/dist/pypy/doc/index.txt Fri Mar 23 18:03:18 2007 @@ -98,8 +98,10 @@ `bytecode interpreter`_ explains the basic mechanisms of the bytecode interpreter and virtual machine. -`object optimizations`_ describes various alternative object implementations -(for strings, dictionaries and lists) in the standard object space. +`interpreter optimizations`_ describes our various strategies for +improving the performance of our interpreter, including alternative +object implementations (for strings, dictionaries 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. @@ -146,7 +148,7 @@ .. _`PyPy LOC statistics`: http://codespeak.net/~hpk/pypy-stat/ .. _`PyPy statistics`: http://codespeak.net/pypy/dist/pypy/doc/statistic .. _`object spaces`: objspace.html -.. _`object optimizations`: object-optimizations.html +.. _`interpreter optimizations`: interpreter-optimizations.html .. _`translation`: translation.html .. _`dynamic-language translation`: dynamic-language-translation.html .. _`low-level encapsulation`: low-level-encapsulation.html Modified: pypy/dist/pypy/doc/objspace-proxies.txt ============================================================================== --- pypy/dist/pypy/doc/objspace-proxies.txt (original) +++ pypy/dist/pypy/doc/objspace-proxies.txt Fri Mar 23 18:03:18 2007 @@ -503,7 +503,7 @@ >>>> i + 3 42 -.. _`alternative object implementations`: object-optimizations.html +.. _`alternative object implementations`: interpreter-optimizations.html Example of recording all operations on builtins Modified: pypy/dist/pypy/doc/objspace.txt ============================================================================== --- pypy/dist/pypy/doc/objspace.txt (original) +++ pypy/dist/pypy/doc/objspace.txt Fri Mar 23 18:03:18 2007 @@ -332,7 +332,7 @@ 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 an optimization that we eventually made, but not hard-coded at this level - -see `object optimizations`_.) +see `Standard Interpreter Optimizations`_.) So in summary: wrapping integers as instances is the simple path, while using plain integers instead is the complex path, not the other way @@ -389,14 +389,14 @@ `stringtype.py`_. For other examples of multiple implementations of the same Python type, -see the `object optimizations`_ page. +see `Standard Interpreter Optimizations`_. .. _`listtype.py`: ../objspace/std/listtype.py .. _`stringtype.py`: ../objspace/std/stringtype.py .. _`tupletype.py`: ../objspace/std/tupletype.py .. _`tupleobject.py`: ../objspace/std/tupleobject.py -.. _`object optimizations`: object-optimizations.html +.. _`Standard Interpreter Optimizations`: interpreter-optimizations.html Multimethods From mwh at codespeak.net Fri Mar 23 18:16:06 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 23 Mar 2007 18:16:06 +0100 (CET) Subject: [pypy-svn] r41204 - pypy/dist/pypy/doc Message-ID: <20070323171606.6F39810076@code0.codespeak.net> Author: mwh Date: Fri Mar 23 18:16:04 2007 New Revision: 41204 Modified: pypy/dist/pypy/doc/interpreter-optimizations.txt Log: divide into object and interpreter optimizations, add stub sections for the special bytecodes and Title Case section titles. Modified: pypy/dist/pypy/doc/interpreter-optimizations.txt ============================================================================== --- pypy/dist/pypy/doc/interpreter-optimizations.txt (original) +++ pypy/dist/pypy/doc/interpreter-optimizations.txt Fri Mar 23 18:16:04 2007 @@ -28,11 +28,14 @@ .. describe other optimizations! -String optimizations +Object Optimizations ==================== -string-join objects -------------------- +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 @@ -44,8 +47,8 @@ You can enable this feature enable with the :config:`objspace.std.withstrjoin` option. -string-slice objects --------------------- +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 @@ -62,7 +65,7 @@ You can enable this feature with the :config:`objspace.std.withstrslice` option. Ropes ------ ++++++ Ropes are a general flexible string implementation, following the paper `"Ropes: An alternative to Strings."`_ by Boehm, Atkinson and Plass. Strings are @@ -89,11 +92,11 @@ .. _`"Ropes: An alternative to Strings."`: http://www.cs.ubc.ca/local/reading/proceedings/spe91-95/spe/vol25/issue12/spe986.pdf -Integer optimizations -===================== +Integer Optimizations +--------------------- -caching small integers ----------------------- +Caching Small Integers +++++++++++++++++++++++ Similar to CPython, 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 @@ -102,8 +105,8 @@ You can enable this feature with the :config:`objspace.std.withsmallint` option. -integers as tagged pointers ---------------------------- +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 @@ -113,11 +116,11 @@ time and memory. -Dictionary optimizations -======================== +Dictionary Optimizations +------------------------ -multi-dicts ------------ +Multi-Dicts ++++++++++++ Multi-dicts are a special implementation of dictionaries. It became clear that it is very useful to *change* the internal representation of an object during @@ -134,8 +137,8 @@ .. XXX chunked dicts, small dicts -sharing dicts -------------- +Sharing Dicts ++++++++++++++ Sharing dictionaries are a special representation used together with multidicts. This dict representation is used only for instance dictionaries and tries to @@ -154,8 +157,8 @@ You can enable this feature with the :config:`objspace.std.withsharingdict` option. -builtin-shadowing ------------------ +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 @@ -181,11 +184,11 @@ :config:`objspace.opcodes.CALL_LIKELY_BUILTIN` option. -List optimizations -================== +List Optimizations +------------------ -range-lists ------------ +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 @@ -199,8 +202,8 @@ You can enable this feature with the :config:`objspace.std.withrangelist` option. -multi-lists ------------ +Multi-Lists ++++++++++++ As with dictionaries it became clear that it is generally useful to allow lists to change their internal representation over their lifetime. Therefore @@ -214,8 +217,8 @@ option. -fast list slicing ------------------- +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 @@ -230,11 +233,11 @@ .. _`Neal Norwitz on pypy-dev`: http://codespeak.net/pipermail/pypy-dev/2005q4/002538.html -User class optimizations -======================== +User Class Optimizations +------------------------ -Shadow tracking ---------------- +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 @@ -251,8 +254,8 @@ option. -Method caching --------------- +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 @@ -267,4 +270,18 @@ You can enable this feature with the :config:`objspace.std.withmethodcache` option. -.. CALL_METHOD? +Interpreter Optimizations +========================= + +Special Bytecodes +----------------- + +LOOKUP_METHOD & CALL_METHOD ++++++++++++++++++++++++++++ + +Write this! + +CALL_LIKELY_BUILTIN ++++++++++++++++++++ + +And this! From cfbolz at codespeak.net Fri Mar 23 18:27:15 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 23 Mar 2007 18:27:15 +0100 (CET) Subject: [pypy-svn] r41206 - pypy/extradoc/eu-report Message-ID: <20070323172715.D360D10033@code0.codespeak.net> Author: cfbolz Date: Fri Mar 23 18:27:14 2007 New Revision: 41206 Added: pypy/extradoc/eu-report/D02.3_Testing_Framework-2007-03-23.pdf - copied unchanged from r41205, pypy/eu-tracking/deliverable/D02_3_Testing_Framework/D02.3-deliverablereport.pdf Log: 2.3 final, hopefully From cfbolz at codespeak.net Fri Mar 23 18:32:14 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 23 Mar 2007 18:32:14 +0100 (CET) Subject: [pypy-svn] r41208 - pypy/extradoc/eu-report Message-ID: <20070323173214.3BA0C10034@code0.codespeak.net> Author: cfbolz Date: Fri Mar 23 18:32:12 2007 New Revision: 41208 Modified: pypy/extradoc/eu-report/D02.3_Testing_Framework-2007-03-23.pdf Log: 2.3 hopefully really final. it pays off being cautious. Modified: pypy/extradoc/eu-report/D02.3_Testing_Framework-2007-03-23.pdf ============================================================================== Files pypy/extradoc/eu-report/D02.3_Testing_Framework-2007-03-23.pdf (original) and pypy/extradoc/eu-report/D02.3_Testing_Framework-2007-03-23.pdf Fri Mar 23 18:32:12 2007 differ From cfbolz at codespeak.net Fri Mar 23 18:36:33 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 23 Mar 2007 18:36:33 +0100 (CET) Subject: [pypy-svn] r41209 - pypy/dist/pypy/doc Message-ID: <20070323173633.95EA710071@code0.codespeak.net> Author: cfbolz Date: Fri Mar 23 18:36:32 2007 New Revision: 41209 Modified: pypy/dist/pypy/doc/index-report.txt Log: fix link Modified: pypy/dist/pypy/doc/index-report.txt ============================================================================== --- pypy/dist/pypy/doc/index-report.txt (original) +++ pypy/dist/pypy/doc/index-report.txt Fri Mar 23 18:36:32 2007 @@ -12,11 +12,14 @@ Reports of 2007 =============== -`D10.1 Aspect-Oriented, Design-by-Contract Programming and RPython static checking`_ is a report -about the ``aop`` module providing an Aspect Oriented Programming -mechanism for PyPy, and how this can be leveraged to implement a -Design-by-Contract module. It also introduces RPylint static type -checker for RPython code. *(2007-03-22)* +`D02.3 Testing Tool`_ is a report about the +`py.test`_ testing tool which is part of the `py-lib`_. *(2007-03-23)* + +`D10.1 Aspect-Oriented, Design-by-Contract Programming and RPython static +checking`_ is a report about the ``aop`` module providing an Aspect Oriented +Programming mechanism for PyPy, and how this can be leveraged to implement a +Design-by-Contract module. It also introduces RPylint static type checker for +RPython code. *(2007-03-22)* `D12.1 High-Level-Backends and Feature Prototypes`_ is a report about our high-level backends and our @@ -43,10 +46,6 @@ PyPy development process. The report is still non-final, all feedback for it is welcome. *(2007-03-12)* -`Interim 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 -non-final, all feedback for it is welcome. *(2007-03-12)* - `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 @@ -125,7 +124,7 @@ .. _`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-2007-03-21.pdf -.. _`Interim D02.3 Testing Tool`: http://codespeak.net/pypy/extradoc/eu-report/D02.3_Testing_Framework-interim-2007-03-12.pdf +.. _`D02.3 Testing Tool`: http://codespeak.net/pypy/extradoc/eu-report/D02.3_Testing_Framework-2007-03-23.pdf .. _`Interim D01.2-4 Project Organization`: http://codespeak.net/pypy/extradoc/eu-report/D01.2-4_Project_Organization-interim-2007-03-12.pdf .. _`D02.1 Development Tools and Website`: http://codespeak.net/pypy/extradoc/eu-report/D02.1_Development_Tools_and_Website-2007-03-21.pdf .. _`Draft D08.2 JIT Compiler Architecture`: http://codespeak.net/pypy/extradoc/eu-report/D08.2_JIT_Compiler_Architecture-interim-2007-01-28.pdf From cfbolz at codespeak.net Fri Mar 23 18:36:54 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 23 Mar 2007 18:36:54 +0100 (CET) Subject: [pypy-svn] r41210 - pypy/extradoc/eu-report Message-ID: <20070323173654.078E510075@code0.codespeak.net> Author: cfbolz Date: Fri Mar 23 18:36:52 2007 New Revision: 41210 Removed: pypy/extradoc/eu-report/D02.3_Testing_Framework-interim-2007-03-12.pdf Log: remove intermediate version From mwh at codespeak.net Fri Mar 23 20:42:37 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 23 Mar 2007 20:42:37 +0100 (CET) Subject: [pypy-svn] r41213 - pypy/dist/pypy/doc Message-ID: <20070323194237.72DCD10071@code0.codespeak.net> Author: mwh Date: Fri Mar 23 20:42:34 2007 New Revision: 41213 Modified: pypy/dist/pypy/doc/interpreter-optimizations.txt Log: some stuff on the special bytecodes, adapted from the wp06 report, also a conclusion type thing which could be more bombastic, i guess. Modified: pypy/dist/pypy/doc/interpreter-optimizations.txt ============================================================================== --- pypy/dist/pypy/doc/interpreter-optimizations.txt (original) +++ pypy/dist/pypy/doc/interpreter-optimizations.txt Fri Mar 23 20:42:34 2007 @@ -279,9 +279,100 @@ LOOKUP_METHOD & CALL_METHOD +++++++++++++++++++++++++++ -Write this! +An unusual feature of Python's version of object oriented programming is the +concept of a "bound method". While the concept is clean and powerful, the +allocation and initialization of the object is not without its performance cost. +We have implemented a pair of bytecodes that alleviate this cost. + +For a given method call ``obj.meth(x, y)``, the standard bytecode looks like +this:: + + LOAD_GLOBAL obj # push 'obj' on the stack + LOAD_ATTR meth # read the 'meth' attribute out of 'obj' + LOAD_GLOBAL x # push 'x' on the stack + LOAD_GLOBAL y # push 'y' on the stack + CALL_FUNCTION 2 # call the 'obj.meth' object with arguments x, y + +We improved this by keeping method lookup separated from method call, unlike +some other approaches, but using the value stack as a cache instead of building +a temporary object. We extended the bytecode compiler to (optionally) generate +the following code for ``obj.meth(x)``:: + + LOAD_GLOBAL obj + LOOKUP_METHOD meth + LOAD_GLOBAL x + LOAD_GLOBAL y + CALL_METHOD 2 + +``LOOKUP_METHOD`` contains exactly the same attribute lookup logic as +``LOAD_ATTR`` - thus fully preserving semantics - but pushes two values onto the +stack instead of one. These two values are an "inlined" version of the bound +method object: the *im_func* and *im_self*, i.e. respectively the underlying +Python function object and a reference to ``obj``. This is only possible when +the attribute actually refers to a function object from the class; when this is +not the case, ``LOOKUP_METHOD`` still pushes two values, but one *(im_func)* is +simply the regular result that ``LOAD_ATTR`` would have returned, and the other +*(im_self)* is a None placeholder. + +After pushing the arguments, the layout of the stack in the above +example is as follows (the stack grows upwards): + ++---------------------------------+ +| ``y`` *(2nd arg)* | ++---------------------------------+ +| ``x`` *(1st arg)* | ++---------------------------------+ +| ``obj`` *(im_self)* | ++---------------------------------+ +| ``function object`` *(im_func)* | ++---------------------------------+ + +The ``CALL_METHOD N`` bytecode emulates a bound method call by +inspecting the *im_self* entry in the stack below the ``N`` arguments: +if it is not None, then it is considered to be an additional first +argument in the call to the *im_func* object from the stack. CALL_LIKELY_BUILTIN +++++++++++++++++++ -And this! +A often heard "tip" for speeding up Python programs is to give an often used +builtin a local name, since local lookups are faster than lookups of builtins, +which involve doing two dictionary lookups: one in the globals dictionary and +one in the the builtins dictionary. PyPy approaches this problem at the +implementation level, with the introduction of the new ``CALL_LIKELY_BUILTIN`` +bytecode. This bytecode is produced by the compiler for a call whose target is +the name of a builtin. Since such a syntactic construct is very often actually +invoking the expected builtin at run-time, this information can be used to make +the call to the builtin directly, without going through any dictionary lookup. + +However, it can occur that the name is shadowed by a global name from the +current module. To catch this case, a special dictionary implementation for +multidicts is introduced, which is used for the dictionaries of modules. This +implementation keeps track which builtin name is shadowed by it. The +``CALL_LIKELY_BUILTIN`` bytecode asks the dictionary whether it is shadowing the +builtin that is about to be called and asks the dictionary of ``__builtin__`` +whether the original builtin was changed. These two checks are cheaper than +full lookups. In the common case, neither of these cases is true, so the +builtin can be directly invoked. + +.. more here? + +Overall Effects +=============== + +The impact these various optimizations have on performance unsurprisingly +depends on the program being. Using the default multi-dict implementation that +simply special cases string-keyed dictionaries is a clear win on all benchmarks, +improving results by anything from 15-40 per cent. + +Another optimization, or rather set of optimizations, that has a uniformly good +effect is the set of three 'method optimizations', i.e. shadow tracking, the +method cache and the LOOKUP_METHOD and CALL_METHOD opcodes. On a heavily +object-oriented benchmark (richards) they combine to give a speed-up of nearly +50%, and even on the extremely un-object-oriented pystone benchmark, the +improvement is over 20%. + +.. waffles about ropes + +A build with all the generally useful optimizations turned on is between 1.5 and +2.5 times faster than one without, depending on the benchmark. From mwh at codespeak.net Fri Mar 23 20:48:17 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 23 Mar 2007 20:48:17 +0100 (CET) Subject: [pypy-svn] r41214 - pypy/dist/pypy/doc Message-ID: <20070323194817.8CBF310071@code0.codespeak.net> Author: mwh Date: Fri Mar 23 20:48:15 2007 New Revision: 41214 Modified: pypy/dist/pypy/doc/interpreter-optimizations.txt Log: forgot a work, thanks cf Modified: pypy/dist/pypy/doc/interpreter-optimizations.txt ============================================================================== --- pypy/dist/pypy/doc/interpreter-optimizations.txt (original) +++ pypy/dist/pypy/doc/interpreter-optimizations.txt Fri Mar 23 20:48:15 2007 @@ -361,7 +361,7 @@ =============== The impact these various optimizations have on performance unsurprisingly -depends on the program being. Using the default multi-dict implementation that +depends on the program being run. Using the default multi-dict implementation that simply special cases string-keyed dictionaries is a clear win on all benchmarks, improving results by anything from 15-40 per cent. From mwh at codespeak.net Fri Mar 23 20:54:58 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 23 Mar 2007 20:54:58 +0100 (CET) Subject: [pypy-svn] r41215 - in pypy/dist/pypy/doc: . config Message-ID: <20070323195458.A996410070@code0.codespeak.net> Author: mwh Date: Fri Mar 23 20:54:57 2007 New Revision: 41215 Modified: pypy/dist/pypy/doc/config/objspace.opcodes.CALL_LIKELY_BUILTIN.txt pypy/dist/pypy/doc/config/objspace.opcodes.CALL_METHOD.txt pypy/dist/pypy/doc/interpreter-optimizations.txt Log: like to interpreter-optimizations from the opcode config descriptions. the change to interpreter-optimizations.txt itself is purely to keep the py lib happy. 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 Fri Mar 23 20:54:57 2007 @@ -6,3 +6,7 @@ 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 dictionary lookups on calls to builtins. + +For more information, see the section in `Standard Interpreter Optimizations`_. + +.. _`Standard Interpreter Optimizations`: ../interpreter-optimizations.html#call-likely-builtin Modified: pypy/dist/pypy/doc/config/objspace.opcodes.CALL_METHOD.txt ============================================================================== --- pypy/dist/pypy/doc/config/objspace.opcodes.CALL_METHOD.txt (original) +++ pypy/dist/pypy/doc/config/objspace.opcodes.CALL_METHOD.txt Fri Mar 23 20:54:57 2007 @@ -5,4 +5,8 @@ case. So far, this only works for calls with no keyword, no ``*arg`` and no ``**arg`` but it would be easy to extend. -Gives the best results combined with --objspace-std-withshadowtracking. +Gives the best results combined with :config:`objspace.std.withshadowtracking`. + +For more information, see the section in `Standard Interpreter Optimizations`_. + +.. _`Standard Interpreter Optimizations`: ../interpreter-optimizations.html#lookup-method-call-method Modified: pypy/dist/pypy/doc/interpreter-optimizations.txt ============================================================================== --- pypy/dist/pypy/doc/interpreter-optimizations.txt (original) +++ pypy/dist/pypy/doc/interpreter-optimizations.txt Fri Mar 23 20:54:57 2007 @@ -276,6 +276,8 @@ Special Bytecodes ----------------- +.. _`lookup method call method`: + LOOKUP_METHOD & CALL_METHOD +++++++++++++++++++++++++++ @@ -332,6 +334,8 @@ if it is not None, then it is considered to be an additional first argument in the call to the *im_func* object from the stack. +.. _`call likely builtin`: + CALL_LIKELY_BUILTIN +++++++++++++++++++ From guido at codespeak.net Fri Mar 23 21:35:42 2007 From: guido at codespeak.net (guido at codespeak.net) Date: Fri, 23 Mar 2007 21:35:42 +0100 (CET) Subject: [pypy-svn] r41216 - in pypy/dist/pypy/tool/build: . testproject/bin Message-ID: <20070323203542.22E021006E@code0.codespeak.net> Author: guido Date: Fri Mar 23 21:35:39 2007 New Revision: 41216 Modified: pypy/dist/pypy/tool/build/buildserver.py pypy/dist/pypy/tool/build/compile.py pypy/dist/pypy/tool/build/testproject/bin/metaserver.py Log: Reconnecting build server on broken connections, fixed some problems in the code I added to compile.py to support multibuild.py, added autopath.py to the test project's metaserver script. Modified: pypy/dist/pypy/tool/build/buildserver.py ============================================================================== --- pypy/dist/pypy/tool/build/buildserver.py (original) +++ pypy/dist/pypy/tool/build/buildserver.py Fri Mar 23 21:35:39 2007 @@ -3,6 +3,7 @@ from zipfile import ZipFile, ZIP_DEFLATED from cStringIO import StringIO from pypy.tool.build import build +from py.execnet import SshGateway, PopenGateway class BuildServer(object): def __init__(self, channel, sysinfo, hostname, testing_sleeptime=False): @@ -150,10 +151,7 @@ return parent.ensure(dirname, dir=True) i += 1 -def main(config, path, compilefunc): - """ build server bootstrapping and main loop """ - from py.execnet import SshGateway, PopenGateway - +def connect(config): if config.server in ['localhost', '127.0.0.1']: gw = PopenGateway() else: @@ -166,12 +164,22 @@ config.system_config, path=config.path, port=config.port) + return gw, channel + +def main(config, path, compilefunc): + """ build server bootstrapping and main loop """ + gw, channel = connect(config) print 'connected' try: while 1: # receive compile requests - request = channel.receive() + try: + request = channel.receive() + except EOFError: + gw.exit() + gw, channel = connect(config) + if not isinstance(request, str): raise ValueError( 'received wrong unexpected data of type %s' % ( Modified: pypy/dist/pypy/tool/build/compile.py ============================================================================== --- pypy/dist/pypy/tool/build/compile.py (original) +++ pypy/dist/pypy/tool/build/compile.py Fri Mar 23 21:35:39 2007 @@ -173,13 +173,14 @@ print 'going to start compile' ret = msa.start_compile(request) reqid = ret['id'] - if ret['path']: + path = ret['path'] + message = ret['message'] + if path: print ('a suitable result is already available, you can ' - 'find it at "%s" on %s' % (ret['path'], - config.server)) + 'find it at "%s" on %s' % (path, config.server)) else: - print ret['message'] - print 'the id of this build request is: %s' % (ret['id'],) + print message + print 'the id of this build request is: %s' % (reqid,) inprogress = True if foreground and inprogress: @@ -195,12 +196,12 @@ print 'error:', error return (False, error) else: - zipfile = py.path.local('pypy-%s.zip' % (retid,)) + zipfile = py.path.local('pypy-%s.zip' % (reqid,)) msa.save_zip(zipfile) print 'done, the result can be found in %s' % (zipfile,) - return (True, ret['message']) - elif not foreground and inprogress and not ret['path']: + return (True, message) + elif not foreground and inprogress and not path: print 'you will be mailed once it\'s ready' elif foreground: - return (False, ret['message']) + return (False, message) Modified: pypy/dist/pypy/tool/build/testproject/bin/metaserver.py ============================================================================== --- pypy/dist/pypy/tool/build/testproject/bin/metaserver.py (original) +++ pypy/dist/pypy/tool/build/testproject/bin/metaserver.py Fri Mar 23 21:35:39 2007 @@ -1,5 +1,6 @@ #!/usr/bin/env python +import autopath from pypy.tool.build.testproject import config from pypy.tool.build.metaserver import main From guido at codespeak.net Fri Mar 23 22:00:40 2007 From: guido at codespeak.net (guido at codespeak.net) Date: Fri, 23 Mar 2007 22:00:40 +0100 (CET) Subject: [pypy-svn] r41217 - pypy/dist/pypy/doc Message-ID: <20070323210040.CF5961007A@code0.codespeak.net> Author: guido Date: Fri Mar 23 22:00:39 2007 New Revision: 41217 Modified: pypy/dist/pypy/doc/stackless.txt Log: Some typos. Modified: pypy/dist/pypy/doc/stackless.txt ============================================================================== --- pypy/dist/pypy/doc/stackless.txt (original) +++ pypy/dist/pypy/doc/stackless.txt Fri Mar 23 22:00:39 2007 @@ -30,11 +30,11 @@ py.py --withmod-_stackless This is implemented internally using greenlets, so it only works on a -platform where the `Py lib greenlets`_ are supported. A few features do -not work in this way, though, and really require a translated +platform where `Py lib greenlets`_ are supported. A few features do +not work this way, though, and really require a translated ``pypy-c``. -To obtained a translated version of ``pypy-c`` that includes Stackless +To obtain a translated version of ``pypy-c`` that includes Stackless support, run translate.py as follows:: cd pypy/translator/goal @@ -45,8 +45,8 @@ ============================= A stackless PyPy contains a module called ``stackless``. The interface -exposed by this module has not been much refined, so it should be -considered in-flux (as of 2006). +exposed by this module have not been refined much, so it should be +considered in-flux (as of 2007). So far, PyPy does not provide support for ``stackless`` in a threaded environment. This limitation is not fundamental, as previous experience From antocuni at codespeak.net Fri Mar 23 23:58:55 2007 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Fri, 23 Mar 2007 23:58:55 +0100 (CET) Subject: [pypy-svn] r41221 - pypy/dist/pypy/translator/cli Message-ID: <20070323225855.B4ECF10084@code0.codespeak.net> Author: antocuni Date: Fri Mar 23 23:58:54 2007 New Revision: 41221 Modified: pypy/dist/pypy/translator/cli/query.py Log: (Scoot Dial) apply the patch from Scott which fixes test_query on windows Modified: pypy/dist/pypy/translator/cli/query.py ============================================================================== --- pypy/dist/pypy/translator/cli/query.py (original) +++ pypy/dist/pypy/translator/cli/query.py Fri Mar 23 23:58:54 2007 @@ -70,7 +70,8 @@ def query_description(name): log.query('Loading description for %s' % name) arglist = SDK.runtime() + [Query.get(), name] - query = subprocess.Popen(arglist, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + query = subprocess.Popen(arglist, stdout=subprocess.PIPE, stderr=subprocess.PIPE, + universal_newlines=True) stdout, stderr = query.communicate() retval = query.wait() if retval == 0: From fijal at codespeak.net Sat Mar 24 09:12:36 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 24 Mar 2007 09:12:36 +0100 (CET) Subject: [pypy-svn] r41223 - pypy/dist/pypy/doc/play1 Message-ID: <20070324081236.819CD1008B@code0.codespeak.net> Author: fijal Date: Sat Mar 24 09:12:34 2007 New Revision: 41223 Added: pypy/dist/pypy/doc/play1/ pypy/dist/pypy/doc/play1/pypy-c-taint.html pypy/dist/pypy/doc/play1/pypy-c-thunk.html pypy/dist/pypy/doc/play1/pypy-c.html pypy/dist/pypy/doc/play1/pypy-cli.html pypy/dist/pypy/doc/play1/pyrolog-c.html pypy/dist/pypy/doc/play1/python.html pypy/dist/pypy/doc/play1/test_snippets.py Log: Intermediate checkin - how play1 help structure will look like, right now nothing is automatically chosen from this directory, although that's the direction. Added: pypy/dist/pypy/doc/play1/pypy-c-taint.html ============================================================================== --- (empty file) +++ pypy/dist/pypy/doc/play1/pypy-c-taint.html Sat Mar 24 09:12:34 2007 @@ -0,0 +1,4 @@ +The PyPy standard interpreter compiled to C using +the taint object space. Example (execute): +
    %s
    +Now try hard getting to value of x :-) Added: pypy/dist/pypy/doc/play1/pypy-c-thunk.html ============================================================================== --- (empty file) +++ pypy/dist/pypy/doc/play1/pypy-c-thunk.html Sat Mar 24 09:12:34 2007 @@ -0,0 +1,4 @@ +The PyPy standard interpreter compiled to C using the +thunk object space. Example (execute): +
    %s
    +And try x. Added: pypy/dist/pypy/doc/play1/pypy-c.html ============================================================================== --- (empty file) +++ pypy/dist/pypy/doc/play1/pypy-c.html Sat Mar 24 09:12:34 2007 @@ -0,0 +1,14 @@ +This is the PyPy standard interpreter translated to C with the following features: +
      +
    • Stackless - You can use all stackless features including + tasklets, channels, coroutines and greenlets, more information and some + examples can be found in the + PyPy stackless documentation. +
    • +
    • Transparent proxy - This is a unique PyPy interpreter feature, + which allows you to provide an application-level controller for any kind of + object. Details and snippets can be found in the + transparent proxy documentation. Example (execute): +
      %s
      +
    • +
    Added: pypy/dist/pypy/doc/play1/pypy-cli.html ============================================================================== --- (empty file) +++ pypy/dist/pypy/doc/play1/pypy-cli.html Sat Mar 24 09:12:34 2007 @@ -0,0 +1 @@ +The PyPy standard interpreter compiled to CLI Added: pypy/dist/pypy/doc/play1/pyrolog-c.html ============================================================================== --- (empty file) +++ pypy/dist/pypy/doc/play1/pyrolog-c.html Sat Mar 24 09:12:34 2007 @@ -0,0 +1 @@ +The Prolog interpreter compiled to C. Added: pypy/dist/pypy/doc/play1/python.html ============================================================================== --- (empty file) +++ pypy/dist/pypy/doc/play1/python.html Sat Mar 24 09:12:34 2007 @@ -0,0 +1 @@ +just CPython, play as you like :) Added: pypy/dist/pypy/doc/play1/test_snippets.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/doc/play1/test_snippets.py Sat Mar 24 09:12:34 2007 @@ -0,0 +1,16 @@ +from pypy.conftest import gettestobjspace + +class AppTest_pypy_c(object): + def setup_class(cls): + cls.space = gettestobjspace(**{"objspace.std.withtproxy": True, + "usemodules":("_stackless",)}) + + def test_snippet_1(self): + from tputil import make_proxy + history = [] + def recorder(operation): + history.append(operation) + return operation.delegate() + + l = make_proxy(recorder, obj=[]) + From fijal at codespeak.net Sat Mar 24 10:32:37 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 24 Mar 2007 10:32:37 +0100 (CET) Subject: [pypy-svn] r41225 - in pypy/dist/pypy/translator/js/examples/console: . test Message-ID: <20070324093237.D027310070@code0.codespeak.net> Author: fijal Date: Sat Mar 24 10:32:36 2007 New Revision: 41225 Added: pypy/dist/pypy/translator/js/examples/console/docloader.py pypy/dist/pypy/translator/js/examples/console/test/test_docloader.py Log: Add the docloader class which loads help messages and code snippets from docdir Added: pypy/dist/pypy/translator/js/examples/console/docloader.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/js/examples/console/docloader.py Sat Mar 24 10:32:36 2007 @@ -0,0 +1,43 @@ + +""" Simple module for loading documentation of various +pypy-cs from doc directory +""" + +import py + +class LoadDoc(object): + def __init__(self, consoles, docdir, testfile='test_snippets.py'): + self.consoles = consoles + self.docdir = py.path.local(docdir) + assert self.docdir.check(dir=1) + self.testfile = self.docdir.join(testfile) + assert self.testfile.check() + self.htmls = {} + self.snippets = {} + self.load() + + def get_html(self, console): + return self.htmls[console] + + def get_snippet(self, console, num): + return str(self.snippets[console][num]) + + def load(self): + def mangle_name(name): + return name.replace("-", "_").replace(".", "_") + + def mangle(source): + source = source.strip() + del source.lines[0] + return source.deindent() + + testmod = self.testfile.pyimport() + for console in self.consoles: + html = self.docdir.join(console + '.html').read() + snip_class = getattr(testmod, 'AppTest_' + mangle_name(console)) + snippets = [mangle(py.code.Source(getattr(snip_class, name))) + for name in + dir(snip_class) if name.startswith("test_snippet")] + self.snippets[console] = snippets + self.htmls[console] = html % tuple([str(i) for i in snippets]) + Added: pypy/dist/pypy/translator/js/examples/console/test/test_docloader.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/js/examples/console/test/test_docloader.py Sat Mar 24 10:32:36 2007 @@ -0,0 +1,16 @@ + +import py +from pypy.tool.udir import udir +from pypy.translator.js.examples.console.docloader import LoadDoc + +def test_load_html(): + tmpdir = udir.ensure("docloader", dir=1) + help = tmpdir.ensure("one.html").write("%s") + code = tmpdir.ensure("test_snippets.py").write(str(py.code.Source(''' + class AppTest_one(object): + def test_snippet_1(self): + x = 1 + ''')) + '\n') + ld = LoadDoc(docdir=tmpdir, consoles=['one']) + assert ld.get_html('one') == "x = 1" + assert ld.get_snippet('one', 0) == 'x = 1' From fijal at codespeak.net Sat Mar 24 10:52:27 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 24 Mar 2007 10:52:27 +0100 (CET) Subject: [pypy-svn] r41226 - in pypy/dist/pypy/translator/js/examples/console: . data test Message-ID: <20070324095227.745161006E@code0.codespeak.net> Author: fijal Date: Sat Mar 24 10:52:25 2007 New Revision: 41226 Modified: pypy/dist/pypy/translator/js/examples/console/client.py pypy/dist/pypy/translator/js/examples/console/console.py pypy/dist/pypy/translator/js/examples/console/data/console.html pypy/dist/pypy/translator/js/examples/console/docloader.py pypy/dist/pypy/translator/js/examples/console/test/test_docloader.py Log: Minor improvements to the console demo, use doc files instead of inlined ones. 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 Sat Mar 24 10:52:25 2007 @@ -50,6 +50,12 @@ sessid = int(data[0]) help_msg = data[1] glob.sess_id = sessid + inp_elem = dom.document.getElementById("inp") + inp_elem.disabled = False + name_bar = dom.document.getElementById("namebar") + name_bar.style.color = "black" + name_bar.removeChild(name_bar.lastChild) + name_bar.appendChild(create_text("Python console")) dom.document.getElementById("helpcontents").innerHTML = help_msg exported_methods.refresh_empty(sessid, refresh_console) @@ -97,8 +103,8 @@ add_text(snippet) exported_methods.refresh(glob.sess_id, snippet, refresh_console) -def execute_snippet(number=3): - exported_methods.execute_snippet(number, add_snippet) +def execute_snippet(name='python', number=3): + exported_methods.execute_snippet(name, number, add_snippet) def console_onload(): #createLoggingPane(True) 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 Sat Mar 24 10:52:25 2007 @@ -10,61 +10,12 @@ from pypy.translator.js.lib.support import callback from pypy.translator.js import commproxy from pypy.translator.js.examples.console.session import Interpreter, Killed +from pypy.translator.js.examples.console.docloader import DocLoader from py.__.green.server.httpserver import GreenHTTPServer commproxy.USE_MOCHIKIT = True -SNIPPETS = [ - """from tputil import make_proxy -history = [] -def recorder(operation): - history.append(operation) - return operation.delegate() - -l = make_proxy(recorder, obj=[]) -""", - """from __pypy__ import thunk -def f(): - print 'computing...' - return 6*7 - -x = thunk(f) -""", - """from __pypy__ import taint -x = taint(6) -"""] - FUNCTION_LIST = ["load_console", "console_onload", "execute_snippet"] -HELP = {'python':"just Python, play as you like :)", - 'pypy-c': -''' -This is the PyPy standard interpreter translated to C with the following features: -
      -
    • Stackless - You can use all stackless features including - tasklets, channels, coroutines and greenlets, more information and some - examples can be found in the - PyPy stackless documentation. -
    • -
    • Transparent proxy - This is a unique PyPy interpreter feature, - which allows you to provide an application-level controller for any kind of - object. Details and snippets can be found in the - transparent proxy documentation. Example (execute): -
      %s
      -
    • -
    -''' % (SNIPPETS[0],), - 'pypy-c-thunk':'''The PyPy standard interpreter compiled to C using - the thunk object space. Example (execute): -
    %s
    - And try x. -''' % (SNIPPETS[1],), - 'pypy-c-taint':'''The PyPy standard interpreter compiled to C using - the taint object space. Example (execute): -
    %s
    - Now try hard getting to value of x :-) - ''' % (SNIPPETS[2],), - 'pypy-cli':'''The PyPy standard interpreter compiled to CLI''', - 'pyrolog-c':'''The Prolog interpreter compiled to C'''} class Ignore(Exception): pass @@ -90,11 +41,14 @@ for x in range(6): STATIC_DIR = STATIC_DIR.dirpath() STATIC_DIR = STATIC_DIR.join("compiled") +DOCDIR = STATIC_DIR.dirpath().join("pypy", "doc", "play1") +CONSOLES = ['pypy-c', 'pypy-c-thunk', 'pypy-c-taint', 'pypy-cli', 'pyrolog-c'] class Sessions(object): def __init__(self): self.sessions = {} self.updating = {} + self.docloader = DocLoader(docdir=DOCDIR, consoles=CONSOLES) def new_session(self, python="python"): if not py.path.local().sysfind(python): @@ -131,7 +85,7 @@ @callback(retval=[str]) def get_console(self, python="python"): retval = sessions.new_session(python) - return [str(retval), HELP[python]] + return [str(retval), sessions.docloader.get_html(python)] @callback(retval=[str]) def refresh(self, pid=0, to_write=""): @@ -154,8 +108,8 @@ return ["ignore"] @callback(retval=str) - def execute_snippet(self, number=3): - return SNIPPETS[int(number)] + def execute_snippet(self, name='aaa', number=3): + return sessions.docloader.get_snippet(name, int(number)) @callback() def kill_console(self, pid=0): Modified: pypy/dist/pypy/translator/js/examples/console/data/console.html ============================================================================== --- pypy/dist/pypy/translator/js/examples/console/data/console.html (original) +++ pypy/dist/pypy/translator/js/examples/console/data/console.html Sat Mar 24 10:52:25 2007 @@ -1,7 +1,7 @@ - + Console Modified: pypy/dist/pypy/translator/js/examples/console/docloader.py ============================================================================== --- pypy/dist/pypy/translator/js/examples/console/docloader.py (original) +++ pypy/dist/pypy/translator/js/examples/console/docloader.py Sat Mar 24 10:52:25 2007 @@ -5,7 +5,7 @@ import py -class LoadDoc(object): +class DocLoader(object): def __init__(self, consoles, docdir, testfile='test_snippets.py'): self.consoles = consoles self.docdir = py.path.local(docdir) Modified: pypy/dist/pypy/translator/js/examples/console/test/test_docloader.py ============================================================================== --- pypy/dist/pypy/translator/js/examples/console/test/test_docloader.py (original) +++ pypy/dist/pypy/translator/js/examples/console/test/test_docloader.py Sat Mar 24 10:52:25 2007 @@ -1,16 +1,16 @@ import py from pypy.tool.udir import udir -from pypy.translator.js.examples.console.docloader import LoadDoc +from pypy.translator.js.examples.console.docloader import DocLoader def test_load_html(): tmpdir = udir.ensure("docloader", dir=1) help = tmpdir.ensure("one.html").write("%s") - code = tmpdir.ensure("test_snippets.py").write(str(py.code.Source(''' + code = tmpdir.ensure("test_snippets2.py").write(str(py.code.Source(''' class AppTest_one(object): def test_snippet_1(self): x = 1 ''')) + '\n') - ld = LoadDoc(docdir=tmpdir, consoles=['one']) + ld = DocLoader(docdir=tmpdir, consoles=['one'], testfile='test_snippets2.py') assert ld.get_html('one') == "x = 1" assert ld.get_snippet('one', 0) == 'x = 1' From hpk at codespeak.net Sat Mar 24 12:27:26 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sat, 24 Mar 2007 12:27:26 +0100 (CET) Subject: [pypy-svn] r41229 - pypy/dist/pypy/doc Message-ID: <20070324112726.74AF010070@code0.codespeak.net> Author: hpk Date: Sat Mar 24 12:27:25 2007 New Revision: 41229 Added: pypy/dist/pypy/doc/new-architecture.txt (contents, props changed) Log: add a new draft of the architecture document (which actually contains and always contained mission/goals) see pypy-dev mail for more details. Added: pypy/dist/pypy/doc/new-architecture.txt ============================================================================== --- (empty file) +++ pypy/dist/pypy/doc/new-architecture.txt Sat Mar 24 12:27:25 2007 @@ -0,0 +1,257 @@ +================================================== +PyPy - Goals and Architecture Overview +================================================== + +.. contents:: +.. sectnum:: + +This document gives an overview of the goals and architecture of PyPy. +See `getting started`_ for a practical introduction and starting points. + +Mission statement +==================== + +We aim to provide: + +* a common translation framework for generating interpreters + and implementations of dynamic languages, supporting a clean separation + between language specification and implementation aspects. + +* a compliant and fast Python Language interpreter + enabling new advanced features without the requirement + to encode low level details into it. + +The choice of target platform as well as advanced optimisations +techniques are to become aspects of the translation process, up +to the ultimate point of *generating Just-in-Time compilers* +for dynamic language interpreters. + + +High Level Goals +============================= + +PyPy - The Translation Framework +----------------------------------------------- + +Traditionally, language interpreters are written in a target platform language +like C/Posix, Java or C#. Each such implementation fundamentally provides +a mapping from application source code to the target environment. One of +the goals of the "all-encompassing" environments, like the .NET framework +and to some extent the Java virtual machine, is to provide standardized +and higher level functionalities in order to support language implementors +for writing language implementations. + +PyPy is experimenting with a more ambitious approach. We are using a +subset of a VHLL language, called RPython, to specify languages +without many references and dependencies to lower level details, +leaving it to the translation framework to add these as translation +aspects and produce custom implementations for particular feature +and platform configurations. + +Particularly, we want to help avoiding having to write ``n * m * o`` +interpreters for ``n`` dynamic languages and ``m`` platforms +with ``o`` crucial design decisions. PyPy aims at having any +one of these parameters changeable independently from each +other: + +* ``n``: modify or replace the language we analyse and regenerate + a concrete interpreter for each target; + +* ``m``: write new translator back-ends to target new + physical and virtual platforms; + +* ``o``: tweak and optimize the translation process to produce + platform specific code based on different models and tradeoffs. + +By contrast, a standardized target environment - say .NET - +enforces ``m=1`` as far as it's concerned. This helps making ``o`` a +bit smaller by providing a higher-level base to build upon. Still, +we believe that enforcing the use of one common environment +is not necessary. PyPy's goal is to give weight to this claim - at least +as far as language implementation is concerned - showing an approach +to the ``n * m * o`` problem that does not rely on standardization. + +Particularly, we set ourselves the goal to *generate +Just-In-Time Compilers* in addition to traditional +Interpreter implementations - an area of language +implementation that is commonly considered the ultimate +in complexity. + + +PyPy - the Python Interpreter +-------------------------------------------- + +Our goal is to provide a full featured, customizable and fast Python +implementation, written in a subset of Python itself, working on and interacting +with a large variety of platforms and allowing to quickly introduce +new advanced language features. + +The architecture and abstractions of PyPy's "Python language specification" +aim to enable new implementation and optimization features that +tradtionally require pervasive changes in a language implementation +source code. + +An important aspect of implementing Python in RPython is the high level of +abstraction and compactness of the language. This allows an implementation +that is, in many respects, easier to understand and play with than the one +written in C (referred to throughout the PyPy documentation and source as +"CPython"). + +Another goal is to specify the language implementation in the form +of a number of independent modules and abstractions, with clearly defined and +automatically tested API's. This eases reuse and allows experimenting with +variations and combinations of features. + +Our Python language implementation architecture, however, also serves as a +key part for the translation framework: we re-use its bytecode evaluator +to analyse RPython programs, PyPy's implementation language for specifying +language semantics and interpretation. + + +PyPy Architecture +=========================== + +As you would expect from a project implemented using ideas from the world +of `Extreme Programming`_, the architecture of PyPy has evolved over time +and continues to evolve. Nevertheless, the high level architecture is +stable. There are two rather independent basic subsystems: the `Python +Interpreter`_ and `the Translation Framework`_. We first talk about the +Python Interpreter because the Translation framework in fact re-uses +parts of its architecture and code. + +.. _`standard interpreter`: + +The Python Interpreter +------------------------------------- + +The *Python Interpreter* is the subsystem implementing the Python language +with the following key components: + +- a bytecode compiler responsible for producing Python Code objects + +- a `bytecode evaluator`_ responsible for interpreting + Python code objects. + +- an `standard object space`_ responsible for creating, accessing and + modifying Python application level objects. + +The *bytecode evaluator* is the part that interprets the compact +bytecode format produced from user Python sources by a preprocessing +phase, the *bytecode compiler*. The bytecode compiler itself is +implemented as a chain of flexible passes (tokenizer, lexer, parser, +abstract syntax tree builder, bytecode generator). The bytecode +evaluator does its work by delegating all actual manipulation of +user objects to the *object space*. The latter can be thought of as the +library of built-in types. It defines the implementation of the user +objects, like integers and lists, as well as the operations between +them, like addition or truth-value-testing. + +This division between bytecode evaluator and object space is very +important, as it gives a lot of flexibility. It is possible to use +different `object spaces`_ to get different behaviours of the Python +objects. Using a special object space is also an important technique +for our translation process. + +.. _`bytecode evaluator`: interpreter.html +.. _`standard object space`: objspace.html#the-standard-object-space +.. _`object spaces`: objspace.html + +The Translation Process +----------------------- + +The *translation process* is implemented in four parts: + +- producing a *flow graph* representation of an RPython program source, + A combination of the `bytecode evaluator`_ and a *flow object space* + performs `abstract interpretation`_ to record the flow of objects + and execution throughout a python program into such a *flow graph*; + +- the *annotator* which performs type inference on the flow graph; + +- the *typer* which, based on the type annotations, turns the flow graph + into another representation fitting the model of the target platform; + +- the *backend* which emits code for and integrates with the target platform. + +.. _`initialization time`: +.. _`translation process in more details`: + +In order for our generic translation and type inference mechanisms to +master complexity, we restrict the dynamism of our source +RPython program, using a particularly dynamic definition of RPython_. +During initialization the source program can make unrestricted +use of Python (including metaclasses and execution of dynamically +constructed strings). However, Python code objects that we eventually +see during the production and analysis of flow graphs, must adhere +to a more static subset of Python. + +The `bytecode evaluator`_ and the Flow Object Space work through +those initialized RPython code objects. The result of this +`abstract interpretation`_ is a flow graph: yet another +representation of the source program, but one which is suitable for +applying translation and type inference techniques. The nodes of the +graph are basic blocks consisting of Object Space operations, flowing +of values, and an exitswitch to one, two or multiple links which connect +each basic block to other basic blocks. + +The flow graphs are fed as input into the Annotator. The Annotator, +given entry point types, infers the types of values that flow through +the program variables. RPython code is restricted in such a way that the +Annotator is able to infer consistent types. How much dynamism we allow in +RPython depends on, and is mostly restricted by, the Flow Object Space and +the Annotator implementation. The more we can improve this translation +phase, the more dynamism we can allow. + +The *Typer* is responsible to prepare and produce target platform specific +representations of the annotated high level RPython flowgraphs. It visits +the flowgraphs in order to transform and amend its contained operations +into specialized representations, suitable for either high level or +low level platforms. High level platforms usually have their own +garbace collectors and high level builtin types, while low level platforms +require dealing with machine level types and pointers. + +The actual target platform code is eventually emitted by +the backend through "visiting" the type-annontated flow graph +and adding platform specific integration code. + +Here is a graphical overview of the translation process (`PDF color version`_): + + .. image:: image/translation-greyscale-small.png + + +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`_. XXX reference specific reports + and provide a summary here? + +* `Getting started`_ with PyPy for a practical introduction. + +.. _`Extreme Programming`: http://www.extremeprogramming.com/ +.. _`statistics web page`: http://codespeak.net/~hpk/pypy-stat/ +.. _`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 +.. _`Compiling dynamic language implementations`: dynamic-language-translation.html +.. _`translation document`: translation.html +.. _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 + +.. _Python: http://docs.python.org/ref +.. _Psyco: http://psyco.sourceforge.net +.. _Stackless: http://stackless.com + +.. include:: _ref.txt + From hpk at codespeak.net Sat Mar 24 12:37:01 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sat, 24 Mar 2007 12:37:01 +0100 (CET) Subject: [pypy-svn] r41230 - pypy/dist/pypy/doc Message-ID: <20070324113701.8BBB910072@code0.codespeak.net> Author: hpk Date: Sat Mar 24 12:37:00 2007 New Revision: 41230 Modified: pypy/dist/pypy/doc/new-architecture.txt Log: use a bit more telling variable names for not-so-mathematically trained people Modified: pypy/dist/pypy/doc/new-architecture.txt ============================================================================== --- pypy/dist/pypy/doc/new-architecture.txt (original) +++ pypy/dist/pypy/doc/new-architecture.txt Sat Mar 24 12:37:00 2007 @@ -48,28 +48,29 @@ aspects and produce custom implementations for particular feature and platform configurations. -Particularly, we want to help avoiding having to write ``n * m * o`` -interpreters for ``n`` dynamic languages and ``m`` platforms +Particularly, we want to help avoiding having to write ``l * o * p`` +interpreters for ``l`` dynamic languages and ``p`` platforms with ``o`` crucial design decisions. PyPy aims at having any one of these parameters changeable independently from each other: -* ``n``: modify or replace the language we analyse and regenerate +* ``l``: modify or replace the language we analyse and regenerate a concrete interpreter for each target; -* ``m``: write new translator back-ends to target new - physical and virtual platforms; - * ``o``: tweak and optimize the translation process to produce platform specific code based on different models and tradeoffs. +* ``p``: write new translator back-ends to target + physical and virtual platforms; + + By contrast, a standardized target environment - say .NET - -enforces ``m=1`` as far as it's concerned. This helps making ``o`` a +enforces ``p=1`` as far as it's concerned. This helps making ``o`` a bit smaller by providing a higher-level base to build upon. Still, we believe that enforcing the use of one common environment is not necessary. PyPy's goal is to give weight to this claim - at least as far as language implementation is concerned - showing an approach -to the ``n * m * o`` problem that does not rely on standardization. +to the ``l * o * p`` problem that does not rely on standardization. Particularly, we set ourselves the goal to *generate Just-In-Time Compilers* in addition to traditional From cfbolz at codespeak.net Sat Mar 24 13:29:55 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sat, 24 Mar 2007 13:29:55 +0100 (CET) Subject: [pypy-svn] r41231 - pypy/dist/pypy/doc Message-ID: <20070324122955.53F9F10070@code0.codespeak.net> Author: cfbolz Date: Sat Mar 24 13:29:53 2007 New Revision: 41231 Modified: pypy/dist/pypy/doc/new-architecture.txt Log: mostly typo-level fixes Modified: pypy/dist/pypy/doc/new-architecture.txt ============================================================================== --- pypy/dist/pypy/doc/new-architecture.txt (original) +++ pypy/dist/pypy/doc/new-architecture.txt Sat Mar 24 13:29:53 2007 @@ -13,7 +13,7 @@ We aim to provide: -* a common translation framework for generating interpreters +* a common translation and support framework for generating interpreters and implementations of dynamic languages, supporting a clean separation between language specification and implementation aspects. @@ -58,7 +58,7 @@ a concrete interpreter for each target; * ``o``: tweak and optimize the translation process to produce - platform specific code based on different models and tradeoffs. + platform specific code based on different models and trade-offs. * ``p``: write new translator back-ends to target physical and virtual platforms; @@ -89,7 +89,7 @@ The architecture and abstractions of PyPy's "Python language specification" aim to enable new implementation and optimization features that -tradtionally require pervasive changes in a language implementation +traditionally require pervasive changes in a language implementation source code. An important aspect of implementing Python in RPython is the high level of @@ -100,7 +100,7 @@ Another goal is to specify the language implementation in the form of a number of independent modules and abstractions, with clearly defined and -automatically tested API's. This eases reuse and allows experimenting with +automatically tested APIs. This eases reuse and allows experimenting with variations and combinations of features. Our Python language implementation architecture, however, also serves as a @@ -128,7 +128,7 @@ The *Python Interpreter* is the subsystem implementing the Python language with the following key components: -- a bytecode compiler responsible for producing Python Code objects +- a bytecode compiler responsible for producing Python code objects - a `bytecode evaluator`_ responsible for interpreting Python code objects. @@ -169,7 +169,7 @@ - the *annotator* which performs type inference on the flow graph; -- the *typer* which, based on the type annotations, turns the flow graph +- the *rtyper* which, based on the type annotations, turns the flow graph into another representation fitting the model of the target platform; - the *backend* which emits code for and integrates with the target platform. @@ -212,7 +212,7 @@ require dealing with machine level types and pointers. The actual target platform code is eventually emitted by -the backend through "visiting" the type-annontated flow graph +the backend through "visiting" the type-annotated flow graph and adding platform specific integration code. Here is a graphical overview of the translation process (`PDF color version`_): From mwh at codespeak.net Sat Mar 24 15:24:04 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Sat, 24 Mar 2007 15:24:04 +0100 (CET) Subject: [pypy-svn] r41234 - pypy/dist/pypy/lib/app_test Message-ID: <20070324142404.3D5B110071@code0.codespeak.net> Author: mwh Date: Sat Mar 24 15:24:03 2007 New Revision: 41234 Modified: pypy/dist/pypy/lib/app_test/test_structseq.py Log: add a skipped, failing test that explains why cpython's test_os fails on pypy-c. shouldn't be that hard to fix, but it's work and too close to the release. 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 Sat Mar 24 15:24:03 2007 @@ -73,3 +73,8 @@ 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") + +def test_no_extra_assignments(): + x = mydata(range(100, 113)) + py.test.skip("not working yet") + py.test.raises((TypeError, AttributeError), "x.some_random_attribute = 1") From hpk at codespeak.net Sat Mar 24 15:24:12 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sat, 24 Mar 2007 15:24:12 +0100 (CET) Subject: [pypy-svn] r41235 - pypy/extradoc/planning/1.0 Message-ID: <20070324142412.6FECB10074@code0.codespeak.net> Author: hpk Date: Sat Mar 24 15:24:05 2007 New Revision: 41235 Modified: pypy/extradoc/planning/1.0/docs-refactoring.txt Log: adding play1 entry points doc refs Modified: pypy/extradoc/planning/1.0/docs-refactoring.txt ============================================================================== --- pypy/extradoc/planning/1.0/docs-refactoring.txt (original) +++ pypy/extradoc/planning/1.0/docs-refactoring.txt Sat Mar 24 15:24:05 2007 @@ -19,3 +19,11 @@ around 2200 times) ones and people expect archictecture.txt to reflect our view on the project. + +* current play1 entry points docs: + taint: objspace-proxies.html#the-taint-object-space + thunk: objspace-proxies.html#the-thunk-object-space + stackless: stackless.html + TProxies: objspspace-proxies.html#tproxy + XXX + From hpk at codespeak.net Sat Mar 24 15:29:09 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sat, 24 Mar 2007 15:29:09 +0100 (CET) Subject: [pypy-svn] r41236 - pypy/dist/pypy/doc Message-ID: <20070324142909.4837B10071@code0.codespeak.net> Author: hpk Date: Sat Mar 24 15:29:07 2007 New Revision: 41236 Modified: pypy/dist/pypy/doc/objspace-proxies.txt Log: Review Taint Space intro and reference D12 to resolve the XXX. Modified: pypy/dist/pypy/doc/objspace-proxies.txt ============================================================================== --- pypy/dist/pypy/doc/objspace-proxies.txt (original) +++ pypy/dist/pypy/doc/objspace-proxies.txt Sat Mar 24 15:29:07 2007 @@ -168,14 +168,13 @@ ---------- The Taint Object Space provides a form of security: "tainted objects", -inspired by various sources, including Perl's tainting (XXX more -references needed). +inspired by various sources, see [D12.1]_ for a more detailed discussion. The basic idea of this kind of security is not to protect against -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. +malicious code but to help with handling and boxing 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 @@ -482,7 +481,8 @@ and dictionary objects without interfering with the type system, i.e. ``type(proxied_list) is list`` holds true while still giving you full control on all operations that are performed on the -``proxied_list``. +``proxied_list``. Please see [D12.1]_ for context, +motivation and usage of transparent proxies. Example of the core mechanism ------------------------------------------- @@ -637,4 +637,7 @@ .. _`transparent.py`: ../../pypy/objspace/std/transparent.py .. _`tputil.py`: ../../pypy/lib/tputil.py +.. [D12.1] `High-Level Backends and Interpreter Feature Prototypes`, PyPy + EU-Report, 2007, http://codespeak.net/pypy/extradoc/eu-report/D12.1_H-L-Backends_and_Feature_Prototypes-2007-03-22.pdf + .. include:: _ref.txt From hpk at codespeak.net Sat Mar 24 15:53:38 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sat, 24 Mar 2007 15:53:38 +0100 (CET) Subject: [pypy-svn] r41237 - pypy/extradoc/planning/1.0 Message-ID: <20070324145338.729EB1006F@code0.codespeak.net> Author: hpk Date: Sat Mar 24 15:53:37 2007 New Revision: 41237 Modified: pypy/extradoc/planning/1.0/TODO.txt Log: some updates and additions ahead of the pypy-sync meeting Modified: pypy/extradoc/planning/1.0/TODO.txt ============================================================================== --- pypy/extradoc/planning/1.0/TODO.txt (original) +++ pypy/extradoc/planning/1.0/TODO.txt Sat Mar 24 15:53:37 2007 @@ -7,15 +7,12 @@ Note: meetings in #pypy-sync every day at 4pm (GMT+1) (weekend attendance optional :-) -published final reports: 3.1, 2.1, 10.1, 12.1, 14.2 +published final reports: 2.1, 2.3, 3.1, 10.1, 12.1, 14.2 -23 WP08 documentation and working examples integrated - release status / remaining tasks (14.5, 11.1) - dist-trunk separation (possibly restricting - permissions for release candidates) -24 (weekend) release candidates testing +24 (weekend) WP08 documentation and working examples integrated + release candidates testing 25 (weekend) release candidates testing -26 testing testing testing (9.1, 2.3) +26 testing testing testing (14.5, 11.1) 27 RELEASE (1.2-4, 13.1) 28 29 @@ -36,25 +33,25 @@ (christian looking into this currently) a bit of progress, but no feedback/interaction with DFKI/Danish yet. - - revisit entry level docs (architecture, mission, getting-started) - - (guido,hpk) review entry points from the play1 demos. - - (hpk, ...) review/refactor architecture.txt -- see docs-refactoring.txt + - revisit entry level docs (architecture/mission, getting-started) + - (hpk, mostly done) review entry points from the play1 demos. + - (hpk, DRAFT available) review/refactor architecture.txt -- see docs-refactoring.txt - - describe particularly Javascript-related demos, refine them. - (mostly done, apart from 404/500 pages and possible JIT demo) - - fix play1 issues: - - source code of web page under the button? + - fix bad terminal behaviour of translated PyPy's + (contributing to play1 quirks) + + - (fijal, NNN) play1 issues: - review/refine help (add examples where necessary) - - make nice 404 and 500 pages, also for apache - - fix linking (it gets easily confused if you click around) + - make examples execute more cleanly + - fix linking (it gets easily confused if you click around), + make correct 404 and 500 pages - discuss/do a JIT demo - (fijal) - update wp6 docs (object-optimizations.txt) and link to them from getting-started (mwh to coordinate) ropes docs added - - (guido) connect more servers to buildtool if possible + - (guido) possibly connect more servers to buildtool - stress-test/use buildtool for translation tests (multicompile) (guido_w) @@ -64,6 +61,10 @@ - include documentation/entry point for the prolog interpreter (cfbolz, maybe) + - tarball packaging and testing + + - write release announcement + NOTES AND DONE TASKS From hpk at codespeak.net Sat Mar 24 16:43:40 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sat, 24 Mar 2007 16:43:40 +0100 (CET) Subject: [pypy-svn] r41239 - pypy/extradoc/planning/1.0 Message-ID: <20070324154340.1D59B1006F@code0.codespeak.net> Author: hpk Date: Sat Mar 24 16:43:38 2007 New Revision: 41239 Modified: pypy/extradoc/planning/1.0/TODO.txt Log: updates after today's meeting, (cfbolz,arigo,pedronis,hpk) Modified: pypy/extradoc/planning/1.0/TODO.txt ============================================================================== --- pypy/extradoc/planning/1.0/TODO.txt (original) +++ pypy/extradoc/planning/1.0/TODO.txt Sat Mar 24 16:43:38 2007 @@ -9,9 +9,8 @@ published final reports: 2.1, 2.3, 3.1, 10.1, 12.1, 14.2 -24 (weekend) WP08 documentation and working examples integrated +25 (weekend) WP08 documentation and working examples integrated release candidates testing -25 (weekend) release candidates testing 26 testing testing testing (14.5, 11.1) 27 RELEASE (1.2-4, 13.1) 28 @@ -29,15 +28,16 @@ - integrate and test: - (arigo,pedronis,arre): wp08 docs & examples, getting-started + - (cfbolz) test wp09 getting-started examples: - wp09 docs, examples and code - maybe what we have is good enough? (christian looking into this currently) a bit of progress, but no feedback/interaction with DFKI/Danish yet. - - revisit entry level docs (architecture/mission, getting-started) + - (hpk) revisit entry level docs (architecture/mission, getting-started) - (hpk, mostly done) review entry points from the play1 demos. - - (hpk, DRAFT available) review/refactor architecture.txt -- see docs-refactoring.txt + - (arigo,cfbolz,pedronis) review/refactor new-architecture.txt - - fix bad terminal behaviour of translated PyPy's + - (possibly arigo) fix bad terminal behaviour of translated PyPy's (contributing to play1 quirks) - (fijal, NNN) play1 issues: @@ -61,10 +61,13 @@ - include documentation/entry point for the prolog interpreter (cfbolz, maybe) - - tarball packaging and testing + - (hpk) fix test failures of translated PyPys + relating to app_test - - write release announcement + - (pedronis) tarball packaging and testing + - (hpk, review from cfbolz and NN) + write release announcement NOTES AND DONE TASKS From xoraxax at codespeak.net Sat Mar 24 17:53:48 2007 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sat, 24 Mar 2007 17:53:48 +0100 (CET) Subject: [pypy-svn] r41242 - pypy/dist/pypy/tool Message-ID: <20070324165348.3AFB510071@code0.codespeak.net> Author: xoraxax Date: Sat Mar 24 17:53:46 2007 New Revision: 41242 Modified: pypy/dist/pypy/tool/ansi_mandelbrot.py Log: Generate the correct amount of dots for the first line. Modified: pypy/dist/pypy/tool/ansi_mandelbrot.py ============================================================================== --- pypy/dist/pypy/tool/ansi_mandelbrot.py (original) +++ pypy/dist/pypy/tool/ansi_mandelbrot.py Sat Mar 24 17:53:46 2007 @@ -62,6 +62,7 @@ self.reset_lines = cnt def generate(self): + self.reset_lines = False iy = 0 while iy < self.y: ix = 0 From xoraxax at codespeak.net Sat Mar 24 18:02:30 2007 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sat, 24 Mar 2007 18:02:30 +0100 (CET) Subject: [pypy-svn] r41243 - pypy/dist/pypy/tool Message-ID: <20070324170230.5C8E110077@code0.codespeak.net> Author: xoraxax Date: Sat Mar 24 18:02:28 2007 New Revision: 41243 Modified: pypy/dist/pypy/tool/ansi_mandelbrot.py Log: In case of zero-width terminals, use 1 as the width for the mandelbrot code. Modified: pypy/dist/pypy/tool/ansi_mandelbrot.py ============================================================================== --- pypy/dist/pypy/tool/ansi_mandelbrot.py (original) +++ pypy/dist/pypy/tool/ansi_mandelbrot.py Sat Mar 24 18:02:28 2007 @@ -110,7 +110,7 @@ self.init() def init(self): - self.width = get_terminal_width() + self.width = get_terminal_width() or 1 self.mandelbrot = Mandelbrot(width=self.width, **self.kwargs) self.mandelbrot.init() self.gen = self.mandelbrot.generate() From xoraxax at codespeak.net Sat Mar 24 18:09:30 2007 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sat, 24 Mar 2007 18:09:30 +0100 (CET) Subject: [pypy-svn] r41244 - pypy/dist/pypy/tool Message-ID: <20070324170930.780BA10077@code0.codespeak.net> Author: xoraxax Date: Sat Mar 24 18:09:29 2007 New Revision: 41244 Modified: pypy/dist/pypy/tool/ansi_mandelbrot.py pypy/dist/pypy/tool/ansi_print.py Log: Make the mandelbrot driver invocation more robust and check for isatty early. Modified: pypy/dist/pypy/tool/ansi_mandelbrot.py ============================================================================== --- pypy/dist/pypy/tool/ansi_mandelbrot.py (original) +++ pypy/dist/pypy/tool/ansi_mandelbrot.py Sat Mar 24 18:09:29 2007 @@ -110,8 +110,8 @@ self.init() def init(self): - self.width = get_terminal_width() or 1 - self.mandelbrot = Mandelbrot(width=self.width, **self.kwargs) + self.width = get_terminal_width() + self.mandelbrot = Mandelbrot(width=(self.width or 1), **self.kwargs) self.mandelbrot.init() self.gen = self.mandelbrot.generate() Modified: pypy/dist/pypy/tool/ansi_print.py ============================================================================== --- pypy/dist/pypy/tool/ansi_print.py (original) +++ pypy/dist/pypy/tool/ansi_print.py Sat Mar 24 18:09:29 2007 @@ -25,13 +25,17 @@ self.kw_to_color = self.KW_TO_COLOR.copy() self.kw_to_color.update(kw_to_color) self.file = file - self.mandelbrot_driver = Driver() + self.fancy = True + self.isatty = getattr(sys.stderr, 'isatty', lambda: False) + if self.fancy and self.isatty(): + self.mandelbrot_driver = Driver() + else: + self.mandelbrot_driver = None def __call__(self, msg): - tty = getattr(sys.stderr, 'isatty', lambda: False)() + tty = self.isatty() flush = False newline = True - fancy = True keywords = [] esc = [] for kw in msg.keywords: @@ -51,7 +55,7 @@ return elif 'dot' in keywords: if tty: - if fancy: + if self.fancy: if not AnsiLog.wrote_dot: self.mandelbrot_driver.reset() self.mandelbrot_driver.dot() From arigo at codespeak.net Sat Mar 24 18:11:25 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 24 Mar 2007 18:11:25 +0100 (CET) Subject: [pypy-svn] r41245 - pypy/dist/pypy/translator/goal/test2 Message-ID: <20070324171125.1FD8F10077@code0.codespeak.net> Author: arigo Date: Sat Mar 24 18:11:23 2007 New Revision: 41245 Modified: pypy/dist/pypy/translator/goal/test2/test_app_main.py Log: Add a test, which can only pass when we have 'readline'. Skipped for now. Modified: pypy/dist/pypy/translator/goal/test2/test_app_main.py ============================================================================== --- pypy/dist/pypy/translator/goal/test2/test_app_main.py (original) +++ pypy/dist/pypy/translator/goal/test2/test_app_main.py Sat Mar 24 18:11:23 2007 @@ -260,6 +260,16 @@ data = os.read(pipe.stdout.fileno(), 1024) assert data.startswith('Python') + def test_paste_several_lines_doesnt_mess_prompt(self): + py.test.skip("this can only work if readline is enabled") + child = self.spawn([]) + child.expect('>>> ') + child.sendline('if 1:\n print 42\n') + child.expect('... print 42') + child.expect('... ') + child.expect('42') + child.expect('>>> ') + class TestNonInteractive: From arigo at codespeak.net Sat Mar 24 18:24:32 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 24 Mar 2007 18:24:32 +0100 (CET) Subject: [pypy-svn] r41246 - in pypy/dist/pypy: config module/readline Message-ID: <20070324172432.9E3AF10070@code0.codespeak.net> Author: arigo Date: Sat Mar 24 18:24:29 2007 New Revision: 41246 Modified: pypy/dist/pypy/config/pypyoption.py pypy/dist/pypy/module/readline/__init__.py Log: Populate the readline module with stubs that just issue a warning. Enable it by default in --allworkingmodules, to get the nice line editing features for pypy-c. Modified: pypy/dist/pypy/config/pypyoption.py ============================================================================== --- pypy/dist/pypy/config/pypyoption.py (original) +++ pypy/dist/pypy/config/pypyoption.py Sat Mar 24 18:24:29 2007 @@ -24,7 +24,7 @@ working_modules = default_modules.copy() working_modules.update(dict.fromkeys( ["rsocket", "unicodedata", "mmap", "fcntl", "rctime", "select", - "crypt", "signal", "dyngram", + "crypt", "signal", "dyngram", "readline", ] )) Modified: pypy/dist/pypy/module/readline/__init__.py ============================================================================== --- pypy/dist/pypy/module/readline/__init__.py (original) +++ pypy/dist/pypy/module/readline/__init__.py Sat Mar 24 18:24:29 2007 @@ -19,4 +19,27 @@ } appleveldefs = { + 'parse_and_bind': 'app_stub.stub', + 'get_line_buffer': 'app_stub.stub_str', + 'insert_text': 'app_stub.stub', + 'read_init_file': 'app_stub.stub', + 'read_history_file': 'app_stub.stub', + 'write_history_file': 'app_stub.stub', + 'clear_history': 'app_stub.stub', + 'get_history_length': 'app_stub.stub_int', + 'set_history_length': 'app_stub.stub', + 'get_current_history_length': 'app_stub.stub_int', + 'get_history_item': 'app_stub.stub_str', + 'remove_history_item': 'app_stub.stub', + 'replace_history_item': 'app_stub.stub', + 'redisplay': 'app_stub.stub', + 'set_startup_hook': 'app_stub.stub', + 'set_pre_input_hook': 'app_stub.stub', + 'set_completer': 'app_stub.stub', + 'get_completer': 'app_stub.stub', + 'get_begidx': 'app_stub.stub_int', + 'get_endidx': 'app_stub.stub_int', + 'set_completer_delims': 'app_stub.stub', + 'get_completer_delims': 'app_stub.stub_str', + 'add_history': 'app_stub.stub', } From arigo at codespeak.net Sat Mar 24 18:26:11 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 24 Mar 2007 18:26:11 +0100 (CET) Subject: [pypy-svn] r41247 - pypy/dist/pypy/module/readline Message-ID: <20070324172611.6076E10070@code0.codespeak.net> Author: arigo Date: Sat Mar 24 18:26:09 2007 New Revision: 41247 Added: pypy/dist/pypy/module/readline/app_stub.py (contents, props changed) Log: Forgot to add this file... Added: pypy/dist/pypy/module/readline/app_stub.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/readline/app_stub.py Sat Mar 24 18:26:09 2007 @@ -0,0 +1,13 @@ +# NOT_RPYTHON + +def stub(*args, **kwds): + import warnings + warnings.warn("the 'readline' module is only a stub so far") + +def stub_str(*args, **kwds): + stub() + return '' + +def stub_int(*args, **kwds): + stub() + return 0 From pedronis at codespeak.net Sat Mar 24 18:34:17 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 24 Mar 2007 18:34:17 +0100 (CET) Subject: [pypy-svn] r41248 - pypy/dist/lib-python/modified-2.4.1 Message-ID: <20070324173417.7C37510070@code0.codespeak.net> Author: pedronis Date: Sat Mar 24 18:34:16 2007 New Revision: 41248 Modified: pypy/dist/lib-python/modified-2.4.1/site.py Log: obscure hack to avoid forcing all our mixed modules at py.py load time. Modified: pypy/dist/lib-python/modified-2.4.1/site.py ============================================================================== --- pypy/dist/lib-python/modified-2.4.1/site.py (original) +++ pypy/dist/lib-python/modified-2.4.1/site.py Sat Mar 24 18:34:16 2007 @@ -70,7 +70,10 @@ """Set all module' __file__ attribute to an absolute path""" for m in sys.modules.values(): try: - m.__file__ = os.path.abspath(m.__file__) + prev = m.__file__ + new = os.path.abspath(m.__file__) + if prev != new: + m.__file__ = new except AttributeError: continue From arigo at codespeak.net Sat Mar 24 18:52:30 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 24 Mar 2007 18:52:30 +0100 (CET) Subject: [pypy-svn] r41249 - pypy/dist/pypy/config Message-ID: <20070324175230.73CA21006F@code0.codespeak.net> Author: arigo Date: Sat Mar 24 18:52:28 2007 New Revision: 41249 Modified: pypy/dist/pypy/config/pypyoption.py Log: No clue any more why r35266 turned off geninterp for the thunk. It looks like a mistake while converting the option system to the new config format. Modified: pypy/dist/pypy/config/pypyoption.py ============================================================================== --- pypy/dist/pypy/config/pypyoption.py (original) +++ pypy/dist/pypy/config/pypyoption.py Sat Mar 24 18:52:28 2007 @@ -38,7 +38,6 @@ ["std", "flow", "logic", "thunk", "cpy", "dump", "taint"], "std", requires = { - "thunk": [("objspace.geninterp", False)], "logic": [("objspace.geninterp", False), ("objspace.usemodules._stackless", True), ("objspace.usemodules.cclp", True), From arigo at codespeak.net Sat Mar 24 19:11:42 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 24 Mar 2007 19:11:42 +0100 (CET) Subject: [pypy-svn] r41250 - in pypy/dist/pypy: config module/cclp Message-ID: <20070324181142.78FBB10071@code0.codespeak.net> Author: arigo Date: Sat Mar 24 19:11:41 2007 New Revision: 41250 Modified: pypy/dist/pypy/config/pypyoption.py pypy/dist/pypy/module/cclp/app.py Log: Trying to re-enable geninterp with the logic objspace.... Modified: pypy/dist/pypy/config/pypyoption.py ============================================================================== --- pypy/dist/pypy/config/pypyoption.py (original) +++ pypy/dist/pypy/config/pypyoption.py Sat Mar 24 19:11:41 2007 @@ -38,7 +38,7 @@ ["std", "flow", "logic", "thunk", "cpy", "dump", "taint"], "std", requires = { - "logic": [("objspace.geninterp", False), + "logic": [#("objspace.geninterp", False), ("objspace.usemodules._stackless", True), ("objspace.usemodules.cclp", True), ("translation.gc", 'framework'), Modified: pypy/dist/pypy/module/cclp/app.py ============================================================================== --- pypy/dist/pypy/module/cclp/app.py (original) +++ pypy/dist/pypy/module/cclp/app.py Sat Mar 24 19:11:41 2007 @@ -1,3 +1,5 @@ +# NOT_RPYTHON + from cclp import _make_expression def make_expression(variables, formula): From hpk at codespeak.net Sat Mar 24 19:16:58 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sat, 24 Mar 2007 19:16:58 +0100 (CET) Subject: [pypy-svn] r41251 - pypy/dist/pypy/lib/app_test Message-ID: <20070324181658.E8F0F10071@code0.codespeak.net> Author: hpk Date: Sat Mar 24 19:16:58 2007 New Revision: 41251 Removed: pypy/dist/pypy/lib/app_test/test_exceptions_extra.py Modified: pypy/dist/pypy/lib/app_test/test_exception_extra.py Log: merge two files with one exception test each Modified: pypy/dist/pypy/lib/app_test/test_exception_extra.py ============================================================================== --- pypy/dist/pypy/lib/app_test/test_exception_extra.py (original) +++ pypy/dist/pypy/lib/app_test/test_exception_extra.py Sat Mar 24 19:16:58 2007 @@ -1,7 +1,6 @@ -from pypy.lib import _exceptions as ex - -def test_environmenterror_repr(): +def app_test_environmenterror_repr(): + import exceptions as ex e = ex.EnvironmentError("hello") assert str(e) == "hello" e = ex.EnvironmentError(1, "hello") @@ -9,3 +8,6 @@ e = ex.EnvironmentError(1, "hello", "world") assert str(e) == "[Errno 1] hello: world" +def app_test_import(): + import exceptions + assert exceptions.SyntaxError is SyntaxError From hpk at codespeak.net Sat Mar 24 19:29:58 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sat, 24 Mar 2007 19:29:58 +0100 (CET) Subject: [pypy-svn] r41253 - pypy/dist/pypy/lib/app_test Message-ID: <20070324182958.0738510071@code0.codespeak.net> Author: hpk Date: Sat Mar 24 19:29:57 2007 New Revision: 41253 Modified: pypy/dist/pypy/lib/app_test/sample_aop_code.py pypy/dist/pypy/lib/app_test/test_aop.py Log: avoid writing to current directories, cleanup test setup Modified: pypy/dist/pypy/lib/app_test/sample_aop_code.py ============================================================================== --- pypy/dist/pypy/lib/app_test/sample_aop_code.py (original) +++ pypy/dist/pypy/lib/app_test/sample_aop_code.py Sat Mar 24 19:29:57 2007 @@ -1,3 +1,5 @@ +import py + code = """ def foo(b, c): ''' @@ -41,18 +43,15 @@ def _make_filename(name): if not name.endswith('.py'): name += ".py" - return osp.join(osp.dirname(__file__), name) + base = py.test.ensuretemp("aop_test") + return base.join(name) -def write_module(name): - clean_module(name) - f = open(_make_filename(name), 'w') +def _write_module(name): + f = _make_filename(name).open('w') f.write(code) f.close() -def clean_module(name): - name = _make_filename(name) - if os.path.isfile(name): - os.unlink(name) - if os.path.isfile(name+'c'): - os.unlink(name+'c') - +def import_(name): + _write_module(name) + p = _make_filename(name) + return p.pyimport() Modified: pypy/dist/pypy/lib/app_test/test_aop.py ============================================================================== --- pypy/dist/pypy/lib/app_test/test_aop.py (original) +++ pypy/dist/pypy/lib/app_test/test_aop.py Sat Mar 24 19:29:57 2007 @@ -151,7 +151,6 @@ from aop import PointCut, Aspect, before from app_test import sample_aop_code __aop__._clear_all() - sample_aop_code.write_module('aop_before_execution') class AspectTest: __metaclass__ = Aspect @@ -168,20 +167,19 @@ assert __aop__.advices == [(aspect, AspectTest.advice_before_execution)] assert not aspect.executed - from app_test import aop_before_execution + aop_before_execution = sample_aop_code.import_('aop_before_execution') + assert aspect.executed == 0 answ = aop_before_execution.foo(1,2) assert aspect.executed == 1 assert aspect.argnames == ['b', 'c'] assert aspect.flags == 0 assert answ == 47 - sample_aop_code.clean_module('aop_before_execution') def test_aspect_before_meth_execution(self): from aop import PointCut, Aspect, before from app_test import sample_aop_code __aop__._clear_all() - sample_aop_code.write_module('aop_before_meth_execution') class AspectTest: __metaclass__ = Aspect @@ -198,20 +196,19 @@ assert __aop__.advices == [(aspect, AspectTest.advice_before_meth_execution)] assert not aspect.executed - from app_test import aop_before_meth_execution + aop_before_meth_execution = sample_aop_code.import_( + 'aop_before_meth_execution') assert aspect.executed == 0 answ = aop_before_meth_execution.truc() assert aspect.executed == 1 assert aspect.argnames == ['self', 'b'] assert aspect.flags == 0 assert answ == 7 - sample_aop_code.clean_module('aop_before_meth_execution') def test_simple_aspect_after_execution(self): from aop import PointCut, Aspect, after from app_test import sample_aop_code __aop__._clear_all() - sample_aop_code.write_module('aop_after_execution') class AspectTest: __metaclass__ = Aspect def __init__(self): @@ -224,18 +221,16 @@ aspect = AspectTest() assert __aop__.advices == [(aspect, AspectTest.advice_after_execution)] assert not aspect.executed - from app_test import aop_after_execution + aop_after_execution = sample_aop_code.import_('aop_after_execution') assert aspect.executed == 0 answ = aop_after_execution.foo(1,2) assert aspect.executed == 1 assert answ == 47 - sample_aop_code.clean_module('aop_after_execution') def test_simple_aspect_around_execution(self): from aop import PointCut, Aspect, around from app_test import sample_aop_code __aop__._clear_all() - sample_aop_code.write_module('aop_around_execution') class AspectTest: __metaclass__ = Aspect def __init__(self): @@ -253,7 +248,7 @@ return tjp.result() aspect = AspectTest() - from app_test import aop_around_execution + aop_around_execution = sample_aop_code.import_('aop_around_execution') assert aspect.executed_before == 0 assert aspect.executed_after == 0 answ = aop_around_execution.foo(1,2) @@ -261,7 +256,6 @@ assert aspect.executed_after == 1 assert aspect.result == 47 assert answ == 47 - sample_aop_code.clean_module('aop_around_execution') class AppTestWeavingAtCall(object): @@ -269,7 +263,6 @@ from aop import PointCut, Aspect, before from app_test import sample_aop_code __aop__._clear_all() - sample_aop_code.write_module('aop_before_call') class AspectTest: __metaclass__ = Aspect @@ -287,18 +280,16 @@ assert __aop__.advices == [(aspect, AspectTest.advice_before_call)] assert not aspect.executed - from app_test import aop_before_call + aop_before_call = sample_aop_code.import_('aop_before_call') assert aspect.executed == 0 answ = aop_before_call.foo(1,2) assert aspect.executed == 1 assert answ == 47 - sample_aop_code.clean_module('aop_before_call') def test_simple_aspect_after_call(self): from aop import PointCut, Aspect, after from app_test import sample_aop_code __aop__._clear_all() - sample_aop_code.write_module('aop_after_call') class AspectTest: __metaclass__ = Aspect @@ -320,20 +311,18 @@ assert __aop__.advices == [(aspect, AspectTest.advice_after_call)] assert not aspect.executed - from app_test import aop_after_call + aop_after_call = sample_aop_code.import_('aop_after_call') assert not aspect.executed answ = aop_after_call.foo(1,2) assert aspect.executed assert answ == 47 assert aspect.result == 42 - sample_aop_code.clean_module('aop_after_call') def test_simple_aspect_around_call(self): from aop import PointCut, Aspect, around from app_test import sample_aop_code __aop__._clear_all() - sample_aop_code.write_module('aop_around_call') class AspectTest: __metaclass__ = Aspect def __init__(self): @@ -351,7 +340,7 @@ return tjp.result() aspect = AspectTest() - from app_test import aop_around_call + aop_around_call = sample_aop_code.import_('aop_around_call') assert aspect.executed_before == 0 assert aspect.executed_after == 0 answ = aop_around_call.foo(1,2) @@ -359,8 +348,6 @@ assert aspect.executed_after == 1 assert aspect.result == 42 assert answ == 47 - sample_aop_code.clean_module('aop_around_call') - class AppTestWeavingIntroduce(object): @@ -368,7 +355,6 @@ from aop import PointCut, Aspect, introduce from app_test import sample_aop_code __aop__._clear_all() - sample_aop_code.write_module('aop_introduce') class AspectTest: __metaclass__ = Aspect @introduce(PointCut(klass='Mumble')) @@ -376,7 +362,7 @@ return it.p*a+b aspect = AspectTest() - from app_test import aop_introduce + aop_introduce = sample_aop_code.import_('aop_introduce') c = aop_introduce.Mumble(2) try: answ = c.newmethod(1,3) From mwh at codespeak.net Sat Mar 24 19:38:01 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Sat, 24 Mar 2007 19:38:01 +0100 (CET) Subject: [pypy-svn] r41254 - pypy/dist/pypy/translator Message-ID: <20070324183801.0F35F10071@code0.codespeak.net> Author: mwh Date: Sat Mar 24 19:38:00 2007 New Revision: 41254 Modified: pypy/dist/pypy/translator/driver.py Log: don't run raisingop2direct_call in task_prehannotatebackendopt_lltype two reason: 1) the replacement for int_mul_ovf uses floats which neither jit backend supports yet and 2) it's just a bad idea Modified: pypy/dist/pypy/translator/driver.py ============================================================================== --- pypy/dist/pypy/translator/driver.py (original) +++ pypy/dist/pypy/translator/driver.py Sat Mar 24 19:38:00 2007 @@ -340,6 +340,7 @@ inline_threshold=0, merge_if_blocks=True, constfold=True, + raisingop2direct_call=False, remove_asserts=True) # task_prehannotatebackendopt_lltype = taskdef( From mwh at codespeak.net Sat Mar 24 20:06:38 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Sat, 24 Mar 2007 20:06:38 +0100 (CET) Subject: [pypy-svn] r41256 - in pypy/dist/pypy/translator/llvm: . test Message-ID: <20070324190638.1938B10074@code0.codespeak.net> Author: mwh Date: Sat Mar 24 20:06:36 2007 New Revision: 41256 Modified: pypy/dist/pypy/translator/llvm/opwriter.py pypy/dist/pypy/translator/llvm/test/test_genllvm.py Log: some kind of llvm support for call_boehm_gc_alloc. Modified: pypy/dist/pypy/translator/llvm/opwriter.py ============================================================================== --- pypy/dist/pypy/translator/llvm/opwriter.py (original) +++ pypy/dist/pypy/translator/llvm/opwriter.py Sat Mar 24 20:06:36 2007 @@ -329,6 +329,11 @@ else: raise NotImplementedError + def call_boehm_gc_alloc(self, opr): + word = self.db.get_machine_word() + self.codewriter.call(opr.retref, 'sbyte*', '%pypy_malloc', + [word], [opr.argrefs[0]]) + def getfield(self, opr): op = opr.op if opr.rettype != "void": Modified: pypy/dist/pypy/translator/llvm/test/test_genllvm.py ============================================================================== --- pypy/dist/pypy/translator/llvm/test/test_genllvm.py (original) +++ pypy/dist/pypy/translator/llvm/test/test_genllvm.py Sat Mar 24 20:06:36 2007 @@ -459,3 +459,15 @@ f = compile_function(func, [int]) res = f(4) assert res == 16 + +def test_call_boehm_gc_alloc(): + from pypy.rpython.lltypesystem import llmemory, lltype + from pypy.rpython.lltypesystem.lloperation import llop + def f(s): + a = llop.call_boehm_gc_alloc(llmemory.Address, 100) + a.signed[0] = s + a.signed[1] = s+2 + return a.signed[0]*a.signed[1] + f = compile_function(f, [int]) + res = f(4) + assert res == 4*(4+2) From arigo at codespeak.net Sat Mar 24 20:27:08 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 24 Mar 2007 20:27:08 +0100 (CET) Subject: [pypy-svn] r41257 - in pypy/dist/pypy/lib: app_test test2 Message-ID: <20070324192708.DE2A210070@code0.codespeak.net> Author: arigo Date: Sat Mar 24 20:27:08 2007 New Revision: 41257 Added: pypy/dist/pypy/lib/test2/test_aop.py - copied, changed from r41256, pypy/dist/pypy/lib/app_test/test_aop.py Removed: pypy/dist/pypy/lib/app_test/test_aop.py Log: (pedronis, arigo) - move test_aop to its proper location. - be careful in test_aop to not leave the object space in a broken state. This caused a lot of debugging time in a "pypy-c py.test -A" run... From arigo at codespeak.net Sat Mar 24 20:38:37 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 24 Mar 2007 20:38:37 +0100 (CET) Subject: [pypy-svn] r41258 - pypy/dist/pypy Message-ID: <20070324193837.DD7EB10074@code0.codespeak.net> Author: arigo Date: Sat Mar 24 20:38:35 2007 New Revision: 41258 Modified: pypy/dist/pypy/conftest.py Log: (pedronis, arigo) Add a helper to build a space without caching it. Forgotten in the previous check-in. Modified: pypy/dist/pypy/conftest.py ============================================================================== --- pypy/dist/pypy/conftest.py (original) +++ pypy/dist/pypy/conftest.py Sat Mar 24 20:38:35 2007 @@ -43,26 +43,32 @@ py.test.skip("cannot runappdirect test: " "%s objspace required" % (name,)) return TinyObjSpace(**kwds) - try: - space = make_objspace(config) - except OperationError, e: - check_keyboard_interrupt(e) - if option.verbose: - import traceback - traceback.print_exc() - py.test.fail("fatal: cannot initialize objspace: %r" % - (config.objspace.name,)) + space = maketestobjspace(config) _SPACECACHE[key] = space - space.setitem(space.builtin.w_dict, space.wrap('AssertionError'), - appsupport.build_pytest_assertion(space)) - space.setitem(space.builtin.w_dict, space.wrap('raises'), - space.wrap(appsupport.app_raises)) - space.setitem(space.builtin.w_dict, space.wrap('skip'), - space.wrap(appsupport.app_skip)) - space.raises_w = appsupport.raises_w.__get__(space) - space.eq_w = appsupport.eq_w.__get__(space) return space +def maketestobjspace(config=None): + if config is None: + config = make_config(option) + try: + space = make_objspace(config) + except OperationError, e: + check_keyboard_interrupt(e) + if option.verbose: + import traceback + traceback.print_exc() + py.test.fail("fatal: cannot initialize objspace: %r" % + (config.objspace.name,)) + space.setitem(space.builtin.w_dict, space.wrap('AssertionError'), + appsupport.build_pytest_assertion(space)) + space.setitem(space.builtin.w_dict, space.wrap('raises'), + space.wrap(appsupport.app_raises)) + space.setitem(space.builtin.w_dict, space.wrap('skip'), + space.wrap(appsupport.app_skip)) + space.raises_w = appsupport.raises_w.__get__(space) + space.eq_w = appsupport.eq_w.__get__(space) + return space + class TinyObjSpace(object): def __init__(self, **kwds): import sys From hpk at codespeak.net Sat Mar 24 20:58:24 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sat, 24 Mar 2007 20:58:24 +0100 (CET) Subject: [pypy-svn] r41259 - in pypy/dist/pypy/lib: app_test test2 Message-ID: <20070324195824.0F58810074@code0.codespeak.net> Author: hpk Date: Sat Mar 24 20:58:23 2007 New Revision: 41259 Added: pypy/dist/pypy/lib/test2/sample_aop_code.py - copied, changed from r41258, pypy/dist/pypy/lib/app_test/sample_aop_code.py Removed: pypy/dist/pypy/lib/app_test/sample_aop_code.py Modified: pypy/dist/pypy/lib/test2/test_aop.py Log: moving sample_aop_code to test2 and reverting 41253 because importing the py lib with aop global tweaking around breaks. Trying now with teardown_module to cleanup any leftover generated modules because i don't want to change much within the aop test code. Modified: pypy/dist/pypy/lib/test2/test_aop.py ============================================================================== --- pypy/dist/pypy/lib/test2/test_aop.py (original) +++ pypy/dist/pypy/lib/test2/test_aop.py Sat Mar 24 20:58:23 2007 @@ -1,7 +1,12 @@ import py from pypy.conftest import option, maketestobjspace - +def teardown_module(mod): + mydir = py.magic.autopath().dirpath() + for p in mydir.listdir(): + if p.purebasename.startswith("aop_"): + p.remove() + class BaseAppTest(object): def setup_class(cls): if option.runappdirect: @@ -160,8 +165,9 @@ class AppTestWeavingAtExecution(BaseAppTest): def test_simple_aspect_before_execution(self): from aop import PointCut, Aspect, before - from app_test import sample_aop_code + import sample_aop_code __aop__._clear_all() + sample_aop_code.write_module('aop_before_execution') class AspectTest: __metaclass__ = Aspect @@ -178,19 +184,20 @@ assert __aop__.advices == [(aspect, AspectTest.advice_before_execution)] assert not aspect.executed - aop_before_execution = sample_aop_code.import_('aop_before_execution') - + import aop_before_execution assert aspect.executed == 0 answ = aop_before_execution.foo(1,2) assert aspect.executed == 1 assert aspect.argnames == ['b', 'c'] assert aspect.flags == 0 assert answ == 47 + sample_aop_code.clean_module('aop_before_execution') def test_aspect_before_meth_execution(self): from aop import PointCut, Aspect, before - from app_test import sample_aop_code + import sample_aop_code __aop__._clear_all() + sample_aop_code.write_module('aop_before_meth_execution') class AspectTest: __metaclass__ = Aspect @@ -207,19 +214,20 @@ assert __aop__.advices == [(aspect, AspectTest.advice_before_meth_execution)] assert not aspect.executed - aop_before_meth_execution = sample_aop_code.import_( - 'aop_before_meth_execution') + import aop_before_meth_execution assert aspect.executed == 0 answ = aop_before_meth_execution.truc() assert aspect.executed == 1 assert aspect.argnames == ['self', 'b'] assert aspect.flags == 0 assert answ == 7 + sample_aop_code.clean_module('aop_before_meth_execution') def test_simple_aspect_after_execution(self): from aop import PointCut, Aspect, after - from app_test import sample_aop_code + import sample_aop_code __aop__._clear_all() + sample_aop_code.write_module('aop_after_execution') class AspectTest: __metaclass__ = Aspect def __init__(self): @@ -232,16 +240,18 @@ aspect = AspectTest() assert __aop__.advices == [(aspect, AspectTest.advice_after_execution)] assert not aspect.executed - aop_after_execution = sample_aop_code.import_('aop_after_execution') + import aop_after_execution assert aspect.executed == 0 answ = aop_after_execution.foo(1,2) assert aspect.executed == 1 assert answ == 47 + sample_aop_code.clean_module('aop_after_execution') def test_simple_aspect_around_execution(self): from aop import PointCut, Aspect, around - from app_test import sample_aop_code + import sample_aop_code __aop__._clear_all() + sample_aop_code.write_module('aop_around_execution') class AspectTest: __metaclass__ = Aspect def __init__(self): @@ -259,7 +269,7 @@ return tjp.result() aspect = AspectTest() - aop_around_execution = sample_aop_code.import_('aop_around_execution') + import aop_around_execution assert aspect.executed_before == 0 assert aspect.executed_after == 0 answ = aop_around_execution.foo(1,2) @@ -267,13 +277,15 @@ assert aspect.executed_after == 1 assert aspect.result == 47 assert answ == 47 + sample_aop_code.clean_module('aop_around_execution') class AppTestWeavingAtCall(BaseAppTest): def test_simple_aspect_before_call(self): from aop import PointCut, Aspect, before - from app_test import sample_aop_code + import sample_aop_code __aop__._clear_all() + sample_aop_code.write_module('aop_before_call') class AspectTest: __metaclass__ = Aspect @@ -291,16 +303,18 @@ assert __aop__.advices == [(aspect, AspectTest.advice_before_call)] assert not aspect.executed - aop_before_call = sample_aop_code.import_('aop_before_call') + import aop_before_call assert aspect.executed == 0 answ = aop_before_call.foo(1,2) assert aspect.executed == 1 assert answ == 47 + sample_aop_code.clean_module('aop_before_call') def test_simple_aspect_after_call(self): from aop import PointCut, Aspect, after - from app_test import sample_aop_code + import sample_aop_code __aop__._clear_all() + sample_aop_code.write_module('aop_after_call') class AspectTest: __metaclass__ = Aspect @@ -322,18 +336,20 @@ assert __aop__.advices == [(aspect, AspectTest.advice_after_call)] assert not aspect.executed - aop_after_call = sample_aop_code.import_('aop_after_call') + import aop_after_call assert not aspect.executed answ = aop_after_call.foo(1,2) assert aspect.executed assert answ == 47 assert aspect.result == 42 + sample_aop_code.clean_module('aop_after_call') def test_simple_aspect_around_call(self): from aop import PointCut, Aspect, around - from app_test import sample_aop_code + import sample_aop_code __aop__._clear_all() + sample_aop_code.write_module('aop_around_call') class AspectTest: __metaclass__ = Aspect def __init__(self): @@ -351,7 +367,7 @@ return tjp.result() aspect = AspectTest() - aop_around_call = sample_aop_code.import_('aop_around_call') + import aop_around_call assert aspect.executed_before == 0 assert aspect.executed_after == 0 answ = aop_around_call.foo(1,2) @@ -359,13 +375,15 @@ assert aspect.executed_after == 1 assert aspect.result == 42 assert answ == 47 + sample_aop_code.clean_module('aop_around_call') class AppTestWeavingIntroduce(BaseAppTest): def test_introduce(self): from aop import PointCut, Aspect, introduce - from app_test import sample_aop_code + import sample_aop_code __aop__._clear_all() + sample_aop_code.write_module('aop_introduce') class AspectTest: __metaclass__ = Aspect @introduce(PointCut(klass='Mumble')) @@ -373,7 +391,7 @@ return it.p*a+b aspect = AspectTest() - aop_introduce = sample_aop_code.import_('aop_introduce') + import aop_introduce c = aop_introduce.Mumble(2) try: answ = c.newmethod(1,3) From hpk at codespeak.net Sat Mar 24 21:07:05 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sat, 24 Mar 2007 21:07:05 +0100 (CET) Subject: [pypy-svn] r41260 - pypy/dist/pypy/doc Message-ID: <20070324200705.9AF8210072@code0.codespeak.net> Author: hpk Date: Sat Mar 24 21:07:00 2007 New Revision: 41260 Modified: pypy/dist/pypy/doc/getting-started.txt Log: a warning note before showing the aop example Modified: pypy/dist/pypy/doc/getting-started.txt ============================================================================== --- pypy/dist/pypy/doc/getting-started.txt (original) +++ pypy/dist/pypy/doc/getting-started.txt Sat Mar 24 21:07:00 2007 @@ -327,9 +327,10 @@ Aspect Oriented Programming +++++++++++++++++++++++++++ -PyPy provides some `Aspect Oriented Programming` facilities. - -Try it out:: +PyPy provides experimental `Aspect Oriented Programming` facilities +(warning: using the 'aop' module may modify compiler state and +badly affect subsequent execution of compiled code and imports) +Here is an example:: cd pypy python bin/py.py From arigo at codespeak.net Sat Mar 24 21:12:51 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 24 Mar 2007 21:12:51 +0100 (CET) Subject: [pypy-svn] r41261 - pypy/dist/pypy/config/test Message-ID: <20070324201251.C9A7010072@code0.codespeak.net> Author: arigo Date: Sat Mar 24 21:12:49 2007 New Revision: 41261 Modified: pypy/dist/pypy/config/test/test_pypyoption.py Log: Kill this test. There is no other example of an option True by default, but turned False by a space option :-( Modified: pypy/dist/pypy/config/test/test_pypyoption.py ============================================================================== --- pypy/dist/pypy/config/test/test_pypyoption.py (original) +++ pypy/dist/pypy/config/test/test_pypyoption.py Sat Mar 24 21:12:49 2007 @@ -16,11 +16,6 @@ conf.objspace.std.withprebuiltint = True py.test.raises(ValueError, "conf.objspace.std.withsmallint = True") -def test_objspace_incopatibilities(): - conf = get_pypy_config() - conf.objspace.name = "logic" - assert not conf.objspace.geninterp - def test_stacklessgc_required(): conf = get_pypy_config() conf.translation.gc = "stacklessgc" From pedronis at codespeak.net Sat Mar 24 21:14:36 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 24 Mar 2007 21:14:36 +0100 (CET) Subject: [pypy-svn] r41262 - pypy/dist/pypy/config Message-ID: <20070324201436.C498F10072@code0.codespeak.net> Author: pedronis Date: Sat Mar 24 21:14:35 2007 New Revision: 41262 Modified: pypy/dist/pypy/config/pypyoption.py Log: currently disabling geninterp doesn't really work. e.g import array; array.__dict__ explodes in a circulary dependency. Remove the corresponding command line options Modified: pypy/dist/pypy/config/pypyoption.py ============================================================================== --- pypy/dist/pypy/config/pypyoption.py (original) +++ pypy/dist/pypy/config/pypyoption.py Sat Mar 24 21:14:35 2007 @@ -88,6 +88,7 @@ negation=False), BoolOption("geninterp", "specify whether geninterp should be used", + cmdline=None, default=True), BoolOption("logbytecodes", @@ -251,9 +252,9 @@ ## ("translation.backend", "llvm")], ## cmdline="--llvm-faassen", negation=False), ]), - BoolOption("lowmem", "Try to use less memory during translation", - default=False, cmdline="--lowmem", - requires=[("objspace.geninterp", False)]), + #BoolOption("lowmem", "Try to use less memory during translation", + # default=False, cmdline="--lowmem", + # requires=[("objspace.geninterp", False)]), ]) From santagada at codespeak.net Sat Mar 24 21:52:10 2007 From: santagada at codespeak.net (santagada at codespeak.net) Date: Sat, 24 Mar 2007 21:52:10 +0100 (CET) Subject: [pypy-svn] r41263 - in pypy/dist/pypy/lang/js: . test Message-ID: <20070324205210.C432E10070@code0.codespeak.net> Author: santagada Date: Sat Mar 24 21:52:09 2007 New Revision: 41263 Modified: pypy/dist/pypy/lang/js/interpreter.py pypy/dist/pypy/lang/js/jsobj.py pypy/dist/pypy/lang/js/operations.py pypy/dist/pypy/lang/js/test/test_interp.py Log: simple problem with function recursion fixed, and removing of DEBUG flag (I should create a new way to see tracing information) Modified: pypy/dist/pypy/lang/js/interpreter.py ============================================================================== --- pypy/dist/pypy/lang/js/interpreter.py (original) +++ pypy/dist/pypy/lang/js/interpreter.py Sat Mar 24 21:52:09 2007 @@ -58,8 +58,6 @@ functioncode = "__anon__ = function (%s) {%s}"%(fargs, fbody) else: functioncode = "__anon__ = function () {}" - if DEBUG: - print functioncode return evaljs(ctx, [W_String(functioncode),], this) def parseIntjs(ctx, args, this): @@ -180,6 +178,10 @@ w_Global.Put('version', W_Builtin(versionjs)) #Number + w_Date = W_Object(Class="Number") + w_Global.Put('Date', w_Date) + + #Number w_Number = W_Builtin(numberjs, Class="Number") w_Number.Put('NaN', W_Number(NaN)) w_Number.Put('POSITIVE_INFINITY', W_Number(Infinity)) Modified: pypy/dist/pypy/lang/js/jsobj.py ============================================================================== --- pypy/dist/pypy/lang/js/jsobj.py (original) +++ pypy/dist/pypy/lang/js/jsobj.py Sat Mar 24 21:52:09 2007 @@ -1,7 +1,6 @@ # encoding: utf-8 from pypy.rlib.rarithmetic import r_uint, intmask -DEBUG = False class SeePage(NotImplementedError): pass @@ -75,8 +74,6 @@ raise NotImplementedError def PutValue(self, w, ctx): - if DEBUG: - print self, w.ToString(), w.__class__, ctx raise NotImplementedError def Call(self, ctx, args=[], this=None): @@ -260,8 +257,6 @@ self.callfuncbi = callfuncbi def Call(self, ctx, args=[], this = None): - if DEBUG: - print args return self.callfuncbi(ctx, args, this) def type(self): @@ -282,6 +277,9 @@ W_PrimitiveObject.__init__(self, Class='Activation') del self.propdict["prototype"] + def __repr__(self): + return str(self.propdict) + def arraycallbi(ctx, args, this): return W_Array() @@ -336,8 +334,6 @@ class W_Boolean(W_Primitive): def __init__(self, boolval): - if DEBUG: - print boolval self.boolval = bool(boolval) def ToString(self): @@ -364,7 +360,7 @@ self.strval = strval def __str__(self): - return self.strval + return self.strval+"W" def ToString(self): return self.strval @@ -380,6 +376,9 @@ def __init__(self, floatval): self.floatval = float(floatval) + def __str__(self): + return str(self.floatval)+"W" + def ToString(self): if str(self.floatval) == str(NaN): return 'NaN' @@ -446,6 +445,9 @@ self.debug = False self.property = Property('',w_Undefined) #Attribute flags for new vars + def __str__(self): + return ""%(str(self.scope)) + def assign(self, name, value): """ assign to property name, creating it if it doesn't exist @@ -483,14 +485,14 @@ def function_context(scope, activation, this=None): ctx = ExecutionContext() - ctx.scope = scope + ctx.scope = scope[:] ctx.push_object(activation) if this is None: ctx.this = ctx.get_global() else: ctx.this = this - ctx.property = Property('', w_Undefined, dd=True) + print ctx return ctx def eval_context(calling_context): @@ -512,9 +514,6 @@ exception = "ReferenceError: %s is not defined"%(self.property_name,) raise ThrowException(W_String(exception)) - if DEBUG: - print "ref base: %s, prop: %s, getresult: %s"%(self.base, - self.property_name, 'self.base.Get(self.property_name)') return self.base.Get(self.property_name) def PutValue(self, w, ctx): Modified: pypy/dist/pypy/lang/js/operations.py ============================================================================== --- pypy/dist/pypy/lang/js/operations.py (original) +++ pypy/dist/pypy/lang/js/operations.py Sat Mar 24 21:52:09 2007 @@ -53,8 +53,6 @@ """ Used for expression evaluation """ - if DEBUG: - print self raise NotImplementedError def execute(self, ctx): @@ -100,8 +98,6 @@ def eval(self, ctx): s2 = self.left.eval(ctx).GetValue() s4 = self.right.eval(ctx).GetValue() - if DEBUG: - print "bincomp, op1 and op2 ", s2, s4 return self.decision(ctx, s2, s4) def decision(self, ctx, op1, op2): @@ -111,8 +107,6 @@ 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): @@ -231,8 +225,6 @@ opcode = 'CALL' def eval(self, ctx): - if DEBUG: - print "calling", self.left, self.right r1 = self.left.eval(ctx) r2 = self.right.eval(ctx) r3 = r1.GetValue() @@ -387,8 +379,6 @@ def decision(self, ctx, op1, op2): s5 = ARC(ctx, op1, op2) - if DEBUG: - print ">= ARC result:", s5 if s5 in (-1, 1): return W_Boolean(False) else: @@ -399,8 +389,6 @@ def decision(self, ctx, op1, op2): s5 = ARC(ctx, op2, op1) - if DEBUG: - print "> ARC result:", s5 if s5 == -1: return W_Boolean(False) else: @@ -666,10 +654,10 @@ class BinaryNumberOp(BinaryOp): def eval(self, ctx): nleft = self.left.eval(ctx).GetValue().ToPrimitive(ctx, 'Number') + print "context now is:" + print ctx nright = self.right.eval(ctx).GetValue().ToPrimitive(ctx, 'Number') result = self.mathop(ctx, nleft, nright) - if DEBUG: - print self.left, nleft, self.opcode, self.right, nright, '=', result return result class Plus(BinaryNumberOp): @@ -814,8 +802,6 @@ def eval(self, ctx): w_obj = W_Object() for prop in self.list: - if DEBUG: - print prop.left name = prop.left.value w_expr = prop.right.eval(ctx).GetValue() w_obj.Put(name, w_expr) 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 Mar 24 21:52:09 2007 @@ -43,7 +43,7 @@ for codepiece in code: js_int.run(load_source(codepiece)) except ThrowException, excpt: - l.append("uncaught exception: "+str(excpt.exception)) + l.append("uncaught exception: "+str(excpt.exception.ToString())) print l, assval assert l == assval @@ -510,18 +510,11 @@ """, ['0', '1']) def test_recursive_call(self): - py.test.skip() - self.assert_prints(""" - function f(x) { if (x == 0) { return 1; } else { return f(x-1)*x; }} - print(f(3)) - """, ['6',]) - - def test_recursive_call(self): - py.test.skip() + #py.test.skip() self.assert_prints(""" function f(x) { if (x == 0) { return 1; } else { return f(x-1)*x; }} - print(f(3)) - """, ['6',]) + print(f(1)) + """, ['1',]) def test_function_prototype(self): py.test.skip() @@ -529,11 +522,6 @@ function foo() {}; foo.prototype.bar = function() {} """, ['',]) - def test_function_prototype(self): - py.test.skip() - self.assert_prints(""" - function foo() {}; foo.prototype.bar = function() {} - """, ['',]) def test_function_this(self): py.test.skip() From arigo at codespeak.net Sat Mar 24 22:20:17 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 24 Mar 2007 22:20:17 +0100 (CET) Subject: [pypy-svn] r41264 - pypy/dist/pypy/doc Message-ID: <20070324212017.D955F10071@code0.codespeak.net> Author: arigo Date: Sat Mar 24 22:20:16 2007 New Revision: 41264 Modified: pypy/dist/pypy/doc/new-architecture.txt Log: Typo-ish kind of fixes. Modified: pypy/dist/pypy/doc/new-architecture.txt ============================================================================== --- pypy/dist/pypy/doc/new-architecture.txt (original) +++ pypy/dist/pypy/doc/new-architecture.txt Sat Mar 24 22:20:16 2007 @@ -21,7 +21,7 @@ enabling new advanced features without the requirement to encode low level details into it. -The choice of target platform as well as advanced optimisations +The choice of target platform as well as advanced optimizations techniques are to become aspects of the translation process, up to the ultimate point of *generating Just-in-Time compilers* for dynamic language interpreters. @@ -58,10 +58,10 @@ a concrete interpreter for each target; * ``o``: tweak and optimize the translation process to produce - platform specific code based on different models and trade-offs. + platform specific code based on different models and trade-offs; * ``p``: write new translator back-ends to target - physical and virtual platforms; + physical and virtual platforms. By contrast, a standardized target environment - say .NET - @@ -121,6 +121,7 @@ parts of its architecture and code. .. _`standard interpreter`: +.. _`python interpreter`: The Python Interpreter ------------------------------------- @@ -141,7 +142,7 @@ phase, the *bytecode compiler*. The bytecode compiler itself is implemented as a chain of flexible passes (tokenizer, lexer, parser, abstract syntax tree builder, bytecode generator). The bytecode -evaluator does its work by delegating all actual manipulation of +evaluator does its work by delegating all actual manipulations of user objects to the *object space*. The latter can be thought of as the library of built-in types. It defines the implementation of the user objects, like integers and lists, as well as the operations between @@ -156,20 +157,24 @@ .. _`bytecode evaluator`: interpreter.html .. _`standard object space`: objspace.html#the-standard-object-space .. _`object spaces`: objspace.html +.. _`flow object space`: objspace.html#the-flow-object-space + +.. _`the translation framework`: The Translation Process ----------------------- The *translation process* is implemented in four parts: -- producing a *flow graph* representation of an RPython program source, - A combination of the `bytecode evaluator`_ and a *flow object space* +- the production of a *flow graph* representation of an RPython program + source, function by function. + A combination of the `bytecode evaluator`_ and a `flow object space`_ performs `abstract interpretation`_ to record the flow of objects - and execution throughout a python program into such a *flow graph*; + and execution throughout a Python program into such a *flow graph*; -- the *annotator* which performs type inference on the flow graph; +- the *annotator*, which performs type inference on the family of flow graphs; -- the *rtyper* which, based on the type annotations, turns the flow graph +- the *rtyper*, which - based on the type annotations - turns the flow graph into another representation fitting the model of the target platform; - the *backend* which emits code for and integrates with the target platform. @@ -177,18 +182,18 @@ .. _`initialization time`: .. _`translation process in more details`: -In order for our generic translation and type inference mechanisms to -master complexity, we restrict the dynamism of our source -RPython program, using a particularly dynamic definition of RPython_. +In order to limit the complexity of our generic translation and type +inference mechanisms, we restrict the dynamism of our source +RPython program. RPython_ is still defined in a particularly dynamic. During initialization the source program can make unrestricted use of Python (including metaclasses and execution of dynamically -constructed strings). However, Python code objects that we eventually +constructed strings). However, the Python code objects that we eventually see during the production and analysis of flow graphs, must adhere to a more static subset of Python. -The `bytecode evaluator`_ and the Flow Object Space work through +The `bytecode evaluator`_ and the `Flow Object Space`_ work through those initialized RPython code objects. The result of this -`abstract interpretation`_ is a flow graph: yet another +`abstract interpretation`_ is a flow graph (one per function): yet another representation of the source program, but one which is suitable for applying translation and type inference techniques. The nodes of the graph are basic blocks consisting of Object Space operations, flowing @@ -197,19 +202,24 @@ The flow graphs are fed as input into the Annotator. The Annotator, given entry point types, infers the types of values that flow through -the program variables. RPython code is restricted in such a way that the +the variables of the entire program. +RPython code is restricted in such a way that the Annotator is able to infer consistent types. How much dynamism we allow in RPython depends on, and is mostly restricted by, the Flow Object Space and the Annotator implementation. The more we can improve this translation phase, the more dynamism we can allow. -The *Typer* is responsible to prepare and produce target platform specific +The *RTyper* is responsible for the preparation and production of target +platform specific representations of the annotated high level RPython flowgraphs. It visits -the flowgraphs in order to transform and amend its contained operations -into specialized representations, suitable for either high level or -low level platforms. High level platforms usually have their own +the flow graphs in order to transform and amend the operations it contains. +After this pass the operations in the flow graphs are suitable for the +target platform. High level platforms (e.g. object-oriented virtual machines) +usually have their own garbace collectors and high level builtin types, while low level platforms -require dealing with machine level types and pointers. +(e.g. C-like environments) +require dealing with machine level types and pointers; the RTyper can +produce flow graphs containing operations suited for either kind of platform. The actual target platform code is eventually emitted by the backend through "visiting" the type-annotated flow graph From mwh at codespeak.net Sun Mar 25 11:28:46 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Sun, 25 Mar 2007 11:28:46 +0200 (CEST) Subject: [pypy-svn] r41269 - pypy/dist/pypy/translator/llvm Message-ID: <20070325092846.9971310080@code0.codespeak.net> Author: mwh Date: Sun Mar 25 11:28:45 2007 New Revision: 41269 Modified: pypy/dist/pypy/translator/llvm/opwriter.py Log: a stub defintion for debug_fatalerror (discards the message). lets pypy-llvm-jit build. Modified: pypy/dist/pypy/translator/llvm/opwriter.py ============================================================================== --- pypy/dist/pypy/translator/llvm/opwriter.py (original) +++ pypy/dist/pypy/translator/llvm/opwriter.py Sun Mar 25 11:28:45 2007 @@ -565,6 +565,10 @@ def debug_print(self, opr): pass # XXX + def debug_fatalerror(self, opr): + # XXX message? + self.codewriter.call(None, "void", "%abort", [], []) + def hint(self, opr): self.same_as(opr) From mwh at codespeak.net Sun Mar 25 11:42:22 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Sun, 25 Mar 2007 11:42:22 +0200 (CEST) Subject: [pypy-svn] r41270 - pypy/dist/pypy/doc/image Message-ID: <20070325094222.427DE10080@code0.codespeak.net> Author: mwh Date: Sun Mar 25 11:42:20 2007 New Revision: 41270 Modified: pypy/dist/pypy/doc/image/compat-matrix.png pypy/dist/pypy/doc/image/compat-matrix.sxc Log: update compat matrix to record that llvm/jit now works. improved the formatting slightly, and did the conversion to png on OS X, so the fonts look a little different (better, probably). Modified: pypy/dist/pypy/doc/image/compat-matrix.png ============================================================================== Binary files. No diff available. Modified: pypy/dist/pypy/doc/image/compat-matrix.sxc ============================================================================== Binary files. No diff available. From mwh at codespeak.net Sun Mar 25 13:28:13 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Sun, 25 Mar 2007 13:28:13 +0200 (CEST) Subject: [pypy-svn] r41273 - pypy/dist/pypy/doc/image Message-ID: <20070325112813.C59511007E@code0.codespeak.net> Author: mwh Date: Sun Mar 25 13:28:12 2007 New Revision: 41273 Modified: pypy/dist/pypy/doc/image/compat-matrix.png pypy/dist/pypy/doc/image/compat-matrix.sxc Log: updates to logic object space compatibilities Modified: pypy/dist/pypy/doc/image/compat-matrix.png ============================================================================== Binary files. No diff available. Modified: pypy/dist/pypy/doc/image/compat-matrix.sxc ============================================================================== Binary files. No diff available. From arigo at codespeak.net Sun Mar 25 14:53:57 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 25 Mar 2007 14:53:57 +0200 (CEST) Subject: [pypy-svn] r41276 - pypy/dist/pypy/doc Message-ID: <20070325125357.6422A1007E@code0.codespeak.net> Author: arigo Date: Sun Mar 25 14:53:55 2007 New Revision: 41276 Modified: pypy/dist/pypy/doc/jit.txt Log: (pedronis, arigo) Bring the first part of this document up-to-date. Modified: pypy/dist/pypy/doc/jit.txt ============================================================================== --- pypy/dist/pypy/doc/jit.txt (original) +++ pypy/dist/pypy/doc/jit.txt Sun Mar 25 14:53:55 2007 @@ -10,37 +10,29 @@ 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. +A foreword of warning about the JIT of PyPy as of March 2007: single +functions doing integer arithmetic get great speed-ups; about anything +else will be a bit slower with the JIT than without. We are working +on this - you can even expect quick progress, because it is mostly a +matter of adding a few careful hints in the source code of the Python +interpreter of PyPy. + +By construction, the JIT is supposed to work correctly on absolutely any +kind of Python code: generators, nested scopes, ``exec`` statements, +``sys._getframe().f_back.f_back.f_locals``, etc. (the latter is an +example of expression that Psyco_ cannot emulate correctly). However, +there are a couple of known issues for now (see Caveats_). 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 +So far there is little point in trying the JIT on anything else than +arithmetic-intensive functions (unless you want to help find bugs). For +small examples, 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. @@ -49,29 +41,20 @@ 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 + this problem to some extent. The PPC backend has at least one known + bug left. 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%). +* The remaining work is to continue the necessary adjustments of the + PyPy interpreter source code so that the timeshifter can process more + of it. At the moment, the timeshifter sees the interpreter's main + dispatch loop, integer arithmetic, and a bit of function call logic. + This means that the produced JIT can remove the bytecode + interpretation overhead and do a good job with integer arithmetic, but + cannot optimize at all the manipulations of any other type of objects. .. _LLVM: http://llvm.org/ @@ -83,9 +66,7 @@ ./translate.py --jit targetpypystandalone -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!** +Please read the Status_ section above first. This will produce the C code for a version pypy-c that includes both a regular interpreter and an automatically generated JIT compiler. This @@ -93,6 +74,16 @@ expect this interpreter to be a bit slower than the one found in a pypy-c compiled without JIT. +In addition to ``--jit``, you can also pass the normal options to +``translate.py`` to compile different flavors of PyPy with a JIT. See +the `compatibility matrix`_ for the combinations known to be working +right now. (The combination of the JIT with the thunk or taint object +spaces probably works too, but we don't expect it to generate good code +before we drop a few extra hints in the source code of the object +spaces.) + +.. _`compatibility matrix`: image/compat-matrix.png + Usage ===== @@ -109,6 +100,15 @@ # machine code already generated, no more jitting occurs here 40 +A few examples of this kind can be found in `demo/jit/`_. The script +`demo/jit/f1.py`_ shows a function that becomes seriously faster with +the JIT - only 10% to 20% slower than what ``gcc -O0`` produces from the +obvious equivalent C code, a result similar to Psyco. Although the JIT +generation process is well-tested, we only have a few tests directly for +the final ``pypy-c``. Try:: + + pypy-c test_all.py module/pypyjit/test/test_pypy_c.py -A --nomagic + 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 @@ -117,7 +117,8 @@ 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 +a disassembly. It should be easy to port to OS/X. 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 @@ -126,7 +127,7 @@ Caveats ------- -When running JIT'ed code, the tracing hooks are not invoked. This +When running JIT'ed code, the bytecode tracing hook is 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. From arigo at codespeak.net Sun Mar 25 14:56:25 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 25 Mar 2007 14:56:25 +0200 (CEST) Subject: [pypy-svn] r41277 - pypy/dist/pypy/doc/config Message-ID: <20070325125625.82A3B1007E@code0.codespeak.net> Author: arigo Date: Sun Mar 25 14:56:18 2007 New Revision: 41277 Removed: pypy/dist/pypy/doc/config/objspace.lowmem.txt Log: Remove for now. From arigo at codespeak.net Sun Mar 25 15:11:47 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 25 Mar 2007 15:11:47 +0200 (CEST) Subject: [pypy-svn] r41279 - pypy/dist/pypy/lib/test2 Message-ID: <20070325131147.04A381007E@code0.codespeak.net> Author: arigo Date: Sun Mar 25 15:11:45 2007 New Revision: 41279 Modified: pypy/dist/pypy/lib/test2/sample_aop_code.py pypy/dist/pypy/lib/test2/test_aop.py Log: Fix test_aop to work even when the current working directory is not the one containing the test file. Create the temp files in the usession directory. Modified: pypy/dist/pypy/lib/test2/sample_aop_code.py ============================================================================== --- pypy/dist/pypy/lib/test2/sample_aop_code.py (original) +++ pypy/dist/pypy/lib/test2/sample_aop_code.py Sun Mar 25 15:11:45 2007 @@ -35,24 +35,16 @@ print 'truc', r, 'expected 7' return r """ -import os +import os, sys import os.path as osp def _make_filename(name): + dir = sys.path[0] # see setup_class() if not name.endswith('.py'): name += ".py" - return osp.join(osp.dirname(__file__), name) + return osp.join(dir, name) def write_module(name): - clean_module(name) f = open(_make_filename(name), 'w') f.write(code) f.close() - -def clean_module(name): - name = _make_filename(name) - if os.path.isfile(name): - os.unlink(name) - if os.path.isfile(name+'c'): - os.unlink(name+'c') - Modified: pypy/dist/pypy/lib/test2/test_aop.py ============================================================================== --- pypy/dist/pypy/lib/test2/test_aop.py (original) +++ pypy/dist/pypy/lib/test2/test_aop.py Sun Mar 25 15:11:45 2007 @@ -1,20 +1,27 @@ import py from pypy.conftest import option, maketestobjspace +from pypy.tool.udir import udir + + +def setup_module(mod): + if option.runappdirect: + py.test.skip("messes up the internal state of the compiler") + # we NEED a fresh space, otherwise the messed-up compiler might + # show up for the other test files and then we get extremely + # confused (speaking from experience here) + space = maketestobjspace() + mod.space = space + p = udir.join('test_aop') + p.ensure(dir=1) + # Note that sample_aop_code.py expects the temp dir to be in sys.path[0]. + space.call_method(space.sys.get('path'), 'insert', + space.wrap(0), + space.wrap(str(p))) + -def teardown_module(mod): - mydir = py.magic.autopath().dirpath() - for p in mydir.listdir(): - if p.purebasename.startswith("aop_"): - p.remove() - class BaseAppTest(object): def setup_class(cls): - if option.runappdirect: - py.test.skip("messes up the internal state of the compiler") - # we NEED a fresh space, otherwise the messed-up compiler might - # show up for the other test files and then we get extremely - # confused (speaking from experience here) - cls.space = maketestobjspace() + cls.space = space class AppTestAOPGeneral(BaseAppTest): @@ -165,7 +172,7 @@ class AppTestWeavingAtExecution(BaseAppTest): def test_simple_aspect_before_execution(self): from aop import PointCut, Aspect, before - import sample_aop_code + from test2 import sample_aop_code __aop__._clear_all() sample_aop_code.write_module('aop_before_execution') @@ -191,11 +198,10 @@ assert aspect.argnames == ['b', 'c'] assert aspect.flags == 0 assert answ == 47 - sample_aop_code.clean_module('aop_before_execution') def test_aspect_before_meth_execution(self): from aop import PointCut, Aspect, before - import sample_aop_code + from test2 import sample_aop_code __aop__._clear_all() sample_aop_code.write_module('aop_before_meth_execution') @@ -221,11 +227,10 @@ assert aspect.argnames == ['self', 'b'] assert aspect.flags == 0 assert answ == 7 - sample_aop_code.clean_module('aop_before_meth_execution') def test_simple_aspect_after_execution(self): from aop import PointCut, Aspect, after - import sample_aop_code + from test2 import sample_aop_code __aop__._clear_all() sample_aop_code.write_module('aop_after_execution') class AspectTest: @@ -245,11 +250,10 @@ answ = aop_after_execution.foo(1,2) assert aspect.executed == 1 assert answ == 47 - sample_aop_code.clean_module('aop_after_execution') def test_simple_aspect_around_execution(self): from aop import PointCut, Aspect, around - import sample_aop_code + from test2 import sample_aop_code __aop__._clear_all() sample_aop_code.write_module('aop_around_execution') class AspectTest: @@ -277,13 +281,12 @@ assert aspect.executed_after == 1 assert aspect.result == 47 assert answ == 47 - sample_aop_code.clean_module('aop_around_execution') class AppTestWeavingAtCall(BaseAppTest): def test_simple_aspect_before_call(self): from aop import PointCut, Aspect, before - import sample_aop_code + from test2 import sample_aop_code __aop__._clear_all() sample_aop_code.write_module('aop_before_call') @@ -308,11 +311,10 @@ answ = aop_before_call.foo(1,2) assert aspect.executed == 1 assert answ == 47 - sample_aop_code.clean_module('aop_before_call') def test_simple_aspect_after_call(self): from aop import PointCut, Aspect, after - import sample_aop_code + from test2 import sample_aop_code __aop__._clear_all() sample_aop_code.write_module('aop_after_call') @@ -342,12 +344,11 @@ assert aspect.executed assert answ == 47 assert aspect.result == 42 - sample_aop_code.clean_module('aop_after_call') def test_simple_aspect_around_call(self): from aop import PointCut, Aspect, around - import sample_aop_code + from test2 import sample_aop_code __aop__._clear_all() sample_aop_code.write_module('aop_around_call') class AspectTest: @@ -375,13 +376,12 @@ assert aspect.executed_after == 1 assert aspect.result == 42 assert answ == 47 - sample_aop_code.clean_module('aop_around_call') class AppTestWeavingIntroduce(BaseAppTest): def test_introduce(self): from aop import PointCut, Aspect, introduce - import sample_aop_code + from test2 import sample_aop_code __aop__._clear_all() sample_aop_code.write_module('aop_introduce') class AspectTest: From cfbolz at codespeak.net Sun Mar 25 15:24:58 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sun, 25 Mar 2007 15:24:58 +0200 (CEST) Subject: [pypy-svn] r41281 - pypy/dist/pypy/objspace/std Message-ID: <20070325132458.4A9D91007E@code0.codespeak.net> Author: cfbolz Date: Sun Mar 25 15:24:57 2007 New Revision: 41281 Modified: pypy/dist/pypy/objspace/std/dictobject.py Log: fix a couple of "demoting ..." warnings Modified: pypy/dist/pypy/objspace/std/dictobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/dictobject.py (original) +++ pypy/dist/pypy/objspace/std/dictobject.py Sun Mar 25 15:24:57 2007 @@ -239,7 +239,12 @@ w_self.len = len(content) w_self.pos = 0 w_self.setup_iterator() + + def setup_iterator(w_self): + raise NotImplementedError("abstract base class") + def next_entry(w_self): + raise NotImplementedError("abstract base class") registerimplementation(W_DictIterObject) From arigo at codespeak.net Sun Mar 25 16:12:32 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 25 Mar 2007 16:12:32 +0200 (CEST) Subject: [pypy-svn] r41285 - in pypy/dist/pypy/doc: . discussion Message-ID: <20070325141232.886D01007E@code0.codespeak.net> Author: arigo Date: Sun Mar 25 16:12:31 2007 New Revision: 41285 Added: pypy/dist/pypy/doc/discussion/jit-draft.txt - copied, changed from r41283, pypy/dist/pypy/doc/jit.txt Modified: pypy/dist/pypy/doc/_ref.txt pypy/dist/pypy/doc/jit.txt Log: Split jit.txt in two: the old unreadable content is now in jit-draft.txt. Modified: pypy/dist/pypy/doc/_ref.txt ============================================================================== --- pypy/dist/pypy/doc/_ref.txt (original) +++ pypy/dist/pypy/doc/_ref.txt Sun Mar 25 16:12:31 2007 @@ -1,4 +1,6 @@ .. _`demo/`: ../../demo +.. _`demo/jit/`: ../../demo/jit +.. _`demo/jit/f1.py`: ../../demo/jit/f1.py .. _`demo/pickle_coroutine.py`: ../../demo/pickle_coroutine.py .. _`lib-python/`: ../../lib-python .. _`lib-python/2.4.1/dis.py`: ../../lib-python/2.4.1/dis.py @@ -58,8 +60,7 @@ .. _`pypy/module/readline`: ../../pypy/module/readline .. _`objspace/`: .. _`pypy/objspace`: ../../pypy/objspace -.. _`objspace/cpy/`: -.. _`pypy/objspace/cpy`: ../../pypy/objspace/cpy +.. _`objspace/cpy/`: ../../pypy/objspace/cpy .. _`objspace/dump.py`: ../../pypy/objspace/dump.py .. _`objspace/flow/`: ../../pypy/objspace/flow .. _`objspace/logic.py`: ../../pypy/objspace/logic.py Modified: pypy/dist/pypy/doc/jit.txt ============================================================================== --- pypy/dist/pypy/doc/jit.txt (original) +++ pypy/dist/pypy/doc/jit.txt Sun Mar 25 16:12:31 2007 @@ -45,7 +45,7 @@ bug left. 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 +* The *timeshifter*, which produces the JIT frontend, is able to handle rather incredibly tricky situations successfully. * The remaining work is to continue the necessary adjustments of the @@ -144,16 +144,38 @@ ------------------------------------------------------------------------ - JIT Compiler Generation - Technical Section + Make your own JIT compiler ------------------------------------------------------------------------ - Introduction -============= +============ + +The central idea of the PyPy JIT is to be *completely independent from +the Python language*. We did not write down a JIT compiler by hand. +Instead, we generate it anew during each translation of pypy-c. + +This means that the same technique works out of the box for any other +language for which we have an interpreter written in RPython. The +technique works on interpreters of any size, from tiny to PyPy. + +Aside from the obvious advantage, it means that we can show all the +basic ideas of the technique on a tiny interpreter. The fact that we +have done the same on the whole of PyPy shows that the approach scales +well. So we will follow in the sequel the example of a tiny interpreter +and insert a JIT compiler into it during translation. + +A tiny interpreter +================== -.. BODY -.. Interpreters to compilers, psyco parallel... + + +------------------------------------------------------------------------ + JIT Compiler Generation - Theory +------------------------------------------------------------------------ + +Introduction +============ One the of the central goals of the PyPy project is to automatically produce a Just in Time Compiler from the interpreter, with as little @@ -171,23 +193,23 @@ the project. Transforming an interpreter into a compiler involves constructing a so -called generating extension, which takes input programs to the -interpreter, and produces what would be the output of partial -evaluating the interpreter with the input data left variable and the -input program being fixed. The generating extension is essentially +called *generating extension*, which takes input programs to the +interpreter, and produces what would be the output of partially +evaluating the interpreter, with the input program fixed and the input +data left as a variable. The generating extension is essentially capable of compiling the input programs. Generating extensions can be produced by self-applying partial evaluators, but this approach may lead to not optimal results or be not scalable -(XXX expand this argument) +(XXX expand this argument). For PyPy, our approach aims at producing the generating extension more directly from the analysed interpreter in the form of a forest of flow graphs. We call such process *timeshifting*. -To be able to achieve this, gathering binding time information is -crucial, this means for an input program distinguishing values in the -data-flow that are compile-time bound and immutable at run-time, +To be able to achieve this, gathering *binding time* information is +crucial. This means distinguishing values in the data-flow of the +interpreter which are compile-time bound and immutable at run-time, versus respectively runtime values. Currently we base the binding time computation on propagating the @@ -202,26 +224,35 @@ code. What is really desired is not a generating extension doing static compilation, but one capable of dynamic compilation, exploiting runtime information in its result. Compilation should be able to -suspend and resume letting the produced code run to collect run-time -information (for example language-level types) to be used to generate -code optimised for the effective run-time behaviour of the program. +suspend, let the produced code run to collect run-time information +(for example language-level types), and then resume with this extra +information. This allow it to generate code optimised for the effective +run-time behaviour of the program. -Inspired by Psyco, which in some sense is such a specialising -generating extension for Python, but hand-written, we added support +Inspired by Psyco, which is in some sense a hand-written generating +extension for Python, we added support for so-called *promotion* to our framework for producing generating extensions. -Simply put, promotion on a value stops compilation when encountered, -when the same point is reached at run-time compilation is restarted -and the current run-time value is used and propagated as a compile-time -value. Concretely the promotion expands into a switch to choose based -on the run-time value one of the possible specialised code paths, plus -a default case to compile further specialised paths. This can be also -thought as a generalisation of polymorphic inline caches (XXX reference). +Simply put, promotion on a value stops compilation and waits until the +runtime reaches this point. When it does, the actual runtime value is +promoted into a compile-time constant, and compilation resumes with this +extra information. Concretely, the promotion expands into a switch in +the generated code. The switch contains one case for each runtime value +encountered so far, to chose which of the specialized code paths the +runtime execution should follow. The switch initially contains no case +at all, but only a fall-back path. The fall-back invokes the compiler +with the newly seen runtime value. The compiler produces the new +specialized code path. It then patches the switch to add this new case, +so that the next time the same value is encountered at runtime, the +execution can directly jump to the correct specialized code path. +This can also be thought of as a generalisation of polymorphic inline +caches (XXX reference). -Terminology ----------------------------------- + +Partial Evaluation +================== Partial evaluation is the process of evaluating a function, say ``f(x, y)``, with only partial information about the value of its arguments, @@ -271,8 +302,7 @@ * *Translation time*: during the normal translation of an RPython program like PyPy, we perform binding-time analysis and off-line specialization. This produces a new set of functions (``f1(x)`` in - our running example) which are linked with the rest of the program, as - described in Timeshifting_. + our running example) which are linked with the rest of the program. * *Compile time*: during the execution of the program, when a new value for ``x`` is found, ``f1(x)`` is invoked. All the computations @@ -291,783 +321,15 @@ * *Red* variables contain values that are not known until run-time - e.g. ``y``. -.. _`hint annotator`: - -Binding-time analysis -========================================= -PyPy performs binding-time analysis of the source RPython_ program after -it has been turned to `low-level graphs`_, i.e. at the level at which -operations manipulate `pointer-and-structures-like objects`_. - -The binding-time analyzer of our translation tool-chain is based on the -same type inference engine that is used on the source RPython program, -the annotator_. In this mode, it is called the *hint-annotator*; it -operates over input graphs that are already low-level instead of -RPython-level, and propagates annotations that do not track types but -value dependencies and manually-provided binding time hints. - -Hints ----------------------------------- - -Our goal in designing our approach to binding-time analysis was to -minimize the number of explicit hints that the user must provide in the -source of the RPython program. This minimalism was not pushed to -extremes, though, to keep the hint-annotator reasonably simple. - -The driving idea was that hints should be need-oriented. In a program -like an interpreter, there are a few clear places where it would be -beneficial for a given value to be known at compile-time, i.e. green. -This is where we require the hints to be added. - -The normal process of the hint-annotator is to propagate the binding -time (i.e. color) of the variables using the following kind of rules: - -* For a foldable operation (i.e. one without side effect and which - depends only on its argument values), if all arguments are green, - then the result can be green too. - -* Non-foldable operations always produce a red result. - -* At join points, where multiple possible values (depending on control - flow) are meeting into a fresh variable, if any incoming value comes - from a red variable, the result is red. Otherwise, the color of the - result might be green. We do not make it eagerly green, because of - the control flow dependency: the residual function is basically a - constant-folded copy of the source function, so it might retain some - of the same control flow. The value that needs to be stored in the - fresh join variable thus depends on which branches are taken in the - residual graph. - -The hint-annotator assumes that all variables are red by default (with -the exception of constants, which are always green). It then propagates -annotations that record dependency information. When encountering the -user-provided hints, the dependency information is used to make some -variables green. (Technically, the color itself is not part of the -annotations propagated by the annotator.) All hints are in the form of -an operation ``hint(v1, someflag=True)`` which semantically just returns -its first argument unmodified. The three kinds of hints that are useful -in practice are: - -``v2 = hint(v1, concrete=True)`` - This is interpreted by the hint-annotator as a request for both - ``v1`` and ``v2`` to be green. It is used in places where the - programmer considers the knowledge of the value to be essential. - This hint has a *global* effect on the binding times: it means that - not only ``v1`` but all the values that ``v1`` depends on - - recursively - are forced to be green. Typically, it can only be - applied on values that directly depend on some input arguments, - making these input arguments green. The hint-annotator complains if - the dependencies of ``v1`` include a value that cannot be green, - like a value read out of a field out of a non-immutable structure. - - The color of the result ``v2`` is green as well. Unlike ``v1``, - all further operations involving ``v2`` are checked to not meet - any red variable (i.e. ``v2`` color is eagerly and recursively - propagated, while ``v1`` is only green and may be involved in - further operations that will produce red results). - -``v2 = hint(v1, promote=True)`` - This hint is a *local* request for ``v2`` to be green. Unlike the - previous hint, this one has no effect on the color of ``v1`` (which - is typically red - the hint has no effect otherwise). - - Note that in classical approaches to partial evaluation, it is not - possible to copy a red value into a green one. The implementation - of such an operation ("promotion") is only possible in a - "just-in-time" approach that only Psyco_ implemented so far (to the - best of our knowledge). Our hint is a direct generalization of the - latter. - -``v2 = hint(v1, variable=True)`` - Force ``v2`` to be red, even if ``v1`` is green. - -A program using promotion also needs to contain a ``global_merge_point`` -hint; this has no effect on the hint-annotator and is described in the -section about promotion_. - - -.. _`example above`: - -Example ----------------------------------- - -Let's consider a very small interpreter-like example:: - - def ll_plus_minus(s, x, y): - acc = x - pc = 0 - while pc < len(s): - op = s[pc] - op = hint(op, concrete=True) - if op == '+': - acc += y - elif op == '-': - acc -= y - pc += 1 - return acc - -``s`` here is an input program, simply a string of ``'+'`` or ``'-'``, ``x`` -and ``y`` are integer input arguments. - -The annotation of ``op = hint(op, concrete=True)`` will follow the -dependencies of the argument ``op``, which is the result of ``op = -s[pc]``, so both ``s`` and ``pc`` will be marked green. ``x``, ``y`` -and ``acc`` will stay red. - -The result ``op`` compared to the possible "instructions" will also be -green. Because ``s`` is green also ``len(s)`` will be. - -As we will see later, the timeshifter_ can use this information to -generate code that unfolds the loop (because the ``while`` condition is -green) and folds instruction dispatching (because the ``if`` conditions -are green) at compile-time. In other words, the only operations left -involving red variables are ``acc += y`` and ``acc -= y``, so only these -operations will eventually appear in the residual graph. - -Calls ----------------------------------- - -The ``concrete`` hint requires precise tracking of dependencies across -calls. More specifically, unlike the regular type-inferencing -annotator, the hint-annotator does not simply propagate this information -through called functions, but keeps all dependency information local to a -function. The problem is best shown by an example:: - - x = ... - y = ... - z = f(x, y) - -In this example, assuming that ``f(x, y)`` has no side effects, then we -want the dependency set of ``z`` to be the union of the dependencies of -``x`` and ``y`` (if both contribute to the result). But if another call -site calls ``f(x2, y2)`` then precision would be lost - the annotations -that would propagate within ``f`` would be marked as depending on all of -``x``, ``x2``, ``y`` and ``y2``, and then so would ``z``. - -To fix this problem, we only propagate dependencies that are local to a -function. Around a call like ``z = f(x, y)``, we check in the -annotations of the function ``f`` on which input arguments the result is -marked as depending on, and we reproduce the same dependency -relationship locally between ``x`` and ``y`` and ``z``. - -There are other aspects of the information carried by annotations that -are used in the "usual" annotator way, i.e. directly propagated between -caller and callee and back. If the result ``z`` of a call is forced to -be green by a ``concrete`` hint, then this forcing effect is propagated -inside the callee (more precisely, in a fresh copy of the callee, so -that forced and non-forced call sites can respectively call a -mostly-green and a mostly-red version of the function; this is done with -the technique of `specialization of functions`_ that is already -available in the normal annotator). - -Also, if all call sites provide a green value for an argument, then the -callee's corresponding input argument can safely be green. (This can -only be determined at the end of the process, though, after all call -sites are known and stable enough; we use another fixpoint loop for -this.) - - -Deep freezing ----------------------------------- - -Among the low-level operations, the one that reads data from a structure -in memory (``getfield``) requires special care. In a first -approximation it can only return a red value, because the reading from -the structure cannot be performed at compile-time - the structure may be -mutated between compile-time and the point at run-time where the read -was supposed to occur in the original code. - -This is a problem in most real-life examples. Unlike our `example -above`_, input arguments to such functions are typically not just -strings and integers but complex data structures. To produce sensible -results, it is necessary to assume that some of these data structures -will not be mutated after the compile-time process used their content. -For example, PyPy's own interpreter works with an instance of a PyCode -class containing not only a string representing the bytecode, but -various simple Python objects (tuple of names, ...). None of this data -can be modified after its construction, though. - -To express this, we use a hint ``v2 = hint(v1, deepfreeze=True)``, where -``v1`` is a pointer (in the low-level graph - it typically comes from a -regular RPython object reference in the RPython source). The -hint-annotation will then propagate a "deepfrozen" flag on the -annotation attached to ``v2``. If ``v2`` is green, a ``getfield(v2, -"name")`` operation then also returns a green. The flag is also -relevant if ``v2`` is red, as we will see in `Red and Green Operations`_ -below. - -As the name suggests, the result of a ``getfield`` is itself -"deepfrozen" if the structure was. We decided to implement recursive -freezing and not one-level-only freezing, as the latter seems more -fragile with respect to changes both in the RPython source and in the -way the source maps to low-level graphs; but variants could easily be -implemented if needed. - - -Blue containers ----------------------------------- - -Undocumented yet. Not implemented in the timeshifter, so not used so far. - - - -.. _timeshifter: -.. _timeshifting: - -Timeshifting: transforming interpreter into compilers -====================================================== - -Once binding times (colors) have been assigned to all variables in a -family of control flow graphs, the next step is to mutate the graphs -accordingly. This process is called *timeshifting*, because it changes -the time at which the graphs are meant to be run. - -Keep in mind that the program described as the "source RPython -program" in this document is typically an interpreter - the canonical -example is that it is the whole `PyPy Standard Interpreter`_. This -program is meant to execute at run-time, and directly compute the -intended result and side-effects. The translation process transforms it -into a forest of flow graphs. These are the flow graphs that -timeshifting processes (and not the application-level program, which -cannot be expressed as low-level flow graphs anyway). - -After being timeshifted, the graphs of our interpreter become logically -very different: they are no longer intended to be executed at run-time, -but just ahead of it (what we call "compile-time"). Their only side -effects is to produce residual code. The residual code itself runs "at -run-time". - -Despite the conceptual difference, though, the form (flow of control) -of timeshifted graphs is related and close to the original graphs. -The rest of this section describes this timeshifting process in more -detail. - - -Red and Green Operations --------------------------- - -The basic idea of timeshifting is to transform operations in a way that -depends on the color of their operands and result. Variables themselves -need to be represented based on their color: - -* The green variables are the compile-time variables. Their values are - meant to be available during compile-time already. A variable that - used to contain e.g. an integer at run-time in the original graph, and - which the hint-annotator found to be green, is turned into a variable - that contains an integer again, but now at compile-time. In other - words, timeshifting leaves green variables untouched - they are - identical in the original and in the timeshifted graph. - -* The red (run-time) variables on the other hand cannot stay unmodified - in the timeshifted graph, because no actual value is available for - them during compile-time. They are replaced by the notion of "red - box": a red box is a small object that describes where, in the - residual code, the value will be stored at run-time. Multiple red - variables are turned into multiple red boxes, which are used to - distinguish the residual storage location for each of them. - -The basic feature of each red box is to provide a field ``genvar``, -which is a backend-specific object that represents a machine code -operand - either a value location (e.g. the register where it is stored) -or a constant (an immediate). Constants are used for red boxes whose -value is, after all, known at compile-time. This can occur even though -the corresponding variable in the graph was red; it is the case when the -hint-annotator cannot tell statically that a given variable will always -contain a compile-time constant, even though it might dynamically be -found to contain one at a particular point in (compile-)time. In -Partial Evaluation terminology, the timeshifted graphs are performing -some *on-line* partial evaluation in addition to the off-line job -enabled by the hint-annotator. - -In addition to the variables, all operations of the original graphs need -to be checked and accordingly transformed: - -* If an operation has no side effect or other run-time dependency, and - if it only involves green operands, then it can stay unmodified in the - graph. In this case, the operation that was run-time in the original - graph becomes a compile-time operation, and it will never be generated - in the residual code. (This is the case that makes the whole approach - worthwhile: some operations become purely compile-time.) - -* In all other cases, the operation might have to be generated in the - residual code. In the timeshifted graph, it is replaced by a call to - a helper. There is one such helper per operation, which takes red - boxes as its arguments, and asks the backend to generate the - corresponding residual operation on the ``genvar`` of the red boxes. - The backend answers by giving a new ``genvar``, which is the location - of the result, and the helper puts it into a new red box, which is - returned to the timeshifted graph as the result of the call. - -Additionally, the helper for some operations checks if all arguments are -red boxes containing constants, and if so just returns a red box -containing the result without producing any residual code. A particular -case to note is that of the ``getfield`` operation: when applied on a -constant red box, the field can sometimes be directly read out of the -structure at compile-time - this decision is based on the static `Deep -freezing`_ analysis performed by the hint-annotator. - -The Example again -------------------- - -If we timeshift the `ll_plus_minus`__ example, given the described -binding time assignments, the only red operations generating -code in the output residual code are ``acc += x``, ``acc -= -x``. Timeshifting substitute them with helpers that do emit such -operations. - -All the rest involves green variables and is left unmutated by -timeshifting. The corresponding computations, the loop over the -"instructions" and dispaching on them would happen at compile-time. - -The timeshifted version of ll_plus_minus for the input "+-+" would -produce something like (in pseudo notation):: - - residual_plus_minus(x,y): - v0 = int_add(x , y) - v1 = int_sub(v0, y) - v2 = int_add(v1, y) - return v2 - -__ `Example above`_ - - -Support code --------------- - -To implement red boxes, we have written a family of support classes in -`pypy/jit/timeshifter/rvalue.py`_: IntRedBox, DoubleRedBox and -PtrRedBox. They are used, respectively, for integral values of any -size, for floating-point values, and for pointers and addresses. As we -will see below, these classes support a number of additional features, -particularly PtrRedBox. - -These classes are regular RPython classes that are translated to -low-level and linked with the rest of the program. The same holds for -the helper functions that inspect red boxes and generate residual -operations. We make extensive use of this technique (described in more -detail in VMC_): all the complex support code that is needed for the -timeshifted graphs is implemented as regular RPython code and linked -with the rest of the program, by inserting calls to these helpers from -the timeshifted graphs, and also (as in the red box case) by putting -variables in the graphs whose types are (the low-level representation -of) instances of helper RPython classes. - -The amount of support code is quite extensive, as it includes the whole -machine code backend as well: when helpers need to produce residual -code, they do so through a well-defined API on classes that are provided -by one of our JIT backends. (This will be described in more details in -the Backends_ section.) All this support code can be arbitrarily -complex RPython code, which allows us to experiment quite freely. - - -Two-Phases Transformation ---------------------------- - -Concretely, the process of timeshifting replaces some variables with -fresh variables of new types, and replaces some operations with calls to -helper functions. This is very similar to what the `RPython Typer`_ -does during a normal translation. The latter replaces RPython-level -variables and operations with low-level variables and operations and -calls to helpers; it is guided by the annotations produced by the -regular type inference. The former does the same, except that the input -is already low-level operations, and the annotations are colors, -produced by the hint-annotator. - -In light of this close analogy, we have implemented the timeshifter -based on the RTyper. This gives us direct benefits, like automatic -conversions for operation arguments or along links. For example, if an -operation takes two arguments, but one of them is red and the other -green, then the whole operation must classify as "red" and be replaced -by a call to the corresponding helper. This helper expects two red -boxes as arguments, though. The red argument is a red box in the -timeshifted graph, but not the green one. Reusing the RTyper logic, the -necessary conversion (creating a red box and putting the green value -into it as an immediate) is inserted automatically in cases like this -one. - -Unlike the regular RTyper, though, the timeshifter is faced with an -additional difficulty that will only become apparent in the sequel: in -addition to the local replacement of variables and operations, it also -needs to modify the control flow of the graph. - -The approach that we have taken is in two phases: - -* The graphs are first transformed "manually". This phase modifies the - control flow and adds pseudo-operations in key places. In some sense, - all the interesting large-scale issues, experiments and solutions with - timeshifting a graph are present in this transformation. The - pseudo-operations are placeholders for bookkeeping operations like - saving local variables into JIT state structures, scheduling various - parts of the compilation, and so on. This phase preserves the colors; - its output is graphs that look like pseudo-code, convenient to inspect - in the graph viewer for debugging and explanation purposes. - -* The modified RTyper (called "HRTyper") is applied in a second phase. - It replaces variables and operations locally as described above. The - pseudo-operations are replaced along with all the other ones, and - become calls to helpers. - - -Merges and Splits --------------------- - -The description of the timeshifting transformation given so far misses a -critical aspect: how to handle control flow (e.g. loops) that involves -red variables. It is easy to see why the timeshifted graphs cannot have -exactly the same control flow than the original graphs: we may not know -at compile-time how many iterations a loop will do at run-time, nor what -branches of a condition will be taken. - -The issue of loops is handled by *merge points*. Merge points are -special operations inserted just after join points, i.e. just after two -or more incoming control flow paths meet. A merge point is a check to -see if the compiler, i.e. the timeshifted graph, has come back to a -state that was previously seen at the same merge point. The goal is -that when the timeshifted graph loops back, the residual code that its -red operations produces should loop as well, as soon as possible. -Without the merge point logic, the timeshifted graph would simply go on -looping forever, producing an infinitely long sequence of residual -operations. The merge point prevents that: when a state is encountered -that was already seen before, the merge logic emits in the residual code -a jump that goes back to the residual code corresponding to the older -state, thus creating a residual loop. After this, the timeshifted graph -stops executing. - -The mirror issue is that of *split points*. Splits are conditional -branches. There are two kinds of splits: the ones whose condition is -itself on a green variable, and the ones whose condition is red. A green -split (i.e. the former) is left untouched by the timeshifting -transformation: as the condition will be known a compile-time, we know -at compile-time which of the branches has to be followed. - -A red split is more delicate. It must generate a conditional branch -in the residual code. From a theoretical point of view, this is done by -emitting a conditional jump instruction, and then *forking* the -compile-time process in two identical copies: each copy follows one of -the branches in the timeshifted graph, and goes on generating code in -the corresponding branch in the residual code. - -In practice, this is implemented by making a copy of the current JIT -state, which is added to a scheduler's queue. At the end of the -timeshifted graph, an extra call to the scheduler will fetch the next -pending JIT state and jump back to it. (This implies that the control -flow of the timeshifted graph is mangled by the timeshifting -transformation, to allow the last block of the graph to jump back to any -of the red splits.) - - -Calls and inlining ---------------------- - -For calls timeshifting can either produce code to generate a residual -call operation or recursively invoke the timeshifted version of the -callee. The residual operations generated by the timeshifted callee -will grow the compile-time produced residual function, this -effectively amounts to compile-time inlining the original callee into -its caller. - -Again timeshifting determines how to transform call operations based on -the color of arguments and result: - -* If all arguments and the result are green and we can detect the called - function not to have side-effects, the call is a so-called *green call*, - and will be left untouched which means there will be a call executed - at compile-time. - -* Calls to function that have no return value (i.e. their return type - is the low-level type Void), are assumed to have side-effects, they - are *gray calls*. - -* Calls with a green result but with side-effects are so-called *yellow calls*. - -* Calls with a red result are *red calls* - -The treatment of *red*, *gray* and *yellow* calls is similar, -timeshifting will transform them into calls to the timeshifted version -of the callee, resulting into an inlining-effect at compile time. - -At compile-time the JIT state contains a chain of virtual frames -(similar to `virtual structures`_), its top frame is updated with all -the red boxes for the call-point red variables before such calls and -the callee will attach a fresh new frame. This chain guarantees that -values (represented by the boxes) are propagated correctly, -accordingly split points duplicate and merge points treat the full -chain properly. - -Each timeshifted function has its own dispatch logic for splits, it -returns to the caller when all the split scheduled states have been -dealt with. A list of all the states that reached the return of the -function (there can be more than one) is returned to the caller which -then schedules these states on its dispatch queue. This is crucial for -yellow calls to keep the various green return values disjunct. - -What we have described applies to direct calls where the callee is a -constant function. For indirect calls, where the callee is a variable -it is checked whether the callee is constant at compile-time in which -case a mapping between the pointers to the original functions and -their timeshifted versions is used to call the appropriate timeshifted -callee as for a direct call. If the exact callee is unknown a residual -call operation is generated. - - -Virtual structures --------------------- - -The support code introduced by the timeshifter contains an optimization -for all memory allocations that would normally have to occur at -run-time: it makes these allocations lazy. A *virtual structure* is -such a lazily-allocated run-time data structure. - -The hint-annotator gives the color red to the result of a malloc -operation. However, the timeshifter turns the malloc into a pure -compile-time operation that returns a special PtrRedBox object. The -PtrRedBox contains neither a compile-time value (because its value as a -pointer is not a compile-time constant) nor a run-time value (because no -residual code was generated to perform the malloc yet, so no run-time -machine code register contains the pointer's value). Instead, the -PtrRedBox references a *virtual structure* object that describes what -shape and what values the structure would contain at run-time; the -values are themselves further RedBoxes. - -For example, in the following code:: - - obj = MyClass() - obj.x = somevalue - ... - print obj.x - -all the variables are red. At compile-time, the malloc corresponding to -the instantiation of ``MyClass`` returns a PtrRedBox with a virtual -structure. In the next line, the attribute assignment stores the RedBox -corresponding to ``somevalue`` into the virtual structure. Later on, -reading ``obj.x`` reads out the same RedBox out of the virtual -structure. This is all done without generating any residual code; the -machine code register that holds ``somevalue`` at run-time simply stays -around and is used directly in the ``print`` statement. - -The above example is of course too simple to reflect the complex control -flow patterns of real-life programs. In some cases, merge points -prevent us from following virtual structures. Indeed, consider:: - - if condition: - obj = MyFirstClass() - else: - obj = MySecondClass() - -Following the ``if`` statement, the control flow graph contains such a -merge point. Assume first that the ``condition`` is a compile-time -constant. In this case, only one path is considered anyway, so ``obj`` -is propagated into the rest of the code as a PtrRedBox with a specific -virtual structure. But assume now that ``condition`` is not a -compile-time constant. In this case, in each incoming path the variable -``obj`` contains a PtrRedBox with a different type of virtual structure. -To avoid an explosion of the number of cases to consider, the -compile-time logic *forces* the virtual structures at this point, -i.e. it generates code that actually allocates them at run-time. For -the rest of the code, the PtrRedBox changes its status and becomes a -regular run-time PtrRedBox. - -Another case in which a virtual structure must be forced is when the -pointer escapes to some uncontrolled place, e.g. when it is stored into -a (non-virtual) run-time structure. - -Note that the virtual structure object itself stores enough information -to know exactly the run-time type it was allocated with. This is -necessary because the PtrRedBox itself might be cast up to a less -precise pointer type, without necessarily forcing the virtual structure. -This is the case in the previous example: the inferred type for ``obj`` -in the rest of the code is the less precise common base class of -``MyFirstClass`` and ``MySecondClass``, whereas if ``condition`` is a -compile-time constant then the virtual structure can carry the precise -class of the instance even in the rest of the code. - -Virtual lists and dicts -------------------------- - -The examples of `virtual structures`_ seen so far are about virtualizing -objects like instances of RPython classes, which have a ``GcStruct`` -low-level type, i.e. a kind of C ``struct``. The same idea can be -generalized to objects with other kinds of low-level representations; we -call the result *virtual containers*. Beside structures, there are two -further kinds of virtual containers: *virtual lists* and *virtual -dicts*. The idea is the optimize the following kind of code:: - - lst = [] - lst.append(somevalue) - ... - print lst.pop() - -As in the examples of `virtual structures`_, the list manipulations here -produce no residual code whatsoever. At compile-time the ``lst`` -variable is a PtrRedBox referencing a *virtual list* object. A virtual -list is implemented as a list of red boxes: operations like -``append(x)`` just append the red box of ``x`` to the virtual list. The -virtual list must be forced in situations where the shape of the list -can no longer be known at compile-time, e.g. when inserting an element -at an index which is not a compile-time constant. - -Virtual dicts are similar, but only support compile-time constants as -keys (otherwise, we would not know at compile-time whether two run-time -keys are equal or not). They are useful in situations where we build -small dicts with fixed keys; in the PyPy interpreter for example we -foresee that they will be useful to implement the dictionary of -application-level objects, which typically have a few well-known string -keys (the instance's attributes). - -Note that some care is required when timeshifting low-level code that -handles lists and dicts: operations like ``lst.append(x)`` have already -been turned into calls to low-level helpers that manipulate low-level -structures and arrays. If no care is taken, the timeshifter will -consider this as code that handles structures and arrays, and try to -make them virtual structures and (yet unsupported) virtual arrays. -However, this is a bit too low-level: e.g. lists that should be similar -may have accidentally different structures, because of the details of -the over-allocation logic in the low-level helpers. The situation is -even worse for dictionaries, where the details of the key placement in -the hash table is irrelevant at the RPython level but is likely to -confuse the merge logic when trying to compare two virtual dicts. The -timeshifter avoids these issues by special-casing the helpers for lists -and dicts and mapping them to compile-time operations on virtual lists -and virtual dicts. (This is the purpose of the ``oopspec`` annotation -found in the source code of these helpers; as e.g. in -`rpython/rlist.py`_.) - - -Exceptions ------------- - -The graphs that the timeshifter inputs are RPython code. As such, they -typically use exceptions. They must be handled in a specific way - the -timeshifted graph itself cannot simply raise and catch the same -exceptions at the same places, because most of these exceptions will -only occur at run-time under some conditions. - -The solution we picked is to *exception-transform* the input graphs -before they are timeshifted. The `exception transformer`_ is a module -that is normally used to prepare a graph for being turned into C code, -by removing the exception handling implicit at the graph level and -turning it into a form suitable for C. This transformation introduces a -*global exception state* structure that stores the current exception -object, if any; it turns exception raising into writing into the global -exception state, and it adds checks in each graph after each operation -that could potentially raise. - -Now, as the timeshifter takes exception-transformed graphs as input, it -would do the right thing without special support. Indeed, loads from -and stores to the global exception state are regular red operations, so -they are simply generated into the residual code. In this model, the -generated residual code would simply check for exception as often as -the original, non-timeshifted graphs did. - -The result is not efficient, however, because many original operations -were removed - for example, green operations are no longer present, and -calls are inlined. This means that the residual graph contains -unnecessary repeated checks. To solve this, we made the global -exception state structure virtual in some sense. The compile-time state -contains two red boxes that correspond to the current exception type and -instance; the intent is that they describe run-time values which -together are considered as the current exception by the residual code. -In other words, when the residual code is itself running, the global -exception state structure is not really containing the current -exception; instead, it is in regular local variables (if the red boxes -are run-time) or simply known as constants at this point (if the red -boxes are compile-time). - -To implement this, the timeshifter needs to special-case the following -places: - -* Operations in the input graphs that directly read from or store to the - global exception state structure become compile-time copies from or to - the compile-time exception red boxes. For example, when the input, - exception-transformed graph wants to clear the current exception, it - stores zeroes in the global exception state; the timeshifter - transforms these into putting red boxes with compile-time zeroes as - the compile-time exception red boxes. Afterwards, any compile-time - code that checks if an exception is set would find the compile-time - zeroes and know that there isn't any. - -* Residual operations that can indirectly raise, like residual calls, - would store an exception into the global exception state; so at - compile-time, just after we generate such a residual operation, we - also generate a pair of ``getfield`` operations that load the run-time - exception back into local run-time variables. This produces - non-constant red boxes which are used as the compile-time exception - boxes. - -* At the end of a residual function, just before returning to the - run-time caller, we generate code that copies the exception boxes back - into the global exception state. - -With the above rules, we can match direct raises with their -corresponding exception handlers purely at compile-time. Indeed, -consider a graph that explicit raises some exception. The exception -transformer first turns it into setting a constant type pointer into the -global exception state. Then the timeshifter turns that code into -storing a constant red box into the compile-time exception state. The -exception remains a compile-time constant until it is either used -(allowing the matching code inserted by the exception transformer to -give compile-time constant answers) or it escapes out of the residual -code (and only in the latter case will residual code store it into the -global exception state for the benefit of the run-time caller). - - -.. _promotion: - -Promotion and global merges ------------------------------ - -...global merge point... - - -Partial data -------------- - -... - - -Portals ----------------------- - -... - - -Scaling to PyPy ----------------------- - -... - - -Virtualizables ----------------------- - -... - -Backends +For more information ==================== -The compilers produced by the timeshifter are linked with one of our -backends, which are written by hand in RPython. We currently have a -backend for producing IA32/i386 machine code in memory, PowerPC machine -code in memory, or (for testing) further low-level control flow graphs. - -The Backend interface ------------------------ - -The interface (which is not yet completely stable) is documented in -`pypy/jit/codegen/model.py`_. - - -Results -====================== - -... - - -Related work -====================== +The `expanded version of the present document`_ is mostly unreadable, +but may be of interest to you if you are already familiar with the +domain of Partial Evaluation. -... +.. _`expanded version of the present document`: discussion/jit-draft.html .. _VMC: http://codespeak.net/svn/pypy/extradoc/talk/dls2006/pypy-vm-construction.pdf From pedronis at codespeak.net Sun Mar 25 18:23:17 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sun, 25 Mar 2007 18:23:17 +0200 (CEST) Subject: [pypy-svn] r41293 - pypy/dist/pypy/doc Message-ID: <20070325162317.2A6B810083@code0.codespeak.net> Author: pedronis Date: Sun Mar 25 18:23:16 2007 New Revision: 41293 Modified: pypy/dist/pypy/doc/new-architecture.txt Log: The translation part needs some streamlining. I may help with that tomorrow but not now. Modified: pypy/dist/pypy/doc/new-architecture.txt ============================================================================== --- pypy/dist/pypy/doc/new-architecture.txt (original) +++ pypy/dist/pypy/doc/new-architecture.txt Sun Mar 25 18:23:16 2007 @@ -164,6 +164,8 @@ The Translation Process ----------------------- +.. XXX this part sounds repetivive here and there and a bit heavy + The *translation process* is implemented in four parts: - the production of a *flow graph* representation of an RPython program From pedronis at codespeak.net Sun Mar 25 18:27:34 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sun, 25 Mar 2007 18:27:34 +0200 (CEST) Subject: [pypy-svn] r41294 - pypy/dist/pypy/doc Message-ID: <20070325162734.3BAA910083@code0.codespeak.net> Author: pedronis Date: Sun Mar 25 18:27:33 2007 New Revision: 41294 Modified: pypy/dist/pypy/doc/new-architecture.txt Log: streamline this sentence Modified: pypy/dist/pypy/doc/new-architecture.txt ============================================================================== --- pypy/dist/pypy/doc/new-architecture.txt (original) +++ pypy/dist/pypy/doc/new-architecture.txt Sun Mar 25 18:27:33 2007 @@ -126,7 +126,7 @@ The Python Interpreter ------------------------------------- -The *Python Interpreter* is the subsystem implementing the Python language +PyPy's *Python Interpreter* implements the Python language with the following key components: - a bytecode compiler responsible for producing Python code objects From pedronis at codespeak.net Sun Mar 25 18:31:17 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sun, 25 Mar 2007 18:31:17 +0200 (CEST) Subject: [pypy-svn] r41295 - pypy/dist/pypy/doc Message-ID: <20070325163117.1A6F110083@code0.codespeak.net> Author: pedronis Date: Sun Mar 25 18:31:15 2007 New Revision: 41295 Modified: pypy/dist/pypy/doc/new-architecture.txt Log: cut a bit this sentence. is repeting what's said in the last para of the previous section. Modified: pypy/dist/pypy/doc/new-architecture.txt ============================================================================== --- pypy/dist/pypy/doc/new-architecture.txt (original) +++ pypy/dist/pypy/doc/new-architecture.txt Sun Mar 25 18:31:15 2007 @@ -117,8 +117,7 @@ and continues to evolve. Nevertheless, the high level architecture is stable. There are two rather independent basic subsystems: the `Python Interpreter`_ and `the Translation Framework`_. We first talk about the -Python Interpreter because the Translation framework in fact re-uses -parts of its architecture and code. +Python Interpreter because of its re-use by the Translation framework. .. _`standard interpreter`: .. _`python interpreter`: From pedronis at codespeak.net Sun Mar 25 18:35:54 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sun, 25 Mar 2007 18:35:54 +0200 (CEST) Subject: [pypy-svn] r41296 - pypy/dist/pypy/doc Message-ID: <20070325163554.5EE7B10085@code0.codespeak.net> Author: pedronis Date: Sun Mar 25 18:35:52 2007 New Revision: 41296 Modified: pypy/dist/pypy/doc/new-architecture.txt Log: tone adjustement (I know, very personal) Modified: pypy/dist/pypy/doc/new-architecture.txt ============================================================================== --- pypy/dist/pypy/doc/new-architecture.txt (original) +++ pypy/dist/pypy/doc/new-architecture.txt Sun Mar 25 18:35:52 2007 @@ -75,8 +75,8 @@ Particularly, we set ourselves the goal to *generate Just-In-Time Compilers* in addition to traditional Interpreter implementations - an area of language -implementation that is commonly considered the ultimate -in complexity. +implementation that is commonly considered very challenging +because of the involved complexity. PyPy - the Python Interpreter From hpk at codespeak.net Sun Mar 25 18:57:25 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sun, 25 Mar 2007 18:57:25 +0200 (CEST) Subject: [pypy-svn] r41297 - pypy/extradoc/planning/1.0 Message-ID: <20070325165725.C92E710080@code0.codespeak.net> Author: hpk Date: Sun Mar 25 18:57:23 2007 New Revision: 41297 Modified: pypy/extradoc/planning/1.0/TODO.txt Log: some update after today's brief (arigo,cfbolz,pedronis,hpk,guido) meeting Modified: pypy/extradoc/planning/1.0/TODO.txt ============================================================================== --- pypy/extradoc/planning/1.0/TODO.txt (original) +++ pypy/extradoc/planning/1.0/TODO.txt Sun Mar 25 18:57:23 2007 @@ -27,7 +27,7 @@ - test windows situation (antocuni, fijal) -- seems generally good - integrate and test: - - (arigo,pedronis,arre): wp08 docs & examples, getting-started + - (arigo,pedronis,arre, IN-PROGRESS): wp08 docs & examples, getting-started - (cfbolz) test wp09 getting-started examples: - wp09 docs, examples and code - maybe what we have is good enough? (christian looking into this currently) a bit of progress, @@ -37,10 +37,9 @@ - (hpk, mostly done) review entry points from the play1 demos. - (arigo,cfbolz,pedronis) review/refactor new-architecture.txt - - (possibly arigo) fix bad terminal behaviour of translated PyPy's - (contributing to play1 quirks) - - (fijal, NNN) play1 issues: + - rebuild pypy's to use the new readline stub (fixing + ugly stdout/stdin interactions) - review/refine help (add examples where necessary) - make examples execute more cleanly - fix linking (it gets easily confused if you click around), @@ -61,10 +60,11 @@ - include documentation/entry point for the prolog interpreter (cfbolz, maybe) - - (hpk) fix test failures of translated PyPys - relating to app_test + - (DONE), arigo,pedronis,hpk) fix test failures of translated PyPys + related to aop.py module modifying global compiler state and + subsequent tests randomly breaking - - (pedronis) tarball packaging and testing + - (pedronis, in-progress) tarball packaging and testing - (hpk, review from cfbolz and NN) write release announcement @@ -104,3 +104,8 @@ appears to work well, gives nice speedups on suitably contrived examples - (done) document build tool usages (getting-started?) + + - (DONE, arigo) fix bad terminal behaviour of translated PyPy's + + (contributing to play1 quirks) + From cfbolz at codespeak.net Sun Mar 25 20:20:10 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sun, 25 Mar 2007 20:20:10 +0200 (CEST) Subject: [pypy-svn] r41299 - pypy/dist/pypy/lang/prolog/interpreter Message-ID: <20070325182010.523DE10085@code0.codespeak.net> Author: cfbolz Date: Sun Mar 25 20:20:08 2007 New Revision: 41299 Modified: pypy/dist/pypy/lang/prolog/interpreter/main.py Log: factor main into a function Modified: pypy/dist/pypy/lang/prolog/interpreter/main.py ============================================================================== --- pypy/dist/pypy/lang/prolog/interpreter/main.py (original) +++ pypy/dist/pypy/lang/prolog/interpreter/main.py Sun Mar 25 20:20:08 2007 @@ -168,7 +168,7 @@ getch = _Getch() -if __name__ == '__main__': +def main(): import readline oldps1 = getattr(sys, "ps1", ">>> ") oldps2 = getattr(sys, "ps2", "... ") @@ -193,3 +193,6 @@ sys.ps1 = oldps1 sys.ps2 = oldps2 + +if __name__ == '__main__': + main() From mwh at codespeak.net Sun Mar 25 20:20:15 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Sun, 25 Mar 2007 20:20:15 +0200 (CEST) Subject: [pypy-svn] r41300 - pypy/dist/pypy/translator/llvm/test Message-ID: <20070325182015.012CE10089@code0.codespeak.net> Author: mwh Date: Sun Mar 25 20:20:13 2007 New Revision: 41300 Modified: pypy/dist/pypy/translator/llvm/test/test_symbolic.py Log: updadte this skipped test a bit (still doesn't work) Modified: pypy/dist/pypy/translator/llvm/test/test_symbolic.py ============================================================================== --- pypy/dist/pypy/translator/llvm/test/test_symbolic.py (original) +++ pypy/dist/pypy/translator/llvm/test/test_symbolic.py Sun Mar 25 20:20:13 2007 @@ -25,7 +25,7 @@ def test_sizeof_array_with_no_length(): py.test.skip("inprogress") A = lltype.GcArray(lltype.Signed, hints={'nolength': True}) - a = lltype.malloc(A, 5) + a = lltype.malloc(A, 5, zero=True) arraysize = llmemory.itemoffsetof(A, 10) signedsize = llmemory.sizeof(lltype.Signed) From cfbolz at codespeak.net Sun Mar 25 20:20:41 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sun, 25 Mar 2007 20:20:41 +0200 (CEST) Subject: [pypy-svn] r41301 - pypy/dist/pypy/lang/prolog/interpreter Message-ID: <20070325182041.0811710085@code0.codespeak.net> Author: cfbolz Date: Sun Mar 25 20:20:40 2007 New Revision: 41301 Added: pypy/dist/pypy/lang/prolog/interpreter/interactive.py - copied unchanged from r41299, pypy/dist/pypy/lang/prolog/interpreter/main.py Removed: pypy/dist/pypy/lang/prolog/interpreter/main.py Log: rename main to interactive, consistend with the python interpreter From cfbolz at codespeak.net Sun Mar 25 20:33:08 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sun, 25 Mar 2007 20:33:08 +0200 (CEST) Subject: [pypy-svn] r41302 - pypy/dist/pypy/bin Message-ID: <20070325183308.DFF4110085@code0.codespeak.net> Author: cfbolz Date: Sun Mar 25 20:33:06 2007 New Revision: 41302 Added: pypy/dist/pypy/bin/pyrolog.py (contents, props changed) Log: add the prolog front end entry point to bin Added: pypy/dist/pypy/bin/pyrolog.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/bin/pyrolog.py Sun Mar 25 20:33:06 2007 @@ -0,0 +1,8 @@ +#!/usr/bin/env python + +import autopath + +from pypy.lang.prolog.interpreter.interactive import main + +if __name__ == '__main__': + main() From cfbolz at codespeak.net Sun Mar 25 21:55:24 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sun, 25 Mar 2007 21:55:24 +0200 (CEST) Subject: [pypy-svn] r41303 - pypy/dist/pypy/lang/prolog/interpreter Message-ID: <20070325195524.8111D10089@code0.codespeak.net> Author: cfbolz Date: Sun Mar 25 21:55:23 2007 New Revision: 41303 Modified: pypy/dist/pypy/lang/prolog/interpreter/translatedmain.py Log: fix import Modified: pypy/dist/pypy/lang/prolog/interpreter/translatedmain.py ============================================================================== --- pypy/dist/pypy/lang/prolog/interpreter/translatedmain.py (original) +++ pypy/dist/pypy/lang/prolog/interpreter/translatedmain.py Sun Mar 25 21:55:23 2007 @@ -1,7 +1,7 @@ import os, sys from pypy.rlib.parsing.parsing import ParseError from pypy.rlib.parsing.deterministic import LexerError -from pypy.lang.prolog.interpreter.main import helptext +from pypy.lang.prolog.interpreter.interactive import helptext from pypy.lang.prolog.interpreter.parsing import parse_file, get_query_and_vars from pypy.lang.prolog.interpreter.parsing import get_engine from pypy.lang.prolog.interpreter.engine import Engine From cfbolz at codespeak.net Sun Mar 25 21:55:58 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sun, 25 Mar 2007 21:55:58 +0200 (CEST) Subject: [pypy-svn] r41304 - pypy/dist/pypy/doc Message-ID: <20070325195558.C426010089@code0.codespeak.net> Author: cfbolz Date: Sun Mar 25 21:55:56 2007 New Revision: 41304 Added: pypy/dist/pypy/doc/prolog-interpreter.txt (contents, props changed) Log: add some prolog examples Added: pypy/dist/pypy/doc/prolog-interpreter.txt ============================================================================== --- (empty file) +++ pypy/dist/pypy/doc/prolog-interpreter.txt Sun Mar 25 21:55:56 2007 @@ -0,0 +1,158 @@ +================================== +Pyrolog: PyPy's Prolog interpreter +================================== + +.. contents:: + +Pyrolog, PyPy's Prolog interpreter was written by Carl Friedrich Bolz as part of +his bachelor thesis. It aims at being fully implementing the `Prolog ISO +specification`_. Currently it implements the core Prolog semantics and many, but +not all, ISO builtins (it is especially lacking when it comes to I/O and module +support). Its speed is still quite a bit below that of highly optimized Prologs, +roughly 10-100 times slower than `Sicstus Prolog`_. In addition, it currently is +not very polished in many respects. + +This page probably won't make too much sense to you if you don't know some +Prolog. `Learn Prolog Now!`_ is a rather nice book (available online) to learn +some Prolog with (but it's probably not a good idea to use Pyrolog while +learning since it is too rough for that). + +.. _`Prolog ISO specification`: http://pauillac.inria.fr/~deransar/prolog/docs.html +.. _`Sicstus Prolog`: http://www.sics.se/sicstus/ +.. _`Learn Prolog Now!`: http://www.coli.uni-saarland.de/~kris/learn-prolog-now/ + +Example useage +============== + +First some simple examples that show simple unification:: + + pypy/bin$ ./pyrolog.py + PyPy Prolog Console + >?- X = f(Y, a, b), Y = [1, 2, 3]. + yes + X = f([1, 2, 3], a, b) + Y = [1, 2, ...] + + + yes + >?- X = f(Y, a, b), Y = [1, 2]. + yes + X = f([1, 2], a, b) + Y = [1, 2] + + + yes + >?- f(A, B, c) = f(a, b(1, 2), C). + yes + A = a + B = b(1, 2) + C = c + + +A more complicated example with an actual function: First define the function +using ``assertz``: + + pypy/bin$ ./pyrolog.py + PyPy Prolog Console + >?- assertz(takeout(A, [A|B], B)). + yes + A = _G0 + B = _G1 + + + yes + >?- + >?- assertz(takeout(A, [B|C], [B|D]) :- takeout(A, C, D)). + yes + A = _G0 + B = _G1 + C = _G2 + D = _G3 + + + yes + +Then use it:: + + >?- takeout(3, [1, 2, 3, 4], R). + yes + R = [1, 2, 4] + + + yes + >?- takeout(X, [a, b, c], Rest). + yes + Rest = [b, c] + X = a + ; + yes + Rest = [a, c] + X = b + ; + yes + Rest = [a, b] + X = c + ; + no + >?- takeout(3, X, [a, b]). + yes + X = [3, a, b] + ; + yes + X = [a, 3, b] + ; + yes + X = [a, b, 3] + ; + no + +And of course the typical "family tree" example can't be left out (who can find +the most boring names), this time using an actual file instead of asserting +everything.):: + + pypy/bin$ cat > family.pl + parent(john, mary). + parent(anne, mary). + parent(john, paul). + parent(anne, paul). + parent(john, jack). + parent(anne, jack). + parent(jack, sophie). + + descendant(X, Y) :- parent(X, Y). + descendant(X, Y) :- parent(X, Z), descendant(Z, Y). + +Now we can query this database in the following way:: + + pypy/bin$ ./pyrolog.py family.pl + PyPy Prolog Console + >?- descendant(john, X). + yes + X = mary + ; + yes + X = paul + ; + yes + X = jack + ; + yes + X = sophie + ; + no + >?- findall(X, descendant(anne, X), Result). + yes + Result = [mary, paul, jack, sophie] + X = _G0 + +Translating the interpreter to C +================================ + +Just as you can translate PyPy's Python interpreter, you can also translate the +Prolog interpreter to C:: + + pypy$ cd translator/goal + pypy/translator/goal$ python translate.py targetprologstandalone.py + + + From arigo at codespeak.net Mon Mar 26 09:14:16 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 26 Mar 2007 09:14:16 +0200 (CEST) Subject: [pypy-svn] r41306 - pypy/dist/pypy/doc Message-ID: <20070326071416.F0CC71007F@code0.codespeak.net> Author: arigo Date: Mon Mar 26 09:14:14 2007 New Revision: 41306 Modified: pypy/dist/pypy/doc/jit.txt Log: XXX => .. XXX Modified: pypy/dist/pypy/doc/jit.txt ============================================================================== --- pypy/dist/pypy/doc/jit.txt (original) +++ pypy/dist/pypy/doc/jit.txt Mon Mar 26 09:14:14 2007 @@ -184,7 +184,9 @@ transparently introduced by and during the translation process. Partial evaluation techniques should, at least theoretically, allow -such a derivation of a compiler from an interpreter. (XXX references) +such a derivation of a compiler from an interpreter. + +.. XXX references The forest of flow graphs that the translation process generates and transforms constitutes a reasonable base for the necessary analyses. @@ -200,8 +202,9 @@ capable of compiling the input programs. Generating extensions can be produced by self-applying partial evaluators, -but this approach may lead to not optimal results or be not scalable -(XXX expand this argument). +but this approach may lead to not optimal results or be not scalable. + +.. XXX expand this argument For PyPy, our approach aims at producing the generating extension more directly from the analysed interpreter in the form of a forest of flow @@ -248,7 +251,9 @@ execution can directly jump to the correct specialized code path. This can also be thought of as a generalisation of polymorphic inline -caches (XXX reference). +caches. + +.. XXX reference Partial Evaluation From arigo at codespeak.net Mon Mar 26 09:15:27 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 26 Mar 2007 09:15:27 +0200 (CEST) Subject: [pypy-svn] r41307 - in pypy/dist/pypy: jit/hintannotator translator translator/goal Message-ID: <20070326071527.32CB410084@code0.codespeak.net> Author: arigo Date: Mon Mar 26 09:15:24 2007 New Revision: 41307 Modified: pypy/dist/pypy/jit/hintannotator/annotator.py pypy/dist/pypy/translator/driver.py pypy/dist/pypy/translator/goal/translate.py Log: A hack for translate.py: if we look at the graphs just after --hintannotate, show the red/green colors of the hint annotations. Modified: pypy/dist/pypy/jit/hintannotator/annotator.py ============================================================================== --- pypy/dist/pypy/jit/hintannotator/annotator.py (original) +++ pypy/dist/pypy/jit/hintannotator/annotator.py Mon Mar 26 09:15:24 2007 @@ -61,6 +61,9 @@ flowgraph = desc.specialize(input_args_hs) return self.build_graph_types(flowgraph, input_args_hs) + def getuserclassdefinitions(self): + return [] + def consider_op_malloc(self, hs_TYPE): TYPE = hs_TYPE.const if self.policy.novirtualcontainer: Modified: pypy/dist/pypy/translator/driver.py ============================================================================== --- pypy/dist/pypy/translator/driver.py (original) +++ pypy/dist/pypy/translator/driver.py Mon Mar 26 09:15:24 2007 @@ -359,6 +359,7 @@ self.portal_graph = graphof(t, PORTAL) hannotator = HintAnnotator(base_translator=t, policy=POLICY) + self.hint_translator = hannotator.translator hs = hannotator.build_types(self.portal_graph, [SomeLLAbstractConstant(v.concretetype, {OriginFlags(): True}) @@ -388,6 +389,7 @@ else: raise Exception('Unsuported cpu %r'%cpu) + del self.hint_translator ha = self.hannotator t = self.translator # make the timeshifted graphs Modified: pypy/dist/pypy/translator/goal/translate.py ============================================================================== --- pypy/dist/pypy/translator/goal/translate.py (original) +++ pypy/dist/pypy/translator/goal/translate.py Mon Mar 26 09:15:24 2007 @@ -214,15 +214,19 @@ async_server = None def __call__(self, port=None, async_only=False): + try: + t1 = drv.hint_translator + except (NameError, AttributeError): + t1 = t if self.async_server is not None: return self.async_server elif port is not None: from pypy.translator.tool.graphserver import run_async_server - serv_start, serv_show, serv_stop = self.async_server = run_async_server(t, translateconfig, port) + serv_start, serv_show, serv_stop = self.async_server = run_async_server(t1, translateconfig, port) return serv_start, serv_show, serv_stop elif not async_only: from pypy.translator.tool.graphserver import run_server_for_inprocess_client - return run_server_for_inprocess_client(t, translateconfig) + return run_server_for_inprocess_client(t1, translateconfig) server_setup = ServerSetup() server_setup(translateconfig.graphserve, async_only=True) From arigo at codespeak.net Mon Mar 26 10:33:20 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 26 Mar 2007 10:33:20 +0200 (CEST) Subject: [pypy-svn] r41309 - pypy/dist/pypy/jit/tl Message-ID: <20070326083320.B958610085@code0.codespeak.net> Author: arigo Date: Mon Mar 26 10:33:19 2007 New Revision: 41309 Added: pypy/dist/pypy/jit/tl/targettiny2.py (contents, props changed) pypy/dist/pypy/jit/tl/tiny2.py (contents, props changed) Log: A "tiny" interpreter, sadly heavily hacked at to be JIT-friendly. Added: pypy/dist/pypy/jit/tl/targettiny2.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/jit/tl/targettiny2.py Mon Mar 26 10:33:19 2007 @@ -0,0 +1,28 @@ +from pypy.jit.tl import tiny2 +from pypy.jit.codegen.hlinfo import highleveljitinfo + + +def entry_point(args): + highleveljitinfo.sys_executable = args[0] + bytecode = [s for s in args[1].split(' ') if s != ''] + args = [tiny2.StrBox(arg) for arg in args[2:]] + res = tiny2.interpret(bytecode, args) + print res.as_str() + return 0 + +def target(driver, args): + return entry_point, None + +# ____________________________________________________________ + +from pypy.jit.hintannotator.annotator import HintAnnotatorPolicy + +class MyHintAnnotatorPolicy(HintAnnotatorPolicy): + novirtualcontainer = True + oopspec = True + + def look_inside_graph(self, graph): + return getattr(graph, 'func', None) is not tiny2.myint_internal + +def portal(driver): + return tiny2.interpret, MyHintAnnotatorPolicy() Added: pypy/dist/pypy/jit/tl/tiny2.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/jit/tl/tiny2.py Mon Mar 26 10:33:19 2007 @@ -0,0 +1,131 @@ +from pypy.rlib.objectmodel import hint, _is_early_constant +import sys + + +INVALID = -sys.maxint-1 + +def myint_internal(s, start=0): + if start >= len(s): + return INVALID + res = 0 + while start < len(s): + c = s[start] + n = ord(c) - ord('0') + if not (0 <= n <= 9): + return INVALID + res = res * 10 + n + start += 1 + return res + +def myint(s, start=0): + if _is_early_constant(s): + s = hint(s, promote=True) + start = hint(start, promote=True) + n = myint_internal(s, start) + if n == INVALID: + raise ValueError + else: + n = myint_internal(s, start) + if n == INVALID: + raise ValueError + return n + + +class Box: + pass + +class IntBox(Box): + def __init__(self, intval): + self.intval = intval + def as_int(self): + return self.intval + def as_str(self): + return str(self.intval) + +class StrBox(Box): + def __init__(self, strval): + self.strval = strval + def as_int(self): + return myint(self.strval) + def as_str(self): + return self.strval + + +def func_add_int(ix, iy): return ix + iy +def func_sub_int(ix, iy): return ix - iy +def func_mul_int(ix, iy): return ix * iy + +def func_add_str(sx, sy): return sx + ' ' + sy +def func_sub_str(sx, sy): return sx + '-' + sy +def func_mul_str(sx, sy): return sx + '*' + sy + +def op2(stack, func_int, func_str): + y = stack.pop() + hint(y.__class__, promote=True) + x = stack.pop() + hint(x.__class__, promote=True) + try: + z = IntBox(func_int(x.as_int(), y.as_int())) + except ValueError: + z = StrBox(func_str(x.as_str(), y.as_str())) + stack.append(z) + + +def interpret(bytecode, args): + hint(None, global_merge_point=True) + bytecode = hint(bytecode, deepfreeze=True) + # ------------------------------ + oldargs = args + argcount = hint(len(oldargs), promote=True) + args = [] + n = 0 + while n < argcount: + hint(n, concrete=True) + args.append(oldargs[n]) + n += 1 + # ------------------------------ + loops = [] + stack = [] + pos = 0 + while pos < len(bytecode): + hint(None, global_merge_point=True) + opcode = bytecode[pos] + hint(opcode, concrete=True) + pos += 1 + if opcode == 'ADD': op2(stack, func_add_int, func_add_str) + elif opcode == 'SUB': op2(stack, func_sub_int, func_sub_str) + elif opcode == 'MUL': op2(stack, func_mul_int, func_mul_str) + elif opcode[0] == '#': + n = myint(opcode, start=1) + stack.append(args[n-1]) + elif opcode.startswith('->#'): + n = myint(opcode, start=3) + args[n-1] = stack.pop() + elif opcode == '{': + loops.append(pos) + elif opcode == '}': + if stack.pop().as_int() == 0: + loops.pop() + else: + pos = loops[-1] + pos = hint(pos, promote=True) + else: + stack.append(StrBox(opcode)) + while len(stack) > 1: + op2(stack, func_add_int, func_add_str) + return stack.pop() + + +def test_main(): + main = """#1 5 ADD""".split() + res = interpret(main, [IntBox(20)]) + assert res.as_int() == 25 + res = interpret(main, [StrBox('foo')]) + assert res.as_str() == 'foo 5' + +FACTORIAL = """The factorial of #1 is + 1 { #1 MUL #1 1 SUB ->#1 #1 }""".split() + +def test_factorial(): + res = interpret(FACTORIAL, [IntBox(5)]) + assert res.as_str() == 'The factorial of 5 is 120' From cfbolz at codespeak.net Mon Mar 26 11:02:12 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 26 Mar 2007 11:02:12 +0200 (CEST) Subject: [pypy-svn] r41311 - pypy/dist/pypy/module/__builtin__ Message-ID: <20070326090212.13ED31007C@code0.codespeak.net> Author: cfbolz Date: Mon Mar 26 11:02:11 2007 New Revision: 41311 Modified: pypy/dist/pypy/module/__builtin__/functional.py Log: don't check explicitely for std object space, since this makes the translation crash with thunk, taint, etc :-( Modified: pypy/dist/pypy/module/__builtin__/functional.py ============================================================================== --- pypy/dist/pypy/module/__builtin__/functional.py (original) +++ pypy/dist/pypy/module/__builtin__/functional.py Mon Mar 26 11:02:11 2007 @@ -85,9 +85,8 @@ except (ValueError, OverflowError): pass else: - if (space.config.objspace.name == "std" and - (space.config.objspace.std.withmultilist or - space.config.objspace.std.withrangelist)): + if (space.config.objspace.std.withmultilist or + space.config.objspace.std.withrangelist): return range_withspecialized_implementation(space, start, step, howmany) res_w = [None] * howmany From arigo at codespeak.net Mon Mar 26 11:02:20 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 26 Mar 2007 11:02:20 +0200 (CEST) Subject: [pypy-svn] r41312 - pypy/dist/pypy/jit/tl Message-ID: <20070326090220.F25B91007C@code0.codespeak.net> Author: arigo Date: Mon Mar 26 11:02:17 2007 New Revision: 41312 Added: pypy/dist/pypy/jit/tl/targettiny1.py (contents, props changed) pypy/dist/pypy/jit/tl/tiny1.py (contents, props changed) Log: The small example from draft-jit.txt. Added: pypy/dist/pypy/jit/tl/targettiny1.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/jit/tl/targettiny1.py Mon Mar 26 11:02:17 2007 @@ -0,0 +1,29 @@ +from pypy.jit.tl import tiny1 +from pypy.jit.codegen.hlinfo import highleveljitinfo + + +def entry_point(args): + highleveljitinfo.sys_executable = args[0] + if len(args) < 4: + print "Usage: %s bytecode x y" % (args[0],) + return 2 + bytecode = args[1] + x = int(args[2]) + y = int(args[3]) + res = tiny1.ll_plus_minus(bytecode, x, y) + print res + return 0 + +def target(driver, args): + return entry_point, None + +# ____________________________________________________________ + +from pypy.jit.hintannotator.annotator import HintAnnotatorPolicy + +class MyHintAnnotatorPolicy(HintAnnotatorPolicy): + novirtualcontainer = True + oopspec = True + +def portal(driver): + return tiny2.interpret, MyHintAnnotatorPolicy() Added: pypy/dist/pypy/jit/tl/tiny1.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/jit/tl/tiny1.py Mon Mar 26 11:02:17 2007 @@ -0,0 +1,20 @@ +from pypy.rlib.objectmodel import hint + + +def ll_plus_minus(s, x, y): + acc = x + pc = 0 + while pc < len(s): + op = s[pc] + op = hint(op, concrete=True) + if op == '+': + acc += y + elif op == '-': + acc -= y + pc += 1 + return acc + + +def test_simple(): + res = ll_plus_minus("+-++", 100, 10) + assert res == 120 From mwh at codespeak.net Mon Mar 26 11:17:12 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Mon, 26 Mar 2007 11:17:12 +0200 (CEST) Subject: [pypy-svn] r41314 - pypy/extradoc/planning/1.0 Message-ID: <20070326091712.C525A10085@code0.codespeak.net> Author: mwh Date: Mon Mar 26 11:17:10 2007 New Revision: 41314 Modified: pypy/extradoc/planning/1.0/TODO.txt Log: update a filename Modified: pypy/extradoc/planning/1.0/TODO.txt ============================================================================== --- pypy/extradoc/planning/1.0/TODO.txt (original) +++ pypy/extradoc/planning/1.0/TODO.txt Mon Mar 26 11:17:10 2007 @@ -46,7 +46,7 @@ make correct 404 and 500 pages - discuss/do a JIT demo - - update wp6 docs (object-optimizations.txt) and link + - update wp6 docs (interpreter-optimizations.txt) and link to them from getting-started (mwh to coordinate) ropes docs added From xoraxax at codespeak.net Mon Mar 26 11:19:10 2007 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Mon, 26 Mar 2007 11:19:10 +0200 (CEST) Subject: [pypy-svn] r41315 - pypy/dist/pypy/module/__builtin__ Message-ID: <20070326091910.D149710068@code0.codespeak.net> Author: xoraxax Date: Mon Mar 26 11:19:09 2007 New Revision: 41315 Modified: pypy/dist/pypy/module/__builtin__/app_functional.py Log: Move operator import to inner functions to see if this fixes some recursive gateway usage problems. Modified: pypy/dist/pypy/module/__builtin__/app_functional.py ============================================================================== --- pypy/dist/pypy/module/__builtin__/app_functional.py (original) +++ pypy/dist/pypy/module/__builtin__/app_functional.py Mon Mar 26 11:19:09 2007 @@ -4,7 +4,6 @@ """ from __future__ import generators -from operator import lt, gt def sum(sequence, total=0): @@ -203,9 +202,6 @@ # ____________________________________________________________ -# min and max could be one function if we had operator.__gt__ and -# operator.__lt__ Perhaps later when we have operator. - def _identity(arg): return arg @@ -214,6 +210,7 @@ def min(*arr, **kwargs): """return the smallest number in a list, or its smallest argument if more than one is given.""" + from operator import gt return min_max(gt, "min", *arr, **kwargs) @@ -246,6 +243,7 @@ def max(*arr, **kwargs): """return the largest number in a list, or its largest argument if more than one is given.""" + from operator import lt return min_max(lt, "max", *arr, **kwargs) From antocuni at codespeak.net Mon Mar 26 11:50:40 2007 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Mon, 26 Mar 2007 11:50:40 +0200 (CEST) Subject: [pypy-svn] r41316 - pypy/dist/lib-python/modified-2.4.1 Message-ID: <20070326095040.F3F741006E@code0.codespeak.net> Author: antocuni Date: Mon Mar 26 11:50:40 2007 New Revision: 41316 Modified: pypy/dist/lib-python/modified-2.4.1/site.py Log: (antocuni, xoraxax) Work-around a not well specified CPython behaviour and make py.py starting on windows Modified: pypy/dist/lib-python/modified-2.4.1/site.py ============================================================================== --- pypy/dist/lib-python/modified-2.4.1/site.py (original) +++ pypy/dist/lib-python/modified-2.4.1/site.py Mon Mar 26 11:50:40 2007 @@ -349,7 +349,7 @@ if sys.platform == 'win32': import locale, codecs enc = locale.getdefaultlocale()[1] - if enc.startswith('cp'): # "cp***" ? + if enc is not None and enc.startswith('cp'): # "cp***" ? try: codecs.lookup(enc) except LookupError: From guido at codespeak.net Mon Mar 26 12:14:19 2007 From: guido at codespeak.net (guido at codespeak.net) Date: Mon, 26 Mar 2007 12:14:19 +0200 (CEST) Subject: [pypy-svn] r41319 - in pypy/dist/pypy: bin tool/build Message-ID: <20070326101419.8189E1007F@code0.codespeak.net> Author: guido Date: Mon Mar 26 12:14:17 2007 New Revision: 41319 Modified: pypy/dist/pypy/bin/buildserver.py pypy/dist/pypy/bin/startcompile.py pypy/dist/pypy/tool/build/compile.py pypy/dist/pypy/tool/build/multibuild.py Log: Some indentation, removed unused import, added print when zip downloading starts (in compile.py). Modified: pypy/dist/pypy/bin/buildserver.py ============================================================================== --- pypy/dist/pypy/bin/buildserver.py (original) +++ pypy/dist/pypy/bin/buildserver.py Mon Mar 26 12:14:17 2007 @@ -35,14 +35,14 @@ from pypy.tool.udir import udir from pypy.config.pypyoption import get_pypy_config - from pypy.translator.goal.translate import translate_optiondescr + from pypy.translator.goal.translate import \ + translate_optiondescr from pypy.tool.build.compileoption import combine_config from pypy.config.config import Config pypy_config = get_pypy_config() translate_config = Config(translate_optiondescr) - config = combine_config(pypy_config, translate_config, 'pypy', - 'pypy options') - open('/tmp/compileinfo', 'w').write(repr(compileinfo)) + config = combine_config(pypy_config, translate_config, + 'pypy', 'pypy options') config.override(compileinfo) targetpypystandalone.PyPyTarget.translateconfig = config Modified: pypy/dist/pypy/bin/startcompile.py ============================================================================== --- pypy/dist/pypy/bin/startcompile.py (original) +++ pypy/dist/pypy/bin/startcompile.py Mon Mar 26 12:14:17 2007 @@ -3,7 +3,6 @@ import autopath from pypy.tool.build import config from pypy.tool.build.compile import main, getrequest -from py.execnet import SshGateway, PopenGateway request, foreground = getrequest(config) main(config, request, foreground) Modified: pypy/dist/pypy/tool/build/compile.py ============================================================================== --- pypy/dist/pypy/tool/build/compile.py (original) +++ pypy/dist/pypy/tool/build/compile.py Mon Mar 26 12:14:17 2007 @@ -193,9 +193,10 @@ break time.sleep(POLLTIME) if error and error != 'None': - print 'error:', error + print 'error compiling:', error return (False, error) else: + print 'compilation finished successfully, downloading zip file' zipfile = py.path.local('pypy-%s.zip' % (reqid,)) msa.save_zip(zipfile) print 'done, the result can be found in %s' % (zipfile,) Modified: pypy/dist/pypy/tool/build/multibuild.py ============================================================================== --- pypy/dist/pypy/tool/build/multibuild.py (original) +++ pypy/dist/pypy/tool/build/multibuild.py Mon Mar 26 12:14:17 2007 @@ -38,7 +38,7 @@ try: override_conf(config, opts) except: - return exe_name_from_options(newconfig.compile_config, opts), \ + return exe_name_from_options(config.compile_config, opts), \ "didn't configure" request, foreground = getrequest(config, sys.argv[3:]) hasbuilt, message = main(config, request, True) From guido at codespeak.net Mon Mar 26 12:22:43 2007 From: guido at codespeak.net (guido at codespeak.net) Date: Mon, 26 Mar 2007 12:22:43 +0200 (CEST) Subject: [pypy-svn] r41320 - pypy/dist/pypy/tool/build/web Message-ID: <20070326102243.1D3E51007F@code0.codespeak.net> Author: guido Date: Mon Mar 26 12:22:41 2007 New Revision: 41320 Modified: pypy/dist/pypy/tool/build/web/app.py Log: Using the compile_config from tool/build/config.py instead of the 'raw' PyPy config to find out what options were given in the web tool build page (somewhat untested). Modified: pypy/dist/pypy/tool/build/web/app.py ============================================================================== --- pypy/dist/pypy/tool/build/web/app.py (original) +++ pypy/dist/pypy/tool/build/web/app.py Mon Mar 26 12:22:41 2007 @@ -46,14 +46,15 @@ from pypy.config.pypyoption import get_pypy_config from pypy.config.config import Config from pypy.translator.driver import DEFAULTS - config = get_pypy_config(DEFAULTS, translating=True) - def add(config, path_upto_here="", outermost=False): + #config = get_pypy_config(DEFAULTS, translating=True) + cconfig = config.compile_config.copy() + def add(cconfig, path_upto_here="", outermost=False): items = [] children = [(child._name, child) - for child in config._cfgimpl_descr._children] + for child in cconfig._cfgimpl_descr._children] children.sort() for name, child in children: - value_default = getattr(config, name) + value_default = getattr(cconfig, name) if path_upto_here: subpath = path_upto_here + "." + name else: @@ -78,7 +79,7 @@ if outermost and not lines: return "" return "\n ".join(items) - return "
      %s
    " % (add(config, outermost=False), ) + return "
      %s
    " % (add(cconfig, outermost=False), ) class ServerPage(object): """ base class for pages that communicate with the server @@ -355,7 +356,6 @@ # be found, this page will raise an exception) return LogPage(name, self.config, self.gateway) - class LogPage(ServerPage): def __init__(self, buildid, config, gateway=None): super(LogPage, self).__init__(config, gateway) From cfbolz at codespeak.net Mon Mar 26 12:33:02 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 26 Mar 2007 12:33:02 +0200 (CEST) Subject: [pypy-svn] r41321 - pypy/dist/pypy/config Message-ID: <20070326103302.7448A1007B@code0.codespeak.net> Author: cfbolz Date: Mon Mar 26 12:33:01 2007 New Revision: 41321 Modified: pypy/dist/pypy/config/pypyoption.py Log: remove some modules from --allworkingmodules under windows (because they don't work). Modified: pypy/dist/pypy/config/pypyoption.py ============================================================================== --- pypy/dist/pypy/config/pypyoption.py (original) +++ pypy/dist/pypy/config/pypyoption.py Mon Mar 26 12:33:01 2007 @@ -1,7 +1,6 @@ import autopath import py, os import sys -import platform from pypy.config.config import OptionDescription, BoolOption, IntOption, ArbitraryOption from pypy.config.config import ChoiceOption, StrOption, to_optparse, Config @@ -28,6 +27,13 @@ ] )) +if sys.platform == "win32": + del working_modules["rsocket"] + del working_modules["fcntl"] + del working_modules["select"] + del working_modules["readline"] + + module_dependencies = { } if os.name == "posix": module_dependencies['rctime'] = [("objspace.usemodules.select", True),] From arigo at codespeak.net Mon Mar 26 12:39:06 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 26 Mar 2007 12:39:06 +0200 (CEST) Subject: [pypy-svn] r41322 - pypy/dist/pypy/doc Message-ID: <20070326103906.53E971007B@code0.codespeak.net> Author: arigo Date: Mon Mar 26 12:39:05 2007 New Revision: 41322 Modified: pypy/dist/pypy/doc/_ref.txt pypy/dist/pypy/doc/index.txt pypy/dist/pypy/doc/jit.txt Log: Document the tiny1.py interpreter. Fix links. Modified: pypy/dist/pypy/doc/_ref.txt ============================================================================== --- pypy/dist/pypy/doc/_ref.txt (original) +++ pypy/dist/pypy/doc/_ref.txt Mon Mar 26 12:39:05 2007 @@ -39,6 +39,9 @@ .. _`jit/timeshifter/`: ../../pypy/jit/timeshifter .. _`pypy/jit/timeshifter/rvalue.py`: ../../pypy/jit/timeshifter/rvalue.py .. _`jit/tl/`: ../../pypy/jit/tl +.. _`pypy/jit/tl/targettiny1.py`: ../../pypy/jit/tl/targettiny1.py +.. _`pypy/jit/tl/tiny1.py`: ../../pypy/jit/tl/tiny1.py +.. _`pypy/jit/tl/tiny2.py`: ../../pypy/jit/tl/tiny2.py .. _`lang/`: ../../pypy/lang .. _`lang/js/`: ../../pypy/lang/js .. _`lang/prolog/`: ../../pypy/lang/prolog Modified: pypy/dist/pypy/doc/index.txt ============================================================================== --- pypy/dist/pypy/doc/index.txt (original) +++ pypy/dist/pypy/doc/index.txt Mon Mar 26 12:39:05 2007 @@ -334,9 +334,9 @@ .. _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 +.. _`jit backends`: discussion/jit-draft.html#backends +.. _`hint-annotator`: discussion/jit-draft.html#hint-annotator +.. _`timeshifter`: discussion/jit-draft.html#timeshifter .. _rtyper: rtyper.html .. _`low-level type system`: rtyper.html#low-level-type .. _`object-oriented type system`: rtyper.html#oo-type Modified: pypy/dist/pypy/doc/jit.txt ============================================================================== --- pypy/dist/pypy/doc/jit.txt (original) +++ pypy/dist/pypy/doc/jit.txt Mon Mar 26 12:39:05 2007 @@ -161,19 +161,182 @@ Aside from the obvious advantage, it means that we can show all the basic ideas of the technique on a tiny interpreter. The fact that we have done the same on the whole of PyPy shows that the approach scales -well. So we will follow in the sequel the example of a tiny interpreter -and insert a JIT compiler into it during translation. +well. So we will follow in the sequel the example of small interpreters +and insert a JIT compiler into them during translation. -A tiny interpreter -================== +The important terms: + +* *Translation time*: while you are running ``translate.py`` to produce + the static executable. + +* *Compile time*: when the JIT compiler runs. This really occurs at + runtime, as it is a Just-In-Time compiler, but we need a consistent + way of naming the part of runtime that is occupied by running the + JIT support code and generating more machine code. + +* *Run time*: the execution of the user program. This can mean either + when the interpreter runs (for parts of the user program that have not + been JIT-compiled), or when the generated machine code runs. + + +A first example +=============== + +Source +------ + +Let's consider a very small interpreter-like example:: + + def ll_plus_minus(s, x, y): + acc = x + pc = 0 + while pc < len(s): + op = s[pc] + hint(op, concrete=True) + if op == '+': + acc += y + elif op == '-': + acc -= y + pc += 1 + return acc + +Here, ``s`` is an input program which is simply a string of ``'+'`` or +``'-'``. The ``x`` and ``y`` are integer input arguments. The source +code of this example is in `pypy/jit/tl/tiny1.py`_. + +Hint +---- + +Ideally, turning an interpreter into a JIT compiler is only a matter of +adding a few hints. In practice, the current JIT generation framework +has many limitations and rough edges requiring workarounds. On the +above example, though, it works out of the box. We only need one hint, +the central hint that all interpreter need. In the source, it is the line:: + + hint(op, concrete=True) + +This hint says: "at this point in time, ensure that ``op`` is a +compile-time constant". The motivation for such a hint is that the most +important source of inefficiency in a small interpreter is the switch on +the next opcode, here ``op``. If ``op`` is known at the time where the +JIT compiler runs, then the whole switch dispatch and be constant-folded +away; only the case that applies remains. + +The way the ``concrete=True`` hint works is by setting a constraint: it +requires ``op`` to be a compile-time constant. During translation, a +phase called *hint-annotation* processes these hints and tries to +satisfy the constraints. Without further hints, the only way that +``op`` could be a compile-time constant is if all the other values that +``op`` depends on are also compile-time constants. So the +hint-annotator will also mark ``s`` and ``pc`` as compile-time +constants. + +Colors +------ + +You can see the results of the hint-annotator with the following +commands:: + + cd pypy/jit/tl + python ../../translator/goal/translate.py --hintannotate targettiny1.py + +Click on ``ll_plus_minus`` in the Pygame viewer to get a nicely colored +graph of that function. The graph contains the low-level operations +produced by RTyping. The *green* variables are the ones that have been +forced to be compile-time constants by the hint-annotator. The *red* +variables are the ones that will generally not be compile-time +constants, although the JIT compiler is also able to do constant +propagation of red variables if they contain compile-time constants in +the first place. + +In this example, when the JIT runs, it generates machine code that is +simply a list of additions and subtractions, as indicated by the ``'+'`` +and ``'-'`` characters in the input string. To understand why it does +this, consider the colored graph of ``ll_plus_minus`` more closely. A +way to understand this graph is to consider that it is no longer the +graph of the ``ll_plus_minus`` interpreter, but really the graph of the +JIT compiler itself. All operations involving only green variables will +be performed by the JIT compiler at compile-time. In this case, the +whole looping code only involves the green variables ``s`` and ``pc``, +so the JIT compiler itself will loop over all the opcodes of the +bytecode string ``s``, fetch the characters and do the switch on them. +The only operations involving red variables are the ``int_add`` and +``int_sub`` operations in the implementation of the ``'+'`` and ``'-'`` +opcodes respectively. These are the operations that will be generated +as machine code by the JIT. + +Over-simplifying, we can say that at the end of translation, in the +actual implementation of the JIT compiler, operations involving only +green variables are kept unchanged, and operations involving red +variables have been replaced by calls to helpers. These helpers contain +the logic to generate a copy of the original operation, as machine code, +directly into memory. + +Translating +----------- + +Now try translating ``tiny1.py`` with a JIT without stopping at the +hint-annotation viewer:: + + python ../../translator/goal/translate.py --jit targettiny1.py + +Test it:: + + ./targettiny1-c +++-+++ 100 10 + 150 + +What occurred here is that the colored graph seen above was turned into +a JIT compiler, and the original ``ll_plus_minus`` function was patched. +Whenever that function is called from the rest of the program (in this +case, from ``entry_point()`` in `pypy/jit/tl/targettiny1.py`_), then +instead of the original code performing the interpretation, the patched +function performs the following operations: + +* It looks up the value of its green argument ``s`` in a cache (the red + ``x`` and ``y`` are not considered here). + +* If the cache does not contain a corresponding entry, the JIT compiler + is called to produce machine code. At this point, we pass to the JIT + compiler the value of ``s`` as a compile-time constant, but ``x`` and + ``y`` remain variables. + +* Finally, the machine code (either just produced or retrieved from the + cache) is invoked with the actual values of ``x`` and ``y``. + +The idea is that interpreting the same bytecode over and over again with +different values of ``x`` and ``y`` should be the fast path: the +compilation step is only required the first time. + +On 386-compatible processors running Linux, you can inspect the +generated machine code as follows:: + + PYPYJITLOG=log ./targettiny1-c +++-+++ 100 10 + python ../../jit/codegen/i386/viewcode.py log + +If you are familiar with GNU-style 386 assembler, you will notice that +the code is a single block with no jump, containing the three additions, +the subtraction, and the three further additions. The machine code is +not particularly optimal in this example because all the values are +input arguments of the function, so they are reloaded and stored back in +the stack at every operation. The current backend tends to use +registers in a (slightly) more reasonable way on more complicated +examples. +A (slightly less) tiny interpreter +================================== + +`pypy/jit/tl/tiny2.py`_ XXX ------------------------------------------------------------------------ JIT Compiler Generation - Theory ------------------------------------------------------------------------ +.. _warning: + + This section is work in progress! + Introduction ============ @@ -330,9 +493,9 @@ For more information ==================== -The `expanded version of the present document`_ is mostly unreadable, -but may be of interest to you if you are already familiar with the -domain of Partial Evaluation. +The `expanded version of the present document`_ may be of interest to +you if you are already familiar with the domain of Partial Evaluation +and are looking for a quick overview of some of our techniques. .. _`expanded version of the present document`: discussion/jit-draft.html From mwh at codespeak.net Mon Mar 26 12:42:53 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Mon, 26 Mar 2007 12:42:53 +0200 (CEST) Subject: [pypy-svn] r41323 - pypy/dist/pypy/config Message-ID: <20070326104253.9A2791007B@code0.codespeak.net> Author: mwh Date: Mon Mar 26 12:42:52 2007 New Revision: 41323 Modified: pypy/dist/pypy/config/pypyoption.py Log: add an --alloptimizations command line synonym for --faassen. i just can't bring myself to document the latter... Modified: pypy/dist/pypy/config/pypyoption.py ============================================================================== --- pypy/dist/pypy/config/pypyoption.py (original) +++ pypy/dist/pypy/config/pypyoption.py Mon Mar 26 12:42:52 2007 @@ -248,7 +248,7 @@ ("objspace.std.withprebuiltchar", True), # ("objspace.std.optimized_int_add", True), ], - cmdline="--faassen", negation=False), + cmdline="--alloptimizations --faassen", negation=False), ## BoolOption("llvmallopts", ## "enable all optimizations, and use llvm compiled via C", From mwh at codespeak.net Mon Mar 26 12:45:17 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Mon, 26 Mar 2007 12:45:17 +0200 (CEST) Subject: [pypy-svn] r41324 - pypy/dist/pypy/config Message-ID: <20070326104517.349991007B@code0.codespeak.net> Author: mwh Date: Mon Mar 26 12:45:16 2007 New Revision: 41324 Modified: pypy/dist/pypy/config/pypyoption.py Log: argh, tweaking so :config:`objspace.std.allopts` says --allopts, not --faassen Modified: pypy/dist/pypy/config/pypyoption.py ============================================================================== --- pypy/dist/pypy/config/pypyoption.py (original) +++ pypy/dist/pypy/config/pypyoption.py Mon Mar 26 12:45:16 2007 @@ -248,7 +248,7 @@ ("objspace.std.withprebuiltchar", True), # ("objspace.std.optimized_int_add", True), ], - cmdline="--alloptimizations --faassen", negation=False), + cmdline="--allopts --faassen", negation=False), ## BoolOption("llvmallopts", ## "enable all optimizations, and use llvm compiled via C", From guido at codespeak.net Mon Mar 26 12:45:33 2007 From: guido at codespeak.net (guido at codespeak.net) Date: Mon, 26 Mar 2007 12:45:33 +0200 (CEST) Subject: [pypy-svn] r41325 - pypy/dist/pypy/tool/build/web Message-ID: <20070326104533.4782D1007F@code0.codespeak.net> Author: guido Date: Mon Mar 26 12:45:32 2007 New Revision: 41325 Modified: pypy/dist/pypy/tool/build/web/app.py Log: Not linking to config items in goal_options anymore. Modified: pypy/dist/pypy/tool/build/web/app.py ============================================================================== --- pypy/dist/pypy/tool/build/web/app.py (original) +++ pypy/dist/pypy/tool/build/web/app.py Mon Mar 26 12:45:32 2007 @@ -43,6 +43,7 @@ def format_compileinfo(compileinfo): # XXX hack and partially copied from Config.__str__ + from urllib import quote from pypy.config.pypyoption import get_pypy_config from pypy.config.config import Config from pypy.translator.driver import DEFAULTS @@ -72,10 +73,13 @@ continue if value == value_default: continue - url = "http://codespeak.net/pypy/dist/pypy/doc/config/" - url += subpath + ".html" - items.append('
  • %s = %s
  • ' % ( - url, name, value)) + if path_upto_here == 'goal_options': + title = name + else: + url = "http://codespeak.net/pypy/dist/pypy/doc/config/" + url += quote(subpath) + ".html" + title = '%s' % (url, name) + items.append('
  • %s = %s
  • ' % (title, value)) if outermost and not lines: return "" return "\n ".join(items) From mwh at codespeak.net Mon Mar 26 12:46:12 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Mon, 26 Mar 2007 12:46:12 +0200 (CEST) Subject: [pypy-svn] r41327 - pypy/dist/pypy/doc Message-ID: <20070326104612.C88111007B@code0.codespeak.net> Author: mwh Date: Mon Mar 26 12:46:11 2007 New Revision: 41327 Modified: pypy/dist/pypy/doc/interpreter-optimizations.txt Log: link to some config documentation Modified: pypy/dist/pypy/doc/interpreter-optimizations.txt ============================================================================== --- pypy/dist/pypy/doc/interpreter-optimizations.txt (original) +++ pypy/dist/pypy/doc/interpreter-optimizations.txt Mon Mar 26 12:46:11 2007 @@ -334,6 +334,9 @@ if it is not None, then it is considered to be an additional first argument in the call to the *im_func* object from the stack. +You can enable this feature with the :config:`objspace.opcodes.CALL_METHOD` +option. + .. _`call likely builtin`: CALL_LIKELY_BUILTIN @@ -359,6 +362,9 @@ full lookups. In the common case, neither of these cases is true, so the builtin can be directly invoked. +You can enable this feature with the +:config:`objspace.opcodes.CALL_LIKELY_BUILTIN` option. + .. more here? Overall Effects @@ -378,5 +384,6 @@ .. waffles about ropes -A build with all the generally useful optimizations turned on is between 1.5 and -2.5 times faster than one without, depending on the benchmark. +You can build a pypy with all generally useful optimizations turned on by using +the :config:`objspace.std.allopts` option. Such a build is between 1.5 and 2.5 +times faster than the default, depending on the benchmark. From auc at codespeak.net Mon Mar 26 12:48:45 2007 From: auc at codespeak.net (auc at codespeak.net) Date: Mon, 26 Mar 2007 12:48:45 +0200 (CEST) Subject: [pypy-svn] r41328 - pypy/dist/pypy/config Message-ID: <20070326104845.CCDB11007B@code0.codespeak.net> Author: auc Date: Mon Mar 26 12:48:44 2007 New Revision: 41328 Modified: pypy/dist/pypy/config/pypyoption.py Log: this may help ... Modified: pypy/dist/pypy/config/pypyoption.py ============================================================================== --- pypy/dist/pypy/config/pypyoption.py (original) +++ pypy/dist/pypy/config/pypyoption.py Mon Mar 26 12:48:44 2007 @@ -46,6 +46,7 @@ requires = { "logic": [#("objspace.geninterp", False), ("objspace.usemodules._stackless", True), + ("objspace.usemodules._cslib", True), ("objspace.usemodules.cclp", True), ("translation.gc", 'framework'), ], From guido at codespeak.net Mon Mar 26 12:58:06 2007 From: guido at codespeak.net (guido at codespeak.net) Date: Mon, 26 Mar 2007 12:58:06 +0200 (CEST) Subject: [pypy-svn] r41329 - pypy/dist/pypy/tool/build Message-ID: <20070326105806.1291C1007B@code0.codespeak.net> Author: guido Date: Mon Mar 26 12:58:06 2007 New Revision: 41329 Modified: pypy/dist/pypy/tool/build/multibuild.py Log: Added MAX_ACTIVE_THREADS switch that controls how many active threads there can be at max, removed some stupid line of debug code. Modified: pypy/dist/pypy/tool/build/multibuild.py ============================================================================== --- pypy/dist/pypy/tool/build/multibuild.py (original) +++ pypy/dist/pypy/tool/build/multibuild.py Mon Mar 26 12:58:06 2007 @@ -9,10 +9,13 @@ import random import os import threading +import time from pypy.translator.goal.multibuild import get_options, exe_name_from_options from pypy.tool.build import config from pypy.tool.build.compile import getrequest, main +MAX_ACTIVE_THREADS = 5 + class ConfigWrapper(object): def __init__(self, orgconfig): self.__dict__.update(orgconfig.__dict__) @@ -42,7 +45,6 @@ "didn't configure" request, foreground = getrequest(config, sys.argv[3:]) hasbuilt, message = main(config, request, True) - hasbuilt, message = (True, 'foo') return hasbuilt and 'successfully built' or 'not built: %s' % (message,) def wait_until_done(): @@ -84,6 +86,14 @@ t = threading.Thread(target=build_pypy_with_options, args=(basedir, opts)) t.start() + while 1: + # tiny bit of slack to the server + time.sleep(1) + active = len([t for t in threading.enumerate() if t.isAlive() and + t != threading.currentThread()]) + if active < MAX_ACTIVE_THREADS: + break + wait_until_done() print 'done' From guido at codespeak.net Mon Mar 26 13:06:07 2007 From: guido at codespeak.net (guido at codespeak.net) Date: Mon, 26 Mar 2007 13:06:07 +0200 (CEST) Subject: [pypy-svn] r41330 - pypy/dist/pypy/tool/build Message-ID: <20070326110607.15BE310083@code0.codespeak.net> Author: guido Date: Mon Mar 26 13:05:59 2007 New Revision: 41330 Modified: pypy/dist/pypy/tool/build/multibuild.py Log: Count only threads we spawned ourselves... :| Modified: pypy/dist/pypy/tool/build/multibuild.py ============================================================================== --- pypy/dist/pypy/tool/build/multibuild.py (original) +++ pypy/dist/pypy/tool/build/multibuild.py Mon Mar 26 13:05:59 2007 @@ -50,7 +50,7 @@ def wait_until_done(): while 1: for t in threading.enumerate(): - if t != threading.currentThread() and t.isAlive(): + if t.getName().startswith('buildthread-') and t.isAlive(): t.join() else: break @@ -82,15 +82,16 @@ results = [] options = list(get_options(optionsfile)) random.shuffle(options) - for opts in options: + for i, opts in enumerate(options): t = threading.Thread(target=build_pypy_with_options, args=(basedir, opts)) t.start() + t.setName('buildthread-%s' % (i,)) while 1: # tiny bit of slack to the server time.sleep(1) active = len([t for t in threading.enumerate() if t.isAlive() and - t != threading.currentThread()]) + t.getName().startswith('buildthread-')]) if active < MAX_ACTIVE_THREADS: break From cfbolz at codespeak.net Mon Mar 26 13:06:48 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 26 Mar 2007 13:06:48 +0200 (CEST) Subject: [pypy-svn] r41331 - pypy/dist/pypy/tool/build Message-ID: <20070326110648.E455010084@code0.codespeak.net> Author: cfbolz Date: Mon Mar 26 13:06:43 2007 New Revision: 41331 Modified: pypy/dist/pypy/tool/build/config.py Log: aargh! this should really be translating = True. otherwise you can get really funny effects. Modified: pypy/dist/pypy/tool/build/config.py ============================================================================== --- pypy/dist/pypy/tool/build/config.py (original) +++ pypy/dist/pypy/tool/build/config.py Mon Mar 26 13:06:43 2007 @@ -27,7 +27,7 @@ from pypy.config.pypyoption import get_pypy_config from pypy.translator.goal.translate import translate_optiondescr from pypy.tool.build.compileoption import combine_config -pypy_config = get_pypy_config() +pypy_config = get_pypy_config(translating=True) pypy_config.override({'translation.backend': 'c', 'translation.gc': 'boehm'}) translate_config = Config(translate_optiondescr) From xoraxax at codespeak.net Mon Mar 26 13:15:40 2007 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Mon, 26 Mar 2007 13:15:40 +0200 (CEST) Subject: [pypy-svn] r41335 - pypy/dist/pypy/jit/tl Message-ID: <20070326111540.D485910083@code0.codespeak.net> Author: xoraxax Date: Mon Mar 26 13:15:35 2007 New Revision: 41335 Modified: pypy/dist/pypy/jit/tl/targettiny1.py Log: Fix the portal in targettiny1. Modified: pypy/dist/pypy/jit/tl/targettiny1.py ============================================================================== --- pypy/dist/pypy/jit/tl/targettiny1.py (original) +++ pypy/dist/pypy/jit/tl/targettiny1.py Mon Mar 26 13:15:35 2007 @@ -26,4 +26,4 @@ oopspec = True def portal(driver): - return tiny2.interpret, MyHintAnnotatorPolicy() + return tiny1.ll_plus_minus, MyHintAnnotatorPolicy() From arigo at codespeak.net Mon Mar 26 13:18:15 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 26 Mar 2007 13:18:15 +0200 (CEST) Subject: [pypy-svn] r41336 - pypy/dist/pypy/jit/tl Message-ID: <20070326111815.80C4C10083@code0.codespeak.net> Author: arigo Date: Mon Mar 26 13:18:12 2007 New Revision: 41336 Modified: pypy/dist/pypy/jit/tl/tiny1.py pypy/dist/pypy/jit/tl/tiny2.py Log: Shuffle things around. Modified: pypy/dist/pypy/jit/tl/tiny1.py ============================================================================== --- pypy/dist/pypy/jit/tl/tiny1.py (original) +++ pypy/dist/pypy/jit/tl/tiny1.py Mon Mar 26 13:18:12 2007 @@ -6,7 +6,7 @@ pc = 0 while pc < len(s): op = s[pc] - op = hint(op, concrete=True) + hint(op, concrete=True) if op == '+': acc += y elif op == '-': Modified: pypy/dist/pypy/jit/tl/tiny2.py ============================================================================== --- pypy/dist/pypy/jit/tl/tiny2.py (original) +++ pypy/dist/pypy/jit/tl/tiny2.py Mon Mar 26 13:18:12 2007 @@ -1,34 +1,4 @@ from pypy.rlib.objectmodel import hint, _is_early_constant -import sys - - -INVALID = -sys.maxint-1 - -def myint_internal(s, start=0): - if start >= len(s): - return INVALID - res = 0 - while start < len(s): - c = s[start] - n = ord(c) - ord('0') - if not (0 <= n <= 9): - return INVALID - res = res * 10 + n - start += 1 - return res - -def myint(s, start=0): - if _is_early_constant(s): - s = hint(s, promote=True) - start = hint(start, promote=True) - n = myint_internal(s, start) - if n == INVALID: - raise ValueError - else: - n = myint_internal(s, start) - if n == INVALID: - raise ValueError - return n class Box: @@ -116,6 +86,33 @@ return stack.pop() +def myint_internal(s, start=0): + if start >= len(s): + return -1 + res = 0 + while start < len(s): + c = s[start] + n = ord(c) - ord('0') + if not (0 <= n <= 9): + return -1 + res = res * 10 + n + start += 1 + return res + +def myint(s, start=0): + if _is_early_constant(s): + s = hint(s, promote=True) + start = hint(start, promote=True) + n = myint_internal(s, start) + if n < 0: + raise ValueError + else: + n = myint_internal(s, start) + if n < 0: + raise ValueError + return n + + def test_main(): main = """#1 5 ADD""".split() res = interpret(main, [IntBox(20)]) From xoraxax at codespeak.net Mon Mar 26 13:31:01 2007 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Mon, 26 Mar 2007 13:31:01 +0200 (CEST) Subject: [pypy-svn] r41337 - pypy/dist/pypy/translator/goal Message-ID: <20070326113101.7810310083@code0.codespeak.net> Author: xoraxax Date: Mon Mar 26 13:30:59 2007 New Revision: 41337 Modified: pypy/dist/pypy/translator/goal/translate.py Log: Bail out in translate.py if the target could not be found. Modified: pypy/dist/pypy/translator/goal/translate.py ============================================================================== --- pypy/dist/pypy/translator/goal/translate.py (original) +++ pypy/dist/pypy/translator/goal/translate.py Mon Mar 26 13:30:59 2007 @@ -147,7 +147,8 @@ elif os.path.isfile(arg) and arg.endswith('.py'): translateconfig.targetspec = arg[:-3] else: - args = [arg] + args + log.ERROR("Could not find target %r" % (arg, )) + sys.exit(1) targetspec = translateconfig.targetspec targetspec_dic = load_target(targetspec) From xoraxax at codespeak.net Mon Mar 26 13:38:54 2007 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Mon, 26 Mar 2007 13:38:54 +0200 (CEST) Subject: [pypy-svn] r41340 - pypy/dist/pypy/jit/tl Message-ID: <20070326113854.17A9F10085@code0.codespeak.net> Author: xoraxax Date: Mon Mar 26 13:38:51 2007 New Revision: 41340 Modified: pypy/dist/pypy/jit/tl/targettiny2.py Log: Do arg checking in targettiny2.py to avoid segfaults. Modified: pypy/dist/pypy/jit/tl/targettiny2.py ============================================================================== --- pypy/dist/pypy/jit/tl/targettiny2.py (original) +++ pypy/dist/pypy/jit/tl/targettiny2.py Mon Mar 26 13:38:51 2007 @@ -4,6 +4,10 @@ def entry_point(args): highleveljitinfo.sys_executable = args[0] + if len(args) < 3: + print "Invalid command line arguments." + print args[0] + " 'tiny2 program string' arg0 [arg1 [arg2 [...]]]" + return 1 bytecode = [s for s in args[1].split(' ') if s != ''] args = [tiny2.StrBox(arg) for arg in args[2:]] res = tiny2.interpret(bytecode, args) From cfbolz at codespeak.net Mon Mar 26 13:57:40 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 26 Mar 2007 13:57:40 +0200 (CEST) Subject: [pypy-svn] r41344 - pypy/dist/pypy/translator/c/src Message-ID: <20070326115740.BCACA1008F@code0.codespeak.net> Author: cfbolz Date: Mon Mar 26 13:57:39 2007 New Revision: 41344 Modified: pypy/dist/pypy/translator/c/src/main.h Log: change to "Fatal RPython error" to make it more sensible for other targets than targetpypystandalone Modified: pypy/dist/pypy/translator/c/src/main.h ============================================================================== --- pypy/dist/pypy/translator/c/src/main.h (original) +++ pypy/dist/pypy/translator/c/src/main.h Mon Mar 26 13:57:39 2007 @@ -38,7 +38,7 @@ if (RPyExceptionOccurred()) { /* fish for the exception type, at least */ #ifndef AVR - fprintf(stderr, "Fatal PyPy error: %s\n", + fprintf(stderr, "Fatal RPython error: %s\n", RPyFetchExceptionType()->ov_name->items); #endif exitcode = 1; From guido at codespeak.net Mon Mar 26 14:52:17 2007 From: guido at codespeak.net (guido at codespeak.net) Date: Mon, 26 Mar 2007 14:52:17 +0200 (CEST) Subject: [pypy-svn] r41348 - pypy/dist/pypy/doc Message-ID: <20070326125217.6D8EB1007A@code0.codespeak.net> Author: guido Date: Mon Mar 26 14:52:15 2007 New Revision: 41348 Modified: pypy/dist/pypy/doc/objspace-proxies.txt Log: Some typos, grammar, etc. Modified: pypy/dist/pypy/doc/objspace-proxies.txt ============================================================================== --- pypy/dist/pypy/doc/objspace-proxies.txt (original) +++ pypy/dist/pypy/doc/objspace-proxies.txt Mon Mar 26 14:52:15 2007 @@ -6,10 +6,10 @@ .. sectnum:: -Thanks to the `Object Space`_ architecture, there is a kind of feature -that is easy to implement on top of PyPy: namely, any feature that is +Thanks to the `Object Space`_ architecture, any feature that is based on proxying, extending, changing or otherwise controlling the -behavior of all objects in a running program. +behavior of all objects in a running program is easy to implement on +top of PyPy. Here is what we implemented so far, in historical order: @@ -21,9 +21,9 @@ * *Logic Object Space*: logical variables, i.e. placeholder objects whose value can be bound once. -* *Taint Object Space*: a soft security system. Your application cannot +* *Taint Object Space*: a soft security system; your application cannot accidentally compute results based on tainted objects unless it - explicitly untaint them first. + explicitly untaints them first. * *Dump Object Space*: dumps all operations performed on all the objects into a large log file. For debugging your applications. @@ -33,7 +33,8 @@ control operations on application and builtin objects, e.g lists, dictionaries, tracebacks. -Which object space to use can be chosen with :config:`objspace.name` option. +Which object space to use can be chosen with the :config:`objspace.name` +option. .. _`Object Space`: objspace.html @@ -44,10 +45,11 @@ 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. +objects, computed only when an operation is performed on them, and +"become", a more obscure feature which allows to completely and globally +replaces an object with another. -Example usage:: +Example usage of lazily computed objects:: $ py.py -o thunk >>>> from __pypy__ import thunk @@ -66,8 +68,8 @@ computing... -A related, but more obscure feature, allows one object to be instantly -and globally replaced with another:: +Example of how one object can be instantly and globally replaced with +another:: $ py.py -o thunk >>>> from __pypy__ import become @@ -111,7 +113,7 @@ and arguments. When a space operation follows the ``w_thunkalias`` chains of objects, it special-cases ``W_Thunk``: it invokes the stored callable if necessary to compute the real value and then stores it in -the ``w_thunkalias`` field of the ``W_Thunk``, which has the effect of +the ``w_thunkalias`` field of the ``W_Thunk``. This has the effect of replacing the latter with the real value. .. _thunk-interface: @@ -130,7 +132,7 @@ * ``become(obj1, obj2)``: globally replace ``obj1`` with ``obj2``. - * ``lazy(callable)``: Should be used as a function decorator. The decorated + * ``lazy(callable)``: should be used as a function decorator - the decorated function behaves lazily: all calls to it return a thunk object. @@ -143,18 +145,20 @@ including the notion of logical variable. A logical variable is really an object from the Python point of view; it is called "variable" for consistency with logic programming terminology. It is an "empty" object -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. +with no initial value: it's value can be set once, and only once, at any +point in time. -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: +Logical variables are not entirely different from lazily-computed objects, +except that the objects have no built-in knowledge about how they should +compute themselves. + +Using a logical variable before it gets a value results in a lock: the current thread is suspended, in the hope that another thread will -eventually put a value into the object. In practice, this works well +eventually give it a value. In practice, this works well with microthreads instead of real threads (see `Stackless features`_). The `EU Interim Report`_ (PDF) describes the Logic Object Space in -more details. +more detail. .. _`EU Interim Report`: http://codespeak.net/pypy/extradoc/eu-report/D09.1_Constraint_Solving_and_Semantic_Web-interim-2007-02-28.pdf .. _`Stackless features`: stackless.html @@ -197,7 +201,7 @@ 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 +We have implemented a simple two-level model: objects are either 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 @@ -296,21 +300,21 @@ 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 +presence doesn't give information away. This might be a +problem by itself, but there is no satisfying general solution here: +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 way to peek in a Taint +The ``TaintError`` exception deliberately does not include any +useful error messages, because they might give information away. +Of course, this makes debugging quite a bit harder; a difficult +problem to solve properly. So far we have implemented a way to peek in a Taint Box or Bomb, ``__pypy__._taint_look(x)``, and a "debug mode" that -prints the exception as soon as a Bomb is created. Both write +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 +that it is unlikely to be seen by anyone but the application developer. @@ -318,11 +322,11 @@ ---------------------- Occasionally, a more complicated computation must be performed on a -tainted object. This requires first untainting the object, perform the +tainted object. This requires first untainting the object, performing the computations, and then carefully tainting the result again (including hiding all exceptions into Bombs). -There is a built-in decorator that does exactly that:: +There is a built-in decorator that does this for you:: >>>> @__pypy__.taint_atomic >>>> def myop(x, y): @@ -345,7 +349,7 @@ 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. +visible side effects, as these could cause information leakage. 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). @@ -403,7 +407,7 @@ 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 +boxes, and gives 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. @@ -453,11 +457,11 @@ The Dump Object Space ===================== -When PyPy is run with (or translated with) the Dump Object Space, all +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. +editor; better browsing tools are needed before it becomes really useful. Try:: @@ -476,13 +480,14 @@ Transparent Proxies ================================ -PyPy's Transparent Proxies allow to route operations to objects -to a callable. Application level code can customize e.g. list -and dictionary objects without interfering with the type system, -i.e. ``type(proxied_list) is list`` holds true while still +PyPy's Transparent Proxies allow routing of operations on objects +to a callable. Application level code can customize objects without +interfering with the type system - ``type(proxied_list) is list`` holds true +when 'proxied_list' is a proxied built-in list - while giving you full control on all operations that are performed on the -``proxied_list``. Please see [D12.1]_ for context, -motivation and usage of transparent proxies. +``proxied_list``. + +See [D12.1]_ for more context, motivation and usage of transparent proxies. Example of the core mechanism ------------------------------------------- @@ -509,8 +514,8 @@ Example of recording all operations on builtins ---------------------------------------------------- -Suppose we want to have list which stores all operations performed on -it for later analysis. We use a small `tputil`_ module that helps +Suppose we want to have a list which stores all operations performed on +it for later analysis. We can use the small `tputil`_ module to help with transparently proxying builtin instances:: from tputil import make_proxy @@ -531,15 +536,15 @@ ``make_proxy(recorder, obj=[])`` creates a transparent list proxy where we can delegate operations to in the ``recorder`` function. -Calling ``type(l)`` does not lead to any operation at all. +Calling ``type(l)`` does not lead to any operation being executed at all. -XXX 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). +Note that ``append`` shows up as ``__getattribute__`` and that ``type(lst)`` +does not show up at all - the type is the only aspect of the instance which +the controller cannot change. .. _`transparent proxy builtins`: -Transparent Proxy PyPy Builtins and support +Transparent Proxy PyPy builtins and support ----------------------------------------------------------- If you are using the `--objspace-std-withtproxy`_ option @@ -564,7 +569,7 @@ The `tputil.py`_ module provides: -* ``make_proxy(controller, type, obj)`` function which +* ``make_proxy(controller, type, obj)``: function which creates a tranparent proxy controlled by the given 'controller' callable. The proxy will appear as a completely regular instance of the given @@ -584,7 +589,7 @@ `kwargs`: keyword arguments for this operation - `obj`: (if provided to `make_proxy`: an concrete object) + `obj`: (if provided to `make_proxy`): a concrete object If you have specified a concrete object instance `obj` to your `make_proxy` invocation, you may call @@ -594,18 +599,18 @@ Further points of interest --------------------------- -A lot of tasks could be performed using transparent proxies. Including, +A lot of tasks could be performed using transparent proxies, including, but not limited to: -* A Remote version of objects, on which we perform operations +* Remote versions of objects, on which we can directly perform operations (think about transparent distribution) -* Access to some persistent-storages like databases (imagine an - SQL object mapper which looks like real object) +* Access to persistent storage such as a database (imagine an + SQL object mapper which looks like a real object) -* Access to external data structures, like other languages as normal - objects. (Of course some operations on them could raise exceptions, but it's - purely done in application level, so it's not real problem) +* Access to external data structures, such as other languages, as normal + objects (of course some operations could raise exceptions, but + since they are purely done on application level, that is not real problem) Implementation Notes ----------------------------- @@ -613,22 +618,22 @@ PyPy's standard object space allows to internally have multiple implementations of a type and change the implementation at run time while application level code consistently sees the exact -same type and object. Multiple performance optimisations using -this features are already implemented, see the document +same type and object. Multiple performance optimizations using +this features are already implemented: see the document about `alternative object implementations`_. Transparent Proxies use the architecture to provide control back to application level code. -Transparent proxy is implemented on top of `standard object +Transparent proxies are implemented on top of the `standard object space`_, in `proxy_helpers.py`_, `proxyobject.py`_ and -`transparent.py`_. To run it you need to pass +`transparent.py`_. To use them you will need to pass a `--objspace-std-withtproxy`_ 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 +``translate.py``. This registers implementations named +``W_TransparentXxx`` - which usually correspond to an +apropriate ``W_XxxObject`` - and includes some 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, +implemented in the std objspace. The types of objects that can +be proxied this way are user created classes & functions, lists, dicts, exceptions, tracebacks and frames. .. _`standard object space`: objspace.html#the-standard-object-space From pedronis at codespeak.net Mon Mar 26 15:09:34 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Mon, 26 Mar 2007 15:09:34 +0200 (CEST) Subject: [pypy-svn] r41352 - pypy/dist/pypy/doc Message-ID: <20070326130934.B58321007F@code0.codespeak.net> Author: pedronis Date: Mon Mar 26 15:09:33 2007 New Revision: 41352 Added: pypy/dist/pypy/doc/release-1.0.0.txt - copied, changed from r41336, pypy/dist/pypy/doc/release-0.99.0.txt Log: A draft announcement for 1.0 to be reviewed and fleshed out. From auc at codespeak.net Mon Mar 26 15:15:59 2007 From: auc at codespeak.net (auc at codespeak.net) Date: Mon, 26 Mar 2007 15:15:59 +0200 (CEST) Subject: [pypy-svn] r41354 - pypy/dist/pypy/doc Message-ID: <20070326131559.91BE610082@code0.codespeak.net> Author: auc Date: Mon Mar 26 15:15:58 2007 New Revision: 41354 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 Mon Mar 26 15:15:58 2007 @@ -145,7 +145,7 @@ including the notion of logical variable. A logical variable is really an object from the Python point of view; it is called "variable" for consistency with logic programming terminology. It is an "empty" object -with no initial value: it's value can be set once, and only once, at any +with no initial value: its value can be set once, and only once, at any point in time. Logical variables are not entirely different from lazily-computed objects, From pedronis at codespeak.net Mon Mar 26 15:21:23 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Mon, 26 Mar 2007 15:21:23 +0200 (CEST) Subject: [pypy-svn] r41355 - pypy/dist/pypy/doc Message-ID: <20070326132123.CD17110082@code0.codespeak.net> Author: pedronis Date: Mon Mar 26 15:21:22 2007 New Revision: 41355 Modified: pypy/dist/pypy/doc/release-1.0.0.txt Log: oops, obscure typo Modified: pypy/dist/pypy/doc/release-1.0.0.txt ============================================================================== --- pypy/dist/pypy/doc/release-1.0.0.txt (original) +++ pypy/dist/pypy/doc/release-1.0.0.txt Mon Mar 26 15:21:22 2007 @@ -15,7 +15,7 @@ both these goals were achieved quite early in project, but finally: -- the ability to *generate automally* a Just-In-Time Compiler +- the ability to *generate automatically* a Just-In-Time Compiler starting from the interpreter This is *possibly* our main research achievement, and something never From cfbolz at codespeak.net Mon Mar 26 15:26:57 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 26 Mar 2007 15:26:57 +0200 (CEST) Subject: [pypy-svn] r41356 - pypy/dist/pypy/doc Message-ID: <20070326132657.D505110082@code0.codespeak.net> Author: cfbolz Date: Mon Mar 26 15:26:50 2007 New Revision: 41356 Modified: pypy/dist/pypy/doc/release-1.0.0.txt Log: fix some small typos Modified: pypy/dist/pypy/doc/release-1.0.0.txt ============================================================================== --- pypy/dist/pypy/doc/release-1.0.0.txt (original) +++ pypy/dist/pypy/doc/release-1.0.0.txt Mon Mar 26 15:26:50 2007 @@ -13,7 +13,7 @@ - A translation approach to produce efficient low-level versions of the interpreter -both these goals were achieved quite early in project, but finally: +Both these goals were achieved quite early in project, but finally: - the ability to *generate automatically* a Just-In-Time Compiler starting from the interpreter @@ -59,7 +59,7 @@ interpreter implementation, our main frontend. PyPy now is also a Just-In-Time compiler generator. The translation -framework contains , the now integrated, JIT generation +framework contains the now integrated JIT generation technology. This works based on hints added to the source interpreter, it should allow to cope with the changes to the interpreter, and be generally applicable to other interpreters written using the From hpk at codespeak.net Mon Mar 26 15:34:28 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Mon, 26 Mar 2007 15:34:28 +0200 (CEST) Subject: [pypy-svn] r41359 - pypy/branch/pytrunkmerge Message-ID: <20070326133428.A7C4F1007B@code0.codespeak.net> Author: hpk Date: Mon Mar 26 15:34:27 2007 New Revision: 41359 Removed: pypy/branch/pytrunkmerge/ Log: remove unused pytrunkmerge branch From hpk at codespeak.net Mon Mar 26 16:00:25 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Mon, 26 Mar 2007 16:00:25 +0200 (CEST) Subject: [pypy-svn] r41361 - pypy/extradoc/planning/1.0 Message-ID: <20070326140025.8FE5610078@code0.codespeak.net> Author: hpk Date: Mon Mar 26 16:00:19 2007 New Revision: 41361 Modified: pypy/extradoc/planning/1.0/TODO.txt Log: small updates before pypy-sync (starting now) Modified: pypy/extradoc/planning/1.0/TODO.txt ============================================================================== --- pypy/extradoc/planning/1.0/TODO.txt (original) +++ pypy/extradoc/planning/1.0/TODO.txt Mon Mar 26 16:00:19 2007 @@ -9,10 +9,8 @@ published final reports: 2.1, 2.3, 3.1, 10.1, 12.1, 14.2 -25 (weekend) WP08 documentation and working examples integrated - release candidates testing -26 testing testing testing (14.5, 11.1) -27 RELEASE (1.2-4, 13.1) +26 release candidates testing +27 RELEASE (1.2-4, 13.1) 28 29 30 @@ -34,7 +32,7 @@ but no feedback/interaction with DFKI/Danish yet. - (hpk) revisit entry level docs (architecture/mission, getting-started) - - (hpk, mostly done) review entry points from the play1 demos. + - (hpk, guido, mostly done) review entry points from the play1 demos. - (arigo,cfbolz,pedronis) review/refactor new-architecture.txt - (fijal, NNN) play1 issues: @@ -54,25 +52,40 @@ - stress-test/use buildtool for translation tests (multicompile) (guido_w) - - (no news ) include documentation/entry point for - the JS interpreter (santagada, fijal) - - include documentation/entry point for the prolog interpreter (cfbolz, maybe) - - (DONE), arigo,pedronis,hpk) fix test failures of translated PyPys - related to aop.py module modifying global compiler state and - subsequent tests randomly breaking + - (no news ) include documentation/entry point for + the JS interpreter (santagada, fijal) + + - move pedronis/pypy-c-testing, pedronis/tarball-testing + and pypy/tool/build all into + + http://codespeak.net/svn/pypy/build + + directory and arigo's htmlconftest as a snapshot or external. + refactor docs to point to the tools correctly + (build/bin/* probably) - (pedronis, in-progress) tarball packaging and testing + - what is missing (code-wise) for a release candidate? + + - when to do the release candidate? + - skip some weakref tests related to missing GC refactorings + for 1.0? - - (hpk, review from cfbolz and NN) + - (pedronis,hpk, review from cfbolz and NN) write release announcement NOTES AND DONE TASKS ----------------------------- + - (DONE), arigo,pedronis,hpk) fix test failures of translated PyPys + related to aop.py module modifying global compiler state and + subsequent tests randomly breaking + + - (DONE) consider where/how to put special builtins ("pypymagic" might not be a good name), suggestions: - names: not pypymagic, not pypybuiltin, holger and cf to propose From arigo at codespeak.net Mon Mar 26 16:14:51 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 26 Mar 2007 16:14:51 +0200 (CEST) Subject: [pypy-svn] r41362 - in pypy/dist/pypy: doc jit/tl Message-ID: <20070326141451.838DA10082@code0.codespeak.net> Author: arigo Date: Mon Mar 26 16:14:50 2007 New Revision: 41362 Modified: pypy/dist/pypy/doc/jit.txt pypy/dist/pypy/jit/tl/targettiny1.py pypy/dist/pypy/jit/tl/targettiny2.py pypy/dist/pypy/jit/tl/tiny2.py Log: Mostly finished jit.txt. Added long comments in tiny2.py. Modified: pypy/dist/pypy/doc/jit.txt ============================================================================== --- pypy/dist/pypy/doc/jit.txt (original) +++ pypy/dist/pypy/doc/jit.txt Mon Mar 26 16:14:50 2007 @@ -323,10 +323,92 @@ examples. -A (slightly less) tiny interpreter -================================== +A slightly less tiny interpreter +================================ -`pypy/jit/tl/tiny2.py`_ XXX +The interpreter in `pypy/jit/tl/tiny2.py`_ is a reasonably good example +of the difficulties that we meet when scaling up this approach, and how +we solve them - or work around them. For more details, see the comments +in the source code. With more work on the JIT generator, we hope to be +eventually able to remove the need for the workarounds. + +Promotion +--------- + +The most powerful hint introduced in this example is ``promote=True``. +It is applied to a value that is usually not a compile-time constant, +but which we would like to become a compile-time constant "just in +time". Its meaning is to instruct the JIT compiler to stop compiling at +this point, wait until the runtime actually reaches that point, grab the +value that arrived here at runtime, and go on compiling with the value +now considered as a compile-time constant. If the same point is reached +at runtime several times with several different values, the compiler +will produce one code path for each, with a switch in the generated +code. This is a process that is never "finished": in general, new +values can always show up later during runtime, causing more code paths +to be compiled and the switch in the generated code to be extended. + +Promotion is the essential new feature introduced in PyPy when compared +to existing partial evaluation techniques (it was actually first +introduced in Psyco [JITSPEC]_, which is strictly speaking not a partial +evaluator). + +Another way to understand the effect of promotion is to consider it as a +complement to the ``concrete=True`` hint. The latter tells the +hint-annotator that the value that arrives here is required to be a +compile-time constant (i.e. green). In general, this is a very strong +constraint, because it forces "backwards" a potentially large number of +values to be green as well - all the values that this one depends on. +In general, it does not work at all, because the value ultimately +depends on an operation that cannot be constant-folded at all by the JIT +compiler, e.g. because it depends on external input or reads from +non-immutable memory. + +The ``promote=True`` hint can take an arbitrary red value and returns it +as a green variable, so it can be used to bound the set of values that +need to be forced to green. A common idiom is to put a +``concrete=True`` hint at the precise point where a compile-time +constant would be useful (e.g. on the value on which a complex switch +dispatches), and then put a few ``promote=True`` hints to copy specific +values into green variables *before* the ``concrete=True``. + +The ``promote=True`` hints should be applied where we expect not too +many different values to arrive at runtime; here are typical examples: + +* Where we expect a small integer, the integer can be promoted if each + specialized version can be optimized (e.g. lists of known length can + be optimized by the JIT compiler). + +* The interpreter-level class of an object can be promoted before an + indirect method call, if it is useful for the JIT compiler to look + inside the called method. If the method call is indirect, the JIT + compiler merely produces a similar indirect method call in the + generated code. But if the class is a compile-time constant, then it + knows which method is called, and compiles its operations (effectively + inlining it from the point of the view of the generated code). + +* Whole objects can be occasionally promoted, with care. For example, + in an interpreter for a language which has function calls, it might be + useful to know exactly which Function object is called (as opposed to + just the fact that we call an object of class Function). + +Other hints +----------- + +The other hints mentioned in `pypy/jit/tl/tiny2.py`_ are "global merge +points" and "deepfreeze". For more information, please refer to the +explanations there. + +We should also mention a technique not used in ``tiny2.py``, which is +the notion of *virtualizable* objects. In PyPy, the Python frame +objects are virtualizable. Such objects assume that they will be mostly +read and mutated by the JIT'ed code - this is typical of frame objects +in most interpreters: they are either not visible at all for the +interpreted programs, or (as in Python) you have to access them using +some reflection API. The ``_virtualizable_`` hint allows the object to +escape (e.g. in PyPy, the Python frame object is pushed on the +globally-accessible frame stack) while still remaining efficient to +access from JIT'ed code. ------------------------------------------------------------------------ @@ -499,6 +581,8 @@ .. _`expanded version of the present document`: discussion/jit-draft.html +--------------- + .. _VMC: http://codespeak.net/svn/pypy/extradoc/talk/dls2006/pypy-vm-construction.pdf .. _`RPython`: coding-guide.html#rpython @@ -510,5 +594,9 @@ .. _Psyco: http://psyco.sourceforge.net .. _`PyPy Standard Interpreter`: architecture.html#standard-interpreter .. _`exception transformer`: translation.html#making-exception-handling-explicit +.. [JITSPEC] Representation-Based Just-In-Time Specialization and the + Psyco Prototype for Python, ACM SIGPLAN PEPM'04, August 24-26, 2004, + Verona, Italy. + http://psyco.sourceforge.net/psyco-pepm-a.ps.gz .. include:: _ref.txt Modified: pypy/dist/pypy/jit/tl/targettiny1.py ============================================================================== --- pypy/dist/pypy/jit/tl/targettiny1.py (original) +++ pypy/dist/pypy/jit/tl/targettiny1.py Mon Mar 26 16:14:50 2007 @@ -3,6 +3,11 @@ def entry_point(args): + """Main entry point of the stand-alone executable: + takes a list of strings and returns the exit code. + """ + # store args[0] in a place where the JIT log can find it (used by + # viewcode.py to know the executable whose symbols it should display) highleveljitinfo.sys_executable = args[0] if len(args) < 4: print "Usage: %s bytecode x y" % (args[0],) @@ -26,4 +31,8 @@ oopspec = True def portal(driver): + """Return the 'portal' function, and the hint-annotator policy. + The portal is the function that gets patched with a call to the JIT + compiler. + """ return tiny1.ll_plus_minus, MyHintAnnotatorPolicy() Modified: pypy/dist/pypy/jit/tl/targettiny2.py ============================================================================== --- pypy/dist/pypy/jit/tl/targettiny2.py (original) +++ pypy/dist/pypy/jit/tl/targettiny2.py Mon Mar 26 16:14:50 2007 @@ -3,15 +3,20 @@ def entry_point(args): + """Main entry point of the stand-alone executable: + takes a list of strings and returns the exit code. + """ + # store args[0] in a place where the JIT log can find it (used by + # viewcode.py to know the executable whose symbols it should display) highleveljitinfo.sys_executable = args[0] - if len(args) < 3: + if len(args) < 2: print "Invalid command line arguments." print args[0] + " 'tiny2 program string' arg0 [arg1 [arg2 [...]]]" return 1 bytecode = [s for s in args[1].split(' ') if s != ''] args = [tiny2.StrBox(arg) for arg in args[2:]] res = tiny2.interpret(bytecode, args) - print res.as_str() + print tiny2.repr(res) return 0 def target(driver, args): @@ -26,7 +31,12 @@ oopspec = True def look_inside_graph(self, graph): + # temporary workaround return getattr(graph, 'func', None) is not tiny2.myint_internal def portal(driver): + """Return the 'portal' function, and the hint-annotator policy. + The portal is the function that gets patched with a call to the JIT + compiler. + """ return tiny2.interpret, MyHintAnnotatorPolicy() Modified: pypy/dist/pypy/jit/tl/tiny2.py ============================================================================== --- pypy/dist/pypy/jit/tl/tiny2.py (original) +++ pypy/dist/pypy/jit/tl/tiny2.py Mon Mar 26 16:14:50 2007 @@ -1,7 +1,45 @@ +""" +An interpreter for a strange word-based language: the program is a list +of space-separated words. Most words push themselves on a stack; some +words have another action. The result is the space-separated words +from the stack. + + Hello World => 'Hello World' + 6 7 ADD => '13' 'ADD' is a special word + 7 * 5 = 7 5 MUL => '7 * 5 = 35' '*' and '=' are not special words + +Arithmetic on non-integers gives a 'symbolic' result: + + X 2 MUL => 'X*2' + +Input arguments can be passed on the command-line, and used as #1, #2, etc.: + + #1 1 ADD => one more than the argument on the command-line, + or if it was not an integer, concatenates '+1' + +You can store back into an (existing) argument index with ->#N: + + #1 5 ADD ->#1 + +Braces { } delimitate a loop. Don't forget spaces around each one. +The '}' pops an integer value off the stack and loops if it is not zero: + + { #1 #1 1 SUB ->#1 #1 } => when called with 5, gives '5 4 3 2 1' + +""" from pypy.rlib.objectmodel import hint, _is_early_constant +# +# See pypy/doc/jit.txt for a higher-level overview of the JIT techniques +# detailed in the following comments. +# + class Box: + # Although all words are in theory strings, we use two subclasses + # to represent the strings differently from the words known to be integers. + # This is an optimization that is essential for the JIT and merely + # useful for the basic interpreter. pass class IntBox(Box): @@ -25,11 +63,17 @@ def func_sub_int(ix, iy): return ix - iy def func_mul_int(ix, iy): return ix * iy -def func_add_str(sx, sy): return sx + ' ' + sy +def func_add_str(sx, sy): return sx + '+' + sy def func_sub_str(sx, sy): return sx + '-' + sy def func_mul_str(sx, sy): return sx + '*' + sy def op2(stack, func_int, func_str): + # Operate on the top two stack items. The promotion hints force the + # class of each arguments (IntBox or StrBox) to turn into a compile-time + # constant if they weren't already. The effect we seek is to make the + # calls to as_int() direct calls at compile-time, instead of indirect + # ones. The JIT compiler cannot look into indirect calls, but it + # can analyze and inline the code in directly-called functions. y = stack.pop() hint(y.__class__, promote=True) x = stack.pop() @@ -42,9 +86,27 @@ def interpret(bytecode, args): + """The interpreter's entry point and portal function. + """ + # ------------------------------ + # First a lot of JIT hints... + # + # A portal needs a "global merge point" at the beginning, for + # technical reasons, if it uses promotion hints: hint(None, global_merge_point=True) + + # An important hint: 'bytecode' is a list, which is in theory + # mutable. Let's tell the JIT compiler that it can assume that the + # list is entirely frozen, i.e. immutable and only containing immutable + # objects. Otherwise, it cannot do anything - it would have to assume + # that the list can unpredictably change at runtime. bytecode = hint(bytecode, deepfreeze=True) - # ------------------------------ + + # Now some strange code that makes a copy of the 'args' list in + # a complicated way... this is a workaround forcing the whole 'args' + # list to be virtual. It is a way to tell the JIT compiler that it + # doesn't have to worry about the 'args' list being unpredictably + # modified. oldargs = args argcount = hint(len(oldargs), promote=True) args = [] @@ -54,13 +116,21 @@ args.append(oldargs[n]) n += 1 # ------------------------------ + # the real code starts here loops = [] stack = [] pos = 0 while pos < len(bytecode): + # It is a good idea to put another 'global merge point' at the + # start of each iteration in the interpreter's main loop. The + # JIT compiler keeps a table of all the times it passed through + # the global merge point. It allows it to detect when it can + # stop compiling and generate a jump back to some machine code + # that was already generated earlier. hint(None, global_merge_point=True) + opcode = bytecode[pos] - hint(opcode, concrete=True) + hint(opcode, concrete=True) # same as in tiny1.py pos += 1 if opcode == 'ADD': op2(stack, func_add_int, func_add_str) elif opcode == 'SUB': op2(stack, func_sub_int, func_sub_str) @@ -70,6 +140,8 @@ stack.append(args[n-1]) elif opcode.startswith('->#'): n = myint(opcode, start=3) + if n > len(args): + raise IndexError args[n-1] = stack.pop() elif opcode == '{': loops.append(pos) @@ -78,14 +150,32 @@ loops.pop() else: pos = loops[-1] + # A common problem when interpreting loops or jumps: the 'pos' + # above is read out of a list, so the hint-annotator thinks + # it must be red (not a compile-time constant). But the + # hint(opcode, concrete=True) in the next iteration of the + # loop requires all variables the 'opcode' depends on to be + # green, including this 'pos'. We promote 'pos' to a green + # here, as early as possible. Note that in practice the 'pos' + # read out of the 'loops' list will be a compile-time constant + # because it was pushed as a compile-time constant by the '{' + # case above into 'loops', which is a virtual list, so the + # promotion below is just a way to make the colors match. pos = hint(pos, promote=True) else: stack.append(StrBox(opcode)) - while len(stack) > 1: - op2(stack, func_add_int, func_add_str) - return stack.pop() + return stack + +def repr(stack): + # this bit moved out of the portal function because JIT'ing it is not + # very useful, and the JIT generator is confused by the 'for' right now... + return ' '.join([x.as_str() for x in stack]) +# ------------------------------ +# Pure workaround code! It will eventually be unnecessary. +# For now, myint(s, n) is a JIT-friendly way to spell int(s[n:]). +# We don't support negative numbers, though. def myint_internal(s, start=0): if start >= len(s): return -1 @@ -98,7 +188,6 @@ res = res * 10 + n start += 1 return res - def myint(s, start=0): if _is_early_constant(s): s = hint(s, promote=True) @@ -111,18 +200,26 @@ if n < 0: raise ValueError return n +# ------------------------------ def test_main(): main = """#1 5 ADD""".split() res = interpret(main, [IntBox(20)]) - assert res.as_int() == 25 + assert repr(res) == '25' res = interpret(main, [StrBox('foo')]) - assert res.as_str() == 'foo 5' + assert repr(res) == 'foo+5' FACTORIAL = """The factorial of #1 is 1 { #1 MUL #1 1 SUB ->#1 #1 }""".split() def test_factorial(): res = interpret(FACTORIAL, [IntBox(5)]) - assert res.as_str() == 'The factorial of 5 is 120' + assert repr(res) == 'The factorial of 5 is 120' + +FIBONACCI = """Fibonacci numbers: + { #1 #2 #1 #2 ADD ->#2 ->#1 #3 1 SUB ->#3 #3 }""".split() + +def test_fibonacci(): + res = interpret(FIBONACCI, [IntBox(1), IntBox(1), IntBox(10)]) + assert repr(res) == "Fibonacci numbers: 1 1 2 3 5 8 13 21 34 55" From pedronis at codespeak.net Mon Mar 26 16:20:36 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Mon, 26 Mar 2007 16:20:36 +0200 (CEST) Subject: [pypy-svn] r41363 - pypy/dist/pypy/doc Message-ID: <20070326142036.ED83D10085@code0.codespeak.net> Author: pedronis Date: Mon Mar 26 16:20:36 2007 New Revision: 41363 Modified: pypy/dist/pypy/doc/new-architecture.txt Log: some streamlining, the last para are not done yet. Modified: pypy/dist/pypy/doc/new-architecture.txt ============================================================================== --- pypy/dist/pypy/doc/new-architecture.txt (original) +++ pypy/dist/pypy/doc/new-architecture.txt Mon Mar 26 16:20:36 2007 @@ -163,15 +163,13 @@ The Translation Process ----------------------- -.. XXX this part sounds repetivive here and there and a bit heavy - The *translation process* is implemented in four parts: - the production of a *flow graph* representation of an RPython program source, function by function. A combination of the `bytecode evaluator`_ and a `flow object space`_ performs `abstract interpretation`_ to record the flow of objects - and execution throughout a Python program into such a *flow graph*; + and execution throughout a Python program into a family of *flow graphs*; - the *annotator*, which performs type inference on the family of flow graphs; @@ -183,17 +181,17 @@ .. _`initialization time`: .. _`translation process in more details`: -In order to limit the complexity of our generic translation and type -inference mechanisms, we restrict the dynamism of our source -RPython program. RPython_ is still defined in a particularly dynamic. -During initialization the source program can make unrestricted -use of Python (including metaclasses and execution of dynamically -constructed strings). However, the Python code objects that we eventually -see during the production and analysis of flow graphs, must adhere -to a more static subset of Python. +In order for our generic translation and type inference mechanisms to +work effectively we need to restrict the allowed dynamism of RPython +programs. The Python code objects that we eventually see during the +production and analysis of flow graphs, must adhere to a more static +subset of Python. This doesn't apply to the startup code which is not +seen by the translation, so during initialization the source program +can make unrestricted use of Python (including metaclasses and +execution of dynamically constructed strings). The `bytecode evaluator`_ and the `Flow Object Space`_ work through -those initialized RPython code objects. The result of this +the initialized RPython code objects. The result of this `abstract interpretation`_ is a flow graph (one per function): yet another representation of the source program, but one which is suitable for applying translation and type inference techniques. The nodes of the @@ -203,24 +201,21 @@ The flow graphs are fed as input into the Annotator. The Annotator, given entry point types, infers the types of values that flow through -the variables of the entire program. -RPython code is restricted in such a way that the -Annotator is able to infer consistent types. How much dynamism we allow in -RPython depends on, and is mostly restricted by, the Flow Object Space and -the Annotator implementation. The more we can improve this translation -phase, the more dynamism we can allow. - -The *RTyper* is responsible for the preparation and production of target -platform specific -representations of the annotated high level RPython flowgraphs. It visits -the flow graphs in order to transform and amend the operations it contains. -After this pass the operations in the flow graphs are suitable for the -target platform. High level platforms (e.g. object-oriented virtual machines) -usually have their own -garbace collectors and high level builtin types, while low level platforms -(e.g. C-like environments) -require dealing with machine level types and pointers; the RTyper can -produce flow graphs containing operations suited for either kind of platform. +the variables of the entire program. RPython restrictions are crucial +and defined for this to work. + +... XXX these last bits still need a cleanup: + +The *RTyper* is responsible for the preparation and production of +target platform specific representations of the annotated high level +RPython flowgraphs. It visits the flow graphs in order to transform +and amend the operations it contains. After this pass the operations +in the flow graphs are suitable for the target platform. High level +platforms (e.g. object-oriented virtual machines) usually have their +own garbace collectors and high level builtin types, while low level +platforms (e.g. C-like environments) require dealing with machine +level types and pointers; the RTyper can produce flow graphs +containing operations suited for either kind of platform. The actual target platform code is eventually emitted by the backend through "visiting" the type-annotated flow graph From pedronis at codespeak.net Mon Mar 26 16:26:19 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Mon, 26 Mar 2007 16:26:19 +0200 (CEST) Subject: [pypy-svn] r41364 - pypy/dist/pypy/doc Message-ID: <20070326142619.E067D10087@code0.codespeak.net> Author: pedronis Date: Mon Mar 26 16:26:13 2007 New Revision: 41364 Modified: pypy/dist/pypy/doc/release-1.0.0.txt Log: reminder to point to play1 Modified: pypy/dist/pypy/doc/release-1.0.0.txt ============================================================================== --- pypy/dist/pypy/doc/release-1.0.0.txt (original) +++ pypy/dist/pypy/doc/release-1.0.0.txt Mon Mar 26 16:26:13 2007 @@ -89,6 +89,7 @@ - minimal readline +XXX point to play1 What about the Future? ======================= From fijal at codespeak.net Mon Mar 26 16:35:08 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 26 Mar 2007 16:35:08 +0200 (CEST) Subject: [pypy-svn] r41365 - pypy/dist/pypy/doc/play1 Message-ID: <20070326143508.7420D1005A@code0.codespeak.net> Author: fijal Date: Mon Mar 26 16:35:06 2007 New Revision: 41365 Modified: pypy/dist/pypy/doc/play1/pypy-c-taint.html pypy/dist/pypy/doc/play1/pypy-c-thunk.html pypy/dist/pypy/doc/play1/pypy-c.html pypy/dist/pypy/doc/play1/test_snippets.py Log: Update docs. Modified: pypy/dist/pypy/doc/play1/pypy-c-taint.html ============================================================================== --- pypy/dist/pypy/doc/play1/pypy-c-taint.html (original) +++ pypy/dist/pypy/doc/play1/pypy-c-taint.html Mon Mar 26 16:35:06 2007 @@ -1,4 +1,4 @@ The PyPy standard interpreter compiled to C using -the taint object space. Example (execute): +the taint object space. Example (execute):
    %s
    Now try hard getting to value of x :-) Modified: pypy/dist/pypy/doc/play1/pypy-c-thunk.html ============================================================================== --- pypy/dist/pypy/doc/play1/pypy-c-thunk.html (original) +++ pypy/dist/pypy/doc/play1/pypy-c-thunk.html Mon Mar 26 16:35:06 2007 @@ -1,4 +1,4 @@ The PyPy standard interpreter compiled to C using the -thunk object space. Example (execute): +thunk object space. Example (execute):
    %s
    And try x. Modified: pypy/dist/pypy/doc/play1/pypy-c.html ============================================================================== --- pypy/dist/pypy/doc/play1/pypy-c.html (original) +++ pypy/dist/pypy/doc/play1/pypy-c.html Mon Mar 26 16:35:06 2007 @@ -8,7 +8,7 @@
  • Transparent proxy - This is a unique PyPy interpreter feature, which allows you to provide an application-level controller for any kind of object. Details and snippets can be found in the - transparent proxy documentation. Example (execute): + transparent proxy documentation. Example (execute):
    %s
  • Modified: pypy/dist/pypy/doc/play1/test_snippets.py ============================================================================== --- pypy/dist/pypy/doc/play1/test_snippets.py (original) +++ pypy/dist/pypy/doc/play1/test_snippets.py Mon Mar 26 16:35:06 2007 @@ -14,3 +14,62 @@ l = make_proxy(recorder, obj=[]) +class AppTest_pypy_c_thunk(object): + def setup_class(cls): + cls.space = gettestobjspace(**{"objspace.name": 'thunk'}) + + def test_snippet_1(self): + from __pypy__ import thunk + def f(): + print 'computing...' + return 6*7 + + x = thunk(f) + +class AppTest_pypy_c_taint(object): + def setup_class(cls): + cls.space = gettestobjspace(**{'objspace.name': 'taint'}) + + def test_snippet_1(self): + from __pypy__ import taint + x = taint(6) + +class AppTest_pypy_cli(object): + pass + +class AppTest_pyrolog_c(object): + pass + +class AppTest_python(object): + pass + +class AppTest_pypy_c_jit(object): + def setup_class(cls): + cls.space = gettestobjspace(**{'usemodules':('pypyjit',)}) + + def test_snippet_1(self): + import time + + def f1(n): + "Arbitrary test function." + i = 0 + x = 1 + while i Author: hpk Date: Mon Mar 26 16:35:20 2007 New Revision: 41366 Modified: pypy/extradoc/planning/1.0/TODO.txt Log: some updates after pypy-sync meeting, main topics now: play1, code-release candidate and testing, and various DOCs Modified: pypy/extradoc/planning/1.0/TODO.txt ============================================================================== --- pypy/extradoc/planning/1.0/TODO.txt (original) +++ pypy/extradoc/planning/1.0/TODO.txt Mon Mar 26 16:35:20 2007 @@ -9,7 +9,7 @@ published final reports: 2.1, 2.3, 3.1, 10.1, 12.1, 14.2 -26 release candidates testing +26 release candidates / testing / docs 27 RELEASE (1.2-4, 13.1) 28 29 @@ -27,24 +27,14 @@ - integrate and test: - (arigo,pedronis,arre, IN-PROGRESS): wp08 docs & examples, getting-started - (cfbolz) test wp09 getting-started examples: + - after some fixing things seem to work - wp09 docs, examples and code - maybe what we have is good enough? (christian looking into this currently) a bit of progress, but no feedback/interaction with DFKI/Danish yet. - - (hpk) revisit entry level docs (architecture/mission, getting-started) - - (hpk, guido, mostly done) review entry points from the play1 demos. - - (arigo,cfbolz,pedronis) review/refactor new-architecture.txt + - (arigo,cfbolz,pedronis) review/refactor new-architecture.txt - - (fijal, NNN) play1 issues: - - rebuild pypy's to use the new readline stub (fixing - ugly stdout/stdin interactions) - - review/refine help (add examples where necessary) - - make examples execute more cleanly - - fix linking (it gets easily confused if you click around), - make correct 404 and 500 pages - - discuss/do a JIT demo - - - update wp6 docs (interpreter-optimizations.txt) and link + - (done) update wp6 docs (interpreter-optimizations.txt) and link to them from getting-started (mwh to coordinate) ropes docs added @@ -52,11 +42,8 @@ - stress-test/use buildtool for translation tests (multicompile) (guido_w) - - include documentation/entry point for - the prolog interpreter (cfbolz, maybe) - - - (no news ) include documentation/entry point for - the JS interpreter (santagada, fijal) + - (cfbolz, in-progress) include documentation/entry point for + the prolog interpreter - move pedronis/pypy-c-testing, pedronis/tarball-testing and pypy/tool/build all into @@ -67,6 +54,15 @@ refactor docs to point to the tools correctly (build/bin/* probably) + - (fijal, NNN) play1 issues: + - rebuild pypy's to use the new readline stub (fixing + ugly stdout/stdin interactions) + - review/refine help (add examples where necessary) + - make examples execute more cleanly + - fix linking (it gets easily confused if you click around), + make correct 404 and 500 pages + - discuss/do a JIT demo + - (pedronis, in-progress) tarball packaging and testing - what is missing (code-wise) for a release candidate? @@ -81,6 +77,12 @@ NOTES AND DONE TASKS ----------------------------- + - (DROPPED for 1.0) include documentation/entry point for + the JS interpreter (santagada, fijal) + + + - (hpk, guido, DONE) review entry points from the play1 demos. + - (DONE), arigo,pedronis,hpk) fix test failures of translated PyPys related to aop.py module modifying global compiler state and subsequent tests randomly breaking From fijal at codespeak.net Mon Mar 26 16:35:24 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 26 Mar 2007 16:35:24 +0200 (CEST) Subject: [pypy-svn] r41367 - pypy/dist/pypy/doc/play1 Message-ID: <20070326143524.E28FA10087@code0.codespeak.net> Author: fijal Date: Mon Mar 26 16:35:22 2007 New Revision: 41367 Added: pypy/dist/pypy/doc/play1/pypy-c-jit.html Log: Add a jit doc as well Added: pypy/dist/pypy/doc/play1/pypy-c-jit.html ============================================================================== --- (empty file) +++ pypy/dist/pypy/doc/play1/pypy-c-jit.html Mon Mar 26 16:35:22 2007 @@ -0,0 +1,5 @@ +The PyPy standard interpreter compiled to C with the mysterious JIT. +JIT can now speedup very much simple arithmetic operations. +Paste this example (paste) for simple function: +
    %s
    +Try running it (test_f1()) and try running pypyjit.enable(f1.func_code) and watch the difference. From fijal at codespeak.net Mon Mar 26 16:38:13 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 26 Mar 2007 16:38:13 +0200 (CEST) Subject: [pypy-svn] r41368 - pypy/dist/pypy/translator/js Message-ID: <20070326143813.BF4CE1005A@code0.codespeak.net> Author: fijal Date: Mon Mar 26 16:38:11 2007 New Revision: 41368 Modified: pypy/dist/pypy/translator/js/jsbuiltin.py Log: Add stuff needed by play1 (tests coming soon) Modified: pypy/dist/pypy/translator/js/jsbuiltin.py ============================================================================== --- pypy/dist/pypy/translator/js/jsbuiltin.py (original) +++ pypy/dist/pypy/translator/js/jsbuiltin.py Mon Mar 26 16:38:11 2007 @@ -42,6 +42,8 @@ 'll_substring' : CallBuiltin('substring'), 'll_lower' : lambda g, op: Call._render_builtin_method(g, 'toLowerCase', [op.args[1]]), 'll_upper' : lambda g, op: Call._render_builtin_method(g, 'toUpperCase', [op.args[1]]), + 'll_find' : lambda g, op: Call._render_builtin_method(g, 'search', [op.args[1], op.args[2]]), + 'll_find_char' : lambda g, op: Call._render_builtin_method(g, 'search', [op.args[1], op.args[2]]), }, ootype.List: { 'll_setitem_fast' : ListSetitem, From fijal at codespeak.net Mon Mar 26 16:40:09 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 26 Mar 2007 16:40:09 +0200 (CEST) Subject: [pypy-svn] r41369 - in pypy/dist/pypy/translator/js/examples: . console console/data data Message-ID: <20070326144009.412351005A@code0.codespeak.net> Author: fijal Date: Mon Mar 26 16:40:07 2007 New Revision: 41369 Added: pypy/dist/pypy/translator/js/examples/data/error.html pypy/dist/pypy/translator/js/examples/data/py-web1.png (contents, props changed) Modified: pypy/dist/pypy/translator/js/examples/console/client.py pypy/dist/pypy/translator/js/examples/console/console.py pypy/dist/pypy/translator/js/examples/console/data/console.html pypy/dist/pypy/translator/js/examples/data/index.html pypy/dist/pypy/translator/js/examples/data/style.css pypy/dist/pypy/translator/js/examples/overmind.py Log: Play1 revisited 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 Mon Mar 26 16:40:07 2007 @@ -6,10 +6,13 @@ class Glob(object): def __init__(self): self.console_running = False + self.next_console = "" + self.text_to_show = [] + self.pss = [] glob = Glob() -def add_text(txt): +def add_text_to_dom(txt): data_elem = dom.document.getElementById("data") if data_elem.childNodes: data = data_elem.childNodes[0].nodeValue + txt @@ -19,6 +22,26 @@ data_elem.removeChild(data_elem.childNodes[0]) data_elem.appendChild(dom.document.createTextNode(data)) + +def add_text(txt, server_flag, fn=add_text_to_dom): + if not server_flag: + if txt.find("\n") != len(txt) - 1: + if txt[-1] == '\n': + txt = txt[:-1] + lst = txt.split("\n") + add_text_to_dom(lst[0] + "\n") + glob.text_to_show += lst[1:] + else: + add_text_to_dom(txt) + else: + for ps in glob.pss: + if txt.startswith(ps) and glob.text_to_show: + txt = txt[len(ps):] + add_text_to_dom(ps + glob.text_to_show.pop(0) + "\n") + add_text(txt, True) + return + add_text_to_dom(txt) + def create_text(txt): return dom.document.createTextNode(txt) @@ -37,7 +60,7 @@ inp_elem.scrollIntoView() inp_elem.focus() exported_methods.refresh_empty(glob.sess_id, refresh_console) - add_text(data) + add_text(data, True) elif msg[0] == 'disconnected': inp_elem.disabled = True name_bar = dom.document.getElementById("namebar") @@ -45,10 +68,16 @@ text = name_bar.lastChild.nodeValue name_bar.removeChild(name_bar.lastChild) name_bar.appendChild(create_text(text + " [DEFUNCT]")) + glob.console_running = False + if glob.next_console: + next = glob.next_console + glob.next_console = "" + load_console(next) def set_sessid(data): sessid = int(data[0]) help_msg = data[1] + glob.pss = data[2:] glob.sess_id = sessid inp_elem = dom.document.getElementById("inp") inp_elem.disabled = False @@ -70,7 +99,7 @@ inp_elem = dom.document.getElementById("inp") cmd = inp_elem.value inp_elem.value = '' - add_text(cmd + "\n") + add_text(cmd + "\n", False) #if not cmd: # exported_methods.refresh(glob.sess_id, cmd, empty_callback) #else: @@ -91,6 +120,8 @@ def load_console(python="python"): if glob.console_running: cleanup_console() + glob.next_console = python + return inp_elem = dom.document.getElementById("inp") main = dom.document.getElementById("main") main.style.visibility = "visible" @@ -100,7 +131,7 @@ exported_methods.get_console(python, set_sessid) def add_snippet(snippet): - add_text(snippet) + add_text(snippet, False) exported_methods.refresh(glob.sess_id, snippet, refresh_console) def execute_snippet(name='python', number=3): 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 Mon Mar 26 16:40:07 2007 @@ -12,6 +12,7 @@ from pypy.translator.js.examples.console.session import Interpreter, Killed from pypy.translator.js.examples.console.docloader import DocLoader from py.__.green.server.httpserver import GreenHTTPServer +from py.__.green.greensock2 import ConnexionClosed commproxy.USE_MOCHIKIT = True @@ -25,6 +26,8 @@ return rpython2javascript(client, FUNCTION_LIST) def line_split(ret, max_len): + return ret + # XXX borken to_ret = [] for line in ret.split("\n"): if len(line) > max_len: @@ -42,7 +45,7 @@ STATIC_DIR = STATIC_DIR.dirpath() STATIC_DIR = STATIC_DIR.join("compiled") DOCDIR = STATIC_DIR.dirpath().join("pypy", "doc", "play1") -CONSOLES = ['pypy-c', 'pypy-c-thunk', 'pypy-c-taint', 'pypy-cli', 'pyrolog-c'] +CONSOLES = ['python', 'pypy-c', 'pypy-c-thunk', 'pypy-c-taint', 'pypy-cli', 'pyrolog-c', 'pypy-c-jit'] class Sessions(object): def __init__(self): @@ -77,6 +80,15 @@ del self.sessions[pid] del self.updating[pid] + def get_ps(self, python): + if python == 'python': + return ['>>> ', '... '] + if python.startswith('pypy'): + return ['>>>> ', '.... '] + if python == 'pyrolog-c': + return ['>?-'] + return [] + # We hack here, cause in exposed methods we don't have global 'server' # state sessions = Sessions() @@ -85,31 +97,29 @@ @callback(retval=[str]) def get_console(self, python="python"): retval = sessions.new_session(python) - return [str(retval), sessions.docloader.get_html(python)] + return [str(retval), sessions.docloader.get_html(python)] +\ + sessions.get_ps(python) - @callback(retval=[str]) - def refresh(self, pid=0, to_write=""): - #print "Refresh %s %d" % (to_write, int(pid)) + def _refresh(self, pid, to_write): try: return ["refresh", sessions.update_session(int(pid), to_write)] - except (KeyError, IOError, Killed): + except (KeyError, IOError, Killed, ConnexionClosed): return ["disconnected"] except Ignore: - return ["ignore"] + return ["ignore"] + + @callback(retval=[str]) + def refresh(self, pid=0, to_write=""): + return self._refresh(pid, to_write) @callback(retval=[str]) def refresh_empty(self, pid=0): #print "Empty refresh %d" % int(pid) - try: - return ["refresh", sessions.update_session(int(pid), None)] - except (KeyError, IOError, Killed): - return ["disconnected"] - except Ignore: - return ["ignore"] + return self._refresh(pid, None) @callback(retval=str) def execute_snippet(self, name='aaa', number=3): - return sessions.docloader.get_snippet(name, int(number)) + return sessions.docloader.get_snippet(name, int(number)) + "\n" @callback() def kill_console(self, pid=0): Modified: pypy/dist/pypy/translator/js/examples/console/data/console.html ============================================================================== --- pypy/dist/pypy/translator/js/examples/console/data/console.html (original) +++ pypy/dist/pypy/translator/js/examples/console/data/console.html Mon Mar 26 16:40:07 2007 @@ -1,13 +1,13 @@ - + Console - PyPy + PyPy

    PyPy[consoles]