From cfbolz at codespeak.net Mon Apr 2 12:08:34 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 2 Apr 2007 12:08:34 +0200 (CEST) Subject: [pypy-svn] r41794 - pypy/dist/pypy/doc Message-ID: <20070402100834.9117B10077@code0.codespeak.net> Author: cfbolz Date: Mon Apr 2 12:08:32 2007 New Revision: 41794 Modified: pypy/dist/pypy/doc/sprint-reports.txt Log: add link to pycon sprint report (lene again) Modified: pypy/dist/pypy/doc/sprint-reports.txt ============================================================================== --- pypy/dist/pypy/doc/sprint-reports.txt (original) +++ pypy/dist/pypy/doc/sprint-reports.txt Mon Apr 2 12:08:32 2007 @@ -20,7 +20,7 @@ * `Paris (Oct 2005)`_ * `Gothenburg (Dec 2005)`_ * `Mallorca (Jan 2006)`_ - * PyCon/Dallas (Feb 2006) + * `PyCon/Dallas (Feb 2006)`_ * `LouvainLaNeuve (March 2006)`_ * `Leysin (April 2006)`_ * `Tokyo (April 2006)`_ @@ -54,3 +54,4 @@ .. _`Leysin (January 2007)`: http://codespeak.net/pypy/extradoc/sprintinfo/leysin-winter-2007/report.txt .. _Hildesheim (Feb 2007): http://codespeak.net/pypy/extradoc/sprintinfo/trillke-2007/sprint-report.txt .. _`EU report writing sprint`: http://codespeak.net/pypy/extradoc/sprintinfo/trillke-2007/eu-report-sprint-report.txt + .. _`PyCon/Dallas (Feb 2006)`: http://codespeak.net/pypy/extradoc/sprintinfo/pycon06/sprint-report.txt From arigo at codespeak.net Mon Apr 2 14:57:51 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 2 Apr 2007 14:57:51 +0200 (CEST) Subject: [pypy-svn] r41803 - in pypy/dist/pypy: config objspace/std Message-ID: <20070402125751.95CFF10077@code0.codespeak.net> Author: arigo Date: Mon Apr 2 14:57:49 2007 New Revision: 41803 Modified: pypy/dist/pypy/config/pypyoption.py pypy/dist/pypy/objspace/std/objspace.py Log: A version of BINARY_SUBSCR that special-cases 'list[integer]'. Not enabled by default, measuring... Modified: pypy/dist/pypy/config/pypyoption.py ============================================================================== --- pypy/dist/pypy/config/pypyoption.py (original) +++ pypy/dist/pypy/config/pypyoption.py Mon Apr 2 14:57:49 2007 @@ -226,6 +226,9 @@ BoolOption("optimized_int_add", "special case the addition of two integers in BINARY_ADD", default=False), + BoolOption("optimized_list_getitem", + "special case the 'list[integer]' expressions", + default=False), BoolOption("oldstyle", "specify whether the default metaclass should be classobj", Modified: pypy/dist/pypy/objspace/std/objspace.py ============================================================================== --- pypy/dist/pypy/objspace/std/objspace.py (original) +++ pypy/dist/pypy/objspace/std/objspace.py Mon Apr 2 14:57:49 2007 @@ -88,6 +88,20 @@ w_result = f.space.add(w_1, w_2) f.pushvalue(w_result) + if self.config.objspace.std.optimized_list_getitem: + def BINARY_SUBSCR(f, *ignored): + w_2 = f.popvalue() + w_1 = f.popvalue() + if type(w_1) is W_ListObject and type(w_2) is W_IntObject: + try: + w_result = w_1.wrappeditems[w_2.intval] + except IndexError: + raise OperationError(f.space.w_IndexError, + f.space.wrap("list index out of range")) + else: + w_result = f.space.getitem(w_1, w_2) + f.pushvalue(w_result) + def CALL_LIKELY_BUILTIN(f, oparg, *ignored): from pypy.module.__builtin__ import OPTIMIZED_BUILTINS, Module from pypy.objspace.std.dictmultiobject import W_DictMultiObject From mwh at codespeak.net Mon Apr 2 15:13:39 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Mon, 2 Apr 2007 15:13:39 +0200 (CEST) Subject: [pypy-svn] r41804 - in pypy/dist/pypy: config interpreter objspace/std Message-ID: <20070402131339.AA2441007A@code0.codespeak.net> Author: mwh Date: Mon Apr 2 15:13:37 2007 New Revision: 41804 Modified: pypy/dist/pypy/config/pypyoption.py pypy/dist/pypy/interpreter/baseobjspace.py pypy/dist/pypy/interpreter/pyopcode.py pypy/dist/pypy/objspace/std/objspace.py Log: add some code to dump out the types verious simple bytecodes receive, the idea being to inspire optimized bytecodes. Modified: pypy/dist/pypy/config/pypyoption.py ============================================================================== --- pypy/dist/pypy/config/pypyoption.py (original) +++ pypy/dist/pypy/config/pypyoption.py Mon Apr 2 15:13:37 2007 @@ -1,4 +1,4 @@ -import autopath +]import autopath import py, os import sys from pypy.config.config import OptionDescription, BoolOption, IntOption, ArbitraryOption @@ -234,6 +234,11 @@ "specify whether the default metaclass should be classobj", default=False, cmdline="--oldstyle"), + BoolOption("logspaceoptypes", + "a instrumentation option: before exit, print the types seen by " + "certain simpler bytecodes", + default=False), + BoolOption("allopts", "enable all thought-to-be-working optimizations", default=False, Modified: pypy/dist/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/dist/pypy/interpreter/baseobjspace.py (original) +++ pypy/dist/pypy/interpreter/baseobjspace.py Mon Apr 2 15:13:37 2007 @@ -225,6 +225,9 @@ report() if self.config.objspace.logbytecodes: self.reportbytecodecounts() + if self.config.objspace.std.logspaceoptypes: + for s in self.FrameClass._space_op_types: + print s def reportbytecodecounts(self): os.write(2, "Starting bytecode report.\n") Modified: pypy/dist/pypy/interpreter/pyopcode.py ============================================================================== --- pypy/dist/pypy/interpreter/pyopcode.py (original) +++ pypy/dist/pypy/interpreter/pyopcode.py Mon Apr 2 15:13:37 2007 @@ -26,6 +26,7 @@ w_1 = f.popvalue() w_result = operation(w_1) f.pushvalue(w_result) + opimpl.unaryop = operationname return func_with_new_name(opimpl, "opcode_impl_for_%s" % operationname) @@ -37,6 +38,7 @@ w_1 = f.popvalue() w_result = operation(w_1, w_2) f.pushvalue(w_result) + opimpl.binop = operationname return func_with_new_name(opimpl, "opcode_impl_for_%s" % operationname) Modified: pypy/dist/pypy/objspace/std/objspace.py ============================================================================== --- pypy/dist/pypy/objspace/std/objspace.py (original) +++ pypy/dist/pypy/objspace/std/objspace.py Mon Apr 2 15:13:37 2007 @@ -132,6 +132,41 @@ f.dropvalues(nargs) f.pushvalue(w_result) + if self.config.objspace.std.logspaceoptypes: + _space_op_types = [] + for name, func in pyframe.PyFrame.__dict__.iteritems(): + if hasattr(func, 'binop'): + operationname = func.binop + def make_opimpl(operationname): + def opimpl(f, *ignored): + operation = getattr(f.space, operationname) + w_2 = f.popvalue() + w_1 = f.popvalue() + if we_are_translated(): + s = operationname + ' ' + str(w_1) + ' ' + str(w_2) + else: + s = operationname + ' ' + w_1.__class__.__name__ + ' ' + w_2.__class__.__name__ + f._space_op_types.append(s) + w_result = operation(w_1, w_2) + f.pushvalue(w_result) + return func_with_new_name(opimpl, "opcode_impl_for_%s" % operationname) + locals()[name] = make_opimpl(operationname) + elif hasattr(func, 'unaryop'): + operationname = func.unaryop + def make_opimpl(operationname): + def opimpl(f, *ignored): + operation = getattr(f.space, operationname) + w_1 = f.popvalue() + if we_are_translated(): + s = operationname + ' ' + str(w_1) + else: + s = operationname + ' ' + w_1.__class__.__name__ + f._space_op_types.append(s) + w_result = operation(w_1) + f.pushvalue(w_result) + return func_with_new_name(opimpl, "opcode_impl_for_%s" % operationname) + locals()[name] = make_opimpl(operationname) + self.FrameClass = StdObjSpaceFrame # XXX store the dict class on the space to access it in various places From cfbolz at codespeak.net Mon Apr 2 15:17:40 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 2 Apr 2007 15:17:40 +0200 (CEST) Subject: [pypy-svn] r41805 - pypy/dist/pypy/config Message-ID: <20070402131740.07A1A10078@code0.codespeak.net> Author: cfbolz Date: Mon Apr 2 15:17:38 2007 New Revision: 41805 Modified: pypy/dist/pypy/config/pypyoption.py Log: huh? Modified: pypy/dist/pypy/config/pypyoption.py ============================================================================== --- pypy/dist/pypy/config/pypyoption.py (original) +++ pypy/dist/pypy/config/pypyoption.py Mon Apr 2 15:17:38 2007 @@ -1,4 +1,4 @@ -]import autopath +import autopath import py, os import sys from pypy.config.config import OptionDescription, BoolOption, IntOption, ArbitraryOption From mwh at codespeak.net Mon Apr 2 18:45:03 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Mon, 2 Apr 2007 18:45:03 +0200 (CEST) Subject: [pypy-svn] r41816 - pypy/dist/pypy/doc/config Message-ID: <20070402164503.7C53E10081@code0.codespeak.net> Author: mwh Date: Mon Apr 2 18:45:02 2007 New Revision: 41816 Added: pypy/dist/pypy/doc/config/objspace.std.logspaceoptypes.txt (contents, props changed) pypy/dist/pypy/doc/config/objspace.std.optimized_list_getitem.txt (contents, props changed) Log: add minimal docs for the new options. Added: pypy/dist/pypy/doc/config/objspace.std.logspaceoptypes.txt ============================================================================== --- (empty file) +++ pypy/dist/pypy/doc/config/objspace.std.logspaceoptypes.txt Mon Apr 2 18:45:02 2007 @@ -0,0 +1,4 @@ +.. internal + +Wrap "simple" bytecode implementations like BINARY_ADD with code that collects +information about which types these bytecodes receive as arguments. Added: pypy/dist/pypy/doc/config/objspace.std.optimized_list_getitem.txt ============================================================================== --- (empty file) +++ pypy/dist/pypy/doc/config/objspace.std.optimized_list_getitem.txt Mon Apr 2 18:45:02 2007 @@ -0,0 +1 @@ +Optimized list[int] a bit. From arigo at codespeak.net Mon Apr 2 22:13:03 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 2 Apr 2007 22:13:03 +0200 (CEST) Subject: [pypy-svn] r41828 - pypy/dist/pypy/lib Message-ID: <20070402201303.655B510077@code0.codespeak.net> Author: arigo Date: Mon Apr 2 22:13:01 2007 New Revision: 41828 Modified: pypy/dist/pypy/lib/_formatting.py Log: A completely essential bug now fixed. Yippee! Modified: pypy/dist/pypy/lib/_formatting.py ============================================================================== --- pypy/dist/pypy/lib/_formatting.py (original) +++ pypy/dist/pypy/lib/_formatting.py Mon Apr 2 22:13:01 2007 @@ -173,7 +173,7 @@ class PercentFormatter(Formatter): def format(self): - return '%' + return self.std_wp('%') # isinf isn't too hard... def isinf(v): From arigo at codespeak.net Mon Apr 2 22:13:54 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 2 Apr 2007 22:13:54 +0200 (CEST) Subject: [pypy-svn] r41829 - pypy/dist/pypy/objspace/std Message-ID: <20070402201354.A732F10077@code0.codespeak.net> Author: arigo Date: Mon Apr 2 22:13:51 2007 New Revision: 41829 Modified: pypy/dist/pypy/objspace/std/typeobject.py Log: A comment. Modified: pypy/dist/pypy/objspace/std/typeobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/typeobject.py (original) +++ pypy/dist/pypy/objspace/std/typeobject.py Mon Apr 2 22:13:51 2007 @@ -267,6 +267,8 @@ w_value = w_self.dict_w.get(attr, None) if w_self.lazyloaders and w_value is None: if attr in w_self.lazyloaders: + # very clever next line: it forces the attr string + # to be interned. w_attr = space.new_interned_str(attr) loader = w_self.lazyloaders[attr] del w_self.lazyloaders[attr] From mwh at codespeak.net Tue Apr 3 12:23:48 2007 From: mwh at codespeak.net (mwh at codespeak.net) Date: Tue, 3 Apr 2007 12:23:48 +0200 (CEST) Subject: [pypy-svn] r41841 - pypy/dist/pypy/translator/goal Message-ID: <20070403102348.2E9C51007D@code0.codespeak.net> Author: mwh Date: Tue Apr 3 12:23:47 2007 New Revision: 41841 Modified: pypy/dist/pypy/translator/goal/bench-cronjob.py Log: finally change bench-cronjob to reflect change in tproxy option name 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 Tue Apr 3 12:23:47 2007 @@ -183,7 +183,7 @@ c--thread c--_objspace=taint c--_allworkingmodules - c--_with-transparent-proxy--_faassen + c--_objspace-std-withtproxy--_faassen c--gc=framework--_faassen c--_objspace-std-withrope cli From fijal at codespeak.net Tue Apr 3 16:07:46 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 3 Apr 2007 16:07:46 +0200 (CEST) Subject: [pypy-svn] r41851 - in pypy/dist/pypy/translator/js: . jssrc test Message-ID: <20070403140746.504A11008A@code0.codespeak.net> Author: fijal Date: Tue Apr 3 16:07:44 2007 New Revision: 41851 Added: pypy/dist/pypy/translator/js/test/test_str.py Modified: pypy/dist/pypy/translator/js/_class.py pypy/dist/pypy/translator/js/function.py pypy/dist/pypy/translator/js/jsbuiltin.py pypy/dist/pypy/translator/js/jssrc/misc.js pypy/dist/pypy/translator/js/opcodes.py pypy/dist/pypy/translator/js/test/runtest.py pypy/dist/pypy/translator/js/test/test_rclass.py pypy/dist/pypy/translator/js/test/test_rpbc.py pypy/dist/pypy/translator/js/test/test_runtest.py Log: * A bit of wacking * A bit of skipping * bunch of new tests * improved testing machinery = we've got test_str, somehow working. Modified: pypy/dist/pypy/translator/js/_class.py ============================================================================== --- pypy/dist/pypy/translator/js/_class.py (original) +++ pypy/dist/pypy/translator/js/_class.py Tue Apr 3 16:07:44 2007 @@ -11,6 +11,7 @@ self.cts = db.genoo.TypeSystem(db) self.classdef = classdef self.name = classdef._name.replace('.', '_')#[-1] + self.real_name = classdef._name if not self.is_root(classdef): self.parent = self.db.pending_class(classdef._superclass) @@ -50,7 +51,7 @@ # begin to_String method ilasm.begin_method("toString", self.name, []) - ilasm.load_str("'<%s instance>'" % self.name) + ilasm.load_str("'<%s object>'" % self.real_name) ilasm.ret() ilasm.end_function() Modified: pypy/dist/pypy/translator/js/function.py ============================================================================== --- pypy/dist/pypy/translator/js/function.py (original) +++ pypy/dist/pypy/translator/js/function.py Tue Apr 3 16:07:44 2007 @@ -28,6 +28,8 @@ self.ilasm.load_local(v) elif isinstance(v, flowmodel.Constant): self.db.load_const(v.concretetype, v.value, self.ilasm) + elif isinstance(v, str): + self.ilasm.load_const("'" + v + "'") else: assert False Modified: pypy/dist/pypy/translator/js/jsbuiltin.py ============================================================================== --- pypy/dist/pypy/translator/js/jsbuiltin.py (original) +++ pypy/dist/pypy/translator/js/jsbuiltin.py Tue Apr 3 16:07:44 2007 @@ -42,8 +42,16 @@ '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]]), + 'll_find' : CallBuiltin('findIndexOf'), + 'll_find_char' : CallBuiltin('findIndexOf'), + #'ll_find' : lambda g, op: Call._render_builtin_method(g, 'indexOf', [op.args[1], op.args[2], op.args[3]]), + #'ll_find_char' : lambda g, op: Call._render_builtin_method(g, 'indexOf', [op.args[1], op.args[2], op.args[3]]), + 'll_contains' : CallBuiltin('findIndexOfTrue'), + 'll_replace_chr_chr' : lambda g, op: + Call._render_builtin_method(g, 'replace', + [op.args[1], op.args[2], op.args[3], 'g']), + 'll_count_char' : CallBuiltin('countCharOf'), + 'll_count' : CallBuiltin('countOf'), }, ootype.List: { 'll_setitem_fast' : ListSetitem, 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 Tue Apr 3 16:07:44 2007 @@ -175,4 +175,46 @@ delete(d[elem]); } } + +function findIndexOf(s1, s2, start, end) { + if (start > end || start > s1.length) { + return -1; + } + s1 = s1.substr(start, end-start); + res = s1.indexOf(s2); + if (res == -1) { + return -1; + } + return res + start; +} + +function findIndexOfTrue(s1, s2) { + return findIndexOf(s1, s2, 0, s1.length) != -1; +} + +function countCharOf(s, c, start, end) { + s = s.substring(start, end); + var i = 0; + for (c1 in s) { + if (s[c1] == c) { + i++; + } + } + return(i); +} + +function countOf(s, s1, start, end) { + var ret = findIndexOf(s, s1, start, end); + var i = 0; + var lgt = 1; + if (s1.length > 0) { + lgt = s1.length; + } + while (ret != -1) { + i++; + ret = findIndexOf(s, s1, ret + lgt, end); + } + return (i); +} + // ends hand written code Modified: pypy/dist/pypy/translator/js/opcodes.py ============================================================================== --- pypy/dist/pypy/translator/js/opcodes.py (original) +++ pypy/dist/pypy/translator/js/opcodes.py Tue Apr 3 16:07:44 2007 @@ -130,6 +130,7 @@ 'oononnull' : [PushAllArgs,_Prefix('!!')], 'oostring' : [PushArg(0),CastString], 'ooparse_int' : [PushAllArgs,_CastFun("parseInt",2)], + 'ooparse_float' : [PushAllArgs,_CastFun("parseFloat",1)], 'oois' : '===', # when casting from bool we want that every truth value is casted # to 1: we can't simply DoNothing, because the CLI stack could Modified: pypy/dist/pypy/translator/js/test/runtest.py ============================================================================== --- pypy/dist/pypy/translator/js/test/runtest.py (original) +++ pypy/dist/pypy/translator/js/test/runtest.py Tue Apr 3 16:07:44 2007 @@ -1,6 +1,3 @@ -''' - Sests with DONT in front of them will probably not be fixed for the time being. -''' import py, os, re, subprocess from pypy.translator.translator import TranslationContext @@ -12,6 +9,7 @@ from pypy.conftest import option from pypy.rpython.test.tool import BaseRtypingTest, OORtypeMixin from pypy.rlib.nonconst import NonConstant +from pypy.rpython.ootypesystem import ootype from pypy.rpython.llinterp import LLException @@ -21,6 +19,9 @@ port = 8080 +class JSException(LLException): + pass + def _CLI_is_on_path(): if py.path.local.sysfind('js') is None: #we recommend Spidermonkey return False @@ -104,18 +105,22 @@ input = "load(%r);\n" % self.js.filename.strpath for call in self.function_calls[:-1]: input += "%s;\n" % call - input += "print(%s);\n" % self.function_calls[-1] + input += "print(\"'\" + %s + \"'\");\n" % self.function_calls[-1] js.stdin.write(input) stdout, stderr = js.communicate() output = (stderr + stdout).strip() for s in output.split('\n'): log(s) - return self.reinterpret(s) + m = re.match("'(.*)'", output, re.DOTALL) + if not m: + log("Error: %s" % output) + raise JSException(output) + return self.reinterpret(m.group(1)) def reinterpret(cls, s): - while s.startswith(" "): - s = s[1:] # :-) quite inneficient, but who cares + #while s.startswith(" "): + # s = s[1:] # :-) quite inneficient, but who cares if s == 'false': res = False elif s == 'true': @@ -126,8 +131,6 @@ res = 1e300 * 1e300 elif s == 'NaN': res = (1e300 * 1e300) / (1e300 * 1e300) - elif s.startswith("uncaught exception:"): - raise LLException(str(s)) elif s.startswith('[') or s.startswith('('): l = s[1:-1].split(',') res = [cls.reinterpret(i) for i in l] @@ -144,6 +147,9 @@ class JsTest(BaseRtypingTest, OORtypeMixin): def _compile(self, _fn, args, policy=None): argnames = _fn.func_code.co_varnames[:_fn.func_code.co_argcount] + func_name = _fn.func_name + if func_name == '': + func_name = 'func' source = py.code.Source(""" def %s(): from pypy.rlib.nonconst import NonConstant @@ -152,10 +158,13 @@ return None else: return str(res)""" - % (_fn.func_name, ",".join(["%s=NonConstant(%s)" % (name,i) for + % (func_name, ",".join(["%s=NonConstant(%r)" % (name, i) for name, i in zip(argnames, args)]))) exec source.compile() in locals() - return compile_function(locals()[_fn.func_name], [], policy=policy) + return compile_function(locals()[func_name], [], policy=policy) + + def string_to_ll(self, s): + return s def interpret(self, fn, args, policy=None): f = self._compile(fn, args, policy) @@ -168,7 +177,7 @@ #import pdb; pdb.set_trace() try: res = self.interpret(fn, args) - except LLException, e: + except JSException, e: s = e.args[0] assert s.startswith('uncaught exception:') assert re.search(str(exception), s) @@ -180,7 +189,7 @@ # assert False, 'function did raise no exception at all' def ll_to_string(self, s): - return s + return str(s) def ll_to_list(self, l): return l Modified: pypy/dist/pypy/translator/js/test/test_rclass.py ============================================================================== --- pypy/dist/pypy/translator/js/test/test_rclass.py (original) +++ pypy/dist/pypy/translator/js/test/test_rclass.py Tue Apr 3 16:07:44 2007 @@ -73,11 +73,3 @@ def test_isinstance(self): py.test.skip("WIP") -#class TestJsPBC(JsTest, BaseTestRPBC): -# pass -## -#class TestJsRtuple(JsTest, BaseTestRtuple): -# pass -## -#class TestJsStr(JsTest, BaseTestRstr): -# pass Modified: pypy/dist/pypy/translator/js/test/test_rpbc.py ============================================================================== --- pypy/dist/pypy/translator/js/test/test_rpbc.py (original) +++ pypy/dist/pypy/translator/js/test/test_rpbc.py Tue Apr 3 16:07:44 2007 @@ -35,5 +35,6 @@ def test_conv_from_None(self): py.test.skip("WIP") - - + def test_multiple_ll_one_hl_op(self): + py.test.skip("XXX fix me soon") + Modified: pypy/dist/pypy/translator/js/test/test_runtest.py ============================================================================== --- pypy/dist/pypy/translator/js/test/test_runtest.py (original) +++ pypy/dist/pypy/translator/js/test/test_runtest.py Tue Apr 3 16:07:44 2007 @@ -56,6 +56,12 @@ assert rp('[a,b]') == ["a", "b"] #assert rp('(true,[a,b])') == [True, ["a", "b"]] +def test_return_newline(): + def fun_newline(): + return "\n" + fun = compile_function(fun_newline, []) + assert fun() == "\n" + ##def test_multiple_function(): ## def one(): ## return 1 Added: pypy/dist/pypy/translator/js/test/test_str.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/js/test/test_str.py Tue Apr 3 16:07:44 2007 @@ -0,0 +1,63 @@ + +import py +from pypy.translator.js.test.runtest import JsTest +import pypy.translator.oosupport.test_template.string as oostring + +class TestJsString(JsTest, oostring.BaseTestString): + def test_unichar_const(self): + py.test.skip("Cannot test it yet") + + def test_unichar_eq(self): + py.test.skip("Cannot test it yet") + + def test_unichar_ord(self): + py.test.skip("Cannot test it yet") + + def test_unichar_hash(self): + py.test.skip("Cannot test it yet") + + def test_rfind(self): + py.test.skip("Not implemented") + + def test_rfind_empty_string(self): + py.test.skip("Not implemented") + + def test_find_char(self): + py.test.skip("Not implemented") + + def test_strip(self): + py.test.skip("Not implemented") + + def test_upper(self): + #XXX Testing machinery is quite confused by js print + strings = ['', ' ', 'upper', 'UpPeR', ',uppEr,'] + #for i in range(256): + # if chr(i) != "\x00" and chr(i) != '(' and chr(i) != '[': + # strings.append(chr(i)) + def fn(i): + return strings[i].upper() + for i in range(len(strings)): + res = self.interpret(fn, [i]) + assert self.ll_to_string(res) == fn(i) + + def test_lower(self): + #XXX Testing machinery is quite confused by js print + strings = ['', ' ', 'lower', 'LoWeR', ',lowEr,'] + #for i in range(256): strings.append(chr(i)) + def fn(i): + return strings[i].lower() + for i in range(len(strings)): + res = self.interpret(fn, [i]) + assert self.ll_to_string(res) == fn(i) + + def test_strformat(self): + py.test.skip("string formatting not implemented for base different than 10") + + def test_float(self): + py.test.skip("returning NaN instead of raising ValueError") + + def test_hash(self): + py.test.skip("Not implemented") + + def test_hash_value(self): + py.test.skip("Not implemented") From fijal at codespeak.net Tue Apr 3 16:33:46 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 3 Apr 2007 16:33:46 +0200 (CEST) Subject: [pypy-svn] r41852 - pypy/dist/pypy/doc Message-ID: <20070403143346.C4AAC1008A@code0.codespeak.net> Author: fijal Date: Tue Apr 3 16:33:44 2007 New Revision: 41852 Modified: pypy/dist/pypy/doc/jit.txt Log: Add a bit about integer arithmetics Modified: pypy/dist/pypy/doc/jit.txt ============================================================================== --- pypy/dist/pypy/doc/jit.txt (original) +++ pypy/dist/pypy/doc/jit.txt Tue Apr 3 16:33:44 2007 @@ -31,8 +31,8 @@ --------------- 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 +integer 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. From fijal at codespeak.net Tue Apr 3 16:40:39 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 3 Apr 2007 16:40:39 +0200 (CEST) Subject: [pypy-svn] r41853 - pypy/dist/pypy/translator/js/examples/test Message-ID: <20070403144039.E9E411008A@code0.codespeak.net> Author: fijal Date: Tue Apr 3 16:40:38 2007 New Revision: 41853 Modified: pypy/dist/pypy/translator/js/examples/test/test_examples.py Log: Add a test that pings play1. Unsure how to do it better. 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 Apr 3 16:40:38 2007 @@ -30,3 +30,9 @@ from pypy.translator.js.examples.console import console, client assert rpython2javascript(client, console.FUNCTION_LIST, use_pdb=False) + +def test_ping_play1(): + from urllib import URLopener + u = URLopener() + text = "pypy.js various demos" + assert u.open("http://play1.pypy.org/").read().find(text) != -1 From arigo at codespeak.net Tue Apr 3 16:41:57 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 3 Apr 2007 16:41:57 +0200 (CEST) Subject: [pypy-svn] r41854 - pypy/extradoc/pypy.org Message-ID: <20070403144157.3B1311008A@code0.codespeak.net> Author: arigo Date: Tue Apr 3 16:41:56 2007 New Revision: 41854 Modified: pypy/extradoc/pypy.org/news.txt Log: Fix the release announcement links (thanks xoraxax). Modified: pypy/extradoc/pypy.org/news.txt ============================================================================== --- pypy/extradoc/pypy.org/news.txt (original) +++ pypy/extradoc/pypy.org/news.txt Tue Apr 3 16:41:56 2007 @@ -2,7 +2,9 @@ ------------------------------------------------------------------ We are proud to release PyPy 1.0.0, our sixth public release. See -the `release announcement `__ to read about the +the `release announcement +`__ +to read about the many new features in this release, especially the results of our JIT generation technology. See also our detailed instructions on how to `get started`_. *(March 27th, 2007)* @@ -13,7 +15,9 @@ ------------------------------------------------------------------- We are proud to release PyPy 0.99.0, our fifth public release. See -the `release announcement `__ to read about the +the `release announcement +`__ +to read about the many new features in this release. See also our detailed instructions on how to `get started`_. *(February 17th, 2007)* From arigo at codespeak.net Tue Apr 3 18:44:58 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 3 Apr 2007 18:44:58 +0200 (CEST) Subject: [pypy-svn] r41859 - pypy/dist/pypy/doc Message-ID: <20070403164458.4E98E1007C@code0.codespeak.net> Author: arigo Date: Tue Apr 3 18:44:57 2007 New Revision: 41859 Modified: pypy/dist/pypy/doc/cleanup-todo.txt Log: Unicode strings in RPython! Modified: pypy/dist/pypy/doc/cleanup-todo.txt ============================================================================== --- pypy/dist/pypy/doc/cleanup-todo.txt (original) +++ pypy/dist/pypy/doc/cleanup-todo.txt Tue Apr 3 18:44:57 2007 @@ -25,6 +25,7 @@ https://codespeak.net/issue/pypy-dev/issue303 and the fact that we can have more than one translator/annotator around (with the timeshifter) + - unicode strings in RPython interpreter ----------- @@ -32,4 +33,4 @@ - review the things implemented at applevel whether they are performance- critical - - review threading (especially GIL). It's segfaulting quite often now. \ No newline at end of file + - review threading (especially GIL). It's segfaulting quite often now. From fijal at codespeak.net Wed Apr 4 09:29:24 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 4 Apr 2007 09:29:24 +0200 (CEST) Subject: [pypy-svn] r41880 - pypy/dist/pypy/translator/js/test Message-ID: <20070404072924.ADB3D1005A@code0.codespeak.net> Author: fijal Date: Wed Apr 4 09:29:22 2007 New Revision: 41880 Modified: pypy/dist/pypy/translator/js/test/runtest.py pypy/dist/pypy/translator/js/test/test_class.py pypy/dist/pypy/translator/js/test/test_rlist.py Log: Few fixes regarding new way of displaying objects. Modified: pypy/dist/pypy/translator/js/test/runtest.py ============================================================================== --- pypy/dist/pypy/translator/js/test/runtest.py (original) +++ pypy/dist/pypy/translator/js/test/runtest.py Wed Apr 4 09:29:22 2007 @@ -199,10 +199,10 @@ return tuple(t) def class_name(self, value): - return value[:-10].split('_')[-1] + return value[:-8].split('.')[-1] def is_of_instance_type(self, val): - m = re.match("^<.* instance>$", val) + m = re.match("^<.* object>$", val) return bool(m) def read_attr(self, obj, name): Modified: pypy/dist/pypy/translator/js/test/test_class.py ============================================================================== --- pypy/dist/pypy/translator/js/test/test_class.py (original) +++ pypy/dist/pypy/translator/js/test/test_class.py Wed Apr 4 09:29:22 2007 @@ -136,11 +136,11 @@ return str(C()) fn = compile_function(instance_str, []) - assert fn() == '' + assert fn() == '' def test_instance_ret(): def instance_ret(): return str(C()) fn = compile_function(instance_ret, []) - assert fn() == '' + assert fn() == '' Modified: pypy/dist/pypy/translator/js/test/test_rlist.py ============================================================================== --- pypy/dist/pypy/translator/js/test/test_rlist.py (original) +++ pypy/dist/pypy/translator/js/test/test_rlist.py Wed Apr 4 09:29:22 2007 @@ -79,5 +79,5 @@ x = l2.pop() return str(x)+";"+str(l) res = self.ll_to_string(self.interpret(fn, [])) - res = res.replace('pypy_translator_js_test_test_rlist_', '') - assert res == ';[, , , , ]' + res = res.replace('pypy.translator.js.test.test_rlist.', '') + assert res == ';[, , , , ]' From niko at codespeak.net Wed Apr 4 09:52:52 2007 From: niko at codespeak.net (niko at codespeak.net) Date: Wed, 4 Apr 2007 09:52:52 +0200 (CEST) Subject: [pypy-svn] r41882 - in pypy/dist/pypy/translator/jvm: . src/pypy test Message-ID: <20070404075252.19C0C10060@code0.codespeak.net> Author: niko Date: Wed Apr 4 09:52:50 2007 New Revision: 41882 Added: pypy/dist/pypy/translator/jvm/src/pypy/Callback.java pypy/dist/pypy/translator/jvm/src/pypy/CustomDict.java pypy/dist/pypy/translator/jvm/src/pypy/Equals.java pypy/dist/pypy/translator/jvm/src/pypy/Filter.java pypy/dist/pypy/translator/jvm/src/pypy/FilterIterator.java pypy/dist/pypy/translator/jvm/src/pypy/FilterSet.java pypy/dist/pypy/translator/jvm/src/pypy/HashCode.java pypy/dist/pypy/translator/jvm/test/test_objectmodel.py Modified: pypy/dist/pypy/translator/jvm/ (props changed) pypy/dist/pypy/translator/jvm/builtin.py pypy/dist/pypy/translator/jvm/constant.py pypy/dist/pypy/translator/jvm/database.py pypy/dist/pypy/translator/jvm/generator.py pypy/dist/pypy/translator/jvm/genjvm.py pypy/dist/pypy/translator/jvm/metavm.py pypy/dist/pypy/translator/jvm/node.py pypy/dist/pypy/translator/jvm/opcodes.py pypy/dist/pypy/translator/jvm/src/pypy/PyPy.java pypy/dist/pypy/translator/jvm/test/test_dict.py pypy/dist/pypy/translator/jvm/test/test_snippet.py pypy/dist/pypy/translator/jvm/typesystem.py Log: Implement custom dicts (rdicts) in the JVM backend. All tests in objectmodel now pass. The technique is to find all functions which could be used as hashCode() or equals() functions, and to make any static functions that are defined implement either pypy.Equals or pypy.HashCode, then allowing them to be passed to pypy.CustomDict. Modified: pypy/dist/pypy/translator/jvm/builtin.py ============================================================================== --- pypy/dist/pypy/translator/jvm/builtin.py (original) +++ pypy/dist/pypy/translator/jvm/builtin.py Wed Apr 4 09:52:50 2007 @@ -3,7 +3,8 @@ from pypy.rpython.ootypesystem import ootype from pypy.translator.jvm.typesystem import \ jInt, jVoid, jStringBuilder, jString, jPyPy, jChar, jArrayList, jObject, \ - jBool, jHashMap, jPyPyDictItemsIterator, Generifier, jCharSequence + jBool, jHashMap, jPyPyDictItemsIterator, Generifier, jCharSequence, \ + jPyPyCustomDict # ______________________________________________________________________ # Mapping of built-in OOTypes to JVM types @@ -128,6 +129,21 @@ (ootype.Dict, "ll_clear"): jvmgen.Method.v(jHashMap, "clear", (), jVoid), + (ootype.CustomDict, "ll_set"): + jvmgen.Method.v(jPyPyCustomDict, "put", (jObject, jObject), jObject), + + (ootype.CustomDict, "ll_get"): + jvmgen.Method.v(jPyPyCustomDict, "get", (jObject,), jObject), + + (ootype.CustomDict, "ll_contains"): + jvmgen.Method.v(jPyPyCustomDict, "containsKey", (jObject,), jBool), + + (ootype.CustomDict, "ll_length"): + jvmgen.Method.v(jPyPyCustomDict, "size", (), jInt), + + (ootype.CustomDict, "ll_clear"): + jvmgen.Method.v(jPyPyCustomDict, "clear", (), jVoid), + (ootype.List, "ll_length"): jvmgen.Method.v(jArrayList, "size", (), jInt), Modified: pypy/dist/pypy/translator/jvm/constant.py ============================================================================== --- pypy/dist/pypy/translator/jvm/constant.py (original) +++ pypy/dist/pypy/translator/jvm/constant.py Wed Apr 4 09:52:50 2007 @@ -1,9 +1,9 @@ from pypy.rpython.ootypesystem import ootype from pypy.translator.jvm.generator import \ - Field, Method + Field, Method, CUSTOMDICTMAKE from pypy.translator.oosupport.constant import \ BaseConstantGenerator, RecordConst, InstanceConst, ClassConst, \ - StaticMethodConst + StaticMethodConst, CustomDictConst from pypy.translator.jvm.typesystem import \ jPyPyConst, jObject, jVoid @@ -63,7 +63,8 @@ self.delegate_impl = None return StaticMethodConst.record_dependencies(self) - self.delegate_impl = self.db.record_delegate_impl(self.value.graph) + self.delegate_impl = self.db.record_delegate_standalone_func_impl( + self.value.graph) def create_pointer(self, gen): if self.delegate_impl: @@ -74,3 +75,20 @@ def initialize_data(self, ilasm): return +class JVMCustomDictConst(CustomDictConst): + + def record_dependencies(self): + # Near as I can tell, self.value is an ootype._custom_dict, + # key_eq is a Python function and graph is, well, a method + # graph that seems to be added to the function pointer + # somewhere. Adapted from cli/constant.py + self.eq_jcls = self.db.record_delegate_standalone_func_impl( + self.value._dict.key_eq.graph) + self.hash_jcls = self.db.record_delegate_standalone_func_impl( + self.value._dict.key_hash.graph) + + def create_pointer(self, gen): + gen.new_with_jtype(self.eq_jcls) + gen.new_with_jtype(self.hash_jcls) + gen.emit(CUSTOMDICTMAKE) + Modified: pypy/dist/pypy/translator/jvm/database.py ============================================================================== --- pypy/dist/pypy/translator/jvm/database.py (original) +++ pypy/dist/pypy/translator/jvm/database.py Wed Apr 4 09:52:50 2007 @@ -32,7 +32,10 @@ self._functions = {} # graph -> jvmgen.Method # (jargtypes, jrettype) -> node.StaticMethodInterface - self._delegates = {} + self._delegates = {} + + # (INSTANCE, method_name) -> node.StaticMethodImplementation + self._bound_methods = {} self._function_names = {} # graph --> function_name @@ -235,12 +238,27 @@ return res def record_delegate(self, TYPE): - """ TYPE is a StaticMethod """ + """ + Creates and returns a StaticMethodInterface type; this type + represents an abstract base class for functions with a given + signature, represented by TYPE, a ootype.StaticMethod + instance. + """ # Translate argument/return types into java types, check if # we already have such a delegate: - jargs = tuple([self.lltype_to_cts(ARG) for ARG in TYPE.ARGS]) + jargs = tuple([self.lltype_to_cts(ARG) for ARG in TYPE.ARGS + if ARG is not ootype.Void]) jret = self.lltype_to_cts(TYPE.RESULT) + return self.record_delegate_sig(jargs, jret) + + def record_delegate_sig(self, jargs, jret): + """ + Like record_delegate, but the signature is in terms of java + types. jargs is a list of JvmTypes, one for each argument, + and jret is a JvmType. Note that jargs does NOT include an + entry for the this pointer of the resulting object. + """ key = (jargs, jret) if key in self._delegates: return self._delegates[key] @@ -250,19 +268,42 @@ name = self._pkg(self._uniq('Delegate')) # Create a new one if we do not: - interface = node.StaticMethodInterface(name, TYPE, jargs, jret) + interface = node.StaticMethodInterface(name, jargs, jret) self._delegates[key] = interface self.pending_node(interface) return interface - def record_delegate_impl(self, graph): - """ TYPE is a StaticMethod """ + def record_delegate_standalone_func_impl(self, graph): + """ + Creates a class with an invoke() method that invokes the given + graph. This object can be used as a function pointer. It + will extend the appropriate delegate for the graph's + signature. + """ jargtypes, jrettype = self.types_for_graph(graph) - key = (jargtypes, jrettype) - assert key in self._delegates + super_class = self.record_delegate_sig(jargtypes, jrettype) pfunc = self.pending_function(graph) implnm = self._pkg(self._uniq(graph.name+'_delegate')) - n = node.StaticMethodImplementation(implnm, self._delegates[key], pfunc) + n = node.StaticMethodImplementation(implnm, super_class, None, pfunc) + self.pending_node(n) + return n + + def record_delegate_bound_method_impl(self, INSTANCE, method_name): + """ + Creates an object with an invoke() method which invokes + a method named method_name on an instance of INSTANCE. + """ + key = (INSTANCE, method_name) + if key in self._bound_methods: + return self._bound_methods[key] + METH_TYPE = INSTANCE._lookup(method_name)[1]._TYPE + super_class = self.record_delegate(METH_TYPE) + self_class = self.lltype_to_cts(INSTANCE) + mthd_obj = self_class.lookup_method(method_name) + implnm = self._pkg(self._uniq( + self_class.simple_name()+"_"+method_name+"_delegate")) + n = self._bound_methods[key] = node.StaticMethodImplementation( + implnm, super_class, self_class, mthd_obj) self.pending_node(n) return n @@ -338,6 +379,7 @@ ootype.List: jvmtype.jArrayList, ootype.Dict: jvmtype.jHashMap, ootype.DictItemsIterator:jvmtype.jPyPyDictItemsIterator, + ootype.CustomDict: jvmtype.jPyPyCustomDict, } def lltype_to_cts(self, OOT): Modified: pypy/dist/pypy/translator/jvm/generator.py ============================================================================== --- pypy/dist/pypy/translator/jvm/generator.py (original) +++ pypy/dist/pypy/translator/jvm/generator.py Wed Apr 4 09:52:50 2007 @@ -10,7 +10,8 @@ jPyPy, jVoid, jMath, desc_for_method, jPrintStream, jClass, jChar, \ jObject, jByteArray, jPyPyExcWrap, jIntegerClass, jLongClass, \ jDoubleClass, jCharClass, jStringBuilder, JvmScalarType, jArrayList, \ - jObjectArray, jPyPyInterlink + jObjectArray, jPyPyInterlink, jPyPyCustomDict, jPyPyEquals, \ + jPyPyHashCode, jMap # ___________________________________________________________________________ # Miscellaneous helper functions @@ -176,6 +177,7 @@ INVOKESTATIC = Opcode('invokestatic') INVOKEVIRTUAL = Opcode('invokevirtual') INVOKESPECIAL = Opcode('invokespecial') +INVOKEINTERFACE = Opcode('invokeinterface') # Other opcodes LDC = Opcode('ldc') # single-word types @@ -293,11 +295,15 @@ not the this ptr 'rettype' - JvmType for return type """ - assert isinstance(classty, JvmType) classnm = classty.name - return Method(classnm, methnm, argtypes, rettype, opcode=INVOKEVIRTUAL) + if isinstance(classty, jvmtype.JvmInterfaceType): + opc = INVOKEINTERFACE + else: + assert isinstance(classty, jvmtype.JvmClassType) + opc = INVOKEVIRTUAL + return Method(classnm, methnm, argtypes, rettype, opcode=opc) v = staticmethod(v) - + # Create a static method: def s(classty, methnm, argtypes, rettype): """ @@ -329,9 +335,14 @@ def is_static(self): return self.opcode == INVOKESTATIC def jasmin_syntax(self): - return "%s/%s%s" % (self.class_name.replace('.','/'), - self.method_name, - self.descriptor) + res = "%s/%s%s" % (self.class_name.replace('.','/'), + self.method_name, + self.descriptor) + # A weird, inexplicable quirk of Jasmin syntax is that it requires + # the number of arguments after an invokeinterface call: + if self.opcode == INVOKEINTERFACE: + res += " %d" % (len(self.argument_types),) + return res OBJHASHCODE = Method.v(jObject, 'hashCode', (), jInt) OBJTOSTRING = Method.v(jObject, 'toString', (), jString) @@ -375,6 +386,8 @@ OBJECTGETCLASS = Method.v(jObject, 'getClass', (), jClass) CLASSGETNAME = Method.v(jClass, 'getName', (), jString) EXCWRAPWRAP = Method.s(jPyPyExcWrap, 'wrap', (jObject,), jPyPyExcWrap) +CUSTOMDICTMAKE = Method.s(jPyPyCustomDict, 'make', + (jPyPyEquals, jPyPyHashCode), jPyPyCustomDict) # ___________________________________________________________________________ # Fields @@ -594,9 +607,9 @@ The correct opcode and their types depends on the opcode. """ unimplemented - def return_val(self, vartype): - """ Returns a value from top of stack of the JvmType 'vartype' """ - self._instr(RETURN.for_type(vartype)) + def return_val(self, jtype): + """ Returns a value from top of stack of the JvmType 'jtype' """ + self._instr(RETURN.for_type(jtype)) def load_class_name(self): """ Loads the name of the *Java* class of the object on the top of @@ -681,6 +694,9 @@ def prepare_generic_argument(self, ITEMTYPE): jty = self.db.lltype_to_cts(ITEMTYPE) + self.prepare_generic_argument_with_jtype(jty) + + def prepare_generic_argument_with_jtype(self, jty): if jty is jvmtype.jVoid: self.emit(ACONST_NULL) elif isinstance(jty, JvmScalarType): @@ -688,6 +704,9 @@ def prepare_generic_result(self, ITEMTYPE): jresty = self.db.lltype_to_cts(ITEMTYPE) + self.prepare_generic_result_with_jtype(jresty) + + def prepare_generic_result_with_jtype(self, jresty): if jresty is jvmtype.jVoid: self.emit(POP) elif isinstance(jresty, JvmScalarType): @@ -696,7 +715,7 @@ self.unbox_value(jresty) else: # Perform any casting required: - self.downcast(ITEMTYPE) + self.downcast_jtype(jresty) def box_value(self, jscalartype): """ Assuming that an value of type jscalartype is on the stack, Modified: pypy/dist/pypy/translator/jvm/genjvm.py ============================================================================== --- pypy/dist/pypy/translator/jvm/genjvm.py (original) +++ pypy/dist/pypy/translator/jvm/genjvm.py Wed Apr 4 09:52:50 2007 @@ -18,7 +18,7 @@ from pypy.translator.jvm.opcodes import opcodes from pypy.rpython.ootypesystem import ootype from pypy.translator.jvm.constant import \ - JVMConstantGenerator, JVMStaticMethodConst + JVMConstantGenerator, JVMStaticMethodConst, JVMCustomDictConst from pypy.translator.jvm.prebuiltnodes import create_interlink_node class JvmError(Exception): @@ -128,10 +128,18 @@ print "... completed!" self.compiled = True - self._compile_helper(('DictItemsIterator', - 'PyPy', + self._compile_helper(('Callback', + 'CustomDict', + 'DictItemsIterator', + 'Equals', 'ExceptionWrapper', - 'Interlink')) + 'Filter', + 'FilterIterator', + 'FilterSet', + 'HashCode', + 'Interlink', + 'PyPy', + )) def _make_str(self, a): if isinstance(a, ootype._string): @@ -199,6 +207,7 @@ log = log ConstantGenerator = JVMConstantGenerator + CustomDictConst = JVMCustomDictConst StaticMethodConst = JVMStaticMethodConst def __init__(self, tmpdir, translator, entrypoint): Modified: pypy/dist/pypy/translator/jvm/metavm.py ============================================================================== --- pypy/dist/pypy/translator/jvm/metavm.py (original) +++ pypy/dist/pypy/translator/jvm/metavm.py Wed Apr 4 09:52:50 2007 @@ -89,3 +89,28 @@ gen.try_catch_region(self.java_exc, trylbl, catchlbl, catchlbl) +class _NewCustomDict(MicroInstruction): + def _load_func(self, gen, fn, obj, method_name): + db = gen.db + if fn.value: + # Standalone function: find the delegate class and + # instantiate it. + assert method_name.value is None + smimpl = fn.value.concretize().value # ootype._static_meth + db.record_delegate(smimpl._TYPE) # _TYPE is a StaticMethod + ty = db.record_delegate_standalone_func_impl(smimpl.graph) + gen.new_with_jtype(ty) + else: + # Bound method: create a wrapper bound to the given + # object, using the "bind()" static method that bound + # method wrapper classes have. + INSTANCE = obj.concretetype + method_name = method_name.value + ty = db.record_delegate_bound_method_impl(INSTANCE, method_name) + gen.load(obj) + gen.emit(ty.bind_method) + def render(self, generator, op): + self._load_func(generator, *op.args[1:4]) + self._load_func(generator, *op.args[4:7]) + generator.emit(jvmgen.CUSTOMDICTMAKE) +NewCustomDict = _NewCustomDict() Modified: pypy/dist/pypy/translator/jvm/node.py ============================================================================== --- pypy/dist/pypy/translator/jvm/node.py (original) +++ pypy/dist/pypy/translator/jvm/node.py Wed Apr 4 09:52:50 2007 @@ -13,7 +13,6 @@ interface defined by database.JvmType. """ - from pypy.objspace.flow import \ model as flowmodel from pypy.rpython.lltypesystem import \ @@ -22,7 +21,7 @@ ootype, rclass from pypy.translator.jvm.typesystem import \ JvmClassType, jString, jStringArray, jVoid, jThrowable, jInt, jPyPyMain, \ - jObject, JvmType, jStringBuilder, jPyPyInterlink + jObject, JvmType, jStringBuilder, jPyPyInterlink, jCallbackInterfaces from pypy.translator.jvm.opcodes import \ opcodes from pypy.translator.jvm.option import \ @@ -359,20 +358,27 @@ abstract class Foo { public abstract ReturnType invoke(Arg1, Arg2, ...); } - + + Depending on the signature of Arg1, Arg2, and ReturnType, this + abstract class may have additional methods and may implement + interfaces such as PyPy.Equals or PyPy.HashCode. This is to allow + it to interface with the the standalone Java code. See + the pypy.Callback interface for more information. """ - def __init__(self, name, STATIC_METHOD, jargtypes, jrettype): + def __init__(self, name, jargtypes, jrettype): """ argtypes: list of JvmTypes rettype: JvmType """ JvmClassType.__init__(self, name) - self.STATIC_METHOD = STATIC_METHOD assert isinstance(jrettype, JvmType) self.java_argument_types = [self] + list(jargtypes) self.java_return_type = jrettype self.dump_method = ConstantStringDumpMethod( self, "StaticMethodInterface") + self.invoke_method_obj = jvmgen.Method.v( + self, 'invoke', + self.java_argument_types[1:], self.java_return_type) def lookup_field(self, fieldnm): """ Given a field name, returns a jvmgen.Field object """ @@ -381,18 +387,58 @@ """ Given the method name, returns a jvmgen.Method object """ assert isinstance(self.java_return_type, JvmType) if methodnm == 'invoke': - return jvmgen.Method.v( - self, 'invoke', - self.java_argument_types[1:], self.java_return_type) + return self.invoke_method_obj raise KeyError(methodnm) # only one method def render(self, gen): assert isinstance(self.java_return_type, JvmType) + + # Scan through the jCallbackInterfaces and look for any + # that apply. + for jci in jCallbackInterfaces: + if jci.matches(self.java_argument_types[1:], self.java_return_type): + break + else: + jci = None + gen.begin_class(self, jObject, abstract=True) + if jci: gen.implements(jci) gen.begin_constructor() gen.end_constructor() + gen.begin_function('invoke', [], self.java_argument_types, self.java_return_type, abstract=True) gen.end_function() + + # Because methods in the JVM are identified by both their name + # and static signature, we need to create a dummy "invoke" + # method if the Java callback interface argument types don't + # match the actual types for this method. For example, the + # equals interface has the static signature + # "(Object,Object)=>boolean", but there may be static methods + # with some signature "(X,Y)=>boolean" where X and Y are other + # types. In that case, we create an adaptor method like: + # + # boolean invoke(Object x, Object y) { + # return invoke((X)x, (Y)y); + # } + if (jci and + (jci.java_argument_types != self.java_argument_types[1:] or + jci.java_return_type != self.java_return_type)): + + jci_jargs = [self] + list(jci.java_argument_types) + jci_ret = jci.java_return_type + gen.begin_function('invoke', [], jci_jargs, jci_ret) + idx = 0 + for jci_arg, self_arg in zip(jci_jargs, self.java_argument_types): + gen.load_jvm_var(jci_arg, idx) + if jci_arg != self_arg: + gen.prepare_generic_result_with_jtype(self_arg) + idx += jci_arg.descriptor.type_width() + gen.emit(self.invoke_method_obj) + assert jci_ret == self.java_return_type # no variance here currently + gen.return_val(jci_ret) + gen.end_function() + gen.end_class() class StaticMethodImplementation(Node, JvmClassType): @@ -406,26 +452,81 @@ return SomeStaticClass.StaticMethod(Arg1, Arg2); } } + + If the bound_to_jty argument is not None, then this class + represents a bound method, and looks something like: + + class Bar extends Foo { + Qux bound_to; + public static Bar bind(Qux to) { + Bar b = new Bar(); + b.bound_to = to; + return b; + } + public ReturnType invoke(Arg1, Arg2) { + return bound_to.SomeMethod(Arg1, Arg2); + } + } """ - def __init__(self, name, interface, impl_method): - JvmClassType.__init__(self, name) - self.super_class = interface + def __init__(self, name, super_class, bound_to_jty, impl_method): + JvmClassType.__init__(self, name) + self.super_class = super_class self.impl_method = impl_method self.dump_method = ConstantStringDumpMethod( self, "StaticMethodImplementation") + + if bound_to_jty: + self.bound_to_jty = bound_to_jty + self.bound_to_fld = jvmgen.Field( + self.name, 'bound_to', bound_to_jty, False) + self.bind_method = jvmgen.Method.s( + self, 'bind', (self.bound_to_jty,), self) + else: + self.bound_to_jty = None + self.bound_to_fld = None + self.bind_method = None + def lookup_field(self, fieldnm): - """ Given a field name, returns a jvmgen.Field object """ + if self.bound_to_fld and fieldnm == self.bound_to_fld.name: + return self.bound_to_fld return self.super_class.lookup_field(fieldnm) def lookup_method(self, methodnm): - """ Given the method name, returns a jvmgen.Method object """ + if self.bind_method and methodnm == 'bind': + return self.bind_method return self.super_class.lookup_method(methodnm) def render(self, gen): gen.begin_class(self, self.super_class) + + if self.bound_to_fld: + gen.add_field(self.bound_to_fld) + gen.begin_constructor() gen.end_constructor() + + # Emit the "bind" function which creates an instance if there is + # a bound field: + if self.bound_to_jty: + assert self.bound_to_fld and self.bind_method + gen.begin_function( + 'bind', [], (self.bound_to_jty,), self, static=True) + gen.new_with_jtype(self) + gen.emit(jvmgen.DUP) + gen.load_jvm_var(self.bound_to_jty, 0) + self.bound_to_fld.store(gen) + gen.return_val(self) + gen.end_function() + + # Emit the invoke() function, which just re-pushes the + # arguments and then invokes either the (possibly static) + # method self.impl_method. Note that if we are bound to an + # instance, we push that as the this pointer for + # self.impl_method. gen.begin_function('invoke', [], self.super_class.java_argument_types, self.super_class.java_return_type) + if self.bound_to_fld: + gen.load_jvm_var(self, 0) + gen.emit(self.bound_to_fld) for i in range(len(self.super_class.java_argument_types)): if not i: continue # skip the this ptr gen.load_function_argument(i) @@ -457,6 +558,11 @@ # attributes: name, method() and render(). Usually, this is a # Function object, but in some subclasses it is not. + def simple_name(self): + dot = self.name.rfind('.') + if dot == -1: return self.name + return self.name[dot+1:] + def set_super_class(self, supercls): self.super_class = supercls Modified: pypy/dist/pypy/translator/jvm/opcodes.py ============================================================================== --- pypy/dist/pypy/translator/jvm/opcodes.py (original) +++ pypy/dist/pypy/translator/jvm/opcodes.py Wed Apr 4 09:52:50 2007 @@ -9,7 +9,7 @@ PushArg, PushAllArgs, StoreResult, InstructionList, New, DoNothing, Call,\ SetField, GetField, DownCast, RuntimeNew, OOString, CastTo from pypy.translator.jvm.metavm import \ - IndirectCall, JvmCallMethod, TranslateException + IndirectCall, JvmCallMethod, TranslateException, NewCustomDict import pypy.translator.jvm.generator as jvmgen import pypy.translator.jvm.typesystem as jvmtype @@ -53,10 +53,10 @@ 'oohash': [PushAllArgs, jvmgen.OBJHASHCODE, StoreResult], 'oostring': [OOString, StoreResult], #'ooparse_int': [PushAllArgs, 'call int32 [pypylib]pypy.runtime.Utils::OOParseInt(string, int32)'], - #'oonewcustomdict': [NewCustomDict], + 'oonewcustomdict': [NewCustomDict, StoreResult], # 'same_as': DoNothing, - #'hint': [PushArg(0), StoreResult], + 'hint': [PushArg(0), StoreResult], 'direct_call': [Call, StoreResult], 'indirect_call': [PushAllArgs, IndirectCall, StoreResult], # Added: pypy/dist/pypy/translator/jvm/src/pypy/Callback.java ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/jvm/src/pypy/Callback.java Wed Apr 4 09:52:50 2007 @@ -0,0 +1,26 @@ +package pypy; + +/** + * This interface has no function but to serve as a documentation + * point and marker. All the interfaces which inherit from it are + * "callback" interfaces: that means that they are used to allow the + * standalone Java code to invoke methods defined in the RPython code. + * + * Whenever a standalone RPython module has a signature that might + * fit as one of the appropriate callbacks, it simply implements required + * interface. Note that these callback interfaces are simply hard-coded + * into database. A more flexible mechanism may eventually be required. + * + * As an example, consider {@link HashCode}. Any time that we generate + * a standalone method which returns a signed integer and takes a single + * object, we cause it to implement {@link HashCode}, which then allows it + * to be used in an {@link #RDict}. + * + * These callback functions are hard-coded in jvm/typesystem.py. To add + * new ones simply add items to the list. + * + * @author Niko Matsakis + */ +public interface Callback { + +} Added: pypy/dist/pypy/translator/jvm/src/pypy/CustomDict.java ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/jvm/src/pypy/CustomDict.java Wed Apr 4 09:52:50 2007 @@ -0,0 +1,145 @@ +package pypy; + +import java.util.AbstractSet; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; +import java.util.Iterator; +import java.util.Set; + +/** + * An implementation of the Map interface where the hashcode and + * equals methods are supplied in the constructor. It is backed + * by a standard Java hashmap, and uses adapter classes to bridge + * between them. + * @author Niko Matsakis + */ +public class CustomDict implements Map +{ + public final Equals equals; + public final HashCode hashCode; + public final Map, V> backingMap = + new HashMap, V>(); + + public static CustomDict make( + final Equals equals, final HashCode hashCode) + { + return new CustomDict(equals, hashCode); + } + + public CustomDict(final Equals equals, final HashCode hashCode) { + this.hashCode = hashCode; + this.equals = equals; + System.err.println("Equals: "+equals.getClass()); + System.err.println("HashCode: "+hashCode.getClass()); + } + + public class Adapter { + public final AK object; + public Adapter(AK object) { + this.object = object; + } + + public int hashCode() { + return hashCode.invoke(this.object); + } + + public boolean equals(Object other) { + return equals.invoke(this.object, ((Adapter)other).object); + } + } + + private Adapter w(AK k) { + return new Adapter(k); + } + + public void clear() { + this.backingMap.clear(); + } + + public boolean containsKey(Object arg0) { + return this.backingMap.containsKey(w(arg0)); + } + + public boolean containsValue(Object value) { + return this.backingMap.containsValue(value); + } + + public Set> entrySet() { + return new FilterSet, V>, Map.Entry>( + this.backingMap.entrySet(), + new Filter, V>, Map.Entry>() { + public Map.Entry, V> from(final Map.Entry to) { + return new Map.Entry, V>() { + public Adapter getKey() { + return new Adapter(to.getKey()); + } + public V getValue() { + return to.getValue(); + } + public V setValue(V value) { + return to.setValue(value); + } + }; + } + + public Map.Entry to(final Map.Entry, V> from) { + return new Map.Entry() { + public K getKey() { + return from.getKey().object; + } + public V getValue() { + return from.getValue(); + } + public V setValue(V value) { + return from.setValue(value); + } + }; + } + }); + } + + public V get(Object key) { + return this.backingMap.get(w(key)); + } + + public boolean isEmpty() { + return this.backingMap.isEmpty(); + } + + public Set keySet() { + return new FilterSet, K>( + this.backingMap.keySet(), + new Filter, K>() { + public Adapter from(K to) { + return new Adapter(to); + } + public K to(Adapter from) { + return from.object; + } + }); + } + + public V put(K key, V value) { + return this.backingMap.put(w(key), value); + } + + public void putAll(Map t) { + for (Map.Entry entry : t.entrySet()) { + this.put(entry.getKey(), entry.getValue()); + } + } + + public V remove(Object key) { + return this.backingMap.remove(w(key)); + } + + public int size() { + return this.backingMap.size(); + } + + public Collection values() { + return this.backingMap.values(); + } + +} \ No newline at end of file Added: pypy/dist/pypy/translator/jvm/src/pypy/Equals.java ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/jvm/src/pypy/Equals.java Wed Apr 4 09:52:50 2007 @@ -0,0 +1,6 @@ +package pypy; + +/** @see Callback */ +public interface Equals extends Callback { + public boolean invoke(Object one, Object two); +} Added: pypy/dist/pypy/translator/jvm/src/pypy/Filter.java ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/jvm/src/pypy/Filter.java Wed Apr 4 09:52:50 2007 @@ -0,0 +1,6 @@ +package pypy; + +public interface Filter { + public T to(F from); + public F from(T to); +} Added: pypy/dist/pypy/translator/jvm/src/pypy/FilterIterator.java ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/jvm/src/pypy/FilterIterator.java Wed Apr 4 09:52:50 2007 @@ -0,0 +1,27 @@ +package pypy; + +import java.util.Iterator; + +public class FilterIterator implements Iterator { + + public final Iterator iter; + public final Filter filter; + + public FilterIterator(final Iterator iter, final Filter filter) { + this.iter = iter; + this.filter = filter; + } + + public boolean hasNext() { + return this.iter.hasNext(); + } + + public T next() { + return filter.to(this.iter.next()); + } + + public void remove() { + this.iter.remove(); + } + +} Added: pypy/dist/pypy/translator/jvm/src/pypy/FilterSet.java ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/jvm/src/pypy/FilterSet.java Wed Apr 4 09:52:50 2007 @@ -0,0 +1,85 @@ +package pypy; + +import java.lang.reflect.Array; +import java.util.Collection; +import java.util.Iterator; +import java.util.Set; + +public class FilterSet implements Set { + + public final Set base; + public final Filter filter; + + public FilterSet(final Set base, final Filter filter) { + this.base = base; + this.filter = filter; + } + + public boolean add(T o) { + return this.base.add(filter.from(o)); + } + + public boolean addAll(Collection c) { + boolean res = false; + for (T t : c) { + res = add(t) || res; + } + return res; + } + + public void clear() { + this.base.clear(); + } + + public boolean contains(Object o) { + return this.base.contains(o); + } + + public boolean containsAll(Collection c) { + return this.base.containsAll(c); + } + + public boolean isEmpty() { + return this.base.isEmpty(); + } + + public Iterator iterator() { + return new FilterIterator(this.base.iterator(), filter); + } + + public boolean remove(Object o) { + return this.base.remove(o); + } + + public boolean removeAll(Collection c) { + return this.base.removeAll(c); + } + + public boolean retainAll(Collection c) { + return this.base.retainAll(c); + } + + public int size() { + return this.base.size(); + } + + @SuppressWarnings("unchecked") + public Object[] toArray() { + Object[] froms = this.base.toArray(); + Object[] tos = new Object[froms.length]; + for (int i = 0; i < froms.length; i++) + tos[i] = filter.to((F)tos[i]); + return tos; + } + + public X[] toArray(X[] a) { + Object[] arr = toArray(); + if (a.length == arr.length) { + System.arraycopy(arr, 0, a, 0, a.length); + return a; + } + // can't be bothered to navigate reflection apis right now + throw new RuntimeException("TODO"); + } + +} Added: pypy/dist/pypy/translator/jvm/src/pypy/HashCode.java ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/jvm/src/pypy/HashCode.java Wed Apr 4 09:52:50 2007 @@ -0,0 +1,6 @@ +package pypy; + +/** @see Callback */ +public interface HashCode extends Callback { + public int invoke(Object obj); +} Modified: pypy/dist/pypy/translator/jvm/src/pypy/PyPy.java ============================================================================== --- pypy/dist/pypy/translator/jvm/src/pypy/PyPy.java (original) +++ pypy/dist/pypy/translator/jvm/src/pypy/PyPy.java Wed Apr 4 09:52:50 2007 @@ -4,6 +4,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.Arrays; +import java.util.Map; /** * Class with a number of utility routines. @@ -521,15 +522,34 @@ // ---------------------------------------------------------------------- // Dicts + // + // Note: it's easier to cut and paste a few methods here than + // make the code generator smarter to avoid the duplicate code. public static boolean ll_remove(HashMap map, Object key) { return map.remove(key) != null; } + public static boolean ll_remove(CustomDict map, Object key) { + return map.remove(key) != null; + } + public static DictItemsIterator ll_get_items_iterator(HashMap map) { return new DictItemsIterator(map); } + + public static DictItemsIterator ll_get_items_iterator(CustomDict map) { + return new DictItemsIterator(map); + } + public static CustomDict ll_copy(CustomDict map) { + CustomDict cd = new CustomDict(map.equals, map.hashCode); + for (Map.Entry me : map.entrySet()) { + cd.put(me.getKey(), me.getValue()); + } + return cd; + } + // ---------------------------------------------------------------------- // Lists Modified: pypy/dist/pypy/translator/jvm/test/test_dict.py ============================================================================== --- pypy/dist/pypy/translator/jvm/test/test_dict.py (original) +++ pypy/dist/pypy/translator/jvm/test/test_dict.py Wed Apr 4 09:52:50 2007 @@ -17,5 +17,4 @@ py.test.skip("Iteration over empty dict is not supported, yet") class TestJvmConstantDict(JvmTest, oodict.BaseTestConstantDict): - def test_constant_r_dict(self): - py.test.skip("JVM doesn't support r_dict so far") + pass Added: pypy/dist/pypy/translator/jvm/test/test_objectmodel.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/jvm/test/test_objectmodel.py Wed Apr 4 09:52:50 2007 @@ -0,0 +1,9 @@ +import py +from pypy.translator.jvm.test.runtest import JvmTest +from pypy.rlib.test.test_objectmodel import BaseTestObjectModel + +from pypy.rlib.objectmodel import cast_object_to_weakgcaddress,\ + cast_weakgcaddress_to_object + +class TestJvmObjectModel(JvmTest, BaseTestObjectModel): + pass Modified: pypy/dist/pypy/translator/jvm/test/test_snippet.py ============================================================================== --- pypy/dist/pypy/translator/jvm/test/test_snippet.py (original) +++ pypy/dist/pypy/translator/jvm/test/test_snippet.py Wed Apr 4 09:52:50 2007 @@ -1,6 +1,26 @@ from pypy.translator.jvm.test.runtest import JvmTest from pypy.translator.oosupport.test_template.snippets import BaseTestSnippets -class TestSnippets(BaseTestSnippets, JvmTest): +class Foo: pass +class TestSnippets(BaseTestSnippets, JvmTest): + + def test_equals_func(self): + def equals(x, y): + return x == y + def unequals(x, y): + return x != y + def base_func(op): + res = 0 + a = Foo() + b = Foo() + if op: func = equals + else: func = unequals + if func(a,b): res += 1 + if func(a,a): res += 10 + if func(b,b): res += 100 + return res + assert self.interpret(base_func, [True]) == 110 + assert self.interpret(base_func, [False]) == 001 + Modified: pypy/dist/pypy/translator/jvm/typesystem.py ============================================================================== --- pypy/dist/pypy/translator/jvm/typesystem.py (original) +++ pypy/dist/pypy/translator/jvm/typesystem.py Wed Apr 4 09:52:50 2007 @@ -127,7 +127,7 @@ def __repr__(self): return "%s<%s>" % (self.__class__.__name__, self.descriptor) - + class JvmClassType(JvmType): """ Base class used for all class instances. Kind of an abstract class; @@ -143,6 +143,9 @@ def lookup_method(self, methodnm): raise KeyError(fieldnm) # we treat as opaque type +class JvmInterfaceType(JvmClassType): + pass + jIntegerClass = JvmClassType('java.lang.Integer') jLongClass = JvmClassType('java.lang.Long') jDoubleClass = JvmClassType('java.lang.Double') @@ -153,15 +156,15 @@ jObject = JvmClassType('java.lang.Object') jString = JvmClassType('java.lang.String') jCharSequence = JvmClassType('java.lang.CharSequence') -jArrayList = JvmClassType('java.util.ArrayList') jArrays = JvmClassType('java.util.Arrays') +jMap = JvmInterfaceType('java.util.Map') jHashMap = JvmClassType('java.util.HashMap') jIterator = JvmClassType('java.util.Iterator') jClass = JvmClassType('java.lang.Class') jStringBuilder = JvmClassType('java.lang.StringBuilder') jPrintStream = JvmClassType('java.io.PrintStream') jMath = JvmClassType('java.lang.Math') -jList = JvmClassType('java.util.List') +jList = JvmInterfaceType('java.util.List') jArrayList = JvmClassType('java.util.ArrayList') jPyPy = JvmClassType('pypy.PyPy') jPyPyExcWrap = JvmClassType('pypy.ExceptionWrapper') @@ -169,6 +172,7 @@ jPyPyMain = JvmClassType('pypy.Main') jPyPyDictItemsIterator = JvmClassType('pypy.DictItemsIterator') jPyPyInterlink = JvmClassType('pypy.Interlink') +jPyPyCustomDict = JvmClassType('pypy.CustomDict') jArithmeticException = JvmClassType('java.lang.ArithmeticException') @@ -184,6 +188,7 @@ raise KeyError(fieldnm) # Scalar objects have no fields def lookup_method(self, methodnm): raise KeyError(methodnm) # Scalar objects have no methods + jVoid = JvmScalarType('V', None, None) jInt = JvmScalarType('I', jIntegerClass, 'intValue') jLong = JvmScalarType('J', jLongClass, 'longValue') @@ -240,9 +245,9 @@ def full_types(self, method_name): """ Returns a tuple of argument and return types for the method - named 'method_name'. These are the actual generic types. The set method for - a list of strings, for example, might return: - ( [INT, STRING], VOID ) + named 'method_name'. These are the actual generic types. The + set method for a list of strings, for example, might return: + ( [INT, STRING], VOID ) """ GENMETH = self.OOTYPE._GENERIC_METHODS[method_name] ARGS, RESULT = (GENMETH.ARGS, GENMETH.RESULT) @@ -253,9 +258,9 @@ def erased_types(self, method_name): """ Returns a tuple of argument and return types for the method - named 'method_name'. These are the erased generic types. The set method for - a list of strings, for example, might return: - ( [INT, OBJECT], VOID ) + named 'method_name'. These are the erased generic types. The + set method for a list of strings, for example, might return: + ( [INT, OBJECT], VOID ) """ GENMETH = self.OOTYPE._GENERIC_METHODS[method_name] ARGS, RESULT = (GENMETH.ARGS, GENMETH.RESULT) @@ -263,5 +268,35 @@ RESULT = self.generics.get(RESULT, (None,RESULT))[1] return (ARGS, RESULT) +# ______________________________________________________________________ +# Java Callback Interfaces +# +# A list of interfaces which static functions that we generate will +# automatically implement if application. See the pypy/Callback.java, +# node.py/StaticMethodInterface for more information. + +jCallbackInterfaces = [] # collects all of the defined JvmCallbackInterfaces + +class JvmCallbackInterface(JvmInterfaceType): + def __init__(self, name, jargtypes, jrettype): + JvmInterfaceType.__init__(self, name) + self.java_argument_types = jargtypes + self.java_return_type = jrettype + jCallbackInterfaces.append(self) # add to global list + def matches(self, jargtypes, jrettype): + """ Given a set of argument types and a return type for some + static function defined by the user, returns true if this + JvmCallbackInterface applies. Note that the types don't have + to match exactly: we assume that (in the list of arguments) + jObject is used as a wildcard, and some adaptation code may + have to be inserted.""" + if len(self.java_argument_types) != len(jargtypes): + return False + for expjarg, actjarg in zip(self.java_argument_types, jargtypes): + if expjarg == jObject: continue # hack: assume obj means any type + if expjarg != actjarg: return False + return jrettype == self.java_return_type - +jPyPyHashCode = JvmCallbackInterface('pypy.HashCode', [jObject], jInt) +jPyPyEquals = JvmCallbackInterface('pypy.Equals', [jObject, jObject], jBool) + From cfbolz at codespeak.net Wed Apr 4 12:23:10 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 4 Apr 2007 12:23:10 +0200 (CEST) Subject: [pypy-svn] r41893 - pypy/extradoc/eu-report Message-ID: <20070404102310.D54A910053@code0.codespeak.net> Author: cfbolz Date: Wed Apr 4 12:23:07 2007 New Revision: 41893 Added: pypy/extradoc/eu-report/D06.1_Core_Optimizations-2007-04-04.pdf (contents, props changed) Log: interim of D06.1 Added: pypy/extradoc/eu-report/D06.1_Core_Optimizations-2007-04-04.pdf ============================================================================== Binary file. No diff available. From arigo at codespeak.net Wed Apr 4 12:29:02 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 4 Apr 2007 12:29:02 +0200 (CEST) Subject: [pypy-svn] r41894 - pypy/dist/pypy/doc Message-ID: <20070404102902.D2C4B1005A@code0.codespeak.net> Author: arigo Date: Wed Apr 4 12:29:00 2007 New Revision: 41894 Modified: pypy/dist/pypy/doc/index-report.txt Log: Link to the interim of D06.1. Modified: pypy/dist/pypy/doc/index-report.txt ============================================================================== --- pypy/dist/pypy/doc/index-report.txt (original) +++ pypy/dist/pypy/doc/index-report.txt Wed Apr 4 12:29:00 2007 @@ -12,6 +12,10 @@ Reports of 2007 =============== +`D06.1 Core Object Optimization Results`_ documents the optimizations +we implemented in the interpreter and object space: dictionary +imlementations, method call optimizations, etc. *(2007-04-04)* + `D14.5 Documentation of the development process`_ documents PyPy's sprint-driven development process and puts it into the context of agile methodologies. *(2007-03-30)* @@ -129,6 +133,7 @@ .. _`D05.2 A Compiled Version of PyPy`: http://codespeak.net/svn/pypy/extradoc/eu-report/D05.2_A_compiled,_self-contained_version_of_PyPy.pdf .. _`D05.3 Implementation with Translation Aspects`: http://codespeak.net/svn/pypy/extradoc/eu-report/D05.3_Publish_on_implementation_with_translation_aspects.pdf .. _`D05.4 Encapsulating Low Level Aspects`: http://codespeak.net/svn/pypy/extradoc/eu-report/D05.4_Publish_on_encapsulating_low_level_language_aspects.pdf +.. _`D06.1 Core Object Optimization Results`: http://codespeak.net/svn/pypy/extradoc/eu-report/D06.1_Core_Optimizations-2007-04-04.pdf .. _`D07.1 Massive Parallelism and Translation Aspects`: http://codespeak.net/pypy/extradoc/eu-report/D07.1_Massive_Parallelism_and_Translation_Aspects-2007-02-28.pdf .. _`Draft D08.2 JIT Compiler Architecture`: http://codespeak.net/pypy/extradoc/eu-report/D08.2_JIT_Compiler_Architecture-interim-2007-01-28.pdf .. _`D09.1 Constraint Solving and Semantic Web`: http://codespeak.net/pypy/extradoc/eu-report/D09.1_Constraint_Solving_and_Semantic_Web-interim-2007-02-28.pdf From cfbolz at codespeak.net Wed Apr 4 12:34:08 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 4 Apr 2007 12:34:08 +0200 (CEST) Subject: [pypy-svn] r41896 - pypy/dist/pypy/doc Message-ID: <20070404103408.CA13610060@code0.codespeak.net> Author: cfbolz Date: Wed Apr 4 12:34:07 2007 New Revision: 41896 Modified: pypy/dist/pypy/doc/index-report.txt Log: add a feedback wanted 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 Apr 4 12:34:07 2007 @@ -14,7 +14,8 @@ `D06.1 Core Object Optimization Results`_ documents the optimizations we implemented in the interpreter and object space: dictionary -imlementations, method call optimizations, etc. *(2007-04-04)* +imlementations, method call optimizations, etc. The report is still not final +so we are very interested in any feedback *(2007-04-04)* `D14.5 Documentation of the development process`_ documents PyPy's sprint-driven development process and puts it into the context of agile From cfbolz at codespeak.net Thu Apr 5 13:55:45 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 5 Apr 2007 13:55:45 +0200 (CEST) Subject: [pypy-svn] r41911 - pypy/extradoc/eu-report Message-ID: <20070405115545.8F3A910075@code0.codespeak.net> Author: cfbolz Date: Thu Apr 5 13:55:44 2007 New Revision: 41911 Added: pypy/extradoc/eu-report/D14.4_Report_About_Milestone_Phase_3-interim-2007-2007-04-05.pdf (contents, props changed) Log: interim Added: pypy/extradoc/eu-report/D14.4_Report_About_Milestone_Phase_3-interim-2007-2007-04-05.pdf ============================================================================== Binary file. No diff available. From hpk at codespeak.net Thu Apr 5 18:29:15 2007 From: hpk at codespeak.net (hpk at codespeak.net) Date: Thu, 5 Apr 2007 18:29:15 +0200 (CEST) Subject: [pypy-svn] r41916 - pypy/dist/pypy/doc Message-ID: <20070405162915.4158F10072@code0.codespeak.net> Author: hpk Date: Thu Apr 5 18:29:13 2007 New Revision: 41916 Modified: pypy/dist/pypy/doc/index-report.txt Log: added reference to 14.4 and rewrote the intro to make it a bit more timeless. Modified: pypy/dist/pypy/doc/index-report.txt ============================================================================== --- pypy/dist/pypy/doc/index-report.txt (original) +++ pypy/dist/pypy/doc/index-report.txt Thu Apr 5 18:29:13 2007 @@ -2,16 +2,21 @@ PyPy - Overview over the EU-reports ============================================ - -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 from the years 2006 and 2007 are preliminary versions, none of them -have been approved by the European Union. +Below reports summarize and discuss research and development results +of the PyPy project during the EU funding period (Dez 2004 - March 2007). +They also are very good documentation if you'd like to know in more +detail about motivation and implementation of the various parts +and aspects of PyPy. Feel free to send questions or comments +to `pypy-dev`_, the development list. Reports of 2007 =============== +`D14.4 PyPy-1.0 Milestone report`_ (for language developers and researchers) +summarizes research & technical results of the PyPy-1.0 release and discusses +related development process and community aspects. This report is an interim +version, we may still incorporate feedback. *(2007-04-05)* + `D06.1 Core Object Optimization Results`_ documents the optimizations we implemented in the interpreter and object space: dictionary imlementations, method call optimizations, etc. The report is still not final @@ -81,6 +86,7 @@ .. _`py-lib`: http://codespeak.net/py/current/doc/ .. _`py.test`: http://codespeak.net/py/current/doc/test.html .. _codespeak: http://codespeak.net/ +.. _`pypy-dev`: http://codespeak.net/mailman/listinfo/pypy-dev Reports of 2006 @@ -145,6 +151,7 @@ .. _`D14.1 Report about Milestone/Phase 1`: http://codespeak.net/svn/pypy/extradoc/eu-report/D14.1_Report_about_Milestone_Phase_1.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-2007-03-22.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 +.. _`D14.4 PyPy-1.0 Milestone report`: http://codespeak.net/pypy/extradoc/eu-report/D14.4_Report_About_Milestone_Phase_3-interim-2007-2007-04-05.pdf .. _`D14.5 Documentation of the development process`: http://codespeak.net/pypy/extradoc/eu-report/D14.5_Documentation_of_the_development_process-2007-03-30.pdf From arigo at codespeak.net Tue Apr 10 18:19:24 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 10 Apr 2007 18:19:24 +0200 (CEST) Subject: [pypy-svn] r41989 - in pypy/dist/pypy/translator/js: . test Message-ID: <20070410161924.69C1B8090@code0.codespeak.net> Author: arigo Date: Tue Apr 10 18:19:24 2007 New Revision: 41989 Modified: pypy/dist/pypy/translator/js/main.py pypy/dist/pypy/translator/js/test/test_main.py Log: (scott dial) Don't invoke Pygame from the JS test suite. Modified: pypy/dist/pypy/translator/js/main.py ============================================================================== --- pypy/dist/pypy/translator/js/main.py (original) +++ pypy/dist/pypy/translator/js/main.py Tue Apr 10 18:19:24 2007 @@ -117,7 +117,7 @@ print retval return retval -def rpython2javascript(mod, function_names, jsconfig=None, use_pdb=True): +def rpython2javascript(mod, function_names, jsconfig=None): if isinstance(function_names, str): function_names = [function_names] # avoid confusion @@ -129,8 +129,6 @@ if jsconfig is None: jsconfig = Config(js_optiondescr) - if use_pdb: - jsconfig.use_pdb = True module_name = mod.__name__ if not function_names and 'main' in mod.__dict__: function_names.append('main') @@ -162,4 +160,4 @@ # XXX: Add some possibility to write down selected file except Exception, e: # do something nice with it - debug(driver, use_pdb) + debug(driver, jsconfig.use_pdb) Modified: pypy/dist/pypy/translator/js/test/test_main.py ============================================================================== --- pypy/dist/pypy/translator/js/test/test_main.py (original) +++ pypy/dist/pypy/translator/js/test/test_main.py Tue Apr 10 18:19:24 2007 @@ -33,11 +33,11 @@ pass def test_bookkeeper_cleanup(): - assert rpython2javascript(sys.modules[__name__], ["fun"]) - assert rpython2javascript(sys.modules[__name__], ["fun"]) + assert rpython2javascript(sys.modules[__name__], ["fun"], jsconfig) + assert rpython2javascript(sys.modules[__name__], ["fun"], jsconfig) def test_module_none(): - assert rpython2javascript(None, "fff") + assert rpython2javascript(None, "fff", jsconfig) class TestJsMain(object): def _test_not_raises(self, mod_file, args_rest=[]): From arigo at codespeak.net Tue Apr 10 18:23:42 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 10 Apr 2007 18:23:42 +0200 (CEST) Subject: [pypy-svn] r41990 - in pypy/dist/pypy/translator/js: . test Message-ID: <20070410162342.481968097@code0.codespeak.net> Author: arigo Date: Tue Apr 10 18:23:41 2007 New Revision: 41990 Modified: pypy/dist/pypy/translator/js/main.py pypy/dist/pypy/translator/js/test/test_main.py Log: Revert r41989 - many tests fail. Mea culpa. Modified: pypy/dist/pypy/translator/js/main.py ============================================================================== --- pypy/dist/pypy/translator/js/main.py (original) +++ pypy/dist/pypy/translator/js/main.py Tue Apr 10 18:23:41 2007 @@ -117,7 +117,7 @@ print retval return retval -def rpython2javascript(mod, function_names, jsconfig=None): +def rpython2javascript(mod, function_names, jsconfig=None, use_pdb=True): if isinstance(function_names, str): function_names = [function_names] # avoid confusion @@ -129,6 +129,8 @@ if jsconfig is None: jsconfig = Config(js_optiondescr) + if use_pdb: + jsconfig.use_pdb = True module_name = mod.__name__ if not function_names and 'main' in mod.__dict__: function_names.append('main') @@ -160,4 +162,4 @@ # XXX: Add some possibility to write down selected file except Exception, e: # do something nice with it - debug(driver, jsconfig.use_pdb) + debug(driver, use_pdb) Modified: pypy/dist/pypy/translator/js/test/test_main.py ============================================================================== --- pypy/dist/pypy/translator/js/test/test_main.py (original) +++ pypy/dist/pypy/translator/js/test/test_main.py Tue Apr 10 18:23:41 2007 @@ -33,11 +33,11 @@ pass def test_bookkeeper_cleanup(): - assert rpython2javascript(sys.modules[__name__], ["fun"], jsconfig) - assert rpython2javascript(sys.modules[__name__], ["fun"], jsconfig) + assert rpython2javascript(sys.modules[__name__], ["fun"]) + assert rpython2javascript(sys.modules[__name__], ["fun"]) def test_module_none(): - assert rpython2javascript(None, "fff", jsconfig) + assert rpython2javascript(None, "fff") class TestJsMain(object): def _test_not_raises(self, mod_file, args_rest=[]): From arigo at codespeak.net Tue Apr 10 20:16:02 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 10 Apr 2007 20:16:02 +0200 (CEST) Subject: [pypy-svn] r41992 - in pypy/dist/pypy/jit: codegen/llgraph hintannotator hintannotator/test timeshifter/test Message-ID: <20070410181602.B0ECC8090@code0.codespeak.net> Author: arigo Date: Tue Apr 10 20:16:02 2007 New Revision: 41992 Modified: pypy/dist/pypy/jit/codegen/llgraph/llimpl.py pypy/dist/pypy/jit/hintannotator/model.py pypy/dist/pypy/jit/hintannotator/test/test_annotator.py pypy/dist/pypy/jit/timeshifter/test/test_portal.py Log: cast_ptr_to_int support. 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 Tue Apr 10 20:16:02 2007 @@ -167,11 +167,17 @@ block.operations.append(op) return to_opaque_object(erasedvar(v, block)) +RESULT_TYPES = { + 'cast_ptr_to_int': lltype.Signed, + } + def guess_result_type(opname, opvars): if opname.endswith('_zer'): # h opname = opname[:-4] # a if opname.endswith('_ovf'): # c opname = opname[:-4] # k + if opname in RESULT_TYPES: + return RESULT_TYPES[opname] 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" Modified: pypy/dist/pypy/jit/hintannotator/model.py ============================================================================== --- pypy/dist/pypy/jit/hintannotator/model.py (original) +++ pypy/dist/pypy/jit/hintannotator/model.py Tue Apr 10 20:16:02 2007 @@ -15,6 +15,7 @@ cast_uint_to_int cast_char_to_int cast_bool_to_int + cast_ptr_to_int ptr_nonzero ptr_iszero is_early_constant 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 Tue Apr 10 20:16:02 2007 @@ -909,3 +909,13 @@ assert hs.is_green() for graph in hannotator.translator.graphs: assert 'int_mul' not in flowmodel.summary(graph) + + +def test_cast_ptr_to_int(): + GCS1 = lltype.GcStruct('s1', ('x', lltype.Signed)) + def f(): + p = lltype.malloc(GCS1) + return lltype.cast_ptr_to_int(p) + + hs = hannotate(f, [], policy=P_NOVIRTUAL) + assert not hs.is_green() Modified: pypy/dist/pypy/jit/timeshifter/test/test_portal.py ============================================================================== --- pypy/dist/pypy/jit/timeshifter/test/test_portal.py (original) +++ pypy/dist/pypy/jit/timeshifter/test/test_portal.py Tue Apr 10 20:16:02 2007 @@ -5,6 +5,7 @@ from pypy.jit.timeshifter.test.test_timeshift import P_NOVIRTUAL, StopAtXPolicy from pypy.jit.timeshifter.test.test_vlist import P_OOPSPEC from pypy.rpython.llinterp import LLInterpreter +from pypy.rpython.lltypesystem import lltype from pypy.objspace.flow.model import summary from pypy.rlib.objectmodel import hint from pypy.jit.codegen.llgraph.rgenop import RGenOp as LLRGenOp @@ -517,3 +518,14 @@ res = self.timeshift_from_portal(f, f, [15], policy=P_OOPSPEC) assert res == 15 + + def test_cast_ptr_to_int(self): + GCS1 = lltype.GcStruct('s1', ('x', lltype.Signed)) + def g(p): + return lltype.cast_ptr_to_int(p) + def f(): + p = lltype.malloc(GCS1) + return g(p) - lltype.cast_ptr_to_int(p) + + res = self.timeshift_from_portal(f, g, [], policy=P_NOVIRTUAL) + assert res == 0 From arigo at codespeak.net Tue Apr 10 20:40:00 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 10 Apr 2007 20:40:00 +0200 (CEST) Subject: [pypy-svn] r41993 - in pypy/dist/pypy/jit/codegen: . dump i386 llgraph test Message-ID: <20070410184000.560628090@code0.codespeak.net> Author: arigo Date: Tue Apr 10 20:39:58 2007 New Revision: 41993 Modified: pypy/dist/pypy/jit/codegen/dump/rgenop.py pypy/dist/pypy/jit/codegen/graph2rgenop.py pypy/dist/pypy/jit/codegen/i386/rgenop.py pypy/dist/pypy/jit/codegen/llgraph/rgenop.py pypy/dist/pypy/jit/codegen/model.py pypy/dist/pypy/jit/codegen/test/rgenop_tests.py Log: Cast tests. Support for cast_int_to_ptr too, just in case. 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 Tue Apr 10 20:39:58 2007 @@ -181,6 +181,15 @@ self.rgenop.vname(gv_ptr2))) return v + def genop_cast_int_to_ptr(self, kind, gv_int): + v = self.llbuilder.genop_cast_int_to_ptr(kind, gv_int) + self.dump("%s = %s.genop_cast_int_to_ptr(%s, %s)" % ( + self.rgenop.vname(v), + self.name, + self.rgenop.kindtokenname(kind), + self.rgenop.vname(gv_int))) + return v + def genop_same_as(self, kind, gv_x): v = self.llbuilder.genop_same_as(kind, gv_x) self.dump("%s = %s.genop_same_as(%s, %s)" % ( Modified: pypy/dist/pypy/jit/codegen/graph2rgenop.py ============================================================================== --- pypy/dist/pypy/jit/codegen/graph2rgenop.py (original) +++ pypy/dist/pypy/jit/codegen/graph2rgenop.py Tue Apr 10 20:39:58 2007 @@ -171,7 +171,12 @@ gv_result = builder.genop_ptr_ne(token, var2gv(op.args[0]), var2gv(op.args[1])) - + + elif op.opname == 'cast_int_to_ptr': + token = rgenop.kindToken(op.result.concretetype) + gv_result = builder.genop_cast_int_to_ptr(token, + var2gv(op.args[0])) + elif len(op.args) == 1: gv_result = builder.genop1(op.opname, var2gv(op.args[0])) elif len(op.args) == 2: Modified: pypy/dist/pypy/jit/codegen/i386/rgenop.py ============================================================================== --- pypy/dist/pypy/jit/codegen/i386/rgenop.py (original) +++ pypy/dist/pypy/jit/codegen/i386/rgenop.py Tue Apr 10 20:39:58 2007 @@ -419,6 +419,9 @@ self.operations.append(op) return op + def genop_cast_int_to_ptr(self, kind, gv_int): + return gv_int # identity + def genop_same_as(self, kind, gv_x): if gv_x.is_const: # must always return a var op = OpSameAs(gv_x) Modified: pypy/dist/pypy/jit/codegen/llgraph/rgenop.py ============================================================================== --- pypy/dist/pypy/jit/codegen/llgraph/rgenop.py (original) +++ pypy/dist/pypy/jit/codegen/llgraph/rgenop.py Tue Apr 10 20:39:58 2007 @@ -254,6 +254,12 @@ return LLVar(llimpl.genop(self.b, 'ptr_ne', [gv_ptr1, gv_ptr2], gv_Bool.v)) + def genop_cast_int_to_ptr(self, gv_PTRTYPE, gv_int): + debug_assert(self.rgenop.currently_writing is self, + "genop_cast_int_to_ptr: bad currently_writing") + return LLVar(llimpl.genop(self.b, 'cast_int_to_ptr', [gv_int], + gv_PTRTYPE.v)) + def _newblock(self, kinds): self.b = newb = llimpl.newblock() return [LLVar(llimpl.geninputarg(newb, kind.v)) for kind in kinds] Modified: pypy/dist/pypy/jit/codegen/model.py ============================================================================== --- pypy/dist/pypy/jit/codegen/model.py (original) +++ pypy/dist/pypy/jit/codegen/model.py Tue Apr 10 20:39:58 2007 @@ -88,6 +88,7 @@ ## def genop_ptr_nonzero(self, kindtoken, gv_ptr) ## def genop_ptr_eq(self, kindtoken, gv_ptr1, gv_ptr2) ## def genop_ptr_ne(self, kindtoken, gv_ptr1, gv_ptr2) +## def genop_cast_int_to_ptr(self, kindtoken, gv_int) # the other thing that happens for a given chunk is entering and # leaving basic blocks inside it. 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 Apr 10 20:39:58 2007 @@ -1,6 +1,6 @@ import random, sys from pypy.rpython.annlowlevel import MixLevelAnnotatorPolicy, llhelper -from pypy.rlib.rarithmetic import intmask +from pypy.rlib.rarithmetic import intmask, r_uint from pypy.rlib.objectmodel import keepalive_until_here from pypy.rpython.lltypesystem import lltype, llmemory from pypy.translator.c.test import test_boehm @@ -2038,3 +2038,40 @@ assert (res & 1) == 1 else: assert res == intmask(expected << 1) | 0 + + def test_cast_direct(self): + yield self.cast_direct, ["int_is_true", "cast_bool_to_int"], bool + yield self.cast_direct, ["int_is_true", + "cast_bool_to_uint", + "cast_uint_to_int"], bool + yield self.cast_direct, ["cast_int_to_char", + "cast_char_to_int"], int, 255 + yield self.cast_direct, ["cast_int_to_unichar", + "cast_unichar_to_int"], int, sys.maxunicode + yield self.cast_direct, ["cast_int_to_uint", "cast_uint_to_int"], int + yield self.cast_direct, ["cast_int_to_ptr", "cast_ptr_to_int"], int + + def cast_direct(self, operations, expected, max=r_uint(-1)): + need_odd_integer = False + rgenop = self.RGenOp() + sigtoken = rgenop.sigToken(FUNC) + builder, gv_fn, [gv_x] = rgenop.newgraph(sigtoken, "cast") + builder.start_writing() + for opname in operations: + if opname == "cast_int_to_ptr": + S = lltype.GcStruct('s', ('x', lltype.Signed)) + ptrkind = rgenop.kindToken(lltype.Ptr(S)) + gv_x = builder.genop_cast_int_to_ptr(ptrkind, gv_x) + need_odd_integer = True + else: + gv_x = builder.genop1(opname, gv_x) + builder.finish_and_return(sigtoken, gv_x) + builder.end() + + fnptr = self.cast(gv_fn, 1) + for x in [0, 1, max // 6, max // 2, max - 1, max]: + x = intmask(x) + if need_odd_integer: + x |= 1 + result = fnptr(x) + assert result == expected(x) From arigo at codespeak.net Tue Apr 10 20:43:02 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 10 Apr 2007 20:43:02 +0200 (CEST) Subject: [pypy-svn] r41994 - pypy/dist/pypy/jit/codegen/ppc Message-ID: <20070410184302.022238096@code0.codespeak.net> Author: arigo Date: Tue Apr 10 20:43:02 2007 New Revision: 41994 Modified: pypy/dist/pypy/jit/codegen/ppc/rgenop.py Log: Implement genop_cast_int_to_ptr in codegen/ppc too. 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 Apr 10 20:43:02 2007 @@ -398,6 +398,9 @@ else: return gv_arg + def genop_cast_int_to_ptr(self, ptrkindtoken, gv_int): + return gv_int + ## def genop_debug_pdb(self): # may take an args_gv later def genop_get_frame_base(self): @@ -1111,7 +1114,6 @@ return self._compare('eq', gv_arg, self.rgenop.genconst(0)) op_cast_ptr_to_int = _identity - op_cast_int_to_ptr = _identity # ... address operations ... From stephan at codespeak.net Thu Apr 12 10:42:53 2007 From: stephan at codespeak.net (stephan at codespeak.net) Date: Thu, 12 Apr 2007 10:42:53 +0200 (CEST) Subject: [pypy-svn] r41999 - pypy/dist/pypy/lib Message-ID: <20070412084253.D37888091@code0.codespeak.net> Author: stephan Date: Thu Apr 12 10:42:52 2007 New Revision: 41999 Modified: pypy/dist/pypy/lib/stackless.py Log: added a tasklet.run method Modified: pypy/dist/pypy/lib/stackless.py ============================================================================== --- pypy/dist/pypy/lib/stackless.py (original) +++ pypy/dist/pypy/lib/stackless.py Thu Apr 12 10:42:52 2007 @@ -71,7 +71,7 @@ """ try: return greenlet.switch(self._frame) - except TypeError: # self._frame is the main coroutine + except TypeError, exp: # self._frame is the main coroutine return greenlet.switch(self._frame.something) def kill(self): @@ -353,6 +353,12 @@ _scheduler_append(self) return self + def run(self): + if _scheduler_contains(self): + return + else: + _scheduler_append(self) + def __reduce__(self): one, two, three = coroutine.__reduce__(self) assert one is coroutine From stephan at codespeak.net Thu Apr 12 10:51:30 2007 From: stephan at codespeak.net (stephan at codespeak.net) Date: Thu, 12 Apr 2007 10:51:30 +0200 (CEST) Subject: [pypy-svn] r42000 - pypy/dist/pypy/lib Message-ID: <20070412085130.2D7378091@code0.codespeak.net> Author: stephan Date: Thu Apr 12 10:51:29 2007 New Revision: 42000 Modified: pypy/dist/pypy/lib/stackless.py Log: removed calls to super in tasklet.__new__ and tasklet.__init__ Modified: pypy/dist/pypy/lib/stackless.py ============================================================================== --- pypy/dist/pypy/lib/stackless.py (original) +++ pypy/dist/pypy/lib/stackless.py Thu Apr 12 10:51:29 2007 @@ -282,10 +282,10 @@ """ tempval = None def __new__(cls, func=None, label=''): - return super(tasklet,cls).__new__(cls) + return coroutine.__new__(cls) def __init__(self, func=None, label=''): - super(tasklet, self).__init__() + coroutine.__init__(self) self._init(func, label) def _init(self, func=None, label=''): From fijal at codespeak.net Thu Apr 12 14:36:08 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 12 Apr 2007 14:36:08 +0200 (CEST) Subject: [pypy-svn] r42002 - in pypy/dist/pypy/rpython: lltypesystem test Message-ID: <20070412123608.CF73E8096@code0.codespeak.net> Author: fijal Date: Thu Apr 12 14:36:07 2007 New Revision: 42002 Modified: pypy/dist/pypy/rpython/lltypesystem/rstr.py pypy/dist/pypy/rpython/test/test_rstr.py Log: Support for 'x' * negative, apparently this worked in ootypesystem before (not sure if backends support it though) Modified: pypy/dist/pypy/rpython/lltypesystem/rstr.py ============================================================================== --- pypy/dist/pypy/rpython/lltypesystem/rstr.py (original) +++ pypy/dist/pypy/rpython/lltypesystem/rstr.py Thu Apr 12 14:36:07 2007 @@ -149,6 +149,8 @@ class LLHelpers(AbstractLLHelpers): def ll_char_mul(ch, times): + if times < 0: + times = 0 newstr = mallocstr(times) j = 0 while j < times: Modified: pypy/dist/pypy/rpython/test/test_rstr.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_rstr.py (original) +++ pypy/dist/pypy/rpython/test/test_rstr.py Thu Apr 12 14:36:07 2007 @@ -600,6 +600,13 @@ res = self.interpret(f, ['a', 0]) assert self.ll_to_string(res) == "" + def test_char_mul_negative(self): + def f(c): + return c * -3 + + res = self.interpret(f, ['a']) + assert self.ll_to_string(res) == '' + def test_n_mul_char(self): def f(c, n): return n*c From arigo at codespeak.net Thu Apr 12 19:41:11 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 12 Apr 2007 19:41:11 +0200 (CEST) Subject: [pypy-svn] r42003 - pypy/dist/pypy/doc Message-ID: <20070412174111.DCACE80A2@code0.codespeak.net> Author: arigo Date: Thu Apr 12 19:41:11 2007 New Revision: 42003 Modified: pypy/dist/pypy/doc/index-report.txt Log: Typo. Modified: pypy/dist/pypy/doc/index-report.txt ============================================================================== --- pypy/dist/pypy/doc/index-report.txt (original) +++ pypy/dist/pypy/doc/index-report.txt Thu Apr 12 19:41:11 2007 @@ -19,7 +19,7 @@ `D06.1 Core Object Optimization Results`_ documents the optimizations we implemented in the interpreter and object space: dictionary -imlementations, method call optimizations, etc. The report is still not final +implementations, method call optimizations, etc. The report is still not final so we are very interested in any feedback *(2007-04-04)* `D14.5 Documentation of the development process`_ documents PyPy's From fijal at codespeak.net Thu Apr 12 19:50:21 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 12 Apr 2007 19:50:21 +0200 (CEST) Subject: [pypy-svn] r42004 - in pypy/dist/pypy/objspace: cpy cpy/test std Message-ID: <20070412175021.353C980A9@code0.codespeak.net> Author: fijal Date: Thu Apr 12 19:50:20 2007 New Revision: 42004 Modified: pypy/dist/pypy/objspace/cpy/objspace.py pypy/dist/pypy/objspace/cpy/test/test_objspace.py pypy/dist/pypy/objspace/std/objspace.py Log: Change newunicode semantics to use list of unichars Modified: pypy/dist/pypy/objspace/cpy/objspace.py ============================================================================== --- pypy/dist/pypy/objspace/cpy/objspace.py (original) +++ pypy/dist/pypy/objspace/cpy/objspace.py Thu Apr 12 19:50:20 2007 @@ -236,7 +236,7 @@ def newunicode(self, codes): # XXX inefficient - lst = [PyUnicode_FromOrdinal(code) for code in codes] + lst = [PyUnicode_FromOrdinal(ord(code)) for code in codes] w_lst = self.newlist(lst) w_emptyunicode = PyUnicode_FromUnicode(None, 0) return self.call_method(w_emptyunicode, 'join', w_lst) Modified: pypy/dist/pypy/objspace/cpy/test/test_objspace.py ============================================================================== --- pypy/dist/pypy/objspace/cpy/test/test_objspace.py (original) +++ pypy/dist/pypy/objspace/cpy/test/test_objspace.py Thu Apr 12 19:50:20 2007 @@ -56,7 +56,7 @@ def test_newunicode(): space = CPyObjSpace() - w = space.newunicode([65, 66]) + w = space.newunicode([unichr(65), unichr(66)]) assert space.is_w(space.type(w), space.w_unicode) for i in range(2): code = space.int_w(space.ord(space.getitem(w, space.wrap(i)))) @@ -68,9 +68,9 @@ assert space.int_w(space.ord(w)) == 65 w = space.wrap('\x00') assert space.int_w(space.ord(w)) == 0 - w = space.newunicode([65]) + w = space.newunicode([unichr(65)]) assert space.int_w(space.ord(w)) == 65 - w = space.newunicode([0]) + w = space.newunicode([unichr(0)]) assert space.int_w(space.ord(w)) == 0 def test_id(): Modified: pypy/dist/pypy/objspace/std/objspace.py ============================================================================== --- pypy/dist/pypy/objspace/std/objspace.py (original) +++ pypy/dist/pypy/objspace/std/objspace.py Thu Apr 12 19:50:20 2007 @@ -531,11 +531,6 @@ return self.wrap(''.join(chars)) def newunicode(self, chars): - try: - chars = [unichr(c) for c in chars] - except ValueError, e: # unichr(out-of-range) - msg = "character code not in range(%s)" % hex(sys.maxunicode+1) - raise OperationError(self.w_ValueError, self.wrap(msg)) return W_UnicodeObject(chars) def newseqiter(self, w_obj): From fijal at codespeak.net Thu Apr 12 19:51:08 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 12 Apr 2007 19:51:08 +0200 (CEST) Subject: [pypy-svn] r42005 - in pypy/dist/pypy/module: __builtin__ unicodedata Message-ID: <20070412175108.EC87B80A9@code0.codespeak.net> Author: fijal Date: Thu Apr 12 19:51:08 2007 New Revision: 42005 Modified: pypy/dist/pypy/module/__builtin__/operation.py pypy/dist/pypy/module/unicodedata/interp_ucd.py Log: Use list[unichr] as a parameter of space.newunicode Modified: pypy/dist/pypy/module/__builtin__/operation.py ============================================================================== --- pypy/dist/pypy/module/__builtin__/operation.py (original) +++ pypy/dist/pypy/module/__builtin__/operation.py Thu Apr 12 19:51:08 2007 @@ -4,7 +4,8 @@ from pypy.interpreter import gateway from pypy.interpreter.baseobjspace import ObjSpace -from pypy.interpreter.error import OperationError +from pypy.interpreter.error import OperationError +import __builtin__ NoneNotWrapped = gateway.NoneNotWrapped def abs(space, w_val): @@ -18,7 +19,7 @@ def unichr(space, w_code): "Return a Unicode string of one character with the given ordinal." - return space.newunicode([space.int_w(w_code)]) + return space.newunicode([__builtin__.unichr(space.int_w(w_code))]) def len(space, w_obj): "len(object) -> integer\n\nReturn the number of items of a sequence or mapping." Modified: pypy/dist/pypy/module/unicodedata/interp_ucd.py ============================================================================== --- pypy/dist/pypy/module/unicodedata/interp_ucd.py (original) +++ pypy/dist/pypy/module/unicodedata/interp_ucd.py Thu Apr 12 19:51:08 2007 @@ -215,10 +215,10 @@ result[0] = ch if not composed: # If decomposed normalization we are done - return space.newunicode(result[:j]) + return space.newunicode([unichr(i) for i in result[:j]]) if j <= 1: - return space.newunicode(result[:j]) + return space.newunicode([unichr(i) for i in result[:j]]) current = result[0] starter_pos = 0 @@ -268,7 +268,7 @@ result[starter_pos] = current - return space.newunicode(result[:next_insert]) + return space.newunicode([unichr(i) for i in result[:next_insert]]) normalize.unwrap_spec = ['self', ObjSpace, str, W_Root] From fijal at codespeak.net Thu Apr 12 21:44:25 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 12 Apr 2007 21:44:25 +0200 (CEST) Subject: [pypy-svn] r42008 - in pypy/dist/pypy: module/__builtin__ rlib Message-ID: <20070412194425.ED7E380AD@code0.codespeak.net> Author: fijal Date: Thu Apr 12 21:44:24 2007 New Revision: 42008 Modified: pypy/dist/pypy/module/__builtin__/special.py pypy/dist/pypy/rlib/rarithmetic.py Log: Move overflow checking version of formatd from __builtin__.special to rlib, to reuse by formatting Modified: pypy/dist/pypy/module/__builtin__/special.py ============================================================================== --- pypy/dist/pypy/module/__builtin__/special.py (original) +++ pypy/dist/pypy/module/__builtin__/special.py Thu Apr 12 21:44:24 2007 @@ -3,19 +3,11 @@ from pypy.rlib import rarithmetic def _formatd(space, alt, prec, kind, x): - formatd_max_length = rarithmetic.formatd_max_length - if ((kind == 'g' and formatd_max_length <= 10+prec) or - (kind == 'f' and formatd_max_length <= 53+prec)): - raise OperationError(space.w_OverflowError, - space.wrap("formatted float is too long (precision too large?)")) - if alt: - alt = '#' - else: - alt = '' - - fmt = "%%%s.%d%s" % (alt, prec, kind) - - return space.wrap(rarithmetic.formatd(fmt, x)) + try: + return space.wrap(rarithmetic.formatd_overflow(alt, prec, kind, x)) + except OverflowError: + raise OperationError(space.w_OverflowError, space.wrap( + "formatted float is too long (precision too large?)")) _formatd.unwrap_spec = [gateway.ObjSpace, int, int, str, float] Modified: pypy/dist/pypy/rlib/rarithmetic.py ============================================================================== --- pypy/dist/pypy/rlib/rarithmetic.py (original) +++ pypy/dist/pypy/rlib/rarithmetic.py Thu Apr 12 21:44:24 2007 @@ -409,6 +409,19 @@ def formatd(fmt, x): return fmt % (x,) +def formatd_overflow(alt, prec, kind, x): + if ((kind == 'g' and formatd_max_length <= 10+prec) or + (kind == 'f' and formatd_max_length <= 53+prec)): + raise OverflowError("formatted float is too long (precision too large?)") + if alt: + alt = '#' + else: + alt = '' + + fmt = "%%%s.%d%s" % (alt, prec, kind) + + return formatd(fmt, x) + # a common string hash function def _hash_string(s): From fijal at codespeak.net Thu Apr 12 21:45:27 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 12 Apr 2007 21:45:27 +0200 (CEST) Subject: [pypy-svn] r42009 - in pypy/dist/pypy/lib/distributed: . demo Message-ID: <20070412194527.83F6F80AD@code0.codespeak.net> Author: fijal Date: Thu Apr 12 21:45:27 2007 New Revision: 42009 Modified: pypy/dist/pypy/lib/distributed/demo/sockdemo.py pypy/dist/pypy/lib/distributed/socklayer.py Log: Fix demo. Long laying in WC checkin Modified: pypy/dist/pypy/lib/distributed/demo/sockdemo.py ============================================================================== --- pypy/dist/pypy/lib/distributed/demo/sockdemo.py (original) +++ pypy/dist/pypy/lib/distributed/demo/sockdemo.py Thu Apr 12 21:45:27 2007 @@ -1,5 +1,8 @@ from distributed import RemoteProtocol, remote_loop +from distributed.socklayer import Finished, socket_listener, socket_connecter + +PORT = 12122 class X: def __init__(self, z): @@ -10,23 +13,24 @@ def raising(self): 1/0 - + x = X(3) def remote(): - from distributed.socklayer import socket_listener - send, receive = socket_listener() + send, receive = socket_listener(address=('', PORT)) remote_loop(RemoteProtocol(send, receive, globals())) def local(): - from distributed.socklayer import socket_connecter - send, receive = socket_connecter(('localhost', 12122)) + send, receive = socket_connecter(('localhost', PORT)) return RemoteProtocol(send, receive) import sys if __name__ == '__main__': if len(sys.argv) > 1 and sys.argv[1] == '-r': - remote() + try: + remote() + except Finished: + print "Finished" else: rp = local() x = rp.get_remote("x") Modified: pypy/dist/pypy/lib/distributed/socklayer.py ============================================================================== --- pypy/dist/pypy/lib/distributed/socklayer.py (original) +++ pypy/dist/pypy/lib/distributed/socklayer.py Thu Apr 12 21:45:27 2007 @@ -11,6 +11,9 @@ if TRACE: print >>sys.stderr, msg +class Finished(Exception): + pass + class SocketWrapper(object): def __init__(self, conn): self.buffer = "" @@ -19,7 +22,10 @@ def receive(self): msg, self.buffer = decodemessage(self.buffer) while msg is None: - self.buffer += self.conn.recv(8192) + data = self.conn.recv(8192) + if not data: + raise Finished() + self.buffer += data msg, self.buffer = decodemessage(self.buffer) assert msg[0] == 'c' trace("received %s" % msg[1]) From fijal at codespeak.net Thu Apr 12 21:46:42 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 12 Apr 2007 21:46:42 +0200 (CEST) Subject: [pypy-svn] r42010 - pypy/dist/pypy/lib Message-ID: <20070412194642.C37D580AD@code0.codespeak.net> Author: fijal Date: Thu Apr 12 21:46:42 2007 New Revision: 42010 Modified: pypy/dist/pypy/lib/_formatting.py Log: checkin some silly changes to delete this file later Modified: pypy/dist/pypy/lib/_formatting.py ============================================================================== --- pypy/dist/pypy/lib/_formatting.py (original) +++ pypy/dist/pypy/lib/_formatting.py Thu Apr 12 21:46:42 2007 @@ -1,3 +1,4 @@ + # Application level implementation of string formatting. # There's some insane stuff in here. Blame CPython. Please. @@ -14,7 +15,7 @@ # for the usage of rpython-level unicode strings. -import sys +import sys, py class _Flags(object): def __repr__(self): @@ -33,12 +34,13 @@ if not v.isint(): raise TypeError, "* wants int" return fmtiter.next(), v.maybe_int() - n = '' + i0 = fmtiter.i - 1 + ik = i0 while c in '0123456789': - n += c c = fmtiter.next() - if n: - return c, int(n) + ik += 1 + if ik != i0: + return c, int(fmtiter.fmt[i0:ik]) else: return c, 0 @@ -69,7 +71,8 @@ value = None gotvalue = False if c == '(': - n = '' + i0 = fmtiter.i + ik = i0 pcount = 1 while 1: c = fmtiter.next() @@ -79,8 +82,8 @@ break elif c == '(': pcount += 1 - n += c - value = valuegetter.getitem(n) + ik += 1 + value = valuegetter.getitem(fmtiter.fmt[i0:ik]) gotvalue = True c = fmtiter.next() c, flags = peel_flags(c, fmtiter) @@ -108,72 +111,67 @@ class NeedUnicodeFormattingError(Exception): pass -class Formatter(object): - def __init__(self, char, flags, width, prec, valuebox): - self.char = char - self.flags = flags - self.width = width - self.prec = prec - self.valuebox = valuebox - - def numeric_preprocess(self, v): - # negative zeroes? - # * mwh giggles, falls over - # still, if we can recognize them, here's the place to do it. - import math - if v < 0 or v == 0 and isinstance(v, float) and math.atan2(0, v) != 0: - sign = '-' - v = -v - else: - if self.flags.f_sign: - sign = '+' - elif self.flags.f_blank: - sign = ' ' - else: - sign = '' - return v, sign - def numeric_postprocess(self, r, sign, prefix=""): - assert self.char in 'iduoxXeEfFgG' - padchar = ' ' - if self.flags.f_zero: - padchar = '0' - if self.width is not None: - p = self.width - len(r) - len(sign) -len(prefix) - if self.flags.f_ljust: - r = sign + prefix + r + ' '*p - else: - if self.flags.f_zero: - r = sign+prefix+padchar*p + r - else: - r = padchar*p + sign + prefix + r +#class Formatter(object): +# def __init__(self, char, flags, width, prec, valuebox): +# self.char = char +# self.flags = flags +# self.width = width +# self.prec = prec +# self.valuebox = valuebox + +def numeric_preprocess(v, flags): + # negative zeroes? + # * mwh giggles, falls over + # still, if we can recognize them, here's the place to do it. + import math + if v < 0 or v == 0 and isinstance(v, float) and math.atan2(0, v) != 0: + sign = '-' + v = -v + else: + if flags.f_sign: + sign = '+' + elif flags.f_blank: + sign = ' ' else: - r = sign + prefix + r - return r - - def format(self): - raise NotImplementedError + sign = '' + return v, sign - def std_wp(self, r): - assert self.char not in 'iduoxXeEfFgG' - if self.prec is not None: - r = r[:self.prec] - if self.width is not None: - p = self.width - len(r) - if self.flags.f_ljust: - r = r + ' '*p +def numeric_postprocess(r, sign, char, flags, width, prefix=""): + assert char in 'iduoxXeEfFgG' + padchar = ' ' + if flags.f_zero: + padchar = '0' + if width is not None: + p = width - len(r) - len(sign) -len(prefix) + if flags.f_ljust: + r = sign + prefix + r + ' '*p + else: + if flags.f_zero: + r = sign+prefix+padchar*p + r else: - r = ' '*p + r - return r + r = padchar*p + sign + prefix + r + else: + r = sign + prefix + r + return r +def std_wp(r, char, flags, width, prec): + assert char not in 'iduoxXeEfFgG' + if prec is not None: + r = r[:prec] + if width is not None: + p = width - len(r) + if flags.f_ljust: + r = r + ' '*p + else: + r = ' '*p + r + return r -class ReprFormatter(Formatter): - def format(self): - return self.std_wp(self.valuebox.repr()) +def repr_format(char, flags, width, prec, valuebox): + return std_wp(valuebox.repr(), char, flags, width, prec) -class PercentFormatter(Formatter): - def format(self): - return self.std_wp('%') +def percent_format(char, flags, width, prec, valuebox): + return std_wp('%', char, flags, width, prec) # isinf isn't too hard... def isinf(v): @@ -185,210 +183,186 @@ def isnan(v): return v != v*1.0 or (v == 1.0 and v == 2.0) -class FloatFormatter(Formatter): - def eDigits(self, ds): - ds = ds[:self.prec + 1] + ['0'] * (self.prec + 1 - len(ds)) - if self.prec > 0 or self.flags.f_alt: - ds[1:1] = ['.'] - return ''.join(ds) - - def fDigits(self, ds, k): - p = max(self.prec, 0) - if 0 < k < len(ds): - if len(ds) - k < p: - ds.extend(['0'] * (p - (len(ds) - k))) - else: - ds = ds[:p + k] - ds[k:k] = ['.'] - elif k <= 0: - ds[0:0] = ['0']*(-k) - ds = ds[:p] - ds.extend(['0'] * (p - len(ds))) - ds[0:0]= ['0', '.'] - elif k >= len(ds): - ds.extend((k-len(ds))*['0'] + ['.'] + ['0']*p) - return ''.join(ds) - - def format(self): - v = self.valuebox.maybe_float() - if isnan(v): - return 'nan' - elif isinf(v): - return 'inf' - v, sign = self.numeric_preprocess(v) - if self.prec is None: - self.prec = 6 - r = self._format(v) - return self.numeric_postprocess(r, sign) - - def _formatd(self, kind, v): - import __builtin__ - return __builtin__._formatd(self.flags.f_alt, self.prec, kind, v) - -class FloatFFormatter(FloatFormatter): - def _format(self, v): - if v/1e25 > 1e25: - return FloatGFormatter('g', self.flags, self.width, - self.prec, self.valuebox).format() - return self._formatd('f', v) - -# system specific formatting. Linux does 3, Windows does 4... -# XXX this works only when we use geninterp! -if 0: - _x = `1.2e34` - _EF = len(_x) - _x.rindex('+') - del _x -else: - _EF = 3 - - -class FloatEFormatter(FloatFormatter): - def _format(self, v): - return self._formatd('e', v) +#def eDigits(ds, flags, prec): +# ds = ds[:prec + 1] + ['0'] * (prec + 1 - len(ds)) +# if prec > 0 or flags.f_alt: +# ds[1:1] = ['.'] +# return ''.join(ds) + +#def fDigits(ds, k, prec): +# p = max(prec, 0) +# if 0 < k < len(ds): +# if len(ds) - k < p: +# ds.extend(['0'] * (p - (len(ds) - k))) +# else: +# ds = ds[:p + k] +# ds[k:k] = ['.'] +# elif k <= 0: +# ds[0:0] = ['0']*(-k) +# ds = ds[:p] +# ds.extend(['0'] * (p - len(ds))) +# ds[0:0]= ['0', '.'] +# elif k >= len(ds): +# ds.extend((k-len(ds))*['0'] + ['.'] + ['0']*p) +# return ''.join(ds) + +def float_format(char, flags, valuebox): + v = valuebox.maybe_float() + if isnan(v): + return 'nan' + elif isinf(v): + return 'inf' + return numeric_preprocess(v, flags) + +def float_formatd(kind, v, flags, prec): + import __builtin__ + return __builtin__._formatd(flags.f_alt, prec, kind, v) + +def float_f_format(char, flags, width, prec, valuebox): + if prec is None: + prec = 6 + v, sign = float_format(char, flags, valuebox) + if v/1e25 > 1e25: + return float_g_format('g', flags, width, prec, valuebox) + return numeric_postprocess(float_formatd('f', v, flags, prec), + sign, char, flags, width) + +def float_e_format(char, flags, width, prec, valuebox): + if prec is None: + prec = 6 + v, _ = float_format(char, flags, valuebox) + return numeric_postprocess(float_formatd('e', v, flags, prec), + sign, char, flags, width) -class FloatGFormatter(FloatFormatter): +def float_g_format(char, flags, width, prec, valuebox): # The description of %g in the Python documentation lies # in a variety of minor ways. # Gah, this still isn't quite right in the f_alt case. # (One has to wonder who might care). - def _format(self, v): - return self._formatd('g', v) - -class HexFormatter(Formatter): - # NB: this has 2.4 semantics wrt. negative values - def format(self): - v, sign = self.numeric_preprocess(self.valuebox.maybe_int()) - r = hex(v)[2:] - if r[-1]=="L": - # workaround weird behavior of CPython's hex - r = r[:-1].lower() - if self.prec is not None and len(r) < self.prec: - r = '0'*(self.prec - len(r)) + r - if self.flags.f_alt: - prefix = '0x' - else: - prefix = '' - if self.char == 'X': - r = r.upper() - prefix = prefix.upper() - return self.numeric_postprocess(r, sign, prefix) - + if prec is None: + prec = 6 + v, sign = float_format(char, flags, valuebox) + return numeric_postprocess(float_formatd('g', v, flags, prec), + sign, char, flags, width) -class OctFormatter(Formatter): +def hex_format(char, flags, width, prec, valuebox): # NB: this has 2.4 semantics wrt. negative values - def format(self): - v, sign = self.numeric_preprocess(self.valuebox.maybe_int()) - r = oct(v) - if r[-1] == "L": - r = r[:-1] - if v and not self.flags.f_alt: - r = r[1:] - if self.prec is not None and len(r) < self.prec: - r = '0'*(self.prec - len(r)) + r - return self.numeric_postprocess(r, sign) - - -class IntFormatter(Formatter): - # NB: this has 2.4 semantics wrt. negative values (for %u) - def format(self): - 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 - return self.numeric_postprocess(r, sign) - - -class CharFormatter(Formatter): - def format(self): - if self.valuebox.isstr(): - v = self.valuebox.str() - if len(v) != 1: - raise TypeError, "%c requires int or char" - elif self.valuebox.isunicode(): - raise NeedUnicodeFormattingError - else: - i = self.valuebox.maybe_int() - if not 0 <= i <= 255: - raise OverflowError("OverflowError: unsigned byte " - "integer is greater than maximum") - v = chr(i) - self.prec = None - return self.std_wp(v) - -class StringFormatter(Formatter): - def format(self): - if self.valuebox.isunicode(): - raise NeedUnicodeFormattingError - return self.std_wp(self.valuebox.str()) - - + v, sign = numeric_preprocess(valuebox.maybe_int(), flags) + r = hex(v)[2:] + if r[-1]=="L": + # workaround weird behavior of CPython's hex + r = r[:-1].lower() + if prec is not None and len(r) < prec: + r = '0'*(prec - len(r)) + r + if flags.f_alt: + prefix = '0x' + else: + prefix = '' + if char == 'X': + r = r.upper() + prefix = prefix.upper() + return numeric_postprocess(r, sign, char, flags, width, prefix) + +def oct_format(char, flags, width, prec, valuebox): + v, sign = numeric_preprocess(valuebox.maybe_int(), flags) + r = oct(v) + if r[-1] == "L": + r = r[:-1] + if v and not flags.f_alt: + r = r[1:] + if prec is not None and len(r) < prec: + r = '0'*(prec - len(r)) + r + return numeric_postprocess(r, sign, char, flags, width) + +def int_format(char, flags, width, prec, valuebox): + v, sign = numeric_preprocess(valuebox.maybe_int(), flags) + r = str(v) + if prec is not None and len(r) < prec: + r = '0'*(prec - len(r)) + r + return numeric_postprocess(r, sign, char, flags, width) + +def char_format(char, flags, width, prec, valuebox): + if valuebox.isstr(): + v = valuebox.str() + if len(v) != 1: + raise TypeError, "%c requires int or char" + elif valuebox.isunicode(): + raise NeedUnicodeFormattingError + else: + i = valuebox.maybe_int() + if not 0 <= i <= 255: + raise OverflowError("OverflowError: unsigned byte " + "integer is greater than maximum") + v = chr(i) + return std_wp(v, char, flags, width, None) + +def string_format(char, flags, width, prec, valuebox): + if valuebox.isunicode(): + raise NeedUnicodeFormattingError + return std_wp(valuebox.str(), char, flags, width, prec) str_format_registry = { - 'd':IntFormatter, - 'i':IntFormatter, - 'o':OctFormatter, - 'u':IntFormatter, - 'x':HexFormatter, - 'X':HexFormatter, - 'e':FloatEFormatter, - 'E':FloatEFormatter, - 'f':FloatFFormatter, - 'F':FloatFFormatter, - 'g':FloatGFormatter, - 'G':FloatGFormatter, - 'c':CharFormatter, - 's':StringFormatter, - 'r':ReprFormatter, + 'd':int_format, + 'i':int_format, + 'o':oct_format, + 'u':int_format, + 'x':hex_format, + 'X':hex_format, + 'e':float_e_format, + 'E':float_e_format, + 'f':float_f_format, + 'F':float_f_format, + 'g':float_g_format, + 'G':float_g_format, + 'c':char_format, + 's':string_format, + 'r':repr_format, # this *can* get accessed, by e.g. '%()4%'%{'':1}. # The usual %% case has to be handled specially as it # doesn't consume a value. - '%':PercentFormatter, + '%':percent_format, } - -class UnicodeStringFormatter(Formatter): - def format(self): - uval = self.valuebox.unicode() - return self.std_wp(uval) - -class UnicodeCharFormatter(Formatter): - def format(self): - if self.valuebox.isunicode(): - v = self.valuebox.unicode() - if len(v) != 1: - raise TypeError, "%c requires int or unicode char" - elif self.valuebox.isstr(): - v = unicode(self.valuebox.str()) - if len(v) != 1: - raise TypeError, "%c requires int or unicode char" - else: - i = self.valuebox.maybe_int() - if not 0 <= i <= sys.maxunicode: - raise OverflowError("OverflowError: unsigned byte " - "integer is greater than maximum") - v = unichr(i) - self.prec = None - return self.std_wp(v) + +def unicode_string_format(char, flags, width, prec, valuebox): + return std_wp(valuebox.unicode(), char, flags, width, prec) + +def unicode_char_format(char, flags, width, prec, valuebox): + if valuebox.isunicode(): + v = valuebox.unicode() + if len(v) != 1: + raise TypeError, "%c requires int or unicode char" + elif valuebox.isstr(): + v = unicode(valuebox.str()) + if len(v) != 1: + raise TypeError, "%c requires int or unicode char" + else: + i = valuebox.maybe_int() + if not 0 <= i <= sys.maxunicode: + raise OverflowError("OverflowError: unsigned byte " + "integer is greater than maximum") + v = unichr(i) + return std_wp(v, char, flags, width, None) unicode_format_registry = { - u'd':IntFormatter, - u'i':IntFormatter, - u'o':OctFormatter, - u'u':IntFormatter, - u'x':HexFormatter, - u'X':HexFormatter, - u'e':FloatEFormatter, - u'E':FloatEFormatter, - u'f':FloatFFormatter, - u'F':FloatFFormatter, - u'g':FloatGFormatter, - u'G':FloatGFormatter, - u'c':UnicodeCharFormatter, - u's':UnicodeStringFormatter, - u'r':ReprFormatter, + 'd':int_format, + 'i':int_format, + 'o':oct_format, + 'u':int_format, + 'x':hex_format, + 'X':hex_format, + 'e':float_e_format, + 'E':float_e_format, + 'f':float_f_format, + 'F':float_f_format, + 'g':float_g_format, + 'G':float_g_format, + 'c':unicode_char_format, + 's':unicode_string_format, + 'r':repr_format, # 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'%':PercentFormatter, + '%':percent_format, } @@ -402,8 +376,8 @@ return self def next(self): - if self.i >= self._fmtlength: - raise StopIteration + if self.i >= self._fmtlength: + raise StopIteration c = self.fmt[self.i] self.i += 1 return c @@ -451,13 +425,13 @@ # r.append(f(*t).format()) char, flags, width, prec, value = t try: - result = f(char, flags, width, prec, value).format() + result = f(char, flags, width, prec, value) 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()) + r.append(f(char, flags, width, prec, value)) else: r.append(result) else: From fijal at codespeak.net Thu Apr 12 22:00:58 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 12 Apr 2007 22:00:58 +0200 (CEST) Subject: [pypy-svn] r42011 - in pypy/dist/pypy/objspace/std: . test Message-ID: <20070412200058.3222680AC@code0.codespeak.net> Author: fijal Date: Thu Apr 12 22:00:57 2007 New Revision: 42011 Added: pypy/dist/pypy/objspace/std/formatting.py - copied, changed from r41900, pypy/dist/pypy/lib/_formatting.py Modified: pypy/dist/pypy/objspace/std/ropeobject.py pypy/dist/pypy/objspace/std/stringobject.py pypy/dist/pypy/objspace/std/test/test_stringformat.py pypy/dist/pypy/objspace/std/unicodeobject.py Log: Make string formatting RPython. * It's faster * It rather works (tests passes at least, also CPython regr tests) * The unicode support is a hack, let's wait for proper RPython unicode support to do it better * Long overflow is a bit slow (space op everywhere) * Few spaceops can be removed * There is still pending alloc removal, because ValueBox is not longer needed at all. Modified: pypy/dist/pypy/objspace/std/ropeobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/ropeobject.py (original) +++ pypy/dist/pypy/objspace/std/ropeobject.py Thu Apr 12 22:00:57 2007 @@ -11,6 +11,7 @@ from pypy.objspace.std.stringtype import wrapchar from pypy.objspace.std import rope +from pypy.objspace.std.stringobject import mod__String_ANY as mod__Rope_ANY class W_RopeObject(W_Object): from pypy.objspace.std.stringtype import str_typedef as typedef @@ -1061,28 +1062,9 @@ 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 Modified: pypy/dist/pypy/objspace/std/stringobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/stringobject.py (original) +++ pypy/dist/pypy/objspace/std/stringobject.py Thu Apr 12 22:00:57 2007 @@ -14,6 +14,7 @@ from pypy.objspace.std.stringtype import sliced, joined, wrapstr, wrapchar, \ stringendswith, stringstartswith +from pypy.objspace.std.formatting import format class W_StringObject(W_Object): from pypy.objspace.std.stringtype import str_typedef as typedef @@ -907,28 +908,28 @@ return codecs.getencoder(encoding)(str, errors)[0] ''', filename=__file__) -# this one should do the import of _formatting: -app2 = gateway.applevel(''' - import _formatting - - def mod__String_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__String_ANY_ANY = app.interphook('str_translate__String_ANY_ANY') str_decode__String_ANY_ANY = app.interphook('str_decode__String_ANY_ANY') str_encode__String_ANY_ANY = app.interphook('str_encode__String_ANY_ANY') -mod__String_ANY = app2.interphook('mod__String_ANY') + +# CPython's logic for deciding if ""%values is +# an error (1 value, 0 %-formatters) or not +# (values is of a mapping type) +def mod__String_ANY(space, w_format, w_values): + if space.is_true(space.isinstance(w_values, space.w_tuple)): + return format(space, w_format, w_values) + else: + # we check directly for dict to avoid obscure checking + # in simplest case + if space.is_true(space.isinstance(w_values, space.w_dict)) or \ + (space.lookup(w_values, '__getitem__') and + not space.is_true(space.isinstance(w_values, space.w_basestring))): + return format(space, w_format, + space.newtuple([w_values]), w_values) + else: + return format(space, w_format, + space.newtuple([w_values]), None) # register all methods from pypy.objspace.std import stringtype 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 Thu Apr 12 22:00:57 2007 @@ -161,3 +161,24 @@ return fmt % x raises(OverflowError, f, "%.70f", 2.0) raises(OverflowError, f, "%.110g", 2.0) + +class AppTestUnicodeObject: + def test_unicode_convert(self): + assert isinstance("%s" % (u"x"), unicode) + + def test_unicode_d(self): + assert u"%.1d" % 3 == '3' + + def test_unicode_overflow(self): + import sys + raises(OverflowError, 'u"%.*d" % (sys.maxint, 1)') + + def test_unicode_format_a(self): + assert u'%x' % 10L == 'a' + + def test_long_no_overflow(self): + assert "%x" % 100000000000L == "174876e800" + + def test_missing_cases(self): + print '%032d' % -123456789012345678901234567890L + assert '%032d' % -123456789012345678901234567890L == '-0123456789012345678901234567890' Modified: pypy/dist/pypy/objspace/std/unicodeobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/unicodeobject.py (original) +++ pypy/dist/pypy/objspace/std/unicodeobject.py Thu Apr 12 22:00:57 2007 @@ -8,6 +8,8 @@ from pypy.rlib.rarithmetic import intmask, ovfcheck from pypy.module.unicodedata import unicodedb_3_2_0 as unicodedb +from pypy.objspace.std.formatting import format + class W_UnicodeObject(W_Object): from pypy.objspace.std.unicodetype import unicode_typedef as typedef @@ -857,22 +859,6 @@ raise TypeError("character mapping must return integer, None or unicode") return ''.join(result) -def mod__Unicode_ANY(format, values): - import _formatting - if isinstance(values, tuple): - return _formatting.format(format, values, None, do_unicode=True) - 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, - do_unicode=True) - else: - return _formatting.format(format, (values,), None, - do_unicode=True) - def unicode_encode__Unicode_ANY_ANY(unistr, encoding=None, errors=None): import codecs, sys if encoding is None: @@ -1047,6 +1033,25 @@ return space.wrap(''.join(result[:i])) #repr__Unicode = app.interphook('repr__Unicode') # uncomment when repr code is moved to _codecs + +def mod__Unicode_ANY(space, w_format, w_values): + if space.is_true(space.isinstance(w_values, space.w_tuple)): + return format(space, w_format, w_values, do_unicode=True) + else: + # we check directly for dict to avoid obscure checking + # in simplest case + if space.is_true(space.isinstance(w_values, space.w_dict)) or \ + (space.lookup(w_values, '__getitem__') and + not space.is_true(space.isinstance(w_values, space.w_basestring))): + return format(space, w_format, + space.newtuple([w_values]), w_values, + do_unicode=True) + else: + return format(space, w_format, + space.newtuple([w_values]), None, + do_unicode=True) + + import unicodetype register_all(vars(), unicodetype) From fijal at codespeak.net Thu Apr 12 22:01:48 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 12 Apr 2007 22:01:48 +0200 (CEST) Subject: [pypy-svn] r42012 - in pypy/dist/pypy/lib: . test2 Message-ID: <20070412200148.93AA880AC@code0.codespeak.net> Author: fijal Date: Thu Apr 12 22:01:48 2007 New Revision: 42012 Removed: pypy/dist/pypy/lib/_formatting.py pypy/dist/pypy/lib/test2/test_formatting.py Log: Remove app-level version of formatting From santagada at codespeak.net Fri Apr 13 02:59:08 2007 From: santagada at codespeak.net (santagada at codespeak.net) Date: Fri, 13 Apr 2007 02:59:08 +0200 (CEST) Subject: [pypy-svn] r42015 - pypy/dist/pypy/doc Message-ID: <20070413005908.DB99E80B2@code0.codespeak.net> Author: santagada Date: Fri Apr 13 02:59:08 2007 New Revision: 42015 Added: pypy/dist/pypy/doc/javascript-interpreter.txt Log: draft for the javascript documentation --Esta linha, e as abaixo, ser?o ignoradas-- A doc/javascript-interpreter.txt Added: pypy/dist/pypy/doc/javascript-interpreter.txt ============================================================================== --- (empty file) +++ pypy/dist/pypy/doc/javascript-interpreter.txt Fri Apr 13 02:59:08 2007 @@ -0,0 +1,99 @@ +====================================== +JS-PyPy: PyPy's Javascript interpreter +====================================== + + +The pypy Javascript interpreter was written by Leonardo Santagada with the +help of most of the pypy team and is his summer of pypy project. It aims to +show how to implement a clear interpreter on the pypy plataform, and providing +support for some facilities not common to javascript interpreters. + +To run the js interpreter you will need the spidermonkey binary in the path +(or in the same directory in windows). It does have a interactive interpreter +for you to play with, but it is made in pure python (not rpython) so it isn't +present on the translated interpreter + + +Translating the interpreter to C +================================ + +Just as you can translate PyPy's Python interpreter, you can also translate the +Javscript interpreter to C:: + + pypy$ cd translator/goal + pypy/translator/goal$ python translate.py targetjsstandalone.py + +The translated interpreter is not interactive, you can only pass a javascript +file for execution. + +Examples +======== + +This examples are made using the interactive interpreter js_interactive.py, +but you can save the code to a file and run it on the translated interpreter. + +To start the basics, open the interactive interpreter:: + + pypy/lang/js$ ./py_interactive.py + js-pypy> print("hello world") // the classic example + hello world + js-pypy> x = 3+5*2 // arithimetic expressions + 1 + js-pypy> x = "Hello" + " " + "World" // string manipulation + "Hello World" + js-pypy> function f(n) { // functions works + ... return n+1; + ... } + [object Object] + js-pypy> f(13) + 14 + js-pypy> + +some more complex examples:: + + js-pypy> function fact(n) { // recursive functions, this is a factorial + ... if (n==0) { + ... return 1; + ... } + ... else { + ... return n*fact(n-1); + ... } + ... } + [object Object] + js-pypy> fact(3) + 6 + js-pypy> function fact(n) { + ... if (n==0) { + ... return 1; + ... } + ... else { + ... return n*fact(n-1); + ... } + ... } + [object Object] + js-pypy> fact(3) + 6 + + js-pypy> function sumclosure(number) { // closures are supported also + ... return function (n) { return number+n } + ... } + [object Object] + js-pypy> sum5 = sumclosure(5) + [object Object] + js-pypy> sum5(4) + 9 + js-pypy> + +Conclusions +=========== + +The interpreter is working but it is not complete, start playing with it and +fixing bugs and adding features should be easy as the code is still very +small, mostly it is defined in: + +* interpreter.py: main interpreter and builtins +* operations.py: operations and all the nodes that can be interpreted (hint: + the place to implement the switch statement) +* jsobj.py: primitive types and objects of javascript + +Please send comments and ideas (or any form of feedback) santagada at gmail dot com From santagada at codespeak.net Fri Apr 13 03:03:43 2007 From: santagada at codespeak.net (santagada at codespeak.net) Date: Fri, 13 Apr 2007 03:03:43 +0200 (CEST) Subject: [pypy-svn] r42016 - in pypy/dist/pypy/lang/js: . test Message-ID: <20070413010343.D08AB80B0@code0.codespeak.net> Author: santagada Date: Fri Apr 13 03:03:43 2007 New Revision: 42016 Modified: pypy/dist/pypy/lang/js/jsobj.py pypy/dist/pypy/lang/js/operations.py pypy/dist/pypy/lang/js/test/test_interp.py Log: added the creation of a default prototype object Modified: pypy/dist/pypy/lang/js/jsobj.py ============================================================================== --- pypy/dist/pypy/lang/js/jsobj.py (original) +++ pypy/dist/pypy/lang/js/jsobj.py Fri Apr 13 03:03:43 2007 @@ -492,7 +492,6 @@ else: ctx.this = this ctx.property = Property('', w_Undefined, dd=True) - print ctx return ctx def eval_context(calling_context): @@ -530,5 +529,5 @@ return self.property_name def __str__(self): - return "< " + str(self.base) + " -> " + str(self.property_name) + " >" + return "<" + str(self.base) + " -> " + str(self.property_name) + ">" Modified: pypy/dist/pypy/lang/js/operations.py ============================================================================== --- pypy/dist/pypy/lang/js/operations.py (original) +++ pypy/dist/pypy/lang/js/operations.py Fri Apr 13 03:03:43 2007 @@ -283,6 +283,7 @@ def eval(self, ctx): w_obj = W_Object(ctx=ctx, callfunc = self) + w_obj.Put('prototype', W_Object(ctx=ctx)) return w_obj class Identifier(Expression): @@ -654,8 +655,6 @@ 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) return result 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 Apr 13 03:03:43 2007 @@ -510,21 +510,19 @@ """, ['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(1)) - """, ['1',]) + function fact(x) { if (x == 0) { return 1; } else { return fact(x-1)*x; }} + print(fact(3)) + """, ['6',]) 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(); + function foo() {print("debug");this.bar = function() {}}; var f = new foo(); f.bar(); """, ['',]) From fijal at codespeak.net Fri Apr 13 07:38:26 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 13 Apr 2007 07:38:26 +0200 (CEST) Subject: [pypy-svn] r42017 - pypy/extradoc/talk/rupy2007 Message-ID: <20070413053826.D8C1380AF@code0.codespeak.net> Author: fijal Date: Fri Apr 13 07:38:25 2007 New Revision: 42017 Added: pypy/extradoc/talk/rupy2007/talk.txt Log: Added stolen mwh's pycon talk with my remarks Added: pypy/extradoc/talk/rupy2007/talk.txt ============================================================================== --- (empty file) +++ pypy/extradoc/talk/rupy2007/talk.txt Fri Apr 13 07:38:25 2007 @@ -0,0 +1,294 @@ +Fijal's remarks - + +A bit too much about implementation, a bit too little +about new amazing cool features (stackless, distribution, +tproxy and such) + +I would like to have +- a slide about JS backend + demos (play1?) +- a slide about distribution +- a slide about stackless, including cloning demo +- a slide + demo about modifiable grammar +- logic objspace??? (unsure if it even works) +- a slide about different implementations of objects, + including ropes and a demo which ''hangs'' on CPython + +What you' re in for in the next 45 mins +======================================= + +* Quick intro and motivation +* Quick overview of architecture and current statues +* Introduction to features unique to PyPy, + including the JIT, with the odd demo +* A little talk about what the future holds + +What is PyPy? +============== +* PyPy is: +* An implementation of Python, and a very + flexible compiler framework (with some + features that are especially useful for + implementing interpreters) +* An open source project (MIT license) +* A STREP (''Specific Targeted REsearch + Project''), partially funded by the EU +* A lot of fun! + +30 second status +================ + +* We can produce a binary that looks more and + more like CPython to the user +* 2-4x slower, depending on details +* More modules supported -- socket, mmap, ... +* Can now produce binary for CLR (i.e. .NET) +* Can also produce more capable binaries -- + with stackless-style coroutines, with logic + variables, ... + +Motivation +=========== +* PyPy grew out of a desire to modify/extend + the implementation of Python, for example to: +* increase performance (psyco-style JIT + compilation, better garbage collectors) +* add expressiveness (stackless-style + coroutines, logic programming) +* ease porting (to new platforms like the + JVM or CLI or to low memory situations) + +Lofty goals, but first... +=========================== +* CPython is a fine implementation of Python + but: +* it's written in C, which makes porting to, + for example, the CLI hard +* while psyco and stackless exist, they are + very hard to maintain as Python evolves +* some implementation decisions are very + hard to change (e.g. refcounting) + +Enter the PyPy platform +======================== + +XXX Copy picture + +How do you specify the Python language? +======================================== + +* The way we did it was to write an + interpreter for Python in RPython -- a subset + of Python that is amenable to analysis +* This allowed us to write unit tests for our + specification/implementation that run on top + of CPython +* Can also test entire specification/ + implementation in same way + +Translation Aspects +==================== +* Our Python implementation/specification is + very high level +* One of our Big Goals is to produce our + customized Python implementations without + compromising on this point +* We do this by weaving in so-called + 'translation aspects' during the compilation + process + +1,000 ft view +=============== + +XXX copy picture + +The Annotator +============= + +* Works on control flow graphs of the source + program +* Type annotation associates variables with + information about which values they can + take at run time +* An unusual feature of PyPy's approach is that + the annotator works on live objects which + means it never sees initialization code, so + that can use exec and other dynamic tricks + +The Annotator +============== + +* Annotation starts at a given entry point and + discovers as it proceeds which functions may + be called by the input program +* Does not modify the graphs; end result is + essentially a big dictionary +* Read ''Compiling dynamic language + implementations'' on the web site for more + than is on these slides + +The RTyper +============ + +* The RTyper takes as input an annotated + RPython program (e.g. our Python + implementation) +* It reduces the abstraction level of the graphs + towards that of the target platform +* This is where the magic of PyPy really starts + to get going :-) + +The RTyper +=========== + +* Can target a C-ish, pointer-using language or + an object-oriented language like Java or + Smalltalk with classes and instances +* Resulting graphs are not completely low- + level: still assume automatic memory + management for example + +Reducing Abstraction +====================== + +* Many high level operations apply to different + types -- the most extreme example probably + being calling an object +* For example, calling a function is RTyped to a + ''direct_call'' operation +* But calling a class becomes a sequence of + operations including allocating memory for + the instance and calling any __init__ + function + +Further Transforms +=================== + +* RTyping is followed by a sequence of further + transforms, depending on target platform and + options supplied: +* GC transformer -- inserts explicit memory + management operations +* Stackless transform -- inserts bookkeeping + and extra operations to allow use of + coroutines, tasklets etc +* Various optimizations -- malloc removal, + inlining, ... + +The Backend(s) +=============== + +* Maintained backends: C, LLVM, CLI/.NET, + JVM and JavaScript +* All proceed in two phases: +* Traverse the forest of rtyped graphs, + computing names for everything +* Spit out the code + +Status +======= + +* The Standard Interpreter almost completely + compatible with Python 2.4.4 +* The compiler framework: +* Produces standalone binaries +* C, LLVM and CLI backends well + supported, JVM very nearly complete +* JavaScript backend works, but not for all of + PyPy (not really intended to, either) + +Status +======= + +* The C backend support ''stackless'' features + -- coroutines, tasklets, recursion only limited + by RAM +* Can use OS threads with a simple ''GIL- + thread'' model XXX borken +* Our Python specification/implementation + has remained free of all these + implementation decisions! + +What we're working on now +========================== + +* The JIT +* i386, PowerPC and LLVM backends +* Object optimizations +* Dict variants, method caching, ... +* Integration with .NET +* Security and distribution prototypes +* Not trying to revive rexec for now though... + +Things that make PyPy unique +=============================== + +* The Just-In-Time compiler (and the way it + has been made) +* Transparent Proxies +* Runtime modifiable Grammar +* Thunk object space +* JavaScript (demos: b-n-b and rxconsole) +* Logic programming + +About the project +==================== + +* Open source, of course (MIT license) +* Distributed -- the 12 paid developers live in + 6 countries, contributers from many more +* Sprint driven development -- focussed week + long coding sessions, every ~6 weeks during + funding period +* Extreme Programming practices: pair + programming, test-driven development + +Future Facts +=============== + +* Funding period ends March 31st +* Some funding related admin remains -- + reports, reviews +* So PyPy development will end? Of course + not! +* PyPy was a hobbyist open source project + before funding, will return to that state +* ... for a while, at least + +Future Hopes +============= + +* At least in my opinion, the work so far on + PyPy has mostly been preparatory -- the real + fun is yet to come. +* Likely future work includes: +* More work on the JIT +* Reducing code duplication +* Improved C gluing, better GIL handling + +Future Dreams +============== + +* High performance compacting, generational, + etc GC (steal ideas from Jikes?) +* Implementations of other dynamic languages + such as JavaScript, Prolog (already started), + Ruby (?), Perl (??) (which will get a JIT + essentially for free) +* The ability to have dynamically loaded + extension modules + +Join the fun! +============== + +* Project relies more than ever on getting the + community involved +* Read documentation: + http://codespeak.net/pypy/ +* Come hang out in #pypy on freenode, post + to pypy-dev +* Probably will be easier to keep up now... + +Thanks for listening! +====================== + +Any Questions? From fijal at codespeak.net Fri Apr 13 09:37:46 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 13 Apr 2007 09:37:46 +0200 (CEST) Subject: [pypy-svn] r42018 - pypy/extradoc/talk/rupy2007/demos Message-ID: <20070413073746.5F0D680B6@code0.codespeak.net> Author: fijal Date: Fri Apr 13 09:37:45 2007 New Revision: 42018 Added: pypy/extradoc/talk/rupy2007/demos/ pypy/extradoc/talk/rupy2007/demos/listserver.py pypy/extradoc/talk/rupy2007/demos/myproxy.py Log: Add a http server + list over proxy demo Added: pypy/extradoc/talk/rupy2007/demos/listserver.py ============================================================================== --- (empty file) +++ pypy/extradoc/talk/rupy2007/demos/listserver.py Fri Apr 13 09:37:45 2007 @@ -0,0 +1,31 @@ +from pypy.translator.js.lib import server +from py.__.green.server.httpserver import GreenHTTPServer +import random + +class Root(server.Collection): + def __init__(self): + self.l = range(10) + random.shuffle(self.l) + + def index(self): + return repr(self.l) + index.exposed = True + + def getitem(self, item): + return str(self.l[int(item)]) + getitem.exposed = True + + def setitem(self, item, value): + self.l[int(item)] = int(value) + return "" + setitem.exposed = True + +class Handler(server.NewHandler): + application = Root() + +if __name__ == '__main__': + addr = ('', 8010) + httpd = server.create_server(server_address=addr, handler=Handler, + server=GreenHTTPServer) + httpd.serve_forever() + Added: pypy/extradoc/talk/rupy2007/demos/myproxy.py ============================================================================== --- (empty file) +++ pypy/extradoc/talk/rupy2007/demos/myproxy.py Fri Apr 13 09:37:45 2007 @@ -0,0 +1,22 @@ +import tputil +import urllib + +class ProxyController(object): + def __getitem__(self, item): + data = urllib.urlencode({'item':item}) + return int(urllib.urlopen("http://localhost:8010/getitem?%s" % data, + ).read()) + + def __setitem__(self, item, value): + data = urllib.urlencode({'item':item, 'value':value}) + urllib.urlopen("http://localhost:8010/setitem?%s" % data, + data=data).read() + + def __repr__(self): + return urllib.urlopen("http://localhost:8010/").read() + +def proxy_controller(oper): + return oper.delegate() + +l = tputil.make_proxy(proxy_controller, list, ProxyController()) + From fijal at codespeak.net Fri Apr 13 09:39:01 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 13 Apr 2007 09:39:01 +0200 (CEST) Subject: [pypy-svn] r42019 - pypy/extradoc/talk/rupy2007 Message-ID: <20070413073901.818DC80B8@code0.codespeak.net> Author: fijal Date: Fri Apr 13 09:39:01 2007 New Revision: 42019 Added: pypy/extradoc/talk/rupy2007/fijal.txt Modified: pypy/extradoc/talk/rupy2007/talk.txt Log: Update + my version Added: pypy/extradoc/talk/rupy2007/fijal.txt ============================================================================== --- (empty file) +++ pypy/extradoc/talk/rupy2007/fijal.txt Fri Apr 13 09:39:01 2007 @@ -0,0 +1,228 @@ +XXX stealing from mwh + +What you' re in for in the next 45 mins +======================================= + +* Quick intro and motivation +* Introduction to features unique to PyPy, + including the JIT, with the odd demo +* Quick overview of architecture and current statues +* A little talk about what the future holds + +What is PyPy? +============== +* PyPy is: +* An implementation of Python, and a very + flexible compiler framework (with some + features that are especially useful for + implementing interpreters) +* An open source project (MIT license) +* A STREP (''Specific Targeted REsearch + Project''), partially funded by the EU +* A lot of fun! + +30 second status +================ + +* We can produce a binary that looks more and + more like CPython to the user +* 1.5-3x slower, depending on details +* Some modules supported -- socket, mmap, ... +* Can now produce binary for CLR (i.e. .NET) +* Can also produce more capable binaries -- + with stackless-style coroutines, with logic + variables, ... + +Motivation +=========== +* PyPy grew out of a desire to modify/extend + the implementation of Python, for example to: +* increase performance (psyco-style JIT + compilation, better garbage collectors) +* add expressiveness (stackless-style + coroutines, logic programming) +* ease porting (to new platforms like the + JVM or CLI or to low memory situations) + +Lofty goals, but first... +=========================== +* CPython is a fine implementation of Python + but: +* it's written in C, which makes porting to, + for example, the CLI hard +* while psyco and stackless exist, they are + very hard to maintain as Python evolves +* some implementation decisions are very + hard to change (e.g. refcounting) + +Enter the PyPy platform +======================== + +XXX Copy picture + +Things that make PyPy unique +=============================== + +* The Just-In-Time compiler (and the way it + has been made) +* Transparent Proxies +* Runtime modifiable Grammar +* Thunk object space +* JavaScript (demos: b-n-b and rxconsole) +* Logic programming + +Just-In-Time compiler +======================== + +* rather Just in time compiler generator +* applicable to any possible interpreter + (writen in RPython) +* scales to whole Python +* XXX + +Multiple object implementations +================================ + +* XXX + +Transparent proxies +==================== + +* XXX + +Distribution +================ + +* XXX + +Stackless +============ + +* XXX + +Runtime modifiable grammar +=========================== + +* XXX + +How do you specify the Python language? +======================================== + +* The way we did it was to write an + interpreter for Python in RPython -- a subset + of Python that is amenable to analysis +* This allowed us to write unit tests for our + specification/implementation that run on top + of CPython +* Can also test entire specification/ + implementation in same way + +Translation Aspects +==================== +* Our Python implementation/specification is + very high level +* One of our Big Goals is to produce our + customized Python implementations without + compromising on this point +* We do this by weaving in so-called + 'translation aspects' during the compilation + process + +1,000 meters view +=============== + +XXX We're on the continent +XXX copy picture + +The Annotator +============= + +* Works on control flow graphs of the source + program +* Type annotation associates variables with + information about which values they can + take at run time +* An unusual feature of PyPy's approach is that + the annotator works on live objects which + means it never sees initialization code, so + that can use exec and other dynamic tricks + +The Annotator +============== + +* Annotation starts at a given entry point and + discovers as it proceeds which functions may + be called by the input program +* Does not modify the graphs; end result is + essentially a big dictionary +* Read ''Compiling dynamic language + implementations'' on the web site for more + than is on these slides + +The RTyper +============ + +* The RTyper takes as input an annotated + RPython program (e.g. our Python + implementation) +* It reduces the abstraction level of the graphs + towards that of the target platform +* This is where the magic of PyPy really starts + to get going :-) + +The RTyper +=========== + +* Can target a C-ish, pointer-using language or + an object-oriented language like Java or + Smalltalk with classes and instances +* Resulting graphs are not completely low- + level: still assume automatic memory + management for example + +Reducing Abstraction +====================== + +* Many high level operations apply to different + types -- the most extreme example probably + being calling an object +* For example, calling a function is RTyped to a + ''direct_call'' operation +* But calling a class becomes a sequence of + operations including allocating memory for + the instance and calling any __init__ + function + +Further Transforms +=================== + +* RTyping is followed by a sequence of further + transforms, depending on target platform and + options supplied: +* GC transformer -- inserts explicit memory + management operations +* Stackless transform -- inserts bookkeeping + and extra operations to allow use of + coroutines, tasklets etc +* Various optimizations -- malloc removal, + inlining, ... + +The Backend(s) +=============== + +* Maintained backends: C, LLVM, CLI/.NET, + JVM and JavaScript +* All proceed in two phases: +* Traverse the forest of rtyped graphs, + computing names for everything +* Spit out the code + +XXX Write few words about future + +What future holds +================== + +* A bit of a rest +* More work on the JIT +* Threads +* Extenstion modules Modified: pypy/extradoc/talk/rupy2007/talk.txt ============================================================================== --- pypy/extradoc/talk/rupy2007/talk.txt (original) +++ pypy/extradoc/talk/rupy2007/talk.txt Fri Apr 13 09:39:01 2007 @@ -29,10 +29,10 @@ flexible compiler framework (with some features that are especially useful for implementing interpreters) -* An open source project (MIT license) -* A STREP (''Specific Targeted REsearch - Project''), partially funded by the EU -* A lot of fun! +* An open source project (MIT license) +* A STREP (''Specific Targeted REsearch + Project''), partially funded by the EU +* A lot of fun! 30 second status ================ @@ -51,11 +51,11 @@ * PyPy grew out of a desire to modify/extend the implementation of Python, for example to: * increase performance (psyco-style JIT - compilation, better garbage collectors) + compilation, better garbage collectors) * add expressiveness (stackless-style - coroutines, logic programming) + coroutines, logic programming) * ease porting (to new platforms like the - JVM or CLI or to low memory situations) + JVM or CLI or to low memory situations) Lofty goals, but first... =========================== From antocuni at codespeak.net Fri Apr 13 11:32:29 2007 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Fri, 13 Apr 2007 11:32:29 +0200 (CEST) Subject: [pypy-svn] r42020 - pypy/dist/pypy/rpython/ootypesystem Message-ID: <20070413093229.466AC80AC@code0.codespeak.net> Author: antocuni Date: Fri Apr 13 11:32:28 2007 New Revision: 42020 Modified: pypy/dist/pypy/rpython/ootypesystem/ootype.py pypy/dist/pypy/rpython/ootypesystem/rstr.py Log: (antocuni, fijal) make 'x' * -3 works for ootype backend too. Modified: pypy/dist/pypy/rpython/ootypesystem/ootype.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/ootype.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/ootype.py Fri Apr 13 11:32:28 2007 @@ -1118,6 +1118,7 @@ def ll_allocate(self, n): assert isinstance(n, int) + assert n >= 0 # do nothing def ll_append_char(self, ch): Modified: pypy/dist/pypy/rpython/ootypesystem/rstr.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/rstr.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/rstr.py Fri Apr 13 11:32:28 2007 @@ -71,6 +71,8 @@ return ootype.oohash(s) def ll_char_mul(ch, times): + if times < 0: + times = 0 buf = ootype.new(ootype.StringBuilder) buf.ll_allocate(times) i = 0 From fijal at codespeak.net Fri Apr 13 12:09:50 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 13 Apr 2007 12:09:50 +0200 (CEST) Subject: [pypy-svn] r42021 - pypy/dist/pypy/translator/microbench Message-ID: <20070413100950.D4B5B80AF@code0.codespeak.net> Author: fijal Date: Fri Apr 13 12:09:49 2007 New Revision: 42021 Modified: pypy/dist/pypy/translator/microbench/test_formatting.py Log: Add a bit uneasy microbenchmarks, exploating our current impl. Modified: pypy/dist/pypy/translator/microbench/test_formatting.py ============================================================================== --- pypy/dist/pypy/translator/microbench/test_formatting.py (original) +++ pypy/dist/pypy/translator/microbench/test_formatting.py Fri Apr 13 12:09:49 2007 @@ -26,3 +26,14 @@ '%r' % (d,) i += 1 +def test_format_unicode(): + i = 0 + while i < iterations: + '%s %s' % (u'foo', u'bar') + i += 1 + +def test_format_long(): + i = 0 + while i < iterations: + '%d' % (100000000000L,) + i += 1 From fijal at codespeak.net Fri Apr 13 16:08:10 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 13 Apr 2007 16:08:10 +0200 (CEST) Subject: [pypy-svn] r42032 - pypy/dist/pypy/doc Message-ID: <20070413140810.9D40580C4@code0.codespeak.net> Author: fijal Date: Fri Apr 13 16:08:09 2007 New Revision: 42032 Modified: pypy/dist/pypy/doc/style.css Log: Very very risky checkin. Feel free to revert. I guess this style looks a bit better than previous one, but I'm not sure if I didn't break ton of stuff. Modified: pypy/dist/pypy/doc/style.css ============================================================================== --- pypy/dist/pypy/doc/style.css (original) +++ pypy/dist/pypy/doc/style.css Fri Apr 13 16:08:09 2007 @@ -769,8 +769,9 @@ img#pyimg { position: absolute; - top: 4px; - left: 4px; + top: 0px; + left: 20px; + margin: 20px; } img#extraimg { @@ -791,7 +792,7 @@ div#metaspace { position: absolute; top: 40px; - left: 170px; + left: 210px; } div#errorline { @@ -804,9 +805,9 @@ position: absolute; /* font: 120% "Times New Roman", serif;*/ font: 110% Verdana, Helvetica, Arial, sans-serif; - top: 130px; - left: 170px; - margin-right: 5px; + top: 140px; + left: 130px; + margin-right: 140px; } div#menubar { From fijal at codespeak.net Fri Apr 13 16:18:49 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 13 Apr 2007 16:18:49 +0200 (CEST) Subject: [pypy-svn] r42033 - pypy/extradoc/talk/rupy2007 Message-ID: <20070413141849.8664380D0@code0.codespeak.net> Author: fijal Date: Fri Apr 13 16:18:48 2007 New Revision: 42033 Modified: pypy/extradoc/talk/rupy2007/fijal.txt Log: update Modified: pypy/extradoc/talk/rupy2007/fijal.txt ============================================================================== --- pypy/extradoc/talk/rupy2007/fijal.txt (original) +++ pypy/extradoc/talk/rupy2007/fijal.txt Fri Apr 13 16:18:48 2007 @@ -1,16 +1,26 @@ -XXX stealing from mwh +============================ +PyPy +============================ + +:Authors: Maciej Fijalkowski +:Location: Adam Mickiewicz University +:Date: 15.IV.2007 -What you' re in for in the next 45 mins +Next 45 minutes ======================================= * Quick intro and motivation + * Introduction to features unique to PyPy, including the JIT, with the odd demo -* Quick overview of architecture and current statues + +* Quick overview of architecture and current status + * A little talk about what the future holds What is PyPy? ============== + * PyPy is: * An implementation of Python, and a very flexible compiler framework (with some @@ -24,23 +34,25 @@ 30 second status ================ -* We can produce a binary that looks more and - more like CPython to the user +* We can produce a binary that looks almost + like CPython to the user * 1.5-3x slower, depending on details -* Some modules supported -- socket, mmap, ... +* Some modules supported - socket, mmap, ... * Can now produce binary for CLR (i.e. .NET) * Can also produce more capable binaries -- with stackless-style coroutines, with logic - variables, ... + variables +* No C inside Motivation =========== + * PyPy grew out of a desire to modify/extend the implementation of Python, for example to: * increase performance (psyco-style JIT compilation, better garbage collectors) * add expressiveness (stackless-style - coroutines, logic programming) + coroutines, logic programming, distribution) * ease porting (to new platforms like the JVM or CLI or to low memory situations) @@ -58,7 +70,7 @@ Enter the PyPy platform ======================== -XXX Copy picture +XXX Things that make PyPy unique =============================== @@ -68,32 +80,47 @@ * Transparent Proxies * Runtime modifiable Grammar * Thunk object space -* JavaScript (demos: b-n-b and rxconsole) +* JavaScript backend * Logic programming +* whatever you imagine ... -Just-In-Time compiler -======================== +Just-In-Time compiler generator +================================= -* rather Just in time compiler generator +* generates just in time compiler given + the interpreter source + few hints * applicable to any possible interpreter (writen in RPython) -* scales to whole Python -* XXX Multiple object implementations ================================ -* XXX +* Every python-level object can have multiple + implementations +* Examples are: String-key specialized dicts, + ropes, tree-based dicts + +XXX improve Transparent proxies ==================== -* XXX +* Built on top of multiple object implementations + +* Provides new implementation for each object + +* can access everything in transparent manner, + including such things like interpreter frames + +XXX demo Distribution ================ -* XXX +* Built on top of transparent proxies +* Can hide network layer +* Copies only small chunks of data, + avoiding too much traffic Stackless ============ @@ -129,7 +156,7 @@ process 1,000 meters view -=============== +================= XXX We're on the continent XXX copy picture @@ -222,7 +249,7 @@ What future holds ================== -* A bit of a rest +* We need some rest after EU funding period * More work on the JIT * Threads * Extenstion modules From arigo at codespeak.net Fri Apr 13 16:41:53 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 13 Apr 2007 16:41:53 +0200 (CEST) Subject: [pypy-svn] r42034 - pypy/extradoc/talk/rupy2007 Message-ID: <20070413144153.E39FD80CB@code0.codespeak.net> Author: arigo Date: Fri Apr 13 16:41:53 2007 New Revision: 42034 Modified: pypy/extradoc/talk/rupy2007/talk.txt Log: Typos and one-word details. Modified: pypy/extradoc/talk/rupy2007/talk.txt ============================================================================== --- pypy/extradoc/talk/rupy2007/talk.txt (original) +++ pypy/extradoc/talk/rupy2007/talk.txt Fri Apr 13 16:41:53 2007 @@ -17,7 +17,7 @@ ======================================= * Quick intro and motivation -* Quick overview of architecture and current statues +* Quick overview of architecture and current status * Introduction to features unique to PyPy, including the JIT, with the odd demo * A little talk about what the future holds @@ -199,7 +199,7 @@ Status ======= -* The C backend support ''stackless'' features +* The C backend supports ''stackless'' features -- coroutines, tasklets, recursion only limited by RAM * Can use OS threads with a simple ''GIL- @@ -269,10 +269,10 @@ ============== * High performance compacting, generational, - etc GC (steal ideas from Jikes?) + etc GC (steal ideas or code from Jikes?) * Implementations of other dynamic languages such as JavaScript, Prolog (already started), - Ruby (?), Perl (??) (which will get a JIT + Ruby (?), Perl (??) (which will all get a JIT essentially for free) * The ability to have dynamically loaded extension modules From fijal at codespeak.net Fri Apr 13 16:55:44 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 13 Apr 2007 16:55:44 +0200 (CEST) Subject: [pypy-svn] r42035 - pypy/extradoc/talk/rupy2007 Message-ID: <20070413145544.241BE80CA@code0.codespeak.net> Author: fijal Date: Fri Apr 13 16:55:43 2007 New Revision: 42035 Added: pypy/extradoc/talk/rupy2007/old_talk.txt - copied unchanged from r42034, pypy/extradoc/talk/rupy2007/talk.txt Removed: pypy/extradoc/talk/rupy2007/talk.txt Log: Move talk to old_talk From fijal at codespeak.net Fri Apr 13 16:56:25 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 13 Apr 2007 16:56:25 +0200 (CEST) Subject: [pypy-svn] r42036 - pypy/extradoc/talk/rupy2007 Message-ID: <20070413145625.7957A80CA@code0.codespeak.net> Author: fijal Date: Fri Apr 13 16:56:25 2007 New Revision: 42036 Added: pypy/extradoc/talk/rupy2007/talk.txt - copied unchanged from r42034, pypy/extradoc/talk/rupy2007/fijal.txt Removed: pypy/extradoc/talk/rupy2007/fijal.txt Log: move fijal.txt to talk.txt From arigo at codespeak.net Fri Apr 13 17:55:45 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 13 Apr 2007 17:55:45 +0200 (CEST) Subject: [pypy-svn] r42037 - pypy/extradoc/talk/rupy2007 Message-ID: <20070413155545.DC7B780CB@code0.codespeak.net> Author: arigo Date: Fri Apr 13 17:55:45 2007 New Revision: 42037 Modified: pypy/extradoc/talk/rupy2007/talk.txt Log: Typos. Note. Modified: pypy/extradoc/talk/rupy2007/talk.txt ============================================================================== --- pypy/extradoc/talk/rupy2007/talk.txt (original) +++ pypy/extradoc/talk/rupy2007/talk.txt Fri Apr 13 17:55:45 2007 @@ -90,7 +90,7 @@ * generates just in time compiler given the interpreter source + few hints * applicable to any possible interpreter - (writen in RPython) + (written in RPython) Multiple object implementations ================================ @@ -252,4 +252,12 @@ * We need some rest after EU funding period * More work on the JIT * Threads -* Extenstion modules +* Extension modules + +XXX should probably also mention the following +which is interesting at RuPy: + +* Implementations of other dynamic languages + such as JavaScript, Prolog (already started), + Ruby (?), Perl (??) (which will all get a JIT + essentially for free) From fijal at codespeak.net Sat Apr 14 12:21:59 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 14 Apr 2007 12:21:59 +0200 (CEST) Subject: [pypy-svn] r42043 - pypy/dist/pypy/interpreter/astcompiler Message-ID: <20070414102159.6BE7280B7@code0.codespeak.net> Author: fijal Date: Sat Apr 14 12:21:58 2007 New Revision: 42043 Modified: pypy/dist/pypy/interpreter/astcompiler/pyassem.py Log: use wrapped dict instead of unwrapped list for keeping constants. closes #304 Modified: pypy/dist/pypy/interpreter/astcompiler/pyassem.py ============================================================================== --- pypy/dist/pypy/interpreter/astcompiler/pyassem.py (original) +++ pypy/dist/pypy/interpreter/astcompiler/pyassem.py Sat Apr 14 12:21:58 2007 @@ -8,6 +8,7 @@ from pypy.interpreter.pycode import PyCode from pypy.interpreter.baseobjspace import W_Root from pypy.tool import stdlib_opcode as pythonopcode +from pypy.interpreter.error import OperationError class BlockSet: """A Set implementation specific to Blocks @@ -447,7 +448,9 @@ if newlocals: self.flags |= CO_NEWLOCALS - self.consts = [] + # XXX we need to build app-level dict here, bleh + self.w_consts = space.newdict() + #self.const_list = [] self.names = [] # Free variables found by the symbol table scan, including # variables used only in nested scopes, are included here. @@ -631,11 +634,19 @@ for i in pythonopcode.hasjabs: hasjabs[pythonopcode.opname[i]] = True + def setconst(self, w_consts, w_item, value): + space = self.space + w_item_type = space.type(w_item) + w_key = space.newtuple([w_item, w_item_type]) + space.setitem(w_consts, w_key, space.wrap(value)) + def convertArgs(self): """Convert arguments from symbolic to concrete form""" assert self.stage == RAW + space = self.space self.orderedblocks = self.getBlocksInOrder() - self.consts.insert(0, self.docstring) + self.setconst(self.w_consts, self.docstring, 0) + #self.const_list.insert(0, self.docstring) self.sort_cellvars() for b in self.orderedblocks: @@ -691,7 +702,7 @@ return True return False - def _lookupConst(self, w_obj, list_w): + def _lookupConst(self, w_obj, w_dict): """ This routine uses a list instead of a dictionary, because a dictionary can't store two different keys if the keys have the @@ -701,12 +712,15 @@ """ space = self.space w_obj_type = space.type(w_obj) - for i in range(len(list_w)): - if self._cmpConsts(w_obj, list_w[i]): - return i - end = len(list_w) - list_w.append(w_obj) - return end + try: + w_key = space.newtuple([w_obj, w_obj_type]) + return space.int_w(space.getitem(w_dict, w_key)) + except OperationError, operr: + if not operr.match(space, space.w_KeyError): + raise + lgt = space.int_w(space.len(w_dict)) + self.setconst(w_dict, w_obj, lgt) + return lgt _converters = {} @@ -717,7 +731,7 @@ assert isinstance(inst, InstrObj) w_obj = inst.obj #assert w_obj is not None - index = self._lookupConst(w_obj, self.consts) + index = self._lookupConst(w_obj, self.w_consts) return InstrInt(inst.op, index) def _convert_LOAD_FAST(self, inst): @@ -842,7 +856,14 @@ Must convert references to code (MAKE_FUNCTION) to code objects recursively. """ - return self.consts[:] + space = self.space + l_w = [None] * space.int_w(space.len(self.w_consts)) + keys_w = space.unpackiterable(self.w_consts) + for w_key in keys_w: + index = space.int_w(space.getitem(self.w_consts, w_key)) + w_v = space.unpacktuple(w_key)[0] + l_w[index] = w_v + return l_w def isJump(opname): if opname[:4] == 'JUMP': From fijal at codespeak.net Sat Apr 14 12:48:06 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 14 Apr 2007 12:48:06 +0200 (CEST) Subject: [pypy-svn] r42044 - pypy/extradoc/talk/rupy2007 Message-ID: <20070414104806.4642880B7@code0.codespeak.net> Author: fijal Date: Sat Apr 14 12:48:06 2007 New Revision: 42044 Added: pypy/extradoc/talk/rupy2007/revised_talk.txt Log: Add a revised version of talk for not-that-python-fluent people Added: pypy/extradoc/talk/rupy2007/revised_talk.txt ============================================================================== --- (empty file) +++ pypy/extradoc/talk/rupy2007/revised_talk.txt Sat Apr 14 12:48:06 2007 @@ -0,0 +1,192 @@ +============================ +PyPy +============================ + +:Authors: Maciej Fijalkowski +:Location: Adam Mickiewicz University +:Date: 15.IV.2007 + +Next 45 minutes +======================================= + +* Quick intro and motivation, including + CPython problems + +* Introduction to features unique to PyPy, + including the JIT + +* A little talk about our plans + +What is PyPy? +============== + +* PyPy is: +* A Python interpreter +* A very + flexible compiler framework (with some + features that are especially useful for + implementing interpreters) +* An open source project (MIT license) +* A STREP (''Specific Targeted REsearch + Project''), partially funded by the EU +* A lot of fun! + +About the project +==================== + +* Distributed -- the 12 paid developers live in + 6 countries, contributers from many more +* Sprint driven development -- focussed week + long coding sessions, every ~6 weeks during + funding period +* Extreme Programming practices: pair + programming, test-driven development + +Test tools +=========== + +* We use py.test, developed together with PyPy +* distributed testing +* easy to extend (testing docs, js snippets etc.) + +Compiler toolchain +=================== + +* Translates so called RPython + (restricted Python) to lower level language +* Targets C, LLVM, CLI, JVM, JavaScript... +* Can translate any program, but + is aimed at implementing interpreters + +RPython +========= + +* Starts from living python objects, so + all dynamic tricks are allowed for initialization +* Full implicit type inference +* Like Java, but has at least + function pointers + +Motivation +=========== + +* PyPy grew out of a desire to modify/extend + the implementation of Python, for example to: +* increase performance (psyco-style JIT + compilation, better garbage collectors) +* add expressiveness (stackless-style + coroutines, logic programming, distribution) +* ease porting (to new platforms like the + JVM or CLI or to low memory situations) + +Lofty goals, but first... +=========================== +* CPython is a fine implementation of Python + but: +* it's written in C, which makes porting to, + for example, the CLI hard +* while psyco and stackless exist, they are + very hard to maintain as Python evolves +* some implementation decisions are very + hard to change (e.g. refcounting) + +Things that make PyPy unique +=============================== + +* The Just-In-Time compiler (and the way it + has been made) +* Transparent Proxies +* Runtime modifiable Grammar +* Thunk object space +* JavaScript backend +* Logic programming +* whatever you imagine ... + +Just-In-Time compiler generator +================================= + +* generates just in time compiler given + the interpreter source + few hints +* applicable to any possible interpreter + (written in RPython) + +XXX (demo) + +Multiple object implementations +================================ + +* Every python-level object can have multiple + implementations +* Examples are: String-key specialized dicts, + ropes, tree-based dicts + +XXX (rope nasty example) + +Transparent proxies +==================== + +* Built on top of multiple object implementations + +* Provides new implementation for each object + +* can access everything in transparent manner, + including such things like interpreter frames + +XXX www demo + +Distribution +================ + +* Built on top of transparent proxies +* Can hide network layer +* Copies only small chunks of data, + avoiding too much traffic +* Still very experimental! + +XXX not sure about demo + +JavaScript backend +=================== + +* translates RPython to JavaScript + +* has built-in AJAX functionality, + which maps method calls to + JSON calls + +* can be tested on top of CPython + (common case in PyPy) + +XXX play1 +XXX demo + +Interpreter status +========================== + +* We still use CPython :) + +* for some specific use cases, + we use PyPy when CPython is + incapable + +* It's very friendly platform + for experiments + +* Threads and extension modules + are not working + +Translation toolchain status +============================= + +* Usefull +* There is working python interpreter +* prolog interpreter +* JavaScript interpreter coming soon +* Ruby? Perl?? (with JIT almost for free) + +What future holds +==================== + +* More JIT! (faster than C) +* Extension modules +* Holiday! (funding period ended in March) From fijal at codespeak.net Sat Apr 14 12:55:34 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 14 Apr 2007 12:55:34 +0200 (CEST) Subject: [pypy-svn] r42045 - pypy/extradoc/talk/rupy2007 Message-ID: <20070414105534.F323480B7@code0.codespeak.net> Author: fijal Date: Sat Apr 14 12:55:34 2007 New Revision: 42045 Modified: pypy/extradoc/talk/rupy2007/revised_talk.txt Log: Added one slide Modified: pypy/extradoc/talk/rupy2007/revised_talk.txt ============================================================================== --- pypy/extradoc/talk/rupy2007/revised_talk.txt (original) +++ pypy/extradoc/talk/rupy2007/revised_talk.txt Sat Apr 14 12:55:34 2007 @@ -190,3 +190,11 @@ * More JIT! (faster than C) * Extension modules * Holiday! (funding period ended in March) + +Further points of interest +============================== + +* http://codespeak.net/pypy +* http://play1.codespeak.net/ +* #pypy on freenode +* pypy-dev at codespeak.net From arigo at codespeak.net Sat Apr 14 12:58:59 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 14 Apr 2007 12:58:59 +0200 (CEST) Subject: [pypy-svn] r42046 - pypy/extradoc/talk/rupy2007 Message-ID: <20070414105859.AADBF80B7@code0.codespeak.net> Author: arigo Date: Sat Apr 14 12:58:59 2007 New Revision: 42046 Modified: pypy/extradoc/talk/rupy2007/revised_talk.txt Log: Careful when saying "RPython is like Java". Modified: pypy/extradoc/talk/rupy2007/revised_talk.txt ============================================================================== --- pypy/extradoc/talk/rupy2007/revised_talk.txt (original) +++ pypy/extradoc/talk/rupy2007/revised_talk.txt Sat Apr 14 12:58:59 2007 @@ -47,7 +47,7 @@ * We use py.test, developed together with PyPy * distributed testing -* easy to extend (testing docs, js snippets etc.) +* easy to extend (testing docs, JavaScript snippets etc.) Compiler toolchain =================== @@ -64,8 +64,8 @@ * Starts from living python objects, so all dynamic tricks are allowed for initialization * Full implicit type inference -* Like Java, but has at least - function pointers +* Like Java, but with function pointers, specialization, + and more Motivation =========== @@ -169,7 +169,7 @@ we use PyPy when CPython is incapable -* It's very friendly platform +* It's a very friendly platform for experiments * Threads and extension modules From arigo at codespeak.net Sat Apr 14 13:00:38 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 14 Apr 2007 13:00:38 +0200 (CEST) Subject: [pypy-svn] r42047 - pypy/extradoc/talk/rupy2007 Message-ID: <20070414110038.4153780B4@code0.codespeak.net> Author: arigo Date: Sat Apr 14 13:00:38 2007 New Revision: 42047 Modified: pypy/extradoc/talk/rupy2007/revised_talk.txt Log: Some more rewording of "RPython is like Java" :-) Modified: pypy/extradoc/talk/rupy2007/revised_talk.txt ============================================================================== --- pypy/extradoc/talk/rupy2007/revised_talk.txt (original) +++ pypy/extradoc/talk/rupy2007/revised_talk.txt Sat Apr 14 13:00:38 2007 @@ -64,7 +64,7 @@ * Starts from living python objects, so all dynamic tricks are allowed for initialization * Full implicit type inference -* Like Java, but with function pointers, specialization, +* Type system like Java's, but with function pointers and more Motivation From fijal at codespeak.net Sat Apr 14 15:57:18 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 14 Apr 2007 15:57:18 +0200 (CEST) Subject: [pypy-svn] r42048 - pypy/extradoc/talk/rupy2007/demos Message-ID: <20070414135718.9FE0780B7@code0.codespeak.net> Author: fijal Date: Sat Apr 14 15:57:17 2007 New Revision: 42048 Added: pypy/extradoc/talk/rupy2007/demos/local.py pypy/extradoc/talk/rupy2007/demos/remote.py Log: Add distribution demos anyway Added: pypy/extradoc/talk/rupy2007/demos/local.py ============================================================================== --- (empty file) +++ pypy/extradoc/talk/rupy2007/demos/local.py Sat Apr 14 15:57:17 2007 @@ -0,0 +1,18 @@ + +from distributed import RemoteProtocol, remote_loop +from distributed.socklayer import Finished, socket_listener, socket_connecter +import sys +import pdb + +PORT = 12121 + +def f(): + print "Calling f" + return 8 + + +if __name__ == '__main__': + send, receive = socket_connecter(('localhost', PORT)) + r = RemoteProtocol(send, receive) + + Added: pypy/extradoc/talk/rupy2007/demos/remote.py ============================================================================== --- (empty file) +++ pypy/extradoc/talk/rupy2007/demos/remote.py Sat Apr 14 15:57:17 2007 @@ -0,0 +1,24 @@ + +from distributed import RemoteProtocol, remote_loop +from distributed.socklayer import Finished, socket_listener, socket_connecter +import sys + +PORT = 12121 + +class X: + def __init__(self): + self.xxx = 3 + + def meth(self, f): + print "Calling meth" + return f() + self.xxx + +x = X() + +if __name__ == '__main__': + send, receive = socket_listener(address=('', PORT)) + try: + remote_loop(RemoteProtocol(send, receive, globals())) + except Finished: + pass + From fijal at codespeak.net Sat Apr 14 17:22:57 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 14 Apr 2007 17:22:57 +0200 (CEST) Subject: [pypy-svn] r42049 - pypy/extradoc/talk/rupy2007 Message-ID: <20070414152257.1023B80B7@code0.codespeak.net> Author: fijal Date: Sat Apr 14 17:22:55 2007 New Revision: 42049 Modified: pypy/extradoc/talk/rupy2007/revised_talk.txt pypy/extradoc/talk/rupy2007/talk.txt Log: Change order of slides Modified: pypy/extradoc/talk/rupy2007/revised_talk.txt ============================================================================== --- pypy/extradoc/talk/rupy2007/revised_talk.txt (original) +++ pypy/extradoc/talk/rupy2007/revised_talk.txt Sat Apr 14 17:22:55 2007 @@ -42,31 +42,6 @@ * Extreme Programming practices: pair programming, test-driven development -Test tools -=========== - -* We use py.test, developed together with PyPy -* distributed testing -* easy to extend (testing docs, JavaScript snippets etc.) - -Compiler toolchain -=================== - -* Translates so called RPython - (restricted Python) to lower level language -* Targets C, LLVM, CLI, JVM, JavaScript... -* Can translate any program, but - is aimed at implementing interpreters - -RPython -========= - -* Starts from living python objects, so - all dynamic tricks are allowed for initialization -* Full implicit type inference -* Type system like Java's, but with function pointers - and more - Motivation =========== @@ -90,6 +65,24 @@ * some implementation decisions are very hard to change (e.g. refcounting) +Compiler toolchain +=================== + +* Translates so called RPython + (restricted Python) to lower level language +* Targets C, LLVM, CLI, JVM, JavaScript... +* Can translate any program, but + is aimed at implementing interpreters + +RPython +========= + +* Starts from living python objects, so + all dynamic tricks are allowed for initialization +* Full implicit type inference +* Type system like Java's, but with function pointers + and more + Things that make PyPy unique =============================== @@ -98,7 +91,7 @@ * Transparent Proxies * Runtime modifiable Grammar * Thunk object space -* JavaScript backend +* Multiple backends * Logic programming * whatever you imagine ... @@ -184,6 +177,13 @@ * JavaScript interpreter coming soon * Ruby? Perl?? (with JIT almost for free) +Test tools +=========== + +* We use py.test, developed together with PyPy +* distributed testing +* easy to extend (testing docs, JavaScript snippets etc.) + What future holds ==================== Modified: pypy/extradoc/talk/rupy2007/talk.txt ============================================================================== --- pypy/extradoc/talk/rupy2007/talk.txt (original) +++ pypy/extradoc/talk/rupy2007/talk.txt Sat Apr 14 17:22:55 2007 @@ -121,16 +121,17 @@ * Can hide network layer * Copies only small chunks of data, avoiding too much traffic +* Still very experimental! + +Using translation toolchain +============================ -Stackless -============ - -* XXX +* Working prolog interpreter -Runtime modifiable grammar -=========================== +* Started Javascript interpreter -* XXX +* Ruby? Perl?? Whatever interpreter + (having JIT almost for free) How do you specify the Python language? ======================================== From fijal at codespeak.net Sat Apr 14 17:34:32 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 14 Apr 2007 17:34:32 +0200 (CEST) Subject: [pypy-svn] r42050 - pypy/extradoc/talk/rupy2007/demos Message-ID: <20070414153432.20CFD80BA@code0.codespeak.net> Author: fijal Date: Sat Apr 14 17:34:31 2007 New Revision: 42050 Added: pypy/extradoc/talk/rupy2007/demos/f.py Log: Add a function for translatorshell Added: pypy/extradoc/talk/rupy2007/demos/f.py ============================================================================== --- (empty file) +++ pypy/extradoc/talk/rupy2007/demos/f.py Sat Apr 14 17:34:31 2007 @@ -0,0 +1,16 @@ + +class X: + def __init__(self, x): + self.y = x + + def m(self): + return self.y + 3 + +def two(x): + return X(x).m() + +def one(x): + if x: + return two(x) + else: + return 3 From fijal at codespeak.net Sat Apr 14 17:39:30 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 14 Apr 2007 17:39:30 +0200 (CEST) Subject: [pypy-svn] r42051 - pypy/extradoc/talk/rupy2007/demos Message-ID: <20070414153930.5947880BA@code0.codespeak.net> Author: fijal Date: Sat Apr 14 17:39:30 2007 New Revision: 42051 Added: pypy/extradoc/talk/rupy2007/demos/nasty.py Log: nasty rope example Added: pypy/extradoc/talk/rupy2007/demos/nasty.py ============================================================================== --- (empty file) +++ pypy/extradoc/talk/rupy2007/demos/nasty.py Sat Apr 14 17:39:30 2007 @@ -0,0 +1,3 @@ + +x = '0' * 1000000000 +print len(x) From fijal at codespeak.net Sat Apr 14 18:38:47 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 14 Apr 2007 18:38:47 +0200 (CEST) Subject: [pypy-svn] r42055 - pypy/extradoc/talk/rupy2007/demos Message-ID: <20070414163847.EC41380BA@code0.codespeak.net> Author: fijal Date: Sat Apr 14 18:38:47 2007 New Revision: 42055 Added: pypy/extradoc/talk/rupy2007/demos/serv.py pypy/extradoc/talk/rupy2007/demos/test_serv.py pypy/extradoc/talk/rupy2007/demos/thunk.py Log: Add some demos Added: pypy/extradoc/talk/rupy2007/demos/serv.py ============================================================================== --- (empty file) +++ pypy/extradoc/talk/rupy2007/demos/serv.py Sat Apr 14 18:38:47 2007 @@ -0,0 +1,44 @@ +from subprocess import Popen, PIPE + +from pypy.translator.js.lib import server +from pypy.translator.js.lib.support import js_source, callback +from pypy.translator.js.modules import dom + +HTML = """ + + +

Stuff

+""" + +def onupdate(msg): + dom.document.getElementById("s").innerHTML = msg + dom.setTimeout(start, 1000) + +def start(): + exported_methods.update(onupdate) + +class ExportedMethods(server.ExportedMethods): + @callback(retval=str) + def update(self): + p = Popen('uptime', stdout=PIPE) + p.wait() + return p.stdout.read() + +exported_methods = ExportedMethods() + +class App(server.Collection): + exported_methods = exported_methods + def index(self): + return HTML + index.exposed = True + + def stuff_js(self): + return "text/javascript", js_source([start]) + stuff_js.exposed = True + +class Handler(server.NewHandler): + application = App() + +if __name__ == '__main__': + httpd = server.create_server(handler=Handler, server_address=('', 7010)) + httpd.serve_forever() Added: pypy/extradoc/talk/rupy2007/demos/test_serv.py ============================================================================== --- (empty file) +++ pypy/extradoc/talk/rupy2007/demos/test_serv.py Sat Apr 14 18:38:47 2007 @@ -0,0 +1,12 @@ + +from pypy.translator.js import tester +from pypy.translator.js.modules import dom +from serv import HTML, start, exported_methods + +def test_js(): + dom.window = dom.Window(HTML) + dom.document = dom.window.document + start() + tester.schedule_callbacks(exported_methods) + print dom.document.getElementById("s").innerHTML + assert "Stuff" not in dom.document.getElementById("s").innerHTML Added: pypy/extradoc/talk/rupy2007/demos/thunk.py ============================================================================== --- (empty file) +++ pypy/extradoc/talk/rupy2007/demos/thunk.py Sat Apr 14 18:38:47 2007 @@ -0,0 +1,6 @@ +from __pypy__ import thunk +def f(): + print 'computing...' + return 6*7 + +x = thunk(f) From fijal at codespeak.net Sat Apr 14 18:45:55 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 14 Apr 2007 18:45:55 +0200 (CEST) Subject: [pypy-svn] r42056 - pypy/extradoc/talk/rupy2007 Message-ID: <20070414164555.EC95A80BA@code0.codespeak.net> Author: fijal Date: Sat Apr 14 18:45:55 2007 New Revision: 42056 Modified: pypy/extradoc/talk/rupy2007/revised_talk.txt Log: Oops, changes in wc Modified: pypy/extradoc/talk/rupy2007/revised_talk.txt ============================================================================== --- pypy/extradoc/talk/rupy2007/revised_talk.txt (original) +++ pypy/extradoc/talk/rupy2007/revised_talk.txt Sat Apr 14 18:45:55 2007 @@ -103,8 +103,6 @@ * applicable to any possible interpreter (written in RPython) -XXX (demo) - Multiple object implementations ================================ @@ -113,8 +111,6 @@ * Examples are: String-key specialized dicts, ropes, tree-based dicts -XXX (rope nasty example) - Transparent proxies ==================== @@ -125,8 +121,6 @@ * can access everything in transparent manner, including such things like interpreter frames -XXX www demo - Distribution ================ @@ -136,7 +130,23 @@ avoiding too much traffic * Still very experimental! -XXX not sure about demo +Thunk object space +================== + +* Build as different object space + (object operation basis) + +* Can do lazy computation of objects + +Taint object space +=================== + +* Also build as different object space + +* Few lines hack + +* Can track values as taint, which cannot + cross I/O borders implicitely JavaScript backend =================== @@ -150,9 +160,6 @@ * can be tested on top of CPython (common case in PyPy) -XXX play1 -XXX demo - Interpreter status ========================== From fijal at codespeak.net Sat Apr 14 18:46:32 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 14 Apr 2007 18:46:32 +0200 (CEST) Subject: [pypy-svn] r42057 - pypy/extradoc/talk/rupy2007 Message-ID: <20070414164632.E064480BD@code0.codespeak.net> Author: fijal Date: Sat Apr 14 18:46:32 2007 New Revision: 42057 Removed: pypy/extradoc/talk/rupy2007/old_talk.txt pypy/extradoc/talk/rupy2007/talk.txt Log: Delete those From fijal at codespeak.net Sat Apr 14 18:47:26 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 14 Apr 2007 18:47:26 +0200 (CEST) Subject: [pypy-svn] r42058 - pypy/extradoc/talk/rupy2007 Message-ID: <20070414164726.E4AFA80BA@code0.codespeak.net> Author: fijal Date: Sat Apr 14 18:47:26 2007 New Revision: 42058 Added: pypy/extradoc/talk/rupy2007/talk.txt - copied unchanged from r42056, pypy/extradoc/talk/rupy2007/revised_talk.txt Removed: pypy/extradoc/talk/rupy2007/revised_talk.txt Log: Move revised_talk -> talk From fijal at codespeak.net Sat Apr 14 18:49:03 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 14 Apr 2007 18:49:03 +0200 (CEST) Subject: [pypy-svn] r42059 - pypy/extradoc/talk/rupy2007 Message-ID: <20070414164903.2302180BA@code0.codespeak.net> Author: fijal Date: Sat Apr 14 18:49:02 2007 New Revision: 42059 Modified: pypy/extradoc/talk/rupy2007/talk.txt Log: (fijal, arigo) few changes Modified: pypy/extradoc/talk/rupy2007/talk.txt ============================================================================== --- pypy/extradoc/talk/rupy2007/talk.txt (original) +++ pypy/extradoc/talk/rupy2007/talk.txt Sat Apr 14 18:49:02 2007 @@ -82,6 +82,7 @@ * Full implicit type inference * Type system like Java's, but with function pointers and more +* 20-60x faster than CPython Things that make PyPy unique =============================== @@ -175,7 +176,7 @@ * Threads and extension modules are not working -Translation toolchain status +Interpreters in RPython ============================= * Usefull From fijal at codespeak.net Sun Apr 15 18:32:56 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 15 Apr 2007 18:32:56 +0200 (CEST) Subject: [pypy-svn] r42063 - in pypy/dist/pypy/translator/js: . jssrc test Message-ID: <20070415163256.E48338093@code0.codespeak.net> Author: fijal Date: Sun Apr 15 18:32:55 2007 New Revision: 42063 Modified: pypy/dist/pypy/translator/js/jssrc/misc.js pypy/dist/pypy/translator/js/metavm.py pypy/dist/pypy/translator/js/opcodes.py pypy/dist/pypy/translator/js/test/test_rclass.py pypy/dist/pypy/translator/js/test/test_rpbc.py Log: Add few hacks to pass few more tests 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 Sun Apr 15 18:32:55 2007 @@ -22,6 +22,9 @@ } function isinstanceof(self, what) { + if (!self) { + return (false); + } t = self.constructor; while ( t ) { if (t == what) { @@ -216,5 +219,11 @@ } return (i); } - + +function convertToString(stuff) { + if (stuff === undefined) { + return ("undefined"); + } + return (stuff.toString()); +} // ends hand written code Modified: pypy/dist/pypy/translator/js/metavm.py ============================================================================== --- pypy/dist/pypy/translator/js/metavm.py (original) +++ pypy/dist/pypy/translator/js/metavm.py Sun Apr 15 18:32:55 2007 @@ -250,5 +250,5 @@ IsInstance = _IsInstance() CallMethod = _CallMethod() CopyName = [PushAllArgs, _SameAs ()] -CastString = _CastMethod("toString") +CastString = _CastFun("convertToString", 1) SameAs = CopyName Modified: pypy/dist/pypy/translator/js/opcodes.py ============================================================================== --- pypy/dist/pypy/translator/js/opcodes.py (original) +++ pypy/dist/pypy/translator/js/opcodes.py Sun Apr 15 18:32:55 2007 @@ -117,6 +117,7 @@ 'new' : [New], 'runtimenew' : [RuntimeNew], 'instanceof' : [IsInstance], + #'subclassof' : [IsSubclassOf], # objects Modified: pypy/dist/pypy/translator/js/test/test_rclass.py ============================================================================== --- pypy/dist/pypy/translator/js/test/test_rclass.py (original) +++ pypy/dist/pypy/translator/js/test/test_rclass.py Sun Apr 15 18:32:55 2007 @@ -8,6 +8,8 @@ class TestJsException(JsTest, BaseTestException): pass +# ====> ../../../rpython/test/test_rclass.py + class TestJsClass(JsTest, BaseTestRclass): def test___class___attribute(self): class Base(object): pass @@ -70,6 +72,6 @@ def test_issubclass_type(self): py.test.skip("WIP") - def test_isinstance(self): - py.test.skip("WIP") + #def test_isinstance(self): + # py.test.skip("WIP") Modified: pypy/dist/pypy/translator/js/test/test_rpbc.py ============================================================================== --- pypy/dist/pypy/translator/js/test/test_rpbc.py (original) +++ pypy/dist/pypy/translator/js/test/test_rpbc.py Sun Apr 15 18:32:55 2007 @@ -3,6 +3,8 @@ from pypy.translator.js.test.runtest import JsTest from pypy.rpython.test.test_rpbc import BaseTestRPBC +# ====> ../../../rpython/test/test_rpbc.py + class TestJsPBC(JsTest, BaseTestRPBC): def test_single_pbc_getattr(self): class C: @@ -31,10 +33,4 @@ def test_call_memoized_function_with_bools(self): py.test.skip("WIP") - - def test_conv_from_None(self): - py.test.skip("WIP") - - def test_multiple_ll_one_hl_op(self): - py.test.skip("XXX fix me soon") From fijal at codespeak.net Sun Apr 15 18:49:55 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 15 Apr 2007 18:49:55 +0200 (CEST) Subject: [pypy-svn] r42064 - pypy/dist/pypy/doc Message-ID: <20070415164955.5DAB2809F@code0.codespeak.net> Author: fijal Date: Sun Apr 15 18:49:55 2007 New Revision: 42064 Modified: pypy/dist/pypy/doc/javascript-interpreter.txt Log: Typo Modified: pypy/dist/pypy/doc/javascript-interpreter.txt ============================================================================== --- pypy/dist/pypy/doc/javascript-interpreter.txt (original) +++ pypy/dist/pypy/doc/javascript-interpreter.txt Sun Apr 15 18:49:55 2007 @@ -18,7 +18,7 @@ ================================ Just as you can translate PyPy's Python interpreter, you can also translate the -Javscript interpreter to C:: +Javascript interpreter to C:: pypy$ cd translator/goal pypy/translator/goal$ python translate.py targetjsstandalone.py From santagada at codespeak.net Sun Apr 15 18:55:48 2007 From: santagada at codespeak.net (santagada at codespeak.net) Date: Sun, 15 Apr 2007 18:55:48 +0200 (CEST) Subject: [pypy-svn] r42065 - pypy/dist/pypy/doc Message-ID: <20070415165548.24B7D809F@code0.codespeak.net> Author: santagada Date: Sun Apr 15 18:55:47 2007 New Revision: 42065 Modified: pypy/dist/pypy/doc/javascript-interpreter.txt Log: saying why we need spidermonkey for Modified: pypy/dist/pypy/doc/javascript-interpreter.txt ============================================================================== --- pypy/dist/pypy/doc/javascript-interpreter.txt (original) +++ pypy/dist/pypy/doc/javascript-interpreter.txt Sun Apr 15 18:55:47 2007 @@ -9,9 +9,10 @@ support for some facilities not common to javascript interpreters. To run the js interpreter you will need the spidermonkey binary in the path -(or in the same directory in windows). It does have a interactive interpreter -for you to play with, but it is made in pure python (not rpython) so it isn't -present on the translated interpreter +(or in the same directory in windows) as we currently don't have our own +parser and we are using narcisus on top of spidermonkey . Also, it does have +an interactive interpreter for you to play with, but it is made in pure python +(not rpython) so it isn't present on the translated interpreter. Translating the interpreter to C From santagada at codespeak.net Sun Apr 15 19:44:38 2007 From: santagada at codespeak.net (santagada at codespeak.net) Date: Sun, 15 Apr 2007 19:44:38 +0200 (CEST) Subject: [pypy-svn] r42071 - pypy/dist/pypy/doc Message-ID: <20070415174438.B62F280A1@code0.codespeak.net> Author: santagada Date: Sun Apr 15 19:44:38 2007 New Revision: 42071 Modified: pypy/dist/pypy/doc/javascript-interpreter.txt Log: explaning more of what js-pypy is Modified: pypy/dist/pypy/doc/javascript-interpreter.txt ============================================================================== --- pypy/dist/pypy/doc/javascript-interpreter.txt (original) +++ pypy/dist/pypy/doc/javascript-interpreter.txt Sun Apr 15 19:44:38 2007 @@ -2,11 +2,16 @@ JS-PyPy: PyPy's Javascript interpreter ====================================== - -The pypy Javascript interpreter was written by Leonardo Santagada with the -help of most of the pypy team and is his summer of pypy project. It aims to -show how to implement a clear interpreter on the pypy plataform, and providing -support for some facilities not common to javascript interpreters. +JS-PyPy is a Javascript interpreter written in pyton by Leonardo Santagada +with the help of most of the pypy team and is his summer of pypy project. It +is a python program, so you can run it on top of the usual python interpreter +and probably in the future even use it to support javascript in a python +application (some apis and some more work is needed for that), but the most +important stuff now is that it can be translated by pypy to a binary or to any +other backend to make a stand-alone interpreter, with the flexibility that the +pypy tools give you, like changing garbage collector. It aims to show how to +implement a clear interpreter on the pypy plataform, and providing support for +some facilities not common to javascript interpreters. To run the js interpreter you will need the spidermonkey binary in the path (or in the same directory in windows) as we currently don't have our own From santagada at codespeak.net Sun Apr 15 19:48:11 2007 From: santagada at codespeak.net (santagada at codespeak.net) Date: Sun, 15 Apr 2007 19:48:11 +0200 (CEST) Subject: [pypy-svn] r42072 - pypy/dist/pypy/doc Message-ID: <20070415174811.C2DD480A1@code0.codespeak.net> Author: santagada Date: Sun Apr 15 19:48:11 2007 New Revision: 42072 Modified: pypy/dist/pypy/doc/javascript-interpreter.txt Log: limitations note. Modified: pypy/dist/pypy/doc/javascript-interpreter.txt ============================================================================== --- pypy/dist/pypy/doc/javascript-interpreter.txt (original) +++ pypy/dist/pypy/doc/javascript-interpreter.txt Sun Apr 15 19:48:11 2007 @@ -19,8 +19,12 @@ an interactive interpreter for you to play with, but it is made in pure python (not rpython) so it isn't present on the translated interpreter. +If you want to play with it now, you will see that it works for some simple +code and most of javascript statements but it is still missing much on the +standard library, and right now we have some problems with prototypes (but +they are being worked on) -Translating the interpreter to C +Translating the interpreter to C ================================ Just as you can translate PyPy's Python interpreter, you can also translate the From afa at codespeak.net Mon Apr 16 00:14:20 2007 From: afa at codespeak.net (afa at codespeak.net) Date: Mon, 16 Apr 2007 00:14:20 +0200 (CEST) Subject: [pypy-svn] r42078 - pypy/dist/pypy/rpython/rctypes/test Message-ID: <20070415221420.B5DCA809E@code0.codespeak.net> Author: afa Date: Mon Apr 16 00:14:19 2007 New Revision: 42078 Modified: pypy/dist/pypy/rpython/rctypes/test/test_rctypes.py Log: Make test_rctypes pass on Windows Modified: pypy/dist/pypy/rpython/rctypes/test/test_rctypes.py ============================================================================== --- pypy/dist/pypy/rpython/rctypes/test/test_rctypes.py (original) +++ pypy/dist/pypy/rpython/rctypes/test/test_rctypes.py Mon Apr 16 00:14:19 2007 @@ -35,7 +35,7 @@ del c_source # into the generated C sources if sys.platform == "win32": - _rctypes_test = cdll_load("_rctypes_test.pyd") + _rctypes_test = cdll_load(str(thisdir.join("_rctypes_test.pyd"))) else: _rctypes_test = cdll_load(str(thisdir.join("_rctypes_test.so"))) From afa at codespeak.net Mon Apr 16 00:48:53 2007 From: afa at codespeak.net (afa at codespeak.net) Date: Mon, 16 Apr 2007 00:48:53 +0200 (CEST) Subject: [pypy-svn] r42079 - pypy/dist/pypy/rpython/rctypes/tool/test Message-ID: <20070415224853.19302809E@code0.codespeak.net> Author: afa Date: Mon Apr 16 00:48:52 2007 New Revision: 42079 Modified: pypy/dist/pypy/rpython/rctypes/tool/test/test_compilemodule.py Log: Skip test: readline cannot work on Windows Modified: pypy/dist/pypy/rpython/rctypes/tool/test/test_compilemodule.py ============================================================================== --- pypy/dist/pypy/rpython/rctypes/tool/test/test_compilemodule.py (original) +++ pypy/dist/pypy/rpython/rctypes/tool/test/test_compilemodule.py Mon Apr 16 00:48:52 2007 @@ -1,4 +1,5 @@ import py +import sys from pypy.rpython.rctypes.tool.compilemodule import compilemodule def test_demo(): @@ -8,5 +9,8 @@ py.test.raises(mod.DemoError, mod.measuretime, -5, long) def test_readline(): + if sys.platform == "win32": + py.test.skip("no readline on win32") + mod = compilemodule('readline') assert hasattr(mod, 'readline') # XXX test more From afa at codespeak.net Mon Apr 16 00:50:08 2007 From: afa at codespeak.net (afa at codespeak.net) Date: Mon, 16 Apr 2007 00:50:08 +0200 (CEST) Subject: [pypy-svn] r42080 - pypy/dist/pypy/rpython/rctypes/tool Message-ID: <20070415225008.B15D8809F@code0.codespeak.net> Author: afa Date: Mon Apr 16 00:50:08 2007 New Revision: 42080 Modified: pypy/dist/pypy/rpython/rctypes/tool/ctypes_platform.py Log: Generate C89-compliant code, and corresponding tests pass on Windows Modified: pypy/dist/pypy/rpython/rctypes/tool/ctypes_platform.py ============================================================================== --- pypy/dist/pypy/rpython/rctypes/tool/ctypes_platform.py (original) +++ pypy/dist/pypy/rpython/rctypes/tool/ctypes_platform.py Mon Apr 16 00:50:08 2007 @@ -129,7 +129,6 @@ def prepare_code(self): if self.ifdef is not None: yield '#ifdef %s' % (self.ifdef,) - yield 'dump("defined", 1);' yield 'typedef %s ctypesplatcheck_t;' % (self.name,) yield 'typedef struct {' yield ' char c;' @@ -137,6 +136,8 @@ yield '} ctypesplatcheck2_t;' yield '' yield 'ctypesplatcheck_t s;' + if self.ifdef is not None: + yield 'dump("defined", 1);' yield 'dump("align", offsetof(ctypesplatcheck2_t, s));' yield 'dump("size", sizeof(ctypesplatcheck_t));' for fieldname, fieldtype in self.interesting_fields: @@ -231,10 +232,11 @@ def prepare_code(self): if self.ifdef is not None: yield '#ifdef %s' % (self.ifdef,) - yield 'dump("defined", 1);' yield 'typedef %s ctypesplatcheck_t;' % (self.name,) yield '' yield 'ctypesplatcheck_t x;' + if self.ifdef is not None: + yield 'dump("defined", 1);' yield 'dump("size", sizeof(ctypesplatcheck_t));' if self.ctype_hint in integer_class: yield 'x = 0; x = ~x;' From fijal at codespeak.net Mon Apr 16 13:17:11 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 16 Apr 2007 13:17:11 +0200 (CEST) Subject: [pypy-svn] r42088 - pypy/dist/pypy/module/array Message-ID: <20070416111711.4BB0080A6@code0.codespeak.net> Author: fijal Date: Mon Apr 16 13:17:10 2007 New Revision: 42088 Modified: pypy/dist/pypy/module/array/app_array.py Log: (suggestion by armin) Solved at least one problem, but there is still pending flow objspace test failures for python2.5 translate.py Modified: pypy/dist/pypy/module/array/app_array.py ============================================================================== --- pypy/dist/pypy/module/array/app_array.py (original) +++ pypy/dist/pypy/module/array/app_array.py Mon Apr 16 13:17:10 2007 @@ -24,7 +24,6 @@ array(typecode [, initializer]) -- create a new array """ import sys -from struct import pack, unpack if sys.maxunicode == 65535: UNICODE_SIZE = 2 @@ -214,6 +213,7 @@ self._fromiterable(l) def fromstring(self, s): + from struct import pack, unpack """Appends items from the string, interpreting it as an array of machine values, as if it had been read from a file using the fromfile() method).""" @@ -266,6 +266,7 @@ return self._data[:] def tostring(self): + from struct import pack, unpack """Convert the array to an array of machine values and return the string representation.""" if self.typecode == "u": From arigo at codespeak.net Mon Apr 16 14:37:20 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 16 Apr 2007 14:37:20 +0200 (CEST) Subject: [pypy-svn] r42090 - pypy/dist/pypy/interpreter Message-ID: <20070416123720.331B080C6@code0.codespeak.net> Author: arigo Date: Mon Apr 16 14:37:19 2007 New Revision: 42090 Modified: pypy/dist/pypy/interpreter/pyopcode.py Log: Workaround for IMPORT_NAME semantic changes in 2.5. Modified: pypy/dist/pypy/interpreter/pyopcode.py ============================================================================== --- pypy/dist/pypy/interpreter/pyopcode.py (original) +++ pypy/dist/pypy/interpreter/pyopcode.py Mon Apr 16 14:37:19 2007 @@ -707,6 +707,21 @@ w_modulename = f.getname_w(nameindex) modulename = f.space.str_w(w_modulename) w_fromlist = f.popvalue() + + # CPython 2.5 adds an obscure extra flag consumed by this opcode + if f.pycode.magic >= 0xa0df294: + w_flag = f.popvalue() + try: + if space.int_w(w_flag) == -1: + w_flag = None # don't provide the extra flag if == -1 + except OperationError, e: + # let SystemExit and KeyboardInterrupt go through + if e.async(space): + raise + # ignore other exceptions + else: + w_flag = None + w_import = f.get_builtin().getdictvalue_w(f.space, '__import__') if w_import is None: raise OperationError(space.w_ImportError, @@ -714,8 +729,14 @@ w_locals = f.w_locals if w_locals is None: # CPython does this w_locals = space.w_None - w_obj = space.call_function(w_import, space.wrap(modulename), - f.w_globals, w_locals, w_fromlist) + w_modulename = space.wrap(modulename) + w_globals = f.w_globals + if w_flag is None: + w_obj = space.call_function(w_import, w_modulename, w_globals, + w_locals, w_fromlist) + else: + w_obj = space.call_function(w_import, w_modulename, w_globals, + w_locals, w_fromlist, w_flag) f.pushvalue(w_obj) def IMPORT_STAR(f, *ignored): From arigo at codespeak.net Mon Apr 16 14:47:05 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 16 Apr 2007 14:47:05 +0200 (CEST) Subject: [pypy-svn] r42091 - pypy/dist/pypy/interpreter Message-ID: <20070416124705.6DFA080BA@code0.codespeak.net> Author: arigo Date: Mon Apr 16 14:47:05 2007 New Revision: 42091 Modified: pypy/dist/pypy/interpreter/generator.py pypy/dist/pypy/interpreter/pyframe.py Log: Support for 2.5-style YIELD_VALUE semantic. The send() method of generators is not implemented yet, though. Modified: pypy/dist/pypy/interpreter/generator.py ============================================================================== --- pypy/dist/pypy/interpreter/generator.py (original) +++ pypy/dist/pypy/interpreter/generator.py Mon Apr 16 14:47:05 2007 @@ -39,7 +39,7 @@ self.running = True try: try: - w_result = self.frame.execute_frame() + w_result = self.frame.execute_generator_frame(space.w_None) except OperationError: # errors finish a frame self.frame.frame_finished_execution = True Modified: pypy/dist/pypy/interpreter/pyframe.py ============================================================================== --- pypy/dist/pypy/interpreter/pyframe.py (original) +++ pypy/dist/pypy/interpreter/pyframe.py Mon Apr 16 14:47:05 2007 @@ -92,6 +92,14 @@ else: return self.execute_frame() + def execute_generator_frame(self, w_inputvalue): + # opcode semantic change in CPython 2.5: we must pass an input value + # when resuming a generator, which goes into the value stack. + # (it's always w_None for now - not implemented in generator.py) + if self.pycode.magic >= 0xa0df294 and self.last_instr != -1: + self.pushvalue(w_inputvalue) + return self.execute_frame() + def execute_frame(self): """Execute this frame. Main entry point to the interpreter.""" executioncontext = self.space.getexecutioncontext() From tismer at codespeak.net Mon Apr 16 15:20:35 2007 From: tismer at codespeak.net (tismer at codespeak.net) Date: Mon, 16 Apr 2007 15:20:35 +0200 (CEST) Subject: [pypy-svn] r42093 - pypy/dist/pypy/lib/pyontology Message-ID: <20070416132035.8AC8780A8@code0.codespeak.net> Author: tismer Date: Mon Apr 16 15:20:35 2007 New Revision: 42093 Modified: pypy/dist/pypy/lib/pyontology/pyontology.py Log: some reformatting of the docstring Modified: pypy/dist/pypy/lib/pyontology/pyontology.py ============================================================================== --- pypy/dist/pypy/lib/pyontology/pyontology.py (original) +++ pypy/dist/pypy/lib/pyontology/pyontology.py Mon Apr 16 15:20:35 2007 @@ -65,10 +65,15 @@ return format """ In OWL there are Classes, Properties, Individuals and Literals. - Properties creates relations between Classes, Classes and Individuals, Individuals and Individuals and Literals. There are a inheritance tree of Properties. We record instances of Properies in the class variable "prop_instance". - - Classes are defined as the set of Individuals belonging to the Class. We record these as the Values of the Classdomain. - We record the instances of a Classtype in the Class variable "cls_inst". The class instances shall "buble" up the inheritance tree. + Properties creates relations between Classes, Classes and Individuals, + Individuals and Individuals and Literals. There is an inheritance + tree of Properties. + We record instances of Properies in the class variable "prop_instance". + + Classes are defined as the set of Individuals belonging to the Class. + We record these as the Values of the Classdomain. + We record the instances of a Classtype in the Class variable "cls_inst". + The class instances shall "bubble" up the inheritance tree. """ class ClassDomain(AbstractDomain, object): @@ -917,7 +922,6 @@ # class extension of var, ie if a indiviual is in # the extension of s it must be in the extension of # var - avar = self.make_var(ClassDomain, var) svar = self.make_var(ClassDomain, s) self.variables[svar].bases.append(avar) From tismer at codespeak.net Mon Apr 16 15:24:49 2007 From: tismer at codespeak.net (tismer at codespeak.net) Date: Mon, 16 Apr 2007 15:24:49 +0200 (CEST) Subject: [pypy-svn] r42094 - pypy/dist/pypy/lib/pyontology/test Message-ID: <20070416132449.24B5180A8@code0.codespeak.net> Author: tismer Date: Mon Apr 16 15:24:48 2007 New Revision: 42094 Modified: pypy/dist/pypy/lib/pyontology/test/test_ontology.py pypy/dist/pypy/lib/pyontology/test/test_sparql.py Log: some modification to the tests to make them path independent. Without changing the implementation, I had to turn the file names into an opened URL. Note that there is a wrong assumption of having a seekable file, which is not true for URLs. The seek can be avoided by passing the 'xml' type to add_file Modified: pypy/dist/pypy/lib/pyontology/test/test_ontology.py ============================================================================== --- pypy/dist/pypy/lib/pyontology/test/test_ontology.py (original) +++ pypy/dist/pypy/lib/pyontology/test/test_ontology.py Mon Apr 16 15:24:48 2007 @@ -13,6 +13,24 @@ #from pypy.lib.pyontology.pyontology import * # Ontology, ClassDomain, SubClassConstraint from rdflib import Graph, URIRef, BNode +import os +import pypy.lib.pyontology +DATAPATH = os.path.join(os.path.split(pypy.lib.pyontology.__file__)[0], 'test') + +def datapath(name): + """ + Making the tests location independent: + We need to turn the file name into an URL, or the drive letter + would be misinterpreted as protocol on windows. + Instead of a plain file name, we pass an open URL. + But careful, URLs don't have a seek method, so we need to avoid + inspection of the beginning of the file by passing the file type + 'xml' explicitly. + """ + from urllib import urlopen, pathname2url + url = pathname2url(os.path.join(DATAPATH, name)) + return urlopen(url) + UR = URIRef class TestAppOntology: @@ -40,7 +58,7 @@ def test_equivalentProperty_inconst(self): from pypy.lib.pyontology.pyontology import * O = Ontology() - O.add_file("testinconst.rdf") + O.add_file(datapath("testinconst.rdf"), 'xml') O.attach_fd() raises(ConsistencyFailure, O.consistency) @@ -683,12 +701,12 @@ def test_add_file(self): from pypy.lib.pyontology.pyontology import * O = Ontology() - O.add_file('premises001.rdf') + O.add_file(datapath('premises001.rdf'), 'xml') trip = list(O.graph.triples((None,)*3)) # O.attach_fd() ll = len(O.variables) l = len(trip) - O.add_file('conclusions001.rdf') + O.add_file(datapath('conclusions001.rdf'), 'xml') O.attach_fd() lll = len(O.variables) assert len(list(O.graph.triples((None,)*3))) > l @@ -696,12 +714,12 @@ def test_more_cardinality(self): from pypy.lib.pyontology.pyontology import * O = Ontology() - O.add_file('premises003.rdf') + O.add_file(datapath('premises003.rdf'), 'xml') trip = list(O.graph.triples((None,)*3)) # O.attach_fd() ll = len(O.variables) l = len(trip) - O.add_file('conclusions003.rdf') + O.add_file(datapath('conclusions003.rdf'), 'xml') O.attach_fd() O.consistency() lll = len(O.variables) Modified: pypy/dist/pypy/lib/pyontology/test/test_sparql.py ============================================================================== --- pypy/dist/pypy/lib/pyontology/test/test_sparql.py (original) +++ pypy/dist/pypy/lib/pyontology/test/test_sparql.py Mon Apr 16 15:24:48 2007 @@ -9,6 +9,25 @@ from pypy.lib.pyontology.sparql_grammar import SPARQLGrammar as SP from pypy.lib.pyontology.pyontology import Ontology, ConsistencyFailure +import os +import pypy.lib.pyontology +DATAPATH = os.path.join(os.path.split(pypy.lib.pyontology.__file__)[0], 'test') + +def datapath(name): + """ + Making the tests location independent: + We need to turn the file name into an URL, or the drive letter + would be misinterpreted as protocol on windows. + Instead of a plain file name, we pass an open URL. + But careful, URLs don't have a seek method, so we need to avoid + inspection of the beginning of the file by passing the file type + 'xml' explicitly. + """ + from urllib import urlopen, pathname2url + url = pathname2url(os.path.join(DATAPATH, name)) + return urlopen(url) + + qt = """ PREFIX ns: @@ -80,7 +99,7 @@ query = qt_proto % ('?x', 'ns:sub ns:p "a123" .') O = Ontology() - O.add_file("testont.rdf") + O.add_file(datapath("testont.rdf"), 'xml') O.attach_fd() raises(ConsistencyFailure, O.sparql, query) @@ -89,7 +108,7 @@ query = qt_proto % ('?x', '?x ns:p 123 .') O = Ontology() - O.add_file("testont.rdf") + O.add_file(datapath("testont.rdf"), 'xml') O.attach_fd() O.finish() res = O.sparql(query) @@ -100,7 +119,7 @@ query = qt_proto % ('?x', 'ns:sub ?x 123 .') O = Ontology() - O.add_file("testont.rdf") + O.add_file(datapath("testont.rdf"), 'xml') O.attach_fd() O.finish() @@ -113,7 +132,7 @@ query = qt_proto % ('?x', 'ns:sub ns:p ?x .') O = Ontology() - O.add_file("testont.rdf") + O.add_file(datapath("testont.rdf"), 'xml') O.attach_fd() O.finish() @@ -125,7 +144,7 @@ query = qt_proto % ('?x ?y', '?x ?y 123 .') O = Ontology() - O.add_file("testont.rdf") + O.add_file(datapath("testont.rdf"), 'xml') O.attach_fd() O.finish() @@ -139,7 +158,7 @@ query = qt_proto % ('?x ?y', '?x ns:p ?y .') O = Ontology() - O.add_file("testont.rdf") + O.add_file(datapath("testont.rdf"), 'xml') O.attach_fd() O.finish() @@ -154,7 +173,7 @@ query = qt_proto % ('?x ?y', 'ns:sub ?x ?y .') O = Ontology() - O.add_file("testont.rdf") + O.add_file(datapath("testont.rdf"), 'xml') O.attach_fd() O.finish() @@ -167,7 +186,7 @@ query = qt_proto % ('?x ?y ?z', '?x ?y ?z .') O = Ontology() - O.add_file("testont.rdf") + O.add_file(datapath("testont.rdf"), 'xml') O.attach_fd() O.finish() res = O.sparql(query) @@ -177,7 +196,7 @@ def test_filter(): query = qt_proto % ('?x ?y', '?x ns:p ?y .\n FILTER(?y < 124) .') O = Ontology() - O.add_file("testont.rdf") + O.add_file(datapath("testont.rdf"), 'xml') O.attach_fd() O.finish() res = O.sparql(query) @@ -218,7 +237,7 @@ def test_query1(): O = Ontology() - O.add_file("testont2.rdf") + O.add_file(datapath("testont2.rdf"), 'xml') O.attach_fd() res = O.sparql(query1) @@ -229,7 +248,7 @@ def test_query2(): # py.test.skip("Doesn't work yet") O = Ontology() - O.add_file("testont2.rdf") + O.add_file(datapath("testont2.rdf"), 'xml') O.attach_fd() res = O.sparql(query2) @@ -240,7 +259,7 @@ def test_query3(): #py.test.skip("Doesn't work yet") O = Ontology() - O.add_file("testont2.rdf") + O.add_file(datapath("testont2.rdf"), 'xml') O.attach_fd() res = O.sparql(query3) @@ -258,6 +277,8 @@ import sys exe = sys.executable print exe + self.oldcwd = os.getcwd() + os.chdir(DATAPATH) self.shell = Popen("%s ../pyontology.py testont.rdf" % exe, shell=True) server = xmlrpclib.ServerProxy("http://localhost:9000") print "setup" @@ -271,7 +292,11 @@ break def teardown_class(self): print " teardown", self.shell.pid - os.kill(self.shell.pid, signal.SIGTERM) + os.chdir(self.oldcwd) + try: + os.kill(self.shell.pid, signal.SIGTERM) + except AttributeError: + print "SORRY can't kill process in this OS" def test_xmlrpc(self): print "test_xmlrpc" From arigo at codespeak.net Mon Apr 16 17:52:48 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 16 Apr 2007 17:52:48 +0200 (CEST) Subject: [pypy-svn] r42100 - in pypy/dist/pypy: annotation rpython/test Message-ID: <20070416155248.D37AF80BE@code0.codespeak.net> Author: arigo Date: Mon Apr 16 17:52:48 2007 New Revision: 42100 Modified: pypy/dist/pypy/annotation/annrpython.py pypy/dist/pypy/annotation/classdef.py pypy/dist/pypy/annotation/description.py pypy/dist/pypy/rpython/test/test_exception.py Log: Fixes for Python 2.5 (Exception => py.builtin.BaseException). Modified: pypy/dist/pypy/annotation/annrpython.py ============================================================================== --- pypy/dist/pypy/annotation/annrpython.py (original) +++ pypy/dist/pypy/annotation/annrpython.py Mon Apr 16 17:52:48 2007 @@ -622,7 +622,7 @@ last_exc_value_var = link.last_exc_value # may be None for non-exception link if isinstance(link.exitcase, (types.ClassType, type)) \ - and issubclass(link.exitcase, Exception): + and issubclass(link.exitcase, py.builtin.BaseException): assert last_exception_var and last_exc_value_var last_exc_value_object = self.bookkeeper.valueoftype(link.exitcase) last_exception_object = annmodel.SomeObject() Modified: pypy/dist/pypy/annotation/classdef.py ============================================================================== --- pypy/dist/pypy/annotation/classdef.py (original) +++ pypy/dist/pypy/annotation/classdef.py Mon Apr 16 17:52:48 2007 @@ -230,18 +230,8 @@ other1 = other while other is not None and not self.issubclass(other): other = other.basedef - # special case for MI with Exception - #if other is None and other1 is not None: - # if issubclass(self.cls, Exception) and issubclass(other1.cls, Exception): - # return self.bookkeeper.getclassdef(Exception) return other - #def superdef_containing(self, cls): - # clsdef = self - # while clsdef is not None and not issubclass(cls, clsdef.cls): - # clsdef = clsdef.basedef - # return clsdef - def getmro(self): while self is not None: yield self Modified: pypy/dist/pypy/annotation/description.py ============================================================================== --- pypy/dist/pypy/annotation/description.py (original) +++ pypy/dist/pypy/annotation/description.py Mon Apr 16 17:52:48 2007 @@ -536,7 +536,8 @@ return s_instance def is_exception_class(self): - return self.pyobj is not None and issubclass(self.pyobj, Exception) + return self.pyobj is not None and issubclass(self.pyobj, + py.builtin.BaseException) def is_builtin_exception_class(self): if self.is_exception_class(): Modified: pypy/dist/pypy/rpython/test/test_exception.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_exception.py (original) +++ pypy/dist/pypy/rpython/test/test_exception.py Mon Apr 16 17:52:48 2007 @@ -112,6 +112,17 @@ next_instr -= operr.a py.test.raises(LLException, self.interpret, f, [10]) + def test_catch_KeyboardInterrupt(self): + def g(n): + return n + def f(n): + try: + return g(n) + except KeyboardInterrupt: + return -1 + res = self.interpret(f, [11]) + assert res == 11 + class TestLLtype(BaseTestException, LLRtypeMixin): pass From arigo at codespeak.net Mon Apr 16 17:57:48 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 16 Apr 2007 17:57:48 +0200 (CEST) Subject: [pypy-svn] r42101 - pypy/dist/pypy/rpython Message-ID: <20070416155748.E918780C8@code0.codespeak.net> Author: arigo Date: Mon Apr 16 17:57:48 2007 New Revision: 42101 Modified: pypy/dist/pypy/rpython/llinterp.py pypy/dist/pypy/rpython/rclass.py Log: More Exception => py.builtin.BaseException conversions. Modified: pypy/dist/pypy/rpython/llinterp.py ============================================================================== --- pypy/dist/pypy/rpython/llinterp.py (original) +++ pypy/dist/pypy/rpython/llinterp.py Mon Apr 16 17:57:48 2007 @@ -333,7 +333,7 @@ cls = e.args[0] inst = e.args[1] for link in block.exits[1:]: - assert issubclass(link.exitcase, Exception) + assert issubclass(link.exitcase, py.builtin.BaseException) if self.op_direct_call(exdata.fn_exception_match, cls, link.llexitcase): self.setifvar(link.last_exception, cls) @@ -1138,7 +1138,8 @@ result = [] seen = {} def addcls(cls): - if type(cls) is type(Exception) and issubclass(cls, Exception): + if (type(cls) is type(Exception) and + issubclass(cls, py.builtin.BaseException)): if cls in seen: return for base in cls.__bases__: # bases first Modified: pypy/dist/pypy/rpython/rclass.py ============================================================================== --- pypy/dist/pypy/rpython/rclass.py (original) +++ pypy/dist/pypy/rpython/rclass.py Mon Apr 16 17:57:48 2007 @@ -9,16 +9,6 @@ try: result = rtyper.class_reprs[classdef] except KeyError: - #if classdef and classdef.cls is Exception: - # # skip Exception as a base class and go directly to 'object'. - # # the goal is to allow any class anywhere in the hierarchy - # # to have Exception as a second base class. It should be an - # # empty class anyway. - # if classdef.attrs: - # raise TyperError("the Exception class should not " - # "have any attribute attached to it") - # result = getclassrepr(rtyper, None) - #else: result = rtyper.type_system.rclass.ClassRepr(rtyper, classdef) rtyper.class_reprs[classdef] = result rtyper.add_pendingsetup(result) From tismer at codespeak.net Mon Apr 16 18:03:32 2007 From: tismer at codespeak.net (tismer at codespeak.net) Date: Mon, 16 Apr 2007 18:03:32 +0200 (CEST) Subject: [pypy-svn] r42102 - pypy/dist/pypy/lib/pyontology Message-ID: <20070416160332.8980780CC@code0.codespeak.net> Author: tismer Date: Mon Apr 16 18:03:32 2007 New Revision: 42102 Modified: pypy/dist/pypy/lib/pyontology/constraint_classes.py pypy/dist/pypy/lib/pyontology/pyontology.py Log: typos, removed debug calls, enabled verbose, again Modified: pypy/dist/pypy/lib/pyontology/constraint_classes.py ============================================================================== --- pypy/dist/pypy/lib/pyontology/constraint_classes.py (original) +++ pypy/dist/pypy/lib/pyontology/constraint_classes.py Mon Apr 16 18:03:32 2007 @@ -3,6 +3,13 @@ from logilab.constraint.distributors import DichotomyDistributor, SplitDistributor from logilab.constraint.fd import Expression from rdflib import URIRef +try: + # not sure if we have this when running on PyPy + # this is needed for verbose, only (see solve method) + from time import strftime +except ImportError: + pass + import autopath import py from pypy.tool.ansi_print import ansi_log Modified: pypy/dist/pypy/lib/pyontology/pyontology.py ============================================================================== --- pypy/dist/pypy/lib/pyontology/pyontology.py (original) +++ pypy/dist/pypy/lib/pyontology/pyontology.py Mon Apr 16 18:03:32 2007 @@ -415,7 +415,7 @@ """ A owl:restriction is an anonymous class that links a class to a restriction on a property The restriction is only applied to the property in the conntext of the specific task. In order to construct a constraint to check the restriction three things are thus needed : - 1. The property to which the restriction applies - this comes from the onProperty tripple. + 1. The property to which the restriction applies - this comes from the onProperty triple. the property is saved in the Restriction class' property attribute 2. The restriction itself. This comes from one of the property restrictions triples (oneOf, maxCardinality ....). It adds a constraint class From afa at codespeak.net Mon Apr 16 23:15:55 2007 From: afa at codespeak.net (afa at codespeak.net) Date: Mon, 16 Apr 2007 23:15:55 +0200 (CEST) Subject: [pypy-svn] r42107 - in pypy/dist/pypy/rlib: . test Message-ID: <20070416211555.6DE8080CE@code0.codespeak.net> Author: afa Date: Mon Apr 16 23:15:54 2007 New Revision: 42107 Modified: pypy/dist/pypy/rlib/_rsocket_ctypes.py pypy/dist/pypy/rlib/rsocket.py pypy/dist/pypy/rlib/test/test_rsocket.py Log: rsocket.py is now importable on Windows. 2 tests even pass Modified: pypy/dist/pypy/rlib/_rsocket_ctypes.py ============================================================================== --- pypy/dist/pypy/rlib/_rsocket_ctypes.py (original) +++ pypy/dist/pypy/rlib/_rsocket_ctypes.py Mon Apr 16 23:15:54 2007 @@ -10,39 +10,54 @@ from ctypes import c_short, POINTER, ARRAY, cdll, sizeof, SetPointerType from pypy.rlib.rarithmetic import intmask, r_uint - # Also not used here, but exported for other code. from ctypes import cast, pointer, create_string_buffer -includes = ('sys/types.h', - 'sys/socket.h', - 'sys/un.h', - 'sys/poll.h', - 'netinet/in.h', - 'netinet/tcp.h', - 'unistd.h', - 'fcntl.h', - 'stdio.h', - 'netdb.h', - 'arpa/inet.h', - 'stdint.h', - 'errno.h', - ) -cond_includes = [('AF_NETLINK', 'linux/netlink.h')] -HEADER = ''.join(['#include <%s>\n' % filename for filename in includes]) -COND_HEADER = ''.join(['#ifdef %s\n#include <%s>\n#endif\n' % cond_include - for cond_include in cond_includes]) +_POSIX = os.name == "posix" +_MS_WINDOWS = os.name == "nt" + +if _POSIX: + includes = ('sys/types.h', + 'sys/socket.h', + 'sys/un.h', + 'sys/poll.h', + 'netinet/in.h', + 'netinet/tcp.h', + 'unistd.h', + 'fcntl.h', + 'stdio.h', + 'netdb.h', + 'arpa/inet.h', + 'stdint.h', + 'errno.h', + ) + cond_includes = [('AF_NETLINK', 'linux/netlink.h')] + HEADER = ''.join(['#include <%s>\n' % filename for filename in includes]) + COND_HEADER = ''.join(['#ifdef %s\n#include <%s>\n#endif\n' % cond_include + for cond_include in cond_includes]) +if _MS_WINDOWS: + HEADER = '\n'.join([ + '#include ', + '#include ', + # winsock2 defines AF_UNIX, but not sockaddr_un + '#undef AF_UNIX', + # these types do not exist on windows + 'typedef int ssize_t;', + 'typedef unsigned __int16 uint16_t;', + 'typedef unsigned __int32 uint32_t;', + ]) + COND_HEADER = '' constants = {} class CConfig: _header_ = HEADER + COND_HEADER # constants - O_NONBLOCK = ctypes_platform.ConstantInteger('O_NONBLOCK') - F_GETFL = ctypes_platform.ConstantInteger('F_GETFL') - F_SETFL = ctypes_platform.ConstantInteger('F_SETFL') + O_NONBLOCK = ctypes_platform.DefinedConstantInteger('O_NONBLOCK') + F_GETFL = ctypes_platform.DefinedConstantInteger('F_GETFL') + F_SETFL = ctypes_platform.DefinedConstantInteger('F_SETFL') linux = ctypes_platform.Defined('linux') - MS_WINDOWS = ctypes_platform.Defined('MS_WINDOWS') + MS_WINDOWS = ctypes_platform.Defined('_WIN32') INVALID_SOCKET = ctypes_platform.DefinedConstantInteger('INVALID_SOCKET') INET_ADDRSTRLEN = ctypes_platform.DefinedConstantInteger('INET_ADDRSTRLEN') INET6_ADDRSTRLEN= ctypes_platform.DefinedConstantInteger('INET6_ADDRSTRLEN') @@ -213,11 +228,23 @@ [('p_proto', c_int), ]) -CConfig.nfds_t = ctypes_platform.SimpleType('nfds_t') -CConfig.pollfd = ctypes_platform.Struct('struct pollfd', - [('fd', c_int), - ('events', c_short), - ('revents', c_short)]) +if _POSIX: + CConfig.nfds_t = ctypes_platform.SimpleType('nfds_t') + CConfig.pollfd = ctypes_platform.Struct('struct pollfd', + [('fd', c_int), + ('events', c_short), + ('revents', c_short)]) + +if _MS_WINDOWS: + CConfig.WSAData = ctypes_platform.Struct('struct WSAData', + [('wVersion', c_ushort), + ('wHighVersion', c_ushort), + ('szDescription', c_char * 1), # (WSADESCRIPTION_LEN+1) + ('szSystemStatus', c_char * 1), # (WSASYS_STATUS_LEN+1) + ('iMaxSockets', c_ushort), + ('iMaxUdpDg', c_ushort), + ('lpVendorInfo', c_char_p)]) + class cConfig: pass @@ -260,6 +287,8 @@ linux = cConfig.linux MS_WINDOWS = cConfig.MS_WINDOWS +assert MS_WINDOWS == _MS_WINDOWS + if MS_WINDOWS: def invalid_socket(fd): return fd == INVALID_SOCKET @@ -285,8 +314,9 @@ in_addr_size = sizeof(in_addr) in6_addr = cConfig.in6_addr addrinfo = cConfig.addrinfo -nfds_t = cConfig.nfds_t -pollfd = cConfig.pollfd +if _POSIX: + nfds_t = cConfig.nfds_t + pollfd = cConfig.pollfd c_int_size = sizeof(c_int) SetPointerType(addrinfo_ptr, addrinfo) @@ -294,23 +324,31 @@ # functions -dllname = util.find_library('c') -assert dllname is not None -socketdll = cdll.LoadLibrary(dllname) - -dup = socketdll.dup -dup.argtypes = [c_int] -dup.restype = c_int +if MS_WINDOWS: + from ctypes import windll + dllname = util.find_library('wsock32') + assert dllname is not None + socketdll = windll.LoadLibrary(dllname) +else: + dllname = util.find_library('c') + assert dllname is not None + socketdll = cdll.LoadLibrary(dllname) + +if _POSIX: + dup = socketdll.dup + dup.argtypes = [c_int] + dup.restype = c_int #errno = c_int.in_dll(socketdll, 'errno') -strerror = socketdll.strerror -strerror.argtypes = [c_int] -strerror.restype = c_char_p - -gai_strerror = socketdll.gai_strerror -gai_strerror.argtypes = [c_int] -gai_strerror.restype = c_char_p +if _POSIX: + strerror = socketdll.strerror + strerror.argtypes = [c_int] + strerror.restype = c_char_p + + gai_strerror = socketdll.gai_strerror + gai_strerror.argtypes = [c_int] + gai_strerror.restype = c_char_p #h_errno = c_int.in_dll(socketdll, 'h_errno') # @@ -333,20 +371,21 @@ socketconnect.argtypes = [c_int, sockaddr_ptr, socklen_t] socketconnect.restype = c_int -getaddrinfo = socketdll.getaddrinfo -getaddrinfo.argtypes = [c_char_p, c_char_p, addrinfo_ptr, - POINTER(addrinfo_ptr)] -getaddrinfo.restype = c_int - -freeaddrinfo = socketdll.freeaddrinfo -freeaddrinfo.argtypes = [addrinfo_ptr] -freeaddrinfo.restype = None - -getnameinfo = socketdll.getnameinfo -getnameinfo.argtypes = [sockaddr_ptr, socklen_t, - c_char_p, size_t, - c_char_p, size_t, c_int] -getnameinfo.restype = c_int +if not MS_WINDOWS: + getaddrinfo = socketdll.getaddrinfo + getaddrinfo.argtypes = [c_char_p, c_char_p, addrinfo_ptr, + POINTER(addrinfo_ptr)] + getaddrinfo.restype = c_int + + freeaddrinfo = socketdll.freeaddrinfo + freeaddrinfo.argtypes = [addrinfo_ptr] + freeaddrinfo.restype = None + + getnameinfo = socketdll.getnameinfo + getnameinfo.argtypes = [sockaddr_ptr, socklen_t, + c_char_p, size_t, + c_char_p, size_t, c_int] + getnameinfo.restype = c_int htonl = socketdll.htonl htonl.argtypes = [uint32_t] @@ -364,21 +403,23 @@ ntohs.argtypes = [uint16_t] ntohs.restype = uint16_t -inet_aton = socketdll.inet_aton -inet_aton.argtypes = [c_char_p, POINTER(in_addr)] -inet_aton.restype = c_int +if _POSIX: + inet_aton = socketdll.inet_aton + inet_aton.argtypes = [c_char_p, POINTER(in_addr)] + inet_aton.restype = c_int inet_ntoa = socketdll.inet_ntoa inet_ntoa.argtypes = [in_addr] inet_ntoa.restype = c_char_p -inet_pton = socketdll.inet_pton -inet_pton.argtypes = [c_int, c_char_p, c_void_p] -inet_pton.restype = c_int - -inet_ntop = socketdll.inet_ntop -inet_ntop.argtypes = [c_int, c_void_p, c_char_p, socklen_t] -inet_ntop.restype = c_char_p +if _POSIX: + inet_pton = socketdll.inet_pton + inet_pton.argtypes = [c_int, c_char_p, c_void_p] + inet_pton.restype = c_int + + inet_ntop = socketdll.inet_ntop + inet_ntop.argtypes = [c_int, c_void_p, c_char_p, socklen_t] + inet_ntop.restype = c_char_p socketaccept = socketdll.accept socketaccept.argtypes = [c_int, sockaddr_ptr, POINTER(socklen_t)] @@ -436,11 +477,6 @@ socketshutdown.argtypes = [c_int, c_int] socketshutdown.restype = c_int - -getaddrinfo = socketdll.getaddrinfo -getaddrinfo.argtypes = [ c_char_p, c_char_p, addrinfo_ptr, POINTER(addrinfo_ptr)] -getaddrinfo.restype = c_int - gethostname = socketdll.gethostname gethostname.argtypes = [c_char_p, c_int] gethostname.restype = c_int @@ -465,28 +501,37 @@ getprotobyname.argtypes = [c_char_p] getprotobyname.restype = POINTER(cConfig.protoent) -fcntl = socketdll.fcntl -fcntl.argtypes = [c_int] * 3 -fcntl.restype = c_int - -memcpy = socketdll.memcpy -memcpy.argtypes = [c_void_p, c_void_p, size_t] -memcpy.restype = c_void_p - -socketpair_t = ARRAY(c_int, 2) -socketpair = socketdll.socketpair -socketpair.argtypes = [c_int, c_int, c_int, POINTER(socketpair_t)] -socketpair.restype = c_int +if _POSIX: + fcntl = socketdll.fcntl + fcntl.argtypes = [c_int] * 3 + fcntl.restype = c_int + + socketpair_t = ARRAY(c_int, 2) + socketpair = socketdll.socketpair + socketpair.argtypes = [c_int, c_int, c_int, POINTER(socketpair_t)] + socketpair.restype = c_int shutdown = socketdll.shutdown shutdown.argtypes = [c_int, c_int] shutdown.restype = c_int -poll = socketdll.poll -poll.argtypes = [POINTER(pollfd), nfds_t, c_int] -poll.restype = c_int +if _POSIX: + poll = socketdll.poll + poll.argtypes = [POINTER(pollfd), nfds_t, c_int] + poll.restype = c_int if MS_WINDOWS: + WSAData = cConfig.WSAData + WSAStartup = socketdll.WSAStartup + WSAStartup.argtypes = [c_int, POINTER(WSAData)] + WSAStartup.restype = c_int + + WSAGetLastError = socketdll.WSAGetLastError + WSAGetLastError.argtypes = [] + WSAGetLastError.restype = c_int + geterrno = WSAGetLastError + + import errno WIN32_ERROR_MESSAGES = { errno.WSAEINTR: "Interrupted system call", errno.WSAEBADF: "Bad file descriptor", @@ -547,7 +592,7 @@ } def socket_strerror(errno): - return WIN32_ERROR_MESSAGES.get(errno, "winsock error") + return WIN32_ERROR_MESSAGES.get(errno, "winsock error %d" % errno) else: def socket_strerror(errno): return strerror(errno) Modified: pypy/dist/pypy/rlib/rsocket.py ============================================================================== --- pypy/dist/pypy/rlib/rsocket.py (original) +++ pypy/dist/pypy/rlib/rsocket.py Mon Apr 16 23:15:54 2007 @@ -22,6 +22,16 @@ constants = _c.constants locals().update(constants) # Define constants from _c +if _c.MS_WINDOWS: + def rsocket_startup(): + wsadata = _c.WSAData() + res = _c.WSAStartup(1, byref(wsadata)) + assert res == 0 +else: + def rsocket_startup(): + pass + + ntohs = _c.ntohs ntohl = _c.ntohl htons = _c.htons @@ -311,60 +321,62 @@ # ____________________________________________________________ -class UNIXAddress(Address): - family = AF_UNIX - struct = _c.sockaddr_un - maxlen = sizeof(struct) - - def __init__(self, path): - sun = _c.sockaddr_un(sun_family = AF_UNIX) - if _c.linux and path.startswith('\x00'): - # Linux abstract namespace extension - if len(path) > sizeof(sun.sun_path): - raise RSocketError("AF_UNIX path too long") - else: - # regular NULL-terminated string - if len(path) >= sizeof(sun.sun_path): - raise RSocketError("AF_UNIX path too long") - 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) - - def as_sockaddr_un(self): - if self.addrlen <= offsetof(_c.sockaddr_un, 'sun_path'): - raise RSocketError("invalid address") - return cast(pointer(self.addr), POINTER(_c.sockaddr_un)).contents +if 'AF_UNIX' in constants: + class UNIXAddress(Address): + family = AF_UNIX + struct = _c.sockaddr_un + maxlen = sizeof(struct) - def __repr__(self): - try: - return '' % (self.get_path(),) - except SocketError: - return '' + def __init__(self, path): + sun = _c.sockaddr_un(sun_family = AF_UNIX) + if _c.linux and path.startswith('\x00'): + # Linux abstract namespace extension + if len(path) > sizeof(sun.sun_path): + raise RSocketError("AF_UNIX path too long") + else: + # regular NULL-terminated string + if len(path) >= sizeof(sun.sun_path): + raise RSocketError("AF_UNIX path too long") + 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) - def get_path(self): - a = self.as_sockaddr_un() - if _c.linux and a.sun_path[0] == 0: - # Linux abstract namespace - buf = copy_buffer(cast(pointer(a.sun_path), POINTER(c_char)), - self.addrlen - offsetof(_c.sockaddr_un, 'sun_path')) - return buf.raw - else: - # regular NULL-terminated string - return cast(pointer(a.sun_path), c_char_p).value + def as_sockaddr_un(self): + if self.addrlen <= offsetof(_c.sockaddr_un, 'sun_path'): + raise RSocketError("invalid address") + return cast(pointer(self.addr), POINTER(_c.sockaddr_un)).contents - def eq(self, other): # __eq__() is not called by RPython :-/ - return (isinstance(other, UNIXAddress) and - self.get_path() == other.get_path()) + def __repr__(self): + try: + return '' % (self.get_path(),) + except SocketError: + return '' + + def get_path(self): + a = self.as_sockaddr_un() + if _c.linux and a.sun_path[0] == 0: + # Linux abstract namespace + buf = copy_buffer(cast(pointer(a.sun_path), POINTER(c_char)), + self.addrlen - offsetof(_c.sockaddr_un, + 'sun_path')) + return buf.raw + else: + # regular NULL-terminated string + return cast(pointer(a.sun_path), c_char_p).value + + def eq(self, other): # __eq__() is not called by RPython :-/ + return (isinstance(other, UNIXAddress) and + self.get_path() == other.get_path()) - def as_object(self, space): - return space.wrap(self.get_path()) + def as_object(self, space): + return space.wrap(self.get_path()) - def from_object(space, w_address): - return UNIXAddress(space.str_w(w_address)) - from_object = staticmethod(from_object) + def from_object(space, w_address): + return UNIXAddress(space.str_w(w_address)) + from_object = staticmethod(from_object) if 'AF_NETLINK' in constants: class NETLINKAddress(Address): @@ -837,7 +849,7 @@ # ____________________________________________________________ -if AF_UNIX is None: +if 'AF_UNIX' not in constants or AF_UNIX is None: socketpair_default_family = AF_INET else: socketpair_default_family = AF_UNIX Modified: pypy/dist/pypy/rlib/test/test_rsocket.py ============================================================================== --- pypy/dist/pypy/rlib/test/test_rsocket.py (original) +++ pypy/dist/pypy/rlib/test/test_rsocket.py Mon Apr 16 23:15:54 2007 @@ -2,6 +2,9 @@ from pypy.rlib import rsocket from pypy.rlib.rsocket import * +def setup_module(mod): + rsocket_startup() + def test_ipv4_addr(): a = INETAddress("localhost", 4000) assert a.get_host() == "127.0.0.1" From afa at codespeak.net Tue Apr 17 00:59:33 2007 From: afa at codespeak.net (afa at codespeak.net) Date: Tue, 17 Apr 2007 00:59:33 +0200 (CEST) Subject: [pypy-svn] r42108 - in pypy/dist/pypy/rlib: . test Message-ID: <20070416225933.E02A080C3@code0.codespeak.net> Author: afa Date: Tue Apr 17 00:59:32 2007 New Revision: 42108 Added: pypy/dist/pypy/rlib/getaddrinfo.py pypy/dist/pypy/rlib/getnameinfo.py Modified: pypy/dist/pypy/rlib/_rsocket_ctypes.py pypy/dist/pypy/rlib/rsocket.py pypy/dist/pypy/rlib/test/test_rsocket.py Log: rsocket progress: implementation of getnameinfo() and getaddrinfo() on Windows. Some basic tests added, but no IPv6 support. Modified: pypy/dist/pypy/rlib/_rsocket_ctypes.py ============================================================================== --- pypy/dist/pypy/rlib/_rsocket_ctypes.py (original) +++ pypy/dist/pypy/rlib/_rsocket_ctypes.py Tue Apr 17 00:59:32 2007 @@ -222,7 +222,9 @@ CConfig.servent = ctypes_platform.Struct('struct servent', [('s_name', c_char_p), - ('s_port', c_int)]) + ('s_port', c_int), + ('s_proto', c_char_p), + ]) CConfig.protoent = ctypes_platform.Struct('struct protoent', [('p_proto', c_int), @@ -421,6 +423,10 @@ inet_ntop.argtypes = [c_int, c_void_p, c_char_p, socklen_t] inet_ntop.restype = c_char_p +inet_addr = socketdll.inet_addr +inet_addr.argtypes = [c_char_p] +inet_addr.restype = c_uint + socketaccept = socketdll.accept socketaccept.argtypes = [c_int, sockaddr_ptr, POINTER(socklen_t)] socketaccept.restype = c_int Added: pypy/dist/pypy/rlib/getaddrinfo.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/rlib/getaddrinfo.py Tue Apr 17 00:59:32 2007 @@ -0,0 +1,225 @@ +""" +An RPython implementation of getaddrinfo() based on ctypes. +This is a rewrite of the CPython source: Modules/getaddrinfo.c +""" + +from ctypes import POINTER, sizeof, cast, pointer +from pypy.rlib import _rsocket_ctypes as _c +from pypy.rlib.rsocket import GAIError, CSocketError +from pypy.rlib.rsocket import gethost_common, make_address + +# valid flags for addrinfo +AI_MASK = (_c.AI_PASSIVE | _c.AI_CANONNAME | _c.AI_NUMERICHOST) + +GAI_ERRORS = [ + (1, 'EAI_ADDRFAMILY', "address family for hostname not supported"), + (2, 'EAI_AGAIN', "temporary failure in name resolution"), + (3, 'EAI_BADFLAGS', "invalid value for ai_flags"), + (4, 'EAI_FAIL', "failure in name resolution"), + (5, 'EAI_FAMILY', "ai_family not supported"), + (6, 'EAI_MEMORY', "memory allocation failure"), + (7, 'EAI_NODATA', "no address associated with hostname"), + (8, 'EAI_NONAME', "hostname nor servname provided, or not known"), + (9, 'EAI_SERVICE', "servname not supported for ai_socktype"), + (10, 'EAI_SOCKTYPE', "ai_socktype not supported"), + (11, 'EAI_SYSTEM', "system error returned in errno"), + (12, 'EAI_BADHINTS', "invalid value for hints"), + (13, 'EAI_PROTOCOL', "resolved protocol is unknown."), + (14, 'EAI_MAX', "unknown error"), +] + +GAI_ERROR_MESSAGES = {} + +for value, name, text in GAI_ERRORS: + globals()[name] = value + GAI_ERROR_MESSAGES[value] = text + +# Replacement function for rsocket.GAIError.get_msg +def GAIError_getmsg(self): + return GAI_ERROR_MESSAGES[self.errno] + +# str.isdigit is not RPython, so provide our own +def str_isdigit(name): + if name == "": + return False + for c in name: + if c not in "012345789": + return False + return True + +GAI_ANY = 0 +INADDR_NONE = 0xFFFFFFFF + +def getaddrinfo(hostname, servname, + family=_c.AF_UNSPEC, socktype=0, + protocol=0, flags=0, + address_to_fill=None): + + if not hostname and not servname: + raise GAIError(EAI_NONAME) + + # error checks for hints + if flags & ~AI_MASK: + raise GAIError(EAI_BADFLAGS) + if family not in (_c.AF_UNSPEC, _c.AF_INET): + raise GAIError(EAI_FAMILY) + + if socktype == GAI_ANY: + if protocol == GAI_ANY: + pass + elif protocol == _c.IPPROTO_UDP: + socktype = _c.SOCK_DGRAM + elif protocol == _c.IPPROTO_TCP: + socktype = _c.SOCK_STREAM + else: + socktype = _c.SOCK_RAW + + elif socktype == _c.SOCK_RAW: + pass + elif socktype == _c.SOCK_DGRAM: + if protocol not in (_c.IPPROTO_UDP, GAI_ANY): + raise GAIError(EAI_BADHINTS) + protocol = _c.IPPROTO_UDP + elif socktype == _c.SOCK_STREAM: + if protocol not in (_c.IPPROTO_TCP, GAI_ANY): + raise GAIError(EAI_BADHINTS) + protocol = _c.IPPROTO_TCP + else: + raise GAIError(EAI_SOCKTYPE) + + port = GAI_ANY + + # service port + if servname: + if str_isdigit(servname): + port = _c.htons(int(servname)) + # On windows, python2.3 uses getattrinfo.c, + # python2.4 uses VC2003 implementation of getaddrinfo(). + # if sys.version < (2, 4) + # socktype = _c.SOCK_DGRAM + # protocol = _c.IPPROTO_UDP + else: + if socktype == _c.SOCK_DGRAM: + proto = "udp" + elif socktype == _c.SOCK_STREAM: + proto = "tcp" + else: + proto = None + + sp = _c.getservbyname(servname, proto) + if not sp: + raise GAIError(EAI_SERVICE) + port = sp.contents.s_port + if socktype == GAI_ANY: + if sp.contents.s_proto == "udp": + socktype = _c.SOCK_DGRAM + protocol = _c.IPPROTO_UDP + elif sp.contents.s_proto == "tcp": + socktype = _c.SOCK_STREAM + protocol = _c.IPPROTO_TCP + else: + raise GAIError(EAI_PROTOCOL) + + # hostname == NULL + # passive socket -> anyaddr (0.0.0.0 or ::) + # non-passive socket -> localhost (127.0.0.1 or ::1) + if not hostname: + result = [] + if family in (_c.AF_UNSPEC, _c.AF_INET): + + sin = _c.sockaddr_in(sin_family=_c.AF_INET, sin_port=port) + if flags & _c.AI_PASSIVE: + sin.sin_addr.s_addr = 0x0 # addrany + else: + sin.sin_addr.s_addr = 0x0100007f # loopback + + addr = make_address(cast(pointer(sin), POINTER(_c.sockaddr)), + sizeof(_c.sockaddr_in), address_to_fill) + + result.append((_c.AF_INET, socktype, protocol, "", # xxx canonname meaningless? "anyaddr" + addr)) + + if not result: + raise GAIError(EAI_FAMILY) + return result + + # hostname as numeric name + if family in (_c.AF_UNSPEC, _c.AF_INET): + + packedaddr = _c.inet_addr(hostname) + if packedaddr != INADDR_NONE: + + v4a = _c.ntohl(packedaddr) + if (v4a & 0xf0000000 == 0xe0000000 or # IN_MULTICAST() + v4a & 0xe0000000 == 0xe0000000): # IN_EXPERIMENTAL() + flags &= ~_c.AI_CANONNAME + v4a >>= 24 # = IN_CLASSA_NSHIFT + if v4a in (0, 127): # = IN_LOOPBACKNET + flags &= ~_c.AI_CANONNAME + + if not flags & _c.AI_CANONNAME: + sin = _c.sockaddr_in(sin_family=_c.AF_INET, sin_port=port) + sin.sin_addr.s_addr = packedaddr + addr = make_address(cast(pointer(sin), POINTER(_c.sockaddr)), + sizeof(_c.sockaddr_in), address_to_fill) + return [(_c.AF_INET, socktype, protocol, None, addr)] + else: + # XXX getaddrinfo() is a name->address translation function, + # and it looks strange that we do addr->name translation here. + sin = _c.sockaddr_in(sin_family=_c.AF_INET, sin_port=port) + + sin.sin_addr.s_addr = packedaddr + + canonname = get_name(hostname, sin.sin_addr, sizeof(_c.in_addr)) + + addr = make_address(cast(pointer(sin), POINTER(_c.sockaddr)), + sizeof(_c.sockaddr_in), address_to_fill) + return [(_c.AF_INET, socktype, protocol, canonname, addr)] + + if flags & _c.AI_NUMERICHOST: + raise GAIError(EAI_NONAME) + + # hostname as alphabetical name + result = get_addr(hostname, socktype, protocol, port, address_to_fill) + + if result: + return result + + raise GAIError(EAI_FAIL) + +def get_name(hostname, addr, addrlen): + hostent = _c.gethostbyaddr(pointer(addr), addrlen, _c.AF_INET) + + # if reverse lookup fail, + # return address anyway to pacify calling application. + if not hostent: + return hostname + + hname, aliases, address_list = gethost_common("", hostent) + if hostent and hostent.contents.h_name and hostent.contents.h_addr_list[0]: + return hostent.contents.h_name + else: + return hostname + +def get_addr(hostname, socktype, protocol, port, address_to_fill): + hostent = _c.gethostbyname(hostname) + + if not hostent: + raise GAIError(EAI_FAIL) + + hname, aliases, address_list = gethost_common("", hostent) + + result = [] + + for address in address_list: + if address.addr.sa_family == _c.AF_INET: + a = cast(pointer(address.addr), POINTER(_c.sockaddr_in)).contents + a.sin_port = port & 0xffff + addr = make_address(pointer(address.addr),address.addrlen,address_to_fill) + result.append((address.addr.sa_family, + socktype, + protocol, + "", # XXX canonname? + addr)) + + return result Added: pypy/dist/pypy/rlib/getnameinfo.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/rlib/getnameinfo.py Tue Apr 17 00:59:32 2007 @@ -0,0 +1,68 @@ +""" +An RPython implementation of getnameinfo() based on ctypes. +This is a rewrite of the CPython source: Modules/getaddrinfo.c +""" +from ctypes import POINTER, sizeof, cast, pointer +from pypy.rlib import _rsocket_ctypes as _c +from pypy.rlib.rsocket import RSocketError, GAIError + +NI_NOFQDN = 0x00000001 +NI_NUMERICHOST = 0x00000002 +NI_NAMEREQD = 0x00000004 +NI_NUMERICSERV = 0x00000008 +NI_DGRAM = 0x00000010 + +def _getservicename(sin_port, flags): + if flags & NI_NUMERICSERV: + sp = None + elif flags & NI_DGRAM: + sp = _c.getservbyport(sin_port, "udp") + else: + sp = _c.getservbyport(sin_port, "tcp") + + if sp: + serv = sp.contents.s_name + else: + serv = "%d" % _c.ntohs(sin_port) + + return serv + + +def getnameinfo(_addr, flags): + addr = _addr.addr + + if addr.sa_family != _c.AF_INET: + raise RSocketError("unknown address family") + + sockaddr = cast(pointer(addr), POINTER(_c.sockaddr_in)).contents + sin_port = sockaddr.sin_port + sin_addr = sockaddr.sin_addr + + v4a = _c.ntohl(sin_addr.s_addr) + if (v4a & 0xf0000000 == 0xe0000000 or # IN_MULTICAST() + v4a & 0xe0000000 == 0xe0000000): # IN_EXPERIMENTAL() + flags |= NI_NUMERICHOST + # XXX Why does this work in CPython? + # v4a >>= 24 # = IN_CLASSA_NSHIFT + # if v4a in (0, 127): # = IN_LOOPBACKNET + # flags |= NI_NUMERICHOST + numsize = _c.INET_ADDRSTRLEN + + serv = _getservicename(sin_port, flags) + + if not (flags & NI_NUMERICHOST): + hostent = _c.gethostbyaddr(pointer(sin_addr), sizeof(_c.in_addr), addr.sa_family) + else: + hostent = None + + if hostent: + from pypy.rlib.rsocket import gethost_common + host, _, _ = gethost_common("", hostent) + else: + from pypy.rlib.rsocket import copy_buffer + host = _c.inet_ntoa(sin_addr) + #buf = copy_buffer(ptr, len(ptr)) + #host = buf.raw + + return host, serv + Modified: pypy/dist/pypy/rlib/rsocket.py ============================================================================== --- pypy/dist/pypy/rlib/rsocket.py (original) +++ pypy/dist/pypy/rlib/rsocket.py Tue Apr 17 00:59:32 2007 @@ -87,21 +87,15 @@ family = result.family if len(name) == 0: - hints = _c.addrinfo(ai_family = family, - ai_socktype = SOCK_DGRAM, # dummy - ai_flags = AI_PASSIVE) - res = _c.addrinfo_ptr() - error = _c.getaddrinfo(None, "0", byref(hints), byref(res)) - if error: - raise GAIError(error) - try: - info = res.contents - if info.ai_next: - raise RSocketError("wildcard resolved to " - "multiple addresses") - return make_address(info.ai_addr, info.ai_addrlen, result) - finally: - _c.freeaddrinfo(res) + info = getaddrinfo(None, "0", + family=family, + socktype=SOCK_DGRAM, # dummy + flags=AI_PASSIVE, + address_to_fill=result) + if len(info) > 1: + raise RSocketError("wildcard resolved to " + "multiple addresses") + return info[0][4] # IPv4 also supports the special name "". if name == '': @@ -127,17 +121,8 @@ result) # generic host name to IP conversion - hints = _c.addrinfo(ai_family = family) - res = _c.addrinfo_ptr() - error = _c.getaddrinfo(name, None, byref(hints), byref(res)) - # PLAT EAI_NONAME - if error: - raise GAIError(error) - try: - info = res.contents - return make_address(info.ai_addr, info.ai_addrlen, result) - finally: - _c.freeaddrinfo(res) + info = getaddrinfo(name, None, family=family, address_to_fill=result) + return info[0][4] class IPAddress(Address): """AF_INET and AF_INET6 addresses""" @@ -146,13 +131,8 @@ # Create a string object representing an IP address. # For IPv4 this is always a string of the form 'dd.dd.dd.dd' # (with variable size numbers). - buf = create_string_buffer(NI_MAXHOST) - error = _c.getnameinfo(byref(self.addr), self.addrlen, - buf, NI_MAXHOST, - None, 0, NI_NUMERICHOST) - if error: - raise GAIError(error) - return buf.value + host, serv = getnameinfo(self, NI_NUMERICHOST | NI_NUMERICSERV) + return host # ____________________________________________________________ @@ -895,11 +875,11 @@ makeipaddr(name, result) return result -def gethost_common(hostname, hostent, addr): +def gethost_common(hostname, hostent, addr=None): if not hostent: raise HSocketError(hostname) - family = addr.family - if hostent.contents.h_addrtype != family: + family = hostent.contents.h_addrtype + if addr is not None and addr.family != family: raise CSocketError(_c.EAFNOSUPPORT) aliases = [] @@ -944,7 +924,8 @@ return gethost_common(ip, hostent, addr) def getaddrinfo(host, port_or_service, - family=AF_UNSPEC, socktype=0, proto=0, flags=0): + family=AF_UNSPEC, socktype=0, proto=0, flags=0, + address_to_fill=None): # port_or_service is a string, not an int (but try str(port_number)). assert port_or_service is None or isinstance(port_or_service, str) hints = _c.addrinfo(ai_family = family, @@ -961,7 +942,7 @@ p = res while p: info = p.contents - addr = make_address(info.ai_addr, info.ai_addrlen) + addr = make_address(info.ai_addr, info.ai_addrlen, address_to_fill) canonname = info.ai_canonname if canonname is None: canonname = "" @@ -1060,3 +1041,17 @@ if timeout < 0.0: timeout = -1.0 defaults.timeout = timeout + +# _______________________________________________________________ +# +# Patch module, for platforms without getaddrinfo / getnameinfo +# + +if not getattr(_c, 'getaddrinfo', None): + from pypy.rlib.getaddrinfo import getaddrinfo + from pypy.rlib.getaddrinfo import GAIError_getmsg + GAIError.get_msg = GAIError_getmsg + +if not getattr(_c, 'getnameinfo', None): + from pypy.rlib.getnameinfo import getnameinfo + from pypy.rlib.getnameinfo import NI_NUMERICHOST, NI_NUMERICSERV Modified: pypy/dist/pypy/rlib/test/test_rsocket.py ============================================================================== --- pypy/dist/pypy/rlib/test/test_rsocket.py (original) +++ pypy/dist/pypy/rlib/test/test_rsocket.py Tue Apr 17 00:59:32 2007 @@ -180,6 +180,7 @@ addr.get_port() == 80): found = True assert found, lst + py.test.raises(GAIError, getaddrinfo, 'www.very-invalidaddress.com', None) def test_getaddrinfo_snake(): lst = getaddrinfo('snake.cs.uni-duesseldorf.de', None) @@ -190,6 +191,24 @@ found = True assert found, lst +def test_getaddrinfo_reverse_snake(): + lst = getaddrinfo('134.99.112.214', None, flags=AI_CANONNAME) + assert isinstance(lst, list) + found = False + for family, socktype, protocol, canonname, addr in lst: + if canonname == 'snake.cs.uni-duesseldorf.de': + found = True + assert found, lst + +def test_getaddrinfo_reverse_lookup_fail(): + lst = getaddrinfo('1.2.3.4', None, flags=AI_CANONNAME) + assert isinstance(lst, list) + found = False + for family, socktype, protocol, canonname, addr in lst: + if canonname == '1.2.3.4': + found = True + assert found, lst + def test_connect_ex(): s = RSocket() err = s.connect_ex(s.getsockname()) # should not work From afa at codespeak.net Tue Apr 17 01:19:54 2007 From: afa at codespeak.net (afa at codespeak.net) Date: Tue, 17 Apr 2007 01:19:54 +0200 (CEST) Subject: [pypy-svn] r42109 - in pypy/dist/pypy/rlib: . test Message-ID: <20070416231954.CCE2180BD@code0.codespeak.net> Author: afa Date: Tue Apr 17 01:19:54 2007 New Revision: 42109 Modified: pypy/dist/pypy/rlib/getaddrinfo.py pypy/dist/pypy/rlib/test/test_rsocket.py Log: CPython2.3 on Windows did perform a reverse DNS lookup in getaddrinfo. Implement 2.4 behaviour, which is consistent with Unix platforms. Modified: pypy/dist/pypy/rlib/getaddrinfo.py ============================================================================== --- pypy/dist/pypy/rlib/getaddrinfo.py (original) +++ pypy/dist/pypy/rlib/getaddrinfo.py Tue Apr 17 01:19:54 2007 @@ -164,13 +164,17 @@ sizeof(_c.sockaddr_in), address_to_fill) return [(_c.AF_INET, socktype, protocol, None, addr)] else: - # XXX getaddrinfo() is a name->address translation function, - # and it looks strange that we do addr->name translation here. sin = _c.sockaddr_in(sin_family=_c.AF_INET, sin_port=port) sin.sin_addr.s_addr = packedaddr - canonname = get_name(hostname, sin.sin_addr, sizeof(_c.in_addr)) + # getaddrinfo() is a name->address translation function, + # and it looks strange that we do addr->name translation here. + # This is what python2.3 did on Windows: + # if sys.version < (2, 4): + # canonname = get_name(hostname, sin.sin_addr, + # sizeof(_c.in_addr)) + canonname = hostname addr = make_address(cast(pointer(sin), POINTER(_c.sockaddr)), sizeof(_c.sockaddr_in), address_to_fill) Modified: pypy/dist/pypy/rlib/test/test_rsocket.py ============================================================================== --- pypy/dist/pypy/rlib/test/test_rsocket.py (original) +++ pypy/dist/pypy/rlib/test/test_rsocket.py Tue Apr 17 01:19:54 2007 @@ -191,21 +191,15 @@ found = True assert found, lst -def test_getaddrinfo_reverse_snake(): +def test_getaddrinfo_no_reverse_lookup(): + # It seems that getaddrinfo never runs a reverse lookup on Linux. + # Python2.3 on Windows returns the hostname. lst = getaddrinfo('134.99.112.214', None, flags=AI_CANONNAME) assert isinstance(lst, list) found = False for family, socktype, protocol, canonname, addr in lst: - if canonname == 'snake.cs.uni-duesseldorf.de': - found = True - assert found, lst - -def test_getaddrinfo_reverse_lookup_fail(): - lst = getaddrinfo('1.2.3.4', None, flags=AI_CANONNAME) - assert isinstance(lst, list) - found = False - for family, socktype, protocol, canonname, addr in lst: - if canonname == '1.2.3.4': + assert canonname != 'snake.cs.uni-duesseldorf.de' + if addr.get_host() == '134.99.112.214': found = True assert found, lst From afa at codespeak.net Tue Apr 17 01:50:15 2007 From: afa at codespeak.net (afa at codespeak.net) Date: Tue, 17 Apr 2007 01:50:15 +0200 (CEST) Subject: [pypy-svn] r42111 - pypy/dist/pypy/rlib Message-ID: <20070416235015.E0C2480CC@code0.codespeak.net> Author: afa Date: Tue Apr 17 01:50:15 2007 New Revision: 42111 Modified: pypy/dist/pypy/rlib/_rsocket_ctypes.py pypy/dist/pypy/rlib/rsocket.py Log: rsocket progress on Windows: implement timeouts and _select() Modified: pypy/dist/pypy/rlib/_rsocket_ctypes.py ============================================================================== --- pypy/dist/pypy/rlib/_rsocket_ctypes.py (original) +++ pypy/dist/pypy/rlib/_rsocket_ctypes.py Tue Apr 17 01:50:15 2007 @@ -7,7 +7,8 @@ from pypy.rpython.rctypes.aerrno import geterrno from ctypes import c_ushort, c_int, c_uint, c_char_p, c_void_p, c_char, c_ubyte -from ctypes import c_short, POINTER, ARRAY, cdll, sizeof, SetPointerType +from ctypes import c_short, c_long, c_ulong +from ctypes import POINTER, ARRAY, cdll, sizeof, SetPointerType from pypy.rlib.rarithmetic import intmask, r_uint # Also not used here, but exported for other code. @@ -52,12 +53,14 @@ class CConfig: _header_ = HEADER + COND_HEADER # constants + linux = ctypes_platform.Defined('linux') + MS_WINDOWS = ctypes_platform.Defined('_WIN32') + O_NONBLOCK = ctypes_platform.DefinedConstantInteger('O_NONBLOCK') F_GETFL = ctypes_platform.DefinedConstantInteger('F_GETFL') F_SETFL = ctypes_platform.DefinedConstantInteger('F_SETFL') + FIONBIO = ctypes_platform.DefinedConstantInteger('FIONBIO') - linux = ctypes_platform.Defined('linux') - MS_WINDOWS = ctypes_platform.Defined('_WIN32') INVALID_SOCKET = ctypes_platform.DefinedConstantInteger('INVALID_SOCKET') INET_ADDRSTRLEN = ctypes_platform.DefinedConstantInteger('INET_ADDRSTRLEN') INET6_ADDRSTRLEN= ctypes_platform.DefinedConstantInteger('INET6_ADDRSTRLEN') @@ -237,6 +240,13 @@ ('events', c_short), ('revents', c_short)]) +CConfig.timeval = ctypes_platform.Struct('struct timeval', + [('tv_sec', c_long), + ('tv_usec', c_long)]) +CConfig.fd_set = ctypes_platform.Struct('struct fd_set', + [('fd_count', c_uint), + ('fd_array', c_uint * 64)]) # XXX FD_SETSIZE + if _MS_WINDOWS: CConfig.WSAData = ctypes_platform.Struct('struct WSAData', [('wVersion', c_ushort), @@ -279,6 +289,7 @@ O_NONBLOCK = cConfig.O_NONBLOCK F_GETFL = cConfig.F_GETFL F_SETFL = cConfig.F_SETFL +FIONBIO = cConfig.FIONBIO INET_ADDRSTRLEN = cConfig.INET_ADDRSTRLEN INET6_ADDRSTRLEN = cConfig.INET6_ADDRSTRLEN POLLIN = cConfig.POLLIN @@ -293,7 +304,7 @@ if MS_WINDOWS: def invalid_socket(fd): - return fd == INVALID_SOCKET + return c_uint(fd).value == INVALID_SOCKET INVALID_SOCKET = cConfig.INVALID_SOCKET else: def invalid_socket(fd): @@ -319,6 +330,8 @@ if _POSIX: nfds_t = cConfig.nfds_t pollfd = cConfig.pollfd +timeval = cConfig.timeval +fd_set = cConfig.fd_set c_int_size = sizeof(c_int) SetPointerType(addrinfo_ptr, addrinfo) @@ -517,6 +530,12 @@ socketpair.argtypes = [c_int, c_int, c_int, POINTER(socketpair_t)] socketpair.restype = c_int +if _MS_WINDOWS: + ioctlsocket = socketdll.ioctlsocket + ioctlsocket.argtypes = [c_int, c_long, POINTER(c_ulong)] + ioctlsocket.restype = c_int + + shutdown = socketdll.shutdown shutdown.argtypes = [c_int, c_int] shutdown.restype = c_int @@ -525,6 +544,11 @@ poll = socketdll.poll poll.argtypes = [POINTER(pollfd), nfds_t, c_int] poll.restype = c_int +select = socketdll.select +select.argtypes = [c_int, + POINTER(fd_set), POINTER(fd_set), POINTER(fd_set), + POINTER(timeval)] +select.restype = c_int if MS_WINDOWS: WSAData = cConfig.WSAData Modified: pypy/dist/pypy/rlib/rsocket.py ============================================================================== --- pypy/dist/pypy/rlib/rsocket.py (original) +++ pypy/dist/pypy/rlib/rsocket.py Tue Apr 17 01:50:15 2007 @@ -13,8 +13,8 @@ from pypy.rlib.objectmodel import instantiate from pypy.rlib import _rsocket_ctypes as _c -from ctypes import cast, POINTER, c_char, c_char_p, pointer, byref, c_void_p -from ctypes import create_string_buffer, sizeof, cast +from ctypes import c_char, c_ulong, c_char_p, c_void_p +from ctypes import POINTER, pointer, byref, create_string_buffer, sizeof, cast from pypy.rpython.rctypes.astruct import offsetof from pypy.rlib.rarithmetic import intmask @@ -471,35 +471,62 @@ def __del__(self): self.close() - def _setblocking(self, block): - # PLAT various methods on other platforms - # XXX Windows missing - delay_flag = _c.fcntl(self.fd, _c.F_GETFL, 0) - if block: - delay_flag &= ~_c.O_NONBLOCK - else: - delay_flag |= _c.O_NONBLOCK - _c.fcntl(self.fd, _c.F_SETFL, delay_flag) - - def _select(self, for_writing): - """Returns 0 when reading/writing is possible, - 1 when timing out and -1 on error.""" - if self.timeout <= 0.0 or self.fd < 0: - # blocking I/O or no socket. + if hasattr(_c, 'fcntl'): + def _setblocking(self, block): + delay_flag = _c.fcntl(self.fd, _c.F_GETFL, 0) + if block: + delay_flag &= ~_c.O_NONBLOCK + else: + delay_flag |= _c.O_NONBLOCK + _c.fcntl(self.fd, _c.F_SETFL, delay_flag) + elif hasattr(_c, 'ioctlsocket'): + def _setblocking(self, block): + flag = c_ulong(not block) + _c.ioctlsocket(self.fd, _c.FIONBIO, byref(flag)) + + if hasattr(_c, 'poll'): + def _select(self, for_writing): + """Returns 0 when reading/writing is possible, + 1 when timing out and -1 on error.""" + if self.timeout <= 0.0 or self.fd < 0: + # blocking I/O or no socket. + return 0 + pollfd = _c.pollfd() + pollfd.fd = self.fd + if for_writing: + pollfd.events = _c.POLLOUT + else: + pollfd.events = _c.POLLIN + timeout = int(self.timeout * 1000.0 + 0.5) + n = _c.poll(byref(pollfd), 1, timeout) + if n < 0: + return -1 + if n == 0: + return 1 return 0 - pollfd = _c.pollfd() - pollfd.fd = self.fd - if for_writing: - pollfd.events = _c.POLLOUT - else: - pollfd.events = _c.POLLIN - timeout = int(self.timeout * 1000.0 + 0.5) - n = _c.poll(byref(pollfd), 1, timeout) - if n < 0: - return -1 - if n == 0: - return 1 - return 0 + else: + # Version witout poll(): use select() + def _select(self, for_writing): + """Returns 0 when reading/writing is possible, + 1 when timing out and -1 on error.""" + if self.timeout <= 0.0 or self.fd < 0: + # blocking I/O or no socket. + return 0 + tv = _c.timeval(tv_sec=int(self.timeout), + tv_usec=int((self.timeout-int(self.timeout)) + * 1000000)) + fds = _c.fd_set(fd_count=1) + fds.fd_array[0] = self.fd + if for_writing: + n = _c.select(self.fd + 1, None, byref(fds), None, byref(tv)) + else: + n = _c.select(self.fd + 1, byref(fds), None, None, byref(tv)) + if n < 0: + return -1 + if n == 0: + return 1 + return 0 + def error_handler(self): return last_error() From afa at codespeak.net Tue Apr 17 01:54:23 2007 From: afa at codespeak.net (afa at codespeak.net) Date: Tue, 17 Apr 2007 01:54:23 +0200 (CEST) Subject: [pypy-svn] r42112 - pypy/dist/pypy/rlib Message-ID: <20070416235423.7098880CE@code0.codespeak.net> Author: afa Date: Tue Apr 17 01:54:23 2007 New Revision: 42112 Modified: pypy/dist/pypy/rlib/_rsocket_ctypes.py Log: Argh. fd_set structure exists only on win32. Modified: pypy/dist/pypy/rlib/_rsocket_ctypes.py ============================================================================== --- pypy/dist/pypy/rlib/_rsocket_ctypes.py (original) +++ pypy/dist/pypy/rlib/_rsocket_ctypes.py Tue Apr 17 01:54:23 2007 @@ -243,9 +243,12 @@ CConfig.timeval = ctypes_platform.Struct('struct timeval', [('tv_sec', c_long), ('tv_usec', c_long)]) -CConfig.fd_set = ctypes_platform.Struct('struct fd_set', - [('fd_count', c_uint), - ('fd_array', c_uint * 64)]) # XXX FD_SETSIZE + +if _MS_WINDOWS: + CConfig.fd_set = ctypes_platform.Struct('struct fd_set', + [('fd_count', c_uint), + # XXX use FD_SETSIZE + ('fd_array', c_uint * 64)]) if _MS_WINDOWS: CConfig.WSAData = ctypes_platform.Struct('struct WSAData', @@ -331,7 +334,8 @@ nfds_t = cConfig.nfds_t pollfd = cConfig.pollfd timeval = cConfig.timeval -fd_set = cConfig.fd_set +if MS_WINDOWS: + fd_set = cConfig.fd_set c_int_size = sizeof(c_int) SetPointerType(addrinfo_ptr, addrinfo) @@ -544,11 +548,12 @@ poll = socketdll.poll poll.argtypes = [POINTER(pollfd), nfds_t, c_int] poll.restype = c_int -select = socketdll.select -select.argtypes = [c_int, - POINTER(fd_set), POINTER(fd_set), POINTER(fd_set), - POINTER(timeval)] -select.restype = c_int +elif MS_WINDOWS: + select = socketdll.select + select.argtypes = [c_int, + POINTER(fd_set), POINTER(fd_set), POINTER(fd_set), + POINTER(timeval)] + select.restype = c_int if MS_WINDOWS: WSAData = cConfig.WSAData From afa at codespeak.net Tue Apr 17 02:02:29 2007 From: afa at codespeak.net (afa at codespeak.net) Date: Tue, 17 Apr 2007 02:02:29 +0200 (CEST) Subject: [pypy-svn] r42113 - pypy/dist/pypy/rlib/test Message-ID: <20070417000229.CCC7280CE@code0.codespeak.net> Author: afa Date: Tue Apr 17 02:02:29 2007 New Revision: 42113 Modified: pypy/dist/pypy/rlib/test/test_rsocket.py Log: Skip some rsocket tests not relevant on win32 Modified: pypy/dist/pypy/rlib/test/test_rsocket.py ============================================================================== --- pypy/dist/pypy/rlib/test/test_rsocket.py (original) +++ pypy/dist/pypy/rlib/test/test_rsocket.py Tue Apr 17 02:02:29 2007 @@ -1,4 +1,4 @@ -import py, errno +import py, errno, sys from pypy.rlib import rsocket from pypy.rlib.rsocket import * @@ -20,6 +20,8 @@ assert res == "" def test_unix_addr(): + if getattr(rsocket, 'AF_UNIX', None) is None: + py.test.skip('AF_UNIX not supported.') a = UNIXAddress("/tmp/socketname") assert a.get_path() == "/tmp/socketname" @@ -42,6 +44,8 @@ assert a.get_host() == "127.0.0.1" def test_socketpair(): + if sys.platform == "win32": + py.test.skip('No socketpair on Windows') s1, s2 = socketpair() s1.send('?') buf = s2.recv(100) @@ -238,6 +242,8 @@ assert reuseptr[0] != 0 def test_dup(): + if sys.platform == "win32": + skip("dup does not work on Windows") s = RSocket(AF_INET, SOCK_STREAM) s.setsockopt_int(SOL_SOCKET, SO_REUSEADDR, 1) s.bind(INETAddress('localhost', 50007)) From afa at codespeak.net Tue Apr 17 13:51:29 2007 From: afa at codespeak.net (afa at codespeak.net) Date: Tue, 17 Apr 2007 13:51:29 +0200 (CEST) Subject: [pypy-svn] r42123 - pypy/dist/pypy/rlib/test Message-ID: <20070417115129.772C5809D@code0.codespeak.net> Author: afa Date: Tue Apr 17 13:51:28 2007 New Revision: 42123 Modified: pypy/dist/pypy/rlib/test/test_rsocket.py Log: Adapt rsocket tests for win32: - windows often returns EWOULDBLOCK errors - local sockets seem to have a small buffer Modified: pypy/dist/pypy/rlib/test/test_rsocket.py ============================================================================== --- pypy/dist/pypy/rlib/test/test_rsocket.py (original) +++ pypy/dist/pypy/rlib/test/test_rsocket.py Tue Apr 17 13:51:28 2007 @@ -150,7 +150,7 @@ s2 = RSocket(AF_INET, SOCK_STREAM) s2.setblocking(False) err = py.test.raises(CSocketError, s2.connect, addr) - assert err.value.errno == errno.EINPROGRESS + assert err.value.errno in (errno.EINPROGRESS, errno.EWOULDBLOCK) s1, addr2 = sock.accept() s1.setblocking(False) @@ -165,11 +165,16 @@ buf = s2.recv(100) assert buf == '?' err = py.test.raises(CSocketError, s1.recv, 5000) - assert err.value.errno == errno.EAGAIN + assert err.value.errno in (errno.EAGAIN, errno.EWOULDBLOCK) count = s2.send('x'*500000) assert 1 <= count <= 500000 - buf = s1.recv(500100) - assert buf == 'x'*count + while count: # Recv may return less than requested + buf = s1.recv(count + 100) + assert len(buf) <= count + assert buf.count('x') == len(buf) + count -= len(buf) + # Check that everything has been read + err = py.test.raises(CSocketError, s1.recv, 5000) s1.close() s2.close() @@ -209,7 +214,7 @@ def test_connect_ex(): s = RSocket() - err = s.connect_ex(s.getsockname()) # should not work + err = s.connect_ex(INETAddress('0.0.0.0', 0)) # should not work assert err in (errno.ECONNREFUSED, errno.EADDRNOTAVAIL) From fijal at codespeak.net Tue Apr 17 17:55:07 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 17 Apr 2007 17:55:07 +0200 (CEST) Subject: [pypy-svn] r42131 - pypy/dist/pypy/objspace/std Message-ID: <20070417155507.20B6A80A4@code0.codespeak.net> Author: fijal Date: Tue Apr 17 17:55:06 2007 New Revision: 42131 Modified: pypy/dist/pypy/objspace/std/formatting.py pypy/dist/pypy/objspace/std/stringobject.py pypy/dist/pypy/objspace/std/unicodeobject.py Log: Use space.w_None instead of real None, bad fijal. Modified: pypy/dist/pypy/objspace/std/formatting.py ============================================================================== --- pypy/dist/pypy/objspace/std/formatting.py (original) +++ pypy/dist/pypy/objspace/std/formatting.py Tue Apr 17 17:55:06 2007 @@ -419,7 +419,7 @@ return self.fmt[i:j] -def format(space, w_fmt, w_values, w_valuedict=None, do_unicode=False): +def format(space, w_fmt, w_values, w_valuedict, do_unicode=False): vb = ValueGetter(space, w_values, w_valuedict) if not do_unicode: return _format(space, space.str_w(w_fmt), vb) @@ -515,7 +515,7 @@ def check_consumed(self): space = self.space if (self._valueindex < len(self.values_w) and - self.w_valuedict is None): + space.is_w(self.w_valuedict, space.w_None)): raise OperationError(space.w_TypeError, space.wrap('not all arguments converted ' 'during string formatting')) Modified: pypy/dist/pypy/objspace/std/stringobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/stringobject.py (original) +++ pypy/dist/pypy/objspace/std/stringobject.py Tue Apr 17 17:55:06 2007 @@ -918,7 +918,7 @@ # (values is of a mapping type) def mod__String_ANY(space, w_format, w_values): if space.is_true(space.isinstance(w_values, space.w_tuple)): - return format(space, w_format, w_values) + return format(space, w_format, w_values, space.w_None) else: # we check directly for dict to avoid obscure checking # in simplest case @@ -929,7 +929,7 @@ space.newtuple([w_values]), w_values) else: return format(space, w_format, - space.newtuple([w_values]), None) + space.newtuple([w_values]), space.w_None) # register all methods from pypy.objspace.std import stringtype Modified: pypy/dist/pypy/objspace/std/unicodeobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/unicodeobject.py (original) +++ pypy/dist/pypy/objspace/std/unicodeobject.py Tue Apr 17 17:55:06 2007 @@ -1036,7 +1036,7 @@ def mod__Unicode_ANY(space, w_format, w_values): if space.is_true(space.isinstance(w_values, space.w_tuple)): - return format(space, w_format, w_values, do_unicode=True) + return format(space, w_format, w_values, space.w_None, do_unicode=True) else: # we check directly for dict to avoid obscure checking # in simplest case @@ -1048,7 +1048,7 @@ do_unicode=True) else: return format(space, w_format, - space.newtuple([w_values]), None, + space.newtuple([w_values]), space.w_None, do_unicode=True) From afa at codespeak.net Tue Apr 17 20:36:01 2007 From: afa at codespeak.net (afa at codespeak.net) Date: Tue, 17 Apr 2007 20:36:01 +0200 (CEST) Subject: [pypy-svn] r42135 - pypy/dist/pypy/rlib/test Message-ID: <20070417183601.57734809E@code0.codespeak.net> Author: afa Date: Tue Apr 17 20:36:00 2007 New Revision: 42135 Modified: pypy/dist/pypy/rlib/test/test_rsocket.py Log: rsocket intermittent failure: win32 sockets seem to need a few cycles to transfer data Modified: pypy/dist/pypy/rlib/test/test_rsocket.py ============================================================================== --- pypy/dist/pypy/rlib/test/test_rsocket.py (original) +++ pypy/dist/pypy/rlib/test/test_rsocket.py Tue Apr 17 20:36:00 2007 @@ -162,6 +162,8 @@ assert err in (0, errno.EISCONN) s1.send('?') + import time + time.sleep(0.01) # Windows needs some time to transfer data buf = s2.recv(100) assert buf == '?' err = py.test.raises(CSocketError, s1.recv, 5000) From afa at codespeak.net Tue Apr 17 21:46:42 2007 From: afa at codespeak.net (afa at codespeak.net) Date: Tue, 17 Apr 2007 21:46:42 +0200 (CEST) Subject: [pypy-svn] r42136 - in pypy/dist/pypy: module/rsocket module/rsocket/test rlib rlib/test Message-ID: <20070417194642.ECFFD809B@code0.codespeak.net> Author: afa Date: Tue Apr 17 21:46:41 2007 New Revision: 42136 Modified: pypy/dist/pypy/module/rsocket/interp_socket.py pypy/dist/pypy/module/rsocket/test/test_sock_app.py pypy/dist/pypy/rlib/rsocket.py pypy/dist/pypy/rlib/test/test_rsocket.py Log: rsocket progress on win32: hide socket.dup, add implementation of inet_aton 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 Tue Apr 17 21:46:41 2007 @@ -474,6 +474,11 @@ recv recvfrom send sendall sendto setblocking setsockopt settimeout shutdown _reuse _drop """.split() +# Remove non-implemented methods +for name in ('dup',): + if not hasattr(RSocket, name): + socketmethodnames.remove(name) + socketmethods = {} for methodname in socketmethodnames: method = getattr(W_RSocket, methodname + '_w') Modified: pypy/dist/pypy/module/rsocket/test/test_sock_app.py ============================================================================== --- pypy/dist/pypy/module/rsocket/test/test_sock_app.py (original) +++ pypy/dist/pypy/module/rsocket/test/test_sock_app.py Tue Apr 17 21:46:41 2007 @@ -377,6 +377,8 @@ def test_dup(self): import _socket as socket + if not hasattr(socket.socket, 'dup'): + skip('No dup() on this platform') s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) s.bind(('localhost', 50007)) Modified: pypy/dist/pypy/rlib/rsocket.py ============================================================================== --- pypy/dist/pypy/rlib/rsocket.py (original) +++ pypy/dist/pypy/rlib/rsocket.py Tue Apr 17 21:46:41 2007 @@ -613,14 +613,15 @@ return _c.geterrno() return res - def dup(self, SocketClass=None): - if SocketClass is None: - SocketClass = RSocket - fd = _c.dup(self.fd) - if fd < 0: - raise self.error_handler() - return make_socket(fd, self.family, self.type, self.proto, - SocketClass=SocketClass) + if hasattr(_c, 'dup'): + def dup(self, SocketClass=None): + if SocketClass is None: + SocketClass = RSocket + fd = _c.dup(self.fd) + if fd < 0: + raise self.error_handler() + return make_socket(fd, self.family, self.type, self.proto, + SocketClass=SocketClass) def fileno(self): fd = self.fd @@ -1011,13 +1012,25 @@ raise GAIError(error) return host.value, serv.value -def inet_aton(ip): - "IPv4 dotted string -> packed 32-bits string" - buf = create_string_buffer(sizeof(_c.in_addr)) - if _c.inet_aton(ip, cast(buf, POINTER(_c.in_addr))): +if hasattr(_c, 'inet_aton'): + def inet_aton(ip): + "IPv4 dotted string -> packed 32-bits string" + buf = create_string_buffer(sizeof(_c.in_addr)) + if _c.inet_aton(ip, cast(buf, POINTER(_c.in_addr))): + return buf.raw + else: + raise RSocketError("illegal IP address string passed to inet_aton") +else: + def inet_aton(ip): + "IPv4 dotted string -> packed 32-bits string" + if ip == "255.255.255.255": + return "\xff\xff\xff\xff" + packed_addr = _c.inet_addr(ip) + if _c.c_long(packed_addr).value == INADDR_NONE: + raise RSocketError("illegal IP address string passed to inet_aton") + buf = copy_buffer(cast(pointer(c_ulong(packed_addr)), + POINTER(c_char)), 4) return buf.raw - else: - raise RSocketError("illegal IP address string passed to inet_aton") def inet_ntoa(packed): "packet 32-bits string -> IPv4 dotted string" Modified: pypy/dist/pypy/rlib/test/test_rsocket.py ============================================================================== --- pypy/dist/pypy/rlib/test/test_rsocket.py (original) +++ pypy/dist/pypy/rlib/test/test_rsocket.py Tue Apr 17 21:46:41 2007 @@ -257,6 +257,14 @@ s2 = s.dup() assert s.fileno() != s2.fileno() assert s.getsockname().eq(s2.getsockname()) + +def test_inet_aton(): + assert inet_aton('1.2.3.4') == '\x01\x02\x03\x04' + assert inet_aton('127.0.0.1') == '\x7f\x00\x00\x01' + tests = ["127.0.0.256", "127.0.0.255555555555555555", "127.2b.0.0", + "127.2.0.0.1", "127.2..0"] + for ip in tests: + py.test.raises(SocketError, inet_aton, ip) class TestTCP: PORT = 50007 From afa at codespeak.net Tue Apr 17 22:08:09 2007 From: afa at codespeak.net (afa at codespeak.net) Date: Tue, 17 Apr 2007 22:08:09 +0200 (CEST) Subject: [pypy-svn] r42137 - in pypy/dist/pypy: module/rsocket module/rsocket/test rlib Message-ID: <20070417200809.9441B809C@code0.codespeak.net> Author: afa Date: Tue Apr 17 22:08:09 2007 New Revision: 42137 Modified: pypy/dist/pypy/module/rsocket/__init__.py pypy/dist/pypy/module/rsocket/test/test_sock_app.py pypy/dist/pypy/rlib/rsocket.py Log: Hide socket.inet_pton (inet_ntop does exist and works) on win32 + win32 may return errno.WSAEINVAL instead of EINVAL Only one failing test in rsocket module! But many functions are not tested at all... Modified: pypy/dist/pypy/module/rsocket/__init__.py ============================================================================== --- pypy/dist/pypy/module/rsocket/__init__.py (original) +++ pypy/dist/pypy/module/rsocket/__init__.py Tue Apr 17 22:08:09 2007 @@ -27,6 +27,9 @@ getaddrinfo getnameinfo getdefaulttimeout setdefaulttimeout """.split(): + + if name in ('inet_pton',) and not hasattr(rsocket, name): + continue Module.interpleveldefs[name] = 'interp_func.%s' % (name, ) Modified: pypy/dist/pypy/module/rsocket/test/test_sock_app.py ============================================================================== --- pypy/dist/pypy/module/rsocket/test/test_sock_app.py (original) +++ pypy/dist/pypy/module/rsocket/test/test_sock_app.py Tue Apr 17 22:08:09 2007 @@ -131,7 +131,7 @@ def test_pton_ntop_ipv4(): if not hasattr(socket, 'inet_pton'): - py.test.skip('No socket.(inet_pton|inet_ntop) on this platform') + py.test.skip('No socket.inet_pton on this platform') tests = [ ("123.45.67.89", "\x7b\x2d\x43\x59"), ("0.0.0.0", "\x00" * 4), @@ -147,7 +147,7 @@ def test_ntop_ipv6(): if not hasattr(socket, 'inet_pton'): - py.test.skip('No socket.(inet_pton|inet_ntop) on this platform') + py.test.skip('No socket.inet_pton on this platform') if not socket.has_ipv6: py.test.skip("No IPv6 on this platform") tests = [ @@ -168,7 +168,7 @@ def test_pton_ipv6(): if not hasattr(socket, 'inet_pton'): - py.test.skip('No socket.(inet_pton|inet_ntop) on this platform') + py.test.skip('No socket.inet_pton on this platform') if not socket.has_ipv6: py.test.skip("No IPv6 on this platform") tests = [ @@ -256,6 +256,8 @@ def test_pton_exceptions(self): import _socket + if not hasattr(_socket, 'inet_pton'): + skip('No socket.inet_pton on this platform') tests = [ (_socket.AF_INET + _socket.AF_INET6, ""), (_socket.AF_INET, "127.0.0.256"), @@ -455,6 +457,7 @@ s.accept() except Exception, e: assert len(e.args) == 2 - assert e.args[0] == errno.EINVAL + # error is EINVAL, or WSAEINVAL on Windows + assert errno.errorcode[e.args[0]].endswith("EINVAL") assert isinstance(e.args[1], str) Modified: pypy/dist/pypy/rlib/rsocket.py ============================================================================== --- pypy/dist/pypy/rlib/rsocket.py (original) +++ pypy/dist/pypy/rlib/rsocket.py Tue Apr 17 22:08:09 2007 @@ -1040,22 +1040,23 @@ buf.raw = packed return _c.inet_ntoa(cast(buf, POINTER(_c.in_addr)).contents) -def inet_pton(family, ip): - "human-readable string -> packed string" - if family == AF_INET: - size = sizeof(_c.in_addr) - elif AF_INET6 is not None and family == AF_INET6: - size = sizeof(_c.in6_addr) - else: - raise RSocketError("unknown address family") - buf = create_string_buffer(size) - res = _c.inet_pton(family, ip, cast(buf, c_void_p)) - if res < 0: - raise last_error() - elif res == 0: - raise RSocketError("illegal IP address string passed to inet_pton") - else: - return buf.raw +if hasattr(_c, 'inet_pton'): + def inet_pton(family, ip): + "human-readable string -> packed string" + if family == AF_INET: + size = sizeof(_c.in_addr) + elif AF_INET6 is not None and family == AF_INET6: + size = sizeof(_c.in6_addr) + else: + raise RSocketError("unknown address family") + buf = create_string_buffer(size) + res = _c.inet_pton(family, ip, cast(buf, c_void_p)) + if res < 0: + raise last_error() + elif res == 0: + raise RSocketError("illegal IP address string passed to inet_pton") + else: + return buf.raw def inet_ntop(family, packed): "packed string -> human-readable string" From afa at codespeak.net Tue Apr 17 22:13:14 2007 From: afa at codespeak.net (afa at codespeak.net) Date: Tue, 17 Apr 2007 22:13:14 +0200 (CEST) Subject: [pypy-svn] r42138 - pypy/dist/pypy/module/rsocket/test Message-ID: <20070417201314.DEDE38096@code0.codespeak.net> Author: afa Date: Tue Apr 17 22:13:13 2007 New Revision: 42138 Modified: pypy/dist/pypy/module/rsocket/test/test_sock_app.py Log: This test should not run on win32, after all. Modified: pypy/dist/pypy/module/rsocket/test/test_sock_app.py ============================================================================== --- pypy/dist/pypy/module/rsocket/test/test_sock_app.py (original) +++ pypy/dist/pypy/module/rsocket/test/test_sock_app.py Tue Apr 17 22:13:13 2007 @@ -301,6 +301,8 @@ def test_socket_close_error(self): import _socket, os + if os.name == 'nt': + skip("Windows sockets are not files") s = _socket.socket(_socket.AF_INET, _socket.SOCK_STREAM, 0) os.close(s.fileno()) raises(_socket.error, s.close) From afa at codespeak.net Tue Apr 17 22:41:20 2007 From: afa at codespeak.net (afa at codespeak.net) Date: Tue, 17 Apr 2007 22:41:20 +0200 (CEST) Subject: [pypy-svn] r42139 - in pypy/dist/pypy: module/rsocket module/rsocket/test rlib Message-ID: <20070417204120.27474809B@code0.codespeak.net> Author: afa Date: Tue Apr 17 22:41:19 2007 New Revision: 42139 Modified: pypy/dist/pypy/module/rsocket/__init__.py pypy/dist/pypy/module/rsocket/test/test_sock_app.py pypy/dist/pypy/rlib/rsocket.py Log: Correction of previous checkin: on win32 inet_ntop can detect correctly bogus args, but is unable to work in the normal case... :( Untested code never works! Modified: pypy/dist/pypy/module/rsocket/__init__.py ============================================================================== --- pypy/dist/pypy/module/rsocket/__init__.py (original) +++ pypy/dist/pypy/module/rsocket/__init__.py Tue Apr 17 22:41:19 2007 @@ -28,7 +28,8 @@ getdefaulttimeout setdefaulttimeout """.split(): - if name in ('inet_pton',) and not hasattr(rsocket, name): + if name in ('inet_pton', 'inet_ntop', + ) and not hasattr(rsocket, name): continue Module.interpleveldefs[name] = 'interp_func.%s' % (name, ) Modified: pypy/dist/pypy/module/rsocket/test/test_sock_app.py ============================================================================== --- pypy/dist/pypy/module/rsocket/test/test_sock_app.py (original) +++ pypy/dist/pypy/module/rsocket/test/test_sock_app.py Tue Apr 17 22:41:19 2007 @@ -247,6 +247,8 @@ def test_ntop_exceptions(self): import _socket + if not hasattr(_socket, 'inet_ntop'): + skip('No socket.inet_pton on this platform') for family, packed, exception in \ [(_socket.AF_INET + _socket.AF_INET6, "", _socket.error), (_socket.AF_INET, "a", ValueError), Modified: pypy/dist/pypy/rlib/rsocket.py ============================================================================== --- pypy/dist/pypy/rlib/rsocket.py (original) +++ pypy/dist/pypy/rlib/rsocket.py Tue Apr 17 22:41:19 2007 @@ -1058,25 +1058,26 @@ else: return buf.raw -def inet_ntop(family, packed): - "packed string -> human-readable string" - if family == AF_INET: - srcsize = sizeof(_c.in_addr) - dstsize = _c.INET_ADDRSTRLEN - elif AF_INET6 is not None and family == AF_INET6: - srcsize = sizeof(_c.in6_addr) - dstsize = _c.INET6_ADDRSTRLEN - else: - raise RSocketError("unknown address family") - if len(packed) != srcsize: - raise ValueError("packed IP wrong length for inet_ntop") - srcbuf = create_string_buffer(srcsize) - srcbuf.raw = packed - dstbuf = create_string_buffer(dstsize) - res = _c.inet_ntop(family, cast(srcbuf, c_void_p), dstbuf, dstsize) - if res is None: - raise last_error() - return res +if hasattr(_c, 'inet_ntop'): + def inet_ntop(family, packed): + "packed string -> human-readable string" + if family == AF_INET: + srcsize = sizeof(_c.in_addr) + dstsize = _c.INET_ADDRSTRLEN + elif AF_INET6 is not None and family == AF_INET6: + srcsize = sizeof(_c.in6_addr) + dstsize = _c.INET6_ADDRSTRLEN + else: + raise RSocketError("unknown address family") + if len(packed) != srcsize: + raise ValueError("packed IP wrong length for inet_ntop") + srcbuf = create_string_buffer(srcsize) + srcbuf.raw = packed + dstbuf = create_string_buffer(dstsize) + res = _c.inet_ntop(family, cast(srcbuf, c_void_p), dstbuf, dstsize) + if res is None: + raise last_error() + return res def setdefaulttimeout(timeout): if timeout < 0.0: From afa at codespeak.net Tue Apr 17 23:22:46 2007 From: afa at codespeak.net (afa at codespeak.net) Date: Tue, 17 Apr 2007 23:22:46 +0200 (CEST) Subject: [pypy-svn] r42140 - in pypy/dist/pypy: module/rsocket rlib Message-ID: <20070417212246.8656E809B@code0.codespeak.net> Author: afa Date: Tue Apr 17 23:22:45 2007 New Revision: 42140 Modified: pypy/dist/pypy/module/rsocket/__init__.py pypy/dist/pypy/rlib/rsocket.py Log: Call WSAStartup() on module import. Also hide two functions invalid on win32 Modified: pypy/dist/pypy/module/rsocket/__init__.py ============================================================================== --- pypy/dist/pypy/module/rsocket/__init__.py (original) +++ pypy/dist/pypy/module/rsocket/__init__.py Tue Apr 17 23:22:45 2007 @@ -17,6 +17,10 @@ 'socket' : 'interp_socket.W_RSocket', } + def startup(self, space): + from pypy.rlib.rsocket import rsocket_startup + rsocket_startup() + def buildloaders(cls): from pypy.rlib import rsocket for name in """ @@ -29,6 +33,7 @@ """.split(): if name in ('inet_pton', 'inet_ntop', + 'fromfd', 'socketpair', ) and not hasattr(rsocket, name): continue Modified: pypy/dist/pypy/rlib/rsocket.py ============================================================================== --- pypy/dist/pypy/rlib/rsocket.py (original) +++ pypy/dist/pypy/rlib/rsocket.py Tue Apr 17 23:22:45 2007 @@ -862,28 +862,30 @@ else: socketpair_default_family = AF_UNIX -def socketpair(family=socketpair_default_family, type=SOCK_STREAM, proto=0, - SocketClass=RSocket): - """socketpair([family[, type[, proto]]]) -> (socket object, socket object) - - Create a pair of socket objects from the sockets returned by the platform - socketpair() function. - The arguments are the same as for socket() except the default family is - AF_UNIX if defined on the platform; otherwise, the default is AF_INET. - """ - result = _c.socketpair_t() - res = _c.socketpair(family, type, proto, byref(result)) - if res < 0: - raise last_error() - return (make_socket(result[0], family, type, proto, SocketClass), - make_socket(result[1], family, type, proto, SocketClass)) +if hasattr(_c, 'socketpair'): + def socketpair(family=socketpair_default_family, type=SOCK_STREAM, proto=0, + SocketClass=RSocket): + """socketpair([family[, type[, proto]]]) -> (socket object, socket object) + + Create a pair of socket objects from the sockets returned by the platform + socketpair() function. + The arguments are the same as for socket() except the default family is + AF_UNIX if defined on the platform; otherwise, the default is AF_INET. + """ + result = _c.socketpair_t() + res = _c.socketpair(family, type, proto, byref(result)) + if res < 0: + raise last_error() + return (make_socket(result[0], family, type, proto, SocketClass), + make_socket(result[1], family, type, proto, SocketClass)) -def fromfd(fd, family, type, proto=0, SocketClass=RSocket): - # Dup the fd so it and the socket can be closed independently - fd = _c.dup(fd) - if fd < 0: - raise last_error() - return make_socket(fd, family, type, proto, SocketClass) +if hasattr(_c, 'dup'): + def fromfd(fd, family, type, proto=0, SocketClass=RSocket): + # Dup the fd so it and the socket can be closed independently + fd = _c.dup(fd) + if fd < 0: + raise last_error() + return make_socket(fd, family, type, proto, SocketClass) def getdefaulttimeout(): return defaults.timeout From cfbolz at codespeak.net Wed Apr 18 09:53:54 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 18 Apr 2007 09:53:54 +0200 (CEST) Subject: [pypy-svn] r42142 - pypy/extradoc/paper Message-ID: <20070418075354.D156E8097@code0.codespeak.net> Author: cfbolz Date: Wed Apr 18 09:53:54 2007 New Revision: 42142 Added: pypy/extradoc/paper/prolog-in-python.pdf (contents, props changed) Log: add my bachelor thesis Added: pypy/extradoc/paper/prolog-in-python.pdf ============================================================================== Binary file. No diff available. From afa at codespeak.net Wed Apr 18 09:57:15 2007 From: afa at codespeak.net (afa at codespeak.net) Date: Wed, 18 Apr 2007 09:57:15 +0200 (CEST) Subject: [pypy-svn] r42143 - in pypy/dist/pypy: module/rsocket/test rlib/test Message-ID: <20070418075715.60B648099@code0.codespeak.net> Author: afa Date: Wed Apr 18 09:57:15 2007 New Revision: 42143 Modified: pypy/dist/pypy/module/rsocket/test/test_sock_app.py pypy/dist/pypy/rlib/test/test_rsocket.py Log: rsocket: On Windows 2000, inet_aton is more tolerant and accept missing numbers 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 Apr 18 09:57:15 2007 @@ -241,7 +241,7 @@ def test_aton_exceptions(self): import _socket tests = ["127.0.0.256", "127.0.0.255555555555555555", "127.2b.0.0", - "127.2.0.0.1", "127.2..0"] + "127.2.0.0.1", "127.2.0."] for ip in tests: raises(_socket.error, _socket.inet_aton, ip) Modified: pypy/dist/pypy/rlib/test/test_rsocket.py ============================================================================== --- pypy/dist/pypy/rlib/test/test_rsocket.py (original) +++ pypy/dist/pypy/rlib/test/test_rsocket.py Wed Apr 18 09:57:15 2007 @@ -262,9 +262,17 @@ assert inet_aton('1.2.3.4') == '\x01\x02\x03\x04' assert inet_aton('127.0.0.1') == '\x7f\x00\x00\x01' tests = ["127.0.0.256", "127.0.0.255555555555555555", "127.2b.0.0", - "127.2.0.0.1", "127.2..0"] + "127.2.0.0.1", "127.2.0."] for ip in tests: py.test.raises(SocketError, inet_aton, ip) + + # Windows 2000: missing numbers are replaced by 0 + for ip, aton in [("11..22.33", '\x0b\x00\x16\x21'), + (".11.22.33", '\x00\x0b\x16\x21')]: + try: + assert inet_aton(ip) == aton + except SocketError: + pass class TestTCP: PORT = 50007 From cfbolz at codespeak.net Wed Apr 18 09:59:47 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 18 Apr 2007 09:59:47 +0200 (CEST) Subject: [pypy-svn] r42144 - pypy/dist/pypy/doc Message-ID: <20070418075947.EC36A809C@code0.codespeak.net> Author: cfbolz Date: Wed Apr 18 09:59:47 2007 New Revision: 42144 Modified: pypy/dist/pypy/doc/prolog-interpreter.txt Log: put a link to my thesis there, instead of to the paper draft (the content of the draft is mostly a subset of the thesis). Modified: pypy/dist/pypy/doc/prolog-interpreter.txt ============================================================================== --- pypy/dist/pypy/doc/prolog-interpreter.txt (original) +++ pypy/dist/pypy/doc/prolog-interpreter.txt Wed Apr 18 09:59:47 2007 @@ -18,12 +18,12 @@ learning since it is too rough for that). For a more detailed description of the implementation of the Prolog interpreter -see the `A flexible Prolog interpreter in Python`_ draft paper. +see Carl Friedrich's bachelor thesis `A Prolog interpreter in Python`_ paper. .. _`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/ -.. _`A flexible Prolog interpreter in Python`: http://codespeak.net/svn/user/cfbolz/hack/prolog/paper/prolog-in-rpython.pdf +.. _`A Prolog interpreter in Python`: http://codespeak.net/pypy/extradoc/paper/prolog-in-python.pdf Example useage ============== From arigo at codespeak.net Wed Apr 18 11:47:13 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 18 Apr 2007 11:47:13 +0200 (CEST) Subject: [pypy-svn] r42146 - pypy/branch/pypy-string-formatting Message-ID: <20070418094713.53257809E@code0.codespeak.net> Author: arigo Date: Wed Apr 18 11:47:12 2007 New Revision: 42146 Added: pypy/branch/pypy-string-formatting/ - copied from r42145, pypy/dist/pypy/ Log: A temporary branch to check in my changes as I go along rewriting the outer loop of string formatting. From arigo at codespeak.net Wed Apr 18 11:50:36 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 18 Apr 2007 11:50:36 +0200 (CEST) Subject: [pypy-svn] r42147 - pypy/branch/pypy-string-formatting/objspace/std Message-ID: <20070418095036.BB000809E@code0.codespeak.net> Author: arigo Date: Wed Apr 18 11:50:36 2007 New Revision: 42147 Modified: pypy/branch/pypy-string-formatting/objspace/std/formatting.py pypy/branch/pypy-string-formatting/objspace/std/stringobject.py Log: In-progress. Completely broken for now. Modified: pypy/branch/pypy-string-formatting/objspace/std/formatting.py ============================================================================== --- pypy/branch/pypy-string-formatting/objspace/std/formatting.py (original) +++ pypy/branch/pypy-string-formatting/objspace/std/formatting.py Wed Apr 18 11:50:36 2007 @@ -1,602 +1,159 @@ +""" +String formatting routines. +""" +from pypy.rlib.unroll import unrolling_iterable -# Application level implementation of string formatting. - -# There's some insane stuff in here. Blame CPython. Please. - -# Known problems: -# (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 -from pypy.interpreter.error import OperationError, debug_print -from pypy.rlib import rarithmetic - -class _Flags(object): - def __repr__(self): - return "<%s>"%(', '.join([f for f in self.__dict__ - if f[0] == 'f' and getattr(self, f)]),) - f_ljust = 0 - f_sign = 0 - f_blank = 0 - f_alt = 0 - f_zero = 0 - - -def peel_num(space, c, fmtiter, valuegetter): - if c == '*': - v = valuegetter.nextvalue() - if not v.isint(): - raise OperationError(space.w_TypeError, space.wrap("* wants int")) - return fmtiter.next(), space.int_w(v.maybe_int()) - i0 = fmtiter.i - 1 - assert i0 > 0 - ik = i0 - while c in '0123456789': - c = fmtiter.next() - ik += 1 - if ik != i0: - return c, int(fmtiter.fmt[i0:ik]) - else: - return c, 0 - - -def peel_flags(c, fmtiter): - flags = _Flags() - while 1: - if c == '-': - flags.f_ljust = True - elif c == '+': - flags.f_sign = True - elif c == ' ': - flags.f_blank = True - elif c == '#': - flags.f_alt = True - elif c == '0': - flags.f_zero = True - else: - break - c = fmtiter.next() - return c, flags +class StringFormatter(object): + def __init__(self, space, fmt, values_w, w_valuedict): + self.space = space + self.fmt = fmt + self.fmtpos = 0 + self.values_w = values_w + self.values_pos = 0 + self.w_valuedict = w_valuedict -def parse_fmt(space, fmtiter, valuegetter): - """return (char, flags, width, prec, value) - partially consumes fmtiter & valuegetter""" - c = fmtiter.next() - value = None - gotvalue = False - if c == '(': - i0 = fmtiter.i - assert i0 > 0 - ik = i0 + def peekchr(self): + # return the 'current' character + try: + return self.fmt[self.fmtpos] + except IndexError: + space = self.space + raise OperationError(space.w_ValueError, + space.wrap("incomplete format")) + + def forward(self): + # move current position forward + self.fmtpos += 1 + + def getmappingkey(self): + # return the mapping key in a '%(key)s' specifier + fmt = self.fmt + i = self.fmtpos + 1 # first character after '(' + i0 = i pcount = 1 while 1: - c = fmtiter.next() + c = fmt[i] if c == ')': pcount -= 1 if pcount == 0: break elif c == '(': pcount += 1 - ik += 1 - value = valuegetter.getitem(fmtiter.fmt[i0:ik]) - gotvalue = True - c = fmtiter.next() - c, flags = peel_flags(c, fmtiter) - c, width = peel_num(space, c, fmtiter, valuegetter) - if c == '.': - c, prec = peel_num(space, fmtiter.next(), fmtiter, valuegetter) - flags.prec = True - else: - prec = 0 - flags.prec = False - if c in 'hlL': - c = fmtiter.next() - if width < 0: - # this can happen with *-args - flags.f_ljust = True - width = -width - if not gotvalue: - if c == '%': - # did YOU realize that "%4%"%() == ' %'?? - value = valuegetter.makevalue('%') - c = 's' + i += 1 + self.fmtpos = i + 1 # first character after ')' + return fmt[i0:i] + + def nextinputvalue(self): + # return the next value in the tuple of input arguments + try: + w_result = self.values_w[self.values_pos] + except IndexError: + space = self.space + raise OperationError(space.w_TypeError, space.wrap( + 'not enough arguments for format string')) else: - value = valuegetter.nextvalue() - return (c, flags, width, prec, value) - + self.values_pos += 1 + return w_result -class NeedUnicodeFormattingError(Exception): - pass - -def numeric_preprocess(v, flags): - # negative zeroes? - # * mwh giggles, falls over - # still, if we can recognize them, here's the place to do it. - import math - if v < 0 or v == 0 and isinstance(v, float) and math.atan2(0, v) != 0: - sign = '-' - v = -v - else: - if flags.f_sign: - sign = '+' - elif flags.f_blank: - sign = ' ' - else: - sign = '' - return v, sign -numeric_preprocess._annspecialcase_ = 'specialize:argtype(0)' - -def numeric_postprocess(r, sign, char, flags, width, prefix=""): - assert char in 'iduoxXeEfFgG' - padchar = ' ' - if flags.f_zero: - padchar = '0' - p = width - len(r) - len(sign) - len(prefix) - if p < 0: - p = 0 - if flags.f_ljust: - r = sign + prefix + r + ' '*p - else: - if flags.f_zero: - r = sign+prefix+padchar*p + r - else: - r = padchar*p + sign + prefix + r - return r + def getmappingvalue(self, key): + # return the value corresponding to a key in the input dict + space = self.space + if self.w_valuedict is None: + raise OperationError(space.w_TypeError, + space.wrap("format requires a mapping")) + return space.getitem(self.w_valuedict, space.wrap(key)) -def std_wp(r, char, flags, width, prec): - assert char not in 'iduoxXeEfFgG' - if flags.prec: - if prec > 0: - r = r[:prec] - else: - x = len(r) + prec - assert x >= 0 - r = r[:x] - p = width - len(r) - if p < 0: - p = 0 - if flags.f_ljust: - r = r + ' '*p - else: - r = ' '*p + r - return r - -def std_wp_unicode(r, char, flags, width, prec): - assert char not in 'iduoxXeEfFgG' - if flags.prec: - if prec > 0: - r = r[:prec] - else: - x = len(r) + prec - assert x >= 0 - r = r[:x] - p = width - len(r) - if p < 0: - p = 0 - if flags.f_ljust: - r = r + [unichr(ord(' '))]*p - else: - r = [unichr(ord(' '))]*p + r - return r - -def repr_format(space, char, flags, width, prec, valuebox): - return std_wp(valuebox.repr(), char, flags, width, prec) - -def percent_format(space, char, flags, width, prec, valuebox): - return std_wp('%', char, flags, width, prec) - -# isinf isn't too hard... -def isinf(v): - return v != 0 and v*2.0 == v - -# To get isnan, working x-platform and both on 2.3 and 2.4, is a -# horror. I think this works (for reasons I don't really want to talk -# about), and probably when implemented on top of pypy, too. -def isnan(v): - return v != v*1.0 or (v == 1.0 and v == 2.0) - -def float_formatd(space, kind, v, flags, prec): - try: - return rarithmetic.formatd_overflow(flags.f_alt, prec, kind, v) - except OverflowError: - raise OperationError(space.w_OverflowError, space.wrap("formatted float is too long (precision too large?)")) - -def float_f_format(space, char, flags, width, prec, valuebox): - v = valuebox.maybe_float() - if isnan(v): - return 'nan' - elif isinf(v): - return 'inf' - if not flags.prec: - prec = 6 - v, sign = numeric_preprocess(v, flags) - if v/1e25 > 1e25: - return float_g_format(space, 'g', flags, width, prec, valuebox) - return numeric_postprocess(float_formatd(space, 'f', v, flags, prec), - sign, char, flags, width) - -def float_e_format(space, char, flags, width, prec, valuebox): - v = valuebox.maybe_float() - if isnan(v): - return 'nan' - elif isinf(v): - return 'inf' - if not flags.prec: - prec = 6 - v, sign = numeric_preprocess(v, flags) - return numeric_postprocess(float_formatd(space, 'e', v, flags, prec), - sign, char, flags, width) - -def float_g_format(space, char, flags, width, prec, valuebox): - # The description of %g in the Python documentation lies - # in a variety of minor ways. - # Gah, this still isn't quite right in the f_alt case. - # (One has to wonder who might care). - v = valuebox.maybe_float() - if isnan(v): - return 'nan' - elif isinf(v): - return 'inf' - if not flags.prec: - prec = 6 - v, sign = numeric_preprocess(v, flags) - return numeric_postprocess(float_formatd(space, 'g', v, flags, prec), - sign, char, flags, width) - -def format_num_helper_generator(fun_name, fun): - def format_num_helper(space, valuebox, flags): - v = valuebox.maybe_int() - try: - value = space.int_w(v) - value, sign = numeric_preprocess(value, flags) - return (fun(value), sign) - except OperationError, operr: - # XXX: Fix it, this is obviously inefficient - if not operr.match(space, space.w_OverflowError): - raise - if space.is_true(space.lt(v, space.wrap(0))): - sign = '-' - v = space.neg(v) + def parse_fmt(self): + if self.peekchr() == '(': + w_value = self.getmappingvalue(self.getmappingkey()) + else: + w_value = None + + self.peel_flags() + + self.width = self.peel_num() + if self.width < 0: + # this can happen: '%*s' % (-5, "hi") + self.f_ljust = True + self.width = -self.width + + if self.peekchr() == '.': + self.forward() + self.prec = self.peel_num() + if self.prec < 0: + self.prec = 0 # this can happen: '%.*f' % (-5, 3) + else: + self.prec = -1 + + if self.peekchr() in 'hlL': + self.forward() + + return w_value + + def format(self): + result = [] # list of characters + self.result = result + while True: + # fast path: consume as many characters as possible + fmt = self.fmt + i = self.fmtpos + while i < len(fmt): + if fmt[i] == '%': + break + result.append(fmt[i]) + i += 1 else: - if flags.f_sign: - sign = '+' - elif flags.f_blank: - sign = ' ' - else: - sign = '' - val = space.str_w(getattr(space, fun_name)(v)) - return (val, sign) - format_num_helper.func_name = fun_name + '_num_helper' - return format_num_helper - -hex_num_helper = format_num_helper_generator('hex', hex) -oct_num_helper = format_num_helper_generator('oct', oct) -int_num_helper = format_num_helper_generator('str', str) - -def hex_format(space, char, flags, width, prec, valuebox): - # NB: this has 2.4 semantics wrt. negative values - r, sign = hex_num_helper(space, valuebox, flags) - r = r[2:] - if r[-1] == "L": - # workaround weird behavior of CPython's hex - r = r[:-1].lower() - if flags.prec and len(r) < prec: - - r = '0'*(prec - len(r)) + r - if flags.f_alt: - prefix = '0x' - else: - prefix = '' - if char == 'X': - r = r.upper() - prefix = prefix.upper() - return numeric_postprocess(r, sign, char, flags, width, prefix) - -def oct_format(space, char, flags, width, prec, valuebox): - r, sign = oct_num_helper(space, valuebox, flags) - if r[-1] == "L": - r = r[:-1] - if space.is_true(valuebox.maybe_int()) and not flags.f_alt: - r = r[1:] - if flags.prec and len(r) < prec: - r = '0'*(prec - len(r)) + r - return numeric_postprocess(r, sign, char, flags, width) - -def int_format(space, char, flags, width, prec, valuebox): - r, sign = int_num_helper(space, valuebox, flags) - # XXX arbitrary overflow - if prec > 1000: - raise OperationError(space.w_OverflowError, space.wrap - ("Precision (%d) too large" % prec)) - if width > 1000: - raise OperationError(space.w_OverflowError, space.wrap - ("Width (%d) too large" % width)) - if flags.prec and len(r) < prec: - r = '0'*(prec - len(r)) + r - return numeric_postprocess(r, sign, char, flags, width) - -def char_format(space, char, flags, width, prec, valuebox): - if valuebox.isstr(): - v = valuebox.str() - if len(v) != 1: - raise OperationError(space.w_TypeError, space.wrap("%c requires int or char")) - elif valuebox.isunicode(): - raise NeedUnicodeFormattingError - else: - i = space.int_w(valuebox.maybe_int()) - if not 0 <= i <= 255: - raise OperationError(space.w_OverflowError, - space.wrap("OverflowError: unsigned byte " - "integer is greater than maximum")) - v = chr(i) - flags.prec = False - return std_wp(v, char, flags, width, 0) - -def string_format(space, char, flags, width, prec, valuebox): - if valuebox.isunicode(): - raise NeedUnicodeFormattingError - return std_wp(valuebox.str(), char, flags, width, prec) - -str_format_registry = { - 'd':int_format, - 'i':int_format, - 'o':oct_format, - 'u':int_format, - 'x':hex_format, - 'X':hex_format, - 'e':float_e_format, - 'E':float_e_format, - 'f':float_f_format, - 'F':float_f_format, - 'g':float_g_format, - 'G':float_g_format, - 'c':char_format, - 's':string_format, - 'r':repr_format, - # this *can* get accessed, by e.g. '%()4%'%{'':1}. - # The usual %% case has to be handled specially as it - # doesn't consume a value. - '%':percent_format, - } - -def unicode_string_format(space, char, flags, width, prec, valuebox): - return std_wp_unicode(valuebox.unicode(), char, flags, width, prec) - -def unicode_char_format(space, char, flags, width, prec, valuebox): - if valuebox.isunicode(): - v = valuebox.unicode() - if len(v) != 1: - raise TypeError, "%c requires int or unicode char" - elif valuebox.isstr(): - v = space.unichars_w(space.wrap(valuebox.str())) - if len(v) != 1: - raise TypeError, "%c requires int or unicode char" - else: - i = space.int_w(valuebox.maybe_int()) - if not 0 <= i <= sys.maxunicode: - raise OverflowError("OverflowError: unsigned byte " - "integer is greater than maximum") - v = [unichr(i)] - flags.prec = False - return std_wp_unicode(v, char, flags, width, 0) + break # end of 'fmt' string + self.fmtpos = i + 1 -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): - if self.i >= self._fmtlength: - raise StopIteration - c = self.fmt[self.i] - self.i += 1 - return c - - def skip_to_fmt(self): - i = self.i - j = self.fmt.find('%', i) - if j < 0: - self.i = len(self.fmt) - assert i > 0 - return self.fmt[i:] - else: - self.i = j - assert i > 0 - assert j > 0 - return self.fmt[i:j] - - -def format(space, w_fmt, w_values, w_valuedict, do_unicode=False): - vb = ValueGetter(space, w_values, w_valuedict) - if not do_unicode: - return _format(space, space.str_w(w_fmt), vb) - else: - fmt = space.str_w(w_fmt) - fmtiter = FmtIter(fmt) - return _format_unicode(space, fmtiter, vb, [], []) - -def parse_and_check_fmt(space, fmtiter, valuegetter): - try: - t = parse_fmt(space, fmtiter, valuegetter) - except StopIteration: - raise OperationError(space.w_ValueError, - space.wrap("incomplete format")) - try: - f = str_format_registry[t[0]] - except KeyError: - char = t[0] - if isinstance(char, unicode): - char = char.encode(sys.getdefaultencoding(), 'replace') - raise OperationError(space.w_ValueError, - space.wrap("unsupported format character " - "'%s' (0x%x) at index %d" - % (char, ord(t[0]), fmtiter.i - 1))) - return t, f - -def _format(space, fmt, valuegetter): - fmtiter = FmtIter(fmt) - r = [] - # iterator done by hand - while 1: - try: - c = fmtiter.next() + # interpret the next formatter + w_value = self.parse_fmt() + c = self.peekchr() + self.forward() if c == '%': - t = parse_and_check_fmt(space, fmtiter, valuegetter) - (char, flags, width, prec, value), f = t - try: - result = f(space, char, flags, width, prec, value) - except NeedUnicodeFormattingError: - f_list = check_unicode_registry(space, t) - return _format_unicode(space, fmtiter, valuegetter, r, f_list) - else: - r.append(result) - else: - # efficiency hack: - r.append(c + fmtiter.skip_to_fmt()) - except StopIteration: - break - valuegetter.check_consumed() - return space.wrap(''.join(r)) - -def check_unicode_registry(space, t): - # XXX weird specialcasing, because functions returns different - # stuff, need to fix unicode support in RPython for that - (char, flags, width, prec, value), f = t - if char == 's': - return unicode_string_format(space, char, flags, width, prec, value) - elif char == 'c': - return unicode_char_format(space, char, flags, width, prec, value) - else: - result = f(space, char, flags, width, prec, value) - return space.unichars_w(space.wrap(result)) - -def _format_unicode(space, fmtiter, valuegetter, base_list=[], formatted_list=[]): - r = [] - for i in base_list: - r += space.unichars_w(space.wrap(i)) - r += formatted_list - # iterator done by hand - while 1: - try: - c = fmtiter.next() - if c == '%': - t = parse_and_check_fmt(space, fmtiter, valuegetter) - r += check_unicode_registry(space, t) + self.std_wp('%') + continue + if w_value is None: + w_value = self.nextinputvalue() + + # dispatch on the formatter + # (this turns into a switch after translation) + for c1 in FORMATTER_CHARS: + if c == c1: + # 'c1' is an annotation constant here, + # so this getattr() is ok + do_fmt = getattr(self, 'fmt_' + c1) + do_fmt(w_value) + break else: - # efficiency hack: - r += [unichr(ord(i)) for i in c + fmtiter.skip_to_fmt()] - except StopIteration: - break - valuegetter.check_consumed() - return space.newunicode(r) + self.unknown_fmtchar() -class ValueGetter: - """ statefull accesstor to Interpolation Values. """ - def __init__(self, space, w_values, w_valuedict): - self.space = space - self.values_w = space.unpacktuple(w_values) - self.w_valuedict = w_valuedict - self._valueindex = 0 + def fmt_s(self, w_value): + self.std_wp(self.space.str_w(w_value)) - def check_consumed(self): - space = self.space - if (self._valueindex < len(self.values_w) and - space.is_w(self.w_valuedict, space.w_None)): - raise OperationError(space.w_TypeError, - space.wrap('not all arguments converted ' - 'during string formatting')) + def fmt_d(self, w_value): + "int formatting" + + ... - def makevalue(self, string): - return ValueBox(self.space, self.space.wrap(string)) + fmt_i = fmt_d - def nextvalue(self): - space = self.space - if self._valueindex >= len(self.values_w): - raise OperationError(space.w_TypeError, space.wrap( - 'not enough arguments for format string')) - val = self.values_w[self._valueindex] - self._valueindex += 1 - return ValueBox(space, val) - - def getitem(self, key): - return ValueBox(self.space, - self.space.getitem(self.w_valuedict, - self.space.wrap(key))) -class ValueBox: - def __init__(self, space, w_value): - self.space = space - self.w_value = w_value - - def str(self): - return self.space.str_w(self.space.str(self.w_value)) - - def repr(self): - return self.space.str_w(self.space.repr(self.w_value)) +# an "unrolling" list of all the known format characters, +# collected from which fmt_X() functions are defined in the class +FORMATTER_CHARS = unrolling_iterable( + [_name[-1] for _name in StringFormatter.__dict__.keys() + if len(_name) == 5 and _name.startswith('fmt_')]) - def isint(self): - space = self.space - return space.is_true(space.isinstance(self.w_value, space.w_int)) - - def isstr(self): - space = self.space - return space.is_true(space.isinstance(self.w_value, space.w_str)) - - def isunicode(self): - space = self.space - return space.is_true(space.isinstance(self.w_value, space.w_unicode)) - - def maybe_int(self): - space = self.space - if space.is_true(space.isinstance(self.w_value, space.w_int)): - return self.w_value - try: - w_fun = space.getattr(self.w_value, space.wrap('__int__')) - except OperationError, operr: - if not operr.match(space, space.w_AttributeError): - raise - raise OperationError(space.w_TypeError, - space.wrap("int argument required")) - return space.call_function(w_fun) - def maybe_float(self): - space = self.space - if space.is_true(space.isinstance(self.w_value, space.w_float)): - return space.float_w(self.w_value) - try: - w_fun = space.getattr(self.w_value, space.wrap('__float__')) - except OperationError, operr: - if not operr.match(space, space.w_AttributeError): - raise - raise OperationError(space.w_TypeError, - space.wrap("float argument required")) - return space.float_w(space.call_function(w_fun)) +def format(space, w_fmt, values_w, w_valuedict=None, do_unicode=False): + "Entry point" + assert not do_unicode # XXX + fmt = space.str_w(w_fmt) + formatter = StringFormatter(space, fmt, values_w, w_valuedict) + return formatter.format() - def __str__(self): - raise ValueError("use self.str()") - def unicode(self): - space = self.space - if space.is_true(space.isinstance(self.w_value, space.w_unicode)): - return space.unichars_w(self.w_value) - try: - w_fun = space.getattr(self.w_value, space.wrap('__unicode__')) - except OperationError, operr: - if not operr.match(space, space.w_AttributeError): - raise - return space.unichars_w(space.str(self.w_value)) - return space.unichars_w(space.call_function(w_fun)) +... Modified: pypy/branch/pypy-string-formatting/objspace/std/stringobject.py ============================================================================== --- pypy/branch/pypy-string-formatting/objspace/std/stringobject.py (original) +++ pypy/branch/pypy-string-formatting/objspace/std/stringobject.py Wed Apr 18 11:50:36 2007 @@ -918,18 +918,17 @@ # (values is of a mapping type) def mod__String_ANY(space, w_format, w_values): if space.is_true(space.isinstance(w_values, space.w_tuple)): - return format(space, w_format, w_values, space.w_None) + values_w = space.unpackiterable(w_values) + return format(space, w_format, values_w, None) else: # we check directly for dict to avoid obscure checking # in simplest case if space.is_true(space.isinstance(w_values, space.w_dict)) or \ (space.lookup(w_values, '__getitem__') and not space.is_true(space.isinstance(w_values, space.w_basestring))): - return format(space, w_format, - space.newtuple([w_values]), w_values) + return format(space, w_format, [w_values], w_values) else: - return format(space, w_format, - space.newtuple([w_values]), space.w_None) + return format(space, w_format, [w_values], None) # register all methods from pypy.objspace.std import stringtype From arigo at codespeak.net Wed Apr 18 15:54:19 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 18 Apr 2007 15:54:19 +0200 (CEST) Subject: [pypy-svn] r42149 - pypy/dist/pypy/jit/timeshifter Message-ID: <20070418135419.BF53D8076@code0.codespeak.net> Author: arigo Date: Wed Apr 18 15:54:18 2007 New Revision: 42149 Modified: pypy/dist/pypy/jit/timeshifter/rcontainer.py Log: Missing op_ptreq(). Modified: pypy/dist/pypy/jit/timeshifter/rcontainer.py ============================================================================== --- pypy/dist/pypy/jit/timeshifter/rcontainer.py (original) +++ pypy/dist/pypy/jit/timeshifter/rcontainer.py Wed Apr 18 15:54:18 2007 @@ -916,6 +916,9 @@ else: return None + def op_ptreq(self, jitstate, otherbox, reverse): + return None # XXX for now + def remember_field(self, fielddesc, box): searchindex = fielddesc.fieldindex for i in range(len(self.data)): From arigo at codespeak.net Wed Apr 18 16:00:55 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 18 Apr 2007 16:00:55 +0200 (CEST) Subject: [pypy-svn] r42151 - in pypy/dist/pypy: doc doc/config lang/js lib lib/distributed/test module/pypyjit/test objspace/std objspace/std/test rlib tool translator/js/examples/console translator/js/examples/console/test translator/js/test translator/jvm/test translator/oosupport/test Message-ID: <20070418140055.4A14C808F@code0.codespeak.net> Author: arigo Date: Wed Apr 18 16:00:54 2007 New Revision: 42151 Modified: pypy/dist/pypy/doc/config/objspace.std.withrope.txt (props changed) pypy/dist/pypy/doc/config/translation.noprofopt.txt (props changed) pypy/dist/pypy/doc/distribution.txt (props changed) pypy/dist/pypy/doc/javascript-interpreter.txt (props changed) pypy/dist/pypy/doc/parse_logs.py (props changed) pypy/dist/pypy/lang/js/constants.py (props changed) pypy/dist/pypy/lib/_functools.py (props changed) pypy/dist/pypy/lib/distributed/test/test_greensock.py (props changed) pypy/dist/pypy/module/pypyjit/test/__init__.py (props changed) pypy/dist/pypy/module/pypyjit/test/conftest.py (props changed) pypy/dist/pypy/objspace/std/rope.py (props changed) pypy/dist/pypy/objspace/std/ropeobject.py (props changed) pypy/dist/pypy/objspace/std/test/test_index.py (props changed) pypy/dist/pypy/objspace/std/test/test_rope.py (props changed) pypy/dist/pypy/objspace/std/test/test_ropeobject.py (props changed) pypy/dist/pypy/rlib/getaddrinfo.py (contents, props changed) pypy/dist/pypy/rlib/getnameinfo.py (contents, props changed) pypy/dist/pypy/tool/ansi_mandelbrot.py (props changed) pypy/dist/pypy/translator/js/examples/console/docloader.py (props changed) pypy/dist/pypy/translator/js/examples/console/play1_snippets.py (props changed) pypy/dist/pypy/translator/js/examples/console/test/test_docloader.py (props changed) pypy/dist/pypy/translator/js/examples/console/test/test_snippets.py (props changed) pypy/dist/pypy/translator/js/test/test_rfloat.py (props changed) pypy/dist/pypy/translator/js/test/test_str.py (props changed) pypy/dist/pypy/translator/jvm/test/test_objectmodel.py (props changed) pypy/dist/pypy/translator/oosupport/test/ (props changed) Log: fixeol Modified: pypy/dist/pypy/rlib/getaddrinfo.py ============================================================================== --- pypy/dist/pypy/rlib/getaddrinfo.py (original) +++ pypy/dist/pypy/rlib/getaddrinfo.py Wed Apr 18 16:00:54 2007 @@ -1,229 +1,229 @@ -""" -An RPython implementation of getaddrinfo() based on ctypes. -This is a rewrite of the CPython source: Modules/getaddrinfo.c -""" - -from ctypes import POINTER, sizeof, cast, pointer -from pypy.rlib import _rsocket_ctypes as _c -from pypy.rlib.rsocket import GAIError, CSocketError -from pypy.rlib.rsocket import gethost_common, make_address - -# valid flags for addrinfo -AI_MASK = (_c.AI_PASSIVE | _c.AI_CANONNAME | _c.AI_NUMERICHOST) - -GAI_ERRORS = [ - (1, 'EAI_ADDRFAMILY', "address family for hostname not supported"), - (2, 'EAI_AGAIN', "temporary failure in name resolution"), - (3, 'EAI_BADFLAGS', "invalid value for ai_flags"), - (4, 'EAI_FAIL', "failure in name resolution"), - (5, 'EAI_FAMILY', "ai_family not supported"), - (6, 'EAI_MEMORY', "memory allocation failure"), - (7, 'EAI_NODATA', "no address associated with hostname"), - (8, 'EAI_NONAME', "hostname nor servname provided, or not known"), - (9, 'EAI_SERVICE', "servname not supported for ai_socktype"), - (10, 'EAI_SOCKTYPE', "ai_socktype not supported"), - (11, 'EAI_SYSTEM', "system error returned in errno"), - (12, 'EAI_BADHINTS', "invalid value for hints"), - (13, 'EAI_PROTOCOL', "resolved protocol is unknown."), - (14, 'EAI_MAX', "unknown error"), -] - -GAI_ERROR_MESSAGES = {} - -for value, name, text in GAI_ERRORS: - globals()[name] = value - GAI_ERROR_MESSAGES[value] = text - -# Replacement function for rsocket.GAIError.get_msg -def GAIError_getmsg(self): - return GAI_ERROR_MESSAGES[self.errno] - -# str.isdigit is not RPython, so provide our own -def str_isdigit(name): - if name == "": - return False - for c in name: - if c not in "012345789": - return False - return True - -GAI_ANY = 0 -INADDR_NONE = 0xFFFFFFFF - -def getaddrinfo(hostname, servname, - family=_c.AF_UNSPEC, socktype=0, - protocol=0, flags=0, - address_to_fill=None): - - if not hostname and not servname: - raise GAIError(EAI_NONAME) - - # error checks for hints - if flags & ~AI_MASK: - raise GAIError(EAI_BADFLAGS) - if family not in (_c.AF_UNSPEC, _c.AF_INET): - raise GAIError(EAI_FAMILY) - - if socktype == GAI_ANY: - if protocol == GAI_ANY: - pass - elif protocol == _c.IPPROTO_UDP: - socktype = _c.SOCK_DGRAM - elif protocol == _c.IPPROTO_TCP: - socktype = _c.SOCK_STREAM - else: - socktype = _c.SOCK_RAW - - elif socktype == _c.SOCK_RAW: - pass - elif socktype == _c.SOCK_DGRAM: - if protocol not in (_c.IPPROTO_UDP, GAI_ANY): - raise GAIError(EAI_BADHINTS) - protocol = _c.IPPROTO_UDP - elif socktype == _c.SOCK_STREAM: - if protocol not in (_c.IPPROTO_TCP, GAI_ANY): - raise GAIError(EAI_BADHINTS) - protocol = _c.IPPROTO_TCP - else: - raise GAIError(EAI_SOCKTYPE) - - port = GAI_ANY - - # service port - if servname: - if str_isdigit(servname): - port = _c.htons(int(servname)) - # On windows, python2.3 uses getattrinfo.c, - # python2.4 uses VC2003 implementation of getaddrinfo(). - # if sys.version < (2, 4) - # socktype = _c.SOCK_DGRAM - # protocol = _c.IPPROTO_UDP - else: - if socktype == _c.SOCK_DGRAM: - proto = "udp" - elif socktype == _c.SOCK_STREAM: - proto = "tcp" - else: - proto = None - - sp = _c.getservbyname(servname, proto) - if not sp: - raise GAIError(EAI_SERVICE) - port = sp.contents.s_port - if socktype == GAI_ANY: - if sp.contents.s_proto == "udp": - socktype = _c.SOCK_DGRAM - protocol = _c.IPPROTO_UDP - elif sp.contents.s_proto == "tcp": - socktype = _c.SOCK_STREAM - protocol = _c.IPPROTO_TCP - else: - raise GAIError(EAI_PROTOCOL) - - # hostname == NULL - # passive socket -> anyaddr (0.0.0.0 or ::) - # non-passive socket -> localhost (127.0.0.1 or ::1) - if not hostname: - result = [] - if family in (_c.AF_UNSPEC, _c.AF_INET): - - sin = _c.sockaddr_in(sin_family=_c.AF_INET, sin_port=port) - if flags & _c.AI_PASSIVE: - sin.sin_addr.s_addr = 0x0 # addrany - else: - sin.sin_addr.s_addr = 0x0100007f # loopback - - addr = make_address(cast(pointer(sin), POINTER(_c.sockaddr)), - sizeof(_c.sockaddr_in), address_to_fill) - - result.append((_c.AF_INET, socktype, protocol, "", # xxx canonname meaningless? "anyaddr" - addr)) - - if not result: - raise GAIError(EAI_FAMILY) - return result - - # hostname as numeric name - if family in (_c.AF_UNSPEC, _c.AF_INET): - - packedaddr = _c.inet_addr(hostname) - if packedaddr != INADDR_NONE: - - v4a = _c.ntohl(packedaddr) - if (v4a & 0xf0000000 == 0xe0000000 or # IN_MULTICAST() - v4a & 0xe0000000 == 0xe0000000): # IN_EXPERIMENTAL() - flags &= ~_c.AI_CANONNAME - v4a >>= 24 # = IN_CLASSA_NSHIFT - if v4a in (0, 127): # = IN_LOOPBACKNET - flags &= ~_c.AI_CANONNAME - - if not flags & _c.AI_CANONNAME: - sin = _c.sockaddr_in(sin_family=_c.AF_INET, sin_port=port) - sin.sin_addr.s_addr = packedaddr - addr = make_address(cast(pointer(sin), POINTER(_c.sockaddr)), - sizeof(_c.sockaddr_in), address_to_fill) - return [(_c.AF_INET, socktype, protocol, None, addr)] - else: - sin = _c.sockaddr_in(sin_family=_c.AF_INET, sin_port=port) - - sin.sin_addr.s_addr = packedaddr - - # getaddrinfo() is a name->address translation function, - # and it looks strange that we do addr->name translation here. - # This is what python2.3 did on Windows: - # if sys.version < (2, 4): - # canonname = get_name(hostname, sin.sin_addr, - # sizeof(_c.in_addr)) - canonname = hostname - - addr = make_address(cast(pointer(sin), POINTER(_c.sockaddr)), - sizeof(_c.sockaddr_in), address_to_fill) - return [(_c.AF_INET, socktype, protocol, canonname, addr)] - - if flags & _c.AI_NUMERICHOST: - raise GAIError(EAI_NONAME) - - # hostname as alphabetical name - result = get_addr(hostname, socktype, protocol, port, address_to_fill) - - if result: - return result - - raise GAIError(EAI_FAIL) - -def get_name(hostname, addr, addrlen): - hostent = _c.gethostbyaddr(pointer(addr), addrlen, _c.AF_INET) - - # if reverse lookup fail, - # return address anyway to pacify calling application. - if not hostent: - return hostname - - hname, aliases, address_list = gethost_common("", hostent) - if hostent and hostent.contents.h_name and hostent.contents.h_addr_list[0]: - return hostent.contents.h_name - else: - return hostname - -def get_addr(hostname, socktype, protocol, port, address_to_fill): - hostent = _c.gethostbyname(hostname) - - if not hostent: - raise GAIError(EAI_FAIL) - - hname, aliases, address_list = gethost_common("", hostent) - - result = [] - - for address in address_list: - if address.addr.sa_family == _c.AF_INET: - a = cast(pointer(address.addr), POINTER(_c.sockaddr_in)).contents - a.sin_port = port & 0xffff - addr = make_address(pointer(address.addr),address.addrlen,address_to_fill) - result.append((address.addr.sa_family, - socktype, - protocol, - "", # XXX canonname? - addr)) - - return result +""" +An RPython implementation of getaddrinfo() based on ctypes. +This is a rewrite of the CPython source: Modules/getaddrinfo.c +""" + +from ctypes import POINTER, sizeof, cast, pointer +from pypy.rlib import _rsocket_ctypes as _c +from pypy.rlib.rsocket import GAIError, CSocketError +from pypy.rlib.rsocket import gethost_common, make_address + +# valid flags for addrinfo +AI_MASK = (_c.AI_PASSIVE | _c.AI_CANONNAME | _c.AI_NUMERICHOST) + +GAI_ERRORS = [ + (1, 'EAI_ADDRFAMILY', "address family for hostname not supported"), + (2, 'EAI_AGAIN', "temporary failure in name resolution"), + (3, 'EAI_BADFLAGS', "invalid value for ai_flags"), + (4, 'EAI_FAIL', "failure in name resolution"), + (5, 'EAI_FAMILY', "ai_family not supported"), + (6, 'EAI_MEMORY', "memory allocation failure"), + (7, 'EAI_NODATA', "no address associated with hostname"), + (8, 'EAI_NONAME', "hostname nor servname provided, or not known"), + (9, 'EAI_SERVICE', "servname not supported for ai_socktype"), + (10, 'EAI_SOCKTYPE', "ai_socktype not supported"), + (11, 'EAI_SYSTEM', "system error returned in errno"), + (12, 'EAI_BADHINTS', "invalid value for hints"), + (13, 'EAI_PROTOCOL', "resolved protocol is unknown."), + (14, 'EAI_MAX', "unknown error"), +] + +GAI_ERROR_MESSAGES = {} + +for value, name, text in GAI_ERRORS: + globals()[name] = value + GAI_ERROR_MESSAGES[value] = text + +# Replacement function for rsocket.GAIError.get_msg +def GAIError_getmsg(self): + return GAI_ERROR_MESSAGES[self.errno] + +# str.isdigit is not RPython, so provide our own +def str_isdigit(name): + if name == "": + return False + for c in name: + if c not in "012345789": + return False + return True + +GAI_ANY = 0 +INADDR_NONE = 0xFFFFFFFF + +def getaddrinfo(hostname, servname, + family=_c.AF_UNSPEC, socktype=0, + protocol=0, flags=0, + address_to_fill=None): + + if not hostname and not servname: + raise GAIError(EAI_NONAME) + + # error checks for hints + if flags & ~AI_MASK: + raise GAIError(EAI_BADFLAGS) + if family not in (_c.AF_UNSPEC, _c.AF_INET): + raise GAIError(EAI_FAMILY) + + if socktype == GAI_ANY: + if protocol == GAI_ANY: + pass + elif protocol == _c.IPPROTO_UDP: + socktype = _c.SOCK_DGRAM + elif protocol == _c.IPPROTO_TCP: + socktype = _c.SOCK_STREAM + else: + socktype = _c.SOCK_RAW + + elif socktype == _c.SOCK_RAW: + pass + elif socktype == _c.SOCK_DGRAM: + if protocol not in (_c.IPPROTO_UDP, GAI_ANY): + raise GAIError(EAI_BADHINTS) + protocol = _c.IPPROTO_UDP + elif socktype == _c.SOCK_STREAM: + if protocol not in (_c.IPPROTO_TCP, GAI_ANY): + raise GAIError(EAI_BADHINTS) + protocol = _c.IPPROTO_TCP + else: + raise GAIError(EAI_SOCKTYPE) + + port = GAI_ANY + + # service port + if servname: + if str_isdigit(servname): + port = _c.htons(int(servname)) + # On windows, python2.3 uses getattrinfo.c, + # python2.4 uses VC2003 implementation of getaddrinfo(). + # if sys.version < (2, 4) + # socktype = _c.SOCK_DGRAM + # protocol = _c.IPPROTO_UDP + else: + if socktype == _c.SOCK_DGRAM: + proto = "udp" + elif socktype == _c.SOCK_STREAM: + proto = "tcp" + else: + proto = None + + sp = _c.getservbyname(servname, proto) + if not sp: + raise GAIError(EAI_SERVICE) + port = sp.contents.s_port + if socktype == GAI_ANY: + if sp.contents.s_proto == "udp": + socktype = _c.SOCK_DGRAM + protocol = _c.IPPROTO_UDP + elif sp.contents.s_proto == "tcp": + socktype = _c.SOCK_STREAM + protocol = _c.IPPROTO_TCP + else: + raise GAIError(EAI_PROTOCOL) + + # hostname == NULL + # passive socket -> anyaddr (0.0.0.0 or ::) + # non-passive socket -> localhost (127.0.0.1 or ::1) + if not hostname: + result = [] + if family in (_c.AF_UNSPEC, _c.AF_INET): + + sin = _c.sockaddr_in(sin_family=_c.AF_INET, sin_port=port) + if flags & _c.AI_PASSIVE: + sin.sin_addr.s_addr = 0x0 # addrany + else: + sin.sin_addr.s_addr = 0x0100007f # loopback + + addr = make_address(cast(pointer(sin), POINTER(_c.sockaddr)), + sizeof(_c.sockaddr_in), address_to_fill) + + result.append((_c.AF_INET, socktype, protocol, "", # xxx canonname meaningless? "anyaddr" + addr)) + + if not result: + raise GAIError(EAI_FAMILY) + return result + + # hostname as numeric name + if family in (_c.AF_UNSPEC, _c.AF_INET): + + packedaddr = _c.inet_addr(hostname) + if packedaddr != INADDR_NONE: + + v4a = _c.ntohl(packedaddr) + if (v4a & 0xf0000000 == 0xe0000000 or # IN_MULTICAST() + v4a & 0xe0000000 == 0xe0000000): # IN_EXPERIMENTAL() + flags &= ~_c.AI_CANONNAME + v4a >>= 24 # = IN_CLASSA_NSHIFT + if v4a in (0, 127): # = IN_LOOPBACKNET + flags &= ~_c.AI_CANONNAME + + if not flags & _c.AI_CANONNAME: + sin = _c.sockaddr_in(sin_family=_c.AF_INET, sin_port=port) + sin.sin_addr.s_addr = packedaddr + addr = make_address(cast(pointer(sin), POINTER(_c.sockaddr)), + sizeof(_c.sockaddr_in), address_to_fill) + return [(_c.AF_INET, socktype, protocol, None, addr)] + else: + sin = _c.sockaddr_in(sin_family=_c.AF_INET, sin_port=port) + + sin.sin_addr.s_addr = packedaddr + + # getaddrinfo() is a name->address translation function, + # and it looks strange that we do addr->name translation here. + # This is what python2.3 did on Windows: + # if sys.version < (2, 4): + # canonname = get_name(hostname, sin.sin_addr, + # sizeof(_c.in_addr)) + canonname = hostname + + addr = make_address(cast(pointer(sin), POINTER(_c.sockaddr)), + sizeof(_c.sockaddr_in), address_to_fill) + return [(_c.AF_INET, socktype, protocol, canonname, addr)] + + if flags & _c.AI_NUMERICHOST: + raise GAIError(EAI_NONAME) + + # hostname as alphabetical name + result = get_addr(hostname, socktype, protocol, port, address_to_fill) + + if result: + return result + + raise GAIError(EAI_FAIL) + +def get_name(hostname, addr, addrlen): + hostent = _c.gethostbyaddr(pointer(addr), addrlen, _c.AF_INET) + + # if reverse lookup fail, + # return address anyway to pacify calling application. + if not hostent: + return hostname + + hname, aliases, address_list = gethost_common("", hostent) + if hostent and hostent.contents.h_name and hostent.contents.h_addr_list[0]: + return hostent.contents.h_name + else: + return hostname + +def get_addr(hostname, socktype, protocol, port, address_to_fill): + hostent = _c.gethostbyname(hostname) + + if not hostent: + raise GAIError(EAI_FAIL) + + hname, aliases, address_list = gethost_common("", hostent) + + result = [] + + for address in address_list: + if address.addr.sa_family == _c.AF_INET: + a = cast(pointer(address.addr), POINTER(_c.sockaddr_in)).contents + a.sin_port = port & 0xffff + addr = make_address(pointer(address.addr),address.addrlen,address_to_fill) + result.append((address.addr.sa_family, + socktype, + protocol, + "", # XXX canonname? + addr)) + + return result Modified: pypy/dist/pypy/rlib/getnameinfo.py ============================================================================== --- pypy/dist/pypy/rlib/getnameinfo.py (original) +++ pypy/dist/pypy/rlib/getnameinfo.py Wed Apr 18 16:00:54 2007 @@ -1,68 +1,68 @@ -""" -An RPython implementation of getnameinfo() based on ctypes. -This is a rewrite of the CPython source: Modules/getaddrinfo.c -""" -from ctypes import POINTER, sizeof, cast, pointer -from pypy.rlib import _rsocket_ctypes as _c -from pypy.rlib.rsocket import RSocketError, GAIError - -NI_NOFQDN = 0x00000001 -NI_NUMERICHOST = 0x00000002 -NI_NAMEREQD = 0x00000004 -NI_NUMERICSERV = 0x00000008 -NI_DGRAM = 0x00000010 - -def _getservicename(sin_port, flags): - if flags & NI_NUMERICSERV: - sp = None - elif flags & NI_DGRAM: - sp = _c.getservbyport(sin_port, "udp") - else: - sp = _c.getservbyport(sin_port, "tcp") - - if sp: - serv = sp.contents.s_name - else: - serv = "%d" % _c.ntohs(sin_port) - - return serv - - -def getnameinfo(_addr, flags): - addr = _addr.addr - - if addr.sa_family != _c.AF_INET: - raise RSocketError("unknown address family") - - sockaddr = cast(pointer(addr), POINTER(_c.sockaddr_in)).contents - sin_port = sockaddr.sin_port - sin_addr = sockaddr.sin_addr - - v4a = _c.ntohl(sin_addr.s_addr) - if (v4a & 0xf0000000 == 0xe0000000 or # IN_MULTICAST() - v4a & 0xe0000000 == 0xe0000000): # IN_EXPERIMENTAL() - flags |= NI_NUMERICHOST - # XXX Why does this work in CPython? - # v4a >>= 24 # = IN_CLASSA_NSHIFT - # if v4a in (0, 127): # = IN_LOOPBACKNET - # flags |= NI_NUMERICHOST - numsize = _c.INET_ADDRSTRLEN - - serv = _getservicename(sin_port, flags) - - if not (flags & NI_NUMERICHOST): - hostent = _c.gethostbyaddr(pointer(sin_addr), sizeof(_c.in_addr), addr.sa_family) - else: - hostent = None - - if hostent: - from pypy.rlib.rsocket import gethost_common - host, _, _ = gethost_common("", hostent) - else: - from pypy.rlib.rsocket import copy_buffer - host = _c.inet_ntoa(sin_addr) - #buf = copy_buffer(ptr, len(ptr)) - #host = buf.raw - - return host, serv - +""" +An RPython implementation of getnameinfo() based on ctypes. +This is a rewrite of the CPython source: Modules/getaddrinfo.c +""" +from ctypes import POINTER, sizeof, cast, pointer +from pypy.rlib import _rsocket_ctypes as _c +from pypy.rlib.rsocket import RSocketError, GAIError + +NI_NOFQDN = 0x00000001 +NI_NUMERICHOST = 0x00000002 +NI_NAMEREQD = 0x00000004 +NI_NUMERICSERV = 0x00000008 +NI_DGRAM = 0x00000010 + +def _getservicename(sin_port, flags): + if flags & NI_NUMERICSERV: + sp = None + elif flags & NI_DGRAM: + sp = _c.getservbyport(sin_port, "udp") + else: + sp = _c.getservbyport(sin_port, "tcp") + + if sp: + serv = sp.contents.s_name + else: + serv = "%d" % _c.ntohs(sin_port) + + return serv + + +def getnameinfo(_addr, flags): + addr = _addr.addr + + if addr.sa_family != _c.AF_INET: + raise RSocketError("unknown address family") + + sockaddr = cast(pointer(addr), POINTER(_c.sockaddr_in)).contents + sin_port = sockaddr.sin_port + sin_addr = sockaddr.sin_addr + + v4a = _c.ntohl(sin_addr.s_addr) + if (v4a & 0xf0000000 == 0xe0000000 or # IN_MULTICAST() + v4a & 0xe0000000 == 0xe0000000): # IN_EXPERIMENTAL() + flags |= NI_NUMERICHOST + # XXX Why does this work in CPython? + # v4a >>= 24 # = IN_CLASSA_NSHIFT + # if v4a in (0, 127): # = IN_LOOPBACKNET + # flags |= NI_NUMERICHOST + numsize = _c.INET_ADDRSTRLEN + + serv = _getservicename(sin_port, flags) + + if not (flags & NI_NUMERICHOST): + hostent = _c.gethostbyaddr(pointer(sin_addr), sizeof(_c.in_addr), addr.sa_family) + else: + hostent = None + + if hostent: + from pypy.rlib.rsocket import gethost_common + host, _, _ = gethost_common("", hostent) + else: + from pypy.rlib.rsocket import copy_buffer + host = _c.inet_ntoa(sin_addr) + #buf = copy_buffer(ptr, len(ptr)) + #host = buf.raw + + return host, serv + From ale at codespeak.net Wed Apr 18 21:37:39 2007 From: ale at codespeak.net (ale at codespeak.net) Date: Wed, 18 Apr 2007 21:37:39 +0200 (CEST) Subject: [pypy-svn] r42157 - pypy/dist/pypy/lib/pyontology/test Message-ID: <20070418193739.59A1A808D@code0.codespeak.net> Author: ale Date: Wed Apr 18 21:37:37 2007 New Revision: 42157 Modified: pypy/dist/pypy/lib/pyontology/test/test_sparql.py pypy/dist/pypy/lib/pyontology/test/testont2.rdf Log: Changed the query 'query1' to not query for subclass of individuals (which doesnt make sense). Added correct xml date type to testont2. Changed query2 to query for supportedBy. Modified: pypy/dist/pypy/lib/pyontology/test/test_sparql.py ============================================================================== --- pypy/dist/pypy/lib/pyontology/test/test_sparql.py (original) +++ pypy/dist/pypy/lib/pyontology/test/test_sparql.py Wed Apr 18 21:37:37 2007 @@ -8,6 +8,7 @@ from pypy.lib.pyontology.sparql_grammar import SPARQLGrammar as SP from pypy.lib.pyontology.pyontology import Ontology, ConsistencyFailure +import datetime import os import pypy.lib.pyontology @@ -205,10 +206,11 @@ query1 = """ PREFIX ltw : PREFIX owl : + PREFIX rdf : SELECT ?person ?activity WHERE { - ?activity owl:subClassOf ltw:Active_Project . - ?person_obj owl:subClassOf ltw:Active_Person . + ?activity rdf:type ltw:Active_Project . + ?person_obj rdf:type ltw:Active_Person . ?activity ltw:hasParticipant ?person_obj . ?person_obj ltw:personName ?person . } @@ -219,7 +221,7 @@ PREFIX owl : SELECT ?project ?date_begin WHERE { - ?project ltw:funded_by ltw:BMBF . + ?project ltw:supportedBy ltw:BMBF . ?project ltw:dateStart ?date_begin . ?project ltw:dateEnd ?date_end . FILTER ( ?date_begin < 2007 && ?date_end >= 2006) . @@ -228,11 +230,13 @@ query3 = """ PREFIX ltw : PREFIX owl : + PREFIX rdf : SELECT ?project WHERE { - ?project owl:subClassOf ltw:Active_Project . - ?project owl:subClassOf ltw:Semantic_Web . - ?project ltw:supportedby ?x . + ?project rdf:type ltw:Active_Project . + ?project ltw:lt_technologicalMethod ?y . + ?y rdf:type ltw:Semantic_Web . + ?project ltw:supportedBy ?x . }""" def test_query1(): @@ -252,9 +256,9 @@ O.attach_fd() res = O.sparql(query2) - assert len(res) == 1 - assert res[0]['activity'] == u'http://www.lt-world.org/ltw.owl#obj_59754' - assert res[0]['person'] == u'\nKlara Vicsi' + assert len(res) == 2 + assert res[0]['project'] == u'http://www.lt-world.org/ltw.owl#obj_59754' + assert res[0]['date_begin'] == datetime.date(1998,9,1) def test_query3(): #py.test.skip("Doesn't work yet") Modified: pypy/dist/pypy/lib/pyontology/test/testont2.rdf ============================================================================== --- pypy/dist/pypy/lib/pyontology/test/testont2.rdf (original) +++ pypy/dist/pypy/lib/pyontology/test/testont2.rdf Wed Apr 18 21:37:37 2007 @@ -72,7 +72,7 @@ - + 1998-09-01 A Multimedia Multilingual Teaching and Training System for Speech Handicapped Children @@ -86,7 +86,7 @@ vicsi at ttt-202.ttt.bme.hu http://www.hltcentral.org/projects - + 2001-08-31 http://www.hltcentral.org/projects/detail.php?acronym=SPECO From afa at codespeak.net Thu Apr 19 11:05:52 2007 From: afa at codespeak.net (afa at codespeak.net) Date: Thu, 19 Apr 2007 11:05:52 +0200 (CEST) Subject: [pypy-svn] r42162 - in pypy/dist/pypy/annotation: . test Message-ID: <20070419090552.16B138092@code0.codespeak.net> Author: afa Date: Thu Apr 19 11:05:51 2007 New Revision: 42162 Modified: pypy/dist/pypy/annotation/bookkeeper.py pypy/dist/pypy/annotation/test/test_annrpython.py Log: Allow annotation of large unsigned constants like 0xF0000000 Modified: pypy/dist/pypy/annotation/bookkeeper.py ============================================================================== --- pypy/dist/pypy/annotation/bookkeeper.py (original) +++ pypy/dist/pypy/annotation/bookkeeper.py Thu Apr 19 11:05:51 2007 @@ -316,6 +316,8 @@ result = SomeBool() elif tp is int: result = SomeInteger(nonneg = x>=0) + elif tp is long and 0 <= x <= (sys.maxint * 2 + 1): + result = SomeInteger(unsigned = True) elif issubclass(tp, str): # py.lib uses annotated str subclasses if len(x) == 1: result = SomeChar() 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 Apr 19 11:05:51 2007 @@ -1,6 +1,7 @@ import autopath import py.test +import sys from pypy import conftest from pypy.tool.udir import udir @@ -824,6 +825,14 @@ s = a.build_types(f, [r_uint]) assert s == annmodel.SomeInteger(nonneg = True, unsigned = True) + def test_large_unsigned(self): + large_constant = sys.maxint * 2 + 1 # 0xFFFFFFFF on 32-bit platforms + def f(): + return large_constant + a = self.RPythonAnnotator() + s = a.build_types(f, []) + assert s.knowntype == r_uint + def test_pbc_getattr(self): class C: def __init__(self, v1, v2): From afa at codespeak.net Thu Apr 19 13:49:03 2007 From: afa at codespeak.net (afa at codespeak.net) Date: Thu, 19 Apr 2007 13:49:03 +0200 (CEST) Subject: [pypy-svn] r42168 - pypy/dist/pypy/rlib Message-ID: <20070419114903.466C780A5@code0.codespeak.net> Author: afa Date: Thu Apr 19 13:49:03 2007 New Revision: 42168 Modified: pypy/dist/pypy/rlib/_rsocket_ctypes.py pypy/dist/pypy/rlib/rsocket.py Log: rsocket and signedness: SOCKET is unsigned on win32, when fd is signed on Unix. + socklen_t is signed on windows + use WSAEINPROGRESS when EINPROGRESS is not defined. Now pypy-c --withmod-rsocket translates, up to C code generation! Next task: socket structures should not be redefined in structdef.h. Modified: pypy/dist/pypy/rlib/_rsocket_ctypes.py ============================================================================== --- pypy/dist/pypy/rlib/_rsocket_ctypes.py (original) +++ pypy/dist/pypy/rlib/_rsocket_ctypes.py Thu Apr 19 13:49:03 2007 @@ -67,8 +67,11 @@ POLLIN = ctypes_platform.DefinedConstantInteger('POLLIN') POLLOUT = ctypes_platform.DefinedConstantInteger('POLLOUT') EINPROGRESS = ctypes_platform.DefinedConstantInteger('EINPROGRESS') - EWOULDBLOCK = ctypes_platform.DefinedConstantInteger('EWOULDBLOCK') - EAFNOSUPPORT = ctypes_platform.DefinedConstantInteger('EAFNOSUPPORT') + WSAEINPROGRESS = ctypes_platform.DefinedConstantInteger('WSAEINPROGRESS') + EWOULDBLOCK = ctypes_platform.DefinedConstantInteger('EWOULDBLOCK') + WSAEWOULDBLOCK = ctypes_platform.DefinedConstantInteger('WSAEWOULDBLOCK') + EAFNOSUPPORT = ctypes_platform.DefinedConstantInteger('EAFNOSUPPORT') + WSAEAFNOSUPPORT = ctypes_platform.DefinedConstantInteger('WSAEAFNOSUPPORT') constant_names = ''' AF_AAL5 AF_APPLETALK AF_ASH AF_ATMPVC AF_ATMSVC AF_AX25 AF_BLUETOOTH AF_BRIDGE AD_DECnet AF_ECONET AF_INET AF_INET6 AF_IPX AF_IRDA AF_KEY AF_LLC AF_NETBEUI @@ -170,6 +173,11 @@ CConfig.ssize_t = ctypes_platform.SimpleType('ssize_t', c_int) CConfig.socklen_t = ctypes_platform.SimpleType('socklen_t', c_int) +if _MS_WINDOWS: + socketfd_type = c_uint +else: + socketfd_type = c_int + # struct types CConfig.sockaddr = ctypes_platform.Struct('struct sockaddr', [('sa_family', c_int), @@ -236,7 +244,7 @@ if _POSIX: CConfig.nfds_t = ctypes_platform.SimpleType('nfds_t') CConfig.pollfd = ctypes_platform.Struct('struct pollfd', - [('fd', c_int), + [('fd', socketfd_type), ('events', c_short), ('revents', c_short)]) @@ -246,9 +254,9 @@ if _MS_WINDOWS: CConfig.fd_set = ctypes_platform.Struct('struct fd_set', - [('fd_count', c_uint), - # XXX use FD_SETSIZE - ('fd_array', c_uint * 64)]) + [('fd_count', c_uint), + # XXX use FD_SETSIZE + ('fd_array', socketfd_type * 64)]) if _MS_WINDOWS: CConfig.WSAData = ctypes_platform.Struct('struct WSAData', @@ -297,9 +305,9 @@ INET6_ADDRSTRLEN = cConfig.INET6_ADDRSTRLEN POLLIN = cConfig.POLLIN POLLOUT = cConfig.POLLOUT -EINPROGRESS = cConfig.EINPROGRESS -EWOULDBLOCK = cConfig.EWOULDBLOCK -EAFNOSUPPORT = cConfig.EAFNOSUPPORT +EINPROGRESS = cConfig.EINPROGRESS or cConfig.WSAEINPROGRESS +EWOULDBLOCK = cConfig.EWOULDBLOCK or cConfig.WSAEWOULDBLOCK +EAFNOSUPPORT = cConfig.EAFNOSUPPORT or cConfig.WSAEAFNOSUPPORT linux = cConfig.linux MS_WINDOWS = cConfig.MS_WINDOWS @@ -307,7 +315,7 @@ if MS_WINDOWS: def invalid_socket(fd): - return c_uint(fd).value == INVALID_SOCKET + return fd == INVALID_SOCKET INVALID_SOCKET = cConfig.INVALID_SOCKET else: def invalid_socket(fd): @@ -355,8 +363,8 @@ if _POSIX: dup = socketdll.dup - dup.argtypes = [c_int] - dup.restype = c_int + dup.argtypes = [socketfd_type] + dup.restype = socketfd_type #errno = c_int.in_dll(socketdll, 'errno') @@ -377,17 +385,17 @@ socket = socketdll.socket socket.argtypes = [c_int, c_int, c_int] -socket.restype = c_int +socket.restype = socketfd_type if MS_WINDOWS: socketclose = socketdll.closesocket else: socketclose = socketdll.close -socketclose.argtypes = [c_int] +socketclose.argtypes = [socketfd_type] socketclose.restype = c_int socketconnect = socketdll.connect -socketconnect.argtypes = [c_int, sockaddr_ptr, socklen_t] +socketconnect.argtypes = [socketfd_type, sockaddr_ptr, socklen_t] socketconnect.restype = c_int if not MS_WINDOWS: @@ -445,59 +453,59 @@ inet_addr.restype = c_uint socketaccept = socketdll.accept -socketaccept.argtypes = [c_int, sockaddr_ptr, POINTER(socklen_t)] -socketaccept.restype = c_int +socketaccept.argtypes = [socketfd_type, sockaddr_ptr, POINTER(socklen_t)] +socketaccept.restype = socketfd_type socketbind = socketdll.bind -socketbind.argtypes = [c_int, sockaddr_ptr, socklen_t] +socketbind.argtypes = [socketfd_type, sockaddr_ptr, socklen_t] socketbind.restype = c_int socketlisten = socketdll.listen -socketlisten.argtypes = [c_int, c_int] +socketlisten.argtypes = [socketfd_type, c_int] socketlisten.restype = c_int socketgetpeername = socketdll.getpeername -socketgetpeername.argtypes = [c_int, sockaddr_ptr, POINTER(socklen_t)] +socketgetpeername.argtypes = [socketfd_type, sockaddr_ptr, POINTER(socklen_t)] socketgetpeername.restype = c_int socketgetsockname = socketdll.getsockname -socketgetsockname.argtypes = [c_int, sockaddr_ptr, POINTER(socklen_t)] +socketgetsockname.argtypes = [socketfd_type, sockaddr_ptr, POINTER(socklen_t)] socketgetsockname.restype = c_int socketgetsockopt = socketdll.getsockopt -socketgetsockopt.argtypes = [c_int, c_int, c_int, +socketgetsockopt.argtypes = [socketfd_type, c_int, c_int, c_void_p, POINTER(socklen_t)] socketgetsockopt.restype = c_int socketsetsockopt = socketdll.setsockopt -socketsetsockopt.argtypes = [c_int, c_int, c_int, +socketsetsockopt.argtypes = [socketfd_type, c_int, c_int, c_void_p, #this should be constant socklen_t] socketsetsockopt.restype = c_int socketrecv = socketdll.recv -socketrecv.argtypes = [c_int, c_void_p, c_int, c_int] +socketrecv.argtypes = [socketfd_type, c_void_p, c_int, c_int] socketrecv.recv = ssize_t recvfrom = socketdll.recvfrom -recvfrom.argtypes = [c_int, c_void_p, size_t, +recvfrom.argtypes = [socketfd_type, c_void_p, size_t, c_int, sockaddr_ptr, POINTER(socklen_t)] recvfrom.restype = ssize_t send = socketdll.send -send.argtypes = [c_int, +send.argtypes = [socketfd_type, c_void_p, #this should be constant size_t, c_int] send.restype = ssize_t sendto = socketdll.sendto -sendto.argtypes = [c_int, c_void_p, #this should be constant +sendto.argtypes = [socketfd_type, c_void_p, #this should be constant size_t, c_int, sockaddr_ptr, #this should be const socklen_t] sendto.restype = ssize_t socketshutdown = socketdll.shutdown -socketshutdown.argtypes = [c_int, c_int] +socketshutdown.argtypes = [socketfd_type, c_int] socketshutdown.restype = c_int gethostname = socketdll.gethostname @@ -526,17 +534,17 @@ if _POSIX: fcntl = socketdll.fcntl - fcntl.argtypes = [c_int] * 3 + fcntl.argtypes = [socketfd_type, c_int, c_int] fcntl.restype = c_int - socketpair_t = ARRAY(c_int, 2) + socketpair_t = ARRAY(socketfd_type, 2) socketpair = socketdll.socketpair socketpair.argtypes = [c_int, c_int, c_int, POINTER(socketpair_t)] socketpair.restype = c_int if _MS_WINDOWS: ioctlsocket = socketdll.ioctlsocket - ioctlsocket.argtypes = [c_int, c_long, POINTER(c_ulong)] + ioctlsocket.argtypes = [socketfd_type, c_long, POINTER(c_ulong)] ioctlsocket.restype = c_int Modified: pypy/dist/pypy/rlib/rsocket.py ============================================================================== --- pypy/dist/pypy/rlib/rsocket.py (original) +++ pypy/dist/pypy/rlib/rsocket.py Thu Apr 19 13:49:03 2007 @@ -656,7 +656,9 @@ res = _c.socketgetsockopt(self.fd, level, option, cast(buf, POINTER(c_char)), byref(bufsize)) if res < 0: raise self.error_handler() - return buf.raw[:bufsize.value] + size = bufsize.value + assert size > 0 # socklen_t is signed on Windows + return buf.raw[:size] def getsockopt_int(self, level, option): flag = _c.c_int() From fijal at codespeak.net Thu Apr 19 13:57:43 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 19 Apr 2007 13:57:43 +0200 (CEST) Subject: [pypy-svn] r42169 - pypy/dist/pypy/doc Message-ID: <20070419115743.B317E80A4@code0.codespeak.net> Author: fijal Date: Thu Apr 19 13:57:43 2007 New Revision: 42169 Modified: pypy/dist/pypy/doc/index.txt Log: Fix link to point to summary by default Modified: pypy/dist/pypy/doc/index.txt ============================================================================== --- pypy/dist/pypy/doc/index.txt (original) +++ pypy/dist/pypy/doc/index.txt Thu Apr 19 13:57:43 2007 @@ -171,7 +171,7 @@ .. _`EU reports`: index-report.html .. _`Technical reports`: index-report.html .. _`on Linux`: http://wyvern.cs.uni-duesseldorf.de/pypytest/summary.html -.. _`on Windows`: http://scottdial.com/pypytest/ +.. _`on Windows`: http://scottdial.com/pypytest/summary.html .. _`on built pypy-c`: http://wyvern.cs.uni-duesseldorf.de/~fijal/pypy-c-tests/ .. _`ideas for PyPy related projects`: project-ideas.html .. _`Nightly builds and benchmarks`: http://tuatara.cs.uni-duesseldorf.de/benchmark.html From fijal at codespeak.net Thu Apr 19 13:59:09 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 19 Apr 2007 13:59:09 +0200 (CEST) Subject: [pypy-svn] r42170 - pypy/branch/lib-distributed-rewrite Message-ID: <20070419115909.2544380AB@code0.codespeak.net> Author: fijal Date: Thu Apr 19 13:59:08 2007 New Revision: 42170 Added: pypy/branch/lib-distributed-rewrite/ - copied from r42169, pypy/dist/ Log: Create new branch for lib/distributed changes From fijal at codespeak.net Thu Apr 19 14:05:02 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 19 Apr 2007 14:05:02 +0200 (CEST) Subject: [pypy-svn] r42171 - pypy/branch/lib-distributed-rewrite/pypy/lib/distributed Message-ID: <20070419120502.6F4BE80AB@code0.codespeak.net> Author: fijal Date: Thu Apr 19 14:05:02 2007 New Revision: 42171 Added: pypy/branch/lib-distributed-rewrite/pypy/lib/distributed/faker.py Modified: pypy/branch/lib-distributed-rewrite/pypy/lib/distributed/objkeeper.py pypy/branch/lib-distributed-rewrite/pypy/lib/distributed/protocol.py Log: Check (completely broken) wc changes to avoid # XXX jeez comment Added: pypy/branch/lib-distributed-rewrite/pypy/lib/distributed/faker.py ============================================================================== --- (empty file) +++ pypy/branch/lib-distributed-rewrite/pypy/lib/distributed/faker.py Thu Apr 19 14:05:02 2007 @@ -0,0 +1,31 @@ + +""" This file is responsible for faking types +""" + +class GetSetDescriptor(object): + def __init__(self, protocol): + self.protocol = protocol + + def __get__(self, obj, type=None): + return self.protocol.get(obj, type) + + def __set__(self, obj, value): + self.protocol.set(obj, value) + +class GetDescriptor(object): + def __init__(self, protocol): + self.protocol = protocol + + def __get__(self, obj, type=None): + return self.protocol.get(obj, type) + +# these are one-go functions for wrapping/unwrapping types, +# note that actual caching is defined in other files, +# this is only the case when we *need* to wrap/unwrap +# type + +def wrap_type(tp): + pass + +def unwrap_type(name, bases_w, dict_w): + pass Modified: pypy/branch/lib-distributed-rewrite/pypy/lib/distributed/objkeeper.py ============================================================================== --- pypy/branch/lib-distributed-rewrite/pypy/lib/distributed/objkeeper.py (original) +++ pypy/branch/lib-distributed-rewrite/pypy/lib/distributed/objkeeper.py Thu Apr 19 14:05:02 2007 @@ -2,19 +2,8 @@ """ objkeeper - Storage for remoteprotocol """ -# XXX jeez - -import sys -try: - 1/0 -except: - _, _, tb = sys.exc_info() - GetSetDescriptor = type(type(tb).tb_frame) - -class RemoteBase(object): - pass - from types import FunctionType +from distributed import faker class ObjKeeper(object): def __init__(self, exported_names = {}): @@ -33,9 +22,10 @@ return len(self.exported_objects) - 1 def ignore(self, key, value): - if key in ('__dict__', '__weakref__', '__class__'): - return True - if isinstance(value, GetSetDescriptor): + # there are some attributes, which cannot be modified later, nor + # passed into default values, ignore them + if key in ('__dict__', '__weakref__', '__class__', + '__dict__', '__bases__'): return True return False @@ -51,6 +41,11 @@ # XXX: We don't support inheritance here, nor recursive types # shall we??? + ... + tp = faker.unwrap_type(tp, ...) + + + _dict = dict([(key, protocol.wrap(getattr(tp, key))) for key in dir(tp) if not self.ignore(key, getattr(tp, key))]) protocol.send(("type_reg", (tp_id, @@ -58,13 +53,15 @@ return tp_id 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]) # some stuff needs to go first... if '__doc__' in _dict: d['__doc__'] = protocol.unwrap(_dict['__doc__']) - tp = type(_name, (RemoteBase,), d) + tp = type(_name, (object,), d) # Make sure we cannot instantiate the remote type self.remote_types[type_id] = tp self.reverse_remote_types[tp] = type_id @@ -91,3 +88,4 @@ def get_remote_object(self, controller): return self.remote_objects[controller] + Modified: pypy/branch/lib-distributed-rewrite/pypy/lib/distributed/protocol.py ============================================================================== --- pypy/branch/lib-distributed-rewrite/pypy/lib/distributed/protocol.py (original) +++ pypy/branch/lib-distributed-rewrite/pypy/lib/distributed/protocol.py Thu Apr 19 14:05:02 2007 @@ -41,7 +41,7 @@ except ImportError: raise ImportError("Cannot work without transparent proxy functionality") -from distributed.objkeeper import ObjKeeper, RemoteBase +from distributed.objkeeper import ObjKeeper import sys # XXX We do not make any garbage collection. We'll need it at some point @@ -62,6 +62,10 @@ from marshal import dumps import exceptions +class RemoteBase(object): + pass +# just placeholder for letter_types value + class AbstractProtocol(object): immutable_primitives = (str, int, float, long, unicode, bool, types.NotImplementedType) mutable_primitives = (list, dict, types.FunctionType, types.FrameType, types.TracebackType, @@ -132,8 +136,10 @@ id = self.keeper.register_object(obj) return (self.type_letters[tp], id) elif tp is type: - if issubclass(obj, RemoteBase): + try: return "reg", self.keeper.reverse_remote_types[obj] + except KeyError: + pass try: return self.type_letters[tp], self.type_letters[obj] except KeyError: From arigo at codespeak.net Thu Apr 19 18:23:06 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 19 Apr 2007 18:23:06 +0200 (CEST) Subject: [pypy-svn] r42179 - in pypy/branch/pypy-string-formatting/objspace/std: . test Message-ID: <20070419162306.9F78D80A5@code0.codespeak.net> Author: arigo Date: Thu Apr 19 18:23:06 2007 New Revision: 42179 Modified: pypy/branch/pypy-string-formatting/objspace/std/formatting.py pypy/branch/pypy-string-formatting/objspace/std/test/test_stringformat.py Log: More stuff... Modified: pypy/branch/pypy-string-formatting/objspace/std/formatting.py ============================================================================== --- pypy/branch/pypy-string-formatting/objspace/std/formatting.py (original) +++ pypy/branch/pypy-string-formatting/objspace/std/formatting.py Thu Apr 19 18:23:06 2007 @@ -91,6 +91,47 @@ return w_value + def peel_flags(self): + self.f_ljust = False + self.f_sign = False + self.f_blank = False + self.f_alt = False + self.f_zero = False + while True: + c = self.peekchr() + if c == '-': + self.f_ljust = True + elif c == '+': + self.f_sign = True + elif c == ' ': + self.f_blank = True + elif c == '#': + self.f_alt = True + elif c == '0': + self.f_zero = True + else: + break + self.forward() + + def peel_num(self): + space = self.space + c = self.peekchr() + if c == '*': + self.forward() + w_value = self.nextinputvalue() + return space.int_w(maybe_int(space, w_value)) + result = 0 + while '0' <= c <= '9': + n = ord(c) - ord('0') + try: + result = ovfcheck(ovfcheck(result * 10) + n) + except OverflowError: + raise OperationError(space.w_OverflowError, + space.wrap("precision too large")) + self.forward() + c = self.peekchr() + return result + def format(self): result = [] # list of characters self.result = result @@ -155,5 +196,57 @@ formatter = StringFormatter(space, fmt, values_w, w_valuedict) return formatter.format() +# ____________________________________________________________ +# Formatting helpers -... +def maybe_int(space, w_value): + # make sure that w_value is a wrapped integer + return space.int(w_value) + +def numeric_preprocess(v, flags): + # negative zeroes? + # * mwh giggles, falls over + # still, if we can recognize them, here's the place to do it. + import math + if v < 0 or v == 0 and isinstance(v, float) and math.atan2(0, v) != 0: + sign = '-' + v = -v + else: + if flags.f_sign: + sign = '+' + elif flags.f_blank: + sign = ' ' + else: + sign = '' + return v, sign +#numeric_preprocess._annspecialcase_ = 'specialize:argtype(0)' + +def format_num_helper_generator(fun_name, fun): + def format_num_helper(formatter, w_value): + w_value = maybe_int(formatter.space, w_value) + try: + value = space.int_w(w_value) + value, sign = numeric_preprocess(value, formatter) + return (fun(value), sign) + except OperationError, operr: + # XXX: Fix it, this is obviously inefficient + if not operr.match(space, space.w_OverflowError): + raise + if space.is_true(space.lt(v, space.wrap(0))): + sign = '-' + v = space.neg(v) + else: + if flags.f_sign: + sign = '+' + elif flags.f_blank: + sign = ' ' + else: + sign = '' + val = space.str_w(getattr(space, fun_name)(v)) + return (val, sign) + format_num_helper.func_name = fun_name + '_num_helper' + return format_num_helper + +hex_num_helper = format_num_helper_generator('hex', hex) +oct_num_helper = format_num_helper_generator('oct', oct) +int_num_helper = format_num_helper_generator('str', str) Modified: pypy/branch/pypy-string-formatting/objspace/std/test/test_stringformat.py ============================================================================== --- pypy/branch/pypy-string-formatting/objspace/std/test/test_stringformat.py (original) +++ pypy/branch/pypy-string-formatting/objspace/std/test/test_stringformat.py Thu Apr 19 18:23:06 2007 @@ -84,6 +84,8 @@ assert '0x0' == '%#x' % 0 assert '23' == '%s' % 23 assert '23' == '%r' % 23 + assert ('%d' % (-sys.maxint-1,) == '-' + str(sys.maxint+1) + == '-%d' % (sys.maxint+1,)) def test_format_list(self): assert '<[1, 2]>' == '<%s>' % [1,2] From arigo at codespeak.net Thu Apr 19 19:01:47 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 19 Apr 2007 19:01:47 +0200 (CEST) Subject: [pypy-svn] r42182 - in pypy/branch/pypy-string-formatting: interpreter module/math objspace/cpy objspace/fake objspace/std rlib Message-ID: <20070419170147.ADEB880AD@code0.codespeak.net> Author: arigo Date: Thu Apr 19 19:01:47 2007 New Revision: 42182 Modified: pypy/branch/pypy-string-formatting/interpreter/baseobjspace.py pypy/branch/pypy-string-formatting/module/math/interp_math.py pypy/branch/pypy-string-formatting/objspace/cpy/objspace.py pypy/branch/pypy-string-formatting/objspace/fake/objspace.py pypy/branch/pypy-string-formatting/objspace/std/floatobject.py pypy/branch/pypy-string-formatting/objspace/std/longobject.py pypy/branch/pypy-string-formatting/rlib/rbigint.py Log: (cfbolz, arigo) Kill space.log(), which was used in exactly one place. Use space.bigint_w() instead, now that we have it. Modified: pypy/branch/pypy-string-formatting/interpreter/baseobjspace.py ============================================================================== --- pypy/branch/pypy-string-formatting/interpreter/baseobjspace.py (original) +++ pypy/branch/pypy-string-formatting/interpreter/baseobjspace.py Thu Apr 19 19:01:47 2007 @@ -1015,6 +1015,5 @@ 'newslice', 'call_args', 'marshal_w', - 'log', ] Modified: pypy/branch/pypy-string-formatting/module/math/interp_math.py ============================================================================== --- pypy/branch/pypy-string-formatting/module/math/interp_math.py (original) +++ pypy/branch/pypy-string-formatting/module/math/interp_math.py Thu Apr 19 19:01:47 2007 @@ -137,14 +137,28 @@ degrees.unwrap_spec = [ObjSpace, float] def _log_any(space, w_x, base): + # base is supposed to be positive or 0.0, which means we use e try: - return space.log(w_x, base) + if space.is_true(space.isinstance(w_x, space.w_long)): + # special case to support log(extremely-large-long) + num = space.bigint_w(w_x) + result = num.log(base) + else: + x = space.float_w(w_x) + if base == 10.0: + result = math.log10(x) + else: + result = math.log(x) + if base != 0.0: + den = math.log(base) + result /= den except OverflowError: raise OperationError(space.w_OverflowError, space.wrap('math range error')) except ValueError: raise OperationError(space.w_ValueError, space.wrap('math domain error')) + return space.wrap(result) def log(space, w_x, w_base=NoneNotWrapped): """log(x[, base]) -> the logarithm of x to the given base. Modified: pypy/branch/pypy-string-formatting/objspace/cpy/objspace.py ============================================================================== --- pypy/branch/pypy-string-formatting/objspace/cpy/objspace.py (original) +++ pypy/branch/pypy-string-formatting/objspace/cpy/objspace.py Thu Apr 19 19:01:47 2007 @@ -366,7 +366,6 @@ def delete(self, *args): raise NotImplementedError("space.delete()") def userdel(self, *args): raise NotImplementedError("space.userdel()") def marshal_w(self, *args):raise NotImplementedError("space.marshal_w()") - def log(self, *args): raise NotImplementedError("space.log()") def exec_(self, statement, w_globals, w_locals, hidden_applevel=False): "NOT_RPYTHON" Modified: pypy/branch/pypy-string-formatting/objspace/fake/objspace.py ============================================================================== --- pypy/branch/pypy-string-formatting/objspace/fake/objspace.py (original) +++ pypy/branch/pypy-string-formatting/objspace/fake/objspace.py Thu Apr 19 19:01:47 2007 @@ -126,7 +126,6 @@ def delete(self, *args): raise NotImplementedError("space.delete()") def userdel(self, *args): raise NotImplementedError("space.userdel()") def marshal_w(self, *args):raise NotImplementedError("space.marshal_w()") - def log(self, *args): raise NotImplementedError("space.log()") gettypefor = make_dummy() gettypeobject = make_dummy() Modified: pypy/branch/pypy-string-formatting/objspace/std/floatobject.py ============================================================================== --- pypy/branch/pypy-string-formatting/objspace/std/floatobject.py (original) +++ pypy/branch/pypy-string-formatting/objspace/std/floatobject.py Thu Apr 19 19:01:47 2007 @@ -389,19 +389,6 @@ def getnewargs__Float(space, w_float): return space.newtuple([W_FloatObject(w_float.floatval)]) -def log__Float(space, w_float, base): - # base is supposed to be positive or 0.0, which means we use e - x = space.float_w(w_float) - if base == 10.0: - return space.wrap(math.log10(x)) - num = math.log(x) - if base == 0.0: - return space.wrap(num) - else: - den = math.log(base) - return space.wrap(num / den) - - register_all(vars()) # pow delegation for negative 2nd arg Modified: pypy/branch/pypy-string-formatting/objspace/std/longobject.py ============================================================================== --- pypy/branch/pypy-string-formatting/objspace/std/longobject.py (original) +++ pypy/branch/pypy-string-formatting/objspace/std/longobject.py Thu Apr 19 19:01:47 2007 @@ -254,9 +254,6 @@ def getnewargs__Long(space, w_long1): return space.newtuple([W_LongObject(w_long1.num)]) -def log__Long(space, w_long, base): - return space.wrap(w_long.num.log(base)) - register_all(vars()) # register implementations of ops that recover int op overflows Modified: pypy/branch/pypy-string-formatting/rlib/rbigint.py ============================================================================== --- pypy/branch/pypy-string-formatting/rlib/rbigint.py (original) +++ pypy/branch/pypy-string-formatting/rlib/rbigint.py Thu Apr 19 19:01:47 2007 @@ -1288,13 +1288,13 @@ def _loghelper(func, arg): """ A decent logarithm is easy to compute even for huge bigints, but libm can't - do that by itself -- loghelper can. func is log or log10, and name is - "log" or "log10". Note that overflow isn't possible: a bigint can contain + do that by itself -- loghelper can. func is log or log10. + Note that overflow isn't possible: a bigint can contain no more than INT_MAX * SHIFT bits, so has value certainly less than 2**(2**64 * 2**16) == 2**2**80, and log2 of that is 2**80, which is small enough to fit in an IEEE single. log and log10 are even smaller. """ - x, e = _AsScaledDouble(arg); + x, e = _AsScaledDouble(arg) if x <= 0.0: raise ValueError # Value is ~= x * 2**(e*SHIFT), so the log ~= From fijal at codespeak.net Thu Apr 19 22:29:43 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 19 Apr 2007 22:29:43 +0200 (CEST) Subject: [pypy-svn] r42184 - in pypy/branch/lib-distributed-rewrite/pypy/lib/distributed: . test Message-ID: <20070419202943.6116C80AD@code0.codespeak.net> Author: fijal Date: Thu Apr 19 22:29:41 2007 New Revision: 42184 Modified: pypy/branch/lib-distributed-rewrite/pypy/lib/distributed/faker.py pypy/branch/lib-distributed-rewrite/pypy/lib/distributed/objkeeper.py pypy/branch/lib-distributed-rewrite/pypy/lib/distributed/protocol.py pypy/branch/lib-distributed-rewrite/pypy/lib/distributed/test/test_distributed.py Log: Some tests pass now, remote instantiation will not work, unless we provide wrappable bases. One failing test introduced, approaching. Modified: pypy/branch/lib-distributed-rewrite/pypy/lib/distributed/faker.py ============================================================================== --- pypy/branch/lib-distributed-rewrite/pypy/lib/distributed/faker.py (original) +++ pypy/branch/lib-distributed-rewrite/pypy/lib/distributed/faker.py Thu Apr 19 22:29:41 2007 @@ -3,29 +3,95 @@ """ class GetSetDescriptor(object): - def __init__(self, protocol): + def __init__(self, protocol, name): self.protocol = protocol + self.name = name def __get__(self, obj, type=None): - return self.protocol.get(obj, type) + return self.protocol.get(self.name, obj, type) def __set__(self, obj, value): - self.protocol.set(obj, value) + self.protocol.set(self.name, obj, value) class GetDescriptor(object): - def __init__(self, protocol): + def __init__(self, protocol, name): self.protocol = protocol + self.name = name def __get__(self, obj, type=None): - return self.protocol.get(obj, type) + return self.protocol.get(self.name, obj, type) # these are one-go functions for wrapping/unwrapping types, # note that actual caching is defined in other files, # this is only the case when we *need* to wrap/unwrap # type -def wrap_type(tp): - pass +from types import MethodType, FunctionType -def unwrap_type(name, bases_w, dict_w): - pass +def ignore(name): + # we don't want to fake some default descriptors, because + # they'll alter the way we set attributes + l = ['__dict__', '__weakref__', '__class__', '__bases__', + '__getattribute__', '__getattr__', '__setattr__', + '__delattr__'] + return not name in dict.fromkeys(l) + +def wrap_type(protocol, tp, tp_id): + """ Wrap type to transpotable entity, taking + care about descriptors + """ + print "Wrapping type %s" % tp.__name__ + if tp.__name__ == 'file': + import pdb + pdb.set_trace() + # XXX forget about bases right now + bases = [] + dict_w = {} + # XXX we do dir here because we've forgotten about basis + # above + for item in dir(tp): + value = getattr(tp, item) + if ignore(item): + # we've got shortcut for method + if hasattr(value, '__get__') and not type(value) is MethodType: + if hasattr(value, '__set__'): + print "GetSet %s" % value.__name__ + dict_w[item] = ('get', value.__name__) + else: + print "Get %s" % value.__name__ + dict_w[item] = ('set', value.__name__) + else: + dict_w[item] = protocol.wrap(value) + return tp_id, tp.__name__, dict_w, bases + +def unwrap_descriptor_gen(desc_class): + def unwrapper(protocol, data): + name = data + obj = desc_class(protocol, name) + obj.__name__ = name + return obj + return unwrapper + +unwrap_get_descriptor = unwrap_descriptor_gen(GetDescriptor) +unwrap_getset_descriptor = unwrap_descriptor_gen(GetSetDescriptor) + +def unwrap_type(objkeeper, protocol, type_id, name_, dict_w, bases_w): + """ Unwrap remote type, based on it's description + """ + # XXX sanity check + print "Faking type %s" % name_ + assert bases_w == [] + d = dict.fromkeys(dict_w) + # XXX we do it in two steps to avoid cyclic dependencies, + # probably there is some smarter way of doing this + if '__doc__' in dict_w: + d['__doc__'] = protocol.unwrap(dict_w['__doc__']) + tp = type(name_, (object,), d) + objkeeper.register_remote_type(tp, type_id) + for key, value in dict_w.items(): + if key != '__doc__': + v = protocol.unwrap(value) + if isinstance(v, FunctionType): + setattr(tp, key, staticmethod(v)) + else: + setattr(tp, key, v) Modified: pypy/branch/lib-distributed-rewrite/pypy/lib/distributed/objkeeper.py ============================================================================== --- pypy/branch/lib-distributed-rewrite/pypy/lib/distributed/objkeeper.py (original) +++ pypy/branch/lib-distributed-rewrite/pypy/lib/distributed/objkeeper.py Thu Apr 19 22:29:41 2007 @@ -38,23 +38,20 @@ self.exported_types_reverse[self.exported_types_id] = tp tp_id = self.exported_types_id self.exported_types_id += 1 - - # XXX: We don't support inheritance here, nor recursive types - # shall we??? - ... - tp = faker.unwrap_type(tp, ...) - - - _dict = dict([(key, protocol.wrap(getattr(tp, key))) for key in dir(tp) - if not self.ignore(key, getattr(tp, key))]) - protocol.send(("type_reg", (tp_id, - tp.__name__, _dict))) + protocol.send(('type_reg', faker.wrap_type(protocol, tp, tp_id))) return tp_id - def fake_remote_type(self, protocol, type_id, _name, _dict): - ... - + def fake_remote_type(self, protocol, tp_data): + type_id, name_, dict_w, bases_w = tp_data + tp = faker.unwrap_type(self, protocol, type_id, name_, dict_w, bases_w) + + def register_remote_type(self, tp, type_id): + self.remote_types[type_id] = tp + self.reverse_remote_types[tp] = type_id + return + + XXX - stuff #print "Faking type %s as %s" % (_name, type_id) # create and register new type d = dict([(key, None) for key in _dict]) Modified: pypy/branch/lib-distributed-rewrite/pypy/lib/distributed/protocol.py ============================================================================== --- pypy/branch/lib-distributed-rewrite/pypy/lib/distributed/protocol.py (original) +++ pypy/branch/lib-distributed-rewrite/pypy/lib/distributed/protocol.py Thu Apr 19 22:29:41 2007 @@ -42,6 +42,7 @@ raise ImportError("Cannot work without transparent proxy functionality") from distributed.objkeeper import ObjKeeper +from distributed import faker import sys # XXX We do not make any garbage collection. We'll need it at some point @@ -62,9 +63,16 @@ from marshal import dumps import exceptions +# just placeholders for letter_types value class RemoteBase(object): pass -# just placeholder for letter_types value + +class DataDescriptor(object): + pass + +class NonDataDescriptor(object): + pass +# end of placeholders class AbstractProtocol(object): immutable_primitives = (str, int, float, long, unicode, bool, types.NotImplementedType) @@ -95,7 +103,9 @@ 'tp' : None, 'fr' : types.FrameType, 'tb' : types.TracebackType, - 'reg' : RemoteBase + 'reg' : RemoteBase, + 'get' : NonDataDescriptor, + 'set' : DataDescriptor, } type_letters = dict([(value, key) for key, value in letter_types.items()]) assert len(type_letters) == len(letter_types) @@ -202,6 +212,10 @@ return self.letter_types[obj_data] id = obj_data return self.get_type(obj_data) + elif tp is DataDescriptor: + return faker.unwrap_getset_descriptor(self, obj_data) + elif tp is NonDataDescriptor: + return faker.unwrap_get_descriptor(self, obj_data) elif tp is object: # we need to create a proper type w_tp, id = obj_data @@ -292,8 +306,7 @@ exc, val, tb = unwrap(data) raise exc, val, tb elif command == 'type_reg': - type_id, name, _dict = data - protocol.keeper.fake_remote_type(protocol, type_id, name, _dict) + protocol.keeper.fake_remote_type(protocol, data) elif command == 'force': obj = protocol.keeper.get_object(data) w_obj = protocol.pack(obj) @@ -301,6 +314,17 @@ elif command == 'forced': obj = protocol.unpack(data) return obj + elif command == 'desc_get': + name, w_obj, w_type = data + obj = protocol.unwrap(w_obj) + type_ = protocol.unwrap(w_type) + send(('finished', protocol.wrap(getattr(type(obj), name).__get__(obj, type_)))) + elif command == 'desc_set': + name, w_obj, w_value = data + obj = protocol.unwrap(w_obj) + value = protocol.unwrap(w_value) + getattr(type(obj), name).__set__(obj, value) + send(('finished', protocol.wrap(None))) else: raise NotImplementedError("command %s" % command) @@ -353,6 +377,14 @@ else: raise NotImplementedError("Cannot unpack %s" % (data,)) + def get(self, name, obj, type): + self.send(("desc_get", (name, self.wrap(obj), self.wrap(type)))) + retval = remote_loop(self) + return retval + + def set(self, obj, value): + self.send(("desc_set", (name, self.wrap(obj), self.wrap(value)))) + class RemoteObject(object): def __init__(self, protocol, id): self.id = id Modified: pypy/branch/lib-distributed-rewrite/pypy/lib/distributed/test/test_distributed.py ============================================================================== --- pypy/branch/lib-distributed-rewrite/pypy/lib/distributed/test/test_distributed.py (original) +++ pypy/branch/lib-distributed-rewrite/pypy/lib/distributed/test/test_distributed.py Thu Apr 19 22:29:41 2007 @@ -219,8 +219,19 @@ res = xa.x() assert res == 8 + def test_types_reverse_mapping(self): + class A: + def m(self, tp): + assert type(self) is tp + + a = A() + protocol = self.test_env({'a':a, 'A':A}) + xa = protocol.get_remote('a') + xA = protocol.get_remote('A') + xa.m(xA) + def test_instantiate_remote_type(self): - #skip("Doesn't work yet") + skip("Will not work unless we take care about __basis__") class C: def __init__(self, y): self.y = y @@ -230,6 +241,15 @@ protocol = self.test_env({'C':C}) xC = protocol.get_remote('C') - res = xC(3).x() + xc = xC(3) + res = xc.x() assert res == 3 + def test_remote_sys(self): + import sys + + protocol = self.test_env({'sys':sys}) + s = protocol.get_remote('sys') + l = dir(s) + assert l + From fijal at codespeak.net Thu Apr 19 22:34:31 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 19 Apr 2007 22:34:31 +0200 (CEST) Subject: [pypy-svn] r42185 - in pypy/branch/lib-distributed-rewrite/pypy/lib/distributed: . test Message-ID: <20070419203431.7469080AD@code0.codespeak.net> Author: fijal Date: Thu Apr 19 22:34:30 2007 New Revision: 42185 Modified: pypy/branch/lib-distributed-rewrite/pypy/lib/distributed/faker.py pypy/branch/lib-distributed-rewrite/pypy/lib/distributed/test/test_distributed.py Log: Success! The remote file works (even faked one) Modified: pypy/branch/lib-distributed-rewrite/pypy/lib/distributed/faker.py ============================================================================== --- pypy/branch/lib-distributed-rewrite/pypy/lib/distributed/faker.py (original) +++ pypy/branch/lib-distributed-rewrite/pypy/lib/distributed/faker.py Thu Apr 19 22:34:30 2007 @@ -41,9 +41,9 @@ care about descriptors """ print "Wrapping type %s" % tp.__name__ - if tp.__name__ == 'file': - import pdb - pdb.set_trace() + #if tp.__name__ == 'file': + # import pdb + # pdb.set_trace() # XXX forget about bases right now bases = [] dict_w = {} @@ -54,12 +54,13 @@ if ignore(item): # we've got shortcut for method if hasattr(value, '__get__') and not type(value) is MethodType: + name = type(value).__name__ if hasattr(value, '__set__'): - print "GetSet %s" % value.__name__ - dict_w[item] = ('get', value.__name__) + print "GetSet %s" % name + dict_w[item] = ('get', name) else: - print "Get %s" % value.__name__ - dict_w[item] = ('set', value.__name__) + print "Get %s" % name + dict_w[item] = ('set', name) else: dict_w[item] = protocol.wrap(value) return tp_id, tp.__name__, dict_w, bases Modified: pypy/branch/lib-distributed-rewrite/pypy/lib/distributed/test/test_distributed.py ============================================================================== --- pypy/branch/lib-distributed-rewrite/pypy/lib/distributed/test/test_distributed.py (original) +++ pypy/branch/lib-distributed-rewrite/pypy/lib/distributed/test/test_distributed.py Thu Apr 19 22:34:30 2007 @@ -253,3 +253,12 @@ l = dir(s) assert l + def test_remote_file_access(self): + # cannot do test_env({'file':file}) yet :) + def f(name): + return open(name) + + protocol = self.test_env({'f':f}) + xf = protocol.get_remote('f') + data = xf('/etc/passwd').read() + assert data From fijal at codespeak.net Thu Apr 19 22:38:28 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 19 Apr 2007 22:38:28 +0200 (CEST) Subject: [pypy-svn] r42186 - pypy/branch/lib-distributed-rewrite/pypy/lib/distributed Message-ID: <20070419203828.EF5BC80AD@code0.codespeak.net> Author: fijal Date: Thu Apr 19 22:38:28 2007 New Revision: 42186 Modified: pypy/branch/lib-distributed-rewrite/pypy/lib/distributed/faker.py pypy/branch/lib-distributed-rewrite/pypy/lib/distributed/objkeeper.py Log: Remove debug prints Modified: pypy/branch/lib-distributed-rewrite/pypy/lib/distributed/faker.py ============================================================================== --- pypy/branch/lib-distributed-rewrite/pypy/lib/distributed/faker.py (original) +++ pypy/branch/lib-distributed-rewrite/pypy/lib/distributed/faker.py Thu Apr 19 22:38:28 2007 @@ -40,10 +40,6 @@ """ Wrap type to transpotable entity, taking care about descriptors """ - print "Wrapping type %s" % tp.__name__ - #if tp.__name__ == 'file': - # import pdb - # pdb.set_trace() # XXX forget about bases right now bases = [] dict_w = {} @@ -56,10 +52,8 @@ if hasattr(value, '__get__') and not type(value) is MethodType: name = type(value).__name__ if hasattr(value, '__set__'): - print "GetSet %s" % name dict_w[item] = ('get', name) else: - print "Get %s" % name dict_w[item] = ('set', name) else: dict_w[item] = protocol.wrap(value) @@ -80,7 +74,6 @@ """ Unwrap remote type, based on it's description """ # XXX sanity check - print "Faking type %s" % name_ assert bases_w == [] d = dict.fromkeys(dict_w) # XXX we do it in two steps to avoid cyclic dependencies, Modified: pypy/branch/lib-distributed-rewrite/pypy/lib/distributed/objkeeper.py ============================================================================== --- pypy/branch/lib-distributed-rewrite/pypy/lib/distributed/objkeeper.py (original) +++ pypy/branch/lib-distributed-rewrite/pypy/lib/distributed/objkeeper.py Thu Apr 19 22:38:28 2007 @@ -33,7 +33,6 @@ try: return self.exported_types[tp] 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 @@ -49,31 +48,7 @@ def register_remote_type(self, tp, type_id): self.remote_types[type_id] = tp self.reverse_remote_types[tp] = type_id - return - - XXX - stuff - #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... - if '__doc__' in _dict: - d['__doc__'] = protocol.unwrap(_dict['__doc__']) - tp = type(_name, (object,), d) - # Make sure we cannot instantiate the remote type - self.remote_types[type_id] = tp - self.reverse_remote_types[tp] = type_id - for key, value in _dict.items(): - if key != '__doc__': - 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() - # tp.new = value - + def get_type(self, id): return self.remote_types[id] From afa at codespeak.net Fri Apr 20 09:17:56 2007 From: afa at codespeak.net (afa at codespeak.net) Date: Fri, 20 Apr 2007 09:17:56 +0200 (CEST) Subject: [pypy-svn] r42189 - pypy/dist/pypy/rlib/parsing/test Message-ID: <20070420071756.90C5580AD@code0.codespeak.net> Author: afa Date: Fri Apr 20 09:17:55 2007 New Revision: 42189 Modified: pypy/dist/pypy/rlib/parsing/test/test_pythonparse.py Log: rlib parser: Open grammar file in text mode, and tests pass on Windows Modified: pypy/dist/pypy/rlib/parsing/test/test_pythonparse.py ============================================================================== --- pypy/dist/pypy/rlib/parsing/test/test_pythonparse.py (original) +++ pypy/dist/pypy/rlib/parsing/test/test_pythonparse.py Fri Apr 20 09:17:55 2007 @@ -7,7 +7,7 @@ from pypy.rlib.parsing.parsing import PackratParser, Symbol, ParseError, Rule from pypy.rlib.parsing.ebnfparse import parse_ebnf, make_parse_function -grammar = py.magic.autopath().dirpath().join("pygrammar.txt").read() +grammar = py.magic.autopath().dirpath().join("pygrammar.txt").read(mode='rt') def test_parse_grammar(): From fijal at codespeak.net Fri Apr 20 11:10:46 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 20 Apr 2007 11:10:46 +0200 (CEST) Subject: [pypy-svn] r42197 - in pypy/dist/pypy/lib/distributed: . test Message-ID: <20070420091046.A0E0080AD@code0.codespeak.net> Author: fijal Date: Fri Apr 20 11:10:44 2007 New Revision: 42197 Added: pypy/dist/pypy/lib/distributed/faker.py - copied unchanged from r42196, pypy/branch/lib-distributed-rewrite/pypy/lib/distributed/faker.py 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: Hum, history has gone. Anyway: * Added better type faker which is able to fake descriptors * Fixed few bugs * Added few tests * Now we cannot instantiate remote type as long as we don't take care for remote basis, but more faking 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 Apr 20 11:10:44 2007 @@ -2,19 +2,8 @@ """ objkeeper - Storage for remoteprotocol """ -# XXX jeez - -import sys -try: - 1/0 -except: - _, _, tb = sys.exc_info() - GetSetDescriptor = type(type(tb).tb_frame) - -class RemoteBase(object): - pass - from types import FunctionType +from distributed import faker class ObjKeeper(object): def __init__(self, exported_names = {}): @@ -33,9 +22,10 @@ return len(self.exported_objects) - 1 def ignore(self, key, value): - if key in ('__dict__', '__weakref__', '__class__'): - return True - if isinstance(value, GetSetDescriptor): + # there are some attributes, which cannot be modified later, nor + # passed into default values, ignore them + if key in ('__dict__', '__weakref__', '__class__', + '__dict__', '__bases__'): return True return False @@ -43,43 +33,22 @@ try: return self.exported_types[tp] 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 - - # XXX: We don't support inheritance here, nor recursive types - # shall we??? - _dict = dict([(key, protocol.wrap(getattr(tp, key))) for key in dir(tp) - if not self.ignore(key, getattr(tp, key))]) - protocol.send(("type_reg", (tp_id, - tp.__name__, _dict))) + + protocol.send(('type_reg', faker.wrap_type(protocol, tp, tp_id))) return tp_id - 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]) - # some stuff needs to go first... - if '__doc__' in _dict: - d['__doc__'] = protocol.unwrap(_dict['__doc__']) - tp = type(_name, (RemoteBase,), d) - # Make sure we cannot instantiate the remote type + def fake_remote_type(self, protocol, tp_data): + type_id, name_, dict_w, bases_w = tp_data + tp = faker.unwrap_type(self, protocol, type_id, name_, dict_w, bases_w) + + def register_remote_type(self, tp, type_id): self.remote_types[type_id] = tp self.reverse_remote_types[tp] = type_id - for key, value in _dict.items(): - if key != '__doc__': - 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() - # tp.new = value - + def get_type(self, id): return self.remote_types[id] @@ -91,3 +60,4 @@ def get_remote_object(self, controller): return self.remote_objects[controller] + Modified: pypy/dist/pypy/lib/distributed/protocol.py ============================================================================== --- pypy/dist/pypy/lib/distributed/protocol.py (original) +++ pypy/dist/pypy/lib/distributed/protocol.py Fri Apr 20 11:10:44 2007 @@ -41,7 +41,8 @@ except ImportError: raise ImportError("Cannot work without transparent proxy functionality") -from distributed.objkeeper import ObjKeeper, RemoteBase +from distributed.objkeeper import ObjKeeper +from distributed import faker import sys # XXX We do not make any garbage collection. We'll need it at some point @@ -62,6 +63,17 @@ from marshal import dumps import exceptions +# just placeholders for letter_types value +class RemoteBase(object): + pass + +class DataDescriptor(object): + pass + +class NonDataDescriptor(object): + pass +# end of placeholders + class AbstractProtocol(object): immutable_primitives = (str, int, float, long, unicode, bool, types.NotImplementedType) mutable_primitives = (list, dict, types.FunctionType, types.FrameType, types.TracebackType, @@ -91,7 +103,9 @@ 'tp' : None, 'fr' : types.FrameType, 'tb' : types.TracebackType, - 'reg' : RemoteBase + 'reg' : RemoteBase, + 'get' : NonDataDescriptor, + 'set' : DataDescriptor, } type_letters = dict([(value, key) for key, value in letter_types.items()]) assert len(type_letters) == len(letter_types) @@ -132,8 +146,10 @@ id = self.keeper.register_object(obj) return (self.type_letters[tp], id) elif tp is type: - if issubclass(obj, RemoteBase): + try: return "reg", self.keeper.reverse_remote_types[obj] + except KeyError: + pass try: return self.type_letters[tp], self.type_letters[obj] except KeyError: @@ -196,6 +212,10 @@ return self.letter_types[obj_data] id = obj_data return self.get_type(obj_data) + elif tp is DataDescriptor: + return faker.unwrap_getset_descriptor(self, obj_data) + elif tp is NonDataDescriptor: + return faker.unwrap_get_descriptor(self, obj_data) elif tp is object: # we need to create a proper type w_tp, id = obj_data @@ -286,8 +306,7 @@ exc, val, tb = unwrap(data) raise exc, val, tb elif command == 'type_reg': - type_id, name, _dict = data - protocol.keeper.fake_remote_type(protocol, type_id, name, _dict) + protocol.keeper.fake_remote_type(protocol, data) elif command == 'force': obj = protocol.keeper.get_object(data) w_obj = protocol.pack(obj) @@ -295,6 +314,17 @@ elif command == 'forced': obj = protocol.unpack(data) return obj + elif command == 'desc_get': + name, w_obj, w_type = data + obj = protocol.unwrap(w_obj) + type_ = protocol.unwrap(w_type) + send(('finished', protocol.wrap(getattr(type(obj), name).__get__(obj, type_)))) + elif command == 'desc_set': + name, w_obj, w_value = data + obj = protocol.unwrap(w_obj) + value = protocol.unwrap(w_value) + getattr(type(obj), name).__set__(obj, value) + send(('finished', protocol.wrap(None))) else: raise NotImplementedError("command %s" % command) @@ -347,6 +377,14 @@ else: raise NotImplementedError("Cannot unpack %s" % (data,)) + def get(self, name, obj, type): + self.send(("desc_get", (name, self.wrap(obj), self.wrap(type)))) + retval = remote_loop(self) + return retval + + def set(self, obj, value): + self.send(("desc_set", (name, self.wrap(obj), self.wrap(value)))) + class RemoteObject(object): def __init__(self, protocol, id): self.id = id 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 Apr 20 11:10:44 2007 @@ -219,8 +219,19 @@ res = xa.x() assert res == 8 + def test_types_reverse_mapping(self): + class A: + def m(self, tp): + assert type(self) is tp + + a = A() + protocol = self.test_env({'a':a, 'A':A}) + xa = protocol.get_remote('a') + xA = protocol.get_remote('A') + xa.m(xA) + def test_instantiate_remote_type(self): - #skip("Doesn't work yet") + skip("Will not work unless we take care about __basis__") class C: def __init__(self, y): self.y = y @@ -230,6 +241,24 @@ protocol = self.test_env({'C':C}) xC = protocol.get_remote('C') - res = xC(3).x() + xc = xC(3) + res = xc.x() assert res == 3 + def test_remote_sys(self): + import sys + + protocol = self.test_env({'sys':sys}) + s = protocol.get_remote('sys') + l = dir(s) + assert l + + def test_remote_file_access(self): + # cannot do test_env({'file':file}) yet :) + def f(name): + return open(name) + + protocol = self.test_env({'f':f}) + xf = protocol.get_remote('f') + data = xf('/etc/passwd').read() + assert data From afa at codespeak.net Fri Apr 20 11:55:00 2007 From: afa at codespeak.net (afa at codespeak.net) Date: Fri, 20 Apr 2007 11:55:00 +0200 (CEST) Subject: [pypy-svn] r42198 - pypy/dist/pypy/module/_file/test Message-ID: <20070420095500.18F0980AC@code0.codespeak.net> Author: afa Date: Fri Apr 20 11:54:59 2007 New Revision: 42198 Modified: pypy/dist/pypy/module/_file/test/test_file_extra.py Log: Open files in binary mode. Most tests pass on Windows Modified: pypy/dist/pypy/module/_file/test/test_file_extra.py ============================================================================== --- pypy/dist/pypy/module/_file/test/test_file_extra.py (original) +++ pypy/dist/pypy/module/_file/test/test_file_extra.py Fri Apr 20 11:54:59 2007 @@ -248,7 +248,7 @@ extra_args = () def setup_method(self, method): - fd = os.open(TestFile.expected_filename, os.O_RDONLY) + fd = os.open(TestFile.expected_filename, os.O_RDONLY|os.O_BINARY) self.file = _file.file.fdopen(fd, self.expected_mode, *self.extra_args) @@ -392,7 +392,7 @@ assert os.stat(fn).st_size == 1 f.close() - f = _file.file(fn, 'w', 1) + f = _file.file(fn, 'wb', 1) f.write('x') assert os.stat(fn).st_size == 0 f.write('\n') @@ -404,7 +404,7 @@ f.close() assert os.stat(fn).st_size == 3 - f = _file.file(fn, 'w', 100) + f = _file.file(fn, 'wb', 100) f.write('x') assert os.stat(fn).st_size == 0 f.write('\n') From afa at codespeak.net Fri Apr 20 13:26:21 2007 From: afa at codespeak.net (afa at codespeak.net) Date: Fri, 20 Apr 2007 13:26:21 +0200 (CEST) Subject: [pypy-svn] r42201 - in pypy/dist/pypy/module/_file: . test Message-ID: <20070420112621.A0BB180AC@code0.codespeak.net> Author: afa Date: Fri Apr 20 13:26:21 2007 New Revision: 42201 Modified: pypy/dist/pypy/module/_file/app_file.py pypy/dist/pypy/module/_file/test/test_file_extra.py Log: file.__repr__ must use %s for the filename, not %r. This makes a difference when os.path.sep == '\\'. Now all tests for the _file module pass on Windows. 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 Fri Apr 20 13:26:21 2007 @@ -271,7 +271,7 @@ return os.isatty(self.fd) def __repr__(self): - return '<%s file %r, mode %r at 0x%x>' % ( + return "<%s file '%s', mode %r at 0x%x>" % ( self._closed and 'closed' or 'open', self._name, self._mode, Modified: pypy/dist/pypy/module/_file/test/test_file_extra.py ============================================================================== --- pypy/dist/pypy/module/_file/test/test_file_extra.py (original) +++ pypy/dist/pypy/module/_file/test/test_file_extra.py Fri Apr 20 13:26:21 2007 @@ -66,7 +66,7 @@ def test_repr(self): r = repr(self.file) assert r.find('open file') >= 0 - assert r.find(repr(self.file.name)) >= 0 + assert r.find(self.file.name) >= 0 assert r.find(self.file.mode) >= 0 def test_isatty(self): From arigo at codespeak.net Fri Apr 20 16:37:11 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 20 Apr 2007 16:37:11 +0200 (CEST) Subject: [pypy-svn] r42206 - pypy/dist/pypy/lang/prolog/interpreter Message-ID: <20070420143711.2285C80AF@code0.codespeak.net> Author: arigo Date: Fri Apr 20 16:37:10 2007 New Revision: 42206 Modified: pypy/dist/pypy/lang/prolog/interpreter/engine.py Log: Add an XXX comment. Modified: pypy/dist/pypy/lang/prolog/interpreter/engine.py ============================================================================== --- pypy/dist/pypy/lang/prolog/interpreter/engine.py (original) +++ pypy/dist/pypy/lang/prolog/interpreter/engine.py Fri Apr 20 16:37:10 2007 @@ -42,6 +42,8 @@ return self.vars[index] def setvar(self, index, val): + # XXX check if oldval != val + # it happens all the time in get_last_var_in_chain_and_val() oldval = self.vars[index] self.vars[index] = val # only trail for variables that have a chance to get restored From afa at codespeak.net Fri Apr 20 16:55:13 2007 From: afa at codespeak.net (afa at codespeak.net) Date: Fri, 20 Apr 2007 16:55:13 +0200 (CEST) Subject: [pypy-svn] r42208 - pypy/dist/pypy/tool Message-ID: <20070420145513.0B65580AF@code0.codespeak.net> Author: afa Date: Fri Apr 20 16:55:12 2007 New Revision: 42208 Modified: pypy/dist/pypy/tool/slaveproc.py Log: On Windows, remove the 'unbuffered' option when starting the slave process. This helps many tests to pass: test_rgenop, test_boehm, test_newgc. Don't know what was happening, tests seem to fail after 8 successful 'isolated' calls, but I could not reproduce the problem in a unit test. Modified: pypy/dist/pypy/tool/slaveproc.py ============================================================================== --- pypy/dist/pypy/tool/slaveproc.py (original) +++ pypy/dist/pypy/tool/slaveproc.py Fri Apr 20 16:55:12 2007 @@ -37,7 +37,11 @@ _broken = False def __init__(self, slave_impl): - inp, out = os.popen2('%s -u %s' % (sys.executable, os.path.abspath(slave_impl))) + if sys.platform == 'win32': + unbuffered = '' + else: + unbuffered = '-u' + inp, out = os.popen2('%s %s %s' % (sys.executable, unbuffered, os.path.abspath(slave_impl))) self.exchg = Exchange(out, inp) def cmd(self, data): From afa at codespeak.net Fri Apr 20 17:50:12 2007 From: afa at codespeak.net (afa at codespeak.net) Date: Fri, 20 Apr 2007 17:50:12 +0200 (CEST) Subject: [pypy-svn] r42210 - pypy/dist/pypy/translator/goal/test2 Message-ID: <20070420155012.DB95880AF@code0.codespeak.net> Author: afa Date: Fri Apr 20 17:50:12 2007 New Revision: 42210 Modified: pypy/dist/pypy/translator/goal/test2/test_app_main.py Log: win32: os.popen does not work when the program is enclosed in quotes. Let's say that no one installs python in a directory containing spaces. 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 Fri Apr 20 17:50:12 2007 @@ -274,7 +274,7 @@ class TestNonInteractive: def run(self, cmdline): - cmdline = '"%s" "%s" %s' % (sys.executable, app_main, cmdline) + cmdline = '%s "%s" %s' % (sys.executable, app_main, cmdline) print 'POPEN:', cmdline child_in, child_out_err = os.popen4(cmdline) child_in.close() From arigo at codespeak.net Fri Apr 20 18:33:17 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 20 Apr 2007 18:33:17 +0200 (CEST) Subject: [pypy-svn] r42214 - in pypy/branch/pypy-string-formatting/rlib: . test Message-ID: <20070420163317.3E1E280B8@code0.codespeak.net> Author: arigo Date: Fri Apr 20 18:33:16 2007 New Revision: 42214 Modified: pypy/branch/pypy-string-formatting/rlib/rbigint.py pypy/branch/pypy-string-formatting/rlib/test/test_rbigint.py Log: Clean up and generalize the string formatting routine of rbigint. Modified: pypy/branch/pypy-string-formatting/rlib/rbigint.py ============================================================================== --- pypy/branch/pypy-string-formatting/rlib/rbigint.py (original) +++ pypy/branch/pypy-string-formatting/rlib/rbigint.py Fri Apr 20 18:33:16 2007 @@ -228,11 +228,16 @@ # no matter what the sign is (two's complement) return a.digits[0] & 1 + def format(self, digits, prefix='', suffix=''): + # 'digits' is a string whose length is the base to use, + # and where each character is the corresponding digit. + return _format(self, digits, prefix, suffix) + def repr(self): - return _format(self, 10, True) + return _format(self, BASE10, '', 'L') def str(self): - return _format(self, 10, False) + return _format(self, BASE10) def eq(self, other): if (self.sign != other.sign or @@ -526,10 +531,13 @@ return _bitwise(self, '|', other) def oct(self): - return _format(self, 8, True) + if self.sign == 0: + return '0L' + else: + return _format(self, BASE8, '0', 'L') def hex(self): - return _format(self, 16, True) + return _format(self, BASE16, '0x', 'L') def log(self, base): # base is supposed to be positive or 0.0, which means we use e @@ -1323,35 +1331,35 @@ # math.ldexp checks and raises return ad - +BASE8 = '01234567' +BASE10 = '0123456789' +BASE16 = '0123456789ABCDEF' -def _format(a, base, addL): +def _format(a, digits, prefix='', suffix=''): """ Convert a bigint object to a string, using a given conversion base. Return a string object. - If base is 8 or 16, add the proper prefix '0' or '0x'. """ size_a = len(a.digits) + base = len(digits) assert base >= 2 and base <= 36 - sign = False - # Compute a rough upper bound for the length of the string i = base bits = 0 while i > 1: bits += 1 i >>= 1 - i = 5 + int(bool(addL)) + (size_a*SHIFT + bits-1) // bits + i = 5 + len(prefix) + len(suffix) + (size_a*SHIFT + bits-1) // bits s = [chr(0)] * i p = i - if addL: + j = len(suffix) + while j > 0: p -= 1 - s[p] = 'L' - if a.sign < 0: - sign = True + j -= 1 + s[p] = suffix[j] if a.sign == 0: p -= 1 @@ -1374,13 +1382,9 @@ assert accumbits >= basebits while 1: cdigit = accum & (base - 1) - if cdigit < 10: - cdigit += ord('0') - else: - cdigit += ord('A') - 10 - assert p > 0 p -= 1 - s[p] = chr(cdigit) + assert p >= 0 + s[p] = digits[cdigit] accumbits -= basebits accum >>= basebits if i < size_a - 1: @@ -1421,13 +1425,9 @@ while 1: nextrem = rem // base c = rem - nextrem * base - assert p > 0 - if c < 10: - c += ord('0') - else: - c += ord('A') - 10 p -= 1 - s[p] = chr(c) + assert p >= 0 + s[p] = digits[c] rem = nextrem ntostore -= 1 # Termination is a bit delicate: must not @@ -1438,33 +1438,19 @@ if size == 0: break - if base == 8: - if a.sign != 0: - p -= 1 - s[p] = '0' - elif base == 16: + j = len(prefix) + while j > 0: p -= 1 - s[p] ='x' - p -= 1 - s[p] = '0' - elif base != 10: - p -= 1 - s[p] = '#' - p -= 1 - s[p] = chr(ord('0') + base % 10) - if base > 10: - p -= 1 - s[p] = chr(ord('0') + base // 10) - if sign: + j -= 1 + s[p] = prefix[j] + + if a.sign < 0: p -= 1 s[p] = '-' assert p >= 0 # otherwise, buffer overflow (this is also a # hint for the annotator for the slice below) - if p == 0: - return ''.join(s) - else: - return ''.join(s[p:]) + return ''.join(s[p:]) def _bitwise(a, op, b): # '&', '|', '^' Modified: pypy/branch/pypy-string-formatting/rlib/test/test_rbigint.py ============================================================================== --- pypy/branch/pypy-string-formatting/rlib/test/test_rbigint.py (original) +++ pypy/branch/pypy-string-formatting/rlib/test/test_rbigint.py Fri Apr 20 18:33:16 2007 @@ -299,6 +299,20 @@ res2 = getattr(operator, mod)(x, y) assert res1 == res2 + def test_tostring(self): + z = rbigint.fromlong(0) + assert z.str() == '0' + assert z.repr() == '0L' + assert z.hex() == '0x0L' + assert z.oct() == '0L' + x = rbigint.fromlong(-18471379832321) + assert x.str() == '-18471379832321' + assert x.repr() == '-18471379832321L' + assert x.hex() == '-0x10CCB4088E01L' + assert x.oct() == '-0414626402107001L' + assert x.format('.!') == ( + '-!....!!..!!..!.!!.!......!...!...!!!........!') + assert x.format('abcdefghijkl', '<<', '>>') == '-<>' class TestInternalFunctions(object): From arigo at codespeak.net Fri Apr 20 21:02:58 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 20 Apr 2007 21:02:58 +0200 (CEST) Subject: [pypy-svn] r42216 - in pypy/branch/pypy-string-formatting: module/__builtin__ objspace/std objspace/std/test rlib Message-ID: <20070420190258.3F1AA809F@code0.codespeak.net> Author: arigo Date: Fri Apr 20 21:02:54 2007 New Revision: 42216 Removed: pypy/branch/pypy-string-formatting/module/__builtin__/special.py Modified: pypy/branch/pypy-string-formatting/module/__builtin__/__init__.py pypy/branch/pypy-string-formatting/objspace/std/floatobject.py pypy/branch/pypy-string-formatting/objspace/std/formatting.py pypy/branch/pypy-string-formatting/objspace/std/test/test_stringformat.py pypy/branch/pypy-string-formatting/rlib/rarithmetic.py Log: (pedronis, arigo) Progress in the string formatting code. Mostly finished, but without any unicode support. Modified: pypy/branch/pypy-string-formatting/module/__builtin__/__init__.py ============================================================================== --- pypy/branch/pypy-string-formatting/module/__builtin__/__init__.py (original) +++ pypy/branch/pypy-string-formatting/module/__builtin__/__init__.py Fri Apr 20 21:02:54 2007 @@ -129,8 +129,6 @@ 'range' : 'functional.range_int', 'all' : 'functional.all', 'any' : 'functional.any', - # float->string helper - '_formatd' : 'special._formatd' } def pick_builtin(self, w_globals): Modified: pypy/branch/pypy-string-formatting/objspace/std/floatobject.py ============================================================================== --- pypy/branch/pypy-string-formatting/objspace/std/floatobject.py (original) +++ pypy/branch/pypy-string-formatting/objspace/std/floatobject.py Fri Apr 20 21:02:54 2007 @@ -3,6 +3,7 @@ from pypy.objspace.std.noneobject import W_NoneObject from pypy.objspace.std.longobject import W_LongObject from pypy.rlib.rarithmetic import ovfcheck_float_to_int, intmask, isinf +from pypy.rlib.rarithmetic import formatd import math from pypy.objspace.std.intobject import W_IntObject @@ -68,25 +69,23 @@ def float_w__Float(space, w_float): return w_float.floatval -app = gateway.applevel(''' - def repr__Float(f): - r = "%.17g" % f - for c in r: - if c not in '-0123456789': - return r - else: - return r + '.0' +def should_not_look_like_an_int(s): + for c in s: + if c in '.eE': + break + else: + s += '.0' + return s - def str__Float(f): - r = "%.12g" % f - for c in r: - if c not in '-0123456789': - return r - else: - return r + '.0' -''', filename=__file__) -repr__Float = app.interphook('repr__Float') -str__Float = app.interphook('str__Float') +def repr__Float(space, w_float): + x = w_float.floatval + s = formatd("%.17g", x) + return space.wrap(should_not_look_like_an_int(s)) + +def str__Float(space, w_float): + x = w_float.floatval + s = formatd("%.12g", x) + return space.wrap(should_not_look_like_an_int(s)) def lt__Float_Float(space, w_float1, w_float2): i = w_float1.floatval Modified: pypy/branch/pypy-string-formatting/objspace/std/formatting.py ============================================================================== --- pypy/branch/pypy-string-formatting/objspace/std/formatting.py (original) +++ pypy/branch/pypy-string-formatting/objspace/std/formatting.py Fri Apr 20 21:02:54 2007 @@ -2,6 +2,8 @@ String formatting routines. """ from pypy.rlib.unroll import unrolling_iterable +from pypy.rlib.rarithmetic import ovfcheck, formatd_overflow +from pypy.interpreter.error import OperationError class StringFormatter(object): @@ -40,7 +42,7 @@ break elif c == '(': pcount += 1 - i += 1 + i += 1 self.fmtpos = i + 1 # first character after ')' return fmt[i0:i] @@ -64,6 +66,13 @@ space.wrap("format requires a mapping")) return space.getitem(self.w_valuedict, space.wrap(key)) + def checkconsumed(self): + if self.values_pos < len(self.values_w) and self.w_valuedict is None: + space = self.space + raise OperationError(space.w_TypeError, + space.wrap('not all arguments converted ' + 'during string formatting')) + def parse_fmt(self): if self.peekchr() == '(': w_value = self.getmappingvalue(self.getmappingkey()) @@ -170,17 +179,164 @@ else: self.unknown_fmtchar() + self.checkconsumed() + return ''.join(result) + + def unknown_fmtchar(self): + self.fmtpos -= 1 + msg = "unsupported format character '%s' (0x%x) at index %d" % ( + self.peekchr(), # XXX unicode encoding here + ord(self.peekchr()), + self.fmtpos) + space = self.space + raise OperationError(space.w_ValueError, space.wrap(msg)) + + def std_wp(self, r): + length = len(r) + if self.prec >= 0 and self.prec < length: + length = self.prec # ignore the end of the string if too long + result = self.result + padding = self.width - length + if not self.f_ljust: + for i in range(padding): # add any padding at the left of 'r' + result.append(' ') + padding = 0 + for i in range(length): # add 'r' itself + result.append(r[i]) + for i in range(padding): # add any remaining padding at the right + result.append(' ') + + def std_wp_int(self, r, prefix=''): + # use self.prec to add some '0' on the left of the number + if self.prec >= 0: + sign = r[0] == '-' + padding = self.prec - (len(r)-int(sign)) + if padding > 0: + if sign: + r = '-' + '0'*padding + r[1:] + else: + r = '0'*padding + r + elif self.prec == 0 and r == '0': + r = '' + self.std_wp_number(r, prefix) + + def std_wp_number(self, r, prefix=''): + # add a '+' or ' ' sign if necessary + sign = r.startswith('-') + if not sign: + if self.f_sign: + r = '+' + r + sign = True + elif self.f_blank: + r = ' ' + r + sign = True + # do the padding requested by self.width and the flags, + # without building yet another RPython string but directly + # by pushing the pad character into self.result + result = self.result + padding = self.width - len(r) - len(prefix) + + if self.f_ljust: + padnumber = '<' + elif self.f_zero: + padnumber = '0' + else: + padnumber = '>' + + if padnumber == '>': + for i in range(padding): + result.append(' ') # pad with spaces on the left + if sign: + result.append(r[0]) # the sign + for c in prefix: + result.append(c) # the prefix + if padnumber == '0': + for i in range(padding): # pad with zeroes + result.append('0') + for j in range(int(sign), len(r)): # the rest of the number + result.append(r[j]) + if padnumber == '<': # spaces on the right + for i in range(padding): + result.append(' ') def fmt_s(self, w_value): - self.std_wp(self.space.str_w(w_value)) + self.std_wp(self.space.str_w(self.space.str(w_value))) + + def fmt_r(self, w_value): + self.std_wp(self.space.str_w(self.space.repr(w_value))) def fmt_d(self, w_value): "int formatting" - - ... + r = int_num_helper(self.space, w_value) + self.std_wp_int(r) + + def fmt_x(self, w_value): + "hex formatting" + r = hex_num_helper(self.space, w_value) + if self.f_alt: + prefix = '0x' + else: + prefix = '' + self.std_wp_int(r, prefix) + + def fmt_X(self, w_value): + "HEX formatting" + r = hex_num_helper(self.space, w_value) + if self.f_alt: + prefix = '0X' + else: + prefix = '' + self.std_wp_int(r.upper(), prefix) + + def fmt_o(self, w_value): + "oct formatting" + r = oct_num_helper(self.space, w_value) + if self.f_alt and (r != '0' or self.prec == 0): + prefix = '0' + else: + prefix = '' + self.std_wp_int(r, prefix) fmt_i = fmt_d + def fmt_e(self, w_value): + self.format_float(w_value, 'e') + + def fmt_f(self, w_value): + self.format_float(w_value, 'f') + + def fmt_g(self, w_value): + self.format_float(w_value, 'g') + + def fmt_E(self, w_value): + self.format_float(w_value, 'E') + + def fmt_F(self, w_value): + self.format_float(w_value, 'F') + + def fmt_G(self, w_value): + self.format_float(w_value, 'G') + + def format_float(self, w_value, char): + space = self.space + x = space.float_w(maybe_float(space, w_value)) + if isnan(x): + r = 'nan' + elif isinf(x): + r = 'inf' + else: + prec = self.prec + if prec < 0: + prec = 6 + if char in 'fF' and x/1e25 > 1e25: + char = chr(ord(char) + 1) # 'f' => 'g' + try: + r = formatd_overflow(self.f_alt, prec, char, x) + except OverflowError: + raise OperationError(space.w_OverflowError, space.wrap( + "formatted float is too long (precision too large?)")) + self.std_wp_number(r) + # an "unrolling" list of all the known format characters, # collected from which fmt_X() functions are defined in the class @@ -191,10 +347,11 @@ def format(space, w_fmt, values_w, w_valuedict=None, do_unicode=False): "Entry point" - assert not do_unicode # XXX + if do_unicode: # XXX + import py; py.test.skip("XXX unicode formatting") fmt = space.str_w(w_fmt) formatter = StringFormatter(space, fmt, values_w, w_valuedict) - return formatter.format() + return space.wrap(formatter.format()) # ____________________________________________________________ # Formatting helpers @@ -203,50 +360,35 @@ # make sure that w_value is a wrapped integer return space.int(w_value) -def numeric_preprocess(v, flags): - # negative zeroes? - # * mwh giggles, falls over - # still, if we can recognize them, here's the place to do it. - import math - if v < 0 or v == 0 and isinstance(v, float) and math.atan2(0, v) != 0: - sign = '-' - v = -v - else: - if flags.f_sign: - sign = '+' - elif flags.f_blank: - sign = ' ' - else: - sign = '' - return v, sign -#numeric_preprocess._annspecialcase_ = 'specialize:argtype(0)' - -def format_num_helper_generator(fun_name, fun): - def format_num_helper(formatter, w_value): - w_value = maybe_int(formatter.space, w_value) +def maybe_float(space, w_value): + # make sure that w_value is a wrapped float + return space.float(w_value) + +def format_num_helper_generator(fmt, digits): + def format_num_helper(space, w_value): + w_value = maybe_int(space, w_value) try: value = space.int_w(w_value) - value, sign = numeric_preprocess(value, formatter) - return (fun(value), sign) + return fmt % (value,) except OperationError, operr: - # XXX: Fix it, this is obviously inefficient if not operr.match(space, space.w_OverflowError): raise - if space.is_true(space.lt(v, space.wrap(0))): - sign = '-' - v = space.neg(v) - else: - if flags.f_sign: - sign = '+' - elif flags.f_blank: - sign = ' ' - else: - sign = '' - val = space.str_w(getattr(space, fun_name)(v)) - return (val, sign) - format_num_helper.func_name = fun_name + '_num_helper' + num = space.bigint_w(w_value) + return num.format(digits) + format_num_helper.func_name = 'base%d_num_helper' % len(digits) return format_num_helper -hex_num_helper = format_num_helper_generator('hex', hex) -oct_num_helper = format_num_helper_generator('oct', oct) -int_num_helper = format_num_helper_generator('str', str) +int_num_helper = format_num_helper_generator('%d', '0123456789') +oct_num_helper = format_num_helper_generator('%o', '01234567') +hex_num_helper = format_num_helper_generator('%x', '0123456789abcdef') + + +# isinf isn't too hard... +def isinf(v): + return v != 0 and v*2.0 == v + +# To get isnan, working x-platform and both on 2.3 and 2.4, is a +# horror. I think this works (for reasons I don't really want to talk +# about), and probably when implemented on top of pypy, too. +def isnan(v): + return v != v*1.0 or (v == 1.0 and v == 2.0) Modified: pypy/branch/pypy-string-formatting/objspace/std/test/test_stringformat.py ============================================================================== --- pypy/branch/pypy-string-formatting/objspace/std/test/test_stringformat.py (original) +++ pypy/branch/pypy-string-formatting/objspace/std/test/test_stringformat.py Fri Apr 20 21:02:54 2007 @@ -75,9 +75,11 @@ assert '23.456' == '%s' % 23.456 # for 'r' use a float that has an exact decimal rep: assert '23.125' == '%r' % 23.125 - # XXX rounding: assert '0.028' == '%.3f' % 0.0276 + assert '0.028' == '%.3f' % 0.0276 # should work on most platforms... + assert ' inf' == '%6g' % (1E200 * 1E200) def test_format_int(self): + import sys assert '23' == '%d' % 23 assert '17' == '%x' % 23 assert '0x17' == '%#x' % 23 @@ -86,6 +88,16 @@ assert '23' == '%r' % 23 assert ('%d' % (-sys.maxint-1,) == '-' + str(sys.maxint+1) == '-%d' % (sys.maxint+1,)) + assert '1C' == '%X' % 28 + assert '0X1C' == '%#X' % 28 + assert '10' == '%o' % 8 + assert '010' == '%#o' % 8 + assert '-010' == '%#o' % -8 + assert '0' == '%o' % 0 + assert '0' == '%#o' % 0 + + assert '-0x017' == '%#06x' % -23 + assert '0' == '%#.0o' % 0 def test_format_list(self): assert '<[1, 2]>' == '<%s>' % [1,2] @@ -122,6 +134,14 @@ assert "%3s" %'a' == ' a' assert "%-3s"%'a' == 'a ' + def test_prec_cornercase(self): + assert "%.0x" % 0 == '' + assert "%.x" % 0 == '' + assert "%.0d" % 0 == '' + assert "%.i" % 0 == '' + assert "%.0o" % 0 == '' + assert "%.o" % 0 == '' + def test_prec_string(self): assert "%.3s"%'a' == 'a' assert "%.3s"%'abcde' == 'abc' Modified: pypy/branch/pypy-string-formatting/rlib/rarithmetic.py ============================================================================== --- pypy/branch/pypy-string-formatting/rlib/rarithmetic.py (original) +++ pypy/branch/pypy-string-formatting/rlib/rarithmetic.py Fri Apr 20 21:02:54 2007 @@ -410,8 +410,8 @@ return fmt % (x,) def formatd_overflow(alt, prec, kind, x): - if ((kind == 'g' and formatd_max_length <= 10+prec) or - (kind == 'f' and formatd_max_length <= 53+prec)): + if ((kind in 'gG' and formatd_max_length <= 10+prec) or + (kind in 'fF' and formatd_max_length <= 53+prec)): raise OverflowError("formatted float is too long (precision too large?)") if alt: alt = '#' From arigo at codespeak.net Fri Apr 20 21:17:24 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 20 Apr 2007 21:17:24 +0200 (CEST) Subject: [pypy-svn] r42217 - in pypy/branch/pypy-string-formatting/objspace/std: . test Message-ID: <20070420191724.D869D80AD@code0.codespeak.net> Author: arigo Date: Fri Apr 20 21:17:23 2007 New Revision: 42217 Modified: pypy/branch/pypy-string-formatting/objspace/std/formatting.py pypy/branch/pypy-string-formatting/objspace/std/test/test_stringformat.py Log: (pedronis, arigo) Support for %c. Modified: pypy/branch/pypy-string-formatting/objspace/std/formatting.py ============================================================================== --- pypy/branch/pypy-string-formatting/objspace/std/formatting.py (original) +++ pypy/branch/pypy-string-formatting/objspace/std/formatting.py Fri Apr 20 21:17:23 2007 @@ -265,6 +265,32 @@ def fmt_r(self, w_value): self.std_wp(self.space.str_w(self.space.repr(w_value))) + def fmt_c(self, w_value): + space = self.space + try: + n = space.int_w(w_value) + except OperationError, e1: + if not e1.match(space, space.w_TypeError): + raise + try: + s = space.str_w(w_value) + except OperationError, e2: + if not e2.match(space, space.w_TypeError): + raise + s = '' # something invalid to trigger the TypeError + if len(s) != 1: + raise OperationError(space.w_TypeError, + space.wrap("%c requires int or char")) + else: + try: + s = chr(n) + except ValueError: # chr(out-of-range) + raise OperationError(space.w_OverflowError, + space.wrap("character code not in range(256)")) + + self.prec = -1 # just because + self.std_wp(s) + def fmt_d(self, w_value): "int formatting" r = int_num_helper(self.space, w_value) Modified: pypy/branch/pypy-string-formatting/objspace/std/test/test_stringformat.py ============================================================================== --- pypy/branch/pypy-string-formatting/objspace/std/test/test_stringformat.py (original) +++ pypy/branch/pypy-string-formatting/objspace/std/test/test_stringformat.py Fri Apr 20 21:17:23 2007 @@ -129,6 +129,15 @@ def test_incomplete_format(self): raises(ValueError, '%'.__mod__, ((23,),)) + def test_format_char(self): + assert '%c' % 65 == 'A' + assert '%c' % 'e' == 'e' + raises(OverflowError, '%c'.__mod__, (256,)) + raises(OverflowError, '%c'.__mod__, (-1,)) + raises(TypeError, '%c'.__mod__, ("bla",)) + raises(TypeError, '%c'.__mod__, ("",)) + raises(TypeError, '%c'.__mod__, (['c'],)) + class AppTestWidthPrec: def test_width(self): assert "%3s" %'a' == ' a' From arigo at codespeak.net Fri Apr 20 21:34:21 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 20 Apr 2007 21:34:21 +0200 (CEST) Subject: [pypy-svn] r42218 - in pypy/branch/pypy-string-formatting: annotation rpython rpython/test Message-ID: <20070420193421.5BD2F80AF@code0.codespeak.net> Author: arigo Date: Fri Apr 20 21:34:20 2007 New Revision: 42218 Modified: pypy/branch/pypy-string-formatting/annotation/binaryop.py pypy/branch/pypy-string-formatting/rpython/rstr.py pypy/branch/pypy-string-formatting/rpython/test/test_rstr.py Log: Allow the RPython type 'character' to be converted to 'unicode character' transparently. Modified: pypy/branch/pypy-string-formatting/annotation/binaryop.py ============================================================================== --- pypy/branch/pypy-string-formatting/annotation/binaryop.py (original) +++ pypy/branch/pypy-string-formatting/annotation/binaryop.py Fri Apr 20 21:34:20 2007 @@ -399,7 +399,10 @@ def union((chr1, chr2)): return SomeChar() -class __extend__(pairtype(SomeUnicodeCodePoint, SomeUnicodeCodePoint)): + +class __extend__(pairtype(SomeUnicodeCodePoint, SomeUnicodeCodePoint), + pairtype(SomeChar, SomeUnicodeCodePoint), + pairtype(SomeUnicodeCodePoint, SomeChar)): def union((uchr1, uchr2)): return SomeUnicodeCodePoint() Modified: pypy/branch/pypy-string-formatting/rpython/rstr.py ============================================================================== --- pypy/branch/pypy-string-formatting/rpython/rstr.py (original) +++ pypy/branch/pypy-string-formatting/rpython/rstr.py Fri Apr 20 21:34:20 2007 @@ -7,7 +7,7 @@ from pypy.rpython.rtuple import AbstractTupleRepr from pypy.rpython.rslice import AbstractSliceRepr from pypy.rpython import rint -from pypy.rpython.lltypesystem.lltype import Signed, Bool, Void +from pypy.rpython.lltypesystem.lltype import Signed, Bool, Void, UniChar class AbstractStringRepr(Repr): pass @@ -496,6 +496,10 @@ return llops.gendirectcall(r_from.ll.ll_stritem_nonneg, v, c_zero) return NotImplemented +class __extend__(pairtype(AbstractCharRepr, AbstractUniCharRepr)): + def convert_from_to((r_from, r_to), v, llops): + v2 = llops.genop('cast_char_to_int', [v], resulttype=Signed) + return llops.genop('cast_int_to_unichar', [v2], resulttype=UniChar) # ____________________________________________________________ # Modified: pypy/branch/pypy-string-formatting/rpython/test/test_rstr.py ============================================================================== --- pypy/branch/pypy-string-formatting/rpython/test/test_rstr.py (original) +++ pypy/branch/pypy-string-formatting/rpython/test/test_rstr.py Fri Apr 20 21:34:20 2007 @@ -148,6 +148,18 @@ return d[c] assert self.interpret(fn, [u'\u03b1']) == 42 + def test_convert_char_to_unichar(self): + def g(c): + return ord(c) + def fn(n): + if n < 0: + c = unichr(-n) + else: + c = chr(n) + return g(c) + assert self.interpret(fn, [65]) == 65 + assert self.interpret(fn, [-5555]) == 5555 + def test_is_none(self): def fn(i): s1 = ['foo', None][i] From arigo at codespeak.net Fri Apr 20 21:40:51 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 20 Apr 2007 21:40:51 +0200 (CEST) Subject: [pypy-svn] r42219 - in pypy/branch/pypy-string-formatting/rpython: . test Message-ID: <20070420194051.3DBCE80AF@code0.codespeak.net> Author: arigo Date: Fri Apr 20 21:40:50 2007 New Revision: 42219 Modified: pypy/branch/pypy-string-formatting/rpython/rstr.py pypy/branch/pypy-string-formatting/rpython/test/test_rstr.py Log: Support == and != between a character and a unichar. Modified: pypy/branch/pypy-string-formatting/rpython/rstr.py ============================================================================== --- pypy/branch/pypy-string-formatting/rpython/rstr.py (original) +++ pypy/branch/pypy-string-formatting/rpython/rstr.py Fri Apr 20 21:40:50 2007 @@ -462,7 +462,9 @@ return hop.genop('cast_unichar_to_int', vlist, resulttype=Signed) -class __extend__(pairtype(AbstractUniCharRepr, AbstractUniCharRepr)): +class __extend__(pairtype(AbstractUniCharRepr, AbstractUniCharRepr), + pairtype(AbstractCharRepr, AbstractUniCharRepr), + pairtype(AbstractUniCharRepr, AbstractCharRepr)): def rtype_eq(_, hop): return _rtype_unchr_compare_template(hop, 'eq') def rtype_ne(_, hop): return _rtype_unchr_compare_template(hop, 'ne') ## def rtype_lt(_, hop): return _rtype_unchr_compare_template(hop, 'lt') Modified: pypy/branch/pypy-string-formatting/rpython/test/test_rstr.py ============================================================================== --- pypy/branch/pypy-string-formatting/rpython/test/test_rstr.py (original) +++ pypy/branch/pypy-string-formatting/rpython/test/test_rstr.py Fri Apr 20 21:40:50 2007 @@ -160,6 +160,14 @@ assert self.interpret(fn, [65]) == 65 assert self.interpret(fn, [-5555]) == 5555 + def test_char_unichar_eq(self): + def fn(c1, c2): + return c1 == c2 + assert self.interpret(fn, [u'(', '(']) == True + assert self.interpret(fn, [u'\u1028', '(']) == False + assert self.interpret(fn, ['(', u'(']) == True + assert self.interpret(fn, ['(', u'\u1028']) == False + def test_is_none(self): def fn(i): s1 = ['foo', None][i] From arigo at codespeak.net Fri Apr 20 22:42:55 2007 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 20 Apr 2007 22:42:55 +0200 (CEST) Subject: [pypy-svn] r42220 - in pypy/branch/pypy-string-formatting: module/__builtin__ objspace/std objspace/std/test Message-ID: <20070420204255.6A64180AD@code0.codespeak.net> Author: arigo Date: Fri Apr 20 22:42:54 2007 New Revision: 42220 Modified: pypy/branch/pypy-string-formatting/module/__builtin__/operation.py pypy/branch/pypy-string-formatting/objspace/std/formatting.py pypy/branch/pypy-string-formatting/objspace/std/stringobject.py pypy/branch/pypy-string-formatting/objspace/std/test/test_stringformat.py pypy/branch/pypy-string-formatting/objspace/std/unicodeobject.py Log: (pedronis, arigo) Unicode support. The tests pass, but there might still be annotation problems. Modified: pypy/branch/pypy-string-formatting/module/__builtin__/operation.py ============================================================================== --- pypy/branch/pypy-string-formatting/module/__builtin__/operation.py (original) +++ pypy/branch/pypy-string-formatting/module/__builtin__/operation.py Fri Apr 20 22:42:54 2007 @@ -19,6 +19,7 @@ def unichr(space, w_code): "Return a Unicode string of one character with the given ordinal." + # XXX range checking! return space.newunicode([__builtin__.unichr(space.int_w(w_code))]) def len(space, w_obj): Modified: pypy/branch/pypy-string-formatting/objspace/std/formatting.py ============================================================================== --- pypy/branch/pypy-string-formatting/objspace/std/formatting.py (original) +++ pypy/branch/pypy-string-formatting/objspace/std/formatting.py Fri Apr 20 22:42:54 2007 @@ -6,46 +6,18 @@ from pypy.interpreter.error import OperationError -class StringFormatter(object): - def __init__(self, space, fmt, values_w, w_valuedict): +class BaseStringFormatter(object): + def __init__(self, space, values_w, w_valuedict): self.space = space - self.fmt = fmt self.fmtpos = 0 self.values_w = values_w self.values_pos = 0 self.w_valuedict = w_valuedict - def peekchr(self): - # return the 'current' character - try: - return self.fmt[self.fmtpos] - except IndexError: - space = self.space - raise OperationError(space.w_ValueError, - space.wrap("incomplete format")) - def forward(self): # move current position forward self.fmtpos += 1 - def getmappingkey(self): - # return the mapping key in a '%(key)s' specifier - fmt = self.fmt - i = self.fmtpos + 1 # first character after '(' - i0 = i - pcount = 1 - while 1: - c = fmt[i] - if c == ')': - pcount -= 1 - if pcount == 0: - break - elif c == '(': - pcount += 1 - i += 1 - self.fmtpos = i + 1 # first character after ')' - return fmt[i0:i] - def nextinputvalue(self): # return the next value in the tuple of input arguments try: @@ -58,14 +30,6 @@ self.values_pos += 1 return w_result - def getmappingvalue(self, key): - # return the value corresponding to a key in the input dict - space = self.space - if self.w_valuedict is None: - raise OperationError(space.w_TypeError, - space.wrap("format requires a mapping")) - return space.getitem(self.w_valuedict, space.wrap(key)) - def checkconsumed(self): if self.values_pos < len(self.values_w) and self.w_valuedict is None: space = self.space @@ -73,139 +37,6 @@ space.wrap('not all arguments converted ' 'during string formatting')) - def parse_fmt(self): - if self.peekchr() == '(': - w_value = self.getmappingvalue(self.getmappingkey()) - else: - w_value = None - - self.peel_flags() - - self.width = self.peel_num() - if self.width < 0: - # this can happen: '%*s' % (-5, "hi") - self.f_ljust = True - self.width = -self.width - - if self.peekchr() == '.': - self.forward() - self.prec = self.peel_num() - if self.prec < 0: - self.prec = 0 # this can happen: '%.*f' % (-5, 3) - else: - self.prec = -1 - - if self.peekchr() in 'hlL': - self.forward() - - return w_value - - def peel_flags(self): - self.f_ljust = False - self.f_sign = False - self.f_blank = False - self.f_alt = False - self.f_zero = False - while True: - c = self.peekchr() - if c == '-': - self.f_ljust = True - elif c == '+': - self.f_sign = True - elif c == ' ': - self.f_blank = True - elif c == '#': - self.f_alt = True - elif c == '0': - self.f_zero = True - else: - break - self.forward() - - def peel_num(self): - space = self.space - c = self.peekchr() - if c == '*': - self.forward() - w_value = self.nextinputvalue() - return space.int_w(maybe_int(space, w_value)) - result = 0 - while '0' <= c <= '9': - n = ord(c) - ord('0') - try: - result = ovfcheck(ovfcheck(result * 10) + n) - except OverflowError: - raise OperationError(space.w_OverflowError, - space.wrap("precision too large")) - self.forward() - c = self.peekchr() - return result - - def format(self): - result = [] # list of characters - self.result = result - while True: - # fast path: consume as many characters as possible - fmt = self.fmt - i = self.fmtpos - while i < len(fmt): - if fmt[i] == '%': - break - result.append(fmt[i]) - i += 1 - else: - break # end of 'fmt' string - self.fmtpos = i + 1 - - # interpret the next formatter - w_value = self.parse_fmt() - c = self.peekchr() - self.forward() - if c == '%': - self.std_wp('%') - continue - if w_value is None: - w_value = self.nextinputvalue() - - # dispatch on the formatter - # (this turns into a switch after translation) - for c1 in FORMATTER_CHARS: - if c == c1: - # 'c1' is an annotation constant here, - # so this getattr() is ok - do_fmt = getattr(self, 'fmt_' + c1) - do_fmt(w_value) - break - else: - self.unknown_fmtchar() - - self.checkconsumed() - return ''.join(result) - - def unknown_fmtchar(self): - self.fmtpos -= 1 - msg = "unsupported format character '%s' (0x%x) at index %d" % ( - self.peekchr(), # XXX unicode encoding here - ord(self.peekchr()), - self.fmtpos) - space = self.space - raise OperationError(space.w_ValueError, space.wrap(msg)) - - def std_wp(self, r): - length = len(r) - if self.prec >= 0 and self.prec < length: - length = self.prec # ignore the end of the string if too long - result = self.result - padding = self.width - length - if not self.f_ljust: - for i in range(padding): # add any padding at the left of 'r' - result.append(' ') - padding = 0 - for i in range(length): # add 'r' itself - result.append(r[i]) - for i in range(padding): # add any remaining padding at the right - result.append(' ') - def std_wp_int(self, r, prefix=''): # use self.prec to add some '0' on the left of the number if self.prec >= 0: @@ -220,77 +51,6 @@ r = '' self.std_wp_number(r, prefix) - def std_wp_number(self, r, prefix=''): - # add a '+' or ' ' sign if necessary - sign = r.startswith('-') - if not sign: - if self.f_sign: - r = '+' + r - sign = True - elif self.f_blank: - r = ' ' + r - sign = True - # do the padding requested by self.width and the flags, - # without building yet another RPython string but directly - # by pushing the pad character into self.result - result = self.result - padding = self.width - len(r) - len(prefix) - - if self.f_ljust: - padnumber = '<' - elif self.f_zero: - padnumber = '0' - else: - padnumber = '>' - - if padnumber == '>': - for i in range(padding): - result.append(' ') # pad with spaces on the left - if sign: - result.append(r[0]) # the sign - for c in prefix: - result.append(c) # the prefix - if padnumber == '0': - for i in range(padding): # pad with zeroes - result.append('0') - for j in range(int(sign), len(r)): # the rest of the number - result.append(r[j]) - if padnumber == '<': # spaces on the right - for i in range(padding): - result.append(' ') - - def fmt_s(self, w_value): - self.std_wp(self.space.str_w(self.space.str(w_value))) - - def fmt_r(self, w_value): - self.std_wp(self.space.str_w(self.space.repr(w_value))) - - def fmt_c(self, w_value): - space = self.space - try: - n = space.int_w(w_value) - except OperationError, e1: - if not e1.match(space, space.w_TypeError): - raise - try: - s = space.str_w(w_value) - except OperationError, e2: - if not e2.match(space, space.w_TypeError): - raise - s = '' # something invalid to trigger the TypeError - if len(s) != 1: - raise OperationError(space.w_TypeError, - space.wrap("%c requires int or char")) - else: - try: - s = chr(n) - except ValueError: # chr(out-of-range) - raise OperationError(space.w_OverflowError, - space.wrap("character code not in range(256)")) - - self.prec = -1 # just because - self.std_wp(s) - def fmt_d(self, w_value): "int formatting" r = int_num_helper(self.space, w_value) @@ -324,6 +84,7 @@ self.std_wp_int(r, prefix) fmt_i = fmt_d + fmt_u = fmt_d def fmt_e(self, w_value): self.format_float(w_value, 'e') @@ -364,20 +125,335 @@ self.std_wp_number(r) +def make_formatter_subclass(do_unicode): + # to build two subclasses of the BaseStringFormatter class, + # each one getting its own subtle differences and RPython types. + + class StringFormatter(BaseStringFormatter): + + def __init__(self, space, fmt, values_w, w_valuedict): + BaseStringFormatter.__init__(self, space, values_w, w_valuedict) + self.fmt = fmt # either a string or a list of unichars + + def peekchr(self): + # return the 'current' character + try: + return self.fmt[self.fmtpos] + except IndexError: + space = self.space + raise OperationError(space.w_ValueError, + space.wrap("incomplete format")) + + def getmappingkey(self): + # return the mapping key in a '%(key)s' specifier + fmt = self.fmt + i = self.fmtpos + 1 # first character after '(' + i0 = i + pcount = 1 + while 1: + c = fmt[i] + if c == ')': + pcount -= 1 + if pcount == 0: + break + elif c == '(': + pcount += 1 + i += 1 + self.fmtpos = i + 1 # first character after ')' + return fmt[i0:i] + + def getmappingvalue(self, key): + # return the value corresponding to a key in the input dict + space = self.space + if self.w_valuedict is None: + raise OperationError(space.w_TypeError, + space.wrap("format requires a mapping")) + if do_unicode: + w_key = space.newunicode(key) + else: + w_key = space.wrap(key) + return space.getitem(self.w_valuedict, w_key) + + def parse_fmt(self): + if self.peekchr() == '(': + w_value = self.getmappingvalue(self.getmappingkey()) + else: + w_value = None + + self.peel_flags() + + self.width = self.peel_num() + if self.width < 0: + # this can happen: '%*s' % (-5, "hi") + self.f_ljust = True + self.width = -self.width + + if self.peekchr() == '.': + self.forward() + self.prec = self.peel_num() + if self.prec < 0: + self.prec = 0 # this can happen: '%.*f' % (-5, 3) + else: + self.prec = -1 + + if self.peekchr() in 'hlL': + self.forward() + + return w_value + + def peel_flags(self): + self.f_ljust = False + self.f_sign = False + self.f_blank = False + self.f_alt = False + self.f_zero = False + while True: + c = self.peekchr() + if c == '-': + self.f_ljust = True + elif c == '+': + self.f_sign = True + elif c == ' ': + self.f_blank = True + elif c == '#': + self.f_alt = True + elif c == '0': + self.f_zero = True + else: + break + self.forward() + + def peel_num(self): + space = self.space + c = self.peekchr() + if c == '*': + self.forward() + w_value = self.nextinputvalue() + return space.int_w(maybe_int(space, w_value)) + result = 0 + while '0' <= c <= '9': + n = ord(c) - ord('0') + try: + result = ovfcheck(ovfcheck(result * 10) + n) + except OverflowError: + raise OperationError(space.w_OverflowError, + space.wrap("precision too large")) + self.forward() + c = self.peekchr() + return result + + def format(self): + result = [] # list of characters or unichars + self.result = result + while True: + # fast path: consume as many characters as possible + fmt = self.fmt + i = self.fmtpos + while i < len(fmt): + if fmt[i] == '%': + break + result.append(fmt[i]) + i += 1 + else: + break # end of 'fmt' string + self.fmtpos = i + 1 + + # interpret the next formatter + w_value = self.parse_fmt() + c = self.peekchr() + self.forward() + if c == '%': + self.std_wp('%') + continue + if w_value is None: + w_value = self.nextinputvalue() + + # dispatch on the formatter + # (this turns into a switch after translation) + for c1 in FORMATTER_CHARS: + if c == c1: + # 'c1' is an annotation constant here, + # so this getattr() is ok + do_fmt = getattr(self, 'fmt_' + c1) + do_fmt(w_value) + break + else: + self.unknown_fmtchar() + + self.checkconsumed() + return result + + def unknown_fmtchar(self): + self.fmtpos -= 1 + c = self.peekchr() + if do_unicode: + w_defaultencoding = space.call_function( + space.sys.get('getdefaultencoding')) + w_s = space.call_method(space.newunicode([c]), + "encode", + [w_defaultencoding, + space.wrap('replace')]) + s = space.str_w(w_s) + else: + s = c + msg = "unsupported format character '%s' (0x%x) at index %d" % ( + s, ord(c), self.fmtpos) + space = self.space + raise OperationError(space.w_ValueError, space.wrap(msg)) + + def std_wp(self, r): + length = len(r) + if self.prec >= 0 and self.prec < length: + length = self.prec # ignore the end of the string if too long + result = self.result + padding = self.width - length + if not self.f_ljust: + for i in range(padding): # add any padding at the left of 'r' + result.append(' ') + padding = 0 + for i in range(length): # add 'r' itself + result.append(r[i]) + for i in range(padding): # add any remaining padding at the right + result.append(' ') + std_wp._annspecialcase_ = 'specialize:argtype(1)' + + def std_wp_number(self, r, prefix=''): + # add a '+' or ' ' sign if necessary + sign = r.startswith('-') + if not sign: + if self.f_sign: + r = '+' + r + sign = True + elif self.f_blank: + r = ' ' + r + sign = True + # do the padding requested by self.width and the flags, + # without building yet another RPython string but directly + # by pushing the pad character into self.result + result = self.result + padding = self.width - len(r) - len(prefix) + + if self.f_ljust: + padnumber = '<' + elif self.f_zero: + padnumber = '0' + else: + padnumber = '>' + + if padnumber == '>': + for i in range(padding): + result.append(' ') # pad with spaces on the left + if sign: + result.append(r[0]) # the sign + for c in prefix: + result.append(c) # the prefix + if padnumber == '0': + for i in range(padding): # pad with zeroes + result.append('0') + for j in range(int(sign), len(r)): # the rest of the number + result.append(r[j]) + if padnumber == '<': # spaces on the right + for i in range(padding): + result.append(' ') + + def fmt_s(self, w_value): + space = self.space + got_unicode = space.is_true(space.isinstance(w_value, + space.w_unicode)) + if not do_unicode: + if got_unicode: + raise NeedUnicodeFormattingError + s = space.str_w(space.str(w_value)) + else: + if not got_unicode: + w_value = space.call_function(space.w_unicode, w_value) + s = space.unichars_w(w_value) + self.std_wp(s) + + def fmt_r(self, w_value): + self.std_wp(self.space.str_w(self.space.repr(w_value))) + + def fmt_c(self, w_value): + self.prec = -1 # just because + space = self.space + if space.is_true(space.isinstance(w_value, space.w_str)): + s = space.str_w(w_value) + if len(s) != 1: + raise OperationError(space.w_TypeError, + space.wrap("%c requires int or char")) + self.std_wp(s) + elif space.is_true(space.isinstance(w_value, space.w_unicode)): + if not do_unicode: + raise NeedUnicodeFormattingError + lst = space.unichars_w(w_value) + if len(lst) != 1: + raise OperationError(space.w_TypeError, + space.wrap("%c requires int or unichar")) + self.std_wp(lst) + else: + n = space.int_w(w_value) + if do_unicode: + c = unichr(n) + # XXX no range checking, but our unichr() builtin needs + # to be fixed too + self.std_wp([c]) + else: + try: + s = chr(n) + except ValueError: # chr(out-of-range) + raise OperationError(space.w_OverflowError, + space.wrap("character code not in range(256)")) + self.std_wp(s) + + return StringFormatter + + +class NeedUnicodeFormattingError(Exception): + pass + +StringFormatter = make_formatter_subclass(do_unicode=False) +UnicodeFormatter = make_formatter_subclass(do_unicode=True) +UnicodeFormatter.__name__ = 'UnicodeFormatter' + + # an "unrolling" list of all the known format characters, # collected from which fmt_X() functions are defined in the class FORMATTER_CHARS = unrolling_iterable( - [_name[-1] for _name in StringFormatter.__dict__.keys() + [_name[-1] for _name in dir(StringFormatter) if len(_name) == 5 and _name.startswith('fmt_')]) def format(space, w_fmt, values_w, w_valuedict=None, do_unicode=False): "Entry point" - if do_unicode: # XXX - import py; py.test.skip("XXX unicode formatting") - fmt = space.str_w(w_fmt) - formatter = StringFormatter(space, fmt, values_w, w_valuedict) - return space.wrap(formatter.format()) + if not do_unicode: + fmt = space.str_w(w_fmt) + formatter = StringFormatter(space, fmt, values_w, w_valuedict) + try: + result = formatter.format() + except NeedUnicodeFormattingError: + # fall through to the unicode case + fmt = [c for c in fmt] # string => list of unichars + else: + return space.wrap(''.join(result)) + else: + fmt = space.unichars_w(w_fmt) + formatter = UnicodeFormatter(space, fmt, values_w, w_valuedict) + result = formatter.format() + return space.newunicode(result) + +def mod_format(space, w_format, w_values, do_unicode=False): + if space.is_true(space.isinstance(w_values, space.w_tuple)): + values_w = space.unpackiterable(w_values) + return format(space, w_format, values_w, None, do_unicode) + else: + # we check directly for dict to avoid obscure checking + # in simplest case + if space.is_true(space.isinstance(w_values, space.w_dict)) or \ + (space.lookup(w_values, '__getitem__') and + not space.is_true(space.isinstance(w_values, space.w_basestring))): + return format(space, w_format, [w_values], w_values, do_unicode) + else: + return format(space, w_format, [w_values], None, do_unicode) # ____________________________________________________________ # Formatting helpers Modified: pypy/branch/pypy-string-formatting/objspace/std/stringobject.py ============================================================================== --- pypy/branch/pypy-string-formatting/objspace/std/stringobject.py (original) +++ pypy/branch/pypy-string-formatting/objspace/std/stringobject.py Fri Apr 20 22:42:54 2007 @@ -14,7 +14,7 @@ from pypy.objspace.std.stringtype import sliced, joined, wrapstr, wrapchar, \ stringendswith, stringstartswith -from pypy.objspace.std.formatting import format +from pypy.objspace.std.formatting import mod_format class W_StringObject(W_Object): from pypy.objspace.std.stringtype import str_typedef as typedef @@ -917,18 +917,7 @@ # an error (1 value, 0 %-formatters) or not # (values is of a mapping type) def mod__String_ANY(space, w_format, w_values): - if space.is_true(space.isinstance(w_values, space.w_tuple)): - values_w = space.unpackiterable(w_values) - return format(space, w_format, values_w, None) - else: - # we check directly for dict to avoid obscure checking - # in simplest case - if space.is_true(space.isinstance(w_values, space.w_dict)) or \ - (space.lookup(w_values, '__getitem__') and - not space.is_true(space.isinstance(w_values, space.w_basestring))): - return format(space, w_format, [w_values], w_values) - else: - return format(space, w_format, [w_values], None) + return mod_format(space, w_format, w_values, do_unicode=False) # register all methods from pypy.objspace.std import stringtype Modified: pypy/branch/pypy-string-formatting/objspace/std/test/test_stringformat.py ============================================================================== --- pypy/branch/pypy-string-formatting/objspace/std/test/test_stringformat.py (original) +++ pypy/branch/pypy-string-formatting/objspace/std/test/test_stringformat.py Fri Apr 20 22:42:54 2007 @@ -201,6 +201,7 @@ assert u"%.1d" % 3 == '3' def test_unicode_overflow(self): + skip("do something about it or just ignore it") import sys raises(OverflowError, 'u"%.*d" % (sys.maxint, 1)') Modified: pypy/branch/pypy-string-formatting/objspace/std/unicodeobject.py ============================================================================== --- pypy/branch/pypy-string-formatting/objspace/std/unicodeobject.py (original) +++ pypy/branch/pypy-string-formatting/objspace/std/unicodeobject.py Fri Apr 20 22:42:54 2007 @@ -8,7 +8,7 @@ from pypy.rlib.rarithmetic import intmask, ovfcheck from pypy.module.unicodedata import unicodedb_3_2_0 as unicodedb -from pypy.objspace.std.formatting import format +from pypy.objspace.std.formatting import mod_format class W_UnicodeObject(W_Object): from pypy.objspace.std.unicodetype import unicode_typedef as typedef @@ -904,7 +904,6 @@ ''') -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') unicode_encode__Unicode_ANY_ANY = app.interphook('unicode_encode__Unicode_ANY_ANY') @@ -1035,21 +1034,7 @@ #repr__Unicode = app.interphook('repr__Unicode') # uncomment when repr code is moved to _codecs def mod__Unicode_ANY(space, w_format, w_values): - if space.is_true(space.isinstance(w_values, space.w_tuple)): - return format(space, w_format, w_values, space.w_None, do_unicode=True) - else: - # we check directly for dict to avoid obscure checking - # in simplest case - if space.is_true(space.isinstance(w_values, space.w_dict)) or \ - (space.lookup(w_values, '__getitem__') and - not space.is_true(space.isinstance(w_values, space.w_basestring))): - return format(space, w_format, - space.newtuple([w_values]), w_values, - do_unicode=True) - else: - return format(space, w_format, - space.newtuple([w_values]), space.w_None, - do_unicode=True) + return mod_format(space, w_format, w_values, do_unicode=True) import unicodetype From santagada at codespeak.net Sat Apr 21 02:02:06 2007 From: santagada at codespeak.net (santagada at codespeak.net) Date: Sat, 21 Apr 2007 02:02:06 +0200 (CEST) Subject: [pypy-svn] r42221 - in pypy/dist/pypy/lang/js: . test Message-ID: <20070421000206.BB0C580A0@code0.codespeak.net> Author: santagada Date: Sat Apr 21 02:02:05 2007 New Revision: 42221 Modified: pypy/dist/pypy/lang/js/jsobj.py pypy/dist/pypy/lang/js/operations.py pypy/dist/pypy/lang/js/test/test_interp.py Log: last fixes to make prototypes work. but js still miss cloning from the base Function Object and Array classes Modified: pypy/dist/pypy/lang/js/jsobj.py ============================================================================== --- pypy/dist/pypy/lang/js/jsobj.py (original) +++ pypy/dist/pypy/lang/js/jsobj.py Sat Apr 21 02:02:05 2007 @@ -161,11 +161,12 @@ obj.Prototype = prot else: obj.Prototype = ctx.get_global().Get('Object') - ret = self.Call(ctx, args, this=obj) - if isinstance(ret, W_PrimitiveObject): - return ret - else: + + try: #this is a hack to be compatible to spidermonkey + self.Call(ctx, args, this=obj) return obj + except ExecutionReturned, e: + return e.value def Get(self, P): @@ -293,6 +294,9 @@ self.length = r_uint(0) self.set_builtin_call(arraycallbi) + def Construct(self, ctx, args=[]): + return self + def Put(self, P, V, dd=False, ro=False, de=False, it=False): Modified: pypy/dist/pypy/lang/js/operations.py ============================================================================== --- pypy/dist/pypy/lang/js/operations.py (original) +++ pypy/dist/pypy/lang/js/operations.py Sat Apr 21 02:02:05 2007 @@ -228,6 +228,9 @@ r1 = self.left.eval(ctx) r2 = self.right.eval(ctx) r3 = r1.GetValue() + if not isinstance(r3, W_PrimitiveObject): # TODO: review this on the spec + raise JsTypeError(str(r3) + " is not a function") + if isinstance(r1, W_Reference): r6 = r1.GetBase() else: @@ -237,8 +240,11 @@ else: r7 = r6 - retval = r3.Call(ctx=ctx, args=r2.get_args(), this=r7) - return retval + try: + retval = r3.Call(ctx=ctx, args=r2.get_args(), this=r7) + return retval + except ExecutionReturned, e: + return e.value class Comma(BinaryOp): opcode = 'COMMA' @@ -282,9 +288,10 @@ self.params = params.split(',') def eval(self, ctx): - w_obj = W_Object(ctx=ctx, callfunc = self) - w_obj.Put('prototype', W_Object(ctx=ctx)) - return w_obj + # TODO: this is wrong, should clone the function prototype + w_obj = W_Object(ctx=ctx, callfunc = self) + w_obj.Put('prototype', W_Object(ctx=ctx)) + return w_obj class Identifier(Expression): opcode = 'IDENTIFIER' @@ -855,7 +862,7 @@ return last except Exception, e: if isinstance(e, ExecutionReturned) and e.type == 'return': - return e.value + raise else: # TODO: proper exception handling print "exception in line: %s, on: %s"%(node.lineno, node.value) 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 Apr 21 02:02:05 2007 @@ -522,7 +522,8 @@ def test_function_this(self): - py.test.skip() self.assert_prints(""" - function foo() {print("debug");this.bar = function() {}}; var f = new foo(); f.bar(); - """, ['',]) + function foo() {print("debug");this.bar = function() {}}; + var f = new foo(); + f.bar(); + """, ['debug',]) From santagada at codespeak.net Sat Apr 21 02:04:43 2007 From: santagada at codespeak.net (santagada at codespeak.net) Date: Sat, 21 Apr 2007 02:04:43 +0200 (CEST) Subject: [pypy-svn] r42222 - pypy/dist/pypy/lang/js Message-ID: <20070421000443.C9BFF80A0@code0.codespeak.net> Author: santagada Date: Sat Apr 21 02:04:43 2007 New Revision: 42222 Modified: pypy/dist/pypy/lang/js/operations.py Log: remove a print debug statement Modified: pypy/dist/pypy/lang/js/operations.py ============================================================================== --- pypy/dist/pypy/lang/js/operations.py (original) +++ pypy/dist/pypy/lang/js/operations.py Sat Apr 21 02:04:43 2007 @@ -1042,7 +1042,6 @@ if prop.de: continue iterator = self.iterator.eval(ctx) - print prop.name iterator.PutValue(prop.value, ctx) try: result = self.body.execute(ctx) From afa at codespeak.net Sat Apr 21 10:49:21 2007 From: afa at codespeak.net (afa at codespeak.net) Date: Sat, 21 Apr 2007 10:49:21 +0200 (CEST) Subject: [pypy-svn] r42226 - pypy/dist/pypy/module/_file/test Message-ID: <20070421084921.2692580A0@code0.codespeak.net> Author: afa Date: Sat Apr 21 10:49:20 2007 New Revision: 42226 Modified: pypy/dist/pypy/module/_file/test/test_file_extra.py Log: oops... os.O_BINARY does not exist on Unix. Modified: pypy/dist/pypy/module/_file/test/test_file_extra.py ============================================================================== --- pypy/dist/pypy/module/_file/test/test_file_extra.py (original) +++ pypy/dist/pypy/module/_file/test/test_file_extra.py Sat Apr 21 10:49:20 2007 @@ -248,7 +248,8 @@ extra_args = () def setup_method(self, method): - fd = os.open(TestFile.expected_filename, os.O_RDONLY|os.O_BINARY) + O_BINARY = getattr(os, "O_BINARY", 0) + fd = os.open(TestFile.expected_filename, os.O_RDONLY | O_BINARY) self.file = _file.file.fdopen(fd, self.expected_mode, *self.extra_args) From pedronis at codespeak.net Sat Apr 21 15:17:42 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 21 Apr 2007 15:17:42 +0200 (CEST) Subject: [pypy-svn] r42231 - pypy/dist/pypy/doc Message-ID: <20070421131742.08EFC809F@code0.codespeak.net> Author: pedronis Date: Sat Apr 21 15:17:41 2007 New Revision: 42231 Modified: pypy/dist/pypy/doc/cleanup-todo.txt Log: add in-progress rctypes rewrite to the list Modified: pypy/dist/pypy/doc/cleanup-todo.txt ============================================================================== --- pypy/dist/pypy/doc/cleanup-todo.txt (original) +++ pypy/dist/pypy/doc/cleanup-todo.txt Sat Apr 21 15:17:41 2007 @@ -26,6 +26,7 @@ we can have more than one translator/annotator around (with the timeshifter) - unicode strings in RPython + - finish rctypes rewrite (some of items of this list depend on it) interpreter ----------- From cfbolz at codespeak.net Sat Apr 21 15:52:57 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sat, 21 Apr 2007 15:52:57 +0200 (CEST) Subject: [pypy-svn] r42232 - in pypy/dist/pypy/lang/prolog: builtin interpreter interpreter/test Message-ID: <20070421135257.27DBD809E@code0.codespeak.net> Author: cfbolz Date: Sat Apr 21 15:52:56 2007 New Revision: 42232 Modified: pypy/dist/pypy/lang/prolog/builtin/database.py pypy/dist/pypy/lang/prolog/interpreter/engine.py pypy/dist/pypy/lang/prolog/interpreter/test/test_builtin.py pypy/dist/pypy/lang/prolog/interpreter/test/test_parsing.py Log: make asserting of new facts more efficient and support the "logical update view" for retract. Modified: pypy/dist/pypy/lang/prolog/builtin/database.py ============================================================================== --- pypy/dist/pypy/lang/prolog/builtin/database.py (original) +++ pypy/dist/pypy/lang/prolog/builtin/database.py Sat Apr 21 15:52:56 2007 @@ -14,8 +14,8 @@ if signature in builtins: error.throw_permission_error("modify", "static_procedure", predicate) - if signature in engine.signature2rules: - del engine.signature2rules[signature] + if signature in engine.signature2function: + del engine.signature2function[signature] expose_builtin(impl_abolish, "abolish", unwrap_spec=["obj"]) def impl_assert(engine, rule): @@ -39,9 +39,13 @@ assert isinstance(head, term.Callable) error.throw_permission_error("modify", "static_procedure", head.get_prolog_signature()) - rules = engine.signature2rules.get(head.signature, []) - for i in range(len(rules)): - rule = rules[i] + function = engine.signature2function.get(head.signature, None) + if function is None: + raise UnificationFailed + #import pdb; pdb.set_trace() + rulechain = function.rulechain + while rulechain: + rule = rulechain.rule oldstate = engine.frame.branch() # standardizing apart try: @@ -51,8 +55,15 @@ except error.UnificationFailed: engine.frame.revert(oldstate) else: - del rules[i] + if function.rulechain is rulechain: + if rulechain.next is None: + del engine.signature2function[head.signature] + else: + function.rulechain = rulechain.next + else: + function.remove(rulechain) break + rulechain = rulechain.next else: raise error.UnificationFailed() expose_builtin(impl_retract, "retract", unwrap_spec=["callable"]) Modified: pypy/dist/pypy/lang/prolog/interpreter/engine.py ============================================================================== --- pypy/dist/pypy/lang/prolog/interpreter/engine.py (original) +++ pypy/dist/pypy/lang/prolog/interpreter/engine.py Sat Apr 21 15:52:56 2007 @@ -90,10 +90,61 @@ self.extend(1) return result +class LinkedRules(object): + def __init__(self, rule, next=None): + self.rule = rule + self.next = next + + def copy(self, stopat=None): + first = LinkedRules(self.rule) + curr = self.next + copy = first + while curr is not stopat: + new = LinkedRules(curr.rule) + copy.next = new + copy = new + curr = curr.next + return first, copy + + def find_applicable_rule(self, query, uh1): + #import pdb;pdb.set_trace() + while self: + uh2 = self.rule.unify_hash + assert len(uh1) == len(uh2) + for j in range(len(uh1)): + if uh1[j] != 0 and uh2[j] != 0 and uh1[j] != uh2[j]: + break + else: + return self + self = self.next + return None + + def __repr__(self): + return "LinkedRules(%r, %r)" % (self.rule, self.next) + + +class Function(object): + def __init__(self, firstrule): + self.rulechain = LinkedRules(firstrule) + self.last = self.rulechain + + def add_rule(self, rule, end): + #import pdb; pdb.set_trace() + if end: + self.rulechain, last = self.rulechain.copy() + self.last = LinkedRules(rule) + last.next = self.last + else: + self.rulechain = LinkedRules(rule, self.rulechain) + + def remove(self, rulechain): + self.rulechain, last = self.rulechain.copy(rulechain) + last.next = rulechain.next + class Engine(object): def __init__(self): self.frame = Frame() - self.signature2rules = {} + self.signature2function = {} self.parser = None self.operations = None @@ -116,13 +167,11 @@ if signature in builtin.builtins: error.throw_permission_error( "modify", "static_procedure", rule.head.get_prolog_signature()) - # it's important to not update the list in place, because - # there might be references to it in the stack somewhere - rules = self.signature2rules.get(signature, []) - if end: - self.signature2rules[signature] = rules + [rule] + function = self.signature2function.get(signature, None) + if function is not None: + self.signature2function[signature].add_rule(rule, end) else: - self.signature2rules[signature] = [rule] + rules + self.signature2function[signature] = Function(rule) def run(self, query, continuation=DONOTHING): if not isinstance(query, Callable): @@ -164,19 +213,21 @@ def user_call(self, query, continuation): #import pdb; pdb.set_trace() signature = query.signature - rules = self.signature2rules.get(signature, None) - if rules is None: + function = self.signature2function.get(signature, None) + if function is None: error.throw_existence_error( "procedure", query.get_prolog_signature()) unify_hash = query.get_deeper_unify_hash(self.frame) - rule, i = self.find_applicable_rule(0, rules, query, unify_hash) - if rule is None: + rulechain = function.rulechain.find_applicable_rule(query, unify_hash) + if rulechain is None: # none of the rules apply raise UnificationFailed() + rule = rulechain.rule + rulechain = rulechain.next oldstate = self.frame.branch() - while 1: - next, i = self.find_applicable_rule(i, rules, query, unify_hash) - if next is None: + while rulechain: + rulechain = rulechain.find_applicable_rule(query, unify_hash) + if rulechain is None: self.frame.discard(oldstate) break if rule.contains_cut: @@ -199,7 +250,8 @@ return result except UnificationFailed: self.frame.revert(oldstate) - rule = next + rule = rulechain.rule + rulechain = rulechain.next if rule.contains_cut: continuation = LimitedScopeContinuation(continuation) try: @@ -226,18 +278,6 @@ return self.call(nextcall, continuation) return continuation.call(self) - def find_applicable_rule(self, startindex, rules, query, uh1): - i = startindex - while i < len(rules): - uh2 = rules[i].unify_hash - assert len(uh1) == len(uh2) - for j in range(len(uh1)): - if uh1[j] != 0 and uh2[j] != 0 and uh1[j] != uh2[j]: - break - else: - return rules[i], i + 1 - i += 1 - return None, 0 def continue_after_cut(self, continuation, lsc=None): while 1: Modified: pypy/dist/pypy/lang/prolog/interpreter/test/test_builtin.py ============================================================================== --- pypy/dist/pypy/lang/prolog/interpreter/test/test_builtin.py (original) +++ pypy/dist/pypy/lang/prolog/interpreter/test/test_builtin.py Sat Apr 21 15:52:56 2007 @@ -120,6 +120,25 @@ """) frames = collect_all(e, "g(X).") assert len(frames) == 3 + e = get_engine(""" + p :- assertz(p), fail. + p :- fail. + """) + assert_false("p.", e) + e = get_engine(""" + q :- fail. + q :- assertz(q), fail. + """) + assert_false("q.", e) + + +def test_retract_logical_update_view(): + e = get_engine(""" + p :- retract(p :- true), fail. + p :- true. + """) + assert_true("p.", e) + assert_false("p.", e) def test_abolish(): e = get_engine("g(b, b). g(c, c). g(a). f(b, b). h(b, b).") Modified: pypy/dist/pypy/lang/prolog/interpreter/test/test_parsing.py ============================================================================== --- pypy/dist/pypy/lang/prolog/interpreter/test/test_parsing.py (original) +++ pypy/dist/pypy/lang/prolog/interpreter/test/test_parsing.py Sat Apr 21 15:52:56 2007 @@ -30,7 +30,7 @@ for fact in facts: print fact e.add_rule(fact) - assert e.signature2rules["add_numeral/3"][0].head.args[1].name == "null" + assert e.signature2function["add_numeral/3"].rulechain.rule.head.args[1].name == "null" four = Term("succ", [Term("succ", [Term("succ", [Term("succ", [Atom("null")])])])]) e.run(parse_query_term("numeral(succ(succ(null))).")) From cfbolz at codespeak.net Sat Apr 21 16:44:36 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sat, 21 Apr 2007 16:44:36 +0200 (CEST) Subject: [pypy-svn] r42236 - pypy/dist/pypy/lang/prolog/builtin Message-ID: <20070421144436.29D8A809E@code0.codespeak.net> Author: cfbolz Date: Sat Apr 21 16:44:35 2007 New Revision: 42236 Modified: pypy/dist/pypy/lang/prolog/builtin/database.py Log: fix translation Modified: pypy/dist/pypy/lang/prolog/builtin/database.py ============================================================================== --- pypy/dist/pypy/lang/prolog/builtin/database.py (original) +++ pypy/dist/pypy/lang/prolog/builtin/database.py Sat Apr 21 16:44:35 2007 @@ -41,7 +41,7 @@ head.get_prolog_signature()) function = engine.signature2function.get(head.signature, None) if function is None: - raise UnificationFailed + raise error.UnificationFailed #import pdb; pdb.set_trace() rulechain = function.rulechain while rulechain: From cfbolz at codespeak.net Sat Apr 21 16:44:43 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sat, 21 Apr 2007 16:44:43 +0200 (CEST) Subject: [pypy-svn] r42237 - pypy/dist/pypy/lang/prolog/interpreter Message-ID: <20070421144443.64DAB80AC@code0.codespeak.net> Author: cfbolz Date: Sat Apr 21 16:44:42 2007 New Revision: 42237 Modified: pypy/dist/pypy/lang/prolog/interpreter/engine.py Log: resolve XXX Modified: pypy/dist/pypy/lang/prolog/interpreter/engine.py ============================================================================== --- pypy/dist/pypy/lang/prolog/interpreter/engine.py (original) +++ pypy/dist/pypy/lang/prolog/interpreter/engine.py Sat Apr 21 16:44:42 2007 @@ -42,13 +42,11 @@ return self.vars[index] def setvar(self, index, val): - # XXX check if oldval != val - # it happens all the time in get_last_var_in_chain_and_val() oldval = self.vars[index] self.vars[index] = val # only trail for variables that have a chance to get restored # on the last choice point - if index < self.last_branch: + if index < self.last_branch and oldval is not val: self.trail.append((index, oldval)) def branch(self): From cfbolz at codespeak.net Sun Apr 22 21:12:54 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sun, 22 Apr 2007 21:12:54 +0200 (CEST) Subject: [pypy-svn] r42245 - in pypy/dist/pypy/lang/prolog: builtin interpreter interpreter/test Message-ID: <20070422191254.CEF868091@code0.codespeak.net> Author: cfbolz Date: Sun Apr 22 21:12:52 2007 New Revision: 42245 Modified: pypy/dist/pypy/lang/prolog/builtin/allsolution.py pypy/dist/pypy/lang/prolog/builtin/arithmeticbuiltin.py pypy/dist/pypy/lang/prolog/builtin/atomconstruction.py pypy/dist/pypy/lang/prolog/builtin/control.py pypy/dist/pypy/lang/prolog/builtin/database.py pypy/dist/pypy/lang/prolog/builtin/exception.py pypy/dist/pypy/lang/prolog/builtin/parseraccess.py pypy/dist/pypy/lang/prolog/builtin/register.py pypy/dist/pypy/lang/prolog/builtin/termconstruction.py pypy/dist/pypy/lang/prolog/builtin/unify.py pypy/dist/pypy/lang/prolog/interpreter/arithmetic.py pypy/dist/pypy/lang/prolog/interpreter/choice.py pypy/dist/pypy/lang/prolog/interpreter/engine.py pypy/dist/pypy/lang/prolog/interpreter/interactive.py pypy/dist/pypy/lang/prolog/interpreter/parsing.py pypy/dist/pypy/lang/prolog/interpreter/term.py pypy/dist/pypy/lang/prolog/interpreter/test/dont_test_translate.py pypy/dist/pypy/lang/prolog/interpreter/test/test_arithmetic.py pypy/dist/pypy/lang/prolog/interpreter/test/test_builtin.py pypy/dist/pypy/lang/prolog/interpreter/test/test_engine.py pypy/dist/pypy/lang/prolog/interpreter/test/test_parsing.py pypy/dist/pypy/lang/prolog/interpreter/test/test_unification.py pypy/dist/pypy/lang/prolog/interpreter/test/tool.py pypy/dist/pypy/lang/prolog/interpreter/translatedmain.py Log: some renamings, lots of cleanups. Re-implement unification, especially the way terms are unified and standardized apart. Modified: pypy/dist/pypy/lang/prolog/builtin/allsolution.py ============================================================================== --- pypy/dist/pypy/lang/prolog/builtin/allsolution.py (original) +++ pypy/dist/pypy/lang/prolog/builtin/allsolution.py Sun Apr 22 21:12:52 2007 @@ -11,23 +11,23 @@ self.template = template def call(self, engine): - clone = self.template.getvalue(engine.frame) + clone = self.template.getvalue(engine.heap) self.found.append(clone) raise error.UnificationFailed() def impl_findall(engine, template, goal, bag): - oldstate = engine.frame.branch() + oldstate = engine.heap.branch() collector = FindallContinuation(template) try: engine.call(goal, collector) except error.UnificationFailed: - engine.frame.revert(oldstate) + engine.heap.revert(oldstate) result = term.Atom("[]") for i in range(len(collector.found) - 1, -1, -1): copy = collector.found[i] d = {} - copy = copy.clone_compress_vars(d, engine.frame.maxvar()) - engine.frame.extend(len(d)) + copy = copy.clone_compress_vars(d, engine.heap.maxvar()) + engine.heap.extend(len(d)) result = term.Term(".", [copy, result]) - bag.unify(result, engine.frame) + bag.unify(result, engine.heap) expose_builtin(impl_findall, "findall", unwrap_spec=['raw', 'callable', 'raw']) Modified: pypy/dist/pypy/lang/prolog/builtin/arithmeticbuiltin.py ============================================================================== --- pypy/dist/pypy/lang/prolog/builtin/arithmeticbuiltin.py (original) +++ pypy/dist/pypy/lang/prolog/builtin/arithmeticbuiltin.py Sun Apr 22 21:12:52 2007 @@ -9,13 +9,13 @@ def impl_between(engine, lower, upper, varorint, continuation): if isinstance(varorint, term.Var): for i in range(lower, upper): - oldstate = engine.frame.branch() + oldstate = engine.heap.branch() try: - varorint.unify(term.Number(i), engine.frame) + varorint.unify(term.Number(i), engine.heap) return continuation.call(engine) except error.UnificationFailed: - engine.frame.revert(oldstate) - varorint.unify(term.Number(upper), engine.frame) + engine.heap.revert(oldstate) + varorint.unify(term.Number(upper), engine.heap) return continuation.call(engine) else: integer = helper.unwrap_int(varorint) @@ -26,7 +26,7 @@ handles_continuation=True) def impl_is(engine, var, num): - var.unify(num, engine.frame) + var.unify(num, engine.heap) expose_builtin(impl_is, "is", unwrap_spec=["raw", "arithmetic"]) for ext, prolog, python in [("eq", "=:=", "=="), Modified: pypy/dist/pypy/lang/prolog/builtin/atomconstruction.py ============================================================================== --- pypy/dist/pypy/lang/prolog/builtin/atomconstruction.py (original) +++ pypy/dist/pypy/lang/prolog/builtin/atomconstruction.py Sun Apr 22 21:12:52 2007 @@ -11,13 +11,13 @@ # nondeterministic splitting of result r = helper.convert_to_str(result) for i in range(len(r) + 1): - oldstate = engine.frame.branch() + oldstate = engine.heap.branch() try: - a1.unify(term.Atom(r[:i]), engine.frame) - a2.unify(term.Atom(r[i:]), engine.frame) + a1.unify(term.Atom(r[:i]), engine.heap) + a2.unify(term.Atom(r[i:]), engine.heap) return continuation.call(engine) except error.UnificationFailed: - engine.frame.revert(oldstate) + engine.heap.revert(oldstate) raise error.UnificationFailed() else: s2 = helper.convert_to_str(a2) @@ -25,7 +25,7 @@ if r.endswith(s2): stop = len(r) - len(s2) assert stop > 0 - a1.unify(term.Atom(r[:stop]), engine.frame) + a1.unify(term.Atom(r[:stop]), engine.heap) else: raise error.UnificationFailed() else: @@ -33,12 +33,12 @@ if isinstance(a2, term.Var): r = helper.convert_to_str(result) if r.startswith(s1): - a2.unify(term.Atom(r[len(s1):]), engine.frame) + a2.unify(term.Atom(r[len(s1):]), engine.heap) else: raise error.UnificationFailed() else: s2 = helper.convert_to_str(a2) - result.unify(term.Atom(s1 + s2), engine.frame) + result.unify(term.Atom(s1 + s2), engine.heap) return continuation.call(engine) expose_builtin(impl_atom_concat, "atom_concat", unwrap_spec=["obj", "obj", "obj"], @@ -47,7 +47,7 @@ def impl_atom_length(engine, s, length): if not (isinstance(length, term.Var) or isinstance(length, term.Number)): error.throw_type_error("integer", length) - term.Number(len(s)).unify(length, engine.frame) + term.Number(len(s)).unify(length, engine.heap) expose_builtin(impl_atom_length, "atom_length", unwrap_spec = ["atom", "obj"]) def impl_sub_atom(engine, s, before, length, after, sub, continuation): @@ -70,7 +70,7 @@ if startbefore < 0: startbefore = 0 stopbefore = len(s) + 1 - oldstate = engine.frame.branch() + oldstate = engine.heap.branch() if not isinstance(sub, term.Var): s1 = helper.unwrap_atom(sub) if len(s1) >= stoplength or len(s1) < startlength: @@ -83,12 +83,12 @@ if b < 0: break start = b + 1 - before.unify(term.Number(b), engine.frame) - after.unify(term.Number(len(s) - len(s1) - b), engine.frame) - length.unify(term.Number(len(s1)), engine.frame) + before.unify(term.Number(b), engine.heap) + after.unify(term.Number(len(s) - len(s1) - b), engine.heap) + length.unify(term.Number(len(s1)), engine.heap) return continuation.call(engine) except: - engine.frame.revert(oldstate) + engine.heap.revert(oldstate) raise except error.UnificationFailed: pass @@ -100,13 +100,13 @@ continue try: try: - before.unify(term.Number(b), engine.frame) - after.unify(term.Number(len(s) - l - b), engine.frame) - length.unify(term.Number(l), engine.frame) - sub.unify(term.Atom(s[b:b + l]), engine.frame) + before.unify(term.Number(b), engine.heap) + after.unify(term.Number(len(s) - l - b), engine.heap) + length.unify(term.Number(l), engine.heap) + sub.unify(term.Atom(s[b:b + l]), engine.heap) return continuation.call(engine) except: - engine.frame.revert(oldstate) + engine.heap.revert(oldstate) raise except error.UnificationFailed: pass @@ -119,14 +119,14 @@ continue try: try: - before.unify(term.Number(b), engine.frame) - after.unify(term.Number(a), engine.frame) - length.unify(term.Number(l), engine.frame) - sub.unify(term.Atom(s[b:b + l]), engine.frame) + before.unify(term.Number(b), engine.heap) + after.unify(term.Number(a), engine.heap) + length.unify(term.Number(l), engine.heap) + sub.unify(term.Atom(s[b:b + l]), engine.heap) return continuation.call(engine) return None except: - engine.frame.revert(oldstate) + engine.heap.revert(oldstate) raise except error.UnificationFailed: pass Modified: pypy/dist/pypy/lang/prolog/builtin/control.py ============================================================================== --- pypy/dist/pypy/lang/prolog/builtin/control.py (original) +++ pypy/dist/pypy/lang/prolog/builtin/control.py Sun Apr 22 21:12:52 2007 @@ -33,7 +33,7 @@ self.continuation = continuation def call(self, engine): - next_call = self.next_call.dereference(engine.frame) + next_call = self.next_call.dereference(engine.heap) if isinstance(next_call, term.Var): error.throw_instantiation_error() next_call = helper.ensure_callable(next_call) @@ -48,11 +48,11 @@ handles_continuation=True) def impl_or(engine, call1, call2, continuation): - oldstate = engine.frame.branch() + oldstate = engine.heap.branch() try: return engine.call(call1, continuation) except error.UnificationFailed: - engine.frame.revert(oldstate) + engine.heap.revert(oldstate) return engine.call(call2, continuation) expose_builtin(impl_or, ";", unwrap_spec=["callable", "callable"], @@ -70,11 +70,11 @@ expose_builtin(impl_not, ["not", "\\+"], unwrap_spec=["callable"]) def impl_if(engine, if_clause, then_clause, continuation): - oldstate = engine.frame.branch() + oldstate = engine.heap.branch() try: engine.call(if_clause) except error.UnificationFailed: - engine.frame.revert(oldstate) + engine.heap.revert(oldstate) raise return engine.call(helper.ensure_callable(then_clause), continuation) expose_builtin(impl_if, "->", unwrap_spec=["callable", "raw"], Modified: pypy/dist/pypy/lang/prolog/builtin/database.py ============================================================================== --- pypy/dist/pypy/lang/prolog/builtin/database.py (original) +++ pypy/dist/pypy/lang/prolog/builtin/database.py Sun Apr 22 21:12:52 2007 @@ -19,11 +19,11 @@ expose_builtin(impl_abolish, "abolish", unwrap_spec=["obj"]) def impl_assert(engine, rule): - engine.add_rule(rule.getvalue(engine.frame)) + engine.add_rule(rule.getvalue(engine.heap)) expose_builtin(impl_assert, ["assert", "assertz"], unwrap_spec=["callable"]) def impl_asserta(engine, rule): - engine.add_rule(rule.getvalue(engine.frame), end=False) + engine.add_rule(rule.getvalue(engine.heap), end=False) expose_builtin(impl_asserta, "asserta", unwrap_spec=["callable"]) @@ -46,14 +46,14 @@ rulechain = function.rulechain while rulechain: rule = rulechain.rule - oldstate = engine.frame.branch() + oldstate = engine.heap.branch() # standardizing apart try: - deleted_body = rule.clone_and_unify_head(engine.frame, head) + deleted_body = rule.clone_and_unify_head(engine.heap, head) if body is not None: - body.unify(deleted_body, engine.frame) + body.unify(deleted_body, engine.heap) except error.UnificationFailed: - engine.frame.revert(oldstate) + engine.heap.revert(oldstate) else: if function.rulechain is rulechain: if rulechain.next is None: Modified: pypy/dist/pypy/lang/prolog/builtin/exception.py ============================================================================== --- pypy/dist/pypy/lang/prolog/builtin/exception.py (original) +++ pypy/dist/pypy/lang/prolog/builtin/exception.py Sun Apr 22 21:12:52 2007 @@ -8,24 +8,24 @@ def impl_catch(engine, goal, catcher, recover, continuation): catching_continuation = enginemod.LimitedScopeContinuation(continuation) - old_state = engine.frame.branch() + old_state = engine.heap.branch() try: return engine.call(goal, catching_continuation) except error.CatchableError, e: if not catching_continuation.scope_active: raise - exc_term = e.term.getvalue(engine.frame) - engine.frame.revert(old_state) + exc_term = e.term.getvalue(engine.heap) + engine.heap.revert(old_state) d = {} - exc_term = exc_term.clone_compress_vars(d, engine.frame.maxvar()) - engine.frame.extend(len(d)) + exc_term = exc_term.clone_compress_vars(d, engine.heap.maxvar()) + engine.heap.extend(len(d)) try: impl_ground(engine, exc_term) except error.UnificationFailed: raise error.UncatchableError( "not implemented: catching of non-ground terms") try: - catcher.unify(exc_term, engine.frame) + catcher.unify(exc_term, engine.heap) except error.UnificationFailed: if isinstance(e, error.UserError): raise error.UserError(exc_term) Modified: pypy/dist/pypy/lang/prolog/builtin/parseraccess.py ============================================================================== --- pypy/dist/pypy/lang/prolog/builtin/parseraccess.py (original) +++ pypy/dist/pypy/lang/prolog/builtin/parseraccess.py Sun Apr 22 21:12:52 2007 @@ -9,14 +9,14 @@ for prec, allops in engine.getoperations(): for form, ops in allops: for op in ops: - oldstate = engine.frame.branch() + oldstate = engine.heap.branch() try: - precedence.unify(term.Number(prec), engine.frame) - typ.unify(term.Atom(form), engine.frame) - name.unify(term.Atom(op), engine.frame) + precedence.unify(term.Number(prec), engine.heap) + typ.unify(term.Atom(form), engine.heap) + name.unify(term.Atom(op), engine.heap) return continuation.call(engine) except error.UnificationFailed: - engine.frame.revert(oldstate) + engine.heap.revert(oldstate) raise error.UnificationFailed() expose_builtin(impl_current_op, "current_op", unwrap_spec=["obj", "obj", "obj"], handles_continuation=True) Modified: pypy/dist/pypy/lang/prolog/builtin/register.py ============================================================================== --- pypy/dist/pypy/lang/prolog/builtin/register.py (original) +++ pypy/dist/pypy/lang/prolog/builtin/register.py Sun Apr 22 21:12:52 2007 @@ -25,10 +25,10 @@ varname = "var%s" % (i, ) subargs.append(varname) if spec in ("obj", "callable", "int", "atom", "arithmetic"): - code.append(" %s = query.args[%s].dereference(engine.frame)" % + code.append(" %s = query.args[%s].dereference(engine.heap)" % (varname, i)) elif spec in ("concrete", "list"): - code.append(" %s = query.args[%s].getvalue(engine.frame)" % + code.append(" %s = query.args[%s].getvalue(engine.heap)" % (varname, i)) if spec in ("callable", "int", "atom", "arithmetic", "list"): code.append( Modified: pypy/dist/pypy/lang/prolog/builtin/termconstruction.py ============================================================================== --- pypy/dist/pypy/lang/prolog/builtin/termconstruction.py (original) +++ pypy/dist/pypy/lang/prolog/builtin/termconstruction.py Sun Apr 22 21:12:52 2007 @@ -7,11 +7,11 @@ def impl_functor(engine, t, functor, arity): if helper.is_atomic(t): - functor.unify(t, engine.frame) - arity.unify(term.Number(0), engine.frame) + functor.unify(t, engine.heap) + arity.unify(term.Number(0), engine.heap) elif isinstance(t, term.Term): - functor.unify(term.Atom(t.name), engine.frame) - arity.unify(term.Number(len(t.args)), engine.frame) + functor.unify(term.Atom(t.name), engine.heap) + arity.unify(term.Number(len(t.args)), engine.heap) elif isinstance(t, term.Var): if isinstance(functor, term.Var): error.throw_instantiation_error() @@ -23,15 +23,15 @@ else: functor = helper.ensure_atomic(functor) if a == 0: - t.unify(helper.ensure_atomic(functor), engine.frame) + t.unify(helper.ensure_atomic(functor), engine.heap) else: name = helper.unwrap_atom(functor) - start = engine.frame.needed_vars - engine.frame.extend(a) + start = engine.heap.needed_vars + engine.heap.extend(a) t.unify( term.Term(name, [term.Var(i) for i in range(start, start + a)]), - engine.frame) + engine.heap) expose_builtin(impl_functor, "functor", unwrap_spec=["obj", "obj", "obj"]) def impl_arg(engine, first, second, third, continuation): @@ -44,13 +44,13 @@ if isinstance(first, term.Var): for i in range(len(second.args)): arg = second.args[i] - oldstate = engine.frame.branch() + oldstate = engine.heap.branch() try: - third.unify(arg, engine.frame) - first.unify(term.Number(i + 1), engine.frame) + third.unify(arg, engine.heap) + first.unify(term.Number(i + 1), engine.heap) return continuation.call(engine) except error.UnificationFailed: - engine.frame.revert(oldstate) + engine.heap.revert(oldstate) raise error.UnificationFailed() elif isinstance(first, term.Number): num = first.num @@ -61,7 +61,7 @@ if num > len(second.args): raise error.UnificationFailed() arg = second.args[num - 1] - third.unify(arg, engine.frame) + third.unify(arg, engine.heap) else: error.throw_type_error("integer", first) return continuation.call(engine) @@ -76,9 +76,9 @@ l = [first] u1 = helper.wrap_list(l) if not isinstance(second, term.Var): - u1.unify(second, engine.frame) + u1.unify(second, engine.heap) else: - u1.unify(second, engine.frame) + u1.unify(second, engine.heap) else: if isinstance(second, term.Var): error.throw_instantiation_error() @@ -87,14 +87,14 @@ head = l[0] if not isinstance(head, term.Atom): error.throw_type_error("atom", head) - term.Term(head.name, l[1:]).unify(first, engine.frame) + term.Term(head.name, l[1:]).unify(first, engine.heap) expose_builtin(impl_univ, "=..", unwrap_spec=["obj", "obj"]) def impl_copy_term(engine, interm, outterm): d = {} - copy = interm.clone_compress_vars(d, engine.frame.maxvar()) - engine.frame.extend(len(d)) - outterm.unify(copy, engine.frame) + copy = interm.clone_compress_vars(d, engine.heap.maxvar()) + engine.heap.extend(len(d)) + outterm.unify(copy, engine.heap) expose_builtin(impl_copy_term, "copy_term", unwrap_spec=["obj", "obj"]) Modified: pypy/dist/pypy/lang/prolog/builtin/unify.py ============================================================================== --- pypy/dist/pypy/lang/prolog/builtin/unify.py (original) +++ pypy/dist/pypy/lang/prolog/builtin/unify.py Sun Apr 22 21:12:52 2007 @@ -8,17 +8,21 @@ # comparison and unification of terms def impl_unify(engine, obj1, obj2): - obj1.unify(obj2, engine.frame) + obj1.unify(obj2, engine.heap) expose_builtin(impl_unify, "=", unwrap_spec=["raw", "raw"]) def impl_unify_with_occurs_check(engine, obj1, obj2): - obj1.unify(obj2, engine.frame, occurs_check=True) + obj1.unify(obj2, engine.heap, occurs_check=True) expose_builtin(impl_unify_with_occurs_check, "unify_with_occurs_check", unwrap_spec=["raw", "raw"]) def impl_does_not_unify(engine, obj1, obj2): try: - obj1.unify(obj2, engine.frame) + branch = engine.heap.branch() + try: + obj1.unify(obj2, engine.heap) + finally: + engine.heap.revert(branch) except error.UnificationFailed: return raise error.UnificationFailed() @@ -33,7 +37,7 @@ ("ge", "@>=", "!= -1")]: exec py.code.Source(""" def impl_standard_comparison_%s(engine, obj1, obj2): - c = term.cmp_standard_order(obj1, obj2, engine.frame) + c = term.cmp_standard_order(obj1, obj2, engine.heap) if not c %s: raise error.UnificationFailed()""" % (ext, python)).compile() expose_builtin(globals()["impl_standard_comparison_%s" % (ext, )], prolog, Modified: pypy/dist/pypy/lang/prolog/interpreter/arithmetic.py ============================================================================== --- pypy/dist/pypy/lang/prolog/interpreter/arithmetic.py (original) +++ pypy/dist/pypy/lang/prolog/interpreter/arithmetic.py Sun Apr 22 21:12:52 2007 @@ -32,7 +32,7 @@ wrap_builtin_operation._annspecialcase_ = 'specialize:memo' def eval_arithmetic(engine, query): - query = query.getvalue(engine.frame) + query = query.getvalue(engine.heap) if isinstance(query, term.Number): return query if isinstance(query, term.Float): Modified: pypy/dist/pypy/lang/prolog/interpreter/choice.py ============================================================================== --- pypy/dist/pypy/lang/prolog/interpreter/choice.py (original) +++ pypy/dist/pypy/lang/prolog/interpreter/choice.py Sun Apr 22 21:12:52 2007 @@ -3,15 +3,15 @@ from py.magic import greenlet from pypy.rlib.objectmodel import we_are_translated -from pypy.rpython.rstack import yield_current_frame_to_caller +from pypy.rpython.rstack import yield_current_heap_to_caller from pypy.translator.c.test.test_stackless import StacklessTest from pypy.lang.prolog.interpreter.error import UnificationFailed, CutException -def make_llframe(choice_point, func, args): - llframe = yield_current_frame_to_caller() +def make_llheap(choice_point, func, args): + llheap = yield_current_heap_to_caller() try: - choice_point.current = llframe + choice_point.current = llheap try: func(*args) except UnificationFailed: @@ -22,14 +22,14 @@ except: pass os.write(0, "bad\n") - return llframe # will nexer be executed, help the translator -make_llframe._annspecialcase_ = "specialize:arg(1)" + return llheap # will nexer be executed, help the translator +make_llheap._annspecialcase_ = "specialize:arg(1)" class ChoicePoint(object): def __init__(self, engine, continuation, stop_cut=False): self._init_current() self.engine = engine - self.oldstate = engine.frame.branch() + self.oldstate = engine.heap.branch() self.continuation = continuation self.stop_cut = stop_cut self.any_choice = True @@ -50,7 +50,7 @@ else: self.exception = e except UnificationFailed: - self.engine.frame.revert(self.oldstate) + self.engine.heap.revert(self.oldstate) if last: raise return @@ -65,8 +65,8 @@ def switch(self, func, *args): if we_are_translated(): - llframe = make_llframe(self, func, args) - llframe.switch() + llheap = make_llheap(self, func, args) + llheap.switch() else: g = greenlet(func) try: Modified: pypy/dist/pypy/lang/prolog/interpreter/engine.py ============================================================================== --- pypy/dist/pypy/lang/prolog/interpreter/engine.py (original) +++ pypy/dist/pypy/lang/prolog/interpreter/engine.py Sun Apr 22 21:12:52 2007 @@ -24,7 +24,7 @@ START_NUMBER_OF_VARS = 4096 -class Frame(object): +class Heap(object): def __init__(self): self.vars = [None] * START_NUMBER_OF_VARS self.trail = [] @@ -141,7 +141,7 @@ class Engine(object): def __init__(self): - self.frame = Frame() + self.heap = Heap() self.signature2function = {} self.parser = None self.operations = None @@ -175,7 +175,7 @@ if not isinstance(query, Callable): error.throw_type_error("callable", query) vars = query.get_max_var() + 1 - self.frame.clear(vars) + self.heap.clear(vars) try: return self.call(query, continuation) except CutException, e: @@ -215,27 +215,27 @@ if function is None: error.throw_existence_error( "procedure", query.get_prolog_signature()) - unify_hash = query.get_deeper_unify_hash(self.frame) + unify_hash = query.get_deeper_unify_hash(self.heap) rulechain = function.rulechain.find_applicable_rule(query, unify_hash) if rulechain is None: # none of the rules apply raise UnificationFailed() rule = rulechain.rule rulechain = rulechain.next - oldstate = self.frame.branch() + oldstate = self.heap.branch() while rulechain: rulechain = rulechain.find_applicable_rule(query, unify_hash) if rulechain is None: - self.frame.discard(oldstate) + self.heap.discard(oldstate) break if rule.contains_cut: continuation = LimitedScopeContinuation(continuation) try: result = self.try_rule(rule, query, continuation) - self.frame.discard(oldstate) + self.heap.discard(oldstate) return result except UnificationFailed: - self.frame.revert(oldstate) + self.heap.revert(oldstate) except CutException, e: if continuation.scope_active: return self.continue_after_cut(e.continuation, @@ -244,10 +244,10 @@ else: try: result = self.try_rule(rule, query, continuation) - self.frame.discard(oldstate) + self.heap.discard(oldstate) return result except UnificationFailed: - self.frame.revert(oldstate) + self.heap.revert(oldstate) rule = rulechain.rule rulechain = rulechain.next if rule.contains_cut: @@ -262,16 +262,11 @@ def try_rule(self, rule, query, continuation=DONOTHING): if DEBUG: - debug_print("trying rule", rule, query, self.frame.vars[:self.frame.needed_vars]) - try: - # standardizing apart - nextcall = rule.clone_and_unify_head(self.frame, query) - except UnificationFailed: - if DEBUG: - debug_print("didn't work", rule, query, self.frame.vars[:self.frame.needed_vars]) - raise + debug_print("trying rule", rule, query, self.heap.vars[:self.heap.needed_vars]) + # standardizing apart + nextcall = rule.clone_and_unify_head(self.heap, query) if DEBUG: - debug_print("worked", rule, query, self.frame.vars[:self.frame.needed_vars]) + debug_print("worked", rule, query, self.heap.vars[:self.heap.needed_vars]) if nextcall is not None: return self.call(nextcall, continuation) return continuation.call(self) Modified: pypy/dist/pypy/lang/prolog/interpreter/interactive.py ============================================================================== --- pypy/dist/pypy/lang/prolog/interpreter/interactive.py (original) +++ pypy/dist/pypy/lang/prolog/interpreter/interactive.py Sun Apr 22 21:12:52 2007 @@ -59,11 +59,11 @@ f = TermFormatter(engine, quoted=True, max_depth=10) vars = var_to_pos.items() vars.sort() - frame = engine.frame + heap = engine.heap for var, real_var in vars: if var.startswith("_"): continue - val = real_var.getvalue(frame) + val = real_var.getvalue(heap) write("%s = %s\n" % (var, f.format(val))) class PrologConsole(code.InteractiveConsole): Modified: pypy/dist/pypy/lang/prolog/interpreter/parsing.py ============================================================================== --- pypy/dist/pypy/lang/prolog/interpreter/parsing.py (original) +++ pypy/dist/pypy/lang/prolog/interpreter/parsing.py Sun Apr 22 21:12:52 2007 @@ -349,7 +349,7 @@ name = unescape(node.additional_info[1:end]) else: name = node.additional_info - return Atom.make_atom(name) + return Atom.newatom(name) def visit_VAR(self, node): from pypy.lang.prolog.interpreter.term import Var @@ -399,7 +399,7 @@ node = node.children[1] if len(node.children) == 1: l = self.build_list(node) - start = Atom.make_atom("[]") + start = Atom.newatom("[]") else: l = self.build_list(node.children[0]) start = self.visit(node.children[2]) Modified: pypy/dist/pypy/lang/prolog/interpreter/term.py ============================================================================== --- pypy/dist/pypy/lang/prolog/interpreter/term.py (original) +++ pypy/dist/pypy/lang/prolog/interpreter/term.py Sun Apr 22 21:12:52 2007 @@ -2,6 +2,7 @@ from pypy.rlib.objectmodel import we_are_translated, UnboxedValue from pypy.rlib.rarithmetic import intmask from pypy.lang.prolog.interpreter.error import UnificationFailed, UncatchableError +from pypy.rlib.objectmodel import hint, specialize DEBUG = True @@ -19,57 +20,54 @@ class PrologObject(object): __slots__ = () - def getvalue(self, frame): + def getvalue(self, heap): return self - def dereference(self, frame): - return self + def dereference(self, heap): + raise NotImplementedError("abstract base class") def get_max_var(self): return -1 - def clone(self, offset): - return self - - def clone_compress_vars(self, vars_new_indexes, offset): - return self + def copy(self, heap, memo): + raise NotImplementedError("abstract base class") - def make_template(self, vars_new_indexes): - return self + def copy_and_unify(self, other, heap, memo): + raise NotImplementedError("abstract base class") - def instantiate_template(self, template_frame): + def clone_compress_vars(self, vars_new_indexes, offset): return self - def get_unify_hash(self, frame=None): + def get_unify_hash(self, heap=None): # if two non-var objects return two different numbers # they must not be unifiable raise NotImplementedError("abstract base class") - def get_deeper_unify_hash(self, frame=None): - return [self.get_unify_hash(frame)] - - def basic_unify(self, other, frame): - pass + def get_deeper_unify_hash(self, heap=None): + return [self.get_unify_hash(heap)] - def unify(self, other, frame, occurs_check=False): - pass - unify._annspecialcase_ = "specialize:arg(3)" + @specialize.arg(3) + def unify(self, other, heap, occurs_check=False): + raise NotImplementedError("abstract base class") - def unify_with_template(self, other, frame, template_frame, to_instantiate): + @specialize.arg(3) + def _unify(self, other, heap, occurs_check=False): raise NotImplementedError("abstract base class") - def contains_var(self, var, frame): + def contains_var(self, var, heap): return False def __eq__(self, other): # for testing - return self.__dict__ == other.__dict__ + return (self.__class__ == other.__class__ and + self.__dict__ == other.__dict__) def __ne__(self, other): + # for testing return not (self == other) -class Var(PrologObject):#, UnboxedValue): +class Var(PrologObject): TAG = 0 STANDARD_ORDER = 0 @@ -78,75 +76,59 @@ def __init__(self, index): self.index = index - def unify(self, other, frame, occurs_check=False): - #debug_print("unify", self, other, frame.vars) - self, val = self.get_last_var_in_chain_and_val(frame) - if val is not None: - other.unify(val, frame, occurs_check) - elif isinstance(other, Var): - other, val = other.get_last_var_in_chain_and_val(frame) - if val is None: - if other.index != self.index: - frame.setvar(self.index, other) - else: - self.unify(val, frame, occurs_check) - else: - if occurs_check and other.contains_var(self, frame): - raise UnificationFailed() - frame.setvar(self.index, other) - unify._annspecialcase_ = "specialize:arg(3)" - - def unify_with_template(self, other, frame, template_frame, to_instantiate): - self, val = self.get_last_var_in_chain_and_val(frame) - if val is not None: - return val.unify_with_template(other, frame, template_frame, - to_instantiate) - if isinstance(other, Var): - other, otherval = other.get_last_var_in_chain_and_val(frame) - if otherval is None: - if other.index != self.index: - return frame.setvar(self.index, other) - else: - return self.unify_with_template(otherval, frame, - template_frame, to_instantiate) - else: - if isinstance(other, TemplateVar): - return other.unify_with_template(self, frame, template_frame, - to_instantiate) - if isinstance(other, Term): - to_instantiate.append((self.index, other)) - frame.setvar(self.index, other) - - def getvalue(self, frame): - var, res = self.get_last_var_in_chain_and_val(frame) - if res is not None: - return res.getvalue(frame) - return var - - def dereference(self, frame): - var, res = self.get_last_var_in_chain_and_val(frame) - if res is not None: - return res - return var - - def get_last_var_in_chain_and_val(self, frame): - next = frame.getvar(self.index) - if next is None or not isinstance(next, Var): - return self, next - # do path compression - last, val = next.get_last_var_in_chain_and_val(frame) - if val is None: - frame.setvar(self.index, last) + @specialize.arg(3) + def unify(self, other, heap, occurs_check=False): + return self.dereference(heap)._unify(other, heap, occurs_check) + + @specialize.arg(3) + def _unify(self, other, heap, occurs_check=False): + other = other.dereference(heap) + if isinstance(other, Var) and other is self: + pass + elif occurs_check and other.contains_var(self, heap): + raise UnificationFailed() + else: + heap.setvar(self.index, other) + + def dereference(self, heap): + next = heap.getvar(self.index) + if next is None: + return self else: - frame.setvar(self.index, val) - return last, val + result = next.dereference(heap) + # do path compression + heap.setvar(self.index, result) + return result + + def getvalue(self, heap): + res = self.dereference(heap) + if not isinstance(res, Var): + return res.getvalue(heap) + return res + + def copy(self, heap, memo): + hint(self, concrete=True) + try: + return memo[self.index] + except KeyError: + newvar = memo[self.index] = heap.newvar() + return newvar + + def copy_and_unify(self, other, heap, memo): + hint(self, concrete=True) + try: + seen_value = memo[self.index] + except KeyError: + memo[self.index] = other + return other + else: + seen_value.unify(other, heap) + return seen_value + def get_max_var(self): return self.index - def clone(self, offset): - return Var(self.index + offset) - def clone_compress_vars(self, vars_new_indexes, offset): if self.index in vars_new_indexes: return Var(vars_new_indexes[self.index]) @@ -154,98 +136,74 @@ vars_new_indexes[self.index] = index return Var(index) - def make_template(self, vars_new_indexes): - if self.index in vars_new_indexes: - return TemplateVar.make_templatevar(vars_new_indexes[self.index]) - index = len(vars_new_indexes) - vars_new_indexes[self.index] = index - return TemplateVar.make_templatevar(index) - - def get_unify_hash(self, frame=None): - if frame is None: + def get_unify_hash(self, heap=None): + if heap is None: return 0 - self = self.dereference(frame) + self = self.dereference(heap) if isinstance(self, Var): return 0 - return self.get_unify_hash(frame) + return self.get_unify_hash(heap) - def contains_var(self, var, frame): - self = self.dereference(frame) + def contains_var(self, var, heap): + self = self.dereference(heap) if self is var: return True if not isinstance(self, Var): - return self.contains_var(var, frame) + return self.contains_var(var, heap) return False def __repr__(self): return "Var(%s)" % (self.index, ) -class TemplateVar(PrologObject): - TAG = 0 - STANDARD_ORDER = 0 - __slots__ = 'index' - cache = [] - - def __init__(self, index): - self.index = index - - def unify(self, other, frame, occurs_check=False): - raise UncatchableError("TemplateVar in wrong place") - - def unify_with_template(self, other, frame, template_frame, to_instantiate): - val = template_frame[self.index] - if val is None: - template_frame[self.index] = other - else: - val.unify_with_template(other, frame, template_frame, to_instantiate) - - def getvalue(self, frame): - raise UncatchableError("TemplateVar in wrong place") - - def dereference(self, frame): - raise UncatchableError("TemplateVar in wrong place") - - def get_max_var(self): - return self.index + def __eq__(self, other): + # for testing + return (self.__class__ == other.__class__ and + self.index == other.index) - def clone(self, offset): - return TemplateVar.make_template(self.index + offset) +class NonVar(PrologObject): - def clone_compress_vars(self, vars_new_indexes, offset): - raise UncatchableError("TemplateVar in wrong place") + def dereference(self, heap): + return self - def make_template(self, vars_new_indexes): - raise UncatchableError("TemplateVar in wrong place") + @specialize.arg(3) + def unify(self, other, heap, occurs_check=False): + return self._unify(other, heap, occurs_check) - def instantiate_template(self, template_frame): - return template_frame[self.index] - def get_unify_hash(self, frame=None): - return 0 + @specialize.arg(3) + def basic_unify(self, other, heap, occurs_check=False): + raise NotImplementedError("abstract base class") - def contains_var(self, var, frame): - raise UncatchableError("TemplateVar in wrong place") + @specialize.arg(3) + def _unify(self, other, heap, occurs_check=False): + other = other.dereference(heap) + if isinstance(other, Var): + other._unify(self, heap, occurs_check) + else: + self.basic_unify(other, heap, occurs_check) - def __repr__(self): - return "TemplateVar(%s)" % (self.index, ) + def copy_and_unify(self, other, heap, memo): + other = other.dereference(heap) + if isinstance(other, Var): + copy = self.copy(heap, memo) + other._unify(copy, heap) + return copy + else: + return self.copy_and_basic_unify(other, heap, memo) - def make_templatevar(index): - l = len(TemplateVar.cache) - if index >= l: - TemplateVar.cache.extend( - [TemplateVar(i) for i in range(l, l + index + 1)]) - return TemplateVar.cache[index] - make_templatevar = staticmethod(make_templatevar) + def copy_and_basic_unify(self, other, heap, memo): + raise NotImplementedError("abstract base class") -class Callable(PrologObject): +class Callable(NonVar): name = "" signature = "" def get_prolog_signature(self): raise NotImplementedError("abstract base") + class Atom(Callable): TAG = tag() STANDARD_ORDER = 1 @@ -262,66 +220,60 @@ def __repr__(self): return "Atom(%r)" % (self.name,) - def basic_unify(self, other, frame): - if isinstance(other, Atom): - if self is other or other.name == self.name: - return + @specialize.arg(3) + def basic_unify(self, other, heap, occurs_check=False): + if isinstance(other, Atom) and (self is other or + other.name == self.name): + return raise UnificationFailed - def unify(self, other, frame, occurs_check=False): - #debug_print("unify", self, other, type(other)) - if isinstance(other, Var): - return other.unify(self, frame, occurs_check) - return self.basic_unify(other, frame) - unify._annspecialcase_ = "specialize:arg(3)" + def copy(self, heap, memo): + return self - def unify_with_template(self, other, frame, template_frame, to_instantiate): - if isinstance(other, Var): - return other.unify_with_template(self, frame, template_frame, to_instantiate) - elif isinstance(other, TemplateVar): - return other.unify_with_template(self, frame, template_frame, to_instantiate) - return self.basic_unify(other, frame) + def copy_and_basic_unify(self, other, heap, memo): + hint(self, concrete=True) + if isinstance(other, Atom) and (self is other or + other.name == self.name): + return self + else: + raise UnificationFailed - def get_unify_hash(self, frame=None): + def get_unify_hash(self, heap=None): return intmask(hash(self.name) << TAGBITS | self.TAG) def get_prolog_signature(self): return Term("/", [self, Number(0)]) - def make_atom(name): + def newatom(name): result = Atom.cache.get(name, None) if result is not None: return result Atom.cache[name] = result = Atom(name) return result - make_atom = staticmethod(make_atom) + newatom = staticmethod(newatom) + -class Number(PrologObject): +class Number(NonVar): TAG = tag() STANDARD_ORDER = 2 def __init__(self, num): self.num = num - def basic_unify(self, other, frame): - if isinstance(other, Number): - if other.num != self.num: - raise UnificationFailed + @specialize.arg(3) + def basic_unify(self, other, heap, occurs_check=False): + if isinstance(other, Number) and other.num == self.num: return raise UnificationFailed - def unify(self, other, frame, occurs_check=False): - #debug_print("unify", self, other, type(other)) - if isinstance(other, Var): - return other.unify(self, frame, occurs_check) - return self.basic_unify(other, frame) - unify._annspecialcase_ = "specialize:arg(3)" + def copy(self, heap, memo): + return self - def unify_with_template(self, other, frame, template_frame, to_instantiate): - if isinstance(other, Var): - return other.unify_with_template(self, frame, template_frame, to_instantiate) - elif isinstance(other, TemplateVar): - return other.unify_with_template(self, frame, template_frame, to_instantiate) - return self.basic_unify(other, frame) + def copy_and_basic_unify(self, other, heap, memo): + hint(self, concrete=True) + if isinstance(other, Number) and other.num == self.num: + return self + else: + raise UnificationFailed def __str__(self): return repr(self.num) @@ -329,44 +281,33 @@ def __repr__(self): return "Number(%r)" % (self.num, ) - def get_unify_hash(self, frame=None): + def get_unify_hash(self, heap=None): return intmask(self.num << TAGBITS | self.TAG) -class Float(PrologObject): +class Float(NonVar): TAG = tag() STANDARD_ORDER = 2 def __init__(self, num): self.num = num - def basic_unify(self, other, frame): - if isinstance(other, Float): - if other.num != self.num: - raise UnificationFailed - return - raise UnificationFailed - - def basic_unify(self, other, frame): - if isinstance(other, Float): - if other.num != self.num: - raise UnificationFailed + @specialize.arg(3) + def basic_unify(self, other, heap, occurs_check=False): + if isinstance(other, Float) and other.num == self.num: return raise UnificationFailed - def unify(self, other, frame, occurs_check=False): - if isinstance(other, Var): - return other.unify(self, frame, occurs_check) - return self.basic_unify(other, frame) - unify._annspecialcase_ = "specialize:arg(3)" + def copy(self, heap, memo): + return self - def unify_with_template(self, other, frame, template_frame, to_instantiate): - if isinstance(other, Var): - return other.unify_with_template(self, frame, template_frame, to_instantiate) - elif isinstance(other, TemplateVar): - return other.unify_with_template(self, frame, template_frame, to_instantiate) - return self.basic_unify(other, frame) + def copy_and_basic_unify(self, other, heap, memo): + hint(self, concrete=True) + if isinstance(other, Float) and other.num == self.num: + return self + else: + raise UnificationFailed - def get_unify_hash(self, frame=None): + def get_unify_hash(self, heap=None): #XXX no clue whether this is a good idea... m, e = math.frexp(self.num) m = intmask(int(m / 2 * 2 ** (32 - TAGBITS))) @@ -387,14 +328,8 @@ def _clone_compress_vars(obj, vars_new_indexes, offset): return obj.clone_compress_vars(vars_new_indexes, offset) -def _make_template(obj, vars_new_indexes): - return obj.make_template(vars_new_indexes) - -def _instantiate_template(obj, template_frame): - return obj.instantiate_template(template_frame) - -def _getvalue(obj, frame): - return obj.getvalue(frame) +def _getvalue(obj, heap): + return obj.getvalue(heap) class Term(Callable): TAG = tag() @@ -413,31 +348,44 @@ def __str__(self): return "%s(%s)" % (self.name, ", ".join([str(a) for a in self.args])) - def unify(self, other, frame, occurs_check=False): - if not isinstance(other, Term): - if isinstance(other, Var): - return other.unify(self, frame, occurs_check) - raise UnificationFailed - if (hash(self.name) != hash(other.name) or - self.name != other.name or len(self.args) != len(other.args)): + @specialize.arg(3) + def basic_unify(self, other, heap, occurs_check=False): + if (isinstance(other, Term) and + self.name == other.name and + len(self.args) == len(other.args)): + for i in range(len(self.args)): + self.args[i].unify(other.args[i], heap, occurs_check) + else: raise UnificationFailed - for i in range(len(self.args)): - self.args[i].unify(other.args[i], frame, occurs_check) - unify._annspecialcase_ = "specialize:arg(3)" - def unify_with_template(self, other, frame, template_frame, to_instantiate): - if not isinstance(other, Term): - if isinstance(other, Var): - return other.unify_with_template(self, frame, template_frame, to_instantiate) - if isinstance(other, TemplateVar): - return other.unify_with_template(self, frame, template_frame, to_instantiate) - raise UnificationFailed - if (hash(self.name) != hash(other.name) or - self.name != other.name or len(self.args) != len(other.args)): + def copy(self, heap, memo): + hint(self, concrete=True) + self = hint(self, deepfreeze=True) + newargs = [] + i = 0 + while i < len(self.args): + hint(i, concrete=True) + arg = self.args[i].copy(heap, memo) + newargs.append(arg) + i += 1 + return Term(self.name, newargs) + + def copy_and_basic_unify(self, other, heap, memo): + hint(self, concrete=True) + self = hint(self, deepfreeze=True) + if (isinstance(other, Term) and + self.name == other.name and + len(self.args) == len(other.args)): + newargs = [None] * len(self.args) + i = 0 + while i < len(self.args): + hint(i, concrete=True) + arg = self.args[i].copy_and_unify(other.args[i], heap, memo) + newargs[i] = arg + i += 1 + return Term(self.name, newargs) + else: raise UnificationFailed - for i in range(len(self.args)): - self.args[i].unify_with_template(other.args[i], frame, - template_frame, to_instantiate) def get_max_var(self): result = -1 @@ -445,20 +393,11 @@ result = max(result, subterm.get_max_var()) return result - def clone(self, offset): - return self._copy_term(_clone, offset) - def clone_compress_vars(self, vars_new_indexes, offset): return self._copy_term(_clone_compress_vars, vars_new_indexes, offset) - def make_template(self, vars_new_indexes): - return self._copy_term(_make_template, vars_new_indexes) - - def instantiate_template(self, template_frame): - return self._copy_term(_instantiate_template, template_frame) - - def getvalue(self, frame): - return self._copy_term(_getvalue, frame) + def getvalue(self, heap): + return self._copy_term(_getvalue, heap) def _copy_term(self, copy_individual, *extraargs): args = [None] * len(self.args) @@ -473,23 +412,22 @@ return Term(self.name, args, self.signature) else: return self - _copy_term._annspecialcase_ = "specialize:arg(1)" - def get_unify_hash(self, frame=None): + def get_unify_hash(self, heap=None): return intmask(hash(self.signature) << TAGBITS | self.TAG) - def get_deeper_unify_hash(self, frame=None): + def get_deeper_unify_hash(self, heap=None): result = [0] * len(self.args) for i in range(len(self.args)): - result[i] = self.args[i].get_unify_hash(frame) + result[i] = self.args[i].get_unify_hash(heap) return result def get_prolog_signature(self): - return Term("/", [Atom.make_atom(self.name), Number(len(self.args))]) + return Term("/", [Atom.newatom(self.name), Number(len(self.args))]) - def contains_var(self, var, frame): + def contains_var(self, var, heap): for arg in self.args: - if arg.contains_var(var, frame): + if arg.contains_var(var, heap): return True return False @@ -498,12 +436,12 @@ def __init__(self, head, body): from pypy.lang.prolog.interpreter import helper d = {} - head = head.make_template(d) + head = head.clone_compress_vars(d, 0) assert isinstance(head, Callable) self.head = head if body is not None: body = helper.ensure_callable(body) - self.body = body.make_template(d) + self.body = body.clone_compress_vars(d, 0) else: self.body = None self.numvars = len(d) @@ -526,41 +464,19 @@ stack.extend(current.args) self.contains_cut = False - def clone(self, offset): - if self.body is None: - body = None - else: - body = self.body.clone(offset) - return Rule(self.head.clone(offset), body) - - def clone_and_unify_head(self, frame, head): - template_frame = [None] * self.numvars + def clone_and_unify_head(self, heap, head): + memo = {} if isinstance(head, Term): - to_instantiate = [] h2 = self.head assert isinstance(h2, Term) for i in range(len(h2.args)): arg1 = h2.args[i] arg2 = head.args[i] - if (isinstance(arg1, Term) or - isinstance(arg1, TemplateVar)): - h2.args[i].unify_with_template( - head.args[i], frame, template_frame, to_instantiate) - else: - h2.args[i].unify(head.args[i], frame) - extend_and_normalize_template_frame(template_frame, frame) - for index, obj in to_instantiate: - frame.vars[index] = obj.instantiate_template(template_frame) - else: - next_free = frame.maxvar() - for i in range(self.numvars): - template_frame[i] = Var(next_free) - next_free += 1 - frame.extend(next_free - frame.maxvar()) + arg1.copy_and_unify(arg2, heap, memo) body = self.body if body is None: return None - return body.instantiate_template(template_frame) + return body.copy(heap, memo) def __repr__(self): if self.body is None: @@ -568,26 +484,15 @@ return "%s :- %s." % (self.head, self.body) -def extend_and_normalize_template_frame(template_frame, frame): - next_free = frame.maxvar() - for i in range(len(template_frame)): - val = template_frame[i] - if val is None: - template_frame[i] = Var(next_free) - next_free += 1 - elif isinstance(val, TemplateVar): - template_frame[i] = template_frame[val.index] - frame.extend(next_free - frame.maxvar()) - + at specialize.argtype(0) def rcmp(a, b): # RPython does not support cmp... if a == b: return 0 if a < b: return -1 return 1 -rcmp._annspecialcase_ = "specialize:argtype(0)" -def cmp_standard_order(obj1, obj2, frame): +def cmp_standard_order(obj1, obj2, heap): c = rcmp(obj1.STANDARD_ORDER, obj2.STANDARD_ORDER) if c != 0: return c @@ -606,9 +511,9 @@ if c != 0: return c for i in range(len(obj1.args)): - a1 = obj1.args[i].dereference(frame) - a2 = obj2.args[i].dereference(frame) - c = cmp_standard_order(a1, a2, frame) + a1 = obj1.args[i].dereference(heap) + a2 = obj2.args[i].dereference(heap) + c = cmp_standard_order(a1, a2, heap) if c != 0: return c return 0 Modified: pypy/dist/pypy/lang/prolog/interpreter/test/dont_test_translate.py ============================================================================== --- pypy/dist/pypy/lang/prolog/interpreter/test/dont_test_translate.py (original) +++ pypy/dist/pypy/lang/prolog/interpreter/test/dont_test_translate.py Sun Apr 22 21:12:52 2007 @@ -39,7 +39,7 @@ def run(): e.run(t1) e.run(t2) - v0 = e.frame.getvar(0) + v0 = e.heap.getvar(0) if isinstance(v0, Atom): return v0.name return "no!" Modified: pypy/dist/pypy/lang/prolog/interpreter/test/test_arithmetic.py ============================================================================== --- pypy/dist/pypy/lang/prolog/interpreter/test/test_arithmetic.py (original) +++ pypy/dist/pypy/lang/prolog/interpreter/test/test_arithmetic.py Sun Apr 22 21:12:52 2007 @@ -2,7 +2,7 @@ from pypy.lang.prolog.interpreter.parsing import parse_file, TermBuilder from pypy.lang.prolog.interpreter.parsing import parse_query_term, get_engine from pypy.lang.prolog.interpreter.error import UnificationFailed, CutException -from pypy.lang.prolog.interpreter.engine import Frame, Engine +from pypy.lang.prolog.interpreter.engine import Heap, Engine from pypy.lang.prolog.interpreter import error from pypy.lang.prolog.interpreter.test.tool import collect_all, assert_false, assert_true Modified: pypy/dist/pypy/lang/prolog/interpreter/test/test_builtin.py ============================================================================== --- pypy/dist/pypy/lang/prolog/interpreter/test/test_builtin.py (original) +++ pypy/dist/pypy/lang/prolog/interpreter/test/test_builtin.py Sun Apr 22 21:12:52 2007 @@ -2,7 +2,7 @@ from pypy.lang.prolog.interpreter.parsing import parse_file, TermBuilder from pypy.lang.prolog.interpreter.parsing import parse_query_term, get_engine from pypy.lang.prolog.interpreter.error import UnificationFailed -from pypy.lang.prolog.interpreter.engine import Frame, Engine +from pypy.lang.prolog.interpreter.engine import Heap, Engine from pypy.lang.prolog.interpreter import error from pypy.lang.prolog.interpreter.test.tool import collect_all, assert_false, assert_true from pypy.lang.prolog.interpreter.test.tool import prolog_raises @@ -13,8 +13,8 @@ f(X) :- g(X), fail. f(a). """) - frames = collect_all(e, "f(X).") - assert len(frames) == 1 + heaps = collect_all(e, "f(X).") + assert len(heaps) == 1 def test_not(): e = get_engine(""" @@ -36,8 +36,8 @@ assert_false("\\+(g(a, a)).", e) assert_false("not(!).", e) - frames = collect_all(e, "sibling(a, X).") - assert len(frames) == 2 + heaps = collect_all(e, "sibling(a, X).") + assert len(heaps) == 2 def test_and(): assert_false("fail, X.") @@ -118,8 +118,8 @@ g(c) :- assertz(g(d)). g(b). """) - frames = collect_all(e, "g(X).") - assert len(frames) == 3 + heaps = collect_all(e, "g(X).") + assert len(heaps) == 3 e = get_engine(""" p :- assertz(p), fail. p :- fail. @@ -155,6 +155,7 @@ assert_false("X \\= Y.") assert_false("X \\= f(X).") assert_true("x \\= y.") + assert_true("f(X, b) \\= f(a, c), X = c.") assert_true("unify_with_occurs_check(X, Y).") assert_true("unify_with_occurs_check(X, X).") assert_false("unify_with_occurs_check(X, f(X)).") @@ -177,8 +178,8 @@ withcut(X) :- call(!), fail. withcut(a). """) - frames = collect_all(e, "g(X).") - assert len(frames) == 2 + heaps = collect_all(e, "g(X).") + assert len(heaps) == 2 assert_true("withcut(a).", e) assert_true("call((!, true)).") @@ -212,8 +213,8 @@ f(2, b). f(3, c). """) - frames = collect_all(e, "arg(X, g(a, b, c), A), f(X, A).") - assert len(frames) == 3 + heaps = collect_all(e, "arg(X, g(a, b, c), A), f(X, A).") + assert len(heaps) == 3 assert_true("arg(X, h(a, b, c), b), X = 2.") assert_true("arg(X, h(a, b, g(X, b)), g(3, B)), X = 3, B = b.") assert_true("copy_term(X, Y), X = 1, Y = 2.") @@ -278,9 +279,9 @@ assert_true("between(-5, 15, 0).") assert_false("between(12, 15, 6).") assert_false("between(12, 15, 16).") - frames = collect_all(Engine(), "between(1, 4, X).") - assert len(frames) == 4 - assert frames[0].vars[0].num == 1 + heaps = collect_all(Engine(), "between(1, 4, X).") + assert len(heaps) == 4 + assert heaps[0].vars[0].num == 1 def test_is(): assert_true("5 is 1 + 1 + 1 + 1 + 1.") @@ -333,10 +334,10 @@ assert_true("atom_concat(ab, X, abcdef), X = cdef.") assert_true("atom_concat(X, cdef, abcdef), X = ab.") assert_true("atom_concat(1, Y, '1def'), Y = def.") - frames = collect_all( + heaps = collect_all( Engine(), "atom_concat(X, Y, abcd), atom(X), atom(Y).") - assert len(frames) == 5 + assert len(heaps) == 5 def test_sub_atom(): assert_true("sub_atom(abc, B, L, A, bc), B=1, L=2, A=0.") Modified: pypy/dist/pypy/lang/prolog/interpreter/test/test_engine.py ============================================================================== --- pypy/dist/pypy/lang/prolog/interpreter/test/test_engine.py (original) +++ pypy/dist/pypy/lang/prolog/interpreter/test/test_engine.py Sun Apr 22 21:12:52 2007 @@ -5,6 +5,13 @@ from pypy.lang.prolog.interpreter.test.tool import collect_all, assert_true, assert_false from pypy.lang.prolog.interpreter.test.tool import prolog_raises +def test_trivial(): + e = get_engine(""" + f(a). + """) + e.run(parse_query_term("f(X).")) + assert e.heap.getvar(0).name == "a" + def test_and(): e = get_engine(""" g(a, a). @@ -14,8 +21,8 @@ """) e.run(parse_query_term("f(a, c).")) e.run(parse_query_term("f(X, c).")) - print e.frame.vars - assert e.frame.getvar(0).name == "a" + print e.heap.vars[:10] + assert e.heap.getvar(0).name == "a" def test_and_long(): e = get_engine(""" @@ -24,8 +31,8 @@ h(d). h(e). h(f). f(X, Y, Z) :- f(X), g(Y), h(Z). """) - frames = collect_all(e, "f(X, Y, Z).") - assert len(frames) == 27 + heaps = collect_all(e, "f(X, Y, Z).") + assert len(heaps) == 27 def test_numeral(): e = get_engine(""" @@ -46,7 +53,7 @@ e.run(parse_query_term("num(0).")) e.run(parse_query_term("num(succ(0)).")) e.run(parse_query_term("num(X).")) - assert e.frame.getvar(0).num == 0 + assert e.heap.getvar(0).num == 0 e.run(parse_query_term("add(0, 0, 0).")) py.test.raises(UnificationFailed, e.run, parse_query_term(""" add(0, 0, succ(0)).""")) @@ -82,7 +89,7 @@ f(X, Y, Z) :- (g(X, Z); g(X, Z); g(Z, Y)), a(Z). """) e.run(parse_query_term("f(a, b, Z).")) - assert e.frame.getvar(0).name == "a" + assert e.heap.getvar(0).name == "a" f = collect_all(e, "X = 1; X = 2.") assert len(f) == 2 @@ -118,11 +125,11 @@ g(b). g(c). """) - frames = collect_all(e, "g(X).") - assert len(frames) == 3 - assert frames[0].getvar(0).name == "a" - assert frames[1].getvar(0).name == "b" - assert frames[2].getvar(0).name == "c" + heaps = collect_all(e, "g(X).") + assert len(heaps) == 3 + assert heaps[0].getvar(0).name == "a" + assert heaps[1].getvar(0).name == "b" + assert heaps[2].getvar(0).name == "c" def test_cut(): e = get_engine(""" @@ -134,8 +141,8 @@ f(x). f(y). """) - frames = collect_all(e, "f(X).") - assert len(frames) == 0 + heaps = collect_all(e, "f(X).") + assert len(heaps) == 0 assert_true("!.") def test_cut2(): @@ -146,8 +153,8 @@ h(a, y). f(X, Y) :- g(X), !, !, !, !, !, h(X, Y). """) - frames = collect_all(e, "f(X, Y).") - assert len(frames) == 2 + heaps = collect_all(e, "f(X, Y).") + assert len(heaps) == 2 def test_cut3(): e = get_engine(""" @@ -171,8 +178,8 @@ g(X) :- f(X), !. g(a). """) - frames = collect_all(e, "g(X).") - assert len(frames) == 1 + heaps = collect_all(e, "g(X).") + assert len(heaps) == 1 def test_not_with_cut(): e = get_engine(""" @@ -227,8 +234,8 @@ sibling(X, Y) :- mother(Z, X), mother(Z, Y). """) - frames = collect_all(e, "sibling(m, X).") - assert len(frames) == 3 + heaps = collect_all(e, "sibling(m, X).") + assert len(heaps) == 3 def test_runstring(): e = get_engine("foo(a, c).") Modified: pypy/dist/pypy/lang/prolog/interpreter/test/test_parsing.py ============================================================================== --- pypy/dist/pypy/lang/prolog/interpreter/test/test_parsing.py (original) +++ pypy/dist/pypy/lang/prolog/interpreter/test/test_parsing.py Sun Apr 22 21:12:52 2007 @@ -37,10 +37,10 @@ term = parse_query_term( """add_numeral(succ(succ(null)), succ(succ(null)), X).""") e.run(term) - var = Var(0).getvalue(e.frame) - print var, e.frame + var = Var(0).getvalue(e.heap) + print var, e.heap # does not raise - var.unify(four, e.frame) + var.unify(four, e.heap) term = parse_query_term( """greater_than(succ(succ(succ(null))), succ(succ(null))).""") e.run(term) Modified: pypy/dist/pypy/lang/prolog/interpreter/test/test_unification.py ============================================================================== --- pypy/dist/pypy/lang/prolog/interpreter/test/test_unification.py (original) +++ pypy/dist/pypy/lang/prolog/interpreter/test/test_unification.py Sun Apr 22 21:12:52 2007 @@ -1,64 +1,65 @@ import py from pypy.lang.prolog.interpreter.error import UnificationFailed from pypy.lang.prolog.interpreter.term import Atom, Var, Number, Term, Rule -from pypy.lang.prolog.interpreter.engine import Frame, Engine +from pypy.lang.prolog.interpreter.engine import Heap, Engine def test_atom(): - a = Atom("hallo") - b = Atom("hallo") + a = Atom.newatom("hallo") + b = Atom.newatom("hallo") # does not raise a.unify(b, None) - py.test.raises(UnificationFailed, "a.unify(Atom('xxx'), None)") + py.test.raises(UnificationFailed, "a.unify(Atom.newatom('xxx'), None)") def test_var(): b = Var(0) - frame = Frame() - frame.clear(1) - b.unify(Atom("hallo"), frame) - assert b.getvalue(frame).name == "hallo" + heap = Heap() + heap.clear(1) + b.unify(Atom.newatom("hallo"), heap) + assert b.getvalue(heap).name == "hallo" a = Var(0) b = Var(1) - frame.clear(2) - a.unify(b, frame) - a.unify(Atom("hallo"), frame) - assert a.getvalue(frame).name == "hallo" - assert b.getvalue(frame).name == "hallo" + heap.clear(2) + a.unify(b, heap) + a.unify(Atom.newatom("hallo"), heap) + assert a.getvalue(heap).name == "hallo" + assert b.getvalue(heap).name == "hallo" def test_unify_var(): b = Var(0) - frame = Frame() - frame.clear(1) - b.unify(b, frame) - b.unify(Atom("hallo"), frame) - py.test.raises(UnificationFailed, b.unify, Atom("bye"), frame) + heap = Heap() + heap.clear(1) + b.unify(b, heap) + b.unify(Atom.newatom("hallo"), heap) + py.test.raises(UnificationFailed, b.unify, Atom.newatom("bye"), heap) def test_recursive(): b = Var(0) - frame = Frame() - frame.clear(1) - b.unify(Term("hallo", [b]), frame) + heap = Heap() + heap.clear(1) + b.unify(Term("hallo", [b]), heap) def test_term(): X = Var(0) Y = Var(1) - t1 = Term("f", [Atom("hallo"), X]) - t2 = Term("f", [Y, Atom("HALLO")]) - frame = Frame() - frame.clear(2) + t1 = Term("f", [Atom.newatom("hallo"), X]) + t2 = Term("f", [Y, Atom.newatom("HALLO")]) + heap = Heap() + heap.clear(2) print t1, t2 - t1.unify(t2, frame) - assert X.getvalue(frame).name == "HALLO" - assert Y.getvalue(frame).name == "hallo" + t1.unify(t2, heap) + assert X.getvalue(heap).name == "HALLO" + assert Y.getvalue(heap).name == "hallo" def test_run(): e = Engine() - e.add_rule(Term("f", [Atom("a"), Atom("b")])) + e.add_rule(Term("f", [Atom.newatom("a"), Atom.newatom("b")])) e.add_rule(Term("f", [Var(0), Var(0)])) e.add_rule(Term(":-", [Term("f", [Var(0), Var(1)]), Term("f", [Var(1), Var(0)])])) - assert e.run(Term("f", [Atom("b"), Var(0)])) is None - assert e.frame.getvar(0).name == "b" - assert e.run(Term("f", [Atom("b"), Atom("a")])) is None + X = e.heap.newvar() + assert e.run(Term("f", [Atom.newatom("b"), X])) is None + assert X.dereference(e.heap).name == "b" + assert e.run(Term("f", [Atom.newatom("b"), Atom.newatom("a")])) is None Modified: pypy/dist/pypy/lang/prolog/interpreter/test/tool.py ============================================================================== --- pypy/dist/pypy/lang/prolog/interpreter/test/tool.py (original) +++ pypy/dist/pypy/lang/prolog/interpreter/test/tool.py Sun Apr 22 21:12:52 2007 @@ -1,15 +1,15 @@ import py from pypy.lang.prolog.interpreter.error import UnificationFailed, FunctionNotFound from pypy.lang.prolog.interpreter.parsing import parse_query_term, get_engine -from pypy.lang.prolog.interpreter.engine import Continuation, Frame, Engine +from pypy.lang.prolog.interpreter.engine import Continuation, Heap, Engine def assert_true(query, e=None): if e is None: e = Engine() term = e.parse(query)[0][0] e.run(term) - f = Frame() - f.vars = e.frame.vars[:] + f = Heap() + f.vars = e.heap.vars[:] return f def assert_false(query, e=None): @@ -24,12 +24,12 @@ class CollectAllContinuation(Continuation): def __init__(self): - self.frames = [] + self.heaps = [] def call(self, engine): - f = Frame() - f.vars = engine.frame.vars[:] - self.frames.append(f) + f = Heap() + f.vars = engine.heap.vars[:] + self.heaps.append(f) # import pdb; pdb.set_trace() print "restarting computation" raise UnificationFailed @@ -39,5 +39,5 @@ term = engine.parse(s)[0][0] py.test.raises(UnificationFailed, engine.run, term, collector) - return collector.frames + return collector.heaps 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 Apr 22 21:12:52 2007 @@ -43,7 +43,7 @@ for var, real_var in var_to_pos.iteritems(): if var.startswith("_"): continue - val = f.format(real_var.getvalue(engine.frame)) + val = f.format(real_var.getvalue(engine.heap)) write("%s = %s\n" % (var, val)) def getch(): From cfbolz at codespeak.net Sun Apr 22 22:42:32 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sun, 22 Apr 2007 22:42:32 +0200 (CEST) Subject: [pypy-svn] r42247 - in pypy/dist/pypy/lang/prolog: builtin interpreter Message-ID: <20070422204232.0BD0A8095@code0.codespeak.net> Author: cfbolz Date: Sun Apr 22 22:42:32 2007 New Revision: 42247 Modified: pypy/dist/pypy/lang/prolog/builtin/register.py pypy/dist/pypy/lang/prolog/interpreter/engine.py Log: add a level of indirection to the calls of builtins Modified: pypy/dist/pypy/lang/prolog/builtin/register.py ============================================================================== --- pypy/dist/pypy/lang/prolog/builtin/register.py (original) +++ pypy/dist/pypy/lang/prolog/builtin/register.py Sun Apr 22 22:42:32 2007 @@ -6,6 +6,14 @@ from pypy.rlib.objectmodel import we_are_translated +class Builtin(object): + def __init__(self, function): + self.function = function + + def call(self, engine, query, continuation): + return self.function(engine, query, continuation) + + def expose_builtin(func, name, unwrap_spec=None, handles_continuation=False, translatable=True): if isinstance(name, list): @@ -68,5 +76,5 @@ exec py.code.Source("\n".join(code)).compile() in miniglobals for name in expose_as: signature = "%s/%s" % (name, len(unwrap_spec)) - builtins[signature] = miniglobals[funcname] + builtins[signature] = Builtin(miniglobals[funcname]) Modified: pypy/dist/pypy/lang/prolog/interpreter/engine.py ============================================================================== --- pypy/dist/pypy/lang/prolog/interpreter/engine.py (original) +++ pypy/dist/pypy/lang/prolog/interpreter/engine.py Sun Apr 22 22:42:32 2007 @@ -204,7 +204,7 @@ # check for builtins builtin = builtins.get(signature, None) if builtin is not None: - return builtin(self, query, continuation) + return builtin.call(self, query, continuation) # do a real call return self.user_call(query, continuation) From cfbolz at codespeak.net Sun Apr 22 22:57:41 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sun, 22 Apr 2007 22:57:41 +0200 (CEST) Subject: [pypy-svn] r42248 - in pypy/dist/pypy/lang/prolog: builtin interpreter Message-ID: <20070422205741.680CF809F@code0.codespeak.net> Author: cfbolz Date: Sun Apr 22 22:57:41 2007 New Revision: 42248 Modified: pypy/dist/pypy/lang/prolog/builtin/allsolution.py pypy/dist/pypy/lang/prolog/builtin/parseraccess.py pypy/dist/pypy/lang/prolog/interpreter/error.py pypy/dist/pypy/lang/prolog/interpreter/helper.py Log: use Atom.newatom to construct Atoms that can be expected to be used more than once to get caching. Modified: pypy/dist/pypy/lang/prolog/builtin/allsolution.py ============================================================================== --- pypy/dist/pypy/lang/prolog/builtin/allsolution.py (original) +++ pypy/dist/pypy/lang/prolog/builtin/allsolution.py Sun Apr 22 22:57:41 2007 @@ -22,7 +22,7 @@ engine.call(goal, collector) except error.UnificationFailed: engine.heap.revert(oldstate) - result = term.Atom("[]") + result = term.Atom.newatom("[]") for i in range(len(collector.found) - 1, -1, -1): copy = collector.found[i] d = {} Modified: pypy/dist/pypy/lang/prolog/builtin/parseraccess.py ============================================================================== --- pypy/dist/pypy/lang/prolog/builtin/parseraccess.py (original) +++ pypy/dist/pypy/lang/prolog/builtin/parseraccess.py Sun Apr 22 22:57:41 2007 @@ -12,7 +12,7 @@ oldstate = engine.heap.branch() try: precedence.unify(term.Number(prec), engine.heap) - typ.unify(term.Atom(form), engine.heap) + typ.unify(term.Atom.newatom(form), engine.heap) name.unify(term.Atom(op), engine.heap) return continuation.call(engine) except error.UnificationFailed: Modified: pypy/dist/pypy/lang/prolog/interpreter/error.py ============================================================================== --- pypy/dist/pypy/lang/prolog/interpreter/error.py (original) +++ pypy/dist/pypy/lang/prolog/interpreter/error.py Sun Apr 22 22:57:41 2007 @@ -29,7 +29,7 @@ def throw_instantiation_error(): from pypy.lang.prolog.interpreter import term - raise CatchableError(term.Atom("instantiation_error")) + raise CatchableError(term.Atom.newatom("instantiation_error")) def throw_type_error(valid_type, obj): from pypy.lang.prolog.interpreter import term @@ -39,7 +39,7 @@ # number, predicate_indicator, variable from pypy.lang.prolog.interpreter import term raise CatchableError( - term.Term("type_error", [term.Atom(valid_type), obj])) + term.Term("type_error", [term.Atom.newatom(valid_type), obj])) def throw_domain_error(valid_domain, obj): from pypy.lang.prolog.interpreter import term @@ -50,14 +50,14 @@ # stream, stream_option, stream_or_alias, stream_position, # stream_property, write_option raise CatchableError( - term.Term("domain_error", [term.Atom(valid_domain), obj])) + term.Term("domain_error", [term.Atom.newatom(valid_domain), obj])) def throw_existence_error(object_type, obj): from pypy.lang.prolog.interpreter import term # valid types are: # procedure, source_sink, stream raise CatchableError( - term.Term("existence_error", [term.Atom(object_type), obj])) + term.Term("existence_error", [term.Atom.newatom(object_type), obj])) def throw_permission_error(operation, permission_type, obj): from pypy.lang.prolog.interpreter import term @@ -68,6 +68,6 @@ # binary_stream, flag, operator, past_end_of_stream, private_procedure, # static_procedure, source_sink, stream, text_stream. raise CatchableError( - term.Term("permission_error", [term.Atom(operation), - term.Atom(permission_type), + term.Term("permission_error", [term.Atom.newatom(operation), + term.Atom.newatom(permission_type), obj])) Modified: pypy/dist/pypy/lang/prolog/interpreter/helper.py ============================================================================== --- pypy/dist/pypy/lang/prolog/interpreter/helper.py (original) +++ pypy/dist/pypy/lang/prolog/interpreter/helper.py Sun Apr 22 22:57:41 2007 @@ -1,10 +1,10 @@ -""" Helper functions for dealing with prolog lists""" +""" Helper functions for dealing with prolog terms""" from pypy.lang.prolog.interpreter import term from pypy.lang.prolog.interpreter import error def wrap_list(python_list): - curr = term.Atom("[]") + curr = term.Atom.newatom("[]") for i in range(len(python_list) - 1, -1, -1): curr = term.Term(".", [python_list[i], curr]) return curr From cfbolz at codespeak.net Sun Apr 22 23:17:14 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sun, 22 Apr 2007 23:17:14 +0200 (CEST) Subject: [pypy-svn] r42249 - in pypy/dist/pypy/lang/prolog/interpreter: . test Message-ID: <20070422211714.22D1F8095@code0.codespeak.net> Author: cfbolz Date: Sun Apr 22 23:17:13 2007 New Revision: 42249 Modified: pypy/dist/pypy/lang/prolog/interpreter/term.py pypy/dist/pypy/lang/prolog/interpreter/test/test_unification.py Log: a BlackBox Prolog object that unifies by identity and is meant to be subclassed for specific purposes. Modified: pypy/dist/pypy/lang/prolog/interpreter/term.py ============================================================================== --- pypy/dist/pypy/lang/prolog/interpreter/term.py (original) +++ pypy/dist/pypy/lang/prolog/interpreter/term.py Sun Apr 22 23:17:13 2007 @@ -319,6 +319,29 @@ def __repr__(self): return "Float(%r)" % (self.num, ) +class BlackBox(NonVar): + # meant to be subclassed + TAG = tag() + STANDARD_ORDER = 4 + @specialize.arg(3) + def basic_unify(self, other, heap, occurs_check=False): + if self is other: + return + raise UnificationFailed + + def copy(self, heap, memo): + return self + + def copy_and_basic_unify(self, other, heap, memo): + hint(self, concrete=True) + if self is other: + return self + else: + raise UnificationFailed + + def get_unify_hash(self, heap=None): + return intmask(id(self) << TAGBITS | self.TAG) + # helper functions for various Term methods Modified: pypy/dist/pypy/lang/prolog/interpreter/test/test_unification.py ============================================================================== --- pypy/dist/pypy/lang/prolog/interpreter/test/test_unification.py (original) +++ pypy/dist/pypy/lang/prolog/interpreter/test/test_unification.py Sun Apr 22 23:17:13 2007 @@ -1,6 +1,6 @@ import py from pypy.lang.prolog.interpreter.error import UnificationFailed -from pypy.lang.prolog.interpreter.term import Atom, Var, Number, Term, Rule +from pypy.lang.prolog.interpreter.term import Atom, Var, Number, Term, BlackBox from pypy.lang.prolog.interpreter.engine import Heap, Engine def test_atom(): @@ -51,6 +51,13 @@ assert X.getvalue(heap).name == "HALLO" assert Y.getvalue(heap).name == "hallo" +def test_blackbox(): + bl1 = BlackBox() + bl2 = BlackBox() + heap = Heap() + bl1.unify(bl1, heap) + py.test.raises(UnificationFailed, bl1.unify, bl2, heap) + def test_run(): e = Engine() e.add_rule(Term("f", [Atom.newatom("a"), Atom.newatom("b")])) From afa at codespeak.net Tue Apr 24 18:04:59 2007 From: afa at codespeak.net (afa at codespeak.net) Date: Tue, 24 Apr 2007 18:04:59 +0200 (CEST) Subject: [pypy-svn] r42288 - in pypy/dist/pypy: rlib translator/c/src Message-ID: <20070424160459.5A5FC807F@code0.codespeak.net> Author: afa Date: Tue Apr 24 18:04:59 2007 New Revision: 42288 Modified: pypy/dist/pypy/rlib/_rsocket_ctypes.py pypy/dist/pypy/translator/c/src/thread_nt.h Log: Finally managed to get rsocket translate on windows! Ouf. The resulting pypy-c.exe works on basic samples (SimpleHTTPServer) Lots of hacks because: - winsock functions have the __stdcall convention, so correct .h must be included - 'in_addr' is passed by *value* to inet_ntoa, so the original name must be used (conversion between unrelated pointers is a warning, but conversion between structs is an error) - 'in6_addr' fields names are actually macros, so we cannot define its real contents. pypy must declare it under another name. All these problems belong to the task: "- clean up the tangle of including headers in the C backend" in pypy/doc/cleanup-todo.txt In the end, some warnings during compilation, but no more than with Unix IMO. Modified: pypy/dist/pypy/rlib/_rsocket_ctypes.py ============================================================================== --- pypy/dist/pypy/rlib/_rsocket_ctypes.py (original) +++ pypy/dist/pypy/rlib/_rsocket_ctypes.py Tue Apr 24 18:04:59 2007 @@ -273,6 +273,16 @@ pass cConfig.__dict__.update(ctypes_platform.configure(CConfig)) +# HACK HACK HACK +if _MS_WINDOWS: + from ctypes import Structure + for struct in cConfig.__dict__.values(): + if isinstance(struct, type) and issubclass(struct, Structure): + if struct.__name__ == 'in6_addr': + struct.__name__ = '_in6_addr' + else: + struct._external_ = True # hack to avoid redeclaration of the struct in C + # fill in missing constants with reasonable defaults cConfig.NI_MAXHOST = cConfig.NI_MAXHOST or 1025 cConfig.NI_MAXSERV = cConfig.NI_MAXSERV or 32 @@ -568,6 +578,7 @@ WSAStartup = socketdll.WSAStartup WSAStartup.argtypes = [c_int, POINTER(WSAData)] WSAStartup.restype = c_int + WSAStartup.libraries = ('ws2_32',) WSAGetLastError = socketdll.WSAGetLastError WSAGetLastError.argtypes = [] Modified: pypy/dist/pypy/translator/c/src/thread_nt.h ============================================================================== --- pypy/dist/pypy/translator/c/src/thread_nt.h (original) +++ pypy/dist/pypy/translator/c/src/thread_nt.h Tue Apr 24 18:04:59 2007 @@ -6,7 +6,9 @@ /* Windows.h includes winsock.h, but the socket module needs */ /* winsock2.h. So I include it before. Ugly. */ + #include +#include #include #include From ericvrp at codespeak.net Wed Apr 25 09:12:39 2007 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Wed, 25 Apr 2007 09:12:39 +0200 (CEST) Subject: [pypy-svn] r42301 - pypy/dist/pypy/translator/llvm Message-ID: <20070425071239.0B8D58084@code0.codespeak.net> Author: ericvrp Date: Wed Apr 25 09:12:38 2007 New Revision: 42301 Modified: pypy/dist/pypy/translator/llvm/buildllvm.py Log: Allow genllvm tests to be run with llvm >= 2.0 by using the -std-compile-opts option instead of the optionlist requested from gccas. Modified: pypy/dist/pypy/translator/llvm/buildllvm.py ============================================================================== --- pypy/dist/pypy/translator/llvm/buildllvm.py (original) +++ pypy/dist/pypy/translator/llvm/buildllvm.py Wed Apr 25 09:12:38 2007 @@ -69,17 +69,21 @@ 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 + if llvm_version() < 2.0: + cmd = "gccas /dev/null -o /dev/null -debug-pass=Arguments 2>&1" + gccas_output = os.popen(cmd) + opts = gccas_output.read()[17:-1] + " " + else: + opts = '-std-compile-opts' + + # these were added by Chris Lattner for some old version 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): From afa at codespeak.net Wed Apr 25 23:39:45 2007 From: afa at codespeak.net (afa at codespeak.net) Date: Wed, 25 Apr 2007 23:39:45 +0200 (CEST) Subject: [pypy-svn] r42338 - pypy/dist/pypy/module/rsocket Message-ID: <20070425213945.2AAE7807E@code0.codespeak.net> Author: afa Date: Wed Apr 25 23:39:44 2007 New Revision: 42338 Modified: pypy/dist/pypy/module/rsocket/interp_socket.py Log: Socket fd is unsigned on win32, but socket.fileno() must return an int in any case. A test was broken since rev 42168. 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 Wed Apr 25 23:39:44 2007 @@ -2,6 +2,7 @@ from pypy.interpreter.typedef import TypeDef, make_weakref_descr from pypy.interpreter.gateway import ObjSpace, W_Root, NoneNotWrapped from pypy.interpreter.gateway import interp2app +from pypy.rlib.rarithmetic import intmask from pypy.rlib.rsocket import RSocket, AF_INET, SOCK_STREAM from pypy.rlib.rsocket import SocketError, SocketErrorWithErrno from pypy.interpreter.error import OperationError @@ -126,7 +127,7 @@ fd = self.fileno() except SocketError, e: raise converted_error(space, e) - return space.wrap(fd) + return space.wrap(intmask(fd)) fileno_w.unwrap_spec = ['self', ObjSpace] def getpeername_w(self, space): From afa at codespeak.net Thu Apr 26 00:16:46 2007 From: afa at codespeak.net (afa at codespeak.net) Date: Thu, 26 Apr 2007 00:16:46 +0200 (CEST) Subject: [pypy-svn] r42340 - pypy/dist/pypy/translator/js/examples/console Message-ID: <20070425221646.E39AC807E@code0.codespeak.net> Author: afa Date: Thu Apr 26 00:16:46 2007 New Revision: 42340 Modified: pypy/dist/pypy/translator/js/examples/console/console.py Log: Remove unused imports, one of them (fcntl) does not exist on win32. Allows 3 more tests to pass. 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 Apr 26 00:16:46 2007 @@ -1,9 +1,4 @@ - -import subprocess -import fcntl -import os import py -import time from pypy.translator.js.lib import server from pypy.translator.js.main import rpython2javascript From santagada at codespeak.net Thu Apr 26 03:53:22 2007 From: santagada at codespeak.net (santagada at codespeak.net) Date: Thu, 26 Apr 2007 03:53:22 +0200 (CEST) Subject: [pypy-svn] r42346 - pypy/dist/pypy/rlib/parsing Message-ID: <20070426015322.C2858807E@code0.codespeak.net> Author: santagada Date: Thu Apr 26 03:53:22 2007 New Revision: 42346 Modified: pypy/dist/pypy/rlib/parsing/ebnfparse.py Log: don't give an error if you don't have the right conftest file and don't want to use the --view option Modified: pypy/dist/pypy/rlib/parsing/ebnfparse.py ============================================================================== --- pypy/dist/pypy/rlib/parsing/ebnfparse.py (original) +++ pypy/dist/pypy/rlib/parsing/ebnfparse.py Thu Apr 26 03:53:22 2007 @@ -85,8 +85,12 @@ tokens = lexer.tokenize(s, eof=eof) s = parser.parse(tokens) if not we_are_translated(): - if py.test.config.option.view: - s.view() + try: + if py.test.config.option.view: + s.view() + except AttributeError: + pass + return s return parse From antocuni at codespeak.net Thu Apr 26 21:22:47 2007 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Thu, 26 Apr 2007 21:22:47 +0200 (CEST) Subject: [pypy-svn] r42363 - in pypy/dist/pypy: config objspace/flow translator/backendopt translator/cli translator/cli/test translator/oosupport Message-ID: <20070426192247.D2F3F8077@code0.codespeak.net> Author: antocuni Date: Thu Apr 26 21:22:46 2007 New Revision: 42363 Modified: pypy/dist/pypy/config/translationoption.py pypy/dist/pypy/objspace/flow/model.py pypy/dist/pypy/translator/backendopt/all.py pypy/dist/pypy/translator/cli/function.py pypy/dist/pypy/translator/cli/test/runtest.py pypy/dist/pypy/translator/cli/test/test_snippet.py pypy/dist/pypy/translator/oosupport/function.py pypy/dist/pypy/translator/oosupport/treebuilder.py Log: A backend optimization for gencli, which turns SSI graphs into stack-based machine friendly graphs. Modified: pypy/dist/pypy/config/translationoption.py ============================================================================== --- pypy/dist/pypy/config/translationoption.py (original) +++ pypy/dist/pypy/config/translationoption.py Thu Apr 26 21:22:46 2007 @@ -17,6 +17,7 @@ ChoiceOption("type_system", "Type system to use when RTyping", ["lltype", "ootype"], cmdline=None, requires={ + "lltype": [("translation.backendopt.stack_optimization", False)], "ootype": [("translation.backendopt.raisingop2direct_call", False), ("translation.backendopt.constfold", False), ("translation.backendopt.heap2stack", False), @@ -30,10 +31,14 @@ ("translation.gc", "boehm"), ("translation.backendopt.raisingop2direct_call", True)], "cli": [("translation.type_system", "ootype")], - "jvm": [("translation.type_system", "ootype")], - "js": [("translation.type_system", "ootype")], - "squeak": [("translation.type_system", "ootype")], - "cl": [("translation.type_system", "ootype")], + "jvm": [("translation.type_system", "ootype"), + ("translation.backendopt.stack_optimization", False)], + "js": [("translation.type_system", "ootype"), + ("translation.backendopt.stack_optimization", False)], + "squeak": [("translation.type_system", "ootype"), + ("translation.backendopt.stack_optimization", False)], + "cl": [("translation.type_system", "ootype"), + ("translation.backendopt.stack_optimization", False)], }, cmdline="-b --backend"), BoolOption("llvm_via_c", "compile llvm via C", @@ -166,6 +171,14 @@ "which lets the C optimizer remove the asserts", default=False), + BoolOption("stack_optimization", + "Tranform graphs in SSI form into graphs tailored for " + "stack based virtual machines", + default=True, + cmdline="--stackopt", + requires=[("translation.type_system", "ootype"), + ("translation.backend", "cli")]), + BoolOption("none", "Do not run any backend optimizations", requires=[('translation.backendopt.inline', False), Modified: pypy/dist/pypy/objspace/flow/model.py ============================================================================== --- pypy/dist/pypy/objspace/flow/model.py (original) +++ pypy/dist/pypy/objspace/flow/model.py Thu Apr 26 21:22:46 2007 @@ -573,6 +573,8 @@ def checkgraph(graph): "Check the consistency of a flow graph." + + from pypy.translator.oosupport.treebuilder import SubOperation if not __debug__: return try: @@ -608,19 +610,24 @@ if in_link is not None: assert vars[v] is None or vars[v] is in_link - for v in block.inputargs: - definevar(v) - - for op in block.operations: + def checkop(op): for v in op.args: - assert isinstance(v, (Constant, Variable)) - if isinstance(v, Variable): + assert isinstance(v, (Constant, Variable, SubOperation)) + if isinstance(v, SubOperation): + checkop(v.op) + elif isinstance(v, Variable): usevar(v) else: assert v.value is not last_exception #assert v.value != last_exc_value if op.opname == 'direct_call': assert isinstance(op.args[0], Constant) + + for v in block.inputargs: + definevar(v) + + for op in block.operations: + checkop(op) definevar(op.result) exc_links = {} Modified: pypy/dist/pypy/translator/backendopt/all.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/all.py (original) +++ pypy/dist/pypy/translator/backendopt/all.py Thu Apr 26 21:22:46 2007 @@ -11,6 +11,8 @@ from pypy.translator.backendopt.removeassert import remove_asserts from pypy.translator.backendopt.support import log from pypy.translator.backendopt.checkvirtual import check_virtual_methods +from pypy.translator.backendopt.ssa import SSI_to_SSA +from pypy.translator.oosupport.treebuilder import build_trees from pypy.objspace.flow.model import checkgraph INLINE_THRESHOLD_FOR_TEST = 33 @@ -125,6 +127,11 @@ print "after if-to-switch:" print_statistics(translator.graphs[0], translator) + if config.stack_optimization: + for graph in graphs: + SSI_to_SSA(graph) + build_trees(graph) + for graph in graphs: checkgraph(graph) Modified: pypy/dist/pypy/translator/cli/function.py ============================================================================== --- pypy/dist/pypy/translator/cli/function.py (original) +++ pypy/dist/pypy/translator/cli/function.py Thu Apr 26 21:22:46 2007 @@ -6,6 +6,7 @@ from pypy.objspace.flow import model as flowmodel from pypy.rpython.lltypesystem.lltype import Void from pypy.rpython.ootypesystem import ootype +from pypy.translator.oosupport.treebuilder import SubOperation from pypy.translator.oosupport.function import Function as OOFunction from pypy.translator.oosupport.constant import push_constant from pypy.translator.cli.option import getoption @@ -127,17 +128,18 @@ else: self.ilasm.opcode('br', self._get_block_name(self.return_block)) - def _render_op(self, op): - from pypy.rpython.ootypesystem import ootype - instr_list = self.db.genoo.opcodes.get(op.opname, None) - assert instr_list is not None, 'Unknown opcode: %s ' % op - assert isinstance(instr_list, InstructionList) - instr_list.render(self.generator, op) + OOFunction._render_op(self, op) if op.opname in ('direct_call', 'oosend', 'indirect_call') and not self.in_try: self._premature_return() - def _premature_return(self): + def _render_sub_op(self, sub_op): + OOFunction._render_sub_op(self, sub_op) + if sub_op.op.opname in ('direct_call', 'oosend', 'indirect_call') and not self.in_try: + self._premature_return(need_pop=sub_op.op.result is not ootype.Void) + + + def _premature_return(self, need_pop=False): try: return_block = self._get_block_name(self.graph.returnblock) except KeyError: @@ -205,6 +207,23 @@ self.load(return_var) self.ilasm.opcode('ret') + # XXX: this method should be moved into oosupport, but other + # backends are not ready :-( + def render_bool_switch(self, block): + assert len(block.exits) == 2 + for link in block.exits: + if link.exitcase: + link_true = link + else: + link_false = link + + true_label = self.next_label('link_true') + self.generator.load(block.exitswitch) + self.generator.branch_conditionally(link.exitcase, true_label) + self._follow_link(link_false) # if here, the exitswitch is false + self.set_label(true_label) + self._follow_link(link_true) # if here, the exitswitch is true + def render_numeric_switch(self, block): if block.exitswitch.concretetype in (ootype.SignedLongLong, ootype.UnsignedLongLong): # TODO: it could be faster to check is the values fit in @@ -269,7 +288,8 @@ self.ilasm.load_arg(v) else: self.ilasm.load_local(v) - + elif isinstance(v, SubOperation): + self._render_sub_op(v) else: super(Function, self).load(v) 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 Thu Apr 26 21:22:46 2007 @@ -166,16 +166,7 @@ t.buildrtyper(type_system="ootype").specialize() check_virtual_methods(ootype.ROOT) - backend_opt_default = dict( - raisingop2direct_call=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) main_graph = t.graphs[0] Modified: pypy/dist/pypy/translator/cli/test/test_snippet.py ============================================================================== --- pypy/dist/pypy/translator/cli/test/test_snippet.py (original) +++ pypy/dist/pypy/translator/cli/test/test_snippet.py Thu Apr 26 21:22:46 2007 @@ -2,5 +2,14 @@ from pypy.translator.oosupport.test_template.snippets import BaseTestSnippets class TestSnippets(BaseTestSnippets, CliTest): - pass + def test_link_SSA(self): + def fn(): + lst = [42, 43, 44] + for i in range(len(lst)): + item = lst[i] + if i < 10: + lst[i] = item+10 + return lst + res = self.ll_to_list(self.interpret(fn, [])) + assert res == [52, 53, 54] Modified: pypy/dist/pypy/translator/oosupport/function.py ============================================================================== --- pypy/dist/pypy/translator/oosupport/function.py (original) +++ pypy/dist/pypy/translator/oosupport/function.py Thu Apr 26 21:22:46 2007 @@ -5,7 +5,8 @@ from pypy.objspace.flow import model as flowmodel from pypy.rpython.ootypesystem import ootype -from pypy.translator.oosupport.metavm import InstructionList +from pypy.translator.oosupport.treebuilder import SubOperation +from pypy.translator.oosupport.metavm import InstructionList, StoreResult class Function(object): @@ -194,6 +195,8 @@ else: assert False, 'Unknonw exitswitch type: %s' % block.exitswitch.concretetype + # XXX: soon or later we should use the implementation in + # cli/function.py, but at the moment jvm and js fail with it. def render_bool_switch(self, block): for link in block.exits: self._setup_link(link) @@ -221,15 +224,21 @@ self.generator.load(block.exitswitch) self.generator.branch_if_equal(target_label) + def _follow_link(self, link): + target_label = self._get_block_name(link.target) + self._setup_link(link) + self.generator.branch_unconditionally(target_label) + def _setup_link(self, link): - self.generator.add_comment("Setup link") target = link.target for to_load, to_store in zip(link.args, target.inputargs): - if to_load.concretetype is not ootype.Void: - self.generator.add_comment(" to_load=%r to_store=%r" % ( - to_load, to_store)) - self.generator.load(to_load) - self.generator.store(to_store) + if isinstance(to_load, flowmodel.Variable) and to_load.name == to_store.name: + continue + if to_load.concretetype is ootype.Void: + continue + self.generator.add_comment("%r --> %r" % (to_load, to_store)) + self.generator.load(to_load) + self.generator.store(to_store) def _render_op(self, op): instr_list = self.db.genoo.opcodes.get(op.opname, None) @@ -237,6 +246,16 @@ assert isinstance(instr_list, InstructionList) instr_list.render(self.generator, op) + def _render_sub_op(self, sub_op): + op = sub_op.op + instr_list = self.db.genoo.opcodes.get(op.opname, None) + assert instr_list is not None, 'Unknown opcode: %s ' % op + assert isinstance(instr_list, InstructionList) + assert instr_list[-1] is StoreResult, "Cannot inline an operation that doesn't store the result" + instr_list = InstructionList(instr_list[:-1]) # leave the value on the stack if this is a sub-op + instr_list.render(self.generator, op) + # now the value is on the stack + # ---------------------------------------------------------# # These methods are quite backend independent, but not # # used in all backends. Invoke them from your __init__ if # Modified: pypy/dist/pypy/translator/oosupport/treebuilder.py ============================================================================== --- pypy/dist/pypy/translator/oosupport/treebuilder.py (original) +++ pypy/dist/pypy/translator/oosupport/treebuilder.py Thu Apr 26 21:22:46 2007 @@ -50,7 +50,7 @@ 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] + block.operations = [op for op in block.operations if op is not None] or () def build_trees(graph): if not getattr(graph, 'tree_built', False): From antocuni at codespeak.net Fri Apr 27 11:02:00 2007 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Fri, 27 Apr 2007 11:02:00 +0200 (CEST) Subject: [pypy-svn] r42367 - pypy/dist/pypy/translator/backendopt Message-ID: <20070427090200.08C8B80A4@code0.codespeak.net> Author: antocuni Date: Fri Apr 27 11:02:00 2007 New Revision: 42367 Modified: pypy/dist/pypy/translator/backendopt/all.py Log: insert a sanity check also here, else a lot of tests calling backendopts directly would fail. Modified: pypy/dist/pypy/translator/backendopt/all.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/all.py (original) +++ pypy/dist/pypy/translator/backendopt/all.py Fri Apr 27 11:02:00 2007 @@ -127,7 +127,8 @@ print "after if-to-switch:" print_statistics(translator.graphs[0], translator) - if config.stack_optimization: + # XXX: it's not nice to have the backend hard-coded here + if config.stack_optimization and translator.config.translation.backend == 'cli': for graph in graphs: SSI_to_SSA(graph) build_trees(graph) From antocuni at codespeak.net Fri Apr 27 11:41:27 2007 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Fri, 27 Apr 2007 11:41:27 +0200 (CEST) Subject: [pypy-svn] r42368 - pypy/dist/pypy/objspace/flow Message-ID: <20070427094127.556CB80A3@code0.codespeak.net> Author: antocuni Date: Fri Apr 27 11:41:27 2007 New Revision: 42368 Modified: pypy/dist/pypy/objspace/flow/model.py Log: (arigo, antocuni) revert r32363 as suggested by Armin, because build_tree is not really a transformation Modified: pypy/dist/pypy/objspace/flow/model.py ============================================================================== --- pypy/dist/pypy/objspace/flow/model.py (original) +++ pypy/dist/pypy/objspace/flow/model.py Fri Apr 27 11:41:27 2007 @@ -573,8 +573,6 @@ def checkgraph(graph): "Check the consistency of a flow graph." - - from pypy.translator.oosupport.treebuilder import SubOperation if not __debug__: return try: @@ -610,24 +608,19 @@ if in_link is not None: assert vars[v] is None or vars[v] is in_link - def checkop(op): + for v in block.inputargs: + definevar(v) + + for op in block.operations: for v in op.args: - assert isinstance(v, (Constant, Variable, SubOperation)) - if isinstance(v, SubOperation): - checkop(v.op) - elif isinstance(v, Variable): + assert isinstance(v, (Constant, Variable)) + if isinstance(v, Variable): usevar(v) else: assert v.value is not last_exception #assert v.value != last_exc_value if op.opname == 'direct_call': assert isinstance(op.args[0], Constant) - - for v in block.inputargs: - definevar(v) - - for op in block.operations: - checkop(op) definevar(op.result) exc_links = {} From antocuni at codespeak.net Fri Apr 27 12:34:24 2007 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Fri, 27 Apr 2007 12:34:24 +0200 (CEST) Subject: [pypy-svn] r42369 - in pypy/dist/pypy: config translator/backendopt translator/cli translator/cli/test translator/oosupport Message-ID: <20070427103424.F0B9580A3@code0.codespeak.net> Author: antocuni Date: Fri Apr 27 12:34:24 2007 New Revision: 42369 Modified: pypy/dist/pypy/config/translationoption.py pypy/dist/pypy/translator/backendopt/all.py pypy/dist/pypy/translator/cli/gencli.py pypy/dist/pypy/translator/cli/test/test_float.py pypy/dist/pypy/translator/oosupport/treebuilder.py Log: Make backends responsible to invoke treebuilder, not backend optimizations. Modified: pypy/dist/pypy/config/translationoption.py ============================================================================== --- pypy/dist/pypy/config/translationoption.py (original) +++ pypy/dist/pypy/config/translationoption.py Fri Apr 27 12:34:24 2007 @@ -17,7 +17,6 @@ ChoiceOption("type_system", "Type system to use when RTyping", ["lltype", "ootype"], cmdline=None, requires={ - "lltype": [("translation.backendopt.stack_optimization", False)], "ootype": [("translation.backendopt.raisingop2direct_call", False), ("translation.backendopt.constfold", False), ("translation.backendopt.heap2stack", False), @@ -31,14 +30,10 @@ ("translation.gc", "boehm"), ("translation.backendopt.raisingop2direct_call", True)], "cli": [("translation.type_system", "ootype")], - "jvm": [("translation.type_system", "ootype"), - ("translation.backendopt.stack_optimization", False)], - "js": [("translation.type_system", "ootype"), - ("translation.backendopt.stack_optimization", False)], - "squeak": [("translation.type_system", "ootype"), - ("translation.backendopt.stack_optimization", False)], - "cl": [("translation.type_system", "ootype"), - ("translation.backendopt.stack_optimization", False)], + "jvm": [("translation.type_system", "ootype")], + "js": [("translation.type_system", "ootype")], + "squeak": [("translation.type_system", "ootype")], + "cl": [("translation.type_system", "ootype")], }, cmdline="-b --backend"), BoolOption("llvm_via_c", "compile llvm via C", @@ -173,11 +168,8 @@ BoolOption("stack_optimization", "Tranform graphs in SSI form into graphs tailored for " - "stack based virtual machines", - default=True, - cmdline="--stackopt", - requires=[("translation.type_system", "ootype"), - ("translation.backend", "cli")]), + "stack based virtual machines (only for backends that support it)", + default=True), BoolOption("none", "Do not run any backend optimizations", Modified: pypy/dist/pypy/translator/backendopt/all.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/all.py (original) +++ pypy/dist/pypy/translator/backendopt/all.py Fri Apr 27 12:34:24 2007 @@ -11,8 +11,6 @@ from pypy.translator.backendopt.removeassert import remove_asserts from pypy.translator.backendopt.support import log from pypy.translator.backendopt.checkvirtual import check_virtual_methods -from pypy.translator.backendopt.ssa import SSI_to_SSA -from pypy.translator.oosupport.treebuilder import build_trees from pypy.objspace.flow.model import checkgraph INLINE_THRESHOLD_FOR_TEST = 33 @@ -127,12 +125,6 @@ print "after if-to-switch:" print_statistics(translator.graphs[0], translator) - # XXX: it's not nice to have the backend hard-coded here - if config.stack_optimization and translator.config.translation.backend == 'cli': - for graph in graphs: - SSI_to_SSA(graph) - build_trees(graph) - for graph in graphs: checkgraph(graph) Modified: pypy/dist/pypy/translator/cli/gencli.py ============================================================================== --- pypy/dist/pypy/translator/cli/gencli.py (original) +++ pypy/dist/pypy/translator/cli/gencli.py Fri Apr 27 12:34:24 2007 @@ -5,6 +5,8 @@ from py.compat import subprocess from pypy.config.config import Config from pypy.translator.oosupport.genoo import GenOO +from pypy.translator.oosupport.treebuilder import build_trees +from pypy.translator.backendopt.ssa import SSI_to_SSA from pypy.translator.cli import conftest from pypy.translator.cli.ilgenerator import IlasmGenerator from pypy.translator.cli.function import Function, log @@ -55,6 +57,11 @@ self.tmpfile = tmpdir.join(self.assembly_name + '.il') self.const_stat = str(tmpdir.join('const_stat')) + if translator.config.translation.backendopt.stack_optimization: + for graph in translator.graphs: + SSI_to_SSA(graph) + build_trees(graph) + def generate_source(self): GenOO.generate_source(self) self.db.const_count.dump(self.const_stat) Modified: pypy/dist/pypy/translator/cli/test/test_float.py ============================================================================== --- pypy/dist/pypy/translator/cli/test/test_float.py (original) +++ pypy/dist/pypy/translator/cli/test/test_float.py Fri Apr 27 12:34:24 2007 @@ -3,9 +3,7 @@ from pypy.rpython.test.test_rfloat import BaseTestRfloat class TestCliFloat(CliTest, BaseTestRfloat): - pass - - def test_float(self): + def test_parse_float(self): ex = ['', ' ', '0', '1', '-1.5', '1.5E2', '2.5e-1', ' 0 ', '?'] def fn(i): s = ex[i] Modified: pypy/dist/pypy/translator/oosupport/treebuilder.py ============================================================================== --- pypy/dist/pypy/translator/oosupport/treebuilder.py (original) +++ pypy/dist/pypy/translator/oosupport/treebuilder.py Fri Apr 27 12:34:24 2007 @@ -50,7 +50,8 @@ 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] or () + if block.operations != (): + block.operations = [op for op in block.operations if op is not None] def build_trees(graph): if not getattr(graph, 'tree_built', False): From afa at codespeak.net Fri Apr 27 13:28:56 2007 From: afa at codespeak.net (afa at codespeak.net) Date: Fri, 27 Apr 2007 13:28:56 +0200 (CEST) Subject: [pypy-svn] r42370 - pypy/dist/pypy/module/signal/test Message-ID: <20070427112856.9ECDB806F@code0.codespeak.net> Author: afa Date: Fri Apr 27 13:28:55 2007 New Revision: 42370 Modified: pypy/dist/pypy/module/signal/test/test_signal.py Log: correctly skip these tests on win32 Modified: pypy/dist/pypy/module/signal/test/test_signal.py ============================================================================== --- pypy/dist/pypy/module/signal/test/test_signal.py (original) +++ pypy/dist/pypy/module/signal/test/test_signal.py Fri Apr 27 13:28:55 2007 @@ -1,4 +1,4 @@ -import os +import os, py from pypy.conftest import gettestobjspace class AppTestSignal: From antocuni at codespeak.net Fri Apr 27 15:55:31 2007 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Fri, 27 Apr 2007 15:55:31 +0200 (CEST) Subject: [pypy-svn] r42373 - in pypy/dist/pypy/translator/oosupport: . test Message-ID: <20070427135531.15A3E8099@code0.codespeak.net> Author: antocuni Date: Fri Apr 27 15:55:30 2007 New Revision: 42373 Modified: pypy/dist/pypy/translator/oosupport/test/test_treebuilder.py pypy/dist/pypy/translator/oosupport/treebuilder.py Log: A better way to determine if we can inline an operation inside a SubOperation. Thanks to arigo. Modified: pypy/dist/pypy/translator/oosupport/test/test_treebuilder.py ============================================================================== --- pypy/dist/pypy/translator/oosupport/test/test_treebuilder.py (original) +++ pypy/dist/pypy/translator/oosupport/test/test_treebuilder.py Fri Apr 27 15:55:30 2007 @@ -37,6 +37,7 @@ assert eval_func(0) == 2 def test_function_call(): + py.test.skip('fixme!') def g(x): return x+1 def fn(x): Modified: pypy/dist/pypy/translator/oosupport/treebuilder.py ============================================================================== --- pypy/dist/pypy/translator/oosupport/treebuilder.py (original) +++ pypy/dist/pypy/translator/oosupport/treebuilder.py Fri Apr 27 15:55:30 2007 @@ -1,6 +1,8 @@ +from pypy.rpython.lltypesystem.lloperation import LL_OPERATIONS from pypy.rpython.ootypesystem import ootype from pypy.objspace.flow import model as flowmodel + class SubOperation(object): def __init__(self, op): self.op = op @@ -19,11 +21,14 @@ ootype.CustomDict, ootype.DictItemsIterator)) +# TODO: analyze graphs to determine which functions calls could have +# side effects and which can be inlined safely. def can_be_inlined(op): - for v in op.args: - if isinstance(v, flowmodel.Variable) and is_mutable(v.concretetype): - return False - return True + try: + llop = LL_OPERATIONS[op.opname] + return llop.canfold + except KeyError: + return False def build_op_map(block): var_count = {} From antocuni at codespeak.net Fri Apr 27 16:01:05 2007 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Fri, 27 Apr 2007 16:01:05 +0200 (CEST) Subject: [pypy-svn] r42374 - pypy/dist/pypy/translator/oosupport Message-ID: <20070427140105.1C1DE8099@code0.codespeak.net> Author: antocuni Date: Fri Apr 27 16:01:05 2007 New Revision: 42374 Modified: pypy/dist/pypy/translator/oosupport/treebuilder.py Log: add infos about cli-specific operations Modified: pypy/dist/pypy/translator/oosupport/treebuilder.py ============================================================================== --- pypy/dist/pypy/translator/oosupport/treebuilder.py (original) +++ pypy/dist/pypy/translator/oosupport/treebuilder.py Fri Apr 27 16:01:05 2007 @@ -1,7 +1,17 @@ -from pypy.rpython.lltypesystem.lloperation import LL_OPERATIONS +from pypy.rpython.lltypesystem.lloperation import LLOp, LL_OPERATIONS as LL_OPS from pypy.rpython.ootypesystem import ootype from pypy.objspace.flow import model as flowmodel +LL_OPERATIONS = { + 'clibox': LLOp(oo=True, canfold=True), + 'cliunbox': LLOp(oo=True, canfold=True), + 'cli_newarray': LLOp(oo=True, canfold=True), + 'cli_getelem': LLOp(oo=True, sideeffects=False), + 'cli_setelem': LLOp(oo=True), + 'cli_typeof': LLOp(oo=True, canfold=True), + 'cli_arraylength': LLOp(oo=True, canfold=True), + } +LL_OPERATIONS.update(LL_OPS) class SubOperation(object): def __init__(self, op): From cfbolz at codespeak.net Sat Apr 28 12:49:47 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sat, 28 Apr 2007 12:49:47 +0200 (CEST) Subject: [pypy-svn] r42389 - pypy/dist/pypy/rlib/parsing Message-ID: <20070428104947.D19248069@code0.codespeak.net> Author: cfbolz Date: Sat Apr 28 12:49:47 2007 New Revision: 42389 Modified: pypy/dist/pypy/rlib/parsing/tree.py Log: typo Modified: pypy/dist/pypy/rlib/parsing/tree.py ============================================================================== --- pypy/dist/pypy/rlib/parsing/tree.py (original) +++ pypy/dist/pypy/rlib/parsing/tree.py Sat Apr 28 12:49:47 2007 @@ -56,7 +56,7 @@ def visit(self, visitor): "NOT_RPYTHON" if isinstance(visitor, RPythonVisitor): - visitor.dispatch(self) + return visitor.dispatch(self) general = getattr(visitor, "visit", None) if general is None: return getattr(visitor, "visit_" + self.symbol)(self) From fijal at codespeak.net Sat Apr 28 19:22:02 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 28 Apr 2007 19:22:02 +0200 (CEST) Subject: [pypy-svn] r42400 - pypy/dist/pypy/lib/distributed/test Message-ID: <20070428172202.A36548067@code0.codespeak.net> Author: fijal Date: Sat Apr 28 19:22:02 2007 New Revision: 42400 Modified: pypy/dist/pypy/lib/distributed/test/test_distributed.py Log: Add another test for descriptors. It's passing, but just to be sure. 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 Sat Apr 28 19:22:02 2007 @@ -262,3 +262,20 @@ xf = protocol.get_remote('f') data = xf('/etc/passwd').read() assert data + + def test_real_descriptor(self): + class getdesc(object): + def __get__(self, obj, val=None): + if obj is not None: + assert type(obj) is X + return 3 + + class X(object): + x = getdesc() + + x = X() + + protocol = self.test_env({'x':x}) + xx = protocol.get_remote('x') + assert xx.x == 3 + From fijal at codespeak.net Sat Apr 28 19:41:09 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 28 Apr 2007 19:41:09 +0200 (CEST) Subject: [pypy-svn] r42403 - in pypy/dist/pypy/lib/distributed: . test Message-ID: <20070428174109.BB64B8067@code0.codespeak.net> Author: fijal Date: Sat Apr 28 19:41:09 2007 New Revision: 42403 Modified: pypy/dist/pypy/lib/distributed/faker.py pypy/dist/pypy/lib/distributed/test/test_distributed.py Log: A bit of support for bases. two-liner file server would work by now Modified: pypy/dist/pypy/lib/distributed/faker.py ============================================================================== --- pypy/dist/pypy/lib/distributed/faker.py (original) +++ pypy/dist/pypy/lib/distributed/faker.py Sat Apr 28 19:41:09 2007 @@ -40,12 +40,8 @@ """ Wrap type to transpotable entity, taking care about descriptors """ - # XXX forget about bases right now - bases = [] dict_w = {} - # XXX we do dir here because we've forgotten about basis - # above - for item in dir(tp): + for item in tp.__dict__.keys(): value = getattr(tp, item) if ignore(item): # we've got shortcut for method @@ -57,7 +53,8 @@ dict_w[item] = ('set', name) else: dict_w[item] = protocol.wrap(value) - return tp_id, tp.__name__, dict_w, bases + bases_w = [protocol.wrap(i) for i in tp.__bases__ if i is not object] + return tp_id, tp.__name__, dict_w, bases_w def unwrap_descriptor_gen(desc_class): def unwrapper(protocol, data): @@ -73,14 +70,16 @@ def unwrap_type(objkeeper, protocol, type_id, name_, dict_w, bases_w): """ Unwrap remote type, based on it's description """ - # XXX sanity check - assert bases_w == [] + if bases_w == []: + bases = (object,) + else: + bases = tuple([protocol.unwrap(i) for i in bases_w]) d = dict.fromkeys(dict_w) # XXX we do it in two steps to avoid cyclic dependencies, # probably there is some smarter way of doing this if '__doc__' in dict_w: d['__doc__'] = protocol.unwrap(dict_w['__doc__']) - tp = type(name_, (object,), d) + tp = type(name_, bases, d) objkeeper.register_remote_type(tp, type_id) for key, value in dict_w.items(): if key != '__doc__': 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 Sat Apr 28 19:41:09 2007 @@ -231,7 +231,6 @@ xa.m(xA) def test_instantiate_remote_type(self): - skip("Will not work unless we take care about __basis__") class C: def __init__(self, y): self.y = y @@ -254,11 +253,7 @@ assert l def test_remote_file_access(self): - # cannot do test_env({'file':file}) yet :) - def f(name): - return open(name) - - protocol = self.test_env({'f':f}) + protocol = self.test_env({'f':open}) xf = protocol.get_remote('f') data = xf('/etc/passwd').read() assert data @@ -279,3 +274,16 @@ xx = protocol.get_remote('x') assert xx.x == 3 + def test_bases(self): + class X(object): + pass + + class Y(X): + pass + + y = Y() + protocol = self.test_env({'y':y, 'X':X}) + xy = protocol.get_remote('y') + xX = protocol.get_remote('X') + assert isinstance(xy, xX) + From santagada at codespeak.net Sat Apr 28 20:12:45 2007 From: santagada at codespeak.net (santagada at codespeak.net) Date: Sat, 28 Apr 2007 20:12:45 +0200 (CEST) Subject: [pypy-svn] r42406 - pypy/dist/pypy/rlib/parsing Message-ID: <20070428181245.6E9498067@code0.codespeak.net> Author: santagada Date: Sat Apr 28 20:12:44 2007 New Revision: 42406 Modified: pypy/dist/pypy/rlib/parsing/ebnfparse.py Log: made a try/catch on py.option.view of generated ToAST Modified: pypy/dist/pypy/rlib/parsing/ebnfparse.py ============================================================================== --- pypy/dist/pypy/rlib/parsing/ebnfparse.py (original) +++ pypy/dist/pypy/rlib/parsing/ebnfparse.py Sat Apr 28 20:12:44 2007 @@ -296,9 +296,14 @@ self.emit("r = self.visit_%s(tree)" % (startsymbol, )) self.emit("assert len(r) == 1") self.start_block("if not we_are_translated():") + self.start_block("try:") self.start_block("if py.test.config.option.view:") self.emit("r[0].view()") self.end_block("option.view") + self.end_block("try") + self.start_block("except AttributeError:") + self.emit("pass") + self.end_block("except") self.end_block("we_are_translated") self.emit("return r[0]") self.end_block("transform") From cfbolz at codespeak.net Sat Apr 28 20:23:31 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sat, 28 Apr 2007 20:23:31 +0200 (CEST) Subject: [pypy-svn] r42407 - pypy/dist/pypy/rlib/parsing Message-ID: <20070428182331.3C9668065@code0.codespeak.net> Author: cfbolz Date: Sat Apr 28 20:23:30 2007 New Revision: 42407 Modified: pypy/dist/pypy/rlib/parsing/ebnfparse.py Log: regenerate Modified: pypy/dist/pypy/rlib/parsing/ebnfparse.py ============================================================================== --- pypy/dist/pypy/rlib/parsing/ebnfparse.py (original) +++ pypy/dist/pypy/rlib/parsing/ebnfparse.py Sat Apr 28 20:23:30 2007 @@ -493,14 +493,9 @@ def visit__star_symbol0(self, node): length = len(node.children) if length == 2: - if (node.children[0].symbol == 'expansion' and node.children[1].symbol == '__2_|'): - children = [] - children.extend(self.visit_expansion(node.children[0])) - return [Nonterminal(node.symbol, children)] - if (node.children[0].symbol == 'expansion' and node.children[1].symbol == '__2_|'): - children = [] - children.extend(self.visit_expansion(node.children[0])) - return [Nonterminal(node.symbol, children)] + children = [] + children.extend(self.visit_expansion(node.children[0])) + return [Nonterminal(node.symbol, children)] children = [] children.extend(self.visit_expansion(node.children[0])) expr = self.visit__star_symbol0(node.children[2]) @@ -591,13 +586,25 @@ children = [] children.extend([node.children[0]]) return [Nonterminal(node.symbol, children)] + def transform(self, tree): + assert isinstance(tree, Nonterminal) + assert tree.symbol == 'file' + r = self.visit_file(tree) + assert len(r) == 1 + if not we_are_translated(): + try: + if py.test.config.option.view: + r[0].view() + except AttributeError: + pass + return r[0] parser = PackratParser([Rule('file', [['list', 'EOF']]), Rule('_plus_symbol0', [['element', '_plus_symbol0'], ['element']]), Rule('list', [['_plus_symbol0']]), Rule('element', [['regex'], ['production']]), Rule('regex', [['SYMBOLNAME', '__0_:', 'QUOTE', '__1_;']]), Rule('production', [['NONTERMINALNAME', '__0_:', 'body', '__1_;']]), - Rule('_star_symbol0', [['expansion', '__2_|', '_star_symbol0'], ['expansion', '__2_|'], ['expansion', '__2_|']]), + Rule('_star_symbol0', [['expansion', '__2_|', '_star_symbol0'], ['expansion', '__2_|']]), Rule('body', [['_star_symbol0', 'expansion'], ['expansion']]), Rule('_plus_symbol1', [['decorated', '_plus_symbol1'], ['decorated']]), Rule('expansion', [['_plus_symbol1']]), From fijal at codespeak.net Sat Apr 28 20:44:32 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 28 Apr 2007 20:44:32 +0200 (CEST) Subject: [pypy-svn] r42408 - in pypy/dist/pypy/lib/distributed: . test Message-ID: <20070428184432.0C576806F@code0.codespeak.net> Author: fijal Date: Sat Apr 28 20:44:31 2007 New Revision: 42408 Added: pypy/dist/pypy/lib/distributed/test/test_socklayer.py Modified: pypy/dist/pypy/lib/distributed/socklayer.py Log: Some simple wrappers around a socket and a weird test, which does not close the socket properly, need to be rethinked at some point Modified: pypy/dist/pypy/lib/distributed/socklayer.py ============================================================================== --- pypy/dist/pypy/lib/distributed/socklayer.py (original) +++ pypy/dist/pypy/lib/distributed/socklayer.py Sat Apr 28 20:44:31 2007 @@ -19,6 +19,7 @@ self.buffer = "" self.conn = conn +class ReceiverWrapper(SocketWrapper): def receive(self): msg, self.buffer = decodemessage(self.buffer) while msg is None: @@ -31,28 +32,39 @@ trace("received %s" % msg[1]) return marshal.loads(msg[1]) +class SenderWrapper(SocketWrapper): def send(self, data): trace("sending %s" % (data,)) self.conn.sendall(message('c', marshal.dumps(data))) trace("done") -def socket_listener(address=('', 12122), socket=socket): +def socket_listener(address, socket=socket): s = socket(AF_INET, SOCK_STREAM) s.bind(address) s.listen(1) print "Waiting for connection" conn, addr = s.accept() - sw = SocketWrapper(conn) - return sw.send, sw.receive + return SenderWrapper(conn).send, ReceiverWrapper(conn).receive + +def socket_loop(address, to_export, socket=socket): + from distributed import RemoteProtocol, remote_loop + try: + send, receive = socket_listener(address, socket) + remote_loop(RemoteProtocol(send, receive, to_export)) + except Finished: + pass 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 + return SenderWrapper(s).send, ReceiverWrapper(s).receive + +def connect(address, socket=socket): + from distributed import RemoteProtocol + return RemoteProtocol(*socket_connecter(address, socket)) def spawn_remote_side(code, gw): """ A very simple wrapper around greenexecnet to allow Added: pypy/dist/pypy/lib/distributed/test/test_socklayer.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/lib/distributed/test/test_socklayer.py Sat Apr 28 20:44:31 2007 @@ -0,0 +1,28 @@ + +from pypy.conftest import gettestobjspace + +# XXX think how to close the socket + +class AppTestSocklayer: + def setup_class(cls): + cls.space = gettestobjspace(**{"objspace.std.withtproxy": True, + "usemodules":("_stackless","rsocket", "select")}) + + def test_socklayer(self): + class X: + z = 3 + + x = X() + + from py.__.green.pipe.gsocket import GreenSocket + from distributed.socklayer import socket_loop, connect + from py.__.green.greensock2 import oneof, allof + + def one(): + socket_loop(('127.0.0.1', 21211), {'x':x}, socket=GreenSocket) + + def two(): + rp = connect(('127.0.0.1', 21211), GreenSocket) + assert rp.get_remote('x').z == 3 + + oneof(one, two) From fijal at codespeak.net Sat Apr 28 20:58:46 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 28 Apr 2007 20:58:46 +0200 (CEST) Subject: [pypy-svn] r42410 - in pypy/dist/pypy/lib/distributed: . test Message-ID: <20070428185846.C38DC8065@code0.codespeak.net> Author: fijal Date: Sat Apr 28 20:58:46 2007 New Revision: 42410 Modified: pypy/dist/pypy/lib/distributed/__init__.py pypy/dist/pypy/lib/distributed/protocol.py pypy/dist/pypy/lib/distributed/test/test_distributed.py Log: catch key error and report it better if object is not there. Modified: pypy/dist/pypy/lib/distributed/__init__.py ============================================================================== --- pypy/dist/pypy/lib/distributed/__init__.py (original) +++ pypy/dist/pypy/lib/distributed/__init__.py Sat Apr 28 20:58:46 2007 @@ -1,6 +1,7 @@ try: - from protocol import RemoteProtocol, test_env, remote_loop + from protocol import RemoteProtocol, test_env, remote_loop, ObjectNotFound except ImportError: + # XXX fix it # UGH. This is needed for tests pass Modified: pypy/dist/pypy/lib/distributed/protocol.py ============================================================================== --- pypy/dist/pypy/lib/distributed/protocol.py (original) +++ pypy/dist/pypy/lib/distributed/protocol.py Sat Apr 28 20:58:46 2007 @@ -45,6 +45,9 @@ from distributed import faker import sys +class ObjectNotFound(Exception): + pass + # XXX We do not make any garbage collection. We'll need it at some point """ @@ -289,8 +292,13 @@ while 1: command, data = receive() if command == 'get': - # XXX: Error recovery anyone??? - send(("finished", wrap(protocol.keeper.exported_names[data]))) + try: + item = protocol.keeper.exported_names[data] + except KeyError: + send(("finished_error",data)) + else: + # XXX wrapping problems catching? do we have any? + send(("finished", wrap(item))) elif command == 'call': id, name, args, kwargs = data args, kwargs = protocol.unpack_args(args, kwargs) @@ -302,6 +310,8 @@ send(("finished", wrap(retval))) elif command == 'finished': return unwrap(data) + elif command == 'finished_error': + raise ObjectNotFound("Cannot find name %s" % (data,)) elif command == 'raised': exc, val, tb = unwrap(data) raise exc, val, tb 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 Sat Apr 28 20:58:46 2007 @@ -287,3 +287,8 @@ xX = protocol.get_remote('X') assert isinstance(xy, xX) + def test_key_error(self): + from distributed import ObjectNotFound + protocol = self.test_env({}) + raises(ObjectNotFound, "protocol.get_remote('x')") + From fijal at codespeak.net Sat Apr 28 21:00:13 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 28 Apr 2007 21:00:13 +0200 (CEST) Subject: [pypy-svn] r42411 - pypy/dist/pypy/lib/distributed Message-ID: <20070428190013.27C518065@code0.codespeak.net> Author: fijal Date: Sat Apr 28 21:00:12 2007 New Revision: 42411 Modified: pypy/dist/pypy/lib/distributed/socklayer.py Log: Be a bit more informative Modified: pypy/dist/pypy/lib/distributed/socklayer.py ============================================================================== --- pypy/dist/pypy/lib/distributed/socklayer.py (original) +++ pypy/dist/pypy/lib/distributed/socklayer.py Sat Apr 28 21:00:12 2007 @@ -42,8 +42,9 @@ s = socket(AF_INET, SOCK_STREAM) s.bind(address) s.listen(1) - print "Waiting for connection" + print "Waiting for connection on %s" % (address,) conn, addr = s.accept() + print "Connected from %s" % (addr,) return SenderWrapper(conn).send, ReceiverWrapper(conn).receive From fijal at codespeak.net Sat Apr 28 21:00:40 2007 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 28 Apr 2007 21:00:40 +0200 (CEST) Subject: [pypy-svn] r42412 - pypy/dist/pypy/lib/distributed/demo Message-ID: <20070428190040.E8EA58068@code0.codespeak.net> Author: fijal Date: Sat Apr 28 21:00:40 2007 New Revision: 42412 Added: pypy/dist/pypy/lib/distributed/demo/fileclient.py pypy/dist/pypy/lib/distributed/demo/fileserver.py Log: Famous 2-line fileserver now working :) Added: pypy/dist/pypy/lib/distributed/demo/fileclient.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/lib/distributed/demo/fileclient.py Sat Apr 28 21:00:40 2007 @@ -0,0 +1,14 @@ + +""" This is sample client for a server based in fileserver.py, not counting +initialization and __doc__ has just 2 lines. Usage: + +pypy-c -i fileclient.py +""" +HOST = '127.0.0.1' +PORT = 12221 + +from distributed.socklayer import connect +file_opener = connect((HOST, PORT)).get_remote('open') + +# now you can do for example file_opener('/etc/passwd').read() to +# read remote /etc/passwd Added: pypy/dist/pypy/lib/distributed/demo/fileserver.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/lib/distributed/demo/fileserver.py Sat Apr 28 21:00:40 2007 @@ -0,0 +1,14 @@ +""" This is sample demo about how flexible pypy distribution is. +Not counting __doc__ and initialization this is 2 line, +fully operational file server, +sample client which is in fileclient.py is included as well. + +Note that you must run it with pypy-c compiled with transparent proxy +and allworkingmodules (or at least socket and select) +""" + +HOST = '127.0.0.1' # defaults to localhost, not to export your files +PORT = 12221 + +from distributed.socklayer import socket_loop +socket_loop((HOST, PORT), {'open':open}) From santagada at codespeak.net Sat Apr 28 21:21:40 2007 From: santagada at codespeak.net (santagada at codespeak.net) Date: Sat, 28 Apr 2007 21:21:40 +0200 (CEST) Subject: [pypy-svn] r42413 - in pypy/dist/pypy/lang/js: . test Message-ID: <20070428192140.89CC28065@code0.codespeak.net> Author: santagada Date: Sat Apr 28 21:21:39 2007 New Revision: 42413 Added: pypy/dist/pypy/lang/js/jsgrammar.txt - copied unchanged from r42409, user/santagada/newjsparser/jsgrammar.txt pypy/dist/pypy/lang/js/test/test_new_parser.py - copied, changed from r42409, user/santagada/newjsparser/test_parser.py Modified: pypy/dist/pypy/lang/js/interpreter.py pypy/dist/pypy/lang/js/jsobj.py pypy/dist/pypy/lang/js/operations.py Log: new js parser inclusion on the pypy tree Modified: pypy/dist/pypy/lang/js/interpreter.py ============================================================================== --- pypy/dist/pypy/lang/js/interpreter.py (original) +++ pypy/dist/pypy/lang/js/interpreter.py Sat Apr 28 21:21:39 2007 @@ -63,7 +63,7 @@ def parseIntjs(ctx, args, this): if len(args) < 1: return W_Number(NaN) - s = args[0].ToString().strip() + s = args[0].ToString().strip(" ") if len(args) > 1: radix = args[1].ToInt32() else: @@ -82,7 +82,7 @@ def parseFloatjs(ctx, args, this): if len(args) < 1: return W_Number(NaN) - s = args[0].ToString().strip() + s = args[0].ToString().strip(" ") try: n = float(s) except ValueError: Modified: pypy/dist/pypy/lang/js/jsobj.py ============================================================================== --- pypy/dist/pypy/lang/js/jsobj.py (original) +++ pypy/dist/pypy/lang/js/jsobj.py Sat Apr 28 21:21:39 2007 @@ -20,6 +20,8 @@ class JsTypeError(JsBaseExcept): pass +class RangeError(JsBaseExcept): pass + Infinity = 1e300 * 1e300 NaN = Infinity/Infinity Modified: pypy/dist/pypy/lang/js/operations.py ============================================================================== --- pypy/dist/pypy/lang/js/operations.py (original) +++ pypy/dist/pypy/lang/js/operations.py Sat Apr 28 21:21:39 2007 @@ -5,6 +5,7 @@ """ from pypy.lang.js.jsobj import * +from pypy.lang.js.jsparser import JsSyntaxError from pypy.rlib.parsing.ebnfparse import Symbol, Nonterminal from pypy.rlib.rarithmetic import r_uint, intmask from constants import unescapedict, SLASH From cfbolz at codespeak.net Sat Apr 28 22:58:19 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sat, 28 Apr 2007 22:58:19 +0200 (CEST) Subject: [pypy-svn] r42415 - pypy/dist/pypy/lang/js/test Message-ID: <20070428205819.2740D8067@code0.codespeak.net> Author: cfbolz Date: Sat Apr 28 22:58:18 2007 New Revision: 42415 Modified: pypy/dist/pypy/lang/js/test/test_new_parser.py Log: force the parser to parse to the end of the input stream Modified: pypy/dist/pypy/lang/js/test/test_new_parser.py ============================================================================== --- pypy/dist/pypy/lang/js/test/test_new_parser.py (original) +++ pypy/dist/pypy/lang/js/test/test_new_parser.py Sat Apr 28 22:58:18 2007 @@ -1,7 +1,7 @@ import py from pypy.rlib.parsing.ebnfparse import parse_ebnf, make_parse_function -from pypy.rlib.parsing.parsing import ParseError +from pypy.rlib.parsing.parsing import ParseError, Rule from pypy.rlib.parsing.tree import RPythonVisitor from pypy import conftest import sys @@ -20,28 +20,28 @@ def setstartrule(rules, start): "takes the rule start and put it on the beginning of the rules" oldpos = 0 - newrules = rules[:] - for n, rule in enumerate(rules): - if rule.nonterminal == start: - oldpos = n - startrule = newrules.pop(oldpos) - newrules.insert(0, startrule) + newrules = [Rule("hacked_first_symbol", [[start, "EOF"]])] + rules return newrules def get_defaultparse(): global parse if parse is None: - parse = make_parse_function(regexs, rules) + parse = make_parse_function(regexs, rules, eof=True) return parse def parse_func(start=None): if start is not None: - parse = make_parse_function(regexs, setstartrule(rules, start)) + parse = make_parse_function(regexs, setstartrule(rules, start), + eof=True) else: parse = get_defaultparse() def methodparse(self, text): - tree = parse(text).visit(ToAST())[0] + tree = parse(text) + if start is not None: + assert tree.symbol == "hacked_first_symbol" + tree = tree.children[0] + tree = tree.visit(ToAST())[0] if conftest.option.view: tree.view() return tree From santagada at codespeak.net Sun Apr 29 20:05:37 2007 From: santagada at codespeak.net (santagada at codespeak.net) Date: Sun, 29 Apr 2007 20:05:37 +0200 (CEST) Subject: [pypy-svn] r42438 - in pypy/dist/pypy/lang/js: . test Message-ID: <20070429180537.E51F88067@code0.codespeak.net> Author: santagada Date: Sun Apr 29 20:05:37 2007 New Revision: 42438 Modified: pypy/dist/pypy/lang/js/jsgrammar.txt pypy/dist/pypy/lang/js/test/test_new_parser.py Log: made the tree evaluator not use python operator priority and made some changes on the grammar to make it really works Modified: pypy/dist/pypy/lang/js/jsgrammar.txt ============================================================================== --- pypy/dist/pypy/lang/js/jsgrammar.txt (original) +++ pypy/dist/pypy/lang/js/jsgrammar.txt Sun Apr 29 20:05:37 2007 @@ -231,7 +231,7 @@ unaryexpression : "delete" unaryexpression | "void" unaryexpression - | "typeof" unaryexpression + | "typeof" unaryexpression | "++" unaryexpression | "--" unaryexpression | "+" unaryexpression @@ -241,57 +241,56 @@ | postfixexpression ; -multiplicativeexpression : unaryexpression "*" multiplicativeexpression - | unaryexpression "/" multiplicativeexpression - | unaryexpression "%" multiplicativeexpression +multiplicativeexpression : unaryexpression "*" >multiplicativeexpression< + | unaryexpression "/" >multiplicativeexpression< + | unaryexpression "%" >multiplicativeexpression< | unaryexpression ; - additiveexpression : multiplicativeexpression "+" >additiveexpression< | multiplicativeexpression "-" >additiveexpression< - | + | multiplicativeexpression ; -shiftexpression : additiveexpression "<<" shiftexpression - | additiveexpression ">>" shiftexpression - | additiveexpression ">>>" shiftexpression +shiftexpression : additiveexpression "<<" >shiftexpression< + | additiveexpression ">>" >shiftexpression< + | additiveexpression ">>>" >shiftexpression< | additiveexpression ; -relationalexpression : shiftexpression "<" relationalexpression - | shiftexpression ">" relationalexpression - | shiftexpression "<=" relationalexpression - | shiftexpression ">=" relationalexpression - | shiftexpression "instanceof" relationalexpression - | shiftexpression "in" relationalexpression +relationalexpression : shiftexpression "<" >relationalexpression< + | shiftexpression ">" >relationalexpression< + | shiftexpression "<=" >relationalexpression< + | shiftexpression ">=" >relationalexpression< + | shiftexpression "instanceof" >relationalexpression< + | shiftexpression "in" >relationalexpression< | shiftexpression ; -equalityexpression : relationalexpression "==" equalityexpression - | relationalexpression "!=" equalityexpression - | relationalexpression "===" equalityexpression - | relationalexpression "!==" equalityexpression +equalityexpression : relationalexpression "==" + | relationalexpression "!=" + | relationalexpression "===" + | relationalexpression "!==" | relationalexpression ; -bitwiseandexpression : equalityexpression "&" bitwiseandexpression +bitwiseandexpression : equalityexpression "&" >bitwiseandexpression< | equalityexpression ; -bitwisexorexpression : bitwiseandexpression "^" bitwisexorexpression +bitwisexorexpression : bitwiseandexpression "^" >bitwisexorexpression< | bitwiseandexpression ; -bitwiseorexpression : bitwisexorexpression "|" bitwiseorexpression +bitwiseorexpression : bitwisexorexpression "|" >bitwiseorexpression< | bitwisexorexpression ; -logicalandexpression : bitwiseorexpression "&&" logicalandexpression +logicalandexpression : bitwiseorexpression "&&" >logicalandexpression< | bitwiseorexpression ; -logicalorexpression : logicalandexpression "||" logicalorexpression +logicalorexpression : logicalandexpression "||" >logicalorexpression< | logicalandexpression ; @@ -317,7 +316,7 @@ "^=" | "\|=" ; -expression : assignmentexpression "," expression +expression : assignmentexpression "," >expression< | assignmentexpression ; Modified: pypy/dist/pypy/lang/js/test/test_new_parser.py ============================================================================== --- pypy/dist/pypy/lang/js/test/test_new_parser.py (original) +++ pypy/dist/pypy/lang/js/test/test_new_parser.py Sun Apr 29 20:05:37 2007 @@ -87,7 +87,11 @@ return self.dispatch(node.children[0]) if len(node.children) >= 3: code = [str(self.dispatch(child)) for child in node.children] - return eval(" ".join(code)) + print code + while len(code) >= 3: + r = eval("%s %s %s"%(code.pop(0), code.pop(0), code.pop(0))) + code.insert(0, r) + return code[0] class TestExpressions(BaseGrammarTest): @@ -113,3 +117,5 @@ self.parse_and_evaluate("1 + 2 * 3") self.parse_and_evaluate("1 * 2 + 3") self.parse_and_evaluate("1 - 3 - 3") + self.parse_and_evaluate("4 / 2 / 2") + From santagada at codespeak.net Sun Apr 29 20:20:45 2007 From: santagada at codespeak.net (santagada at codespeak.net) Date: Sun, 29 Apr 2007 20:20:45 +0200 (CEST) Subject: [pypy-svn] r42439 - pypy/dist/pypy/lang/js/test Message-ID: <20070429182045.55F018067@code0.codespeak.net> Author: santagada Date: Sun Apr 29 20:20:45 2007 New Revision: 42439 Modified: pypy/dist/pypy/lang/js/test/test_new_parser.py Log: simplified test creation and made some tests with shifts and logical ops Modified: pypy/dist/pypy/lang/js/test/test_new_parser.py ============================================================================== --- pypy/dist/pypy/lang/js/test/test_new_parser.py (original) +++ pypy/dist/pypy/lang/js/test/test_new_parser.py Sun Apr 29 20:20:45 2007 @@ -106,16 +106,28 @@ assert result1 == result2 return tree - def test_simple(self): - self.parse_and_evaluate("1") - self.parse_and_evaluate("1 + 2") - self.parse_and_evaluate("1 - 2") - self.parse_and_evaluate("1 * 2") - self.parse_and_evaluate("1 / 2") + def parse_all(self, l): + for i in l: + self.parse_and_evaluate(i) + def test_simple(self): + self.parse_all(["1", + "1 + 2", + "1 - 2", + "1 * 2", + "1 / 2", + "1 >> 2", + "4 % 2", + "4 | 1", + "4 ^ 2", + ]) + def test_chained(self): - self.parse_and_evaluate("1 + 2 * 3") - self.parse_and_evaluate("1 * 2 + 3") - self.parse_and_evaluate("1 - 3 - 3") - self.parse_and_evaluate("4 / 2 / 2") + self.parse_all(["1 + 2 * 3", + "1 * 2 + 3", + "1 - 3 - 3", + "4 / 2 / 2", + "2 << 4 << 4", + "30 | 3 & 5", + ]) From antocuni at codespeak.net Sun Apr 29 20:52:05 2007 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Sun, 29 Apr 2007 20:52:05 +0200 (CEST) Subject: [pypy-svn] r42441 - pypy/dist/pypy/doc/config Message-ID: <20070429185205.1CFC08067@code0.codespeak.net> Author: antocuni Date: Sun Apr 29 20:52:04 2007 New Revision: 42441 Added: pypy/dist/pypy/doc/config/translation.backendopt.stack_optimization.txt (contents, props changed) Log: add doc for the new option Added: pypy/dist/pypy/doc/config/translation.backendopt.stack_optimization.txt ============================================================================== --- (empty file) +++ pypy/dist/pypy/doc/config/translation.backendopt.stack_optimization.txt Sun Apr 29 20:52:04 2007 @@ -0,0 +1 @@ +Enable the optimized code generation for stack based machine, if the backend support it From antocuni at codespeak.net Sun Apr 29 20:52:38 2007 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Sun, 29 Apr 2007 20:52:38 +0200 (CEST) Subject: [pypy-svn] r42442 - pypy/dist/pypy/translator/oosupport/test Message-ID: <20070429185238.539C88067@code0.codespeak.net> Author: antocuni Date: Sun Apr 29 20:52:37 2007 New Revision: 42442 Modified: pypy/dist/pypy/translator/oosupport/test/test_treebuilder.py Log: oops! Modified: pypy/dist/pypy/translator/oosupport/test/test_treebuilder.py ============================================================================== --- pypy/dist/pypy/translator/oosupport/test/test_treebuilder.py (original) +++ pypy/dist/pypy/translator/oosupport/test/test_treebuilder.py Sun Apr 29 20:52:37 2007 @@ -1,3 +1,4 @@ +import py from pypy.rpython.llinterp import LLInterpreter from pypy.translator.translator import TranslationContext, graphof from pypy.translator.oosupport.treebuilder import build_trees, SubOperation From santagada at codespeak.net Sun Apr 29 20:53:39 2007 From: santagada at codespeak.net (santagada at codespeak.net) Date: Sun, 29 Apr 2007 20:53:39 +0200 (CEST) Subject: [pypy-svn] r42443 - pypy/dist/pypy/lang/js/test Message-ID: <20070429185339.E737F8067@code0.codespeak.net> Author: santagada Date: Sun Apr 29 20:53:39 2007 New Revision: 42443 Modified: pypy/dist/pypy/lang/js/test/test_new_parser.py Log: new tests for unary expressions Modified: pypy/dist/pypy/lang/js/test/test_new_parser.py ============================================================================== --- pypy/dist/pypy/lang/js/test/test_new_parser.py (original) +++ pypy/dist/pypy/lang/js/test/test_new_parser.py Sun Apr 29 20:53:39 2007 @@ -74,7 +74,6 @@ self.parse(str(i)).visit(dc) assert dc.counts["DECIMALLITERAL"] == 1 - class IntEvaluationVisitor(RPythonVisitor): def general_symbol_visit(self, node): return node.additional_info @@ -87,11 +86,38 @@ return self.dispatch(node.children[0]) if len(node.children) >= 3: code = [str(self.dispatch(child)) for child in node.children] - print code while len(code) >= 3: - r = eval("%s %s %s"%(code.pop(0), code.pop(0), code.pop(0))) + r = self.evalop(int(code.pop(0)), code.pop(0), int(code.pop(0))) code.insert(0, r) return code[0] + + def visit_unaryexpression(self, node): + if len(node.children) == 1: + return self.dispatch(node.children[0]) + else: + arg1 = self.dispatch(node.children[1]) + op = self.dispatch(node.children[0]) + return self.evalop(arg1,op) + + opmap = {'+': lambda x,y: x+y, + '-': lambda x,y: x-y, + '*': lambda x,y: x*y, + '++': lambda x,y: x+1, + '--': lambda x,y: x-1, + '!': lambda x,y: not x, + '~': lambda x,y: ~ x, + '/': lambda x,y: x / y, + '>>': lambda x,y: x>>y, + '<<': lambda x,y: x< Author: antocuni Date: Sun Apr 29 21:06:07 2007 New Revision: 42444 Modified: pypy/dist/pypy/translator/oosupport/function.py Log: make sure that the database knows about the types involed in each sub-operation Modified: pypy/dist/pypy/translator/oosupport/function.py ============================================================================== --- pypy/dist/pypy/translator/oosupport/function.py (original) +++ pypy/dist/pypy/translator/oosupport/function.py Sun Apr 29 21:06:07 2007 @@ -252,6 +252,12 @@ assert instr_list is not None, 'Unknown opcode: %s ' % op assert isinstance(instr_list, InstructionList) assert instr_list[-1] is StoreResult, "Cannot inline an operation that doesn't store the result" + + # record that we know about the type of result and args + self.cts.lltype_to_cts(op.result.concretetype) + for v in op.args: + self.cts.lltype_to_cts(v.concretetype) + instr_list = InstructionList(instr_list[:-1]) # leave the value on the stack if this is a sub-op instr_list.render(self.generator, op) # now the value is on the stack From santagada at codespeak.net Sun Apr 29 21:34:41 2007 From: santagada at codespeak.net (santagada at codespeak.net) Date: Sun, 29 Apr 2007 21:34:41 +0200 (CEST) Subject: [pypy-svn] r42446 - in pypy/dist/pypy/lang/js: . test test/ecma test/ecma/Array test/ecma/Boolean test/ecma/ExecutionContexts test/ecma/Expressions test/ecma/FunctionObjects test/ecma/GlobalObject test/ecma/LexicalConventions test/ecma/Math test/ecma/NativeObjects test/ecma/Number test/ecma/ObjectObjects test/ecma/SourceText test/ecma/Statements test/ecma/String test/ecma/TypeConversion test/ecma/Types Message-ID: <20070429193441.D4E4E8067@code0.codespeak.net> Author: santagada Date: Sun Apr 29 21:34:39 2007 New Revision: 42446 Modified: pypy/dist/pypy/lang/js/ (props changed) pypy/dist/pypy/lang/js/jsgrammar.txt (props changed) pypy/dist/pypy/lang/js/test/ (props changed) 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/Array/15.4-1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Array/15.4-2.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Array/15.4.1.1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Array/15.4.1.2.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Array/15.4.1.3.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Array/15.4.1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Array/15.4.2.1-1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Array/15.4.2.1-2.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Array/15.4.2.1-3.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Array/15.4.2.2-1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Array/15.4.2.2-2.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Array/15.4.2.3.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Array/15.4.3.1-2.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Array/15.4.3.2.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Array/15.4.3.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Array/15.4.4.1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Array/15.4.4.2.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Array/15.4.4.3-1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Array/15.4.4.4-1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Array/15.4.4.4-2.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Array/15.4.4.5-1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Array/15.4.4.5-2.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Array/15.4.4.5-3.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Array/15.4.4.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Array/15.4.5.1-1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Array/15.4.5.1-2.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Array/15.4.5.2-1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Array/15.4.5.2-2.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Array/browser.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Array/shell.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Boolean/ (props changed) pypy/dist/pypy/lang/js/test/ecma/Boolean/15.6.1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Boolean/15.6.2.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Boolean/15.6.3.1-1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Boolean/15.6.3.1-2.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Boolean/15.6.3.1-3.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Boolean/15.6.3.1-4.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Boolean/15.6.3.1-5.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Boolean/15.6.3.1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Boolean/15.6.3.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Boolean/15.6.4-1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Boolean/15.6.4-2.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Boolean/15.6.4.1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Boolean/15.6.4.2-1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Boolean/15.6.4.2-2.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Boolean/15.6.4.2-3.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Boolean/15.6.4.2-4-n.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Boolean/15.6.4.3-1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Boolean/15.6.4.3-2.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Boolean/15.6.4.3-3.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Boolean/15.6.4.3-4-n.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Boolean/15.6.4.3.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Boolean/15.6.4.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Boolean/browser.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Boolean/shell.js (props changed) pypy/dist/pypy/lang/js/test/ecma/ExecutionContexts/ (props changed) pypy/dist/pypy/lang/js/test/ecma/ExecutionContexts/10.1.3-1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/ExecutionContexts/10.1.3-2.js (props changed) pypy/dist/pypy/lang/js/test/ecma/ExecutionContexts/10.1.3.js (props changed) pypy/dist/pypy/lang/js/test/ecma/ExecutionContexts/10.1.4-1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/ExecutionContexts/10.1.4-10.js (props changed) pypy/dist/pypy/lang/js/test/ecma/ExecutionContexts/10.1.4-2.js (props changed) pypy/dist/pypy/lang/js/test/ecma/ExecutionContexts/10.1.4-3.js (props changed) pypy/dist/pypy/lang/js/test/ecma/ExecutionContexts/10.1.4-4.js (props changed) pypy/dist/pypy/lang/js/test/ecma/ExecutionContexts/10.1.4-5.js (props changed) pypy/dist/pypy/lang/js/test/ecma/ExecutionContexts/10.1.4-6.js (props changed) pypy/dist/pypy/lang/js/test/ecma/ExecutionContexts/10.1.4-7.js (props changed) pypy/dist/pypy/lang/js/test/ecma/ExecutionContexts/10.1.4-8.js (props changed) pypy/dist/pypy/lang/js/test/ecma/ExecutionContexts/10.1.4-9.js (props changed) pypy/dist/pypy/lang/js/test/ecma/ExecutionContexts/10.1.5-1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/ExecutionContexts/10.1.5-2.js (props changed) pypy/dist/pypy/lang/js/test/ecma/ExecutionContexts/10.1.5-3.js (props changed) pypy/dist/pypy/lang/js/test/ecma/ExecutionContexts/10.1.5-4.js (props changed) pypy/dist/pypy/lang/js/test/ecma/ExecutionContexts/10.1.6.js (props changed) pypy/dist/pypy/lang/js/test/ecma/ExecutionContexts/10.1.8-1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/ExecutionContexts/10.1.8-2.js (props changed) pypy/dist/pypy/lang/js/test/ecma/ExecutionContexts/10.2.1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/ExecutionContexts/10.2.2-1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/ExecutionContexts/10.2.2-2.js (props changed) pypy/dist/pypy/lang/js/test/ecma/ExecutionContexts/10.2.3-1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/ExecutionContexts/10.2.3-2.js (props changed) pypy/dist/pypy/lang/js/test/ecma/ExecutionContexts/browser.js (props changed) pypy/dist/pypy/lang/js/test/ecma/ExecutionContexts/shell.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Expressions/ (props changed) pypy/dist/pypy/lang/js/test/ecma/Expressions/11.1.1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Expressions/11.10-1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Expressions/11.10-2.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Expressions/11.10-3.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Expressions/11.12-1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Expressions/11.12-2-n.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Expressions/11.12-3.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Expressions/11.12-4.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Expressions/11.13.1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Expressions/11.13.2-1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Expressions/11.13.2-2.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Expressions/11.13.2-3.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Expressions/11.13.2-4.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Expressions/11.13.2-5.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Expressions/11.13.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Expressions/11.14-1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Expressions/11.2.1-1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Expressions/11.2.1-2.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Expressions/11.2.1-3-n.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Expressions/11.2.1-4-n.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Expressions/11.2.1-5.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Expressions/11.2.2-1-n.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Expressions/11.2.2-1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Expressions/11.2.2-10-n.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Expressions/11.2.2-11.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Expressions/11.2.2-2-n.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Expressions/11.2.2-3-n.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Expressions/11.2.2-4-n.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Expressions/11.2.2-5-n.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Expressions/11.2.2-6-n.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Expressions/11.2.2-7-n.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Expressions/11.2.2-8-n.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Expressions/11.2.2-9-n.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Expressions/11.2.3-1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Expressions/11.2.3-2-n.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Expressions/11.2.3-3-n.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Expressions/11.2.3-4-n.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Expressions/11.2.3-5.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Expressions/11.3.1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Expressions/11.3.2.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Expressions/11.4.1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Expressions/11.4.2.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Expressions/11.4.3.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Expressions/11.4.4.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Expressions/11.4.5.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Expressions/11.4.6.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Expressions/11.4.8.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Expressions/11.4.9.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Expressions/11.5.1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Expressions/11.5.2.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Expressions/11.5.3.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Expressions/11.6.1-1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Expressions/11.6.1-2.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Expressions/11.6.1-3.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Expressions/11.6.2-1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Expressions/11.6.3.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Expressions/11.7.1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Expressions/11.7.2.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Expressions/11.7.3.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Expressions/11.8.1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Expressions/11.8.2.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Expressions/11.8.3.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Expressions/11.8.4.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Expressions/11.9.1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Expressions/11.9.2.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Expressions/11.9.3.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Expressions/browser.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Expressions/shell.js (props changed) pypy/dist/pypy/lang/js/test/ecma/FunctionObjects/ (props changed) pypy/dist/pypy/lang/js/test/ecma/FunctionObjects/15.3.1.1-1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/FunctionObjects/15.3.1.1-2.js (props changed) pypy/dist/pypy/lang/js/test/ecma/FunctionObjects/15.3.1.1-3.js (props changed) pypy/dist/pypy/lang/js/test/ecma/FunctionObjects/15.3.2.1-1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/FunctionObjects/15.3.2.1-2.js (props changed) pypy/dist/pypy/lang/js/test/ecma/FunctionObjects/15.3.2.1-3.js (props changed) pypy/dist/pypy/lang/js/test/ecma/FunctionObjects/15.3.3.1-1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/FunctionObjects/15.3.3.1-2.js (props changed) pypy/dist/pypy/lang/js/test/ecma/FunctionObjects/15.3.3.1-3.js (props changed) pypy/dist/pypy/lang/js/test/ecma/FunctionObjects/15.3.3.1-4.js (props changed) pypy/dist/pypy/lang/js/test/ecma/FunctionObjects/15.3.3.2.js (props changed) pypy/dist/pypy/lang/js/test/ecma/FunctionObjects/15.3.4-1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/FunctionObjects/15.3.4.1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/FunctionObjects/15.3.4.js (props changed) pypy/dist/pypy/lang/js/test/ecma/FunctionObjects/15.3.5-1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/FunctionObjects/15.3.5-2.js (props changed) pypy/dist/pypy/lang/js/test/ecma/FunctionObjects/15.3.5.1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/FunctionObjects/15.3.5.3.js (props changed) pypy/dist/pypy/lang/js/test/ecma/FunctionObjects/browser.js (props changed) pypy/dist/pypy/lang/js/test/ecma/FunctionObjects/shell.js (props changed) pypy/dist/pypy/lang/js/test/ecma/GlobalObject/ (props changed) pypy/dist/pypy/lang/js/test/ecma/GlobalObject/15.1-1-n.js (props changed) pypy/dist/pypy/lang/js/test/ecma/GlobalObject/15.1-2-n.js (props changed) pypy/dist/pypy/lang/js/test/ecma/GlobalObject/15.1.1.1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/GlobalObject/15.1.1.2.js (props changed) pypy/dist/pypy/lang/js/test/ecma/GlobalObject/15.1.2.1-1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/GlobalObject/15.1.2.1-2.js (props changed) pypy/dist/pypy/lang/js/test/ecma/GlobalObject/15.1.2.2-1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/GlobalObject/15.1.2.2-2.js (props changed) pypy/dist/pypy/lang/js/test/ecma/GlobalObject/15.1.2.3-1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/GlobalObject/15.1.2.3-2.js (props changed) pypy/dist/pypy/lang/js/test/ecma/GlobalObject/15.1.2.4.js (props changed) pypy/dist/pypy/lang/js/test/ecma/GlobalObject/15.1.2.5-1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/GlobalObject/15.1.2.5-2.js (props changed) pypy/dist/pypy/lang/js/test/ecma/GlobalObject/15.1.2.5-3.js (props changed) pypy/dist/pypy/lang/js/test/ecma/GlobalObject/15.1.2.6.js (props changed) pypy/dist/pypy/lang/js/test/ecma/GlobalObject/15.1.2.7.js (props changed) pypy/dist/pypy/lang/js/test/ecma/GlobalObject/browser.js (props changed) pypy/dist/pypy/lang/js/test/ecma/GlobalObject/shell.js (props changed) pypy/dist/pypy/lang/js/test/ecma/LexicalConventions/ (props changed) pypy/dist/pypy/lang/js/test/ecma/LexicalConventions/7.1-1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/LexicalConventions/7.1-2.js (props changed) pypy/dist/pypy/lang/js/test/ecma/LexicalConventions/7.1-3.js (props changed) pypy/dist/pypy/lang/js/test/ecma/LexicalConventions/7.2-1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/LexicalConventions/7.2-2-n.js (props changed) pypy/dist/pypy/lang/js/test/ecma/LexicalConventions/7.2-3-n.js (props changed) pypy/dist/pypy/lang/js/test/ecma/LexicalConventions/7.2-4-n.js (props changed) pypy/dist/pypy/lang/js/test/ecma/LexicalConventions/7.2-5-n.js (props changed) pypy/dist/pypy/lang/js/test/ecma/LexicalConventions/7.2-6.js (props changed) pypy/dist/pypy/lang/js/test/ecma/LexicalConventions/7.3-1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/LexicalConventions/7.3-10.js (props changed) pypy/dist/pypy/lang/js/test/ecma/LexicalConventions/7.3-11.js (props changed) pypy/dist/pypy/lang/js/test/ecma/LexicalConventions/7.3-12.js (props changed) pypy/dist/pypy/lang/js/test/ecma/LexicalConventions/7.3-13-n.js (props changed) pypy/dist/pypy/lang/js/test/ecma/LexicalConventions/7.3-2.js (props changed) pypy/dist/pypy/lang/js/test/ecma/LexicalConventions/7.3-3.js (props changed) pypy/dist/pypy/lang/js/test/ecma/LexicalConventions/7.3-4.js (props changed) pypy/dist/pypy/lang/js/test/ecma/LexicalConventions/7.3-5.js (props changed) pypy/dist/pypy/lang/js/test/ecma/LexicalConventions/7.3-6.js (props changed) pypy/dist/pypy/lang/js/test/ecma/LexicalConventions/7.3-7.js (props changed) pypy/dist/pypy/lang/js/test/ecma/LexicalConventions/7.3-8.js (props changed) pypy/dist/pypy/lang/js/test/ecma/LexicalConventions/7.3-9.js (props changed) pypy/dist/pypy/lang/js/test/ecma/LexicalConventions/7.4.1-1-n.js (props changed) pypy/dist/pypy/lang/js/test/ecma/LexicalConventions/7.4.1-2-n.js (props changed) pypy/dist/pypy/lang/js/test/ecma/LexicalConventions/7.4.1-3-n.js (props changed) pypy/dist/pypy/lang/js/test/ecma/LexicalConventions/7.4.2-1-n.js (props changed) pypy/dist/pypy/lang/js/test/ecma/LexicalConventions/7.4.2-10-n.js (props changed) pypy/dist/pypy/lang/js/test/ecma/LexicalConventions/7.4.2-11-n.js (props changed) pypy/dist/pypy/lang/js/test/ecma/LexicalConventions/7.4.2-12-n.js (props changed) pypy/dist/pypy/lang/js/test/ecma/LexicalConventions/7.4.2-13-n.js (props changed) pypy/dist/pypy/lang/js/test/ecma/LexicalConventions/7.4.2-14-n.js (props changed) pypy/dist/pypy/lang/js/test/ecma/LexicalConventions/7.4.2-15-n.js (props changed) pypy/dist/pypy/lang/js/test/ecma/LexicalConventions/7.4.2-16-n.js (props changed) pypy/dist/pypy/lang/js/test/ecma/LexicalConventions/7.4.2-2-n.js (props changed) pypy/dist/pypy/lang/js/test/ecma/LexicalConventions/7.4.2-3-n.js (props changed) pypy/dist/pypy/lang/js/test/ecma/LexicalConventions/7.4.2-4-n.js (props changed) pypy/dist/pypy/lang/js/test/ecma/LexicalConventions/7.4.2-5-n.js (props changed) pypy/dist/pypy/lang/js/test/ecma/LexicalConventions/7.4.2-6-n.js (props changed) pypy/dist/pypy/lang/js/test/ecma/LexicalConventions/7.4.2-7-n.js (props changed) pypy/dist/pypy/lang/js/test/ecma/LexicalConventions/7.4.2-8-n.js (props changed) pypy/dist/pypy/lang/js/test/ecma/LexicalConventions/7.4.2-9-n.js (props changed) pypy/dist/pypy/lang/js/test/ecma/LexicalConventions/7.4.3-1-n.js (props changed) pypy/dist/pypy/lang/js/test/ecma/LexicalConventions/7.4.3-10-n.js (props changed) pypy/dist/pypy/lang/js/test/ecma/LexicalConventions/7.4.3-11-n.js (props changed) pypy/dist/pypy/lang/js/test/ecma/LexicalConventions/7.4.3-12-n.js (props changed) pypy/dist/pypy/lang/js/test/ecma/LexicalConventions/7.4.3-13-n.js (props changed) pypy/dist/pypy/lang/js/test/ecma/LexicalConventions/7.4.3-14-n.js (props changed) pypy/dist/pypy/lang/js/test/ecma/LexicalConventions/7.4.3-15-n.js (props changed) pypy/dist/pypy/lang/js/test/ecma/LexicalConventions/7.4.3-16-n.js (props changed) pypy/dist/pypy/lang/js/test/ecma/LexicalConventions/7.4.3-2-n.js (props changed) pypy/dist/pypy/lang/js/test/ecma/LexicalConventions/7.4.3-3-n.js (props changed) pypy/dist/pypy/lang/js/test/ecma/LexicalConventions/7.4.3-4-n.js (props changed) pypy/dist/pypy/lang/js/test/ecma/LexicalConventions/7.4.3-5-n.js (props changed) pypy/dist/pypy/lang/js/test/ecma/LexicalConventions/7.4.3-6-n.js (props changed) pypy/dist/pypy/lang/js/test/ecma/LexicalConventions/7.4.3-7-n.js (props changed) pypy/dist/pypy/lang/js/test/ecma/LexicalConventions/7.4.3-8-n.js (props changed) pypy/dist/pypy/lang/js/test/ecma/LexicalConventions/7.4.3-9-n.js (props changed) pypy/dist/pypy/lang/js/test/ecma/LexicalConventions/7.5-1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/LexicalConventions/7.5-10-n.js (props changed) pypy/dist/pypy/lang/js/test/ecma/LexicalConventions/7.5-2-n.js (props changed) pypy/dist/pypy/lang/js/test/ecma/LexicalConventions/7.5-3-n.js (props changed) pypy/dist/pypy/lang/js/test/ecma/LexicalConventions/7.5-4-n.js (props changed) pypy/dist/pypy/lang/js/test/ecma/LexicalConventions/7.5-5-n.js (props changed) pypy/dist/pypy/lang/js/test/ecma/LexicalConventions/7.5-6.js (props changed) pypy/dist/pypy/lang/js/test/ecma/LexicalConventions/7.5-7.js (props changed) pypy/dist/pypy/lang/js/test/ecma/LexicalConventions/7.5-8-n.js (props changed) pypy/dist/pypy/lang/js/test/ecma/LexicalConventions/7.5-9-n.js (props changed) pypy/dist/pypy/lang/js/test/ecma/LexicalConventions/7.6.js (props changed) pypy/dist/pypy/lang/js/test/ecma/LexicalConventions/7.7.1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/LexicalConventions/7.7.2.js (props changed) pypy/dist/pypy/lang/js/test/ecma/LexicalConventions/7.7.3-1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/LexicalConventions/7.7.3-2.js (props changed) pypy/dist/pypy/lang/js/test/ecma/LexicalConventions/7.7.3.js (props changed) pypy/dist/pypy/lang/js/test/ecma/LexicalConventions/7.7.4.js (props changed) pypy/dist/pypy/lang/js/test/ecma/LexicalConventions/7.8.2-n.js (props changed) pypy/dist/pypy/lang/js/test/ecma/LexicalConventions/browser.js (props changed) pypy/dist/pypy/lang/js/test/ecma/LexicalConventions/shell.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Math/ (props changed) pypy/dist/pypy/lang/js/test/ecma/Math/15.8-1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Math/15.8-2-n.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Math/15.8-3-n.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Math/15.8.1.1-1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Math/15.8.1.1-2.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Math/15.8.1.2-1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Math/15.8.1.2-2.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Math/15.8.1.3-1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Math/15.8.1.3-2.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Math/15.8.1.4-1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Math/15.8.1.4-2.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Math/15.8.1.5-1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Math/15.8.1.5-2.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Math/15.8.1.6-1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Math/15.8.1.6-2.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Math/15.8.1.7-1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Math/15.8.1.7-2.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Math/15.8.1.8-1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Math/15.8.1.8-2.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Math/15.8.1.8-3.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Math/15.8.1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Math/15.8.2.1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Math/15.8.2.10.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Math/15.8.2.11.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Math/15.8.2.12.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Math/15.8.2.13.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Math/15.8.2.14.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Math/15.8.2.15.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Math/15.8.2.16.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Math/15.8.2.17.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Math/15.8.2.18.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Math/15.8.2.2.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Math/15.8.2.3.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Math/15.8.2.4.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Math/15.8.2.5.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Math/15.8.2.6.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Math/15.8.2.7.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Math/15.8.2.8.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Math/15.8.2.9.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Math/browser.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Math/shell.js (props changed) pypy/dist/pypy/lang/js/test/ecma/NativeObjects/ (props changed) pypy/dist/pypy/lang/js/test/ecma/NativeObjects/15-1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/NativeObjects/15-2.js (props changed) pypy/dist/pypy/lang/js/test/ecma/NativeObjects/browser.js (props changed) pypy/dist/pypy/lang/js/test/ecma/NativeObjects/shell.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Number/ (props changed) pypy/dist/pypy/lang/js/test/ecma/Number/15.7.1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Number/15.7.2.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Number/15.7.3.1-1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Number/15.7.3.1-2.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Number/15.7.3.1-3.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Number/15.7.3.2-1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Number/15.7.3.2-2.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Number/15.7.3.2-3.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Number/15.7.3.2-4.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Number/15.7.3.3-1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Number/15.7.3.3-2.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Number/15.7.3.3-3.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Number/15.7.3.3-4.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Number/15.7.3.4-1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Number/15.7.3.4-2.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Number/15.7.3.4-3.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Number/15.7.3.4-4.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Number/15.7.3.5-1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Number/15.7.3.5-2.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Number/15.7.3.5-3.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Number/15.7.3.5-4.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Number/15.7.3.6-1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Number/15.7.3.6-2.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Number/15.7.3.6-3.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Number/15.7.3.6-4.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Number/15.7.3.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Number/15.7.4-1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Number/15.7.4.1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Number/15.7.4.2-1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Number/15.7.4.2-2-n.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Number/15.7.4.2-3-n.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Number/15.7.4.2-4.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Number/15.7.4.3-1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Number/15.7.4.3-2.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Number/15.7.4.3-3-n.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Number/15.7.4.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Number/browser.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Number/shell.js (props changed) pypy/dist/pypy/lang/js/test/ecma/ObjectObjects/ (props changed) pypy/dist/pypy/lang/js/test/ecma/ObjectObjects/15.2.1.1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/ObjectObjects/15.2.1.2.js (props changed) pypy/dist/pypy/lang/js/test/ecma/ObjectObjects/15.2.2.1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/ObjectObjects/15.2.2.2.js (props changed) pypy/dist/pypy/lang/js/test/ecma/ObjectObjects/15.2.3-1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/ObjectObjects/15.2.3.1-1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/ObjectObjects/15.2.3.1-2.js (props changed) pypy/dist/pypy/lang/js/test/ecma/ObjectObjects/15.2.3.1-3.js (props changed) pypy/dist/pypy/lang/js/test/ecma/ObjectObjects/15.2.3.1-4.js (props changed) pypy/dist/pypy/lang/js/test/ecma/ObjectObjects/15.2.3.js (props changed) pypy/dist/pypy/lang/js/test/ecma/ObjectObjects/15.2.4.1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/ObjectObjects/15.2.4.2.js (props changed) pypy/dist/pypy/lang/js/test/ecma/ObjectObjects/15.2.4.3.js (props changed) pypy/dist/pypy/lang/js/test/ecma/ObjectObjects/15.2.4.js (props changed) pypy/dist/pypy/lang/js/test/ecma/ObjectObjects/browser.js (props changed) pypy/dist/pypy/lang/js/test/ecma/ObjectObjects/shell.js (props changed) pypy/dist/pypy/lang/js/test/ecma/SourceText/ (props changed) pypy/dist/pypy/lang/js/test/ecma/SourceText/6-1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/SourceText/6-2.js (props changed) pypy/dist/pypy/lang/js/test/ecma/SourceText/browser.js (props changed) pypy/dist/pypy/lang/js/test/ecma/SourceText/shell.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Statements/ (props changed) pypy/dist/pypy/lang/js/test/ecma/Statements/12.10-1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Statements/12.10.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Statements/12.2-1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Statements/12.5-1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Statements/12.5-2.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Statements/12.6.1-1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Statements/12.6.2-1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Statements/12.6.2-2.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Statements/12.6.2-3.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Statements/12.6.2-4.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Statements/12.6.2-5.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Statements/12.6.2-6.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Statements/12.6.2-7.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Statements/12.6.2-8.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Statements/12.6.2-9-n.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Statements/12.6.3-1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Statements/12.6.3-10.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Statements/12.6.3-11.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Statements/12.6.3-12.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Statements/12.6.3-19.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Statements/12.6.3-2.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Statements/12.6.3-3.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Statements/12.6.3-4.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Statements/12.6.3-5-n.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Statements/12.6.3-6-n.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Statements/12.6.3-7-n.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Statements/12.6.3-8-n.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Statements/12.6.3-9-n.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Statements/12.7-1-n.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Statements/12.8-1-n.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Statements/12.9-1-n.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Statements/browser.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Statements/shell.js (props changed) pypy/dist/pypy/lang/js/test/ecma/String/ (props changed) pypy/dist/pypy/lang/js/test/ecma/String/15.5.1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/String/15.5.2.js (props changed) pypy/dist/pypy/lang/js/test/ecma/String/15.5.3.1-1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/String/15.5.3.1-2.js (props changed) pypy/dist/pypy/lang/js/test/ecma/String/15.5.3.1-3.js (props changed) pypy/dist/pypy/lang/js/test/ecma/String/15.5.3.1-4.js (props changed) pypy/dist/pypy/lang/js/test/ecma/String/15.5.3.2-1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/String/15.5.3.2-2.js (props changed) pypy/dist/pypy/lang/js/test/ecma/String/15.5.3.2-3.js (props changed) pypy/dist/pypy/lang/js/test/ecma/String/15.5.3.js (props changed) pypy/dist/pypy/lang/js/test/ecma/String/15.5.4.1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/String/15.5.4.10-1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/String/15.5.4.11-1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/String/15.5.4.11-2.js (props changed) pypy/dist/pypy/lang/js/test/ecma/String/15.5.4.11-3.js (props changed) pypy/dist/pypy/lang/js/test/ecma/String/15.5.4.11-4.js (props changed) pypy/dist/pypy/lang/js/test/ecma/String/15.5.4.11-5.js (props changed) pypy/dist/pypy/lang/js/test/ecma/String/15.5.4.11-6.js (props changed) pypy/dist/pypy/lang/js/test/ecma/String/15.5.4.12-1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/String/15.5.4.12-2.js (props changed) pypy/dist/pypy/lang/js/test/ecma/String/15.5.4.12-3.js (props changed) pypy/dist/pypy/lang/js/test/ecma/String/15.5.4.12-4.js (props changed) pypy/dist/pypy/lang/js/test/ecma/String/15.5.4.12-5.js (props changed) pypy/dist/pypy/lang/js/test/ecma/String/15.5.4.2-1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/String/15.5.4.2-2-n.js (props changed) pypy/dist/pypy/lang/js/test/ecma/String/15.5.4.2-3.js (props changed) pypy/dist/pypy/lang/js/test/ecma/String/15.5.4.2.js (props changed) pypy/dist/pypy/lang/js/test/ecma/String/15.5.4.3-1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/String/15.5.4.3-2.js (props changed) pypy/dist/pypy/lang/js/test/ecma/String/15.5.4.3-3-n.js (props changed) pypy/dist/pypy/lang/js/test/ecma/String/15.5.4.4-1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/String/15.5.4.4-2.js (props changed) pypy/dist/pypy/lang/js/test/ecma/String/15.5.4.4-3.js (props changed) pypy/dist/pypy/lang/js/test/ecma/String/15.5.4.4-4.js (props changed) pypy/dist/pypy/lang/js/test/ecma/String/15.5.4.5-1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/String/15.5.4.5-2.js (props changed) pypy/dist/pypy/lang/js/test/ecma/String/15.5.4.5-3.js (props changed) pypy/dist/pypy/lang/js/test/ecma/String/15.5.4.5-4.js (props changed) pypy/dist/pypy/lang/js/test/ecma/String/15.5.4.5-5.js (props changed) pypy/dist/pypy/lang/js/test/ecma/String/15.5.4.5-6.js (props changed) pypy/dist/pypy/lang/js/test/ecma/String/15.5.4.6-1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/String/15.5.4.6-2.js (props changed) pypy/dist/pypy/lang/js/test/ecma/String/15.5.4.7-1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/String/15.5.4.7-2.js (props changed) pypy/dist/pypy/lang/js/test/ecma/String/15.5.4.7-3.js (props changed) pypy/dist/pypy/lang/js/test/ecma/String/15.5.4.8-1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/String/15.5.4.8-2.js (props changed) pypy/dist/pypy/lang/js/test/ecma/String/15.5.4.8-3.js (props changed) pypy/dist/pypy/lang/js/test/ecma/String/15.5.4.9-1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/String/15.5.4.js (props changed) pypy/dist/pypy/lang/js/test/ecma/String/15.5.5.1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/String/browser.js (props changed) pypy/dist/pypy/lang/js/test/ecma/String/shell.js (props changed) pypy/dist/pypy/lang/js/test/ecma/TypeConversion/ (props changed) pypy/dist/pypy/lang/js/test/ecma/TypeConversion/9.2.js (props changed) pypy/dist/pypy/lang/js/test/ecma/TypeConversion/9.3-1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/TypeConversion/9.3.1-1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/TypeConversion/9.3.1-2.js (props changed) pypy/dist/pypy/lang/js/test/ecma/TypeConversion/9.3.1-3.js (props changed) pypy/dist/pypy/lang/js/test/ecma/TypeConversion/9.3.js (props changed) pypy/dist/pypy/lang/js/test/ecma/TypeConversion/9.4-1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/TypeConversion/9.4-2.js (props changed) pypy/dist/pypy/lang/js/test/ecma/TypeConversion/9.5-2.js (props changed) pypy/dist/pypy/lang/js/test/ecma/TypeConversion/9.6.js (props changed) pypy/dist/pypy/lang/js/test/ecma/TypeConversion/9.7.js (props changed) pypy/dist/pypy/lang/js/test/ecma/TypeConversion/9.8.1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/TypeConversion/9.9-1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/TypeConversion/browser.js (props changed) pypy/dist/pypy/lang/js/test/ecma/TypeConversion/shell.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Types/ (props changed) pypy/dist/pypy/lang/js/test/ecma/Types/8.1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Types/8.4.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Types/8.6.2.1-1.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Types/browser.js (props changed) pypy/dist/pypy/lang/js/test/ecma/Types/shell.js (props changed) pypy/dist/pypy/lang/js/test/ecma/shell.js (props changed) pypy/dist/pypy/lang/js/test/test_new_parser.py (props changed) Log: fixeol and svn:ignores everywhere, and some more tests From cfbolz at codespeak.net Sun Apr 29 22:52:38 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sun, 29 Apr 2007 22:52:38 +0200 (CEST) Subject: [pypy-svn] r42449 - in pypy/dist/pypy/lang/js: . test Message-ID: <20070429205238.EBA278067@code0.codespeak.net> Author: cfbolz Date: Sun Apr 29 22:52:37 2007 New Revision: 42449 Modified: pypy/dist/pypy/lang/js/jsgrammar.txt pypy/dist/pypy/lang/js/test/test_new_parser.py Log: make the grammar produce nicer trees for the case of expressions. now running the test with --view is really cool :-) Modified: pypy/dist/pypy/lang/js/jsgrammar.txt ============================================================================== --- pypy/dist/pypy/lang/js/jsgrammar.txt (original) +++ pypy/dist/pypy/lang/js/jsgrammar.txt Sun Apr 29 22:52:37 2007 @@ -13,33 +13,33 @@ | statement ; -statement : block - | variablestatement [";"] +statement : + | [";"] | [ ";" ] - | expressionstatement [";"] - | ifstatement [";"] - | iterationstatement [";"] - | continuestatement [";"] - | breakstatement [";"] - | returnstatement [";"] - | withstatement [";"] - | labelledstatement [";"] - | switchstatement - | throwstatement [";"] - | trystatement [";"] + | [";"] + | [";"] + | [";"] + | [";"] + | [";"] + | [";"] + | [";"] + | [";"] + | + | [";"] + | [";"] ; block : "{" statementlist? "}" ; -statementlist : statement statementlist +statementlist : statement >statementlist< | statement ; variablestatement : ["var"] variabledeclarationlist ; -variabledeclarationlist : variabledeclaration [","] variabledeclarationlist +variabledeclarationlist : variabledeclaration [","] >variabledeclarationlist< | variabledeclaration ; @@ -87,6 +87,7 @@ | ["{"] caseclauses? ["}"] ; +# XXX this looks wrong to me caseclauses : caseclause caseclauses ; @@ -110,14 +111,14 @@ finally : ["finally"] block ; -identifier : IDENTIFIERNAME; +identifier : ; IDENTIFIERNAME : "[a-zA-Z_$][a-zA-Z_0-9]*"; -literal : nullliteral - | booleanliteral - | numericliteral - | stringliteral +literal : + | + | + | ; nullliteral : "null"; @@ -126,8 +127,8 @@ | "false" ; -numericliteral : DECIMALLITERAL - | HEXINTEGERLITERAL +numericliteral : + | ; DECIMALLITERAL : "(((0|[1-9][0-9]*)(\.[0-9]*)?)|(\.[0-9]+))([eE][\+\-]?[0-9]*)?" @@ -136,8 +137,8 @@ HEXINTEGERLITERAL : "0[xX][0-9a-fA-F]+" ; -stringliteral : SINGLESTRING - | DOUBLESTRING +stringliteral : + | ; SINGLESTRING : "'([^']|\\')*'" @@ -147,15 +148,15 @@ ; primaryexpression : "this" - | identifier - | literal - | arrayliteral - | objectliteral - | "\(" expression "\)" + | + | + | + | + | "\(" "\)" ; -arrayliteral : "[" elementlist "]" - | "[" elementlist "," "]" +arrayliteral : ["["] elementlist ["]"] + | ["["] elementlist ["," "]"] ; elementlist : assignmentexpression ("," assignmentexpression)* @@ -174,9 +175,9 @@ hpropertynameandvaluelist : propertyname ":" assignmentexpression "," ; -propertyname : identifier - | stringliteral - | numericliteral +propertyname : + | + | ; functiondeclaration : "function" identifier "(" formalparameterlist? ")" "{" functionbody "}" @@ -185,25 +186,25 @@ functionexpression : "function" identifier? "(" formalparameterlist? ")" "{" functionbody "}" ; -formalparameterlist : identifier "," formalparameterlist +formalparameterlist : identifier [","] >formalparameterlist< | identifier ; functionbody : sourceelements ; -begmemberexpression : primaryexpression - | functionexpression +begmemberexpression : + | ; memberexpression : begmemberexpression "[" expression "]" memberexpression* | begmemberexpression "." identifier memberexpression* | "new" memberexpression arguments - | begmemberexpression + | ; newexpression : "new" newexpression - | memberexpression + | ; callexpression : memberexpression arguments arguments callexpression* @@ -216,17 +217,16 @@ | "(" argumentlist ")" ; -argumentlist : assignmentexpression - | assignmentexpression "," argumentlist - ; +argumentlist : assignmentexpression "," >argumentlist< + | assignmentexpression; -lefthandsideexpression : callexpression - | newexpression +lefthandsideexpression : + | ; postfixexpression : lefthandsideexpression "++" | lefthandsideexpression "--" - | lefthandsideexpression + | ; unaryexpression : "delete" unaryexpression @@ -234,73 +234,63 @@ | "typeof" unaryexpression | "++" unaryexpression | "--" unaryexpression - | "+" unaryexpression - | "-" unaryexpression + | PLM unaryexpression | "~" unaryexpression | "!" unaryexpression - | postfixexpression + | ; -multiplicativeexpression : unaryexpression "*" >multiplicativeexpression< - | unaryexpression "/" >multiplicativeexpression< - | unaryexpression "%" >multiplicativeexpression< - | unaryexpression +multop: "*" | "/" | "%"; +multiplicativeexpression : unaryexpression (multop unaryexpression)+ + | ; - -additiveexpression : multiplicativeexpression "+" >additiveexpression< - | multiplicativeexpression "-" >additiveexpression< - | multiplicativeexpression +PLM : "\+|\-"; +additiveexpression : multiplicativeexpression (PLM multiplicativeexpression)+ + | ; -shiftexpression : additiveexpression "<<" >shiftexpression< - | additiveexpression ">>" >shiftexpression< - | additiveexpression ">>>" >shiftexpression< - | additiveexpression +shiftop: "<<" | ">>" | ">>>"; +shiftexpression : additiveexpression (shiftop additiveexpression)+ + | ; -relationalexpression : shiftexpression "<" >relationalexpression< - | shiftexpression ">" >relationalexpression< - | shiftexpression "<=" >relationalexpression< - | shiftexpression ">=" >relationalexpression< - | shiftexpression "instanceof" >relationalexpression< - | shiftexpression "in" >relationalexpression< - | shiftexpression +relationalop: "<" | ">" | "<=" | ">=" | "instanceof" | "in"; +relationalexpression : shiftexpression (relationalop relationalexpression)+ + | ; -equalityexpression : relationalexpression "==" - | relationalexpression "!=" - | relationalexpression "===" - | relationalexpression "!==" - | relationalexpression +equalityop: "==" | "!=" | "===" | "!=="; +equalityexpression : relationalexpression (equalityop relationalexpression)+ + | ; -bitwiseandexpression : equalityexpression "&" >bitwiseandexpression< - | equalityexpression +bitwiseandexpression : equalityexpression ("&" equalityexpression)+ + | ; -bitwisexorexpression : bitwiseandexpression "^" >bitwisexorexpression< - | bitwiseandexpression +bitwisexorexpression : bitwiseandexpression ("^" bitwiseandexpression)+ + | ; -bitwiseorexpression : bitwisexorexpression "|" >bitwiseorexpression< - | bitwisexorexpression +bitwiseorexpression : bitwisexorexpression ("|" bitwisexorexpression)+ + | ; -logicalandexpression : bitwiseorexpression "&&" >logicalandexpression< - | bitwiseorexpression +logicalandexpression : bitwiseorexpression ("&&" bitwiseorexpression)+ + | ; -logicalorexpression : logicalandexpression "||" >logicalorexpression< - | logicalandexpression +logicalorexpression : logicalandexpression ("||" logicalandexpression)+ + | ; conditionalexpression : logicalorexpression "?" assignmentexpression ":" assignmentexpression - | logicalorexpression + | ; assignmentexpression : lefthandsideexpression assignmentoperator assignmentexpression - | conditionalexpression + | ; assignmentoperator: "=" | @@ -316,75 +306,54 @@ "^=" | "\|=" ; -expression : assignmentexpression "," >expression< - | assignmentexpression +expression : assignmentexpression ([","] assignmentexpression)+ + | ; #noin copy -relationalexpressionnoin : shiftexpression "<" relationalexpression - | shiftexpression ">" relationalexpression - | shiftexpression "<=" relationalexpression - | shiftexpression ">=" relationalexpression - | shiftexpression "instanceof" relationalexpression -# | shiftexpression "in" relationalexpression - | shiftexpression +relationalopnoin: "<" | ">" | "<=" | ">=" | "instanceof"; +relationalexpressionnoin : shiftexpression (relationalopnoin shiftexpression)+ + | ; - -equalityexpressionnoin : relationalexpressionnoin "==" equalityexpressionnoin - | relationalexpressionnoin "!=" equalityexpressionnoin - | relationalexpressionnoin "===" equalityexpressionnoin - | relationalexpressionnoin "!==" equalityexpressionnoin - | relationalexpressionnoin +equalityexpressionnoin : relationalexpressionnoin (equalityop equalityexpressionnoin)+ + | ; -bitwiseandexpressionnoin : equalityexpressionnoin "&" bitwiseandexpressionnoin - | equalityexpressionnoin +bitwiseandexpressionnoin : equalityexpressionnoin ("&" equalityexpressionnoin)+ + | ; -bitwisexorexpressionnoin : bitwiseandexpressionnoin "^" bitwisexorexpressionnoin - | bitwiseandexpressionnoin +bitwisexorexpressionnoin : bitwiseandexpressionnoin ("^" bitwiseandexpressionnoin)+ + | ; -bitwiseorexpressionnoin : bitwisexorexpressionnoin "|" bitwiseorexpressionnoin - | bitwisexorexpressionnoin +bitwiseorexpressionnoin : bitwisexorexpressionnoin ("|" bitwisexorexpressionnoin)+ + | ; -logicalandexpressionnoin : bitwiseorexpressionnoin "&&" logicalandexpressionnoin - | bitwiseorexpressionnoin +logicalandexpressionnoin : bitwiseorexpressionnoin ("&&" bitwiseorexpressionnoin)+ + | ; -logicalorexpressionnoin : logicalandexpressionnoin "||" logicalorexpressionnoin - | logicalandexpressionnoin +logicalorexpressionnoin : logicalandexpressionnoin ("||" logicalandexpressionnoin)+ + | ; conditionalexpressionnoin : logicalorexpressionnoin "?" assignmentexpressionnoin ":" assignmentexpressionnoin - | logicalorexpressionnoin + | ; #lefthandside -assignmentexpressionnoin : lefthandsideexpression assignmentoperatornoin assignmentexpressionnoin - | conditionalexpressionnoin +assignmentexpressionnoin : lefthandsideexpression assignmentoperator assignmentexpressionnoin + | ; -assignmentoperatornoin: "=" | - "\*=" | - "\/=" | - "\%=" | - "\+=" | - "\-=" | - "<<=" | - ">>=" | - ">>>=" | - "&=" | - "^=" | - "\|="; - -expressionnoin : assignmentexpressionnoin "," expressionnoin - | assignmentexpressionnoin +expressionnoin : assignmentexpressionnoin ([","] assignmentexpressionnoin)+ + | ; #identifier Modified: pypy/dist/pypy/lang/js/test/test_new_parser.py ============================================================================== --- pypy/dist/pypy/lang/js/test/test_new_parser.py (original) +++ pypy/dist/pypy/lang/js/test/test_new_parser.py Sun Apr 29 22:52:37 2007 @@ -1,3 +1,4 @@ +from __future__ import division import py from pypy.rlib.parsing.ebnfparse import parse_ebnf, make_parse_function From cfbolz at codespeak.net Sun Apr 29 23:55:55 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sun, 29 Apr 2007 23:55:55 +0200 (CEST) Subject: [pypy-svn] r42450 - pypy/dist/pypy/rpython/ootypesystem Message-ID: <20070429215555.BAF4D8067@code0.codespeak.net> Author: cfbolz Date: Sun Apr 29 23:55:54 2007 New Revision: 42450 Modified: pypy/dist/pypy/rpython/ootypesystem/rstr.py Log: workaround for the inlining bug Modified: pypy/dist/pypy/rpython/ootypesystem/rstr.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/rstr.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/rstr.py Sun Apr 29 23:55:54 2007 @@ -196,7 +196,11 @@ return sign * val def ll_float(ll_str): - return ootype.ooparse_float(ll_str) + # XXX workaround for an inlining bug + try: + return ootype.ooparse_float(ll_str) + except ValueError: + raise # interface to build strings: # x = ll_build_start(n) From santagada at codespeak.net Mon Apr 30 05:14:35 2007 From: santagada at codespeak.net (santagada at codespeak.net) Date: Mon, 30 Apr 2007 05:14:35 +0200 (CEST) Subject: [pypy-svn] r42452 - pypy/dist/pypy/lang/js Message-ID: <20070430031435.0355E8063@code0.codespeak.net> Author: santagada Date: Mon Apr 30 05:14:35 2007 New Revision: 42452 Added: pypy/dist/pypy/lang/js/newparser.py - copied, changed from r42405, user/santagada/newjsparser/newparser.py Modified: pypy/dist/pypy/lang/js/jsgrammar.txt Log: why not eliminate the multop kind of simbols? it seems to work fine Modified: pypy/dist/pypy/lang/js/jsgrammar.txt ============================================================================== --- pypy/dist/pypy/lang/js/jsgrammar.txt (original) +++ pypy/dist/pypy/lang/js/jsgrammar.txt Mon Apr 30 05:14:35 2007 @@ -234,33 +234,33 @@ | "typeof" unaryexpression | "++" unaryexpression | "--" unaryexpression - | PLM unaryexpression + | >addop< unaryexpression | "~" unaryexpression | "!" unaryexpression | ; multop: "*" | "/" | "%"; -multiplicativeexpression : unaryexpression (multop unaryexpression)+ +multiplicativeexpression : unaryexpression (>multop< unaryexpression)+ | ; -PLM : "\+|\-"; -additiveexpression : multiplicativeexpression (PLM multiplicativeexpression)+ +addop: "+" | "-"; +additiveexpression : multiplicativeexpression (>addop< multiplicativeexpression)+ | ; shiftop: "<<" | ">>" | ">>>"; -shiftexpression : additiveexpression (shiftop additiveexpression)+ +shiftexpression : additiveexpression (>shiftop< additiveexpression)+ | ; relationalop: "<" | ">" | "<=" | ">=" | "instanceof" | "in"; -relationalexpression : shiftexpression (relationalop relationalexpression)+ +relationalexpression : shiftexpression (>relationalop< relationalexpression)+ | ; equalityop: "==" | "!=" | "===" | "!=="; -equalityexpression : relationalexpression (equalityop relationalexpression)+ +equalityexpression : relationalexpression (>equalityop< relationalexpression)+ | ; @@ -289,22 +289,13 @@ | ; -assignmentexpression : lefthandsideexpression assignmentoperator assignmentexpression +assignmentexpression : lefthandsideexpression >assignmentoperator< assignmentexpression | ; -assignmentoperator: "=" | - "\*=" | - "\/=" | - "\%=" | - "\+=" | - "\-=" | - "<<=" | - ">>=" | - ">>>=" | - "&=" | - "^=" | - "\|=" ; +assignmentoperator : "=" | "\*=" | "\/=" | "\%=" | "\+=" | "\-=" | "<<=" + | ">>=" | ">>>=" | "&=" | "^=" | "\|=" + ; expression : assignmentexpression ([","] assignmentexpression)+ | From cfbolz at codespeak.net Mon Apr 30 14:05:54 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 30 Apr 2007 14:05:54 +0200 (CEST) Subject: [pypy-svn] r42462 - pypy/extradoc/eu-report Message-ID: <20070430120554.7A5A58076@code0.codespeak.net> Author: cfbolz Date: Mon Apr 30 14:05:53 2007 New Revision: 42462 Added: pypy/extradoc/eu-report/D06.1_Core_Optimizations-2007-04-30.pdf (contents, props changed) Removed: pypy/extradoc/eu-report/D06.1_Core_Optimizations-2007-04-04.pdf Log: final final version of D06.1 Added: pypy/extradoc/eu-report/D06.1_Core_Optimizations-2007-04-30.pdf ============================================================================== Binary file. No diff available. From cfbolz at codespeak.net Mon Apr 30 14:06:59 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 30 Apr 2007 14:06:59 +0200 (CEST) Subject: [pypy-svn] r42466 - pypy/dist/pypy/doc Message-ID: <20070430120659.DD1398077@code0.codespeak.net> Author: cfbolz Date: Mon Apr 30 14:06:59 2007 New Revision: 42466 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 Mon Apr 30 14:06:59 2007 @@ -140,7 +140,7 @@ .. _`D05.2 A Compiled Version of PyPy`: http://codespeak.net/svn/pypy/extradoc/eu-report/D05.2_A_compiled,_self-contained_version_of_PyPy.pdf .. _`D05.3 Implementation with Translation Aspects`: http://codespeak.net/svn/pypy/extradoc/eu-report/D05.3_Publish_on_implementation_with_translation_aspects.pdf .. _`D05.4 Encapsulating Low Level Aspects`: http://codespeak.net/svn/pypy/extradoc/eu-report/D05.4_Publish_on_encapsulating_low_level_language_aspects.pdf -.. _`D06.1 Core Object Optimization Results`: http://codespeak.net/svn/pypy/extradoc/eu-report/D06.1_Core_Optimizations-2007-04-04.pdf +.. _`D06.1 Core Object Optimization Results`: http://codespeak.net/svn/pypy/extradoc/eu-report/D06.1_Core_Optimizations-2007-04-30.pdf .. _`D07.1 Massive Parallelism and Translation Aspects`: http://codespeak.net/pypy/extradoc/eu-report/D07.1_Massive_Parallelism_and_Translation_Aspects-2007-02-28.pdf .. _`Draft D08.2 JIT Compiler Architecture`: http://codespeak.net/pypy/extradoc/eu-report/D08.2_JIT_Compiler_Architecture-interim-2007-01-28.pdf .. _`D09.1 Constraint Solving and Semantic Web`: http://codespeak.net/pypy/extradoc/eu-report/D09.1_Constraint_Solving_and_Semantic_Web-interim-2007-02-28.pdf From pedronis at codespeak.net Mon Apr 30 15:56:04 2007 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Mon, 30 Apr 2007 15:56:04 +0200 (CEST) Subject: [pypy-svn] r42482 - pypy/dist/pypy/doc Message-ID: <20070430135604.4A57D8078@code0.codespeak.net> Author: pedronis Date: Mon Apr 30 15:56:03 2007 New Revision: 42482 Modified: pypy/dist/pypy/doc/index-report.txt Log: D08.1 entry Modified: pypy/dist/pypy/doc/index-report.txt ============================================================================== --- pypy/dist/pypy/doc/index-report.txt (original) +++ pypy/dist/pypy/doc/index-report.txt Mon Apr 30 15:56:03 2007 @@ -12,6 +12,10 @@ Reports of 2007 =============== +`D08.1 JIT Compiler Release` reports on our sucessfully including a +JIT compiler for Python and the novel framework we used to +automatically generate it in PyPy 1.0. *()* + `D14.4 PyPy-1.0 Milestone report`_ (for language developers and researchers) summarizes research & technical results of the PyPy-1.0 release and discusses related development process and community aspects. This report is an interim From cfbolz at codespeak.net Mon Apr 30 15:57:19 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 30 Apr 2007 15:57:19 +0200 (CEST) Subject: [pypy-svn] r42484 - pypy/extradoc/eu-report Message-ID: <20070430135719.6AA03807F@code0.codespeak.net> Author: cfbolz Date: Mon Apr 30 15:57:18 2007 New Revision: 42484 Added: pypy/extradoc/eu-report/D08.1_JIT_Compiler_Release-2007-04-30.pdf (contents, props changed) Log: final D08.1 Added: pypy/extradoc/eu-report/D08.1_JIT_Compiler_Release-2007-04-30.pdf ============================================================================== Binary file. No diff available. From cfbolz at codespeak.net Mon Apr 30 15:58:34 2007 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 30 Apr 2007 15:58:34 +0200 (CEST) Subject: [pypy-svn] r42485 - pypy/dist/pypy/doc Message-ID: <20070430135834.B28D5807A@code0.codespeak.net> Author: cfbolz Date: Mon Apr 30 15:58:34 2007 New Revision: 42485 Modified: pypy/dist/pypy/doc/index-report.txt Log: link and date Modified: pypy/dist/pypy/doc/index-report.txt ============================================================================== --- pypy/dist/pypy/doc/index-report.txt (original) +++ pypy/dist/pypy/doc/index-report.txt Mon Apr 30 15:58:34 2007 @@ -12,9 +12,9 @@ Reports of 2007 =============== -`D08.1 JIT Compiler Release` reports on our sucessfully including a +`D08.1 JIT Compiler Release`_ reports on our sucessfully including a JIT compiler for Python and the novel framework we used to -automatically generate it in PyPy 1.0. *()* +automatically generate it in PyPy 1.0. *(2007-04-30)* `D14.4 PyPy-1.0 Milestone report`_ (for language developers and researchers) summarizes research & technical results of the PyPy-1.0 release and discusses @@ -147,6 +147,7 @@ .. _`D06.1 Core Object Optimization Results`: http://codespeak.net/svn/pypy/extradoc/eu-report/D06.1_Core_Optimizations-2007-04-30.pdf .. _`D07.1 Massive Parallelism and Translation Aspects`: http://codespeak.net/pypy/extradoc/eu-report/D07.1_Massive_Parallelism_and_Translation_Aspects-2007-02-28.pdf .. _`Draft D08.2 JIT Compiler Architecture`: http://codespeak.net/pypy/extradoc/eu-report/D08.2_JIT_Compiler_Architecture-interim-2007-01-28.pdf +.. _`D08.1 JIT Compiler Release`: http://codespeak.net/pypy/extradoc/eu-report/D08.1_JIT_Compiler_Release-2007-04-30.pdf .. _`D09.1 Constraint Solving and Semantic Web`: http://codespeak.net/pypy/extradoc/eu-report/D09.1_Constraint_Solving_and_Semantic_Web-interim-2007-02-28.pdf .. _`D10.1 Aspect-Oriented, Design-by-Contract Programming and RPython static checking`: http://codespeak.net/pypy/extradoc/eu-report/D10.1_Aspect_Oriented_Programming_in_PyPy-2007-03-22.pdf .. _`D11.1 PyPy for Embedded Devices`: http://codespeak.net/pypy/extradoc/eu-report/D11.1_PyPy_for_Embedded_Devices-2007-03-26.pdf